solidus_stripe 1.0.0 → 1.1.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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/.gem_release.yml +2 -5
  3. data/.github/stale.yml +17 -0
  4. data/.gitignore +11 -4
  5. data/.rspec +2 -1
  6. data/.rubocop.yml +2 -319
  7. data/Gemfile +16 -9
  8. data/LICENSE +26 -0
  9. data/README.md +58 -1
  10. data/Rakefile +3 -20
  11. data/app/assets/javascripts/solidus_stripe/stripe-init.js +1 -0
  12. data/app/assets/javascripts/solidus_stripe/stripe-init/base.js +180 -0
  13. data/app/controllers/solidus_stripe/intents_controller.rb +52 -0
  14. data/app/controllers/solidus_stripe/payment_request_controller.rb +42 -0
  15. data/app/controllers/spree/stripe_controller.rb +13 -0
  16. data/app/models/solidus_stripe/address_from_params_service.rb +57 -0
  17. data/app/models/solidus_stripe/prepare_order_for_payment_service.rb +46 -0
  18. data/app/models/solidus_stripe/shipping_rates_service.rb +46 -0
  19. data/app/models/spree/payment_method/stripe_credit_card.rb +57 -8
  20. data/bin/console +17 -0
  21. data/bin/rails +12 -4
  22. data/bin/setup +8 -0
  23. data/config/routes.rb +11 -0
  24. data/lib/assets/stylesheets/spree/frontend/solidus_stripe.scss +5 -0
  25. data/lib/generators/solidus_stripe/install/install_generator.rb +3 -13
  26. data/lib/solidus_stripe/engine.rb +14 -2
  27. data/lib/solidus_stripe/version.rb +1 -1
  28. data/lib/views/frontend/spree/checkout/payment/_stripe.html.erb +2 -0
  29. data/lib/views/frontend/spree/checkout/payment/v2/_javascript.html.erb +13 -12
  30. data/lib/views/frontend/spree/checkout/payment/v3/_elements_js.html.erb +28 -0
  31. data/lib/views/frontend/spree/checkout/payment/v3/_form_elements.html.erb +42 -0
  32. data/lib/views/frontend/spree/checkout/payment/v3/_intents.html.erb +5 -0
  33. data/lib/views/frontend/spree/checkout/payment/v3/_intents_js.html.erb +48 -0
  34. data/lib/views/frontend/spree/checkout/payment/v3/_stripe.html.erb +3 -131
  35. data/lib/views/frontend/spree/orders/_stripe_payment_request_button.html.erb +92 -0
  36. data/solidus_stripe.gemspec +15 -20
  37. data/spec/features/stripe_checkout_spec.rb +196 -35
  38. data/spec/models/solidus_stripe/address_from_params_service_spec.rb +62 -0
  39. data/spec/models/solidus_stripe/prepare_order_for_payment_service_spec.rb +65 -0
  40. data/spec/models/solidus_stripe/shipping_rates_service_spec.rb +54 -0
  41. data/spec/models/spree/payment_method/stripe_credit_card_spec.rb +44 -5
  42. data/spec/spec_helper.rb +9 -7
  43. metadata +38 -136
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe SolidusStripe::AddressFromParamsService do
6
+ let(:service) { described_class.new(params, user) }
7
+ let(:state) { create :state }
8
+
9
+ describe '#call' do
10
+ let(:params) do
11
+ {
12
+ country: state.country.iso,
13
+ region: state.abbr,
14
+ recipient: 'Clark Kent',
15
+ city: 'Metropolis',
16
+ postalCode: '12345',
17
+ addressLine: [ '12, Lincoln Rd']
18
+ }
19
+ end
20
+
21
+ subject { service.call }
22
+
23
+ context "when there is no user" do
24
+ let(:user) { nil }
25
+
26
+ it "returns a non-persisted address model" do
27
+ expect(subject).to be_new_record
28
+ end
29
+ end
30
+
31
+ context "when there is a user" do
32
+ let(:user) { create :user }
33
+
34
+ context "when the user has an address compatible with the params" do
35
+ before do
36
+ user.addresses << create(
37
+ :address, city: params[:city],
38
+ zipcode: params[:postalCode],
39
+ firstname: 'Clark',
40
+ lastname: 'Kent',
41
+ address1: params[:addressLine].first,
42
+ address2: nil
43
+ )
44
+ end
45
+
46
+ it "returns an existing user's address" do
47
+ expect(subject).to eql user.addresses.first
48
+ end
49
+ end
50
+
51
+ context "when no user's address is compatible with the params" do
52
+ before do
53
+ user.addresses << create(:address)
54
+ end
55
+
56
+ it "returns a non-persisted address model" do
57
+ expect(subject).to be_new_record
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,65 @@
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
@@ -0,0 +1,54 @@
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
@@ -7,12 +7,23 @@ describe Spree::PaymentMethod::StripeCreditCard do
7
7
  let(:email) { 'customer@example.com' }
8
8
  let(:source) { Spree::CreditCard.new }
9
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
+
10
22
  let(:payment) {
11
23
  double('Spree::Payment',
12
24
  source: source,
13
- order: double('Spree::Order',
14
- email: email,
15
- bill_address: bill_address))
25
+ order: order
26
+ )
16
27
  }
17
28
 
18
29
  let(:gateway) do
@@ -35,6 +46,36 @@ describe Spree::PaymentMethod::StripeCreditCard do
35
46
  end.to change { subject.v3_elements? }.from(false).to true
36
47
  end
37
48
 
49
+ describe '#stripe_config' do
50
+ context 'when payment request feature is disabled' do
51
+ before { subject.preferences = { publishable_key: 'stripe_key' } }
52
+
53
+ it 'includes the basic configuration' do
54
+ config = subject.stripe_config(order)
55
+ expect(config.keys).to eq %i[id publishable_key]
56
+ expect(config[:publishable_key]).to include('stripe_key')
57
+ end
58
+ end
59
+
60
+ context 'when the payment request feature is enabled' do
61
+ before do
62
+ subject.preferences = {
63
+ publishable_key: 'stripe_key',
64
+ stripe_country: 'US',
65
+ v3_intents: true
66
+ }
67
+ end
68
+
69
+ it 'includes the payment request configuration as well' do
70
+ config = subject.stripe_config(order)
71
+ expect(config.keys).to eq %i[id publishable_key payment_request]
72
+ expect(config[:payment_request][:currency]).to eq 'usd'
73
+ expect(config[:payment_request][:amount]).to be 1099
74
+ expect(config[:payment_request][:label]).to include 'NUMBER'
75
+ end
76
+ end
77
+ end
78
+
38
79
  describe '#create_profile' do
39
80
  before do
40
81
  allow(payment.source).to receive(:update_attributes!)
@@ -71,8 +112,6 @@ describe Spree::PaymentMethod::StripeCreditCard do
71
112
  end
72
113
 
73
114
  context 'with an order that does not have a bill address' do
74
- let(:bill_address) { nil }
75
-
76
115
  it 'does not store a bill address with the gateway' do
77
116
  expect(subject.gateway).to receive(:store).with(payment.source, {
78
117
  email: email,
data/spec/spec_helper.rb CHANGED
@@ -1,20 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "simplecov"
4
- SimpleCov.start "rails"
3
+ # Configure Rails Environment
4
+ ENV['RAILS_ENV'] = 'test'
5
5
 
6
- ENV["RAILS_ENV"] ||= "test"
6
+ # Run Coverage report
7
+ require 'solidus_dev_support/rspec/coverage'
7
8
 
8
9
  require File.expand_path('dummy/config/environment.rb', __dir__)
9
10
 
10
- require 'solidus_support/extension/feature_helper'
11
+ # Requires factories and other useful helpers defined in spree_core.
12
+ require 'solidus_dev_support/rspec/feature_helper'
11
13
 
14
+ # Requires supporting ruby files with custom matchers and macros, etc,
15
+ # in spec/support/ and its subdirectories.
12
16
  Dir[File.join(File.dirname(__FILE__), "support/**/*.rb")].each { |f| require f }
13
17
 
14
- Capybara.server = :webrick
15
-
16
18
  RSpec.configure do |config|
17
19
  config.infer_spec_type_from_file_location!
18
-
19
20
  FactoryBot.find_definitions
21
+ config.use_transactional_fixtures = false
20
22
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solidus_stripe
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Solidus Team
8
8
  autorequire:
9
- bindir: bin
9
+ bindir: exe
10
10
  cert_chain: []
11
- date: 2019-09-30 00:00:00.000000000 Z
11
+ date: 2020-03-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: solidus_core
@@ -32,158 +32,34 @@ dependencies:
32
32
  version: '3'
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: solidus_support
35
- requirement: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - ">="
38
- - !ruby/object:Gem::Version
39
- version: 0.3.1
40
- type: :runtime
41
- prerelease: false
42
- version_requirements: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - ">="
45
- - !ruby/object:Gem::Version
46
- version: 0.3.1
47
- - !ruby/object:Gem::Dependency
48
- name: activemerchant
49
35
  requirement: !ruby/object:Gem::Requirement
50
36
  requirements:
51
37
  - - "~>"
52
38
  - !ruby/object:Gem::Version
53
- version: '1.48'
54
- - - "!="
55
- - !ruby/object:Gem::Version
56
- version: 1.58.0
57
- - - "!="
58
- - !ruby/object:Gem::Version
59
- version: 1.59.0
39
+ version: 0.4.0
60
40
  type: :runtime
61
41
  prerelease: false
62
42
  version_requirements: !ruby/object:Gem::Requirement
63
43
  requirements:
64
44
  - - "~>"
65
45
  - !ruby/object:Gem::Version
66
- version: '1.48'
67
- - - "!="
68
- - !ruby/object:Gem::Version
69
- version: 1.58.0
70
- - - "!="
71
- - !ruby/object:Gem::Version
72
- version: 1.59.0
73
- - !ruby/object:Gem::Dependency
74
- name: capybara
75
- requirement: !ruby/object:Gem::Requirement
76
- requirements:
77
- - - ">="
78
- - !ruby/object:Gem::Version
79
- version: '0'
80
- type: :development
81
- prerelease: false
82
- version_requirements: !ruby/object:Gem::Requirement
83
- requirements:
84
- - - ">="
85
- - !ruby/object:Gem::Version
86
- version: '0'
87
- - !ruby/object:Gem::Dependency
88
- name: capybara-screenshot
89
- requirement: !ruby/object:Gem::Requirement
90
- requirements:
91
- - - ">="
92
- - !ruby/object:Gem::Version
93
- version: '0'
94
- type: :development
95
- prerelease: false
96
- version_requirements: !ruby/object:Gem::Requirement
97
- requirements:
98
- - - ">="
99
- - !ruby/object:Gem::Version
100
- version: '0'
101
- - !ruby/object:Gem::Dependency
102
- name: database_cleaner
103
- requirement: !ruby/object:Gem::Requirement
104
- requirements:
105
- - - "~>"
106
- - !ruby/object:Gem::Version
107
- version: '1.5'
108
- type: :development
109
- prerelease: false
110
- version_requirements: !ruby/object:Gem::Requirement
111
- requirements:
112
- - - "~>"
113
- - !ruby/object:Gem::Version
114
- version: '1.5'
115
- - !ruby/object:Gem::Dependency
116
- name: factory_bot
117
- requirement: !ruby/object:Gem::Requirement
118
- requirements:
119
- - - "~>"
120
- - !ruby/object:Gem::Version
121
- version: '4.4'
122
- type: :development
123
- prerelease: false
124
- version_requirements: !ruby/object:Gem::Requirement
125
- requirements:
126
- - - "~>"
127
- - !ruby/object:Gem::Version
128
- version: '4.4'
46
+ version: 0.4.0
129
47
  - !ruby/object:Gem::Dependency
130
- name: gem-release
131
- requirement: !ruby/object:Gem::Requirement
132
- requirements:
133
- - - "~>"
134
- - !ruby/object:Gem::Version
135
- version: '2.0'
136
- type: :development
137
- prerelease: false
138
- version_requirements: !ruby/object:Gem::Requirement
139
- requirements:
140
- - - "~>"
141
- - !ruby/object:Gem::Version
142
- version: '2.0'
143
- - !ruby/object:Gem::Dependency
144
- name: rspec-rails
145
- requirement: !ruby/object:Gem::Requirement
146
- requirements:
147
- - - "~>"
148
- - !ruby/object:Gem::Version
149
- version: '3.2'
150
- type: :development
151
- prerelease: false
152
- version_requirements: !ruby/object:Gem::Requirement
153
- requirements:
154
- - - "~>"
155
- - !ruby/object:Gem::Version
156
- version: '3.2'
157
- - !ruby/object:Gem::Dependency
158
- name: selenium-webdriver
159
- requirement: !ruby/object:Gem::Requirement
160
- requirements:
161
- - - "~>"
162
- - !ruby/object:Gem::Version
163
- version: '3.142'
164
- type: :development
165
- prerelease: false
166
- version_requirements: !ruby/object:Gem::Requirement
167
- requirements:
168
- - - "~>"
169
- - !ruby/object:Gem::Version
170
- version: '3.142'
171
- - !ruby/object:Gem::Dependency
172
- name: simplecov
48
+ name: activemerchant
173
49
  requirement: !ruby/object:Gem::Requirement
174
50
  requirements:
175
51
  - - ">="
176
52
  - !ruby/object:Gem::Version
177
- version: '0'
178
- type: :development
53
+ version: '1.100'
54
+ type: :runtime
179
55
  prerelease: false
180
56
  version_requirements: !ruby/object:Gem::Requirement
181
57
  requirements:
182
58
  - - ">="
183
59
  - !ruby/object:Gem::Version
184
- version: '0'
60
+ version: '1.100'
185
61
  - !ruby/object:Gem::Dependency
186
- name: sqlite3
62
+ name: solidus_dev_support
187
63
  requirement: !ruby/object:Gem::Requirement
188
64
  requirements:
189
65
  - - ">="
@@ -204,16 +80,29 @@ extra_rdoc_files: []
204
80
  files:
205
81
  - ".circleci/config.yml"
206
82
  - ".gem_release.yml"
83
+ - ".github/stale.yml"
207
84
  - ".gitignore"
208
85
  - ".rspec"
209
86
  - ".rubocop.yml"
210
87
  - ".travis.yml"
211
88
  - Gemfile
89
+ - LICENSE
212
90
  - LICENSE.md
213
91
  - README.md
214
92
  - Rakefile
93
+ - app/assets/javascripts/solidus_stripe/stripe-init.js
94
+ - app/assets/javascripts/solidus_stripe/stripe-init/base.js
95
+ - app/controllers/solidus_stripe/intents_controller.rb
96
+ - app/controllers/solidus_stripe/payment_request_controller.rb
97
+ - app/controllers/spree/stripe_controller.rb
98
+ - app/models/solidus_stripe/address_from_params_service.rb
99
+ - app/models/solidus_stripe/prepare_order_for_payment_service.rb
100
+ - app/models/solidus_stripe/shipping_rates_service.rb
215
101
  - app/models/spree/payment_method/stripe_credit_card.rb
102
+ - bin/console
216
103
  - bin/rails
104
+ - bin/setup
105
+ - config/routes.rb
217
106
  - db/migrate/20181010123508_update_stripe_payment_method_type_to_credit_card.rb
218
107
  - db/seeds.rb
219
108
  - lib/assets/stylesheets/spree/frontend/solidus_stripe.scss
@@ -229,15 +118,25 @@ files:
229
118
  - lib/views/frontend/spree/checkout/existing_payment/_stripe.html.erb
230
119
  - lib/views/frontend/spree/checkout/payment/_stripe.html.erb
231
120
  - lib/views/frontend/spree/checkout/payment/v2/_javascript.html.erb
121
+ - lib/views/frontend/spree/checkout/payment/v3/_elements_js.html.erb
122
+ - lib/views/frontend/spree/checkout/payment/v3/_form_elements.html.erb
123
+ - lib/views/frontend/spree/checkout/payment/v3/_intents.html.erb
124
+ - lib/views/frontend/spree/checkout/payment/v3/_intents_js.html.erb
232
125
  - lib/views/frontend/spree/checkout/payment/v3/_stripe.html.erb
126
+ - lib/views/frontend/spree/orders/_stripe_payment_request_button.html.erb
233
127
  - solidus_stripe.gemspec
234
128
  - spec/features/stripe_checkout_spec.rb
129
+ - spec/models/solidus_stripe/address_from_params_service_spec.rb
130
+ - spec/models/solidus_stripe/prepare_order_for_payment_service_spec.rb
131
+ - spec/models/solidus_stripe/shipping_rates_service_spec.rb
235
132
  - spec/models/spree/payment_method/stripe_credit_card_spec.rb
236
133
  - spec/spec_helper.rb
237
134
  homepage: https://solidus.io
238
135
  licenses:
239
136
  - BSD-3
240
- metadata: {}
137
+ metadata:
138
+ homepage_uri: https://solidus.io
139
+ source_code_uri: https://solidus.io
241
140
  post_install_message:
242
141
  rdoc_options: []
243
142
  require_paths:
@@ -254,11 +153,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
254
153
  version: '0'
255
154
  requirements:
256
155
  - none
257
- rubygems_version: 3.0.6
156
+ rubygems_version: 3.0.3
258
157
  signing_key:
259
158
  specification_version: 4
260
159
  summary: Stripe Payment Method for Solidus
261
160
  test_files:
262
161
  - spec/features/stripe_checkout_spec.rb
162
+ - spec/models/solidus_stripe/address_from_params_service_spec.rb
163
+ - spec/models/solidus_stripe/prepare_order_for_payment_service_spec.rb
164
+ - spec/models/solidus_stripe/shipping_rates_service_spec.rb
263
165
  - spec/models/spree/payment_method/stripe_credit_card_spec.rb
264
166
  - spec/spec_helper.rb