update Webhooks UI

pull/382/head
Alex Turchyn 12 months ago committed by Pete Matsyburka
parent 4ea863592b
commit fd3530ac62

@ -10,7 +10,8 @@ class WebhookSecretController < ApplicationController
webhook_secret_params[:key] => webhook_secret_params[:value]
}.compact_blank)
redirect_back(fallback_location: settings_webhooks_path, notice: I18n.t('webhook_secret_has_been_saved'))
redirect_back(fallback_location: settings_webhook_path(@webhook_url),
notice: I18n.t('webhook_secret_has_been_saved'))
end
private

@ -1,24 +1,55 @@
# frozen_string_literal: true
class WebhookSettingsController < ApplicationController
before_action :load_webhook_url
before_action :load_webhook_url, only: %i[show update destroy]
authorize_resource :webhook_url, parent: false
def index
@webhook_urls = current_account.webhook_urls.order(id: :desc)
@webhook_url = @webhook_urls.first_or_initialize
render @webhook_urls.size > 1 ? 'index' : 'show'
end
def show; end
def new
@webhook_url = current_account.webhook_urls.build
end
def create
@webhook_url.assign_attributes(webhook_params)
@webhook_url = current_account.webhook_urls.build(create_webhook_params)
@webhook_url.url.present? ? @webhook_url.save! : @webhook_url.delete
@webhook_url.save!
redirect_back(fallback_location: settings_webhooks_path, notice: I18n.t('webhook_url_has_been_saved'))
redirect_to settings_webhooks_path, notice: I18n.t('webhook_url_has_been_saved')
end
def update
@webhook_url.update!(update_webhook_params)
redirect_to settings_webhook_path(@webhook_url), notice: I18n.t('webhook_url_has_been_updated')
end
def destroy
@webhook_url.delete
redirect_to settings_webhooks_path, notice: I18n.t('webhook_url_has_been_deleted')
end
def resend
submitter = current_account.submitters.where.not(completed_at: nil).order(:id).last
webhook = current_account.webhook_urls
.where(Arel::Table.new(:webhook_urls)[:events].matches('%"form.completed"%'))
.find_by(id: params[:webhook_id])
if submitter.blank? || webhook.blank?
return redirect_back(fallback_location: settings_webhooks_path,
alert: I18n.t('unable_to_resend_webhook_request'))
end
SendFormCompletedWebhookRequestJob.perform_async('submitter_id' => submitter.id,
'webhook_url_id' => @webhook_url.id)
'webhook_url_id' => webhook.id)
redirect_back(fallback_location: settings_webhooks_path, notice: I18n.t('webhook_request_has_been_sent'))
end
@ -26,10 +57,16 @@ class WebhookSettingsController < ApplicationController
private
def load_webhook_url
@webhook_url = current_account.webhook_urls.first_or_initialize
@webhook_url = current_account.webhook_urls.find_by(id: params[:id])
redirect_to settings_webhooks_path unless @webhook_url
end
def create_webhook_params
params.require(:webhook_url).permit(:url, events: []).reverse_merge(events: [])
end
def webhook_params
def update_webhook_params
params.require(:webhook_url).permit(:url)
end
end

@ -0,0 +1,5 @@
<svg class="<%= local_assigns[:class] %>" xmlns="http://www.w3.org/2000/svg" x-bind:width="size" x-bind:height="size" viewBox="0 0 24 24" fill="none" stroke="currentColor" x-bind:stroke-width="stroke" stroke-linecap="round" stroke-linejoin="round" width="24" height="24" stroke-width="2">
<path d="M5 13a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v6a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2v-6z"></path>
<path d="M11 16a1 1 0 1 0 2 0a1 1 0 0 0 -2 0"></path>
<path d="M8 11v-4a4 4 0 1 1 8 0v4"></path>
</svg>

After

Width:  |  Height:  |  Size: 496 B

@ -0,0 +1,34 @@
<div class="flex flex-wrap space-y-4 md:flex-nowrap md:space-y-0 md:space-x-10">
<%= render 'shared/settings_nav' %>
<div class="flex-grow min-w-0">
<div class="flex flex-col gap-2 md:flex-row md:justify-between md:items-center mb-4">
<h1 class="text-4xl font-bold">Webhooks</h1>
<div class="flex flex-col gap-2 md:flex-row md:justify-between md:items-center">
<%= render 'shared/test_mode_toggle' %>
<% if @webhook_url.persisted? %>
<%= link_to new_settings_webhook_path, class: 'md:ml-3 btn bg-white btn-outline btn-md gap-2 w-full md:w-fit', data: { turbo_frame: 'modal' } do %>
<%= svg_icon('plus', class: 'w-6 h-6') %>
<span><%= t('new_webhook') %></span>
<% end %>
<% end %>
</div>
</div>
<div class="space-y-4">
<% @webhook_urls.each do |webhook_url| %>
<%= link_to settings_webhook_path(webhook_url), class: 'card bg-base-200' do %>
<div class="card-body p-6 min-w-0">
<p class="flex items-center space-x-1">
<%= svg_icon('world', class: 'w-6 h-6 shrink-0') %>
<span class="text-xl font-semibold truncate"><%= webhook_url.url %></span>
</p>
<div class="flex flex-wrap gap-2 mt-2">
<% webhook_url.events.each do |event| %>
<span class="badge badge-outline"><%= event %></span>
<% end %>
</div>
</div>
<% end %>
<% end %>
</div>
</div>
</div>

@ -0,0 +1,29 @@
<%= render 'shared/turbo_modal', title: t('new_webhook') do %>
<%= form_for @webhook_url, url: settings_webhooks_path, html: { class: 'space-y-4' }, data: { turbo_frame: :_top } do |f| %>
<div class="space-y-4">
<div class="form-control">
<%= f.label :url, 'Webhook URL', class: 'label' %>
<%= f.url_field :url, class: 'base-input', placeholder: 'https://example.com/hook', required: true %>
</div>
<div class="space-y-4">
<% WebhookUrl::EVENTS.group_by { |e| e.include?('form') }.each do |_, events| %>
<div class="grid grid-cols-1 md:grid-cols-2 gap-y-2">
<%= f.collection_check_boxes(:events, events, :to_s, :to_s, include_hidden: false) do |b| %>
<div class="flex">
<label class="flex items-center space-x-2">
<%= b.check_box class: 'base-checkbox', checked: @webhook_url.events.include?(b.value) %>
<span>
<%= b.label %>
</span>
</label>
</div>
<% end %>
</div>
<% end %>
</div>
</div>
<div class="form-control pt-2">
<%= f.button button_title(title: t('save'), disabled_with: t('saving')), class: 'base-button' %>
</div>
<% end %>
<% end %>

@ -1,38 +1,78 @@
<div class="flex flex-wrap space-y-4 md:flex-nowrap md:space-y-0 md:space-x-10">
<%= render 'shared/settings_nav' %>
<div class="flex-grow">
<div class="flex flex-col gap-2 md:flex-row md:justify-between md:items-end mb-4">
<h1 class="text-4xl font-bold">Webhooks</h1>
<%= render 'shared/test_mode_toggle' %>
<div class="flex flex-col gap-2 md:flex-row md:justify-between md:items-center mb-4">
<h1 class="text-4xl font-bold">Webhook</h1>
<div class="flex flex-col gap-2 md:flex-row md:justify-between md:items-center">
<% if params[:action] == 'index' %>
<%= render 'shared/test_mode_toggle' %>
<% end %>
<% if @webhook_url.persisted? && params[:action] == 'index' %>
<%= link_to new_settings_webhook_path, class: 'md:ml-3 btn bg-white btn-outline btn-md gap-2 w-full md:w-fit', data: { turbo_frame: 'modal' } do %>
<%= svg_icon('plus', class: 'w-6 h-6') %>
<span><%= t('new_webhook') %></span>
<% end %>
<% end %>
</div>
</div>
<div class="card bg-base-200">
<div class="card-body p-6">
<%= form_for @webhook_url, url: settings_webhooks_path, method: :post, html: { autocomplete: 'off' } do |f| %>
<%= f.label :url, 'Webhook URL', class: 'text-sm font-semibold' %>
<div class="flex flex-row flex-wrap space-y-2 md:space-y-0 md:flex-nowrap md:space-x-2 mt-2">
<%= f.url_field :url, class: 'input font-mono input-bordered w-full', placeholder: 'https://example.com/hook' %>
<div class="flex flex-col gap-2 md:flex-row md:justify-between md:items-end md:relative">
<%= label_tag :url, 'Webhook URL', class: 'text-sm font-semibold' %>
<% if @webhook_url.persisted? %>
<div class="flex items-center space-x-2 md:absolute md:right-0">
<%= link_to webhook_secret_path(@webhook_url), class: 'btn btn-outline btn-sm bg-white', data: { turbo_frame: 'modal' } do %>
<%= svg_icon('lock', class: 'w-4 h-4') %>
<span><%= @webhook_url.secret.present? ? t('edit_secret') : t('add_secret') %></span>
<% end %>
<div class="tooltip tooltip-left md:tooltip-top" data-tip="<%= t('delete_webhook') %>">
<%= button_to settings_webhook_path(@webhook_url), class: 'btn btn-warning btn-sm', method: :delete, data: { turbo_confirm: t('are_you_sure_') } do %>
<span><%= t('delete') %></span>
<% end %>
</div>
</div>
<% end %>
</div>
<%= form_for @webhook_url, url: @webhook_url.persisted? ? settings_webhook_path(@webhook_url) : settings_webhooks_path, html: { autocomplete: 'off' }, data: { turbo: false } do |f| %>
<div class="flex flex-row flex-wrap space-y-2 md:space-y-0 md:flex-nowrap md:space-x-2">
<%= f.url_field :url, class: 'input font-mono input-bordered w-full', placeholder: 'https://example.com/hook', required: true %>
<%= f.button button_title(title: t('save'), disabled_with: t('saving')), class: 'base-button w-full md:w-32' %>
<% if @webhook_url.persisted? %>
<a href="<%= webhook_secret_path(@webhook_url) %>" data-turbo-frame="modal" class="white-button w-full md:w-auto">
<%= @webhook_url.secret.present? ? t('edit_secret') : t('add_secret') %>
</a>
<% end %>
</div>
<% unless @webhook_url.persisted? %>
<div class="space-y-4 mt-4">
<% WebhookUrl::EVENTS.group_by { |e| e.include?('form') }.each do |_, events| %>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-y-2">
<%= f.collection_check_boxes(:events, events, :to_s, :to_s, include_hidden: false) do |b| %>
<div class="flex">
<label class="flex items-center space-x-2">
<%= b.check_box class: 'base-checkbox', checked: @webhook_url.events.include?(b.value) %>
<span>
<%= b.label %>
</span>
</label>
</div>
<% end %>
</div>
<% end %>
</div>
<% end %>
<% end %>
<%= form_for @webhook_url, url: @webhook_url.url.present? ? webhook_preference_path(@webhook_url) : '', method: :put, html: { autocomplete: 'off' } do |f| %>
<% WebhookUrl::EVENTS.group_by { |e| e.include?('form') }.each do |_, events| %>
<div class="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-4 mt-4 gap-y-2">
<% events.each do |event| %>
<%= f.fields_for :events do |ff| %>
<div class="flex">
<label class="flex items-center space-x-2 cursor-pointer">
<%= ff.check_box event, class: 'base-checkbox', checked: @webhook_url.events.include?(event), onchange: 'this.form.requestSubmit()', disabled: @webhook_url.url.blank? %>
<span>
<%= event %>
</span>
</label>
</div>
<% end %>
<% if @webhook_url.persisted? %>
<%= form_for @webhook_url, url: webhook_preference_path(@webhook_url), method: :put, html: { autocomplete: 'off', class: 'mt-2' } do |f| %>
<div class="space-y-4">
<% WebhookUrl::EVENTS.group_by { |e| e.include?('form') }.each do |_, events| %>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-y-4">
<% events.each do |event| %>
<%= f.fields_for :events do |ff| %>
<div class="flex">
<label class="flex items-center cursor-pointer">
<%= ff.check_box event, class: 'base-checkbox', checked: @webhook_url.events.include?(event), onchange: 'this.form.requestSubmit()' %>
<span class="ml-2"><%= event %></span>
</label>
</div>
<% end %>
<% end %>
</div>
<% end %>
</div>
<% end %>
@ -44,12 +84,12 @@
<div class="space-y-4 mt-4">
<div class="collapse collapse-open bg-base-200 px-1">
<div class="p-4 text-xl font-medium">
<div class="flex items-center justify-between gap-2">
<div class="flex flex-col gap-2 md:flex-row md:justify-between md:items-center md:h-8">
<span>
<%= t('submission_example_payload') %>
</span>
<% if @webhook_url.url.present? && @webhook_url.events.include?('form.completed') %>
<%= button_to button_title(title: 'Test Webhook', disabled_with: t('sending'), icon_disabled: svg_icon('loader', class: 'w-4 h-4 animate-spin')), settings_webhooks_path, class: 'btn btn-neutral btn-outline btn-sm', method: :put %>
<%= button_to button_title(title: 'Test Webhook', disabled_with: t('sending'), icon_disabled: svg_icon('loader', class: 'w-4 h-4 animate-spin')), settings_webhook_resend_path(@webhook_url), class: 'btn btn-neutral btn-outline btn-sm', method: :post %>
<% end %>
</div>
</div>

@ -511,13 +511,17 @@ en: &en
webhook_secret_has_been_saved: Webhook Secret has been saved.
webhook_url_has_been_saved: Webhook URL has been saved.
webhook_request_has_been_sent: Webhook request has been sent.
webhook_url_has_been_updated: Webhook URL has been updated.
webhook_url_has_been_deleted: Webhook URL has been deleted.
unable_to_resend_webhook_request: Unable to resend webhook request.
new_webhook: New Webhook
delete_webhook: Delete webhook
count_submissions_have_been_created: '%{count} submissions have been created.'
gmail_has_been_connected: Gmail has been connected
microsoft_account_has_been_connected: Microsoft Account has been connected
sms_length_cant_be_longer_than_120_bytes: SMS length can't be longer than 120 bytes
connected_successfully: Connected successfully.
user_nameid_not_found: 'User %{nameid} not found.'
webhook_request_has_been_sent: Webhook request has been sent.
sso_settings_have_been_updated: SSO settings have been updated.
sms_has_been_sent: SMS has been sent.
account_has_been_created: Account has been created.
@ -1156,13 +1160,17 @@ es: &es
webhook_secret_has_been_saved: El secreto del Webhook ha sido guardado.
webhook_url_has_been_saved: La URL del Webhook ha sido guardada.
webhook_request_has_been_sent: La solicitud del Webhook ha sido enviada.
webhook_url_has_been_updated: La URL del Webhook ha sido actualizada.
webhook_url_has_been_deleted: La URL del Webhook ha sido eliminada.
unable_to_resend_webhook_request: No se pudo reenviar la solicitud del webhook.
new_webhook: Nuevo Webhook
delete_webhook: Eliminar webhook
count_submissions_have_been_created: '%{count} envíos han sido creados.'
gmail_has_been_connected: Gmail ha sido conectado.
microsoft_account_has_been_connected: La cuenta de Microsoft ha sido conectada.
sms_length_cant_be_longer_than_120_bytes: La longitud del SMS no puede ser mayor a 120 bytes.
connected_successfully: Conectado con éxito.
user_nameid_not_found: 'Usuario %{nameid} no encontrado.'
webhook_request_has_been_sent: La solicitud del Webhook ha sido enviada.
sso_settings_have_been_updated: La configuración de SSO ha sido actualizada.
sms_has_been_sent: El SMS ha sido enviado.
account_has_been_created: La cuenta ha sido creada.
@ -1801,13 +1809,17 @@ it: &it
webhook_secret_has_been_saved: Il segreto del Webhook è stato salvato.
webhook_url_has_been_saved: "L'URL del Webhook è stato salvato."
webhook_request_has_been_sent: La richiesta del Webhook è stata inviata.
webhook_url_has_been_updated: "L'URL del Webhook è stata aggiornata."
webhook_url_has_been_deleted: "L'URL del Webhook è stata eliminata."
unable_to_resend_webhook_request: Impossibile reinviare la richiesta del webhook.
new_webhook: Nuovo Webhook
delete_webhook: Elimina webhook
count_submissions_have_been_created: '%{count} invii sono stati creati.'
gmail_has_been_connected: Gmail è stato connesso.
microsoft_account_has_been_connected: "L'account Microsoft è stato connesso."
sms_length_cant_be_longer_than_120_bytes: "La lunghezza dell'SMS non può superare i 120 byte."
connected_successfully: Collegamento avvenuto con successo.
user_nameid_not_found: 'Utente %{nameid} non trovato.'
webhook_request_has_been_sent: La richiesta del Webhook è stata inviata.
sso_settings_have_been_updated: Le impostazioni SSO sono state aggiornate.
sms_has_been_sent: "L'SMS è stato inviato."
account_has_been_created: "L'account è stato creato."
@ -2447,13 +2459,17 @@ fr: &fr
webhook_secret_has_been_saved: Le secret du Webhook a été enregistré.
webhook_url_has_been_saved: "L'URL du Webhook a été enregistrée."
webhook_request_has_been_sent: La demande du Webhook a été envoyée.
webhook_url_has_been_updated: "L'URL du Webhook a été mise à jour."
webhook_url_has_been_deleted: "L'URL du Webhook a été supprimée."
unable_to_resend_webhook_request: Impossible de renvoyer la requête du webhook.
new_webhook: Nouveau Webhook
delete_webhook: Supprimer le webhook
count_submissions_have_been_created: '%{count} soumissions ont été créées.'
gmail_has_been_connected: Gmail a été connecté.
microsoft_account_has_been_connected: Le compte Microsoft a été connecté.
sms_length_cant_be_longer_than_120_bytes: La longueur du SMS ne peut pas dépasser 120 octets.
connected_successfully: Connecté avec succès.
user_nameid_not_found: 'Utilisateur %{nameid} introuvable.'
webhook_request_has_been_sent: La demande du Webhook a été envoyée.
sso_settings_have_been_updated: Les paramètres de SSO ont été mis à jour.
sms_has_been_sent: Le SMS a été envoyé.
account_has_been_created: Le compte a été créé.
@ -3092,13 +3108,17 @@ pt: &pt
webhook_secret_has_been_saved: O segredo do Webhook foi salvo.
webhook_url_has_been_saved: A URL do Webhook foi salva.
webhook_request_has_been_sent: A solicitação do Webhook foi enviada.
webhook_url_has_been_updated: URL do Webhook foi atualizada.
webhook_url_has_been_deleted: URL do Webhook foi excluída.
unable_to_resend_webhook_request: Não foi possível reenviar a solicitação do webhook.
new_webhook: Novo Webhook
delete_webhook: Excluir webhook
count_submissions_have_been_created: '%{count} submissões foram criadas.'
gmail_has_been_connected: O Gmail foi conectado
microsoft_account_has_been_connected: A conta da Microsoft foi conectada
sms_length_cant_be_longer_than_120_bytes: O comprimento do SMS não pode ultrapassar 120 bytes
connected_successfully: Conectado com sucesso.
user_nameid_not_found: 'Usuário %{nameid} não encontrado.'
webhook_request_has_been_sent: A solicitação do Webhook foi enviada.
sso_settings_have_been_updated: As configurações de SSO foram atualizadas.
sms_has_been_sent: O SMS foi enviado.
account_has_been_created: A conta foi criada.
@ -3699,8 +3719,8 @@ de: &de
api_key: API-Schlüssel
logo: Logo
back: Zurück
add_secret: Geheimnis hinzufügen
edit_secret: Geheimnis bearbeiten
add_secret: Geheimnis hinzuf
edit_secret: Geheimnis bearb
submission_example_payload: Beispiel-Payload für Einreichung
there_are_no_signatures: Es gibt keine Unterschriften
signed_with_trusted_certificate: Signiert mit vertrauenswürdigem Zertifikat
@ -3737,13 +3757,17 @@ de: &de
webhook_secret_has_been_saved: Das Webhook-Geheimnis wurde gespeichert.
webhook_url_has_been_saved: Die Webhook-URL wurde gespeichert.
webhook_request_has_been_sent: Die Webhook-Anfrage wurde gesendet.
webhook_url_has_been_updated: Webhook-URL wurde aktualisiert.
webhook_url_has_been_deleted: Webhook-URL wurde gelöscht.
unable_to_resend_webhook_request: Webhook-Anfrage konnte nicht erneut gesendet werden.
new_webhook: Neuer Webhook
delete_webhook: Webhook löschen
count_submissions_have_been_created: '%{count} Einreichungen wurden erstellt.'
gmail_has_been_connected: Gmail wurde verbunden.
microsoft_account_has_been_connected: Microsoft-Konto wurde verbunden.
sms_length_cant_be_longer_than_120_bytes: Die SMS-Länge darf 120 Bytes nicht überschreiten.
connected_successfully: Erfolgreich verbunden.
user_nameid_not_found: 'Benutzer %{nameid} nicht gefunden.'
webhook_request_has_been_sent: Die Webhook-Anfrage wurde gesendet.
sso_settings_have_been_updated: Die SSO-Einstellungen wurden aktualisiert.
sms_has_been_sent: Die SMS wurde gesendet.
account_has_been_created: Das Konto wurde erstellt.

@ -168,7 +168,9 @@ Rails.application.routes.draw do
defaults: { status: :integration }
resource :personalization, only: %i[show create], controller: 'personalization_settings'
resources :api, only: %i[index create], controller: 'api_settings'
resource :webhooks, only: %i[show create update], controller: 'webhook_settings'
resources :webhooks, except: %i[edit], controller: 'webhook_settings' do
post :resend
end
resource :account, only: %i[show update destroy]
resources :profile, only: %i[index] do
collection do

@ -44,7 +44,9 @@ RSpec.describe 'Template' do
it 'archives a template' do
expect do
click_button 'Archive'
accept_confirm('Are you sure?') do
click_button 'Archive'
end
end.to change { Template.active.count }.by(-1)
expect(page).to have_content('Template has been archived')

@ -10,22 +10,58 @@ RSpec.describe 'Webhook Settings' do
sign_in(user)
end
it 'shows webhook settings page' do
it 'shows webhook settings page with empty form when there are no webhooks' do
visit settings_webhooks_path
expect(page).to have_content('Webhook')
expect(page).to have_content('Webhook URL')
expect(page).to have_field('webhook_url[url]', type: 'url')
expect(page).to have_button('Save')
WebhookUrl::EVENTS.each do |event|
expect(page).to have_field(event, type: 'checkbox')
end
end
it 'shows list of webhooks when there are more than one' do
webhook_urls = create_list(:webhook_url, 2, account:)
visit settings_webhooks_path
expect(page).to have_content('Webhooks')
expect(page).to have_field('Webhook URL')
expect(page).to have_link('New Webhook')
webhook_urls.each do |webhook_url|
expect(page).to have_content(webhook_url.url)
within("a[href='#{settings_webhook_path(webhook_url)}']") do
webhook_url.events.each do |event|
expect(page).to have_content(event)
end
end
end
end
it 'shows webhook settings page with pre-filled form when there is one webhook' do
webhook_url = create(:webhook_url, account:)
visit settings_webhooks_path
expect(page).to have_content('Webhook')
expect(page).to have_field('webhook_url[url]', type: 'url', with: webhook_url.url)
expect(page).to have_button('Save')
expect(page).to have_button('Delete')
expect(page).to have_link('Add Secret')
WebhookUrl::EVENTS.each do |event|
expect(page).to have_field(event, type: 'checkbox', disabled: true)
expect(page).to have_field(event, type: 'checkbox', checked: webhook_url.events.include?(event))
end
end
it 'creates the webhook' do
visit settings_webhooks_path
fill_in 'Webhook URL', with: 'https://example.com/webhook'
fill_in 'webhook_url[url]', with: 'https://example.com/webhook'
expect do
click_button 'Save'
@ -34,6 +70,8 @@ RSpec.describe 'Webhook Settings' do
webhook_url = account.webhook_urls.first
expect(webhook_url.url).to eq('https://example.com/webhook')
expect(page).to have_content('Webhook URL has been saved.')
expect(page.current_path).to eq(settings_webhooks_path)
end
it 'updates the webhook' do
@ -41,12 +79,14 @@ RSpec.describe 'Webhook Settings' do
visit settings_webhooks_path
fill_in 'Webhook URL', with: 'https://example.org/webhook'
fill_in 'webhook_url[url]', with: 'https://example.org/webhook'
click_button 'Save'
webhook_url.reload
expect(webhook_url.url).to eq('https://example.org/webhook')
expect(page).to have_content('Webhook URL has been updated.')
expect(page.current_path).to eq(settings_webhook_path(webhook_url))
end
it 'deletes the webhook' do
@ -54,11 +94,14 @@ RSpec.describe 'Webhook Settings' do
visit settings_webhooks_path
fill_in 'Webhook URL', with: ''
expect do
click_button 'Save'
accept_confirm('Are you sure?') do
click_button 'Delete'
end
end.to change(WebhookUrl, :count).by(-1)
expect(page).to have_content('Webhook URL has been deleted.')
expect(page.current_path).to eq(settings_webhooks_path)
end
it 'updates the webhook events' do
@ -94,6 +137,9 @@ RSpec.describe 'Webhook Settings' do
expect(webhook_url.secret).to eq({ 'X-Signature' => 'secret-value' })
end
expect(page).to have_link('Edit Secret')
expect(page).to have_content('Webhook Secret has been saved.')
end
it 'removes a secret from the webhook' do
@ -113,5 +159,43 @@ RSpec.describe 'Webhook Settings' do
expect(webhook_url.secret).to eq({})
end
expect(page).to have_link('Add Secret')
expect(page).to have_content('Webhook Secret has been saved.')
end
context 'when testing the webhook' do
let!(:webhook_url) { create(:webhook_url, account:) }
let!(:template) { create(:template, account:, author: user) }
let!(:submission) { create(:submission, template:, created_by_user: user) }
let!(:submitter) do
create(:submitter, submission:, uuid: template.submitters.first['uuid'], completed_at: Time.current)
end
it 'sends the webhook request' do
visit settings_webhooks_path
expect do
click_button 'Test Webhook'
end.to change(SendFormCompletedWebhookRequestJob.jobs, :size).by(1)
args = SendFormCompletedWebhookRequestJob.jobs.last['args'].first
expect(args['webhook_url_id']).to eq(webhook_url.id)
expect(args['submitter_id']).to eq(submitter.id)
expect(page).to have_content('Webhook request has been sent.')
end
it "doesn't resend the webhook request when the webhook is doesn't exist" do
visit settings_webhooks_path
webhook_url.destroy
expect do
click_button 'Test Webhook'
end.not_to change(SendFormCompletedWebhookRequestJob.jobs, :size)
expect(page).to have_content('Unable to resend webhook request.')
end
end
end

Loading…
Cancel
Save