mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
6. Add webhook endpoints to user developer settings screen
Allowing creation and deleting via the user association. It probably won't be much effort to allow editing and multiple records, but I cut it down to the minimum needed to avoid any further delays. I couldn't find a way to test a failure in the destroy method, but decided to keep the condition because I thought it was worth having.
This commit is contained in:
47
app/controllers/webhook_endpoints_controller.rb
Normal file
47
app/controllers/webhook_endpoints_controller.rb
Normal file
@@ -0,0 +1,47 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class WebhookEndpointsController < ::BaseController
|
||||
before_action :load_resource, only: :destroy
|
||||
|
||||
def create
|
||||
webhook_endpoint = spree_current_user.webhook_endpoints.new(webhook_endpoint_params)
|
||||
|
||||
if webhook_endpoint.save
|
||||
flash[:success] = t('.success')
|
||||
else
|
||||
flash[:error] = t('.error')
|
||||
end
|
||||
|
||||
redirect_to redirect_path
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @webhook_endpoint.destroy
|
||||
flash[:success] = t('.success')
|
||||
else
|
||||
flash[:error] = t('.error')
|
||||
end
|
||||
|
||||
redirect_to redirect_path
|
||||
end
|
||||
|
||||
def load_resource
|
||||
@webhook_endpoint = spree_current_user.webhook_endpoints.find(params[:id])
|
||||
end
|
||||
|
||||
def webhook_endpoint_params
|
||||
params.require(:webhook_endpoint).permit(:url)
|
||||
end
|
||||
|
||||
def redirect_path
|
||||
if request.referer.blank? || request.referer.include?(spree.account_path)
|
||||
developer_settings_path
|
||||
else
|
||||
request.referer
|
||||
end
|
||||
end
|
||||
|
||||
def developer_settings_path
|
||||
"#{spree.account_path}#/developer_settings"
|
||||
end
|
||||
end
|
||||
@@ -41,6 +41,7 @@ module Spree
|
||||
has_many :webhook_endpoints, dependent: :destroy
|
||||
|
||||
accepts_nested_attributes_for :enterprise_roles, allow_destroy: true
|
||||
accepts_nested_attributes_for :webhook_endpoints
|
||||
|
||||
accepts_nested_attributes_for :bill_address
|
||||
accepts_nested_attributes_for :ship_address
|
||||
|
||||
@@ -15,7 +15,10 @@ module PermittedAttributes
|
||||
private
|
||||
|
||||
def permitted_attributes
|
||||
[:email, :password, :password_confirmation, :disabled]
|
||||
[
|
||||
:email, :password, :password_confirmation, :disabled,
|
||||
{ webhook_endpoints_attributes: [:id, :url] },
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
%script{ type: "text/ng-template", id: "account/developer_settings.html" }
|
||||
%h3= t('.title')
|
||||
= render partial: 'api_keys'
|
||||
= render partial: 'webhook_endpoints'
|
||||
|
||||
33
app/views/spree/users/_webhook_endpoints.html.haml
Normal file
33
app/views/spree/users/_webhook_endpoints.html.haml
Normal file
@@ -0,0 +1,33 @@
|
||||
%section{ id: "webhook_endpoints" }
|
||||
%hr
|
||||
%h3= t('.title')
|
||||
%p= t('.description')
|
||||
|
||||
%table{width: "100%"}
|
||||
%thead
|
||||
%tr
|
||||
%th= t('.event_type.header')
|
||||
%th= t('.url.header')
|
||||
%th.actions
|
||||
%tbody
|
||||
-# Existing endpoints
|
||||
- @user.webhook_endpoints.each do |webhook_endpoint|
|
||||
%tr
|
||||
%td= t('.event_types.order_cycle_opened') # For now, we only support one type.
|
||||
%td= webhook_endpoint.url
|
||||
%td.actions
|
||||
- if webhook_endpoint.persisted?
|
||||
= button_to account_webhook_endpoint_path(webhook_endpoint), method: :delete,
|
||||
class: "tiny alert no-margin",
|
||||
data: { confirm: I18n.t(:are_you_sure)} do
|
||||
= I18n.t(:delete)
|
||||
|
||||
-# Create new
|
||||
- if @user.webhook_endpoints.empty? # Only one allowed for now.
|
||||
%tr
|
||||
%td= t('.event_types.order_cycle_opened') # For now, we only support one type.
|
||||
%td
|
||||
= form_for(@user.webhook_endpoints.build, url: account_webhook_endpoints_path, id: 'new_webhook_endpoint') do |f|
|
||||
= f.url_field :url, placeholder: t('.url.create_placeholder'), required: true, size: 64
|
||||
%td.actions
|
||||
= button_tag t(:create), class: 'button primary tiny no-margin', form: 'new_webhook_endpoint'
|
||||
@@ -3562,6 +3562,14 @@ See the %{link} to find out more about %{sitename}'s features and to start using
|
||||
previous: "Previous"
|
||||
last: "Last"
|
||||
|
||||
webhook_endpoints:
|
||||
create:
|
||||
success: Webhook endpoint successfully created
|
||||
error: Webhook endpoint failed to create
|
||||
destroy:
|
||||
success: Webhook endpoint successfully deleted
|
||||
error: Webhook endpoint failed to delete
|
||||
|
||||
spree:
|
||||
order_updated: "Order Updated"
|
||||
add_country: "Add country"
|
||||
@@ -4357,6 +4365,16 @@ See the %{link} to find out more about %{sitename}'s features and to start using
|
||||
api_keys:
|
||||
regenerate_key: "Regenerate Key"
|
||||
title: API key
|
||||
webhook_endpoints:
|
||||
title: Webhook Endpoints
|
||||
description: Events in the system may trigger webhooks to external systems.
|
||||
event_types:
|
||||
order_cycle_opened: Order Cycle Opened
|
||||
event_type:
|
||||
header: Event type
|
||||
url:
|
||||
header: Endpoint URL
|
||||
create_placeholder: Enter the URL of the remote webhook endpoint
|
||||
developer_settings:
|
||||
title: Developer Settings
|
||||
form:
|
||||
|
||||
@@ -32,7 +32,9 @@ Spree::Core::Engine.routes.draw do
|
||||
put '/password/change' => 'user_passwords#update', :as => :update_password
|
||||
end
|
||||
|
||||
resource :account, :controller => 'users'
|
||||
resource :account, :controller => 'users' do
|
||||
resources :webhook_endpoints, only: [:create, :destroy], controller: '/webhook_endpoints'
|
||||
end
|
||||
|
||||
match '/admin/orders/bulk_management' => 'admin/orders#bulk_management', :as => "admin_bulk_order_management", via: :get
|
||||
match '/admin/payment_methods/show_provider_preferences' => 'admin/payment_methods#show_provider_preferences', :via => :get
|
||||
|
||||
67
spec/controllers/webhook_endpoints_controller_spec.rb
Normal file
67
spec/controllers/webhook_endpoints_controller_spec.rb
Normal file
@@ -0,0 +1,67 @@
|
||||
# frozen_string_literal: false
|
||||
|
||||
require 'spec_helper'
|
||||
require 'open_food_network/order_cycle_permissions'
|
||||
|
||||
describe WebhookEndpointsController, type: :controller do
|
||||
let(:user) { create(:admin_user) }
|
||||
|
||||
before { allow(controller).to receive(:spree_current_user) { user } }
|
||||
|
||||
describe "#create" do
|
||||
it "creates a webhook_endpoint" do
|
||||
expect {
|
||||
spree_post :create, { url: "https://url" }
|
||||
}.to change {
|
||||
user.webhook_endpoints.count
|
||||
}.by(1)
|
||||
|
||||
expect(flash[:success]).to be_present
|
||||
expect(flash[:error]).to be_blank
|
||||
expect(user.webhook_endpoints.first.url).to eq "https://url"
|
||||
end
|
||||
|
||||
it "shows error if parameters not specified" do
|
||||
expect {
|
||||
spree_post :create, { url: "" }
|
||||
}.to_not change {
|
||||
user.webhook_endpoints.count
|
||||
}
|
||||
|
||||
expect(flash[:success]).to be_blank
|
||||
expect(flash[:error]).to be_present
|
||||
end
|
||||
|
||||
it "redirects back to referrer" do
|
||||
spree_post :create, { url: "https://url" }
|
||||
|
||||
expect(response).to redirect_to "/account#/developer_settings"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#destroy" do
|
||||
let!(:webhook_endpoint) { user.webhook_endpoints.create(url: "https://url") }
|
||||
|
||||
it "destroys a webhook_endpoint" do
|
||||
webhook_endpoint2 = user.webhook_endpoints.create!(url: "https://url2")
|
||||
|
||||
expect {
|
||||
spree_delete :destroy, { id: webhook_endpoint.id }
|
||||
}.to change {
|
||||
user.webhook_endpoints.count
|
||||
}.by(-1)
|
||||
|
||||
expect(flash[:success]).to be_present
|
||||
expect(flash[:error]).to be_blank
|
||||
|
||||
expect{ webhook_endpoint.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
||||
expect(webhook_endpoint2.reload).to be_present
|
||||
end
|
||||
|
||||
it "redirects back to developer settings tab" do
|
||||
spree_delete :destroy, id: webhook_endpoint.id
|
||||
|
||||
expect(response).to redirect_to "/account#/developer_settings"
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -35,6 +35,22 @@ describe "Developer Settings" do
|
||||
expect(page).to have_content "Key generated"
|
||||
expect(page).to have_input "api_key", with: user.reload.spree_api_key
|
||||
end
|
||||
|
||||
describe "Webhook Endpoints" do
|
||||
it "creates a new webhook endpoint and deletes it" do
|
||||
within "#webhook_endpoints" do
|
||||
fill_in "webhook_endpoint_url", with: "https://url"
|
||||
|
||||
click_button I18n.t(:create)
|
||||
expect(page.document).to have_content I18n.t('webhook_endpoints.create.success')
|
||||
expect(page).to have_content "https://url"
|
||||
|
||||
click_button I18n.t(:delete)
|
||||
expect(page.document).to have_content I18n.t('webhook_endpoints.destroy.success')
|
||||
expect(page).to_not have_content "https://url"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user