solidus_stripe 4.4.1 → 5.0.0.alpha.1

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 (153) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +92 -52
  3. data/.gitignore +3 -0
  4. data/.rubocop.yml +94 -4
  5. data/.yardopts +1 -0
  6. data/Gemfile +10 -30
  7. data/LICENSE +2 -2
  8. data/Procfile.dev +3 -0
  9. data/README.md +145 -215
  10. data/Rakefile +5 -44
  11. data/app/assets/javascripts/spree/backend/solidus_stripe.js +2 -0
  12. data/app/assets/stylesheets/spree/backend/solidus_stripe.css +4 -0
  13. data/app/controllers/solidus_stripe/intents_controller.rb +36 -52
  14. data/app/controllers/solidus_stripe/webhooks_controller.rb +28 -0
  15. data/app/models/concerns/solidus_stripe/log_entries.rb +31 -0
  16. data/app/models/solidus_stripe/customer.rb +21 -0
  17. data/app/models/solidus_stripe/gateway.rb +231 -0
  18. data/app/models/solidus_stripe/payment_intent.rb +111 -0
  19. data/app/models/solidus_stripe/payment_method.rb +106 -0
  20. data/app/models/solidus_stripe/payment_source.rb +31 -0
  21. data/app/models/solidus_stripe/slug_entry.rb +20 -0
  22. data/app/models/solidus_stripe.rb +7 -0
  23. data/app/subscribers/solidus_stripe/webhook/charge_subscriber.rb +28 -0
  24. data/app/subscribers/solidus_stripe/webhook/payment_intent_subscriber.rb +112 -0
  25. data/app/views/spree/admin/payments/source_forms/_stripe.html.erb +29 -0
  26. data/app/views/spree/admin/payments/source_forms/existing_payment/_stripe.html.erb +14 -0
  27. data/app/views/spree/admin/payments/source_forms/existing_payment/stripe/_card.html.erb +8 -0
  28. data/app/views/spree/admin/payments/source_forms/existing_payment/stripe/_default.html.erb +7 -0
  29. data/app/views/spree/admin/payments/source_views/_stripe.html.erb +15 -0
  30. data/app/views/spree/api/payments/source_views/_stripe.json.jbuilder +8 -0
  31. data/bin/dev +13 -0
  32. data/bin/dummy-app +29 -0
  33. data/bin/rails +38 -3
  34. data/bin/rails-dummy-app +3 -0
  35. data/bin/rails-engine +1 -11
  36. data/bin/rails-new +55 -0
  37. data/bin/rails-sandbox +1 -14
  38. data/bin/rspec +10 -0
  39. data/bin/sandbox +12 -74
  40. data/bin/setup +1 -0
  41. data/bin/update-migrations +56 -0
  42. data/codecov.yml +12 -0
  43. data/config/locales/en.yml +16 -1
  44. data/config/routes.rb +5 -11
  45. data/coverage.rb +42 -0
  46. data/db/migrate/20230109183332_create_solidus_stripe_payment_sources.rb +10 -0
  47. data/db/migrate/20230303154931_create_solidus_stripe_setup_intent.rb +10 -0
  48. data/db/migrate/20230306105520_create_solidus_stripe_payment_intents.rb +10 -0
  49. data/db/migrate/20230308122414_create_solidus_stripe_webhook_endpoints.rb +10 -0
  50. data/db/migrate/20230310152615_add_payment_method_reference_to_stripe_intents.rb +6 -0
  51. data/db/migrate/20230310171444_normalize_stripe_intent_id_attributes.rb +6 -0
  52. data/db/migrate/20230313150008_create_solidus_stripe_customers.rb +16 -0
  53. data/db/migrate/20230323154931_drop_solidus_stripe_setup_intent.rb +13 -0
  54. data/db/migrate/20230403094916_rename_webhook_endpoint_to_payment_method_slug_entries.rb +5 -0
  55. data/db/seeds.rb +6 -24
  56. data/lib/generators/solidus_stripe/install/install_generator.rb +121 -14
  57. data/lib/generators/solidus_stripe/install/templates/app/assets/stylesheets/spree/frontend/solidus_stripe.css +13 -0
  58. data/lib/generators/solidus_stripe/install/templates/app/javascript/controllers/solidus_stripe_confirm_controller.js +39 -0
  59. data/lib/generators/solidus_stripe/install/templates/app/javascript/controllers/solidus_stripe_payment_controller.js +89 -0
  60. data/lib/generators/solidus_stripe/install/templates/app/views/checkouts/existing_payment/_stripe.html.erb +16 -0
  61. data/lib/generators/solidus_stripe/install/templates/app/views/checkouts/existing_payment/stripe/_card.html.erb +8 -0
  62. data/lib/generators/solidus_stripe/install/templates/app/views/checkouts/existing_payment/stripe/_default.html.erb +7 -0
  63. data/lib/generators/solidus_stripe/install/templates/app/views/checkouts/payment/_stripe.html.erb +39 -0
  64. data/lib/generators/solidus_stripe/install/templates/app/views/orders/payment_info/_stripe.html.erb +20 -0
  65. data/lib/generators/solidus_stripe/install/templates/config/initializers/solidus_stripe.rb +31 -0
  66. data/lib/solidus_stripe/configuration.rb +24 -3
  67. data/lib/solidus_stripe/engine.rb +19 -6
  68. data/lib/solidus_stripe/money_to_stripe_amount_converter.rb +109 -0
  69. data/lib/solidus_stripe/refunds_synchronizer.rb +96 -0
  70. data/lib/solidus_stripe/seeds.rb +19 -0
  71. data/lib/solidus_stripe/testing_support/factories.rb +153 -0
  72. data/lib/solidus_stripe/version.rb +1 -1
  73. data/lib/solidus_stripe/webhook/event.rb +90 -0
  74. data/lib/solidus_stripe.rb +0 -2
  75. data/solidus_stripe.gemspec +29 -6
  76. data/spec/lib/solidus_stripe/configuration_spec.rb +21 -0
  77. data/spec/lib/solidus_stripe/money_to_stripe_amount_converter_spec.rb +133 -0
  78. data/spec/lib/solidus_stripe/refunds_synchronizer_spec.rb +238 -0
  79. data/spec/lib/solidus_stripe/seeds_spec.rb +43 -0
  80. data/spec/lib/solidus_stripe/webhook/event_spec.rb +134 -0
  81. data/spec/models/concerns/solidus_stripe/log_entries_spec.rb +54 -0
  82. data/spec/models/solidus_stripe/customer_spec.rb +47 -0
  83. data/spec/models/solidus_stripe/gateway_spec.rb +283 -0
  84. data/spec/models/solidus_stripe/payment_intent_spec.rb +17 -0
  85. data/spec/models/solidus_stripe/payment_method_spec.rb +137 -0
  86. data/spec/models/solidus_stripe/payment_source_spec.rb +25 -0
  87. data/spec/requests/solidus_stripe/intents_controller_spec.rb +29 -0
  88. data/spec/requests/solidus_stripe/webhooks_controller/charge/refunded_spec.rb +31 -0
  89. data/spec/requests/solidus_stripe/webhooks_controller/payment_intent/canceled_spec.rb +23 -0
  90. data/spec/requests/solidus_stripe/webhooks_controller/payment_intent/payment_failed_spec.rb +23 -0
  91. data/spec/requests/solidus_stripe/webhooks_controller/payment_intent/succeeded_spec.rb +29 -0
  92. data/spec/requests/solidus_stripe/webhooks_controller_spec.rb +52 -0
  93. data/spec/solidus_stripe_spec_helper.rb +10 -0
  94. data/spec/subscribers/solidus_stripe/webhook/charge_subscriber_spec.rb +33 -0
  95. data/spec/subscribers/solidus_stripe/webhook/payment_intent_subscriber_spec.rb +297 -0
  96. data/spec/support/solidus_stripe/backend_test_helper.rb +210 -0
  97. data/spec/support/solidus_stripe/checkout_test_helper.rb +339 -0
  98. data/spec/support/solidus_stripe/factories.rb +5 -0
  99. data/spec/support/solidus_stripe/webhook/data_fixtures.rb +106 -0
  100. data/spec/support/solidus_stripe/webhook/event_with_context_factory.rb +82 -0
  101. data/spec/support/solidus_stripe/webhook/request_helper.rb +32 -0
  102. data/spec/system/backend/solidus_stripe/orders/payments_spec.rb +119 -0
  103. data/spec/system/frontend/.keep +0 -0
  104. data/spec/system/frontend/solidus_stripe/checkout_spec.rb +187 -0
  105. data/tmp/.keep +0 -0
  106. metadata +202 -78
  107. data/.rubocop_todo.yml +0 -298
  108. data/.travis.yml +0 -28
  109. data/app/assets/javascripts/spree/frontend/solidus_stripe/stripe-cart-page-checkout.js +0 -122
  110. data/app/assets/javascripts/spree/frontend/solidus_stripe/stripe-elements.js +0 -148
  111. data/app/assets/javascripts/spree/frontend/solidus_stripe/stripe-init.js +0 -20
  112. data/app/assets/javascripts/spree/frontend/solidus_stripe/stripe-payment-intents.js +0 -84
  113. data/app/assets/javascripts/spree/frontend/solidus_stripe/stripe-payment-request-button-shared.js +0 -160
  114. data/app/assets/javascripts/spree/frontend/solidus_stripe/stripe-payment.js +0 -16
  115. data/app/assets/javascripts/spree/frontend/solidus_stripe.js +0 -6
  116. data/app/controllers/solidus_stripe/payment_request_controller.rb +0 -52
  117. data/app/controllers/spree/stripe_controller.rb +0 -13
  118. data/app/decorators/models/spree/order_update_attributes_decorator.rb +0 -39
  119. data/app/decorators/models/spree/payment_decorator.rb +0 -11
  120. data/app/decorators/models/spree/refund_decorator.rb +0 -9
  121. data/app/models/solidus_stripe/address_from_params_service.rb +0 -72
  122. data/app/models/solidus_stripe/create_intents_payment_service.rb +0 -114
  123. data/app/models/solidus_stripe/prepare_order_for_payment_service.rb +0 -46
  124. data/app/models/solidus_stripe/shipping_rates_service.rb +0 -46
  125. data/app/models/spree/payment_method/stripe_credit_card.rb +0 -230
  126. data/bin/r +0 -13
  127. data/bin/sandbox_rails +0 -18
  128. data/db/migrate/20181010123508_update_stripe_payment_method_type_to_credit_card.rb +0 -21
  129. data/lib/assets/stylesheets/spree/frontend/solidus_stripe.scss +0 -11
  130. data/lib/solidus_stripe/testing_support/card_input_helper.rb +0 -34
  131. data/lib/tasks/solidus_stripe/db/seed.rake +0 -14
  132. data/lib/views/api/spree/api/payments/source_views/_stripe.json.jbuilder +0 -3
  133. data/lib/views/backend/spree/admin/log_entries/_stripe.html.erb +0 -28
  134. data/lib/views/backend/spree/admin/payments/source_forms/_stripe.html.erb +0 -1
  135. data/lib/views/backend/spree/admin/payments/source_views/_stripe.html.erb +0 -1
  136. data/lib/views/frontend/spree/checkout/existing_payment/_stripe.html.erb +0 -1
  137. data/lib/views/frontend/spree/checkout/payment/_stripe.html.erb +0 -8
  138. data/lib/views/frontend/spree/checkout/payment/v2/_javascript.html.erb +0 -78
  139. data/lib/views/frontend/spree/checkout/payment/v3/_elements.html.erb +0 -1
  140. data/lib/views/frontend/spree/checkout/payment/v3/_form_elements.html.erb +0 -40
  141. data/lib/views/frontend/spree/checkout/payment/v3/_intents.html.erb +0 -1
  142. data/lib/views/frontend/spree/checkout/payment/v3/_stripe.html.erb +0 -2
  143. data/lib/views/frontend/spree/orders/_stripe_payment_request_button.html.erb +0 -14
  144. data/spec/features/stripe_checkout_spec.rb +0 -486
  145. data/spec/models/solidus_stripe/address_from_params_service_spec.rb +0 -87
  146. data/spec/models/solidus_stripe/create_intents_payment_service_spec.rb +0 -127
  147. data/spec/models/solidus_stripe/prepare_order_for_payment_service_spec.rb +0 -65
  148. data/spec/models/solidus_stripe/shipping_rates_service_spec.rb +0 -54
  149. data/spec/models/spree/payment_method/stripe_credit_card_spec.rb +0 -354
  150. data/spec/requests/payment_requests_spec.rb +0 -152
  151. data/spec/solidus_frontend_app_template.rb +0 -17
  152. data/spec/spec_helper.rb +0 -37
  153. data/spec/support/solidus_address_helper.rb +0 -15
@@ -1,65 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- RSpec.describe SolidusStripe::PrepareOrderForPaymentService do
6
- let(:service) { described_class.new(address, controller) }
7
-
8
- let(:address) { create :address }
9
- let(:user) { double("Spree::User") }
10
- let(:email) { "foo@example.com" }
11
- let(:order) { create :order_with_line_items, state: :cart, ship_address: nil, bill_address: nil }
12
- let!(:shipping_method) { create :shipping_method, name: 'Air Mail', cost: 15 }
13
- let!(:other_shipping_method) { create :shipping_method, name: 'DHL', cost: 7 }
14
- let(:controller) do
15
- double(
16
- current_order: order,
17
- spree_current_user: user,
18
- params: {
19
- email: email,
20
- shipping_option: { id: shipping_method.id }
21
- }
22
- )
23
- end
24
-
25
- before do
26
- Spree::ZoneMember.create!(zone: Spree::Zone.first, zoneable: address.country)
27
- end
28
-
29
- describe "#call" do
30
- subject { service.call }
31
-
32
- it "sets the order ship and bill address" do
33
- expect { subject }.to change { order.ship_address }.to(address)
34
- .and change { order.bill_address }.to(address)
35
- end
36
-
37
- context "when the user is not logged in" do
38
- let(:user) { nil }
39
-
40
- it "sets the order email to allow guest checkout" do
41
- expect { subject }.to change { order.email }.to(email)
42
- end
43
- end
44
-
45
- it "sets the right shipping rate" do
46
- expect { subject }.to change {
47
- order.shipments.first.selected_shipping_rate.shipping_method_id
48
- }.to(shipping_method.id)
49
- end
50
-
51
- context "when the order can be advanced to payment state" do
52
- it "advances the order to 'payment'" do
53
- expect { subject }.to change { order.state }.to("payment")
54
- end
55
- end
56
-
57
- context "when the order fails to be advanced to payment state" do
58
- before { order.line_items.destroy_all }
59
-
60
- it "leaves the order to a previous state" do
61
- expect { subject }.not_to change { order.state }
62
- end
63
- end
64
- end
65
- end
@@ -1,54 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- RSpec.describe SolidusStripe::ShippingRatesService do
6
- let(:service) { described_class.new(order, user, params) }
7
-
8
- let(:order) { create :order }
9
- let(:user) { Spree::User.new }
10
-
11
- let(:params) do
12
- {
13
- country: Spree::ZoneMember.first.zoneable.iso,
14
- city: "Metropolis",
15
- postalCode: "12345",
16
- recipient: "",
17
- addressLine: []
18
- }
19
- end
20
-
21
- let(:ups_ground) { create(:shipping_method, cost: 5, available_to_all: false) }
22
- let(:air_mail) { create(:shipping_method, cost: 8, name: "Air Mail", available_to_all: false) }
23
-
24
- let(:fl_warehouse) { create(:stock_location, name: "FL Warehouse", shipping_methods: [ups_ground]) }
25
- let(:ca_warehouse) { create(:stock_location, name: "CA Warehouse", shipping_methods: [air_mail]) }
26
-
27
- before do
28
- 2.times { create :inventory_unit, order: order }
29
- Spree::StockLocation.update_all backorderable_default: false
30
- Spree::StockItem.find_by(stock_location: fl_warehouse, variant: order.variants.first).set_count_on_hand(1)
31
- Spree::StockItem.find_by(stock_location: ca_warehouse, variant: order.variants.last).set_count_on_hand(1)
32
- order.create_proposed_shipments
33
- end
34
-
35
- describe "#call" do
36
- subject { service.call }
37
-
38
- context "when there are no common shipping methods for all order shipments" do
39
- it "cannot find any shipping rate" do
40
- expect(subject).to be_empty
41
- end
42
- end
43
-
44
- context "when there are common shipping methods for all order shipments" do
45
- before { fl_warehouse.shipping_methods << ca_warehouse.shipping_methods.first }
46
-
47
- context "when one shipping method is available for all shipments" do
48
- it "sums the shipping rates for the shared shipping method" do
49
- expect(subject).to eql [{ amount: 1600, id: air_mail.id.to_s, label: air_mail.name }]
50
- end
51
- end
52
- end
53
- end
54
- end
@@ -1,354 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe Spree::PaymentMethod::StripeCreditCard do
6
- let(:secret_key) { 'key' }
7
- let(:email) { 'customer@example.com' }
8
- let(:source) { Spree::CreditCard.new }
9
-
10
- let(:bill_address) { nil }
11
-
12
- let(:order) {
13
- double('Spree::Order',
14
- email: email,
15
- bill_address: bill_address,
16
- currency: 'USD',
17
- number: 'NUMBER',
18
- total: 10.99
19
- )
20
- }
21
-
22
- let(:payment) {
23
- double('Spree::Payment',
24
- source: source,
25
- order: order,
26
- amount: order.total
27
- )
28
- }
29
-
30
- let(:gateway) do
31
- double('gateway').tap do |p|
32
- allow(p).to receive(:purchase)
33
- allow(p).to receive(:authorize)
34
- allow(p).to receive(:capture)
35
- end
36
- end
37
-
38
- before do
39
- subject.preferences = { secret_key: secret_key }
40
- allow(subject).to receive(:options_for_purchase_or_auth).and_return(['money', 'cc', 'opts'])
41
- allow(subject).to receive(:gateway).and_return gateway
42
- end
43
-
44
- it 'can enable Stripe.js V3 Elements via preference setting' do
45
- expect do
46
- subject.preferred_v3_elements = true
47
- end.to change { subject.v3_elements? }.from(false).to true
48
- end
49
-
50
- describe '#stripe_config' do
51
- context 'when payment request feature is disabled' do
52
- before { subject.preferences = { publishable_key: 'stripe_key' } }
53
-
54
- it 'includes the basic configuration' do
55
- config = subject.stripe_config(order)
56
- expect(config.keys).to eq %i[id publishable_key]
57
- expect(config[:publishable_key]).to include('stripe_key')
58
- end
59
- end
60
-
61
- context 'when the payment request feature is enabled' do
62
- before do
63
- subject.preferences = {
64
- publishable_key: 'stripe_key',
65
- stripe_country: 'US',
66
- v3_intents: true
67
- }
68
- end
69
-
70
- it 'includes the payment request configuration as well' do
71
- config = subject.stripe_config(order)
72
- expect(config.keys).to eq %i[id publishable_key payment_request]
73
- expect(config[:payment_request][:currency]).to eq 'usd'
74
- expect(config[:payment_request][:amount]).to be 1099
75
- expect(config[:payment_request][:label]).to include 'NUMBER'
76
- end
77
- end
78
- end
79
-
80
- describe '#create_profile' do
81
- before do
82
- allow(payment.source).to receive(:update_attributes!)
83
- end
84
-
85
- context 'with an order that has a bill address' do
86
- let(:bill_address) {
87
- double('Spree::Address',
88
- address1: '123 Happy Road',
89
- address2: 'Apt 303',
90
- city: 'Suzarac',
91
- zipcode: '95671',
92
- state: double('Spree::State', name: 'Oregon'),
93
- country: double('Spree::Country', name: 'United States'))
94
- }
95
-
96
- it 'stores the bill address with the gateway' do
97
- expect(subject.gateway).to receive(:store).with(payment.source, {
98
- email: email,
99
- login: secret_key,
100
-
101
- address: {
102
- address1: '123 Happy Road',
103
- address2: 'Apt 303',
104
- city: 'Suzarac',
105
- zip: '95671',
106
- state: 'Oregon',
107
- country: 'United States'
108
- }
109
- }).and_return double.as_null_object
110
-
111
- subject.create_profile payment
112
- end
113
- end
114
-
115
- context 'with an order that does not have a bill address' do
116
- it 'does not store a bill address with the gateway' do
117
- expect(subject.gateway).to receive(:store).with(payment.source, {
118
- email: email,
119
- login: secret_key,
120
- }).and_return double.as_null_object
121
-
122
- subject.create_profile payment
123
- end
124
-
125
- # Regression test for #141
126
- context "correcting the card type" do
127
- before do
128
- # We don't care about this method for these tests
129
- allow(subject.gateway).to receive(:store).and_return(double.as_null_object)
130
- end
131
-
132
- it "converts 'American Express' to 'american_express'" do
133
- payment.source.cc_type = 'American Express'
134
- subject.create_profile(payment)
135
- expect(payment.source.cc_type).to eq('american_express')
136
- end
137
-
138
- it "converts 'Diners Club' to 'diners_club'" do
139
- payment.source.cc_type = 'Diners Club'
140
- subject.create_profile(payment)
141
- expect(payment.source.cc_type).to eq('diners_club')
142
- end
143
-
144
- it "converts 'Visa' to 'visa'" do
145
- payment.source.cc_type = 'Visa'
146
- subject.create_profile(payment)
147
- expect(payment.source.cc_type).to eq('visa')
148
- end
149
- end
150
- end
151
-
152
- context 'with a card represents payment_profile' do
153
- let(:source) { Spree::CreditCard.new(gateway_payment_profile_id: 'tok_profileid') }
154
- let(:bill_address) { nil }
155
-
156
- it 'stores the profile_id as a card' do
157
- expect(subject.gateway).to receive(:store).with(source.gateway_payment_profile_id, anything).and_return double.as_null_object
158
-
159
- subject.create_profile payment
160
- end
161
- end
162
- end
163
-
164
- context 'purchasing' do
165
- after do
166
- subject.purchase(19.99, 'credit card', {})
167
- end
168
-
169
- it 'send the payment to the gateway' do
170
- expect(gateway).to receive(:purchase).with('money', 'cc', 'opts')
171
- end
172
- end
173
-
174
- context 'purchasing with fractionless currency' do
175
- after do
176
- subject.purchase(1999, 'credit card', { currency: 'JPY' })
177
- end
178
-
179
- it 'send the payment to the gateway' do
180
- expect(gateway).to receive(:purchase).with('money', 'cc', 'opts')
181
- end
182
- end
183
-
184
- context 'authorizing' do
185
- after do
186
- subject.authorize(19.99, 'credit card', {})
187
- end
188
-
189
- it 'send the authorization to the gateway' do
190
- expect(gateway).to receive(:authorize).with('money', 'cc', 'opts')
191
- end
192
- end
193
-
194
- context 'authorizing with fractionless currency' do
195
- after do
196
- subject.authorize(1999, 'credit card', { currency: 'JPY' })
197
- end
198
-
199
- it 'send the authorization to the gateway' do
200
- expect(gateway).to receive(:authorize).with('money', 'cc', 'opts')
201
- end
202
- end
203
-
204
- context 'capturing' do
205
- after do
206
- subject.capture(1234, 'response_code', {})
207
- end
208
-
209
- it 'convert the amount to cents' do
210
- expect(gateway).to receive(:capture).with(1234, anything, anything)
211
- end
212
-
213
- it 'use the response code as the authorization' do
214
- expect(gateway).to receive(:capture).with(anything, 'response_code', anything)
215
- end
216
- end
217
-
218
- context 'capturing with fractionless currency' do
219
- after do
220
- subject.capture(1234, 'response_code', { currency: 'JPY' })
221
- end
222
-
223
- it 'amount not converted to cents' do
224
- expect(gateway).to receive(:capture).with(Spree::Money.new(123_400, { currency: 'JPY' }), anything, anything)
225
- end
226
-
227
- it 'use the response code as the authorization' do
228
- expect(gateway).to receive(:capture).with(anything, 'response_code', anything)
229
- end
230
- end
231
-
232
- context 'capture with payment class' do
233
- let(:payment_method) do
234
- payment_method = described_class.new(active: true)
235
- payment_method.set_preference :secret_key, secret_key
236
- allow(payment_method).to receive(:options_for_purchase_or_auth).and_return(['money', 'cc', 'opts'])
237
- allow(payment_method).to receive(:gateway).and_return gateway
238
- allow(payment_method).to receive_messages source_required: true
239
- payment_method
240
- end
241
-
242
- let!(:store) { FactoryBot.create(:store) }
243
- let(:order) { Spree::Order.create! }
244
-
245
- let(:card) do
246
- FactoryBot.create(
247
- :credit_card,
248
- gateway_customer_profile_id: 'cus_abcde',
249
- imported: false
250
- )
251
- end
252
-
253
- let(:payment) do
254
- payment = Spree::Payment.new
255
- payment.source = card
256
- payment.order = order
257
- payment.payment_method = payment_method
258
- payment.amount = 98.55
259
- payment.state = 'pending'
260
- payment.response_code = '12345'
261
- payment
262
- end
263
-
264
- let!(:success_response) do
265
- ActiveMerchant::Billing::Response.new(
266
- true,
267
- nil,
268
- {},
269
- avs_result: { 'code' => 'avs-code' },
270
- cvv_result: 'cvv-code',
271
- authorization: '123',
272
- )
273
- end
274
-
275
- after do
276
- payment.capture!
277
- end
278
-
279
- it 'gets correct amount' do
280
- expect(gateway).to receive(:capture).with(9855, '12345', anything).and_return(success_response)
281
- end
282
- end
283
-
284
- describe '#try_void' do
285
- let(:payment) { create :payment, amount: order.total }
286
-
287
- shared_examples 'voids the payment transaction' do
288
- it 'voids the payment transaction' do
289
- expect(gateway).to receive(:void)
290
-
291
- subject.try_void(payment)
292
- end
293
- end
294
-
295
- context 'when using Payment Intents' do
296
- before { subject.preferred_v3_intents = true }
297
-
298
- context 'when the payment is completed' do
299
- before do
300
- allow(payment).to receive(:completed?) { true }
301
- end
302
-
303
- it 'creates a refund' do
304
- expect { subject.try_void(payment) }.to change { Spree::Refund.count }.by(1)
305
- end
306
- end
307
-
308
- context 'when the payment is not completed' do
309
- it_behaves_like 'voids the payment transaction'
310
- end
311
- end
312
-
313
- context 'when not using Payment Intents' do
314
- before { subject.preferred_v3_intents = false }
315
-
316
- context 'when the payment is completed' do
317
- it_behaves_like 'voids the payment transaction'
318
- end
319
-
320
- context 'when the payment is not completed' do
321
- it_behaves_like 'voids the payment transaction'
322
- end
323
- end
324
- end
325
-
326
- describe '#options_for_purchase_or_auth' do
327
- let(:card) do
328
- FactoryBot.create(
329
- :credit_card,
330
- gateway_customer_profile_id: 'cus_abcde',
331
- imported: false
332
- )
333
- end
334
-
335
- before do
336
- allow(subject).to receive(:options_for_purchase_or_auth).and_call_original
337
- end
338
-
339
- context 'transaction_options' do
340
- it 'includes basic values and keys' do
341
- options = subject.send(:options_for_purchase_or_auth, 19.99, card, {})
342
- expect(options[0]).to eq(19.99)
343
- expect(options[1]).to eq(card)
344
- expect(options[2].keys).to eq([:description, :currency, :customer])
345
- end
346
-
347
- it 'includes statement_descriptor_suffix within options' do
348
- transaction_options = { statement_descriptor_suffix: 'FFFFFFF' }
349
- options = subject.send(:options_for_purchase_or_auth, 19.99, card, transaction_options)
350
- expect(options.last[:statement_descriptor_suffix]).to eq('FFFFFFF')
351
- end
352
- end
353
- end
354
- end
@@ -1,152 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
-
5
- RSpec.describe "Payment Request", type: :request do
6
- describe "POST /stripe/update_order" do
7
- it "responds with { success: true } when the order is correctly updated" do
8
- order = create(:order_ready_to_complete)
9
- allow_any_instance_of(SolidusStripe::PaymentRequestController).to receive(:current_order).and_return(order)
10
-
11
- with_disabled_forgery_protection do
12
- post "/stripe/update_order", params: stripe_update_request_params(order: order)
13
- end
14
-
15
- json = JSON.parse(response.body)
16
- expect(json["success"]).to be_truthy
17
- end
18
-
19
- context "when phone number is provided as param and already set on the address" do
20
- it "overrides the address field" do
21
- order = create(:order_ready_to_complete)
22
- allow_any_instance_of(SolidusStripe::PaymentRequestController).to receive(:current_order).and_return(order)
23
-
24
- expect {
25
- with_disabled_forgery_protection do
26
- post "/stripe/update_order", params: stripe_update_request_params(order: order, shipping_address: default_shipping_address(phone: nil), phone: '911')
27
- end
28
- }.to change { order.shipping_address.phone }.to('911')
29
- end
30
- end
31
-
32
- context "when phone number is provided both as shipping address param and main param, and already set on the address" do
33
- it "overrides the address field giving precedence to the shipping address param" do
34
- order = create(:order_ready_to_complete)
35
- allow_any_instance_of(SolidusStripe::PaymentRequestController).to receive(:current_order).and_return(order)
36
-
37
- expect {
38
- with_disabled_forgery_protection do
39
- post "/stripe/update_order", params: stripe_update_request_params(order: order, shipping_address: default_shipping_address(phone: '555'), phone: '911')
40
- end
41
- }.to change { order.shipping_address.phone }.to('555')
42
- end
43
- end
44
-
45
- context "when phone number is not required, not provided as param and not set on the shipping address" do
46
- it "does not populate the address field" do
47
- with_address_phone_not_required
48
- order = create(:order_ready_to_complete, shipping_address: create(:address, phone: nil))
49
- allow_any_instance_of(SolidusStripe::PaymentRequestController).to receive(:current_order).and_return(order)
50
-
51
- expect {
52
- with_disabled_forgery_protection do
53
- post "/stripe/update_order", params: stripe_update_request_params(order: order, shipping_address: default_shipping_address(phone: nil), phone: nil)
54
- end
55
- }.not_to change { order.shipping_address.phone }
56
- end
57
- end
58
-
59
- context "when phone number is not required, provided as param and not set on the shipping address" do
60
- it "populates the address field with the phone passed as param" do
61
- with_address_phone_not_required
62
- order = create(:order_ready_to_complete, shipping_address: create(:address, phone: nil))
63
- allow_any_instance_of(SolidusStripe::PaymentRequestController).to receive(:current_order).and_return(order)
64
-
65
- expect {
66
- with_disabled_forgery_protection do
67
- post "/stripe/update_order", params: stripe_update_request_params(order: order, shipping_address: default_shipping_address(phone: nil), phone: '911')
68
- end
69
- }.to change { order.shipping_address.phone }.from(nil).to('911')
70
- end
71
- end
72
-
73
- context "when phone number is not required, provided as param but already set on the shipping address" do
74
- it "populates the address field with the phone passed in the shipping field" do
75
- with_address_phone_not_required
76
- order = create(:order_ready_to_complete, shipping_address: create(:address, phone: nil))
77
- allow_any_instance_of(SolidusStripe::PaymentRequestController).to receive(:current_order).and_return(order)
78
-
79
- expect {
80
- with_disabled_forgery_protection do
81
- post "/stripe/update_order", params: stripe_update_request_params(order: order, shipping_address: default_shipping_address(phone: '555'), phone: '911')
82
- end
83
- }.to change { order.shipping_address.phone }.from(nil).to('555')
84
- end
85
- end
86
- end
87
-
88
- private
89
-
90
- def with_address_phone_not_required
91
- if Spree::Config.respond_to?(:address_requires_phone)
92
- stub_spree_preferences(address_requires_phone: false)
93
- else
94
- allow_any_instance_of(Spree::Address).to receive(:require_phone?).and_return(false)
95
- end
96
- end
97
-
98
- def with_disabled_forgery_protection
99
- original_allow_forgery_protection_value = ActionController::Base.allow_forgery_protection
100
- ActionController::Base.allow_forgery_protection = false
101
-
102
- yield
103
-
104
- ActionController::Base.allow_forgery_protection = original_allow_forgery_protection_value
105
- end
106
-
107
- def stripe_update_request_params(
108
- order:,
109
- shipping_address: nil,
110
- name: 'Clark Kent',
111
- phone: '555-555-0199'
112
- )
113
-
114
- {
115
- shipping_address: shipping_address || default_shipping_address,
116
- shipping_option: {
117
- id: order.shipments.first.shipping_rates.first.shipping_method.id
118
- },
119
- name: name,
120
- phone: phone,
121
- email: order.email
122
- }
123
- end
124
-
125
- def default_shipping_address(
126
- country: nil,
127
- region: nil,
128
- recipient: 'Clark Kent',
129
- city: 'Metropolis',
130
- postal_code: '12345',
131
- address_line: ['12, Lincoln Rd'],
132
- phone: '555-555-0199'
133
- )
134
-
135
- if country.blank? || region.blank?
136
- state = create(:state)
137
-
138
- country ||= state.country.iso
139
- region ||= state.abbr
140
- end
141
-
142
- {
143
- country: country,
144
- region: region,
145
- recipient: recipient,
146
- city: city,
147
- postalCode: postal_code,
148
- addressLine: address_line,
149
- phone: phone
150
- }
151
- end
152
- end
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- create_file "public/robots.txt"
4
- bundle_command "add solidus_frontend --github solidusio/solidus_frontend --branch #{ENV['SOLIDUS_BRANCH'] || 'main'}"
5
- generate "solidus_frontend:install --auto-accept"
6
- empty_directory 'lib/generators/solidus_frontend/install'
7
-
8
- create_file 'lib/generators/solidus_frontend/install/install_generator.rb', <<-CODE
9
- puts "SolidusFrontend::Generators::InstallGenerator was disabled."
10
- module SolidusFrontend
11
- module Generators
12
- class InstallGenerator < Rails::Generators::Base
13
- class_option :auto_accept, type: :boolean, default: false
14
- end
15
- end
16
- end
17
- CODE
data/spec/spec_helper.rb DELETED
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Configure Rails Environment
4
- ENV['RAILS_ENV'] = 'test'
5
-
6
- # Run Coverage report
7
- require 'solidus_dev_support/rspec/coverage'
8
-
9
- # Create the dummy app if it's still missing.
10
- dummy_env = "#{__dir__}/dummy/config/environment.rb"
11
- system 'bin/rake extension:test_app' unless File.exist? dummy_env
12
- require dummy_env
13
-
14
- # Requires factories and other useful helpers defined in spree_core.
15
- require 'solidus_dev_support/rspec/feature_helper'
16
-
17
- # Requires supporting ruby files with custom matchers and macros, etc,
18
- # in spec/support/ and its subdirectories.
19
- Dir["#{__dir__}/support/**/*.rb"].sort.each { |f| require f }
20
-
21
- # Requires factories defined in lib/solidus_stripe/testing_support/factories.rb
22
- SolidusDevSupport::TestingSupport::Factories.load_for(SolidusStripe::Engine)
23
-
24
- # Requires card input helper defined in lib/solidus_stripe/testing_support/card_input_helper.rb
25
- require 'solidus_stripe/testing_support/card_input_helper'
26
-
27
- RSpec.configure do |config|
28
- config.infer_spec_type_from_file_location!
29
- config.use_transactional_fixtures = false
30
-
31
- config.include SolidusAddressNameHelper, type: :feature
32
- config.include SolidusCardInputHelper, type: :feature
33
-
34
- if Spree.solidus_gem_version < Gem::Version.new('2.11')
35
- config.extend Spree::TestingSupport::AuthorizationHelpers::Request, type: :system
36
- end
37
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Since https://github.com/solidusio/solidus/pull/3524 was merged,
4
- # we need to verify if we're using the single "Name" field or the
5
- # previous first/last name combination.
6
- module SolidusAddressNameHelper
7
- def fill_in_name
8
- if SolidusSupport.combined_first_and_last_name_in_address?
9
- fill_in "Name", with: "Han Solo"
10
- else
11
- fill_in "First Name", with: "Han"
12
- fill_in "Last Name", with: "Solo"
13
- end
14
- end
15
- end