solidus_stripe 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +35 -0
  3. data/.gem_release.yml +8 -0
  4. data/.gitignore +11 -0
  5. data/.rspec +1 -0
  6. data/.rubocop.yml +319 -0
  7. data/.travis.yml +28 -0
  8. data/Gemfile +25 -0
  9. data/LICENSE.md +26 -0
  10. data/README.md +115 -0
  11. data/Rakefile +23 -0
  12. data/app/models/spree/payment_method/stripe_credit_card.rb +136 -0
  13. data/bin/rails +7 -0
  14. data/db/migrate/20181010123508_update_stripe_payment_method_type_to_credit_card.rb +21 -0
  15. data/db/seeds.rb +26 -0
  16. data/lib/assets/stylesheets/spree/frontend/solidus_stripe.scss +6 -0
  17. data/lib/generators/solidus_stripe/install/install_generator.rb +46 -0
  18. data/lib/solidus_stripe.rb +7 -0
  19. data/lib/solidus_stripe/engine.rb +23 -0
  20. data/lib/solidus_stripe/version.rb +5 -0
  21. data/lib/tasks/solidus_stripe/db/seed.rake +14 -0
  22. data/lib/views/api/spree/api/payments/source_views/_stripe.json.jbuilder +3 -0
  23. data/lib/views/backend/spree/admin/log_entries/_stripe.html.erb +28 -0
  24. data/lib/views/backend/spree/admin/payments/source_forms/_stripe.html.erb +1 -0
  25. data/lib/views/backend/spree/admin/payments/source_views/_stripe.html.erb +1 -0
  26. data/lib/views/frontend/spree/checkout/existing_payment/_stripe.html.erb +1 -0
  27. data/lib/views/frontend/spree/checkout/payment/_stripe.html.erb +6 -0
  28. data/lib/views/frontend/spree/checkout/payment/v2/_javascript.html.erb +77 -0
  29. data/lib/views/frontend/spree/checkout/payment/v3/_stripe.html.erb +133 -0
  30. data/solidus_stripe.gemspec +45 -0
  31. data/spec/features/stripe_checkout_spec.rb +279 -0
  32. data/spec/models/spree/payment_method/stripe_credit_card_spec.rb +205 -0
  33. data/spec/spec_helper.rb +20 -0
  34. metadata +264 -0
@@ -0,0 +1,205 @@
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(:payment) {
11
+ double('Spree::Payment',
12
+ source: source,
13
+ order: double('Spree::Order',
14
+ email: email,
15
+ bill_address: bill_address))
16
+ }
17
+
18
+ let(:gateway) do
19
+ double('gateway').tap do |p|
20
+ allow(p).to receive(:purchase)
21
+ allow(p).to receive(:authorize)
22
+ allow(p).to receive(:capture)
23
+ end
24
+ end
25
+
26
+ before do
27
+ subject.preferences = { secret_key: secret_key }
28
+ allow(subject).to receive(:options_for_purchase_or_auth).and_return(['money', 'cc', 'opts'])
29
+ allow(subject).to receive(:gateway).and_return gateway
30
+ end
31
+
32
+ it 'can enable Stripe.js V3 Elements via preference setting' do
33
+ expect do
34
+ subject.preferred_v3_elements = true
35
+ end.to change { subject.v3_elements? }.from(false).to true
36
+ end
37
+
38
+ describe '#create_profile' do
39
+ before do
40
+ allow(payment.source).to receive(:update_attributes!)
41
+ end
42
+
43
+ context 'with an order that has a bill address' do
44
+ let(:bill_address) {
45
+ double('Spree::Address',
46
+ address1: '123 Happy Road',
47
+ address2: 'Apt 303',
48
+ city: 'Suzarac',
49
+ zipcode: '95671',
50
+ state: double('Spree::State', name: 'Oregon'),
51
+ country: double('Spree::Country', name: 'United States'))
52
+ }
53
+
54
+ it 'stores the bill address with the gateway' do
55
+ expect(subject.gateway).to receive(:store).with(payment.source, {
56
+ email: email,
57
+ login: secret_key,
58
+
59
+ address: {
60
+ address1: '123 Happy Road',
61
+ address2: 'Apt 303',
62
+ city: 'Suzarac',
63
+ zip: '95671',
64
+ state: 'Oregon',
65
+ country: 'United States'
66
+ }
67
+ }).and_return double.as_null_object
68
+
69
+ subject.create_profile payment
70
+ end
71
+ end
72
+
73
+ context 'with an order that does not have a bill address' do
74
+ let(:bill_address) { nil }
75
+
76
+ it 'does not store a bill address with the gateway' do
77
+ expect(subject.gateway).to receive(:store).with(payment.source, {
78
+ email: email,
79
+ login: secret_key,
80
+ }).and_return double.as_null_object
81
+
82
+ subject.create_profile payment
83
+ end
84
+
85
+ # Regression test for #141
86
+ context "correcting the card type" do
87
+ before do
88
+ # We don't care about this method for these tests
89
+ allow(subject.gateway).to receive(:store).and_return(double.as_null_object)
90
+ end
91
+
92
+ it "converts 'American Express' to 'american_express'" do
93
+ payment.source.cc_type = 'American Express'
94
+ subject.create_profile(payment)
95
+ expect(payment.source.cc_type).to eq('american_express')
96
+ end
97
+
98
+ it "converts 'Diners Club' to 'diners_club'" do
99
+ payment.source.cc_type = 'Diners Club'
100
+ subject.create_profile(payment)
101
+ expect(payment.source.cc_type).to eq('diners_club')
102
+ end
103
+
104
+ it "converts 'Visa' to 'visa'" do
105
+ payment.source.cc_type = 'Visa'
106
+ subject.create_profile(payment)
107
+ expect(payment.source.cc_type).to eq('visa')
108
+ end
109
+ end
110
+ end
111
+
112
+ context 'with a card represents payment_profile' do
113
+ let(:source) { Spree::CreditCard.new(gateway_payment_profile_id: 'tok_profileid') }
114
+ let(:bill_address) { nil }
115
+
116
+ it 'stores the profile_id as a card' do
117
+ expect(subject.gateway).to receive(:store).with(source.gateway_payment_profile_id, anything).and_return double.as_null_object
118
+
119
+ subject.create_profile payment
120
+ end
121
+ end
122
+ end
123
+
124
+ context 'purchasing' do
125
+ after do
126
+ subject.purchase(19.99, 'credit card', {})
127
+ end
128
+
129
+ it 'send the payment to the gateway' do
130
+ expect(gateway).to receive(:purchase).with('money', 'cc', 'opts')
131
+ end
132
+ end
133
+
134
+ context 'authorizing' do
135
+ after do
136
+ subject.authorize(19.99, 'credit card', {})
137
+ end
138
+
139
+ it 'send the authorization to the gateway' do
140
+ expect(gateway).to receive(:authorize).with('money', 'cc', 'opts')
141
+ end
142
+ end
143
+
144
+ context 'capturing' do
145
+ after do
146
+ subject.capture(1234, 'response_code', {})
147
+ end
148
+
149
+ it 'convert the amount to cents' do
150
+ expect(gateway).to receive(:capture).with(1234, anything, anything)
151
+ end
152
+
153
+ it 'use the response code as the authorization' do
154
+ expect(gateway).to receive(:capture).with(anything, 'response_code', anything)
155
+ end
156
+ end
157
+
158
+ context 'capture with payment class' do
159
+ let(:payment_method) do
160
+ payment_method = described_class.new(active: true)
161
+ payment_method.set_preference :secret_key, secret_key
162
+ allow(payment_method).to receive(:options_for_purchase_or_auth).and_return(['money', 'cc', 'opts'])
163
+ allow(payment_method).to receive(:gateway).and_return gateway
164
+ allow(payment_method).to receive_messages source_required: true
165
+ payment_method
166
+ end
167
+
168
+ let!(:store) { FactoryBot.create(:store) }
169
+ let(:order) { Spree::Order.create! }
170
+
171
+ let(:card) do
172
+ FactoryBot.create(
173
+ :credit_card,
174
+ gateway_customer_profile_id: 'cus_abcde',
175
+ imported: false
176
+ )
177
+ end
178
+
179
+ let(:payment) do
180
+ payment = Spree::Payment.new
181
+ payment.source = card
182
+ payment.order = order
183
+ payment.payment_method = payment_method
184
+ payment.amount = 98.55
185
+ payment.state = 'pending'
186
+ payment.response_code = '12345'
187
+ payment
188
+ end
189
+
190
+ let!(:success_response) do
191
+ double('success_response', success?: true,
192
+ authorization: '123',
193
+ avs_result: { 'code' => 'avs-code' },
194
+ cvv_result: { 'code' => 'cvv-code', 'message' => "CVV Result" })
195
+ end
196
+
197
+ after do
198
+ payment.capture!
199
+ end
200
+
201
+ it 'gets correct amount' do
202
+ expect(gateway).to receive(:capture).with(9855, '12345', anything).and_return(success_response)
203
+ end
204
+ end
205
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "simplecov"
4
+ SimpleCov.start "rails"
5
+
6
+ ENV["RAILS_ENV"] ||= "test"
7
+
8
+ require File.expand_path('dummy/config/environment.rb', __dir__)
9
+
10
+ require 'solidus_support/extension/feature_helper'
11
+
12
+ Dir[File.join(File.dirname(__FILE__), "support/**/*.rb")].each { |f| require f }
13
+
14
+ Capybara.server = :webrick
15
+
16
+ RSpec.configure do |config|
17
+ config.infer_spec_type_from_file_location!
18
+
19
+ FactoryBot.find_definitions
20
+ end
metadata ADDED
@@ -0,0 +1,264 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: solidus_stripe
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Solidus Team
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-09-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: solidus_core
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '2.3'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '3'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '2.3'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '3'
33
+ - !ruby/object:Gem::Dependency
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
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !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
60
+ type: :runtime
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !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'
129
+ - !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
173
+ requirement: !ruby/object:Gem::Requirement
174
+ requirements:
175
+ - - ">="
176
+ - !ruby/object:Gem::Version
177
+ version: '0'
178
+ type: :development
179
+ prerelease: false
180
+ version_requirements: !ruby/object:Gem::Requirement
181
+ requirements:
182
+ - - ">="
183
+ - !ruby/object:Gem::Version
184
+ version: '0'
185
+ - !ruby/object:Gem::Dependency
186
+ name: sqlite3
187
+ requirement: !ruby/object:Gem::Requirement
188
+ requirements:
189
+ - - ">="
190
+ - !ruby/object:Gem::Version
191
+ version: '0'
192
+ type: :development
193
+ prerelease: false
194
+ version_requirements: !ruby/object:Gem::Requirement
195
+ requirements:
196
+ - - ">="
197
+ - !ruby/object:Gem::Version
198
+ version: '0'
199
+ description: Stripe Payment Method for Solidus
200
+ email: contact@solidus.io
201
+ executables: []
202
+ extensions: []
203
+ extra_rdoc_files: []
204
+ files:
205
+ - ".circleci/config.yml"
206
+ - ".gem_release.yml"
207
+ - ".gitignore"
208
+ - ".rspec"
209
+ - ".rubocop.yml"
210
+ - ".travis.yml"
211
+ - Gemfile
212
+ - LICENSE.md
213
+ - README.md
214
+ - Rakefile
215
+ - app/models/spree/payment_method/stripe_credit_card.rb
216
+ - bin/rails
217
+ - db/migrate/20181010123508_update_stripe_payment_method_type_to_credit_card.rb
218
+ - db/seeds.rb
219
+ - lib/assets/stylesheets/spree/frontend/solidus_stripe.scss
220
+ - lib/generators/solidus_stripe/install/install_generator.rb
221
+ - lib/solidus_stripe.rb
222
+ - lib/solidus_stripe/engine.rb
223
+ - lib/solidus_stripe/version.rb
224
+ - lib/tasks/solidus_stripe/db/seed.rake
225
+ - lib/views/api/spree/api/payments/source_views/_stripe.json.jbuilder
226
+ - lib/views/backend/spree/admin/log_entries/_stripe.html.erb
227
+ - lib/views/backend/spree/admin/payments/source_forms/_stripe.html.erb
228
+ - lib/views/backend/spree/admin/payments/source_views/_stripe.html.erb
229
+ - lib/views/frontend/spree/checkout/existing_payment/_stripe.html.erb
230
+ - lib/views/frontend/spree/checkout/payment/_stripe.html.erb
231
+ - lib/views/frontend/spree/checkout/payment/v2/_javascript.html.erb
232
+ - lib/views/frontend/spree/checkout/payment/v3/_stripe.html.erb
233
+ - solidus_stripe.gemspec
234
+ - spec/features/stripe_checkout_spec.rb
235
+ - spec/models/spree/payment_method/stripe_credit_card_spec.rb
236
+ - spec/spec_helper.rb
237
+ homepage: https://solidus.io
238
+ licenses:
239
+ - BSD-3
240
+ metadata: {}
241
+ post_install_message:
242
+ rdoc_options: []
243
+ require_paths:
244
+ - lib
245
+ required_ruby_version: !ruby/object:Gem::Requirement
246
+ requirements:
247
+ - - ">="
248
+ - !ruby/object:Gem::Version
249
+ version: '2.2'
250
+ required_rubygems_version: !ruby/object:Gem::Requirement
251
+ requirements:
252
+ - - ">="
253
+ - !ruby/object:Gem::Version
254
+ version: '0'
255
+ requirements:
256
+ - none
257
+ rubygems_version: 3.0.6
258
+ signing_key:
259
+ specification_version: 4
260
+ summary: Stripe Payment Method for Solidus
261
+ test_files:
262
+ - spec/features/stripe_checkout_spec.rb
263
+ - spec/models/spree/payment_method/stripe_credit_card_spec.rb
264
+ - spec/spec_helper.rb