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.
- checksums.yaml +4 -4
- data/README.md +52 -23
- data/app/assets/javascripts/solidus_afterpay/afterpay_checkout.js +11 -11
- data/app/assets/javascripts/solidus_afterpay/afterpay_checkout_button.js +85 -0
- data/app/assets/javascripts/solidus_afterpay/afterpay_init.js +12 -0
- data/app/assets/javascripts/solidus_afterpay/backend/afterpay_autocomplete.js +9 -0
- data/app/assets/javascripts/spree/backend/solidus_afterpay.js +3 -1
- data/app/assets/javascripts/spree/frontend/solidus_afterpay.js +2 -0
- data/app/controllers/solidus_afterpay/checkouts_controller.rb +8 -2
- data/app/controllers/solidus_afterpay/express_callbacks_controller.rb +61 -0
- data/app/decorators/controllers/solidus_afterpay/spree/orders_controller_decorator.rb +13 -0
- data/app/helpers/solidus_afterpay/afterpay_helper.rb +5 -4
- data/app/models/solidus_afterpay/gateway.rb +37 -10
- data/app/models/solidus_afterpay/order_component_builder.rb +34 -5
- data/app/models/solidus_afterpay/payment_method.rb +43 -10
- data/app/models/solidus_afterpay/payment_source.rb +1 -1
- data/app/presentes/solidus_afterpay/order_presenter.rb +17 -0
- data/app/presentes/solidus_afterpay/shipping_rate_presenter.rb +28 -0
- data/app/services/solidus_afterpay/base_service.rb +13 -0
- data/app/services/solidus_afterpay/shipping_rate_builder_service.rb +32 -0
- data/app/services/solidus_afterpay/update_order_addresses_service.rb +45 -0
- data/app/services/solidus_afterpay/update_order_attributes_service.rb +49 -0
- data/app/views/solidus_afterpay/_afterpay_checkout_button.html.erb +9 -0
- data/app/views/solidus_afterpay/_afterpay_javascript.html.erb +4 -1
- data/app/views/spree/api/payments/source_views/_afterpay.json.jbuilder +1 -1
- data/app/views/spree/shared/_afterpay_messaging.html.erb +14 -12
- data/config/locales/en.yml +4 -0
- data/config/routes.rb +2 -0
- data/lib/generators/solidus_afterpay/install/templates/initializer.rb +12 -0
- data/lib/solidus_afterpay/configuration.rb +22 -0
- data/lib/solidus_afterpay/testing_support/factories.rb +20 -0
- data/lib/solidus_afterpay/version.rb +1 -1
- data/solidus_afterpay.gemspec +1 -1
- data/spec/fixtures/vcr_casettes/find_order/invalid.yml +64 -0
- data/spec/fixtures/vcr_casettes/find_order/valid.yml +120 -0
- data/spec/helpers/solidus_afterpay/afterpay_helper_spec.rb +18 -2
- data/spec/models/solidus_afterpay/gateway_spec.rb +86 -12
- data/spec/models/solidus_afterpay/order_component_builder_spec.rb +67 -6
- data/spec/models/solidus_afterpay/payment_method_spec.rb +103 -39
- data/spec/models/solidus_afterpay/payment_source_spec.rb +3 -3
- data/spec/presenters/solidus_afterpay/order_presenter_spec.rb +34 -0
- data/spec/presenters/solidus_afterpay/shipping_rate_presenter_spec.rb +28 -0
- data/spec/requests/solidus_afterpay/checkouts_controller_spec.rb +72 -4
- data/spec/requests/solidus_afterpay/express_callbacks_controller_spec.rb +167 -0
- data/spec/services/solidus_afterpay/base_service_spec.rb +13 -0
- data/spec/services/solidus_afterpay/shipping_rate_builder_service_spec.rb +34 -0
- data/spec/services/solidus_afterpay/update_order_addresses_service_spec.rb +82 -0
- data/spec/services/solidus_afterpay/update_order_attributes_service_spec.rb +58 -0
- data/spec/support/cache.rb +5 -0
- data/spec/support/solidus.rb +1 -0
- data/spec/views/solidus_afterpay/express_checkout_button_spec.rb +33 -0
- data/spec/views/spree/shared/afterpay_messaging_spec.rb +44 -0
- 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(:
|
18
|
-
let(:payment_method) { build(:afterpay_payment_method,
|
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(:
|
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(:
|
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,
|
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(:
|
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(:
|
162
|
-
let(:payment_method) { build(:afterpay_payment_method,
|
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(:
|
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(:
|
348
|
+
let(:auto_capture) { true }
|
295
349
|
let(:amount) { 10 }
|
296
|
-
let(:payment_method) { build(:afterpay_payment_method,
|
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(:
|
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) {
|
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
|
-
|
130
|
-
|
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
|
-
|
134
|
-
|
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 "#
|
62
|
-
subject { payment_method.
|
61
|
+
describe "#excluded_product?" do
|
62
|
+
subject { payment_method.excluded_product?(product) }
|
63
63
|
|
64
|
-
let(:
|
65
|
-
let(:
|
66
|
-
let(:
|
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
|
-
|
69
|
-
|
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
|
-
|
77
|
-
|
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
|
-
|
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
|
-
|
90
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
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
|
122
|
-
let(:
|
123
|
-
|
124
|
-
let(:preferred_currency) { 'USD' }
|
136
|
+
context 'when there is no cache' do
|
137
|
+
let(:configuration) do
|
138
|
+
require 'hashie'
|
125
139
|
|
126
|
-
|
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
|
-
|
132
|
-
|
133
|
-
|
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(:
|
18
|
-
let(:payment_method) { build(:afterpay_payment_method,
|
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(:
|
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
|
-
{
|
84
|
-
|
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' }
|