solidus_backend 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of solidus_backend might be problematic. Click here for more details.

Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1 -0
  3. data/Gemfile +6 -0
  4. data/Rakefile +15 -0
  5. data/script/rails +9 -0
  6. data/solidus_backend.gemspec +28 -0
  7. data/spec/controllers/spree/admin/base_controller_spec.rb +24 -0
  8. data/spec/controllers/spree/admin/cancellations_controller_spec.rb +77 -0
  9. data/spec/controllers/spree/admin/customer_returns_controller_spec.rb +234 -0
  10. data/spec/controllers/spree/admin/general_settings_controller_spec.rb +41 -0
  11. data/spec/controllers/spree/admin/missing_products_controller_spec.rb +18 -0
  12. data/spec/controllers/spree/admin/orders/customer_details_controller_spec.rb +80 -0
  13. data/spec/controllers/spree/admin/orders_controller_spec.rb +472 -0
  14. data/spec/controllers/spree/admin/payment_methods_controller_spec.rb +49 -0
  15. data/spec/controllers/spree/admin/payments_controller_spec.rb +175 -0
  16. data/spec/controllers/spree/admin/products_controller_spec.rb +45 -0
  17. data/spec/controllers/spree/admin/promotion_actions_controller_spec.rb +21 -0
  18. data/spec/controllers/spree/admin/promotion_codes_controller_spec.rb +18 -0
  19. data/spec/controllers/spree/admin/promotion_rules_controller_spec.rb +21 -0
  20. data/spec/controllers/spree/admin/promotions_controller_spec.rb +122 -0
  21. data/spec/controllers/spree/admin/refunds_controller_spec.rb +32 -0
  22. data/spec/controllers/spree/admin/reimbursements_controller_spec.rb +75 -0
  23. data/spec/controllers/spree/admin/reports_controller_spec.rb +134 -0
  24. data/spec/controllers/spree/admin/resource_controller_spec.rb +166 -0
  25. data/spec/controllers/spree/admin/return_authorizations_controller_spec.rb +226 -0
  26. data/spec/controllers/spree/admin/return_items_controller_spec.rb +27 -0
  27. data/spec/controllers/spree/admin/root_controller_spec.rb +41 -0
  28. data/spec/controllers/spree/admin/search_controller_spec.rb +104 -0
  29. data/spec/controllers/spree/admin/shipping_methods_controller_spec.rb +14 -0
  30. data/spec/controllers/spree/admin/stock_items_controller_spec.rb +50 -0
  31. data/spec/controllers/spree/admin/stock_locations_controller_spec.rb +41 -0
  32. data/spec/controllers/spree/admin/stock_transfers_controller_spec.rb +331 -0
  33. data/spec/controllers/spree/admin/store_credits_controller_spec.rb +309 -0
  34. data/spec/controllers/spree/admin/users_controller_spec.rb +236 -0
  35. data/spec/controllers/spree/admin/variants_controller_spec.rb +32 -0
  36. data/spec/features/admin/configuration/analytics_tracker_spec.rb +54 -0
  37. data/spec/features/admin/configuration/countries_spec.rb +22 -0
  38. data/spec/features/admin/configuration/general_settings_spec.rb +45 -0
  39. data/spec/features/admin/configuration/payment_methods_spec.rb +125 -0
  40. data/spec/features/admin/configuration/shipping_methods_spec.rb +64 -0
  41. data/spec/features/admin/configuration/states_spec.rb +64 -0
  42. data/spec/features/admin/configuration/stock_locations_spec.rb +50 -0
  43. data/spec/features/admin/configuration/tax_categories_spec.rb +56 -0
  44. data/spec/features/admin/configuration/tax_rates_spec.rb +30 -0
  45. data/spec/features/admin/configuration/taxonomies_spec.rb +52 -0
  46. data/spec/features/admin/configuration/zones_spec.rb +39 -0
  47. data/spec/features/admin/homepage_spec.rb +78 -0
  48. data/spec/features/admin/locale_spec.rb +30 -0
  49. data/spec/features/admin/orders/adjustments_promotions_spec.rb +53 -0
  50. data/spec/features/admin/orders/adjustments_spec.rb +126 -0
  51. data/spec/features/admin/orders/cancelling_and_resuming_spec.rb +48 -0
  52. data/spec/features/admin/orders/cancelling_inventory_spec.rb +48 -0
  53. data/spec/features/admin/orders/customer_details_spec.rb +163 -0
  54. data/spec/features/admin/orders/line_items_spec.rb +50 -0
  55. data/spec/features/admin/orders/listing_spec.rb +130 -0
  56. data/spec/features/admin/orders/log_entries_spec.rb +55 -0
  57. data/spec/features/admin/orders/new_order_spec.rb +185 -0
  58. data/spec/features/admin/orders/order_details_spec.rb +533 -0
  59. data/spec/features/admin/orders/payments_spec.rb +228 -0
  60. data/spec/features/admin/orders/risk_analysis_spec.rb +47 -0
  61. data/spec/features/admin/orders/shipments_spec.rb +65 -0
  62. data/spec/features/admin/payments/store_credits_spec.rb +21 -0
  63. data/spec/features/admin/products/edit/images_spec.rb +87 -0
  64. data/spec/features/admin/products/edit/products_spec.rb +66 -0
  65. data/spec/features/admin/products/edit/taxons_spec.rb +43 -0
  66. data/spec/features/admin/products/edit/variants_spec.rb +61 -0
  67. data/spec/features/admin/products/option_types_spec.rb +114 -0
  68. data/spec/features/admin/products/products_spec.rb +392 -0
  69. data/spec/features/admin/products/properties_spec.rb +139 -0
  70. data/spec/features/admin/products/prototypes_spec.rb +110 -0
  71. data/spec/features/admin/products/stock_management_spec.rb +82 -0
  72. data/spec/features/admin/products/variant_spec.rb +51 -0
  73. data/spec/features/admin/promotion_adjustments_spec.rb +220 -0
  74. data/spec/features/admin/promotions/tiered_calculator_spec.rb +69 -0
  75. data/spec/features/admin/reports_spec.rb +61 -0
  76. data/spec/features/admin/stock_transfer_spec.rb +86 -0
  77. data/spec/features/admin/store_credits_spec.rb +82 -0
  78. data/spec/features/admin/taxons_spec.rb +31 -0
  79. data/spec/features/admin/users_spec.rb +270 -0
  80. data/spec/helpers/admin/base_helper_spec.rb +24 -0
  81. data/spec/helpers/admin/navigation_helper_spec.rb +73 -0
  82. data/spec/helpers/admin/reimbursements_helper_spec.rb +34 -0
  83. data/spec/helpers/admin/stock_movements_helper_spec.rb +29 -0
  84. data/spec/helpers/admin/store_credit_events_helper_spec.rb +95 -0
  85. data/spec/helpers/promotion_rules_helper_spec.rb +12 -0
  86. data/spec/spec_helper.rb +108 -0
  87. data/spec/support/appear_before_matcher.rb +8 -0
  88. data/spec/support/ror_ringer.jpeg +0 -0
  89. data/spec/test_views/spree/admin/widgets/edit.html.erb +1 -0
  90. data/spec/test_views/spree/admin/widgets/new.html.erb +1 -0
  91. metadata +95 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5c1aabfafe249cd68514b7850b380fb72ffc3873
4
- data.tar.gz: b8bede6cfb8618a491ae5ac2facd469dcbde8a70
3
+ metadata.gz: 3cc15db5ea4f24b80c4f82d3fbcf6c7d78480d4f
4
+ data.tar.gz: c8677011afd99426d09e8ae8bd1da587d3435d7f
5
5
  SHA512:
6
- metadata.gz: d0c0066c0465294409254c33c2ddd182567f60d4c7f6b1f65cf2bcfba177e15f99f335145f1211211a752070790365049f32fd8659a43c9507534a66cc95daac
7
- data.tar.gz: d2f71a223d8c67bb49b0b5e25ed37815586e90b14140f6e0540ff9767775b4eb4d258f4eaea46965640fd42ff079154153dcd29dd01dde529c4b7eb07a58c74f
6
+ metadata.gz: 07026b1e153afdc4a4ec0cb3b001b57b4bfc3ca5bf4b5d81830efc38e22c4e8a9ccca8521d49ba4396108de93beeec044b998f576bfc8cf84025f88325dadbdb
7
+ data.tar.gz: 2149d733ca7ca912df33a5cbd2b9bec3221c4101a97bd53241f3d925efab172abbb4dd0bca3adc582dfeb589a37a2a3ff08ea22ac743e4a84ce2d4d26ff25503
@@ -0,0 +1 @@
1
+ ## Spree 2.4.0 (unreleased) ##
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ eval(File.read(File.dirname(__FILE__) + '/../common_spree_dependencies.rb'))
2
+
3
+ gem 'solidus_core', :path => '../core'
4
+ gem 'solidus_api', :path => '../api'
5
+
6
+ gemspec
@@ -0,0 +1,15 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require 'rspec/core/rake_task'
5
+ require 'spree/testing_support/common_rake'
6
+
7
+ RSpec::Core::RakeTask.new
8
+
9
+ task :default => :spec
10
+
11
+ desc "Generates a dummy app for testing"
12
+ task :test_app do
13
+ ENV['LIB_NAME'] = 'spree/backend'
14
+ Rake::Task['common:test_app'].invoke
15
+ end
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
+
4
+ ENGINE_ROOT = File.expand_path('../..', __FILE__)
5
+ ENGINE_PATH = File.expand_path('../../lib/spree/backend/engine', __FILE__)
6
+
7
+ require 'rails/all'
8
+ require 'rails/engine/commands'
9
+
@@ -0,0 +1,28 @@
1
+ # encoding: UTF-8
2
+ version = File.read(File.expand_path("../../SOLIDUS_VERSION", __FILE__)).strip
3
+
4
+ Gem::Specification.new do |s|
5
+ s.platform = Gem::Platform::RUBY
6
+ s.name = 'solidus_backend'
7
+ s.version = version
8
+ s.summary = 'Admin interface for the Solidus e-commerce framework.'
9
+ s.description = s.summary
10
+
11
+ s.required_ruby_version = '>= 2.1.0'
12
+ s.author = 'Solidus Team'
13
+ s.email = 'contact@solidus.io'
14
+ s.homepage = 'http://solidus.io'
15
+ s.rubyforge_project = 'solidus_backend'
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.require_path = 'lib'
19
+ s.requirements << 'none'
20
+
21
+ s.add_dependency 'solidus_api', version
22
+ s.add_dependency 'solidus_core', version
23
+
24
+ s.add_dependency 'bourbon'
25
+ s.add_dependency 'jquery-rails'
26
+ s.add_dependency 'jquery-ui-rails', '~> 5.0.0'
27
+ s.add_dependency 'select2-rails', '3.5.9.1' # 3.5.9.2 breaks forms
28
+ end
@@ -0,0 +1,24 @@
1
+ # Spree's rpsec controller tests get the Spree::ControllerHacks
2
+ # we don't need those for the anonymous controller here, so
3
+ # we call process directly instead of get
4
+ require 'spec_helper'
5
+
6
+ describe Spree::Admin::BaseController, :type => :controller do
7
+ controller(Spree::Admin::BaseController) do
8
+ def index
9
+ authorize! :update, Spree::Order
10
+ render :text => 'test'
11
+ end
12
+ end
13
+
14
+ context "unauthorized request" do
15
+ before do
16
+ allow_any_instance_of(Spree::Admin::BaseController).to receive(:spree_current_user).and_return(nil)
17
+ end
18
+
19
+ it "redirects to unauthorized" do
20
+ get :index
21
+ expect(response).to redirect_to '/unauthorized'
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Admin::CancellationsController do
4
+ stub_authorization!
5
+
6
+ describe "#index" do
7
+ subject { spree_get :index, order_id: order.number }
8
+
9
+ let(:order) { create(:order_ready_to_ship, line_items_count: 1)}
10
+
11
+ context "for an order with inventory" do
12
+ render_views
13
+
14
+ it "succeeds" do
15
+ expect(response).to be_ok
16
+ end
17
+ end
18
+ end
19
+
20
+ describe "#cancel" do
21
+ subject { spree_post :short_ship, order_id: order.number, inventory_unit_ids: inventory_units.map(&:id) }
22
+
23
+ let(:order) { order = create(:order_ready_to_ship, :number => "R100", :state => "complete", line_items_count: 1) }
24
+ let(:referer) { "order_admin_page" }
25
+
26
+ context "no inventory unit ids are provided" do
27
+ subject { spree_post :short_ship, order_id: order.number }
28
+
29
+ it "redirects back" do
30
+ subject
31
+ expect(response).to redirect_to(spree.admin_order_cancellations_path(order))
32
+ end
33
+
34
+ it "sets an error message" do
35
+ subject
36
+ expect(flash[:error]).to eq Spree.t(:no_inventory_selected)
37
+ end
38
+ end
39
+
40
+ context "unable to find all the inventory" do
41
+ let(:inventory_units) { [Spree::InventoryUnit.new(id: -1)] }
42
+
43
+ it "redirects back" do
44
+ subject
45
+ expect(response).to redirect_to(spree.admin_order_cancellations_path(order))
46
+ end
47
+
48
+ it "sets an error message" do
49
+ subject
50
+ expect(flash[:error]).to eq Spree.t(:unable_to_find_all_inventory_units)
51
+ end
52
+ end
53
+
54
+ context "successfully cancels inventory" do
55
+ let(:inventory_units) { order.inventory_units.not_canceled }
56
+
57
+ it "redirects to admin order edit" do
58
+ subject
59
+ expect(response).to redirect_to(spree.edit_admin_order_path(order))
60
+ end
61
+
62
+ it "sets an success message" do
63
+ subject
64
+ expect(flash[:success]).to eq Spree.t(:inventory_canceled)
65
+ end
66
+
67
+ it "creates a unit cancel" do
68
+ expect { subject }.to change { Spree::UnitCancel.count }.by(1)
69
+ end
70
+
71
+ it "cancels the inventory" do
72
+ subject
73
+ expect(order.inventory_units.map(&:state).uniq).to match_array(['canceled'])
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,234 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ module Admin
5
+ describe CustomerReturnsController, :type => :controller do
6
+ stub_authorization!
7
+
8
+ describe "#index" do
9
+ let(:order) { customer_return.order }
10
+ let(:customer_return) { create(:customer_return) }
11
+
12
+ subject do
13
+ spree_get :index, { order_id: customer_return.order.to_param }
14
+ end
15
+
16
+ before { subject }
17
+
18
+ it "loads the order" do
19
+ expect(assigns(:order)).to eq order
20
+ end
21
+
22
+ it "loads the customer return" do
23
+ expect(assigns(:customer_returns)).to include(customer_return)
24
+ end
25
+ end
26
+
27
+ describe "#new" do
28
+ let(:order) { create(:shipped_order, line_items_count: 1) }
29
+ let!(:inactive_reimbursement_type) { create(:reimbursement_type, active: false) }
30
+ let!(:first_active_reimbursement_type) { create(:reimbursement_type) }
31
+ let!(:second_active_reimbursement_type) { create(:reimbursement_type) }
32
+
33
+ subject do
34
+ spree_get :new, { order_id: order.to_param }
35
+ end
36
+
37
+ it "loads the order" do
38
+ subject
39
+ expect(assigns(:order)).to eq order
40
+ end
41
+
42
+ it "builds a new customer return" do
43
+ subject
44
+ expect(assigns(:customer_return)).to_not be_persisted
45
+ end
46
+
47
+ context "with previous customer return" do
48
+ let(:return_reason_1) { create(:return_reason) }
49
+ let(:return_reason_2) { create(:return_reason) }
50
+ let(:return_reason_3) { create(:return_reason) }
51
+ let!(:inactive_rma_reason) { create(:return_reason, active: false) }
52
+
53
+
54
+ let(:order) { create(:shipped_order, line_items_count: 4) }
55
+ let(:rma) { create(:return_authorization, order: order, reason: return_reason_1) }
56
+
57
+ let!(:rma_return_item) { create(:return_item, return_authorization: rma, inventory_unit: order.inventory_units.first, return_reason: return_reason_2) }
58
+ let!(:customer_return_return_item) { create(:return_item, return_authorization: nil, inventory_unit: order.inventory_units.last, return_reason: return_reason_3) }
59
+
60
+ context "all return items are associated with a customer return" do
61
+ let!(:previous_customer_return) { create(:customer_return_without_return_items, return_items: [rma_return_item, customer_return_return_item]) }
62
+
63
+ before { subject }
64
+
65
+ it "loads the possible return items" do
66
+ total_inventory_count = 4
67
+ rma_return_items_count = 1
68
+ customer_return_return_items_count = 1
69
+ expect(assigns(:new_return_items).length).to eq (total_inventory_count - rma_return_items_count - customer_return_return_items_count)
70
+ end
71
+
72
+ it "builds new return items" do
73
+ expect(assigns(:new_return_items).all? { |return_item| !return_item.persisted? }).to eq true
74
+ end
75
+
76
+ it "does not have any rma return items" do
77
+ expect(assigns(:rma_return_items)).to eq []
78
+ end
79
+
80
+ it "loads the correct return authorization reasons" do
81
+ expect(assigns(:reasons)).to match_array([return_reason_1, return_reason_2, return_reason_3])
82
+ end
83
+ end
84
+
85
+ context "there is a return item associated with an rma but not a customer return" do
86
+ let!(:previous_customer_return) { create(:customer_return_without_return_items, return_items: [customer_return_return_item]) }
87
+
88
+ before do
89
+ subject
90
+ end
91
+
92
+ it "loads the possible return items" do
93
+ rma_return_item_count = rma.return_items.count
94
+ total_unit_count = order.inventory_units.count
95
+ customer_returned_count = previous_customer_return.return_items.count
96
+ expected_total = total_unit_count - customer_returned_count - rma_return_item_count
97
+ expect(assigns(:new_return_items).length).to eq expected_total
98
+ end
99
+
100
+ it "builds new return items" do
101
+ expect(assigns(:new_return_items).all? { |return_item| !return_item.persisted? }).to eq true
102
+ end
103
+
104
+ it "loads the persisted rma return items" do
105
+ expect(assigns(:rma_return_items).all? { |return_item| return_item.persisted? }).to eq true
106
+ end
107
+
108
+ it "has one rma return item" do
109
+ expect(assigns(:rma_return_items)).to include(rma_return_item)
110
+ end
111
+
112
+ it "loads the correct return authorization reasons" do
113
+ expect(assigns(:reasons)).to match_array([return_reason_1, return_reason_2, return_reason_3])
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ describe "#edit" do
120
+ let(:order) { customer_return.order }
121
+ let(:customer_return) { create(:customer_return, line_items_count: 3) }
122
+
123
+ let!(:inactive_rma_reason) { create(:return_reason, active: false) }
124
+
125
+ let!(:accepted_return_item) { customer_return.return_items.order('id').first.tap(&:accept!) }
126
+ let!(:rejected_return_item) { customer_return.return_items.order('id').second.tap(&:reject!)}
127
+ let!(:manual_intervention_return_item) { customer_return.return_items.order('id').third.tap(&:require_manual_intervention!) }
128
+
129
+ subject do
130
+ spree_get :edit, { order_id: order.to_param, id: customer_return.to_param }
131
+ end
132
+
133
+ it "loads the order" do
134
+ subject
135
+ expect(assigns(:order)).to eq order
136
+ end
137
+
138
+ it "loads the customer return" do
139
+ subject
140
+ expect(assigns(:customer_return)).to eq customer_return
141
+ end
142
+
143
+ it "loads the accepted return items" do
144
+ subject
145
+ expect(assigns(:accepted_return_items)).to eq [accepted_return_item]
146
+ end
147
+
148
+ it "loads the rejected return items" do
149
+ subject
150
+ expect(assigns(:rejected_return_items)).to eq [rejected_return_item]
151
+ end
152
+
153
+ it "loads the return items that require manual intervention" do
154
+ subject
155
+ expect(assigns(:manual_intervention_return_items)).to eq [manual_intervention_return_item]
156
+ end
157
+
158
+ it "loads the return items that are still pending" do
159
+ subject
160
+ expect(assigns(:pending_return_items)).to eq []
161
+ end
162
+
163
+ it "loads the reimbursements that are still pending" do
164
+ subject
165
+ expect(assigns(:pending_reimbursements)).to eq []
166
+ end
167
+
168
+ it "loads the correct return authorization reasons" do
169
+ subject
170
+ expect(assigns(:reasons)).to match(Spree::ReturnReason.active)
171
+ end
172
+
173
+ context "a return item has an inactive return authorization reason" do
174
+ before(:each) do
175
+ accepted_return_item.update_attributes(return_reason_id: inactive_rma_reason.id)
176
+ end
177
+
178
+ it "includes the inactive return authorization reason" do
179
+ subject
180
+ expect(assigns(:reasons)).to match(Spree::ReturnReason.active + [inactive_rma_reason])
181
+ end
182
+ end
183
+ end
184
+
185
+ describe "#create" do
186
+ let(:order) { create(:shipped_order, line_items_count: 1) }
187
+ let(:reception_status_event) { 'receive' }
188
+ let(:stock_location_id) { order.shipments.last.stock_location.id }
189
+ let(:customer_return_params) do
190
+ {
191
+ order_id: order.to_param,
192
+ customer_return: {
193
+ stock_location_id: stock_location_id,
194
+ return_items_attributes: {
195
+ "0" => {
196
+ returned: "1",
197
+ "pre_tax_amount"=>"15.99",
198
+ inventory_unit_id: order.inventory_units.shipped.last.id,
199
+ reception_status_event: reception_status_event
200
+ }
201
+ }
202
+ }
203
+ }
204
+ end
205
+
206
+ subject { spree_post :create, customer_return_params }
207
+
208
+ it { expect { subject }.to change { Spree::CustomerReturn.count }.by(1) }
209
+ it do
210
+ subject
211
+ expect(response).to redirect_to spree.edit_admin_order_customer_return_path(order, id: Spree::CustomerReturn.last.id)
212
+ end
213
+
214
+ it 'executes the reception status event on the return items' do
215
+ subject
216
+ customer_return = Spree::CustomerReturn.last
217
+ expect(customer_return.return_items.map(&:reception_status).uniq).to eq ['received']
218
+ end
219
+
220
+ context "missing stock location" do
221
+ let(:stock_location_id) { '' }
222
+ it { expect{ subject }.to_not change { Spree::CustomerReturn.count } }
223
+ it { subject; expect(response).to render_template(:new) }
224
+ end
225
+
226
+ context "missing reception status event" do
227
+ let(:reception_status_event) { '' }
228
+ it { expect{ subject }.to_not change { Spree::CustomerReturn.count } }
229
+ it { subject; expect(response).to redirect_to spree.new_admin_order_customer_return_path(order) }
230
+ end
231
+ end
232
+ end
233
+ end
234
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Admin::GeneralSettingsController, type: :controller do
4
+ let(:user) { create(:user) }
5
+
6
+ before do
7
+ allow(controller).to receive_messages :spree_current_user => user
8
+ user.spree_roles << Spree::Role.find_or_create_by(name: 'admin')
9
+ end
10
+
11
+ describe '#clear_cache' do
12
+ subject { spree_post :clear_cache }
13
+
14
+ shared_examples 'a HTTP 204 response' do
15
+ it 'grant access to users with an admin role' do
16
+ subject
17
+ expect(response.status).to eq(204)
18
+ end
19
+ end
20
+
21
+ context 'when no callback' do
22
+ it_behaves_like 'a HTTP 204 response'
23
+ end
24
+
25
+ context 'when callback implemented' do
26
+ Spree::Admin::GeneralSettingsController.class_eval do
27
+ custom_callback(:clear_cache).after :foo
28
+
29
+ def foo
30
+ # Make a call to Akamai, CloudFlare, etc invalidation....
31
+ end
32
+ end
33
+
34
+ before do
35
+ expect(controller).to receive(:foo).once
36
+ end
37
+
38
+ it_behaves_like 'a HTTP 204 response'
39
+ end
40
+ end
41
+ end