Skip to content

Commit a57f0c9

Browse files
authored
Merge pull request #6134 from chaimann/fix-bulk-delete
[Admin] Allow bulk delete resources
2 parents acd092f + 4b0089c commit a57f0c9

25 files changed

+281
-1027
lines changed

admin/app/controllers/solidus_admin/resources_controller.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ def update
5656
end
5757

5858
def destroy
59-
@resource = resource_class.find_by!(id: params[:id])
59+
@resource = resource_class.where(id: params[:id])
6060

61-
resource_class.transaction { @resource.destroy }
61+
resource_class.transaction { @resource.destroy_all }
6262

6363
flash[:notice] = t('.success')
6464
redirect_back_or_to after_destroy_path, status: :see_other
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# frozen_string_literal: true
2+
3+
RSpec.shared_examples_for 'feature: bulk delete resources' do
4+
it 'allows to bulk delete resources' do
5+
create(resource_factory, name: 'Bulk delete item 1')
6+
create(resource_factory, name: 'Bulk delete item 2')
7+
8+
visit index_path
9+
expect(page).to have_content('Bulk delete item 1')
10+
expect(page).to have_content('Bulk delete item 2')
11+
12+
select_row('Bulk delete item 1')
13+
select_row('Bulk delete item 2')
14+
click_on 'Delete'
15+
16+
expect(page).to have_content('were successfully removed.')
17+
expect(page).not_to have_content('Bulk delete item 1')
18+
expect(page).not_to have_content('Bulk delete item 2')
19+
end
20+
end
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
# frozen_string_literal: true
2+
3+
RSpec.shared_examples_for 'CRUD resource requests' do |resource_name|
4+
let(:admin_user) { create(:admin_user) }
5+
let(:resource) { create(factory) }
6+
7+
# Overridables
8+
let(:factory) { resource_name.to_sym }
9+
let(:url_helpers) { solidus_admin }
10+
11+
before do
12+
allow_any_instance_of(SolidusAdmin::BaseController).to receive(:spree_current_user).and_return(admin_user)
13+
end
14+
15+
describe "GET /index" do
16+
it "renders the index template with a 200 OK status" do
17+
get url_helpers.public_send("#{resource_name.pluralize}_path")
18+
expect(response).to have_http_status(:ok)
19+
end
20+
end
21+
22+
describe "GET /new" do
23+
it "renders the new template with a 200 OK status" do
24+
get url_helpers.public_send("new_#{resource_name}_path")
25+
expect(response).to have_http_status(:ok)
26+
end
27+
end
28+
29+
describe "POST /create" do
30+
context "with valid parameters" do
31+
it "creates a new #{resource_name.humanize}" do
32+
expect {
33+
post url_helpers.public_send("#{resource_name.pluralize}_path"), params: { resource_name => valid_attributes }
34+
}.to change(resource_class, :count).by(1)
35+
end
36+
37+
it "redirects to the index page with a 303 See Other status" do
38+
post url_helpers.public_send("#{resource_name.pluralize}_path"), params: { resource_name => valid_attributes }
39+
expect(response).to redirect_to(url_helpers.public_send("#{resource_name.pluralize}_path"))
40+
expect(response).to have_http_status(:see_other)
41+
end
42+
43+
it "displays a success flash message" do
44+
post url_helpers.public_send("#{resource_name.pluralize}_path"), params: { resource_name => valid_attributes }
45+
follow_redirect!
46+
expect(response.body).to include("#{resource_name.humanize} was successfully created.")
47+
end
48+
end
49+
50+
context "with invalid parameters" do
51+
let(:invalid_attributes) { { name: "", code: "", active: true } }
52+
53+
it "does not create a new #{resource_name.humanize}" do
54+
expect {
55+
post url_helpers.public_send("#{resource_name.pluralize}_path"), params: { resource_name => invalid_attributes }
56+
}.not_to change(resource_class, :count)
57+
end
58+
59+
it "renders the new template with unprocessable_entity status" do
60+
post url_helpers.public_send("#{resource_name.pluralize}_path"), params: { resource_name => invalid_attributes }
61+
expect(response).to have_http_status(:unprocessable_entity)
62+
end
63+
end
64+
end
65+
66+
describe "GET /edit" do
67+
it "renders the edit template with a 200 OK status" do
68+
get url_helpers.public_send("edit_#{resource_name}_path", resource)
69+
expect(response).to have_http_status(:ok)
70+
end
71+
end
72+
73+
describe "PATCH /update" do
74+
context "with valid parameters" do
75+
it "updates the #{resource_name.humanize}" do
76+
patch url_helpers.public_send("#{resource_name}_path", resource), params: { resource_name => valid_attributes }
77+
resource.reload
78+
valid_attributes.each do |attr, value|
79+
expect(resource.public_send(attr)).to eq(value)
80+
end
81+
end
82+
83+
it "redirects to the index page with a 303 See Other status" do
84+
patch url_helpers.public_send("#{resource_name}_path", resource), params: { resource_name => valid_attributes }
85+
expect(response).to redirect_to(url_helpers.public_send("#{resource_name.pluralize}_path"))
86+
expect(response).to have_http_status(:see_other)
87+
end
88+
89+
it "displays a success flash message" do
90+
patch url_helpers.public_send("#{resource_name}_path", resource), params: { resource_name => valid_attributes }
91+
follow_redirect!
92+
expect(response.body).to include("#{resource_name.humanize} was successfully updated.")
93+
end
94+
end
95+
96+
context "with invalid parameters" do
97+
it "does not update the #{resource_name.humanize}" do
98+
expect {
99+
patch url_helpers.public_send("#{resource_name}_path", resource), params: { resource_name => invalid_attributes }
100+
}.not_to change { resource.reload }
101+
end
102+
103+
it "renders the edit template with unprocessable_entity status" do
104+
patch url_helpers.public_send("#{resource_name}_path", resource), params: { resource_name => invalid_attributes }
105+
expect(response).to have_http_status(:unprocessable_entity)
106+
end
107+
end
108+
end
109+
110+
describe "DELETE /destroy" do
111+
it "deletes the #{resource_name.humanize} and redirects to the index page with a 303 See Other status" do
112+
# This ensures resource exists prior to deletion.
113+
resource
114+
expect {
115+
delete url_helpers.public_send("#{resource_name}_path", resource)
116+
}.to change(resource_class, :count).by(-1)
117+
118+
expect(response).to redirect_to(url_helpers.public_send("#{resource_name.pluralize}_path"))
119+
expect(response).to have_http_status(:see_other)
120+
end
121+
122+
it "displays a success flash message after deletion" do
123+
delete url_helpers.public_send("#{resource_name}_path", resource)
124+
follow_redirect!
125+
expect(response.body).to include("#{resource_name.humanize.pluralize} were successfully removed.")
126+
end
127+
128+
it 'allows to bulk delete resources' do
129+
ids = [create(factory), create(factory)].map(&:id)
130+
expect {
131+
delete url_helpers.public_send("#{resource_name.pluralize}_path", id: ids)
132+
}.to change { resource_class.count }.by(-ids.size)
133+
134+
expect(response).to redirect_to(url_helpers.public_send("#{resource_name.pluralize}_path"))
135+
expect(response).to have_http_status(:see_other)
136+
end
137+
end
138+
end

admin/lib/solidus_admin/testing_support/shared_examples/promotion_categories_features.rb

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# frozen_string_literal: true
22

3+
require 'solidus_admin/testing_support/shared_examples/bulk_delete_resources'
4+
35
RSpec.shared_examples_for 'promotion categories features' do
46
before { sign_in create(:admin_user, email: "admin@example.com") }
57

@@ -28,7 +30,7 @@
2830
fill_in "Name", with: "Soon to expire"
2931
click_on "Add Promotion Category"
3032

31-
expect(page).to have_content("Promotion Category was successfully created.")
33+
expect(page).to have_content("Promotion category was successfully created.")
3234
expect(page).to have_content("Soon to expire")
3335
expect(page).to have_content("ste.1")
3436
expect(model_class.count).to eq(1)
@@ -46,7 +48,7 @@
4648
fill_in "Code", with: "exp.2"
4749
click_on "Update Promotion Category"
4850

49-
expect(page).to have_content("Promotion Category was successfully updated.")
51+
expect(page).to have_content("Promotion category was successfully updated.")
5052
expect(page).to have_content("Expired")
5153
expect(page).to have_content("exp.2")
5254
end
@@ -59,8 +61,12 @@
5961

6062
select_row("Expired")
6163
click_on "Delete"
62-
expect(page).to have_content("Promotion Categories were successfully removed.")
64+
expect(page).to have_content("Promotion categories were successfully removed.")
6365
expect(page).not_to have_content("Expired")
6466
expect(model_class.count).to eq(1)
6567
end
68+
69+
include_examples 'feature: bulk delete resources' do
70+
let(:resource_factory) { factory_name }
71+
end
6672
end

admin/lib/solidus_admin/testing_support/shared_examples/promotion_categories_requests.rb

Lines changed: 0 additions & 126 deletions
This file was deleted.

admin/spec/features/adjustment_reasons_spec.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# frozen_string_literal: true
22

33
require 'spec_helper'
4+
require 'solidus_admin/testing_support/shared_examples/bulk_delete_resources'
45

56
describe "Adjustment Reasons", :js, type: :feature do
67
before { sign_in create(:admin_user, email: 'admin@example.com') }
@@ -20,6 +21,11 @@
2021
expect(page).to be_axe_clean
2122
end
2223

24+
include_examples 'feature: bulk delete resources' do
25+
let(:resource_factory) { :adjustment_reason }
26+
let(:index_path) { "/admin/adjustment_reasons" }
27+
end
28+
2329
context "when creating a new adjustment reason" do
2430
let(:query) { "?page=1&q%5Bname_or_code_cont%5D=new" }
2531

admin/spec/features/properties_spec.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# frozen_string_literal: true
22

33
require 'spec_helper'
4+
require 'solidus_admin/testing_support/shared_examples/bulk_delete_resources'
45

56
describe "Properties", :js, type: :feature do
67
before { sign_in create(:admin_user, email: 'admin@example.com') }
@@ -22,6 +23,11 @@
2223
expect(Spree::Property.count).to eq(1)
2324
end
2425

26+
include_examples 'feature: bulk delete resources' do
27+
let(:resource_factory) { :property }
28+
let(:index_path) { "/admin/properties" }
29+
end
30+
2531
context "creating a new property" do
2632
it "creates a new product property" do
2733
visit "/admin/properties"

admin/spec/features/refund_reasons_spec.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# frozen_string_literal: true
22

33
require 'spec_helper'
4+
require 'solidus_admin/testing_support/shared_examples/bulk_delete_resources'
45

56
describe "Refund Reasons", :js, type: :feature do
67
before { sign_in create(:admin_user, email: 'admin@example.com') }
@@ -20,6 +21,11 @@
2021
expect(page).to be_axe_clean
2122
end
2223

24+
include_examples 'feature: bulk delete resources' do
25+
let(:resource_factory) { :refund_reason }
26+
let(:index_path) { "/admin/refund_reasons" }
27+
end
28+
2329
context "when creating a new refund reason" do
2430
let(:query) { "?page=1&q%5Bname_or_description_cont%5D=Ret" }
2531

0 commit comments

Comments
 (0)