From 1acc54cfc70be60db45bafa6853edcb22fbc5468 Mon Sep 17 00:00:00 2001
From: Matt Jankowski <matt@jankowski.online>
Date: Fri, 20 Dec 2024 02:52:16 -0500
Subject: [PATCH] Convert `admin/webhooks` spec controller->system (#33364)

---
 .../admin/webhooks_controller_spec.rb         | 117 ------------------
 spec/system/admin/webhooks_spec.rb            | 117 ++++++++++++++++++
 2 files changed, 117 insertions(+), 117 deletions(-)
 delete mode 100644 spec/controllers/admin/webhooks_controller_spec.rb
 create mode 100644 spec/system/admin/webhooks_spec.rb

diff --git a/spec/controllers/admin/webhooks_controller_spec.rb b/spec/controllers/admin/webhooks_controller_spec.rb
deleted file mode 100644
index 4fe787c26..000000000
--- a/spec/controllers/admin/webhooks_controller_spec.rb
+++ /dev/null
@@ -1,117 +0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-
-RSpec.describe Admin::WebhooksController do
-  render_views
-
-  let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
-
-  before do
-    sign_in user, scope: :user
-  end
-
-  describe 'GET #index' do
-    it 'returns http success' do
-      get :index
-
-      expect(response).to have_http_status(:success)
-    end
-  end
-
-  describe 'GET #new' do
-    it 'returns http success and renders view' do
-      get :new
-
-      expect(response).to have_http_status(:success)
-      expect(response).to render_template(:new)
-    end
-  end
-
-  describe 'POST #create' do
-    it 'creates a new webhook record with valid data' do
-      expect do
-        post :create, params: { webhook: { url: 'https://example.com/hook', events: ['account.approved'] } }
-      end.to change(Webhook, :count).by(1)
-
-      expect(response).to be_redirect
-    end
-
-    it 'does not create a new webhook record with invalid data' do
-      expect do
-        post :create, params: { webhook: { url: 'https://example.com/hook', events: [] } }
-      end.to_not change(Webhook, :count)
-
-      expect(response).to have_http_status(:success)
-      expect(response).to render_template(:new)
-    end
-  end
-
-  context 'with an existing record' do
-    let!(:webhook) { Fabricate(:webhook, events: ['account.created', 'report.created']) }
-
-    describe 'GET #show' do
-      it 'returns http success and renders view' do
-        get :show, params: { id: webhook.id }
-
-        expect(response).to have_http_status(:success)
-        expect(response).to render_template(:show)
-      end
-    end
-
-    describe 'GET #edit' do
-      it 'returns http success and renders view' do
-        get :edit, params: { id: webhook.id }
-
-        expect(response).to have_http_status(:success)
-        expect(response).to render_template(:edit)
-      end
-    end
-
-    describe 'PUT #update' do
-      it 'updates the record with valid data' do
-        put :update, params: { id: webhook.id, webhook: { url: 'https://example.com/new/location' } }
-
-        expect(webhook.reload.url).to match(%r{new/location})
-        expect(response).to redirect_to(admin_webhook_path(webhook))
-      end
-
-      it 'does not update the record with invalid data' do
-        expect do
-          put :update, params: { id: webhook.id, webhook: { url: '' } }
-        end.to_not change(webhook, :url)
-
-        expect(response).to have_http_status(:success)
-        expect(response).to render_template(:edit)
-      end
-    end
-
-    describe 'POST #enable' do
-      it 'enables the webhook' do
-        post :enable, params: { id: webhook.id }
-
-        expect(webhook.reload).to be_enabled
-        expect(response).to redirect_to(admin_webhook_path(webhook))
-      end
-    end
-
-    describe 'POST #disable' do
-      it 'disables the webhook' do
-        post :disable, params: { id: webhook.id }
-
-        expect(webhook.reload).to_not be_enabled
-        expect(response).to redirect_to(admin_webhook_path(webhook))
-      end
-    end
-
-    describe 'DELETE #destroy' do
-      it 'destroys the record' do
-        expect do
-          delete :destroy, params: { id: webhook.id }
-        end.to change(Webhook, :count).by(-1)
-
-        expect(response).to redirect_to(admin_webhooks_path)
-      end
-    end
-  end
-end
diff --git a/spec/system/admin/webhooks_spec.rb b/spec/system/admin/webhooks_spec.rb
new file mode 100644
index 000000000..69e8a7d69
--- /dev/null
+++ b/spec/system/admin/webhooks_spec.rb
@@ -0,0 +1,117 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe 'Admin Webhooks' do
+  describe 'Managing webhooks' do
+    before { sign_in Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
+
+    describe 'Viewing webhooks' do
+      let!(:webhook) { Fabricate :webhook }
+
+      it 'lists existing records' do
+        visit admin_webhooks_path
+
+        expect(page)
+          .to have_content(I18n.t('admin.webhooks.title'))
+          .and have_content(webhook.url)
+
+        click_on(webhook.url)
+        expect(page)
+          .to have_content(I18n.t('admin.webhooks.title'))
+      end
+    end
+
+    describe 'Creating a new webhook' do
+      it 'creates new record with valid attributes' do
+        visit admin_webhooks_path
+
+        # Visit new page
+        click_on I18n.t('admin.webhooks.add_new')
+        expect(page)
+          .to have_content(I18n.t('admin.webhooks.new'))
+
+        # Invalid submission (missing url, no events selected)
+        fill_in 'webhook_url', with: ''
+        expect { submit_form }
+          .to_not change(Webhook, :count)
+        expect(page)
+          .to have_content(/errors below/)
+
+        # Valid submission
+        fill_in 'webhook_url', with: 'https://host.example/hooks/123'
+        check Webhook::EVENTS.first
+        expect { submit_form }
+          .to change(Webhook, :count).by(1)
+        expect(page)
+          .to have_content(I18n.t('admin.webhooks.title'))
+      end
+
+      it 'fails to create with no events selected' do
+        visit new_admin_webhook_path
+
+        fill_in 'webhook_url', with: 'https://host.example/hooks/123'
+        expect { submit_form }
+          .to_not change(Webhook, :count)
+        expect(page)
+          .to have_content(/errors below/)
+      end
+
+      def submit_form
+        click_on I18n.t('admin.webhooks.add_new')
+      end
+    end
+
+    describe 'Editing an existing webhook' do
+      let!(:webhook) { Fabricate :webhook, events: [Webhook::EVENTS.first] }
+
+      it 'updates with valid attributes' do
+        visit admin_webhook_path(webhook)
+
+        # Invalid submission (missing url)
+        click_on I18n.t('admin.webhooks.edit')
+        fill_in 'webhook_url', with: ''
+        expect { submit_form }
+          .to_not change(webhook.reload, :updated_at)
+
+        # Valid update
+        fill_in 'webhook_url', with: 'https://host.example/new/value/123'
+        expect { submit_form }
+          .to_not change(webhook.reload, :url)
+      end
+
+      def submit_form
+        click_on I18n.t('generic.save_changes')
+      end
+    end
+
+    describe 'Destroy a webhook' do
+      let!(:webhook) { Fabricate :webhook, events: [Webhook::EVENTS.first] }
+
+      it 'removes the record' do
+        visit admin_webhooks_path
+
+        expect { click_on I18n.t('admin.webhooks.delete') }
+          .to change(Webhook, :count).by(-1)
+        expect { webhook.reload }
+          .to raise_error(ActiveRecord::RecordNotFound)
+      end
+    end
+
+    describe 'Toggle state of webhook' do
+      let!(:webhook) { Fabricate :webhook, events: [Webhook::EVENTS.first], enabled: true }
+
+      it 'switches enabled and disabled as requested' do
+        visit admin_webhook_path(webhook)
+
+        # Disable the initially enabled record
+        expect { click_on I18n.t('admin.webhooks.disable') }
+          .to change { webhook.reload.enabled? }.to(false)
+
+        # Re-enable the record
+        expect { click_on I18n.t('admin.webhooks.enable') }
+          .to change { webhook.reload.enabled? }.to(true)
+      end
+    end
+  end
+end