From 29c2c2b92ad70b59b20e9c5e716da3c4a607340d Mon Sep 17 00:00:00 2001 From: Eugene Chaikin Date: Mon, 30 Jun 2025 16:22:08 +0200 Subject: [PATCH 01/16] Update payment_methods_controller.rb Inherit from resources controller, define necessary overriding methods. We also do not need #index and #destroy actions other than the ones defined on the ResourcesController. --- .../payment_methods_controller.rb | 26 ++++++------------- 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/admin/app/controllers/solidus_admin/payment_methods_controller.rb b/admin/app/controllers/solidus_admin/payment_methods_controller.rb index cb2b213003b..36db482a969 100644 --- a/admin/app/controllers/solidus_admin/payment_methods_controller.rb +++ b/admin/app/controllers/solidus_admin/payment_methods_controller.rb @@ -1,8 +1,7 @@ # frozen_string_literal: true module SolidusAdmin - class PaymentMethodsController < SolidusAdmin::BaseController - include SolidusAdmin::ControllerHelpers::Search + class PaymentMethodsController < SolidusAdmin::ResourcesController include SolidusAdmin::Moveable search_scope(:all) @@ -11,26 +10,17 @@ class PaymentMethodsController < SolidusAdmin::BaseController search_scope(:storefront, &:available_to_users) search_scope(:admin, &:available_to_admin) - def index - payment_methods = apply_search_to( - Spree::PaymentMethod.ordered_by_position, - param: :q - ) + private - set_page_and_extract_portion_from(payment_methods) + def resource_class = Spree::PaymentMethod - respond_to do |format| - format.html { render component("payment_methods/index").new(page: @page) } - end - end - - def destroy - @payment_methods = Spree::PaymentMethod.where(id: params[:id]) + def resources_collection = resource_class.all - Spree::PaymentMethod.transaction { @payment_methods.destroy_all } + def resources_sorting_options = {position: :asc} - flash[:notice] = t(".success") - redirect_back_or_to payment_methods_path, status: :see_other + def permitted_resource_params + params.require(:payment_method).permit(:name, :description, :auto_capture, :type, :preference_source, + :preferred_server, :preferred_test_mode, :active, :available_to_admin, :available_to_users, store_ids: []) end end end From 40b618ab694dc89787986986a077923e15dc9b57 Mon Sep 17 00:00:00 2001 From: Eugene Chaikin Date: Mon, 30 Jun 2025 16:27:20 +0200 Subject: [PATCH 02/16] Update payment methods index component Render links in the table. --- .../solidus_admin/payment_methods/index/component.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/admin/app/components/solidus_admin/payment_methods/index/component.rb b/admin/app/components/solidus_admin/payment_methods/index/component.rb index aadf5f08487..478eef42631 100644 --- a/admin/app/components/solidus_admin/payment_methods/index/component.rb +++ b/admin/app/components/solidus_admin/payment_methods/index/component.rb @@ -59,13 +59,13 @@ def columns { header: :name, data: ->(payment_method) do - content_tag :div, payment_method.name + link_to payment_method.name, row_url(payment_method), class: "body-link" end }, { header: :type, data: ->(payment_method) do - content_tag :div, payment_method.model_name.human + link_to payment_method.model_name.human, row_url(payment_method), class: "body-link" end }, { From 520a1057c5e0ace2180690315f6f2aa5b85ba281 Mon Sep 17 00:00:00 2001 From: Eugene Chaikin Date: Mon, 30 Jun 2025 16:31:25 +0200 Subject: [PATCH 03/16] Request confirmation when deleting payment methods --- .../solidus_admin/payment_methods/index/component.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/admin/app/components/solidus_admin/payment_methods/index/component.rb b/admin/app/components/solidus_admin/payment_methods/index/component.rb index 478eef42631..da542201848 100644 --- a/admin/app/components/solidus_admin/payment_methods/index/component.rb +++ b/admin/app/components/solidus_admin/payment_methods/index/component.rb @@ -39,7 +39,8 @@ def batch_actions label: t(".batch_actions.delete"), action: solidus_admin.payment_methods_path, method: :delete, - icon: "delete-bin-7-line" + icon: "delete-bin-7-line", + require_confirmation: true } ] end From 52df3758edc37aa6acb78270eee8396ab3baed02 Mon Sep 17 00:00:00 2001 From: Eugene Chaikin Date: Fri, 4 Jul 2025 19:22:45 +0200 Subject: [PATCH 04/16] Create payment method form component --- .../payment_methods/form/component.html.erb | 27 +++++++++++++++++++ .../payment_methods/form/component.rb | 11 ++++++++ .../payment_methods/form/component.yml | 11 ++++++++ 3 files changed, 49 insertions(+) create mode 100644 admin/app/components/solidus_admin/payment_methods/form/component.html.erb create mode 100644 admin/app/components/solidus_admin/payment_methods/form/component.rb create mode 100644 admin/app/components/solidus_admin/payment_methods/form/component.yml diff --git a/admin/app/components/solidus_admin/payment_methods/form/component.html.erb b/admin/app/components/solidus_admin/payment_methods/form/component.html.erb new file mode 100644 index 00000000000..fdc7f1ea1db --- /dev/null +++ b/admin/app/components/solidus_admin/payment_methods/form/component.html.erb @@ -0,0 +1,27 @@ +<%= solidus_form_for @payment_method, as: "payment_method", url: @url, html: { id: @form_id } do |f| %> + <%= page_with_sidebar do %> + <%= page_with_sidebar_main do %> + <%= render component("ui/panel").new do %> + <%= f.text_field :name %> + <%= f.text_field :description %> + <%= f.switch_field :auto_capture, hint: t(".hints.autocapture").html_safe %> + <% end %> + + <%= render component("ui/panel").new(title: t(".deployment")) do %> + <%= f.select :type, Rails.application.config.spree.payment_methods.map { [_1.model_name.human, _1.to_s] } %> + <%= f.select :preference_source, Spree::PaymentMethod.available_preference_sources, include_blank: t(".preference_source_none") %> + <%= f.text_field :preferred_server %> + <%= f.switch_field :preferred_test_mode, hint: t(".hints.test_mode").html_safe %> + <% end %> + <% end %> + + <%= page_with_sidebar_aside do %> + <%= render component("ui/panel").new(title: t(".availability")) do %> + <%= f.checkbox :active %> + <%= f.select :store_ids, Spree::Store.pluck(:name, :id), multiple: true %> + <%= f.checkbox :available_to_admin %> + <%= f.checkbox :available_to_users %> + <% end %> + <% end %> + <% end %> +<% end %> diff --git a/admin/app/components/solidus_admin/payment_methods/form/component.rb b/admin/app/components/solidus_admin/payment_methods/form/component.rb new file mode 100644 index 00000000000..114647b8966 --- /dev/null +++ b/admin/app/components/solidus_admin/payment_methods/form/component.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +class SolidusAdmin::PaymentMethods::Form::Component < SolidusAdmin::BaseComponent + include SolidusAdmin::Layout::PageHelpers + + def initialize(payment_method:, url:, form_id:) + @payment_method = payment_method + @url = url + @form_id = form_id + end +end diff --git a/admin/app/components/solidus_admin/payment_methods/form/component.yml b/admin/app/components/solidus_admin/payment_methods/form/component.yml new file mode 100644 index 00000000000..97e8ed8b578 --- /dev/null +++ b/admin/app/components/solidus_admin/payment_methods/form/component.yml @@ -0,0 +1,11 @@ +en: + availability: "Availability" + deployment: "Deployment" + hints: + autocapture: >- +

Auto-capture setting charges customer's account upon transaction authorization.

+

Enable to reduce manual intervention and streamline the payment process.

+ test_mode: >- +

Payment methods test mode allows users to simulate transactions using dummy data, ensuring the payment gateway's functionality without real transactions.

+

In test mode, users can check if payment methods, such as credit cards or digital wallets, are functioning correctly before going live with real transactions.

+ preference_source_none: "Custom" From 2a16a11ecbdf223fe071abcde5be508cd1d3ba97 Mon Sep 17 00:00:00 2001 From: Eugene Chaikin Date: Fri, 4 Jul 2025 19:23:15 +0200 Subject: [PATCH 05/16] Create component for new payment methods --- .../payment_methods/new/component.html.erb | 19 +++++++++++++++++++ .../payment_methods/new/component.rb | 5 +++++ .../payment_methods/new/component.yml | 5 +++++ 3 files changed, 29 insertions(+) create mode 100644 admin/app/components/solidus_admin/payment_methods/new/component.html.erb create mode 100644 admin/app/components/solidus_admin/payment_methods/new/component.rb create mode 100644 admin/app/components/solidus_admin/payment_methods/new/component.yml diff --git a/admin/app/components/solidus_admin/payment_methods/new/component.html.erb b/admin/app/components/solidus_admin/payment_methods/new/component.html.erb new file mode 100644 index 00000000000..6c2e2c9ecb8 --- /dev/null +++ b/admin/app/components/solidus_admin/payment_methods/new/component.html.erb @@ -0,0 +1,19 @@ + + +<%= page id: :resource_modal do %> + <%= page_header do %> + <%= page_header_back(solidus_admin.payment_methods_path) %> + <%= page_header_title(t(".title")) %> + <%= page_header_actions do %> + <%= render component("ui/button").new( + tag: :a, + text: t(".discard"), + href: solidus_admin.payment_methods_path, + scheme: :secondary + ) %> + <%= render component("ui/button").new(tag: :button, text: t(".save"), form: form_id) %> + <% end %> + <% end %> + + <%= render component("payment_methods/form").new(payment_method: @resource, url: solidus_admin.payment_methods_path, form_id:) %> +<% end %> diff --git a/admin/app/components/solidus_admin/payment_methods/new/component.rb b/admin/app/components/solidus_admin/payment_methods/new/component.rb new file mode 100644 index 00000000000..f384cd56b11 --- /dev/null +++ b/admin/app/components/solidus_admin/payment_methods/new/component.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class SolidusAdmin::PaymentMethods::New::Component < SolidusAdmin::Resources::New::Component + include SolidusAdmin::Layout::PageHelpers +end diff --git a/admin/app/components/solidus_admin/payment_methods/new/component.yml b/admin/app/components/solidus_admin/payment_methods/new/component.yml new file mode 100644 index 00000000000..57197ddaac4 --- /dev/null +++ b/admin/app/components/solidus_admin/payment_methods/new/component.yml @@ -0,0 +1,5 @@ +en: + back: "Back" + discard: "Discard" + save: "Save" + title: "New Payment Method" From f47703bb1c7af41af0d595ac170e691d54ec8e0f Mon Sep 17 00:00:00 2001 From: Eugene Chaikin Date: Fri, 4 Jul 2025 19:23:31 +0200 Subject: [PATCH 06/16] Create component for payment methods edits --- .../payment_methods/edit/component.html.erb | 19 +++++++++++++++++++ .../payment_methods/edit/component.rb | 5 +++++ .../payment_methods/edit/component.yml | 5 +++++ 3 files changed, 29 insertions(+) create mode 100644 admin/app/components/solidus_admin/payment_methods/edit/component.html.erb create mode 100644 admin/app/components/solidus_admin/payment_methods/edit/component.rb create mode 100644 admin/app/components/solidus_admin/payment_methods/edit/component.yml diff --git a/admin/app/components/solidus_admin/payment_methods/edit/component.html.erb b/admin/app/components/solidus_admin/payment_methods/edit/component.html.erb new file mode 100644 index 00000000000..5224b1e50e2 --- /dev/null +++ b/admin/app/components/solidus_admin/payment_methods/edit/component.html.erb @@ -0,0 +1,19 @@ + + +<%= page id: :resource_modal do %> + <%= page_header do %> + <%= page_header_back(solidus_admin.payment_methods_path) %> + <%= page_header_title(t(".title")) %> + <%= page_header_actions do %> + <%= render component("ui/button").new( + tag: :a, + text: t(".discard"), + href: solidus_admin.payment_methods_path, + scheme: :secondary + ) %> + <%= render component("ui/button").new(tag: :button, text: t(".save"), form: form_id) %> + <% end %> + <% end %> + + <%= render component("payment_methods/form").new(payment_method: @resource, url: solidus_admin.payment_method_path(@resource), form_id:) %> +<% end %> diff --git a/admin/app/components/solidus_admin/payment_methods/edit/component.rb b/admin/app/components/solidus_admin/payment_methods/edit/component.rb new file mode 100644 index 00000000000..08034e8db8e --- /dev/null +++ b/admin/app/components/solidus_admin/payment_methods/edit/component.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class SolidusAdmin::PaymentMethods::Edit::Component < SolidusAdmin::Resources::Edit::Component + include SolidusAdmin::Layout::PageHelpers +end diff --git a/admin/app/components/solidus_admin/payment_methods/edit/component.yml b/admin/app/components/solidus_admin/payment_methods/edit/component.yml new file mode 100644 index 00000000000..4a30ee3de6a --- /dev/null +++ b/admin/app/components/solidus_admin/payment_methods/edit/component.yml @@ -0,0 +1,5 @@ +en: + back: "Back" + discard: "Discard" + save: "Save" + title: "Edit Payment Method" From fed2522a79c440a14b5051732a7ebe00117a2524 Mon Sep 17 00:00:00 2001 From: Eugene Chaikin Date: Fri, 4 Jul 2025 19:23:52 +0200 Subject: [PATCH 07/16] Update payment method translation strings --- admin/config/locales/payment_methods.en.yml | 6 +++++- core/config/locales/en.yml | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/admin/config/locales/payment_methods.en.yml b/admin/config/locales/payment_methods.en.yml index c9b1308e35e..53ef2fc2c00 100644 --- a/admin/config/locales/payment_methods.en.yml +++ b/admin/config/locales/payment_methods.en.yml @@ -2,5 +2,9 @@ en: solidus_admin: payment_methods: title: "Payment Methods" + create: + success: "Payment method was successfully created." destroy: - success: "Payment Methods were successfully removed." + success: "Payment methods were successfully removed." + update: + success: "Payment method was successfully updated." diff --git a/core/config/locales/en.yml b/core/config/locales/en.yml index fd2010e341f..91ceee1446c 100644 --- a/core/config/locales/en.yml +++ b/core/config/locales/en.yml @@ -158,6 +158,9 @@ en: display_on: Display name: Name preference_source: Preference Source + preferred_server: Server + preferred_test_mode: Test Mode + store_ids: Stores type: Type spree/price: amount: Price From 900a62d72d07a94addbcd4db30a205c94c1b1347 Mon Sep 17 00:00:00 2001 From: Eugene Chaikin Date: Fri, 4 Jul 2025 19:24:26 +0200 Subject: [PATCH 08/16] Update payment method routes to direct to solidus admin --- admin/config/routes.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/config/routes.rb b/admin/config/routes.rb index 4234dc6af3e..980f41c23bd 100644 --- a/admin/config/routes.rb +++ b/admin/config/routes.rb @@ -77,7 +77,7 @@ admin_resources :promotion_categories, only: [:index, :destroy] admin_resources :tax_categories, except: [:show] admin_resources :tax_rates, except: [:show] - admin_resources :payment_methods, only: [:index, :destroy], sortable: true + admin_resources :payment_methods, except: [:show], sortable: true admin_resources :stock_items, only: [:index, :edit, :update] admin_resources :shipping_methods, only: [:index, :destroy] admin_resources :shipping_categories, except: [:show] From 18cb6c9ee69336e2b9c1db4c1159c07ed8a12539 Mon Sep 17 00:00:00 2001 From: Eugene Chaikin Date: Fri, 4 Jul 2025 19:25:06 +0200 Subject: [PATCH 09/16] Update payment methods index component Removes row_url and replaces it with edit_path and usages of new routing paths. --- .../solidus_admin/payment_methods/index/component.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/admin/app/components/solidus_admin/payment_methods/index/component.rb b/admin/app/components/solidus_admin/payment_methods/index/component.rb index da542201848..2cf57219657 100644 --- a/admin/app/components/solidus_admin/payment_methods/index/component.rb +++ b/admin/app/components/solidus_admin/payment_methods/index/component.rb @@ -13,8 +13,8 @@ def search_url solidus_admin.payment_methods_path end - def row_url(payment_method) - spree.edit_admin_payment_method_path(payment_method) + def edit_path(payment_method) + solidus_admin.edit_payment_method_path(payment_method) end def sortable_options @@ -28,7 +28,7 @@ def page_actions render component("ui/button").new( tag: :a, text: t(".add"), - href: spree.new_admin_payment_method_path, + href: solidus_admin.new_payment_method_path, icon: "add-line" ) end @@ -60,13 +60,13 @@ def columns { header: :name, data: ->(payment_method) do - link_to payment_method.name, row_url(payment_method), class: "body-link" + link_to payment_method.name, edit_path(payment_method), class: "body-link" end }, { header: :type, data: ->(payment_method) do - link_to payment_method.model_name.human, row_url(payment_method), class: "body-link" + link_to payment_method.model_name.human, edit_path(payment_method), class: "body-link" end }, { From cd1cab4cd8e16229d11501493584e363f3b2f559 Mon Sep 17 00:00:00 2001 From: Eugene Chaikin Date: Fri, 4 Jul 2025 20:31:23 +0200 Subject: [PATCH 10/16] Update page with form identifier For validation errors to be shown correctly we need a proper identifier for turbo stream to replace, default one used by resources controller is :resource_modal but this name does not fit for our page so we use a custom name. --- .../solidus_admin/payment_methods/edit/component.html.erb | 4 +--- .../solidus_admin/payment_methods/new/component.html.erb | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/admin/app/components/solidus_admin/payment_methods/edit/component.html.erb b/admin/app/components/solidus_admin/payment_methods/edit/component.html.erb index 5224b1e50e2..1319c32e244 100644 --- a/admin/app/components/solidus_admin/payment_methods/edit/component.html.erb +++ b/admin/app/components/solidus_admin/payment_methods/edit/component.html.erb @@ -1,6 +1,4 @@ - - -<%= page id: :resource_modal do %> +<%= page id: :payment_method_form do %> <%= page_header do %> <%= page_header_back(solidus_admin.payment_methods_path) %> <%= page_header_title(t(".title")) %> diff --git a/admin/app/components/solidus_admin/payment_methods/new/component.html.erb b/admin/app/components/solidus_admin/payment_methods/new/component.html.erb index 6c2e2c9ecb8..fcf0b5417a3 100644 --- a/admin/app/components/solidus_admin/payment_methods/new/component.html.erb +++ b/admin/app/components/solidus_admin/payment_methods/new/component.html.erb @@ -1,6 +1,4 @@ - - -<%= page id: :resource_modal do %> +<%= page id: :payment_method_form do %> <%= page_header do %> <%= page_header_back(solidus_admin.payment_methods_path) %> <%= page_header_title(t(".title")) %> From b4356cb0e45e02a0561edd873b9f784caab59520 Mon Sep 17 00:00:00 2001 From: Eugene Chaikin Date: Fri, 4 Jul 2025 20:40:26 +0200 Subject: [PATCH 11/16] Update payment methods feature tests --- admin/spec/features/payment_methods_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/admin/spec/features/payment_methods_spec.rb b/admin/spec/features/payment_methods_spec.rb index 55c365e046e..4e24fe244ee 100644 --- a/admin/spec/features/payment_methods_spec.rb +++ b/admin/spec/features/payment_methods_spec.rb @@ -41,8 +41,8 @@ expect(page).to be_axe_clean select_row("Check") - click_on "Delete" - expect(page).to have_content("Payment Methods were successfully removed.") + accept_turbo_confirm("Are you sure you want to delete 1 payment method?") { click_on "Delete" } + expect(page).to have_content("Payment methods were successfully removed.") expect(page).not_to have_content("Check") expect(Spree::PaymentMethod.count).to eq(3) end From 3dd646daf792cf90bd27a98455be9d8eb479abcb Mon Sep 17 00:00:00 2001 From: Eugene Chaikin Date: Fri, 4 Jul 2025 21:02:05 +0200 Subject: [PATCH 12/16] Add missing feature tests --- admin/spec/features/payment_methods_spec.rb | 70 +++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/admin/spec/features/payment_methods_spec.rb b/admin/spec/features/payment_methods_spec.rb index 4e24fe244ee..d37183dbf80 100644 --- a/admin/spec/features/payment_methods_spec.rb +++ b/admin/spec/features/payment_methods_spec.rb @@ -52,4 +52,74 @@ let(:displayed_attribute) { :name } let(:path) { solidus_admin.payment_methods_path } end + + context "creating payment method" do + before { create(:store, name: "Store") } + context "with valid attributes" do + it "creates payment method" do + visit "/admin/payment_methods" + click_on "Add new" + + expect(page).to have_current_path("/admin/payment_methods/new") + expect(page).to be_axe_clean + + fill_in "Name", with: "Checking" + fill_in "Description", with: "Payment Method Description" + switch "Auto Capture" + solidus_select "Check Payments", from: "Type" + fill_in "Server", with: "test" + switch "Test Mode" + check "Active" + solidus_select("Store", from: "Stores") + check "Available to Admin" + check "Available to Users" + + click_on "Save" + + expect(page).to have_content("Payment method was successfully created.") + expect(page).to have_content("Checking") + expect(page).to have_content("Check Payments") + end + end + + context "with invalid attributes" do + it "shows validation errors" do + visit "/admin/payment_methods" + click_on "Add new" + click_on "Save" + expect(page).to have_content("can't be blank") + end + end + end + + context "updating payment method" do + before { create(:payment_method, name: "Check payments") } + + context "with valid attributes" do + it "updates payment method" do + visit "/admin/payment_methods" + click_on "Check payments" + + fill_in "Name", with: "Checking payments" + solidus_select "Check Payments", from: "Type" + click_on "Save" + + expect(page).to have_content("Payment method was successfully updated.") + expect(page).to have_content("Checking payments") + expect(page).to have_content("Check Payments") + end + end + + context "with invalid attributes" do + it "shows validation errors" do + visit "/admin/payment_methods" + click_on "Check payments" + + fill_in "Name", with: "" + click_on "Save" + + expect(page).to have_content("can't be blank") + end + end + end end From cd74f6f7e4b1d7f2660e187b2b89991cbd0fe2b9 Mon Sep 17 00:00:00 2001 From: Eugene Chaikin Date: Fri, 4 Jul 2025 21:11:05 +0200 Subject: [PATCH 13/16] Add request tests --- admin/spec/requests/solidus_admin/payment_methods_spec.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/admin/spec/requests/solidus_admin/payment_methods_spec.rb b/admin/spec/requests/solidus_admin/payment_methods_spec.rb index 5cc99dae2ab..6505bc0678a 100644 --- a/admin/spec/requests/solidus_admin/payment_methods_spec.rb +++ b/admin/spec/requests/solidus_admin/payment_methods_spec.rb @@ -2,10 +2,17 @@ require "spec_helper" require "solidus_admin/testing_support/shared_examples/moveable" +require "solidus_admin/testing_support/shared_examples/crud_resource_requests" RSpec.describe "SolidusAdmin::PaymentMethodsController", type: :request do it_behaves_like "requests: moveable" do let(:factory) { :payment_method } let(:request_path) { solidus_admin.move_payment_method_path(record, format: :js) } end + + include_examples "CRUD resource requests", "payment_method" do + let(:resource_class) { Spree::PaymentMethod } + let(:valid_attributes) { {name: "Credit Card", type: "Spree::PaymentMethod::BogusCreditCard"} } + let(:invalid_attributes) { {name: "", type: ""} } + end end From 04f9aa93b5b87c6457f7908bf0554a742f2020eb Mon Sep 17 00:00:00 2001 From: benjamin wil Date: Tue, 15 Sep 2026 13:51:18 -0700 Subject: [PATCH 14/16] Resolve issues with payment methods forms, i18n The HTML IDs were incorrect. While I was making this change I saw opportunities to reduce the complexity of the component templates and reduce the need generic translation strings at the component level. --- .../payment_methods/edit/component.html.erb | 13 ++++--------- .../solidus_admin/payment_methods/edit/component.rb | 2 ++ .../payment_methods/edit/component.yml | 3 --- .../payment_methods/new/component.html.erb | 13 ++++--------- .../solidus_admin/payment_methods/new/component.rb | 2 ++ .../solidus_admin/payment_methods/new/component.yml | 3 --- 6 files changed, 12 insertions(+), 24 deletions(-) diff --git a/admin/app/components/solidus_admin/payment_methods/edit/component.html.erb b/admin/app/components/solidus_admin/payment_methods/edit/component.html.erb index 1319c32e244..c299cf773e0 100644 --- a/admin/app/components/solidus_admin/payment_methods/edit/component.html.erb +++ b/admin/app/components/solidus_admin/payment_methods/edit/component.html.erb @@ -1,15 +1,10 @@ -<%= page id: :payment_method_form do %> +<%= page id: :resource_form do %> <%= page_header do %> - <%= page_header_back(solidus_admin.payment_methods_path) %> + <%= page_header_back(back_url) %> <%= page_header_title(t(".title")) %> <%= page_header_actions do %> - <%= render component("ui/button").new( - tag: :a, - text: t(".discard"), - href: solidus_admin.payment_methods_path, - scheme: :secondary - ) %> - <%= render component("ui/button").new(tag: :button, text: t(".save"), form: form_id) %> + <%= render component("ui/button").discard(path: back_url) %> + <%= render component("ui/button").save(form: form_id) %> <% end %> <% end %> diff --git a/admin/app/components/solidus_admin/payment_methods/edit/component.rb b/admin/app/components/solidus_admin/payment_methods/edit/component.rb index 08034e8db8e..909c32b26da 100644 --- a/admin/app/components/solidus_admin/payment_methods/edit/component.rb +++ b/admin/app/components/solidus_admin/payment_methods/edit/component.rb @@ -2,4 +2,6 @@ class SolidusAdmin::PaymentMethods::Edit::Component < SolidusAdmin::Resources::Edit::Component include SolidusAdmin::Layout::PageHelpers + + def back_url = solidus_admin.payment_methods_path end diff --git a/admin/app/components/solidus_admin/payment_methods/edit/component.yml b/admin/app/components/solidus_admin/payment_methods/edit/component.yml index 4a30ee3de6a..49390bdfcd6 100644 --- a/admin/app/components/solidus_admin/payment_methods/edit/component.yml +++ b/admin/app/components/solidus_admin/payment_methods/edit/component.yml @@ -1,5 +1,2 @@ en: - back: "Back" - discard: "Discard" - save: "Save" title: "Edit Payment Method" diff --git a/admin/app/components/solidus_admin/payment_methods/new/component.html.erb b/admin/app/components/solidus_admin/payment_methods/new/component.html.erb index fcf0b5417a3..32c6fe90029 100644 --- a/admin/app/components/solidus_admin/payment_methods/new/component.html.erb +++ b/admin/app/components/solidus_admin/payment_methods/new/component.html.erb @@ -1,15 +1,10 @@ -<%= page id: :payment_method_form do %> +<%= page id: :resource_form do %> <%= page_header do %> - <%= page_header_back(solidus_admin.payment_methods_path) %> + <%= page_header_back(back_url) %> <%= page_header_title(t(".title")) %> <%= page_header_actions do %> - <%= render component("ui/button").new( - tag: :a, - text: t(".discard"), - href: solidus_admin.payment_methods_path, - scheme: :secondary - ) %> - <%= render component("ui/button").new(tag: :button, text: t(".save"), form: form_id) %> + <%= render component("ui/button").discard(path: back_url) %> + <%= render component("ui/button").save(form: form_id) %> <% end %> <% end %> diff --git a/admin/app/components/solidus_admin/payment_methods/new/component.rb b/admin/app/components/solidus_admin/payment_methods/new/component.rb index f384cd56b11..8ad6be786d7 100644 --- a/admin/app/components/solidus_admin/payment_methods/new/component.rb +++ b/admin/app/components/solidus_admin/payment_methods/new/component.rb @@ -2,4 +2,6 @@ class SolidusAdmin::PaymentMethods::New::Component < SolidusAdmin::Resources::New::Component include SolidusAdmin::Layout::PageHelpers + + def back_url = solidus_admin.payment_methods_path end diff --git a/admin/app/components/solidus_admin/payment_methods/new/component.yml b/admin/app/components/solidus_admin/payment_methods/new/component.yml index 57197ddaac4..176ffc14cc0 100644 --- a/admin/app/components/solidus_admin/payment_methods/new/component.yml +++ b/admin/app/components/solidus_admin/payment_methods/new/component.yml @@ -1,5 +1,2 @@ en: - back: "Back" - discard: "Discard" - save: "Save" title: "New Payment Method" From e2f9ebb7def84f81d36c5f87b4ba196365df59a9 Mon Sep 17 00:00:00 2001 From: benjamin wil Date: Tue, 15 Sep 2026 15:37:49 -0700 Subject: [PATCH 15/16] Flag the payment methods UI as an alpha feature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based on Jared Norman's review, the work done so far on the payment methods editor is missing a lot of functionality: > 1. I don't think validation errors are showing up. > 2. This doesn't render controls for additional preferences on the > payment methods, making it kind of useless for many payment > methods. > 3. Auto-capture is (sadly) not boolean. Null means something (use > store default) and we should let people select that. > 4. When a preference source is chosen, the server/test-mode still > looks editable even though changes to those are ignored. That's > not a great user experience. > 5. Probably should sort gateway types in alphabetically or something. > 6. Changing a payment method's type on update doesn't convert the > record to the new class the way the old admin did. > 7. New records no longer preselect the default store. ☹️ > 8. We should use the shared discard and save button helpers and drop > the unused translation keys, and name the HTML hint translations > with the _html suffix instead of calling html_safe. > 9. I think the description a text area. > 10. Can we pull the store and type queries out of the template? > 11. We should use the payment method's name as the edit page title. I don't want to tackle all of this in a single pull request, though I think it's all necessary changes to the functionality. Using the alpha features flag lets us work more iteratively over this. --- admin/config/routes.rb | 6 +++++- admin/spec/features/payment_methods_spec.rb | 5 ++++- admin/spec/requests/solidus_admin/payment_methods_spec.rb | 4 ++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/admin/config/routes.rb b/admin/config/routes.rb index 980f41c23bd..8e565deb1e3 100644 --- a/admin/config/routes.rb +++ b/admin/config/routes.rb @@ -47,6 +47,11 @@ end end + admin_resources :payment_methods, + constraints: -> { SolidusAdmin::Config.enable_alpha_features? }, + except: [:show], + sortable: true + admin_resources :users, only: [:index, :edit, :destroy] do member do get :addresses @@ -77,7 +82,6 @@ admin_resources :promotion_categories, only: [:index, :destroy] admin_resources :tax_categories, except: [:show] admin_resources :tax_rates, except: [:show] - admin_resources :payment_methods, except: [:show], sortable: true admin_resources :stock_items, only: [:index, :edit, :update] admin_resources :shipping_methods, only: [:index, :destroy] admin_resources :shipping_categories, except: [:show] diff --git a/admin/spec/features/payment_methods_spec.rb b/admin/spec/features/payment_methods_spec.rb index d37183dbf80..1cf02d2f8e3 100644 --- a/admin/spec/features/payment_methods_spec.rb +++ b/admin/spec/features/payment_methods_spec.rb @@ -4,7 +4,10 @@ require "solidus_admin/testing_support/shared_examples/moveable" describe "Payment Methods", :js, type: :feature do - before { sign_in create(:admin_user, email: "admin@example.com") } + before do + allow(SolidusAdmin::Config).to receive(:enable_alpha_features?).and_return(true) + sign_in create(:admin_user, email: "admin@example.com") + end it "lists users and allows deleting them" do create(:check_payment_method, name: "Check", active: true) diff --git a/admin/spec/requests/solidus_admin/payment_methods_spec.rb b/admin/spec/requests/solidus_admin/payment_methods_spec.rb index 6505bc0678a..a7d5b55a057 100644 --- a/admin/spec/requests/solidus_admin/payment_methods_spec.rb +++ b/admin/spec/requests/solidus_admin/payment_methods_spec.rb @@ -5,6 +5,10 @@ require "solidus_admin/testing_support/shared_examples/crud_resource_requests" RSpec.describe "SolidusAdmin::PaymentMethodsController", type: :request do + before do + allow(SolidusAdmin::Config).to receive(:enable_alpha_features?).and_return(true) + end + it_behaves_like "requests: moveable" do let(:factory) { :payment_method } let(:request_path) { solidus_admin.move_payment_method_path(record, format: :js) } From bb27342b3de18e504254942a738985ee5220090e Mon Sep 17 00:00:00 2001 From: benjamin wil Date: Tue, 15 Sep 2026 16:37:21 -0700 Subject: [PATCH 16/16] Extract SQL queries from form component template This was bad form, no pun intended. --- .../payment_methods/form/component.html.erb | 6 +- .../payment_methods/form/component.rb | 12 ++++ .../payment_methods/form/component_spec.rb | 69 +++++++++++++++++++ 3 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 admin/spec/components/solidus_admin/payment_methods/form/component_spec.rb diff --git a/admin/app/components/solidus_admin/payment_methods/form/component.html.erb b/admin/app/components/solidus_admin/payment_methods/form/component.html.erb index fdc7f1ea1db..92e5260415d 100644 --- a/admin/app/components/solidus_admin/payment_methods/form/component.html.erb +++ b/admin/app/components/solidus_admin/payment_methods/form/component.html.erb @@ -8,8 +8,8 @@ <% end %> <%= render component("ui/panel").new(title: t(".deployment")) do %> - <%= f.select :type, Rails.application.config.spree.payment_methods.map { [_1.model_name.human, _1.to_s] } %> - <%= f.select :preference_source, Spree::PaymentMethod.available_preference_sources, include_blank: t(".preference_source_none") %> + <%= f.select :type, available_types.map { [_1.model_name.human, _1.to_s] } %> + <%= f.select :preference_source, available_preference_sources, include_blank: t(".preference_source_none") %> <%= f.text_field :preferred_server %> <%= f.switch_field :preferred_test_mode, hint: t(".hints.test_mode").html_safe %> <% end %> @@ -18,7 +18,7 @@ <%= page_with_sidebar_aside do %> <%= render component("ui/panel").new(title: t(".availability")) do %> <%= f.checkbox :active %> - <%= f.select :store_ids, Spree::Store.pluck(:name, :id), multiple: true %> + <%= f.select :store_ids, store_select_values, multiple: true %> <%= f.checkbox :available_to_admin %> <%= f.checkbox :available_to_users %> <% end %> diff --git a/admin/app/components/solidus_admin/payment_methods/form/component.rb b/admin/app/components/solidus_admin/payment_methods/form/component.rb index 114647b8966..5c937dd2b79 100644 --- a/admin/app/components/solidus_admin/payment_methods/form/component.rb +++ b/admin/app/components/solidus_admin/payment_methods/form/component.rb @@ -8,4 +8,16 @@ def initialize(payment_method:, url:, form_id:) @url = url @form_id = form_id end + + def available_preference_sources + Spree::PaymentMethod.available_preference_sources + end + + def available_types + Rails.application.config.spree.payment_methods.sort_by(&:name) + end + + def store_select_values + Spree::Store.pluck(:name, :id) + end end diff --git a/admin/spec/components/solidus_admin/payment_methods/form/component_spec.rb b/admin/spec/components/solidus_admin/payment_methods/form/component_spec.rb new file mode 100644 index 00000000000..457f8251602 --- /dev/null +++ b/admin/spec/components/solidus_admin/payment_methods/form/component_spec.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe SolidusAdmin::PaymentMethods::Form::Component, type: :component do + let(:component) { + described_class.new payment_method: create(:payment_method), + url: "/test-url", + form_id: "test-form-id" + } + + describe "#available_preference_sources" do + subject { component.available_preference_sources } + + it "requests available sources from Spree::PaymentMethod" do + allow(Spree::PaymentMethod).to receive(:available_preference_sources) + + subject + + expect(Spree::PaymentMethod) + .to have_received(:available_preference_sources) + .once + end + end + + describe ".available_types" do + subject { component.available_types } + + let(:fake_payment_methods_set) { + Spree::Core::ClassConstantizer::Set.new( + default: [ + "Spree::PaymentMethod::CreditCard", + "Spree::PaymentMethod::Check" + ] + ) + } + let(:fake_subconfig) { double(payment_methods: fake_payment_methods_set) } + + before do + allow(Rails.application) + .to receive(:config) + .and_return(double(spree: fake_subconfig)) + end + + it "requests available payment method types from the Rails application configuration", :aggregate_failures do + subject + + expect(Rails.application).to have_received(:config).once + expect(fake_subconfig).to have_received(:payment_methods).once + end + + it "sorts the available payment method types by name" do + expect(subject).to eq [ + Spree::PaymentMethod::Check, + Spree::PaymentMethod::CreditCard + ] + end + end + + describe "#store_select_values" do + subject { component.store_select_values } + + let!(:store) { create :store, name: "Selectable Store" } + + it "gets all store name and IDs for a form