solidus_paypal_braintree 1.1.0 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +4 -0
  3. data/.gitignore +1 -0
  4. data/.rubocop.yml +1 -1
  5. data/CHANGELOG.md +70 -1
  6. data/Gemfile +9 -6
  7. data/app/models/solidus_paypal_braintree/gateway.rb +5 -3
  8. data/app/models/solidus_paypal_braintree/transaction.rb +2 -2
  9. data/app/models/solidus_paypal_braintree/transaction_import.rb +2 -2
  10. data/lib/solidus_paypal_braintree/engine.rb +5 -3
  11. data/lib/solidus_paypal_braintree/factories.rb +5 -5
  12. data/lib/solidus_paypal_braintree/version.rb +1 -1
  13. data/lib/views/frontend/solidus_paypal_braintree/payments/_payment.html.erb +3 -3
  14. data/solidus_paypal_braintree.gemspec +0 -1
  15. metadata +4 -122
  16. data/spec/controllers/solidus_paypal_braintree/checkouts_controller_spec.rb +0 -99
  17. data/spec/controllers/solidus_paypal_braintree/client_tokens_controller_spec.rb +0 -55
  18. data/spec/controllers/solidus_paypal_braintree/configurations_controller_spec.rb +0 -73
  19. data/spec/controllers/solidus_paypal_braintree/transactions_controller_spec.rb +0 -183
  20. data/spec/features/backend/configuration_spec.rb +0 -23
  21. data/spec/features/backend/new_payment_spec.rb +0 -137
  22. data/spec/features/frontend/braintree_credit_card_checkout_spec.rb +0 -191
  23. data/spec/features/frontend/paypal_checkout_spec.rb +0 -166
  24. data/spec/features/frontend/venmo_checkout_spec.rb +0 -189
  25. data/spec/fixtures/cassettes/admin/invalid_credit_card.yml +0 -63
  26. data/spec/fixtures/cassettes/admin/resubmit_credit_card.yml +0 -352
  27. data/spec/fixtures/cassettes/admin/valid_credit_card.yml +0 -412
  28. data/spec/fixtures/cassettes/braintree/create_profile.yml +0 -71
  29. data/spec/fixtures/cassettes/braintree/generate_token.yml +0 -63
  30. data/spec/fixtures/cassettes/braintree/token.yml +0 -63
  31. data/spec/fixtures/cassettes/checkout/invalid_credit_card.yml +0 -63
  32. data/spec/fixtures/cassettes/checkout/resubmit_credit_card.yml +0 -216
  33. data/spec/fixtures/cassettes/checkout/update.yml +0 -71
  34. data/spec/fixtures/cassettes/checkout/valid_credit_card.yml +0 -156
  35. data/spec/fixtures/cassettes/checkout/valid_venmo_transaction.yml +0 -599
  36. data/spec/fixtures/cassettes/gateway/authorize/credit_card/address.yml +0 -86
  37. data/spec/fixtures/cassettes/gateway/authorize/merchant_account/EUR.yml +0 -154
  38. data/spec/fixtures/cassettes/gateway/authorize/paypal/EUR.yml +0 -90
  39. data/spec/fixtures/cassettes/gateway/authorize/paypal/address.yml +0 -90
  40. data/spec/fixtures/cassettes/gateway/authorize.yml +0 -86
  41. data/spec/fixtures/cassettes/gateway/authorized_transaction.yml +0 -73
  42. data/spec/fixtures/cassettes/gateway/cancel/missing.yml +0 -63
  43. data/spec/fixtures/cassettes/gateway/cancel/refunds.yml +0 -272
  44. data/spec/fixtures/cassettes/gateway/cancel/void.yml +0 -201
  45. data/spec/fixtures/cassettes/gateway/capture.yml +0 -141
  46. data/spec/fixtures/cassettes/gateway/complete.yml +0 -157
  47. data/spec/fixtures/cassettes/gateway/credit.yml +0 -208
  48. data/spec/fixtures/cassettes/gateway/purchase.yml +0 -87
  49. data/spec/fixtures/cassettes/gateway/settled_transaction.yml +0 -140
  50. data/spec/fixtures/cassettes/gateway/void.yml +0 -137
  51. data/spec/fixtures/cassettes/source/card_type.yml +0 -267
  52. data/spec/fixtures/cassettes/source/last4.yml +0 -267
  53. data/spec/fixtures/cassettes/transaction/import/valid/capture.yml +0 -224
  54. data/spec/fixtures/cassettes/transaction/import/valid.yml +0 -71
  55. data/spec/fixtures/views/spree/orders/edit.html.erb +0 -50
  56. data/spec/helpers/solidus_paypal_braintree/braintree_admin_helper_spec.rb +0 -17
  57. data/spec/helpers/solidus_paypal_braintree/braintree_checkout_helper_spec.rb +0 -70
  58. data/spec/models/solidus_paypal_braintree/address_spec.rb +0 -71
  59. data/spec/models/solidus_paypal_braintree/avs_result_spec.rb +0 -317
  60. data/spec/models/solidus_paypal_braintree/gateway_spec.rb +0 -692
  61. data/spec/models/solidus_paypal_braintree/response_spec.rb +0 -280
  62. data/spec/models/solidus_paypal_braintree/source_spec.rb +0 -499
  63. data/spec/models/solidus_paypal_braintree/transaction_address_spec.rb +0 -235
  64. data/spec/models/solidus_paypal_braintree/transaction_import_spec.rb +0 -300
  65. data/spec/models/solidus_paypal_braintree/transaction_spec.rb +0 -85
  66. data/spec/models/spree/store_spec.rb +0 -14
  67. data/spec/requests/spree/api/orders_controller_spec.rb +0 -36
  68. data/spec/spec_helper.rb +0 -29
  69. data/spec/support/capybara.rb +0 -7
  70. data/spec/support/factories.rb +0 -2
  71. data/spec/support/gateway_helpers.rb +0 -29
  72. data/spec/support/order_ready_for_payment.rb +0 -37
  73. data/spec/support/vcr.rb +0 -42
  74. data/spec/support/views.rb +0 -1
@@ -1,692 +0,0 @@
1
- require 'spec_helper'
2
- require 'webmock'
3
- require 'support/order_ready_for_payment'
4
-
5
- RSpec.describe SolidusPaypalBraintree::Gateway do
6
- let(:gateway) do
7
- new_gateway.tap(&:save)
8
- end
9
-
10
- let(:braintree) { gateway.braintree }
11
-
12
- let(:user) { create :user }
13
-
14
- let(:source) do
15
- SolidusPaypalBraintree::Source.create!(
16
- nonce: 'fake-valid-nonce',
17
- user: user,
18
- payment_type: payment_type,
19
- payment_method: gateway
20
- )
21
- end
22
-
23
- let(:payment_type) { SolidusPaypalBraintree::Source::PAYPAL }
24
-
25
- describe "saving preference hashes as strings" do
26
- subject { gateway.update(update_params) }
27
-
28
- context "with valid hash syntax" do
29
- let(:update_params) do
30
- {
31
- preferred_merchant_currency_map: '{"EUR" => "test_merchant_account_id"}',
32
- preferred_paypal_payee_email_map: '{"CAD" => "bruce+wayne@example.com"}'
33
- }
34
- end
35
-
36
- it "successfully updates the preference" do
37
- subject
38
- expect(gateway.preferred_merchant_currency_map).to eq({ "EUR" => "test_merchant_account_id" })
39
- expect(gateway.preferred_paypal_payee_email_map).to eq({ "CAD" => "bruce+wayne@example.com" })
40
- end
41
- end
42
-
43
- context "with invalid user input" do
44
- let(:update_params) do
45
- { preferred_merchant_currency_map: '{this_is_not_a_valid_hash}' }
46
- end
47
-
48
- it "raise a JSON parser error" do
49
- expect{ subject }.to raise_error(JSON::ParserError)
50
- end
51
- end
52
- end
53
-
54
- describe 'making a payment on an order', vcr: {
55
- cassette_name: 'gateway/complete',
56
- match_requests_on: [:braintree_uri]
57
- } do
58
- include_context 'when order is ready for payment'
59
-
60
- before do
61
- order.update(number: "ORDER0")
62
- payment.update(number: "PAYMENT0")
63
- end
64
-
65
- let(:payment) do
66
- order.payments.create!(
67
- payment_method: gateway,
68
- source: source,
69
- amount: 55
70
- )
71
- end
72
-
73
- it 'can complete an order' do
74
- order.payments.reset
75
-
76
- expect(order.total).to eq 55
77
-
78
- expect(payment.capture_events.count).to eq 0
79
-
80
- order.next!
81
- expect(order.state).to eq "confirm"
82
-
83
- order.complete!
84
- expect(order.state).to eq "complete"
85
-
86
- expect(order.outstanding_balance).to eq 0.0
87
-
88
- expect(payment.capture_events.count).to eq 1
89
- end
90
- end
91
-
92
- describe "instance methods" do
93
- shared_examples "successful response" do
94
- it 'returns a successful billing response', aggregate_failures: true do
95
- expect(subject).to be_a ActiveMerchant::Billing::Response
96
- expect(subject).to be_success
97
- end
98
- end
99
-
100
- shared_examples "protects against connection errors" do
101
- context 'when a timeout error happens' do
102
- it 'raises ActiveMerchant::ConnectionError' do
103
- expect_any_instance_of(Braintree::TransactionGateway).to receive(gateway_action) do
104
- raise Braintree::BraintreeError
105
- end
106
-
107
- expect { subject }.to raise_error ActiveMerchant::ConnectionError
108
- end
109
- end
110
- end
111
-
112
- let(:authorized_id) do
113
- braintree.transaction.sale(
114
- amount: 40,
115
- payment_method_nonce: source.nonce
116
- ).transaction.id
117
- end
118
-
119
- let(:sale_id) do
120
- braintree.transaction.sale(
121
- amount: 40,
122
- payment_method_nonce: source.nonce,
123
- options: {
124
- submit_for_settlement: true
125
- }
126
- ).transaction.id
127
- end
128
-
129
- let(:settled_id) do
130
- braintree.testing.settle(sale_id).transaction.id
131
- end
132
-
133
- let(:currency) { 'USD' }
134
-
135
- let(:gateway_options) do
136
- {
137
- currency: currency,
138
- shipping_address: {
139
- name: "Bruce Wayne",
140
- address1: "42 Spruce Lane",
141
- address2: "Apt 312",
142
- city: "Gotham",
143
- state: "CA",
144
- zip: "90210",
145
- country: "US"
146
- },
147
- billing_address: {
148
- name: "Dick Grayson",
149
- address1: "15 Robin Walk",
150
- address2: "Apt 123",
151
- city: "Blüdhaven",
152
- state: "CA",
153
- zip: "90210",
154
- country: "US"
155
- }
156
- }
157
- end
158
-
159
- describe "#method_type" do
160
- subject { gateway.method_type }
161
-
162
- it { is_expected.to eq "paypal_braintree" }
163
- end
164
-
165
- describe '#gateway_options' do
166
- subject(:gateway_options) { gateway.gateway_options }
167
-
168
- it 'includes http_open_timeout' do
169
- expect(subject).to have_key(:http_open_timeout)
170
- expect(gateway_options[:http_open_timeout]).to eq(60)
171
- end
172
-
173
- it 'includes http_read_timeout' do
174
- expect(subject).to have_key(:http_read_timeout)
175
- expect(gateway_options[:http_read_timeout]).to eq(60)
176
- end
177
- end
178
-
179
- describe '#purchase' do
180
- subject(:purchase) { gateway.purchase(1000, source, gateway_options) }
181
-
182
- context 'with successful purchase', vcr: {
183
- cassette_name: 'gateway/purchase',
184
- match_requests_on: [:braintree_uri]
185
- } do
186
- include_examples "successful response"
187
-
188
- it 'submits the transaction for settlement', aggregate_failures: true do
189
- expect(purchase.message).to eq 'submitted_for_settlement'
190
- expect(purchase.authorization).to be_present
191
- end
192
- end
193
-
194
- include_examples "protects against connection errors" do
195
- let(:gateway_action) { :sale }
196
- end
197
- end
198
-
199
- describe "#authorize" do
200
- subject(:authorize) { gateway.authorize(1000, source, gateway_options) }
201
-
202
- include_examples "protects against connection errors" do
203
- let(:gateway_action) { :sale }
204
- end
205
-
206
- context 'with successful authorization', vcr: {
207
- cassette_name: 'gateway/authorize',
208
- match_requests_on: [:braintree_uri]
209
- } do
210
- include_examples "successful response"
211
-
212
- it 'passes "Solidus" as the channel parameter in the request' do
213
- expect_any_instance_of(Braintree::TransactionGateway).
214
- to receive(:sale).
215
- with(hash_including({ channel: "Solidus" })).and_call_original
216
- authorize
217
- end
218
-
219
- it 'authorizes the transaction', aggregate_failures: true do
220
- expect(authorize.message).to eq 'authorized'
221
- expect(authorize.authorization).to be_present
222
- end
223
- end
224
-
225
- context 'with different merchant account for currency', vcr: {
226
- cassette_name: 'gateway/authorize/merchant_account/EUR',
227
- match_requests_on: [:braintree_uri]
228
- } do
229
- let(:currency) { 'EUR' }
230
-
231
- it 'settles with the correct currency' do
232
- transaction = braintree.transaction.find(authorize.authorization)
233
- expect(transaction.merchant_account_id).to eq 'stembolt_EUR'
234
- end
235
- end
236
-
237
- context 'with different paypal payee email for currency', vcr: {
238
- cassette_name: 'gateway/authorize/paypal/EUR',
239
- match_requests_on: [:braintree_uri]
240
- } do
241
- let(:currency) { 'EUR' }
242
-
243
- it 'uses the correct payee email' do
244
- expect_any_instance_of(Braintree::TransactionGateway).
245
- to receive(:sale).
246
- with(hash_including({
247
- options: {
248
- store_in_vault_on_success: true,
249
- paypal: {
250
- payee_email: ENV.fetch('BRAINTREE_PAYPAL_PAYEE_EMAIL')
251
- }
252
- }
253
- })).and_call_original
254
- authorize
255
- end
256
-
257
- context "with PayPal transaction", vcr: {
258
- cassette_name: 'gateway/authorize/paypal/address',
259
- match_requests_on: [:braintree_uri]
260
- } do
261
- it 'includes the shipping address in the request' do
262
- expect_any_instance_of(Braintree::TransactionGateway).
263
- to receive(:sale).
264
- with(hash_including({
265
- shipping: {
266
- first_name: "Bruce",
267
- last_name: "Wayne",
268
- street_address: "42 Spruce Lane Apt 312",
269
- locality: "Gotham",
270
- postal_code: "90210",
271
- region: "CA",
272
- country_code_alpha2: "US"
273
- }
274
- })).and_call_original
275
- authorize
276
- end
277
- end
278
- end
279
-
280
- context "with CreditCard transaction", vcr: {
281
- cassette_name: 'gateway/authorize/credit_card/address',
282
- match_requests_on: [:braintree_uri]
283
- } do
284
- let(:payment_type) { SolidusPaypalBraintree::Source::CREDIT_CARD }
285
-
286
- it 'includes the billing address in the request' do
287
- expect_any_instance_of(Braintree::TransactionGateway).to receive(:sale).
288
- with(hash_including({
289
- billing: {
290
- first_name: "Dick",
291
- last_name: "Grayson",
292
- street_address: "15 Robin Walk Apt 123",
293
- locality: "Blüdhaven",
294
- postal_code: "90210",
295
- region: "CA",
296
- country_code_alpha2: "US"
297
- }
298
- })).and_call_original
299
- authorize
300
- end
301
- end
302
- end
303
-
304
- describe "#capture" do
305
- subject(:capture) { gateway.capture(1000, authorized_id, {}) }
306
-
307
- context 'with successful capture', vcr: {
308
- cassette_name: 'gateway/capture',
309
- match_requests_on: [:braintree_uri]
310
- } do
311
- include_examples "successful response"
312
-
313
- it 'submits the transaction for settlement' do
314
- expect(capture.message).to eq "submitted_for_settlement"
315
- end
316
- end
317
-
318
- context 'with authorized transaction', vcr: {
319
- cassette_name: 'gateway/authorized_transaction',
320
- match_requests_on: [:braintree_uri]
321
- } do
322
- include_examples "protects against connection errors" do
323
- let(:gateway_action) { :submit_for_settlement }
324
- end
325
- end
326
- end
327
-
328
- describe "#credit" do
329
- subject(:credit) { gateway.credit(2000, source, settled_id, {}) }
330
-
331
- context 'with successful credit', vcr: {
332
- cassette_name: 'gateway/credit',
333
- match_requests_on: [:braintree_uri]
334
- } do
335
- include_examples "successful response"
336
-
337
- it 'credits the transaction' do
338
- expect(credit.message).to eq 'submitted_for_settlement'
339
- end
340
- end
341
-
342
- context 'with settled transaction', vcr: {
343
- cassette_name: 'gateway/settled_transaction',
344
- match_requests_on: [:braintree_uri]
345
- } do
346
- include_examples "protects against connection errors" do
347
- let(:gateway_action) { :refund }
348
- end
349
- end
350
- end
351
-
352
- describe "#void" do
353
- subject(:void) { gateway.void(authorized_id, source, {}) }
354
-
355
- context 'when successfully voided', vcr: {
356
- cassette_name: 'gateway/void',
357
- match_requests_on: [:braintree_uri]
358
- } do
359
- include_examples "successful response"
360
-
361
- it 'voids the transaction' do
362
- expect(void.message).to eq 'voided'
363
- end
364
- end
365
-
366
- context 'with authorized transaction', vcr: {
367
- cassette_name: 'gateway/authorized_transaction',
368
- match_requests_on: [:braintree_uri]
369
- } do
370
- include_examples "protects against connection errors" do
371
- let(:gateway_action) { :void }
372
- end
373
- end
374
- end
375
-
376
- describe "#cancel", vcr: {
377
- cassette_name: 'gateway/cancel',
378
- match_requests_on: [:braintree_uri]
379
- } do
380
- subject(:cancel) { gateway.cancel(transaction_id) }
381
-
382
- let(:transaction_id) { "fake_transaction_id" }
383
-
384
- context "when the transaction is found" do
385
- context "when it is voidable", vcr: {
386
- cassette_name: 'gateway/cancel/void',
387
- match_requests_on: [:braintree_uri]
388
- } do
389
- let(:transaction_id) { authorized_id }
390
-
391
- include_examples "successful response"
392
-
393
- it 'voids the transaction' do
394
- expect(cancel.message).to eq 'voided'
395
- end
396
- end
397
-
398
- context "when it is not voidable", vcr: {
399
- cassette_name: 'gateway/cancel/refunds',
400
- match_requests_on: [:braintree_uri]
401
- } do
402
- let(:transaction_id) { settled_id }
403
-
404
- include_examples "successful response"
405
-
406
- it 'refunds the transaction' do
407
- expect(cancel.message).to eq 'submitted_for_settlement'
408
- end
409
- end
410
- end
411
-
412
- context "when the transaction is not found", vcr: {
413
- cassette_name: 'gateway/cancel/missing',
414
- match_requests_on: [:braintree_uri]
415
- } do
416
- it 'raises an error' do
417
- expect{ cancel }.to raise_error ActiveMerchant::ConnectionError
418
- end
419
- end
420
- end
421
-
422
- describe '#try_void' do
423
- subject { gateway.try_void(instance_double('Spree::Payment', response_code: source.token)) }
424
-
425
- let(:transaction_request) do
426
- class_double('Braintree::Transaction',
427
- find: transaction_response)
428
- end
429
-
430
- before do
431
- client = instance_double('Braintree::Gateway')
432
- allow(client).to receive(:transaction) { transaction_request }
433
- allow(gateway).to receive(:braintree) { client }
434
- end
435
-
436
- context 'with voidable payment' do
437
- let(:transaction_response) do
438
- instance_double('Braintree::Transaction',
439
- status: Braintree::Transaction::Status::Authorized)
440
- end
441
-
442
- it 'voids the payment' do
443
- expect(gateway).to receive(:void)
444
- subject
445
- end
446
-
447
- context 'with error response mentioning an unvoidable transaction' do
448
- before do
449
- allow(gateway).to receive(:void) do
450
- raise ActiveMerchant::ConnectionError.new(
451
- 'Transaction can only be voided if status is authorized',
452
- double
453
- )
454
- end
455
- end
456
-
457
- it { is_expected.to be(false) }
458
- end
459
-
460
- context 'with other error response' do
461
- before do
462
- allow(gateway).to receive(:void) do
463
- raise ActiveMerchant::ConnectionError.new(
464
- 'Server unreachable',
465
- double
466
- )
467
- end
468
- end
469
-
470
- it { expect { subject }.to raise_error ActiveMerchant::ConnectionError }
471
- end
472
- end
473
-
474
- context 'with voidable paypal payment' do
475
- let(:transaction_response) do
476
- instance_double('Braintree::Transaction',
477
- status: Braintree::Transaction::Status::SettlementPending)
478
- end
479
-
480
- it 'voids the payment' do
481
- expect(gateway).to receive(:void)
482
- subject
483
- end
484
- end
485
-
486
- context 'with non-voidable payment' do
487
- let(:transaction_response) do
488
- instance_double('Braintree::Transaction',
489
- status: Braintree::Transaction::Status::Settled)
490
- end
491
-
492
- it { is_expected.to be(false) }
493
- end
494
- end
495
-
496
- describe "#create_profile" do
497
- subject(:profile) { gateway.create_profile(payment) }
498
-
499
- let(:payment) do
500
- build(:payment, {
501
- payment_method: gateway,
502
- source: source
503
- })
504
- end
505
-
506
- cassette_options = {
507
- cassette_name: "braintree/create_profile",
508
- match_requests_on: [:braintree_uri]
509
- }
510
- context "with no existing customer profile", vcr: cassette_options do
511
- it 'creates and returns a new customer profile', aggregate_failures: true do
512
- expect(profile).to be_a SolidusPaypalBraintree::Customer
513
- expect(profile.sources).to eq [source]
514
- expect(profile.braintree_customer_id).to be_present
515
- end
516
-
517
- it "sets a token on the payment source" do
518
- expect{ subject }.to change(source, :token)
519
- end
520
- end
521
-
522
- context "when the source already has a token" do
523
- before { source.token = "totally-a-valid-token" }
524
-
525
- it "does not create a new customer profile" do
526
- expect(profile).to be_nil
527
- end
528
- end
529
-
530
- context "when the source already has a customer" do
531
- before { source.build_customer }
532
-
533
- it "does not create a new customer profile" do
534
- expect(profile).to be_nil
535
- end
536
- end
537
-
538
- context "when the source has no nonce" do
539
- before { source.nonce = nil }
540
-
541
- it "does not create a new customer profile" do
542
- expect(profile).to be_nil
543
- end
544
- end
545
- end
546
-
547
- shared_examples "sources_by_order" do
548
- let(:order) { FactoryBot.create :order, user: user, state: "complete", completed_at: Time.current }
549
- let(:gateway) { new_gateway.tap(&:save!) }
550
-
551
- let(:other_payment_method) { FactoryBot.create(:payment_method) }
552
-
553
- let(:source_without_profile) do
554
- SolidusPaypalBraintree::Source.create!(
555
- payment_method_id: gateway.id,
556
- payment_type: payment_type,
557
- user_id: user.id
558
- )
559
- end
560
-
561
- let(:source_with_profile) do
562
- SolidusPaypalBraintree::Source.create!(
563
- payment_method_id: gateway.id,
564
- payment_type: payment_type,
565
- user_id: user.id
566
- ).tap do |source|
567
- source.create_customer!(user: user)
568
- source.save!
569
- end
570
- end
571
-
572
- before do
573
- create(:payment, order: order, payment_method_id: payment_method_id, source: source)
574
- end
575
-
576
- context "when the order has payments with the braintree payment method" do
577
- let(:payment_method_id) { gateway.id }
578
-
579
- context "when the payment has a saved source with a profile" do
580
- let(:source) { source_with_profile }
581
-
582
- it "returns the source" do
583
- expect(subject.to_a).to eql([source])
584
- end
585
- end
586
-
587
- context "when the payment has a saved source without a profile" do
588
- let(:source) { source_without_profile }
589
-
590
- it "returns no result" do
591
- expect(subject.to_a).to eql([])
592
- end
593
- end
594
- end
595
-
596
- context "when the order has no payments with the braintree payment method" do
597
- let(:payment_method_id) { other_payment_method.id }
598
- let(:source) { FactoryBot.create :credit_card }
599
-
600
- it "returns no results" do
601
- expect(subject.to_a).to eql([])
602
- end
603
- end
604
- end
605
-
606
- describe "#sources_by_order" do
607
- subject { gateway.sources_by_order(order) }
608
-
609
- let(:gateway) { new_gateway.tap(&:save!) }
610
- let(:order) { FactoryBot.create :order, user: user, state: "complete", completed_at: Time.current }
611
-
612
- include_examples "sources_by_order"
613
- end
614
-
615
- describe "#reusable_sources" do
616
- subject { gateway.reusable_sources(order) }
617
-
618
- let(:order) { FactoryBot.build :order, user: user }
619
- let(:gateway) { new_gateway.tap(&:save!) }
620
-
621
- context "when an order is completed" do
622
- include_examples "sources_by_order"
623
- end
624
-
625
- context "when an order is not completed" do
626
- context "when the order has a user id" do
627
- let(:user) { FactoryBot.create(:user) }
628
-
629
- let!(:source_without_profile) do
630
- SolidusPaypalBraintree::Source.create!(
631
- payment_method_id: gateway.id,
632
- payment_type: payment_type,
633
- user_id: user.id
634
- )
635
- end
636
-
637
- let!(:source_with_profile) do
638
- SolidusPaypalBraintree::Source.create!(
639
- payment_method_id: gateway.id,
640
- payment_type: payment_type,
641
- user_id: user.id
642
- ).tap do |source|
643
- source.create_customer!(user: user)
644
- source.save!
645
- end
646
- end
647
-
648
- it "includes saved sources with payment profiles" do
649
- expect(subject).to include(source_with_profile)
650
- end
651
-
652
- it "excludes saved sources without payment profiles" do
653
- expect(subject).not_to include(source_without_profile)
654
- end
655
- end
656
-
657
- context "when the order does not have a user" do
658
- let(:user) { nil }
659
-
660
- it "returns no sources for guest users" do
661
- expect(subject).to eql([])
662
- end
663
- end
664
- end
665
- end
666
- end
667
-
668
- describe '.generate_token' do
669
- subject do
670
- # dont VCR ignore generate token request, use the existing cassette
671
- allow(VCR.request_ignorer.hooks).to receive(:[]).with(:ignore_request).and_return([])
672
- gateway.generate_token
673
- end
674
-
675
- context 'with connection enabled', vcr: {
676
- cassette_name: 'braintree/generate_token',
677
- match_requests_on: [:braintree_uri]
678
- } do
679
- it { is_expected.to be_a(String).and be_present }
680
- end
681
-
682
- context 'when token generation is disabled' do
683
- let(:gateway) do
684
- gateway = described_class.create!(name: 'braintree')
685
- gateway.preferred_token_generation_enabled = false
686
- gateway
687
- end
688
-
689
- it { expect { subject }.to raise_error SolidusPaypalBraintree::Gateway::TokenGenerationDisabledError }
690
- end
691
- end
692
- end