solidus_stripe 1.0.0 → 1.1.0

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