solidus_backend 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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