solidus_afterpay 0.1.0 → 0.2.0

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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +52 -23
  3. data/app/assets/javascripts/solidus_afterpay/afterpay_checkout.js +11 -11
  4. data/app/assets/javascripts/solidus_afterpay/afterpay_checkout_button.js +85 -0
  5. data/app/assets/javascripts/solidus_afterpay/afterpay_init.js +12 -0
  6. data/app/assets/javascripts/solidus_afterpay/backend/afterpay_autocomplete.js +9 -0
  7. data/app/assets/javascripts/spree/backend/solidus_afterpay.js +3 -1
  8. data/app/assets/javascripts/spree/frontend/solidus_afterpay.js +2 -0
  9. data/app/controllers/solidus_afterpay/checkouts_controller.rb +8 -2
  10. data/app/controllers/solidus_afterpay/express_callbacks_controller.rb +61 -0
  11. data/app/decorators/controllers/solidus_afterpay/spree/orders_controller_decorator.rb +13 -0
  12. data/app/helpers/solidus_afterpay/afterpay_helper.rb +5 -4
  13. data/app/models/solidus_afterpay/gateway.rb +37 -10
  14. data/app/models/solidus_afterpay/order_component_builder.rb +34 -5
  15. data/app/models/solidus_afterpay/payment_method.rb +43 -10
  16. data/app/models/solidus_afterpay/payment_source.rb +1 -1
  17. data/app/presentes/solidus_afterpay/order_presenter.rb +17 -0
  18. data/app/presentes/solidus_afterpay/shipping_rate_presenter.rb +28 -0
  19. data/app/services/solidus_afterpay/base_service.rb +13 -0
  20. data/app/services/solidus_afterpay/shipping_rate_builder_service.rb +32 -0
  21. data/app/services/solidus_afterpay/update_order_addresses_service.rb +45 -0
  22. data/app/services/solidus_afterpay/update_order_attributes_service.rb +49 -0
  23. data/app/views/solidus_afterpay/_afterpay_checkout_button.html.erb +9 -0
  24. data/app/views/solidus_afterpay/_afterpay_javascript.html.erb +4 -1
  25. data/app/views/spree/api/payments/source_views/_afterpay.json.jbuilder +1 -1
  26. data/app/views/spree/shared/_afterpay_messaging.html.erb +14 -12
  27. data/config/locales/en.yml +4 -0
  28. data/config/routes.rb +2 -0
  29. data/lib/generators/solidus_afterpay/install/templates/initializer.rb +12 -0
  30. data/lib/solidus_afterpay/configuration.rb +22 -0
  31. data/lib/solidus_afterpay/testing_support/factories.rb +20 -0
  32. data/lib/solidus_afterpay/version.rb +1 -1
  33. data/solidus_afterpay.gemspec +1 -1
  34. data/spec/fixtures/vcr_casettes/find_order/invalid.yml +64 -0
  35. data/spec/fixtures/vcr_casettes/find_order/valid.yml +120 -0
  36. data/spec/helpers/solidus_afterpay/afterpay_helper_spec.rb +18 -2
  37. data/spec/models/solidus_afterpay/gateway_spec.rb +86 -12
  38. data/spec/models/solidus_afterpay/order_component_builder_spec.rb +67 -6
  39. data/spec/models/solidus_afterpay/payment_method_spec.rb +103 -39
  40. data/spec/models/solidus_afterpay/payment_source_spec.rb +3 -3
  41. data/spec/presenters/solidus_afterpay/order_presenter_spec.rb +34 -0
  42. data/spec/presenters/solidus_afterpay/shipping_rate_presenter_spec.rb +28 -0
  43. data/spec/requests/solidus_afterpay/checkouts_controller_spec.rb +72 -4
  44. data/spec/requests/solidus_afterpay/express_callbacks_controller_spec.rb +167 -0
  45. data/spec/services/solidus_afterpay/base_service_spec.rb +13 -0
  46. data/spec/services/solidus_afterpay/shipping_rate_builder_service_spec.rb +34 -0
  47. data/spec/services/solidus_afterpay/update_order_addresses_service_spec.rb +82 -0
  48. data/spec/services/solidus_afterpay/update_order_attributes_service_spec.rb +58 -0
  49. data/spec/support/cache.rb +5 -0
  50. data/spec/support/solidus.rb +1 -0
  51. data/spec/views/solidus_afterpay/express_checkout_button_spec.rb +33 -0
  52. data/spec/views/spree/shared/afterpay_messaging_spec.rb +44 -0
  53. metadata +42 -4
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  RSpec.describe SolidusAfterpay::Gateway do
@@ -14,8 +16,8 @@ RSpec.describe SolidusAfterpay::Gateway do
14
16
  subject(:response) { gateway.authorize(amount, payment_source, gateway_options) }
15
17
 
16
18
  let(:order_token) { '002.m6d9jkrtv1p0j4jqslklhfq9k4nl54jo2530d58kf6snpqq1' }
17
- let(:deferred?) { false }
18
- let(:payment_method) { build(:afterpay_payment_method, preferred_deferred: deferred?) }
19
+ let(:auto_capture) { true }
20
+ let(:payment_method) { build(:afterpay_payment_method, auto_capture: auto_capture) }
19
21
 
20
22
  let(:amount) { 1000 }
21
23
  let(:payment_source) { build(:afterpay_payment_source, token: order_token, payment_method: payment_method) }
@@ -28,7 +30,7 @@ RSpec.describe SolidusAfterpay::Gateway do
28
30
  end
29
31
 
30
32
  context 'with the deferred flow' do
31
- let(:deferred?) { true }
33
+ let(:auto_capture) { false }
32
34
 
33
35
  context 'with valid params', vcr: 'deferred/authorize/valid' do
34
36
  it 'authorize the afterpay payment with the order_token' do
@@ -69,6 +71,32 @@ RSpec.describe SolidusAfterpay::Gateway do
69
71
  expect(response.error_code).to eq('payment_declined')
70
72
  end
71
73
  end
74
+
75
+ context 'with a timeout error' do
76
+ before do
77
+ allow(::Afterpay::API::Payment::Auth).to receive(:call).and_raise(
78
+ ::Afterpay::RequestTimeoutError.new('request_timeout'), 'Request Timeout'
79
+ )
80
+ allow(::Afterpay::API::Payment::Reversal).to receive(:call)
81
+ end
82
+
83
+ it 'returns an unsuccesfull response' do
84
+ is_expected.not_to be_success
85
+ end
86
+
87
+ it 'returns the error message from Afterpay in the response' do
88
+ expect(response.message).to eq('Request Timeout')
89
+ end
90
+
91
+ it 'returns the error_code from Afterpay in the response' do
92
+ expect(response.error_code).to eq('request_timeout')
93
+ end
94
+
95
+ it 'calls the ::Afterpay::API::Payment::Reversal with order token' do
96
+ response
97
+ expect(::Afterpay::API::Payment::Reversal).to have_received(:call).with(token: order_token)
98
+ end
99
+ end
72
100
  end
73
101
  end
74
102
 
@@ -76,9 +104,9 @@ RSpec.describe SolidusAfterpay::Gateway do
76
104
  subject(:response) { gateway.capture(amount, response_code, gateway_options) }
77
105
 
78
106
  let(:order_token) { '002.nt7e0ioqj00fh0ua1nbqcj6vcn9obtfsglqvrj9ijpo3edfc' }
79
- let(:deferred?) { false }
107
+ let(:auto_capture) { true }
80
108
  let(:payment_source) { build(:afterpay_payment_source, token: order_token) }
81
- let(:payment_method) { build(:afterpay_payment_method, preferred_deferred: deferred?) }
109
+ let(:payment_method) { build(:afterpay_payment_method, auto_capture: auto_capture) }
82
110
  let(:payment) { build(:afterpay_payment, source: payment_source, payment_method: payment_method) }
83
111
 
84
112
  let(:amount) { 1000 }
@@ -128,7 +156,7 @@ RSpec.describe SolidusAfterpay::Gateway do
128
156
  end
129
157
 
130
158
  context 'with the deferred flow' do
131
- let(:deferred?) { true }
159
+ let(:auto_capture) { false }
132
160
 
133
161
  context 'with valid params', vcr: 'deferred/capture/valid' do
134
162
  it 'captures the afterpay payment with the order_id' do
@@ -151,6 +179,32 @@ RSpec.describe SolidusAfterpay::Gateway do
151
179
  expect(response.error_code).to eq('not_found')
152
180
  end
153
181
  end
182
+
183
+ context 'with a timeout error' do
184
+ before do
185
+ allow(::Afterpay::API::Payment::DeferredCapture).to receive(:call).and_raise(
186
+ ::Afterpay::RequestTimeoutError.new('request_timeout'), 'Request Timeout'
187
+ )
188
+ allow(::Afterpay::API::Payment::Reversal).to receive(:call)
189
+ end
190
+
191
+ it 'returns an unsuccesfull response' do
192
+ is_expected.not_to be_success
193
+ end
194
+
195
+ it 'returns the error message from Afterpay in the response' do
196
+ expect(response.message).to eq('Request Timeout')
197
+ end
198
+
199
+ it 'returns the error_code from Afterpay in the response' do
200
+ expect(response.error_code).to eq('request_timeout')
201
+ end
202
+
203
+ it 'calls the ::Afterpay::API::Payment::Reversal with order token' do
204
+ response
205
+ expect(::Afterpay::API::Payment::Reversal).to have_received(:call).with(token: order_token)
206
+ end
207
+ end
154
208
  end
155
209
  end
156
210
 
@@ -158,8 +212,8 @@ RSpec.describe SolidusAfterpay::Gateway do
158
212
  subject(:response) { gateway.purchase(amount, payment_source, gateway_options) }
159
213
 
160
214
  let(:order_token) { '002.nt7e0ioqj00fh0ua1nbqcj6vcn9obtfsglqvrj9ijpo3edfc' }
161
- let(:deferred?) { false }
162
- let(:payment_method) { build(:afterpay_payment_method, preferred_deferred: deferred?) }
215
+ let(:auto_capture) { true }
216
+ let(:payment_method) { build(:afterpay_payment_method, auto_capture: auto_capture) }
163
217
  let(:payment) { build(:afterpay_payment, source: payment_source, payment_method: payment_method) }
164
218
 
165
219
  let(:amount) { 1000 }
@@ -209,7 +263,7 @@ RSpec.describe SolidusAfterpay::Gateway do
209
263
  end
210
264
 
211
265
  context 'with the deferred flow' do
212
- let(:deferred?) { true }
266
+ let(:auto_capture) { false }
213
267
 
214
268
  context 'with valid params', vcr: 'deferred/authorize/valid' do
215
269
  it 'authorize and captures the afterpay payment with the order_token' do
@@ -291,9 +345,9 @@ RSpec.describe SolidusAfterpay::Gateway do
291
345
  describe '#void' do
292
346
  subject(:response) { gateway.void(response_code, gateway_options) }
293
347
 
294
- let(:deferred?) { false }
348
+ let(:auto_capture) { true }
295
349
  let(:amount) { 10 }
296
- let(:payment_method) { build(:afterpay_payment_method, preferred_deferred: deferred?) }
350
+ let(:payment_method) { build(:afterpay_payment_method, auto_capture: auto_capture) }
297
351
  let(:payment) { build(:afterpay_payment, payment_method: payment_method, amount: amount) }
298
352
 
299
353
  let(:response_code) { '100101785223' }
@@ -314,7 +368,7 @@ RSpec.describe SolidusAfterpay::Gateway do
314
368
  end
315
369
 
316
370
  context 'with the deferred flow' do
317
- let(:deferred?) { true }
371
+ let(:auto_capture) { false }
318
372
 
319
373
  context 'with valid params', vcr: 'deferred/void/valid' do
320
374
  it 'voids the payment using the response_code' do
@@ -396,6 +450,26 @@ RSpec.describe SolidusAfterpay::Gateway do
396
450
  end
397
451
  end
398
452
 
453
+ describe '#find_order' do
454
+ subject(:response) { gateway.find_order(token: token) }
455
+
456
+ let(:token) { '002.cb9qevbs1o4el3adh817hqkotkbv4b8u1jkekofd3nb2m8lu' }
457
+
458
+ context 'with valid params', vcr: 'find_order/valid' do
459
+ it 'retrieves the Afterpay order' do
460
+ expect(response).to include(token: token)
461
+ end
462
+ end
463
+
464
+ context 'with an invalid params', vcr: 'find_order/invalid' do
465
+ let(:token) { 'INVALID_TOKEN' }
466
+
467
+ it 'returns nil' do
468
+ is_expected.to be_nil
469
+ end
470
+ end
471
+ end
472
+
399
473
  describe '#retrieve_configuration' do
400
474
  subject(:response) { gateway.retrieve_configuration }
401
475
 
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  RSpec.describe SolidusAfterpay::OrderComponentBuilder do
4
- let(:order) { build(:order_with_line_items) }
4
+ let(:order) { create(:order_with_product_property) }
5
5
  let(:redirect_confirm_url) { 'https://merchantsite.com/confirm' }
6
6
  let(:redirect_cancel_url) { 'https://merchantsite.com/cancel' }
7
7
 
@@ -9,7 +9,9 @@ RSpec.describe SolidusAfterpay::OrderComponentBuilder do
9
9
  described_class.new(
10
10
  order: order,
11
11
  redirect_confirm_url: redirect_confirm_url,
12
- redirect_cancel_url: redirect_cancel_url
12
+ redirect_cancel_url: redirect_cancel_url,
13
+ mode: nil,
14
+ popup_origin_url: nil
13
15
  )
14
16
  end
15
17
 
@@ -40,6 +42,8 @@ RSpec.describe SolidusAfterpay::OrderComponentBuilder do
40
42
  discounts: nil,
41
43
  items: [
42
44
  Afterpay::Components::Item.new(
45
+ preorder: true,
46
+ estimated_shipment_date: "2025-10-25",
43
47
  name: order.line_items.first.name,
44
48
  price: Afterpay::Components::Money.new(
45
49
  amount: '10.0',
@@ -95,6 +99,8 @@ RSpec.describe SolidusAfterpay::OrderComponentBuilder do
95
99
  discounts: nil,
96
100
  items: [
97
101
  Afterpay::Components::Item.new(
102
+ estimated_shipment_date: "2025-10-25",
103
+ preorder: true,
98
104
  name: order.line_items.first.name,
99
105
  price: Afterpay::Components::Money.new(
100
106
  amount: '10.0',
@@ -126,12 +132,67 @@ RSpec.describe SolidusAfterpay::OrderComponentBuilder do
126
132
  )
127
133
  end
128
134
 
129
- let(:expected_result) do
130
- SolidusSupport.combined_first_and_last_name_in_address? ? expected_result_combined : expected_result_not_combined
135
+ context 'when solidus combines first and last name' do
136
+ before do
137
+ allow(SolidusSupport)
138
+ .to receive(:combined_first_and_last_name_in_address?)
139
+ .and_return(true)
140
+ end
141
+
142
+ it 'returns the correct payload' do
143
+ expect(result.as_json).to eq(expected_result_combined.as_json)
144
+ end
145
+ end
146
+
147
+ context 'when solidus does not combine first and last name' do
148
+ before do
149
+ allow(SolidusSupport)
150
+ .to receive(:combined_first_and_last_name_in_address?)
151
+ .and_return(false)
152
+
153
+ # rubocop:disable RSpec/AnyInstance
154
+ allow_any_instance_of(Spree::Address)
155
+ .to receive(:first_name)
156
+ .and_return('John')
157
+
158
+ allow_any_instance_of(Spree::Address)
159
+ .to receive(:last_name)
160
+ .and_return(nil)
161
+ # rubocop:enable RSpec/AnyInstance
162
+ end
163
+
164
+ it 'returns the correct payload' do
165
+ expect(result.as_json).to eq(expected_result_not_combined.as_json)
166
+ end
131
167
  end
132
168
 
133
- it 'returns the correct payload' do
134
- expect(result.as_json).to eq(expected_result.as_json)
169
+ context "when provided an estimated shipment date" do
170
+ context "when provided a product estimated shipment date" do
171
+ it "returns the correct estimated shipment date" do
172
+ expect(result.items.first.estimated_shipment_date).to match("2025-10-25")
173
+ end
174
+
175
+ it "returns true if the estimated shipping date didn't pass yet" do
176
+ expect(result.items.first.preorder).to be_truthy
177
+ end
178
+ end
179
+
180
+ context "when provided a variant estimated shipment date" do
181
+ let(:order) { create(:order_with_variant_property) }
182
+
183
+ it 'contains the correct estimated shipment date' do
184
+ expect(result.items.first.estimated_shipment_date).to match("2021-09-19")
185
+ end
186
+
187
+ it 'returns the variant estimated shipment date when product and variant properties are set' do
188
+ order.line_items.first.product.set_property("estimatedShipmentDate", "2025-10-25")
189
+ expect(result.items.first.estimated_shipment_date).to match("2021-09-19")
190
+ end
191
+
192
+ it "returns false when the estimated shipping date passed" do
193
+ expect(result.items.first.preorder).to be_falsey
194
+ end
195
+ end
135
196
  end
136
197
  end
137
198
  end
@@ -58,79 +58,104 @@ RSpec.describe SolidusAfterpay::PaymentMethod, type: :model do
58
58
  end
59
59
  end
60
60
 
61
- describe "#available_for_order?" do
62
- subject { payment_method.available_for_order?(order) }
61
+ describe "#excluded_product?" do
62
+ subject { payment_method.excluded_product?(product) }
63
63
 
64
- let(:preferred_minimum_amount) { nil }
65
- let(:preferred_maximum_amount) { nil }
66
- let(:preferred_currency) { nil }
64
+ let(:product) { create(:base_product) }
65
+ let(:excluded_product_ids) { product.id.to_s }
66
+ let(:payment_method) { described_class.new(preferred_excluded_products: excluded_product_ids) }
67
67
 
68
- let(:payment_method) do
69
- described_class.new(
70
- preferred_minimum_amount: preferred_minimum_amount,
71
- preferred_maximum_amount: preferred_maximum_amount,
72
- preferred_currency: preferred_currency
73
- )
68
+ context 'when the product is excluded' do
69
+ it { is_expected.to be_truthy }
74
70
  end
75
71
 
76
- let(:order) { build(:order, currency: order_currency, total: order_total) }
77
- let(:order_total) { 5 }
78
- let(:order_currency) { 'USD' }
79
-
80
- let(:configuration) do
81
- require 'hashie'
72
+ context 'when the product is not excluded' do
73
+ let(:excluded_product_ids) { '' }
82
74
 
83
- Hashie::Mash.new({
84
- minimumAmount: { amount: '1', currency: 'USD' },
85
- maximumAmount: { amount: '10', currency: 'USD' }
86
- })
75
+ it { is_expected.to be_falsey }
87
76
  end
77
+ end
88
78
 
89
- before do
90
- allow(payment_method.gateway).to receive(:retrieve_configuration).and_return(configuration)
79
+ describe "#available_for_order?" do
80
+ subject { payment_method.available_for_order?(order) }
81
+
82
+ let(:product) { create(:base_product) }
83
+ let(:excluded_product_ids) { '' }
84
+ let(:payment_method) { create(:afterpay_payment_method, preferred_excluded_products: excluded_product_ids) }
85
+ let(:order) {
86
+ build(:order_with_line_items, currency: order_currency,
87
+ line_items_attributes: line_items_attributes)
88
+ }
89
+ let(:line_items_attributes) do
90
+ [{ product: product }]
91
91
  end
92
+ let(:order_currency) { 'USD' }
92
93
 
93
- context 'when preference settings are nil' do
94
+ context "with cache" do
94
95
  context 'when order total is inside the range' do
96
+ before do
97
+ Rails.cache.write("solidus_afterpay_configuration_maximumAmount_currency", "USD")
98
+ Rails.cache.write("solidus_afterpay_configuration_maximumAmount_amount", 1000.0)
99
+ Rails.cache.write("solidus_afterpay_configuration_minimumAmount_amount", 1.0)
100
+ end
101
+
95
102
  it { is_expected.to be(true) }
96
103
  end
97
104
 
98
105
  context 'when order total is outside the range' do
99
- let(:order_total) { 11 }
106
+ before do
107
+ Rails.cache.write("solidus_afterpay_configuration_maximumAmount_currency", "USD")
108
+ Rails.cache.write("solidus_afterpay_configuration_maximumAmount_amount", 4.0)
109
+ Rails.cache.write("solidus_afterpay_configuration_minimumAmount_amount", 1.0)
110
+ end
100
111
 
101
112
  it { is_expected.to be(false) }
102
113
  end
103
114
 
104
115
  context 'when order currency is different from afterpay configuration' do
105
- let(:order_currency) { 'EUR' }
116
+ before do
117
+ Rails.cache.write("solidus_afterpay_configuration_maximumAmount_amount", 1000.0)
118
+ Rails.cache.write("solidus_afterpay_configuration_minimumAmount_amount", 1.0)
119
+ Rails.cache.write("solidus_afterpay_configuration_maximumAmount_currency", "EUR")
120
+ end
106
121
 
107
122
  it { is_expected.to be(false) }
108
123
  end
109
124
 
110
- context "when afterpay configuration doesn't include the minumumAmount" do
111
- let(:configuration) do
112
- require 'hashie'
113
-
114
- Hashie::Mash.new({ maximumAmount: { amount: '10', currency: 'USD' } })
125
+ context 'when order currency is the same from afterpay configuration' do
126
+ before do
127
+ Rails.cache.write("solidus_afterpay_configuration_maximumAmount_amount", 1000.0)
128
+ Rails.cache.write("solidus_afterpay_configuration_minimumAmount_amount", 1.0)
129
+ Rails.cache.write("solidus_afterpay_configuration_maximumAmount_currency", "USD")
115
130
  end
116
131
 
117
132
  it { is_expected.to be(true) }
118
133
  end
119
134
  end
120
135
 
121
- context 'when preference settings are not nil' do
122
- let(:preferred_minimum_amount) { 1 }
123
- let(:preferred_maximum_amount) { 10 }
124
- let(:preferred_currency) { 'USD' }
136
+ context 'when there is no cache' do
137
+ let(:configuration) do
138
+ require 'hashie'
125
139
 
126
- context 'when order total is inside the range' do
140
+ Hashie::Mash.new({
141
+ minimumAmount: { amount: '1', currency: 'USD' },
142
+ maximumAmount: { amount: '110', currency: 'USD' }
143
+ })
144
+ end
145
+
146
+ before do
147
+ allow(payment_method.gateway).to receive(:retrieve_configuration).and_return(configuration)
148
+ end
149
+
150
+ context 'when order total is inside the range and the currency is the same from afterpay configuration' do
127
151
  it { is_expected.to be(true) }
128
152
  end
129
153
 
130
154
  context 'when order total is outside the range' do
131
- let(:order_total) { 11 }
132
-
133
- it { is_expected.to be(false) }
155
+ it do
156
+ order.update(total: 111)
157
+ is_expected.to be(false)
158
+ end
134
159
  end
135
160
 
136
161
  context 'when order currency is different from afterpay configuration' do
@@ -139,5 +164,44 @@ RSpec.describe SolidusAfterpay::PaymentMethod, type: :model do
139
164
  it { is_expected.to be(false) }
140
165
  end
141
166
  end
167
+
168
+ context "when the items are excluded from the payment_method" do
169
+ let(:excluded_product_ids) { product.id.to_s }
170
+
171
+ context "when the id's of all the products are excluded" do
172
+ it { is_expected.to be_falsey }
173
+ end
174
+
175
+ context "when the id of one of the products is excluded" do
176
+ let(:second_product) { create(:base_product) }
177
+ let(:line_items_attributes) do
178
+ [{ product: product }, { product: second_product }]
179
+ end
180
+
181
+ it { is_expected.to be(false) }
182
+ end
183
+ end
184
+
185
+ context "when none of the items are excluded from the payment_method" do
186
+ let(:configuration) do
187
+ require 'hashie'
188
+
189
+ Hashie::Mash.new({
190
+ minimumAmount: { amount: '1', currency: 'USD' },
191
+ maximumAmount: { amount: '1000', currency: 'USD' }
192
+ })
193
+ end
194
+
195
+ let(:excluded_product_ids) { '' }
196
+
197
+ before do
198
+ Rails.cache.clear
199
+ allow(payment_method.gateway).to receive(:retrieve_configuration).and_return(configuration)
200
+ end
201
+
202
+ it "returns true when none of the products are excluded" do
203
+ is_expected.to be(true)
204
+ end
205
+ end
142
206
  end
143
207
  end
@@ -14,8 +14,8 @@ RSpec.describe SolidusAfterpay::PaymentSource, type: :model do
14
14
  describe '#can_void?' do
15
15
  subject { payment_source.can_void?(payment) }
16
16
 
17
- let(:deferred?) { false }
18
- let(:payment_method) { build(:afterpay_payment_method, preferred_deferred: deferred?) }
17
+ let(:auto_capture) { true }
18
+ let(:payment_method) { build(:afterpay_payment_method, auto_capture: auto_capture) }
19
19
  let(:payment) { build(:afterpay_payment, payment_method: payment_method) }
20
20
 
21
21
  context 'with the immediate flow' do
@@ -25,7 +25,7 @@ RSpec.describe SolidusAfterpay::PaymentSource, type: :model do
25
25
  end
26
26
 
27
27
  context 'with the deferred flow' do
28
- let(:deferred?) { true }
28
+ let(:auto_capture) { false }
29
29
 
30
30
  let(:payment_state) { 'AUTH_APPROVED' }
31
31
  let(:gateway_response) { { paymentState: payment_state } }
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe SolidusAfterpay::OrderPresenter do
6
+ describe '#line_items_tax_amount' do
7
+ subject(:line_items_tax_amount) { described_class.new(order: order).line_items_tax_amount }
8
+
9
+ describe '#line_items_tax_amount' do
10
+ before do
11
+ country = create(:country)
12
+ state = create(:state, country: country)
13
+ zone = create(:zone, country_ids: [country.id], state_ids: [state.id])
14
+ create(:tax_rate, zone: zone)
15
+ end
16
+
17
+ context 'when the order has line items' do
18
+ let(:order) { create(:order_with_line_items, line_items_count: 2) }
19
+
20
+ it 'returns the line items tax total amout' do
21
+ expect(line_items_tax_amount).to eq(2.0)
22
+ end
23
+ end
24
+
25
+ context 'when the order does not have line items' do
26
+ let(:order) { create(:order) }
27
+
28
+ it 'returns 0' do
29
+ expect(line_items_tax_amount).to eq(0)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe SolidusAfterpay::ShippingRatePresenter do
6
+ let(:order) { create(:order_with_line_items ) }
7
+ let(:shipment) { create(:shipment, order: order) }
8
+ let(:shipping_rate) { create(:shipping_rate, cost: 5, shipment: shipment) }
9
+ let(:shipping_rate_tax) { ::Spree::ShippingRateTax.create(amount: 0.75, shipping_rate: shipping_rate) }
10
+
11
+ before { shipping_rate.taxes << shipping_rate_tax }
12
+
13
+ describe '#order_amount' do
14
+ subject(:order_amount) { described_class.new(shipping_rate: shipping_rate).order_amount }
15
+
16
+ it 'returns the order total including the shipping rate' do
17
+ expect(order_amount.to_f).to eq(15.75)
18
+ end
19
+ end
20
+
21
+ describe '#amount_with_taxes' do
22
+ subject(:amount_with_taxes) { described_class.new(shipping_rate: shipping_rate).amount_with_taxes }
23
+
24
+ it 'returns the total amount including taxes' do
25
+ expect(amount_with_taxes.to_f).to eq(5.75)
26
+ end
27
+ end
28
+ end
@@ -70,7 +70,9 @@ describe SolidusAfterpay::CheckoutsController, type: :request do
70
70
  expect(gateway).to have_received(:create_checkout).with(
71
71
  order,
72
72
  redirect_confirm_url: redirect_confirm_url,
73
- redirect_cancel_url: redirect_cancel_url
73
+ redirect_cancel_url: redirect_cancel_url,
74
+ mode: nil,
75
+ popup_origin_url: nil
74
76
  )
75
77
  end
76
78
  end
@@ -80,15 +82,49 @@ describe SolidusAfterpay::CheckoutsController, type: :request do
80
82
  let(:redirect_cancel_url) { 'http://www.example.com/cancel_url' }
81
83
 
82
84
  let(:params) do
83
- { order_number: order_number, payment_method_id: payment_method_id,
84
- redirect_confirm_url: redirect_confirm_url, redirect_cancel_url: redirect_cancel_url }
85
+ {
86
+ order_number: order_number,
87
+ payment_method_id: payment_method_id,
88
+ redirect_confirm_url: redirect_confirm_url,
89
+ redirect_cancel_url: redirect_cancel_url
90
+ }
85
91
  end
86
92
 
87
93
  it 'calls the create_checkout with the correct arguments' do
88
94
  expect(gateway).to have_received(:create_checkout).with(
89
95
  order,
90
96
  redirect_confirm_url: redirect_confirm_url,
91
- redirect_cancel_url: redirect_cancel_url
97
+ redirect_cancel_url: redirect_cancel_url,
98
+ mode: nil,
99
+ popup_origin_url: nil
100
+ )
101
+ end
102
+ end
103
+
104
+ context 'when the mode is passed as params' do
105
+ let(:params) do
106
+ {
107
+ order_number: order_number,
108
+ payment_method_id: payment_method_id,
109
+ mode: 'express'
110
+ }
111
+ end
112
+
113
+ let(:redirect_confirm_url) do
114
+ "http://www.example.com/solidus_afterpay/callbacks/confirm?order_number=#{order.number}&payment_method_id=#{payment_method.id}"
115
+ end
116
+
117
+ let(:redirect_cancel_url) do
118
+ "http://www.example.com/solidus_afterpay/callbacks/cancel?order_number=#{order.number}&payment_method_id=#{payment_method.id}"
119
+ end
120
+
121
+ it 'calls the create_checkout with the correct arguments' do
122
+ expect(gateway).to have_received(:create_checkout).with(
123
+ order,
124
+ redirect_confirm_url: redirect_confirm_url,
125
+ redirect_cancel_url: redirect_cancel_url,
126
+ popup_origin_url: nil,
127
+ mode: 'express'
92
128
  )
93
129
  end
94
130
  end
@@ -122,6 +158,38 @@ describe SolidusAfterpay::CheckoutsController, type: :request do
122
158
  end
123
159
  end
124
160
 
161
+ context 'when the payment_method_id is not passed as param' do
162
+ let(:redirect_confirm_url) do
163
+ "http://www.example.com/solidus_afterpay/callbacks/confirm?order_number=#{order.number}&payment_method_id=#{payment_method.id}"
164
+ end
165
+
166
+ let(:redirect_cancel_url) do
167
+ "http://www.example.com/solidus_afterpay/callbacks/cancel?order_number=#{order.number}&payment_method_id=#{payment_method.id}"
168
+ end
169
+
170
+ let(:params) do
171
+ {
172
+ order_number: order_number,
173
+ mode: 'express'
174
+ }
175
+ end
176
+
177
+ before do
178
+ payment_method
179
+ request
180
+ end
181
+
182
+ it 'uses the first solidus afterpay payment method' do
183
+ expect(gateway).to have_received(:create_checkout).with(
184
+ order,
185
+ redirect_confirm_url: redirect_confirm_url,
186
+ redirect_cancel_url: redirect_cancel_url,
187
+ popup_origin_url: nil,
188
+ mode: 'express'
189
+ )
190
+ end
191
+ end
192
+
125
193
  context 'when the gateway responds with error' do
126
194
  let(:gateway_response_success?) { false }
127
195
  let(:gateway_response_message) { 'Error message' }