diff --git a/admin/app/controllers/concerns/solidus_admin/moveable.rb b/admin/app/controllers/concerns/solidus_admin/moveable.rb new file mode 100644 index 00000000000..a1f3756d0de --- /dev/null +++ b/admin/app/controllers/concerns/solidus_admin/moveable.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +module SolidusAdmin::Moveable + extend ActiveSupport::Concern + + included do + before_action :load_moveable, only: [:move] + end + + def move + @moveable.insert_at(params.require(:position).to_i) + + respond_to do |format| + format.js { head :no_content } + end + end + + private + + def load_moveable + @moveable = moveable_class.find(params.require(:id)) + authorize! action_name, @moveable + end + + def moveable_class + "Spree::#{self.class.name.demodulize.remove('Controller').singularize}".constantize + rescue NameError + raise NameError, + "could not infer model class from #{self.class.name}. Please override `moveable_class` to specify it explicitly." + end +end diff --git a/admin/app/controllers/solidus_admin/option_types_controller.rb b/admin/app/controllers/solidus_admin/option_types_controller.rb index 444f1bbbafa..18b9ce8f1df 100644 --- a/admin/app/controllers/solidus_admin/option_types_controller.rb +++ b/admin/app/controllers/solidus_admin/option_types_controller.rb @@ -3,8 +3,7 @@ module SolidusAdmin class OptionTypesController < SolidusAdmin::BaseController include SolidusAdmin::ControllerHelpers::Search - - before_action :load_option_type, only: [:move] + include SolidusAdmin::Moveable def index option_types = apply_search_to( @@ -19,14 +18,6 @@ def index end end - def move - @option_type.insert_at(params[:position].to_i) - - respond_to do |format| - format.js { head :no_content } - end - end - def destroy @option_types = Spree::OptionType.where(id: params[:id]) @@ -35,12 +26,5 @@ def destroy flash[:notice] = t('.success') redirect_back_or_to option_types_path, status: :see_other end - - private - - def load_option_type - @option_type = Spree::OptionType.find(params[:id]) - authorize! action_name, @option_type - end end end diff --git a/admin/app/controllers/solidus_admin/payment_methods_controller.rb b/admin/app/controllers/solidus_admin/payment_methods_controller.rb index 684eb7381f3..fc3ce0316dd 100644 --- a/admin/app/controllers/solidus_admin/payment_methods_controller.rb +++ b/admin/app/controllers/solidus_admin/payment_methods_controller.rb @@ -3,8 +3,7 @@ module SolidusAdmin class PaymentMethodsController < SolidusAdmin::BaseController include SolidusAdmin::ControllerHelpers::Search - - before_action :load_payment_method, only: [:move] + include SolidusAdmin::Moveable search_scope(:all) search_scope(:active, default: true, &:active) @@ -25,14 +24,6 @@ def index end end - def move - @payment_method.insert_at(params[:position].to_i) - - respond_to do |format| - format.js { head :no_content } - end - end - def destroy @payment_methods = Spree::PaymentMethod.where(id: params[:id]) @@ -41,12 +32,5 @@ def destroy flash[:notice] = t('.success') redirect_back_or_to payment_methods_path, status: :see_other end - - private - - def load_payment_method - @payment_method = Spree::PaymentMethod.find_by!(id: params[:id]) - authorize! action_name, @payment_method - end end end diff --git a/admin/app/controllers/solidus_admin/taxonomies_controller.rb b/admin/app/controllers/solidus_admin/taxonomies_controller.rb index fb0387d075a..3c6b4cdc2db 100644 --- a/admin/app/controllers/solidus_admin/taxonomies_controller.rb +++ b/admin/app/controllers/solidus_admin/taxonomies_controller.rb @@ -3,8 +3,7 @@ module SolidusAdmin class TaxonomiesController < SolidusAdmin::BaseController include SolidusAdmin::ControllerHelpers::Search - - before_action :load_taxonomy, only: [:move] + include SolidusAdmin::Moveable def index taxonomies = apply_search_to( @@ -19,14 +18,6 @@ def index end end - def move - @taxonomy.insert_at(params[:position].to_i) - - respond_to do |format| - format.js { head :no_content } - end - end - def destroy @taxonomies = Spree::Taxonomy.where(id: params[:id]) @@ -35,12 +26,5 @@ def destroy flash[:notice] = t('.success') redirect_back_or_to taxonomies_path, status: :see_other end - - private - - def load_taxonomy - @taxonomy = Spree::Taxonomy.find(params[:id]) - authorize! action_name, @taxonomy - end end end diff --git a/admin/lib/solidus_admin/testing_support/shared_examples/moveable.rb b/admin/lib/solidus_admin/testing_support/shared_examples/moveable.rb new file mode 100644 index 00000000000..a321ea5faa4 --- /dev/null +++ b/admin/lib/solidus_admin/testing_support/shared_examples/moveable.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +RSpec.shared_examples_for "requests: moveable" do + let(:admin_user) { create(:admin_user) } + let(:record) { create(factory, position: 1) } + let(:request_path) do + solidus_admin.send("move_#{record.model_name.singular_route_key}_path", record, format: :js) + end + + before do + allow_any_instance_of(SolidusAdmin::BaseController).to receive(:spree_current_user).and_return(admin_user) + end + + describe "PATCH /move" do + it "updates record's position" do + expect { patch request_path, params: { position: 2 } }.to change { record.reload.position }.from(1).to(2) + expect(response).to have_http_status(:no_content) + end + end +end + +RSpec.shared_examples_for "features: sortable" do + let(:factory_attrs) { {} } + let(:scope) { "body" } + + before do + create(factory, displayed_attribute => "First", position: 1, **factory_attrs) + create(factory, displayed_attribute => "Second", position: 2, **factory_attrs) + visit path + end + + it "allows sorting via drag and drop" do + within(scope) do + expect(find("[data-controller='sortable']").all(:xpath, "./*").first).to have_text("First") + expect(find("[data-controller='sortable']").all(:xpath, "./*").last).to have_text("Second") + + rows = find("[data-controller='sortable']").all(:xpath, "./*") + rows[1].drag_to rows[0] + + expect(find("[data-controller='sortable']").all(:xpath, "./*").first).to have_text("Second") + expect(find("[data-controller='sortable']").all(:xpath, "./*").last).to have_text("First") + end + end +end diff --git a/admin/spec/features/payment_methods_spec.rb b/admin/spec/features/payment_methods_spec.rb index 55ebf3ec74b..06b4dc0f3ab 100644 --- a/admin/spec/features/payment_methods_spec.rb +++ b/admin/spec/features/payment_methods_spec.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require 'spec_helper' +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') } @@ -45,4 +46,10 @@ expect(page).not_to have_content("Check") expect(Spree::PaymentMethod.count).to eq(3) end + + it_behaves_like "features: sortable" do + let(:factory) { :payment_method } + let(:displayed_attribute) { :name } + let(:path) { solidus_admin.payment_methods_path } + end end diff --git a/admin/spec/features/taxonomies_spec.rb b/admin/spec/features/taxonomies_spec.rb index 88cb0ec782a..33fab23194e 100644 --- a/admin/spec/features/taxonomies_spec.rb +++ b/admin/spec/features/taxonomies_spec.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require 'spec_helper' +require "solidus_admin/testing_support/shared_examples/moveable" describe "Taxonomies", :js, type: :feature do before { sign_in create(:admin_user, email: 'admin@example.com') } @@ -21,4 +22,10 @@ expect(page).not_to have_content("Categories") expect(Spree::Taxonomy.count).to eq(1) end + + it_behaves_like "features: sortable" do + let(:factory) { :taxonomy } + let(:displayed_attribute) { :name } + let(:path) { solidus_admin.taxonomies_path } + end end diff --git a/admin/spec/requests/solidus_admin/payment_methods_spec.rb b/admin/spec/requests/solidus_admin/payment_methods_spec.rb new file mode 100644 index 00000000000..5cc99dae2ab --- /dev/null +++ b/admin/spec/requests/solidus_admin/payment_methods_spec.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +require "spec_helper" +require "solidus_admin/testing_support/shared_examples/moveable" + +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 +end diff --git a/admin/spec/requests/solidus_admin/taxonomies_spec.rb b/admin/spec/requests/solidus_admin/taxonomies_spec.rb new file mode 100644 index 00000000000..0c93d5551c1 --- /dev/null +++ b/admin/spec/requests/solidus_admin/taxonomies_spec.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +require "spec_helper" +require "solidus_admin/testing_support/shared_examples/moveable" + +RSpec.describe "SolidusAdmin::TaxonomiesController", type: :request do + it_behaves_like "requests: moveable" do + let(:factory) { :taxonomy } + end +end