solidus_afterpay 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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' }