stripe-ruby-mock 2.5.6 → 3.1.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -1
  3. data/.travis.yml +6 -9
  4. data/CHANGELOG.md +35 -0
  5. data/Gemfile +1 -0
  6. data/README.md +17 -11
  7. data/lib/stripe_mock.rb +11 -0
  8. data/lib/stripe_mock/api/client.rb +1 -1
  9. data/lib/stripe_mock/api/errors.rb +34 -28
  10. data/lib/stripe_mock/api/instance.rb +1 -1
  11. data/lib/stripe_mock/api/webhooks.rb +7 -0
  12. data/lib/stripe_mock/client.rb +2 -1
  13. data/lib/stripe_mock/data.rb +323 -13
  14. data/lib/stripe_mock/data/list.rb +42 -9
  15. data/lib/stripe_mock/instance.rb +52 -5
  16. data/lib/stripe_mock/request_handlers/account_links.rb +15 -0
  17. data/lib/stripe_mock/request_handlers/balance_transactions.rb +2 -2
  18. data/lib/stripe_mock/request_handlers/charges.rb +13 -12
  19. data/lib/stripe_mock/request_handlers/checkout.rb +15 -0
  20. data/lib/stripe_mock/request_handlers/checkout_session.rb +16 -0
  21. data/lib/stripe_mock/request_handlers/customers.rb +35 -18
  22. data/lib/stripe_mock/request_handlers/ephemeral_key.rb +1 -1
  23. data/lib/stripe_mock/request_handlers/express_login_links.rb +15 -0
  24. data/lib/stripe_mock/request_handlers/helpers/coupon_helpers.rb +14 -10
  25. data/lib/stripe_mock/request_handlers/helpers/subscription_helpers.rb +22 -7
  26. data/lib/stripe_mock/request_handlers/helpers/token_helpers.rb +1 -1
  27. data/lib/stripe_mock/request_handlers/invoices.rb +11 -5
  28. data/lib/stripe_mock/request_handlers/payment_intents.rb +182 -0
  29. data/lib/stripe_mock/request_handlers/payment_methods.rb +120 -0
  30. data/lib/stripe_mock/request_handlers/plans.rb +1 -1
  31. data/lib/stripe_mock/request_handlers/prices.rb +44 -0
  32. data/lib/stripe_mock/request_handlers/products.rb +44 -0
  33. data/lib/stripe_mock/request_handlers/refunds.rb +6 -3
  34. data/lib/stripe_mock/request_handlers/setup_intents.rb +93 -0
  35. data/lib/stripe_mock/request_handlers/sources.rb +12 -6
  36. data/lib/stripe_mock/request_handlers/subscription_items.rb +36 -0
  37. data/lib/stripe_mock/request_handlers/subscriptions.rb +82 -41
  38. data/lib/stripe_mock/request_handlers/tax_rates.rb +36 -0
  39. data/lib/stripe_mock/request_handlers/tokens.rb +8 -6
  40. data/lib/stripe_mock/request_handlers/validators/param_validators.rb +130 -9
  41. data/lib/stripe_mock/test_strategies/base.rb +68 -8
  42. data/lib/stripe_mock/test_strategies/live.rb +23 -12
  43. data/lib/stripe_mock/test_strategies/mock.rb +6 -2
  44. data/lib/stripe_mock/version.rb +1 -1
  45. data/lib/stripe_mock/webhook_fixtures/balance.available.json +6 -0
  46. data/lib/stripe_mock/webhook_fixtures/charge.dispute.funds_reinstated.json +88 -0
  47. data/lib/stripe_mock/webhook_fixtures/charge.dispute.funds_withdrawn.json +88 -0
  48. data/lib/stripe_mock/webhook_fixtures/charge.failed.json +166 -38
  49. data/lib/stripe_mock/webhook_fixtures/customer.created.json +1 -0
  50. data/lib/stripe_mock/webhook_fixtures/customer.updated.json +1 -0
  51. data/lib/stripe_mock/webhook_fixtures/invoice.created.json +2 -1
  52. data/lib/stripe_mock/webhook_fixtures/invoice.payment_succeeded.json +1 -1
  53. data/lib/stripe_mock/webhook_fixtures/invoice.updated.json +2 -1
  54. data/lib/stripe_mock/webhook_fixtures/payment_intent.payment_failed.json +186 -0
  55. data/lib/stripe_mock/webhook_fixtures/payment_intent.succeeded.json +164 -0
  56. data/lib/stripe_mock/webhook_fixtures/product.created.json +34 -0
  57. data/lib/stripe_mock/webhook_fixtures/product.deleted.json +34 -0
  58. data/lib/stripe_mock/webhook_fixtures/product.updated.json +38 -0
  59. data/spec/instance_spec.rb +10 -12
  60. data/spec/list_spec.rb +38 -0
  61. data/spec/server_spec.rb +6 -3
  62. data/spec/shared_stripe_examples/account_examples.rb +1 -1
  63. data/spec/shared_stripe_examples/account_link_examples.rb +16 -0
  64. data/spec/shared_stripe_examples/balance_examples.rb +6 -0
  65. data/spec/shared_stripe_examples/balance_transaction_examples.rb +3 -3
  66. data/spec/shared_stripe_examples/bank_examples.rb +3 -3
  67. data/spec/shared_stripe_examples/card_examples.rb +4 -4
  68. data/spec/shared_stripe_examples/card_token_examples.rb +17 -21
  69. data/spec/shared_stripe_examples/charge_examples.rb +32 -36
  70. data/spec/shared_stripe_examples/checkout_examples.rb +38 -0
  71. data/spec/shared_stripe_examples/coupon_examples.rb +1 -1
  72. data/spec/shared_stripe_examples/customer_examples.rb +103 -53
  73. data/spec/shared_stripe_examples/dispute_examples.rb +2 -2
  74. data/spec/shared_stripe_examples/error_mock_examples.rb +8 -7
  75. data/spec/shared_stripe_examples/express_login_link_examples.rb +12 -0
  76. data/spec/shared_stripe_examples/external_account_examples.rb +3 -3
  77. data/spec/shared_stripe_examples/invoice_examples.rb +43 -41
  78. data/spec/shared_stripe_examples/invoice_item_examples.rb +1 -1
  79. data/spec/shared_stripe_examples/payment_intent_examples.rb +147 -0
  80. data/spec/shared_stripe_examples/payment_method_examples.rb +449 -0
  81. data/spec/shared_stripe_examples/payout_examples.rb +2 -2
  82. data/spec/shared_stripe_examples/plan_examples.rb +135 -77
  83. data/spec/shared_stripe_examples/price_examples.rb +183 -0
  84. data/spec/shared_stripe_examples/product_examples.rb +155 -0
  85. data/spec/shared_stripe_examples/refund_examples.rb +41 -31
  86. data/spec/shared_stripe_examples/setup_intent_examples.rb +68 -0
  87. data/spec/shared_stripe_examples/subscription_examples.rb +546 -295
  88. data/spec/shared_stripe_examples/subscription_items_examples.rb +76 -0
  89. data/spec/shared_stripe_examples/tax_rate_examples.rb +42 -0
  90. data/spec/shared_stripe_examples/transfer_examples.rb +9 -9
  91. data/spec/shared_stripe_examples/webhook_event_examples.rb +11 -11
  92. data/spec/spec_helper.rb +7 -4
  93. data/spec/stripe_mock_spec.rb +4 -4
  94. data/spec/support/shared_contexts/stripe_validator_spec.rb +8 -0
  95. data/spec/support/stripe_examples.rb +12 -2
  96. data/stripe-ruby-mock.gemspec +8 -3
  97. metadata +81 -32
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 0b5d9cbcf4490a6413cf153d1c2a1a21acf38929
4
- data.tar.gz: cb9f625fc17632de27cfeef7ec97f429fa79804d
2
+ SHA256:
3
+ metadata.gz: e44063ad0593364e5b9a85f514113c0dd8222e95440410ff9989545e2b947f08
4
+ data.tar.gz: 3bb136ecba532f8e6e8078b5eba0c8877876d6cf9a0f9c66cb311fd8271e9242
5
5
  SHA512:
6
- metadata.gz: bde32906b3e0c262da53cbea9263250a497736e81c824a08c6c668546317f8209ed3bd5e6c4ef34df5414af3d753d6a6fdcaedf956e7e4f9a31a50f327e4174b
7
- data.tar.gz: 182a87b8a9f5cc078ecb5c8a3afbcfd6d51d14d72518928aad1e2e85effb1bb3667888fee21a658dc428c4fd1e7c6a1303ea09599e9b2d7791801576fc6b5029
6
+ metadata.gz: 36e31f008894062f3678c14158436b50a72699977d14c9419e36b53ca4c22d68d3f2bc5f72fac39abb0adcd01121ae3223b43cc71bc79c54159fcba343131d3e
7
+ data.tar.gz: a49ae0d98ffa6560dac087acfeff75ea041c8d63a1703b7e72214321362208ef4b38ef9411f5698022c2fdc1003345e21f1c10e02309a93ce624fbb67f7108e6
data/.gitignore CHANGED
@@ -5,4 +5,4 @@ stripe-mock-server.pid
5
5
  Gemfile.lock
6
6
  stripe-mock-server.log
7
7
  .idea
8
- .ruby-version
8
+ .ruby-version
data/.travis.yml CHANGED
@@ -1,15 +1,12 @@
1
- dist: trusty
2
- group: deprecated-2017Q2
3
1
  sudo: required
4
2
  language: ruby
5
3
  rvm:
6
- - 2.0.0
7
- - 2.1.10
8
- - 2.2.7
9
- - 2.3.4
4
+ - 2.4.6
5
+ - 2.5.5
6
+ - 2.6.3
7
+ - 2.7.0
10
8
  before_install:
11
- - rvm 2.1.10 do gem install mime-types -v 2.6.2
12
- - gem install bundler
9
+ - gem install bundler -v '< 2'
13
10
  before_script:
14
11
  - "sudo touch /var/log/stripe-mock-server.log"
15
12
  - "sudo chown travis /var/log/stripe-mock-server.log"
@@ -17,7 +14,7 @@ script: "bundle exec rspec && bundle exec rspec -t live"
17
14
 
18
15
  env:
19
16
  global:
20
- - IS_TRAVIS=true STRIPE_TEST_SECRET_KEY_A=sk_test_Ut2MSlZANdT3iDALdGhyLymy STRIPE_TEST_SECRET_KEY_B=sk_test_JXtzss9tHOG1ofIyEZgoUP4Q STRIPE_TEST_SECRET_KEY_C=sk_test_ZR5nVz9p3ivsqVa7mYB0sFep STRIPE_TEST_SECRET_KEY_D=sk_test_ZR5nVz9p3ivsqVa7mYB0sFep
17
+ - IS_TRAVIS=true STRIPE_TEST_SECRET_KEY_A=sk_test_BsztzqQjzd7lqkgo1LjEG5DF00KzH7tWKF STRIPE_TEST_SECRET_KEY_B=sk_test_rKCEu0x8jzg6cKPqoey8kUPQ00usQO3KYE STRIPE_TEST_SECRET_KEY_C=sk_test_qeaB7R6Ywp8sC9pzd1ZIABH700YLC7nhmZ STRIPE_TEST_SECRET_KEY_D=sk_test_r1NwHkUW7UyoozyP4aEBD6cs00CI5uDiGq
21
18
 
22
19
  notifications:
23
20
  webhooks:
data/CHANGELOG.md ADDED
@@ -0,0 +1,35 @@
1
+ ### 3.1.0.rc2 (pre-release 2021-03-03)
2
+
3
+ - [#767](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/767): Fixes tests and more [@lpsBetty](https://github.com/lpsBetty)
4
+
5
+ ### 3.1.0.rc1 (pre-release 2021-02-17)
6
+
7
+ - [#765](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/765): Properly set the status of a trialing subscription. [@csalvato](https://github.com/csalvato)
8
+ - [#764](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/764): Fixes erroneous error message when fetching upcoming invoices. [@csalvato](https://github.com/csalvato)
9
+ - [#762](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/762): Support Stripe Connect with Customers by adding stripe_account header namespace for customer object [@csalvato](https://github.com/csalvato)
10
+ - [#755](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/755): Add allowed params to subscriptions [@dominikdarnel ](https://github.com/dominikdarnel)
11
+ - [#748](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/758): Support Prices - [@hidenba](https://github.com/hidenba) and [@jamesprior](https://github.com/jamesprior).
12
+ - [#747](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/747/files): Fix ruby 2.7 deprecation warnings. Adds Ruby 3.0.0 compatibility. [@coding-chimp](https://github.com/coding-chimp)
13
+ - [#715](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/715): Added application_fee_amount to mock charge object - [@espen](https://github.com/espen)
14
+ - [#709](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/709): Remove unnecessary check on customer's currency - [@coorasse](https://github.com/coorasse)
15
+
16
+ ### 3.0.1 (TBD)
17
+
18
+ - Added Changelog file
19
+ - [#640](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/640): Support Payment Intent status requires_capture - [@theodorton](https://github.com/theodorton).
20
+ - [#685](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/685): Adds support for pending_invoice_item_interval - [@joshcass](https://github.com/joshcass).
21
+ - [#682](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/682): Prevent customer metadata from being overwritten with each update - [@sethkrasnianski](https://github.com/sethkrasnianski).
22
+ - [#679](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/679): Fix for [#678](https://github.com/stripe-ruby-mock/stripe-ruby-mock/issues/678) Add active filter to Data::List - [@rnmp](https://github.com/rnmp).
23
+ - [#668](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/668): Fix for [#665](https://github.com/stripe-ruby-mock/stripe-ruby-mock/issues/665) Allow to remove discount from customer - [@mnin](https://github.com/mnin).
24
+ - [#667](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/667):
25
+ Remove empty and duplicated methods from payment methods - [@mnin](https://github.com/mnin).
26
+ - [#664](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/664): Bugfix: pass through PaymentIntent amount to mocked Charge - [@typeoneerror](https://github.com/typeoneerror).
27
+ - [#654](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/654): fix for [#626](https://github.com/stripe-ruby-mock/stripe-ruby-mock/issues/626) Added missing decline codes - [@iCreateJB](https://github.com/iCreateJB).
28
+ - [#648](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/648): Initial implementation of checkout session API - [@fauxparse](https://github.com/fauxparse).
29
+ - [#644](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/644): Allow payment_behavior attribute on subscription create - [@j15e](https://github.com/j15e).
30
+
31
+ ### 3.0.0 (2019-12-17)
32
+
33
+ ##### the main thing is:
34
+
35
+ - [#658](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/658) Make the gem compatible with Stripe Gem v.5
data/Gemfile CHANGED
@@ -7,6 +7,7 @@ end
7
7
 
8
8
  group :test do
9
9
  gem 'rake'
10
+ gem 'dotenv'
10
11
  end
11
12
 
12
13
  gemspec
data/README.md CHANGED
@@ -1,18 +1,24 @@
1
- # stripe-ruby-mock [![Build Status](https://travis-ci.org/rebelidealist/stripe-ruby-mock.png?branch=master)](https://travis-ci.org/rebelidealist/stripe-ruby-mock) [![Gitter chat](https://badges.gitter.im/rebelidealist/stripe-ruby-mock.png)](https://gitter.im/rebelidealist/stripe-ruby-mock)
1
+ # stripe-ruby-mock [![Build Status](https://travis-ci.org/stripe-ruby-mock/stripe-ruby-mock.png?branch=master)](https://travis-ci.org/stripe-ruby-mock/stripe-ruby-mock) [![Gitter chat](https://badges.gitter.im/rebelidealist/stripe-ruby-mock.png)](https://gitter.im/rebelidealist/stripe-ruby-mock)
2
2
 
3
- * Homepage: https://github.com/rebelidealist/stripe-ruby-mock
4
- * Issues: https://github.com/rebelidealist/stripe-ruby-mock/issues
3
+ * Homepage: https://github.com/stripe-ruby-mock/stripe-ruby-mock
4
+ * Issues: https://github.com/stripe-ruby-mock/stripe-ruby-mock/issues
5
5
  * **CHAT**: https://gitter.im/rebelidealist/stripe-ruby-mock
6
6
 
7
7
  # REQUEST: Looking for More Core Contributors
8
8
 
9
- This gem has unexpectedly grown in popularity and I've gotten pretty busy, so I'm currently looking for more core contributors to help me out. If you're interested, there is only one requirement: submit a significant enough pull request and have it merged into master (many of you have already done this). Afterwards, ping me in [chat](https://gitter.im/rebelidealist/stripe-ruby-mock) and I will add you as a collaborator.
9
+ This gem has unexpectedly grown in popularity and I've gotten pretty busy, so I'm currently looking for more core contributors to help me out. If you're interested, there is only one requirement: submit a significant enough pull request and have it merged into master (many of you have already done this). Afterwards, ping [@gilbert](https://gitter.im/gilbert) in [chat](https://gitter.im/rebelidealist/stripe-ruby-mock) and I will add you as a collaborator.
10
10
 
11
11
  ## Install
12
12
 
13
13
  In your gemfile:
14
14
 
15
- gem 'stripe-ruby-mock', '~> 2.5.6', :require => 'stripe_mock'
15
+ gem 'stripe-ruby-mock', '~> 3.0.1', :require => 'stripe_mock'
16
+
17
+ ## !!! Important
18
+
19
+ We have [changelog](https://github.com/stripe-ruby-mock/stripe-ruby-mock/blob/master/CHANGELOG.md). It's first attempt. Feel free to update it and suggest to a new format of it.
20
+
21
+ version `3.0.0` has [breaking changes](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/658) - we support stripe > 5 and < 6 for now and try to follow the newest API version. But if you still use older versions please [read](https://github.com/stripe-ruby-mock/stripe-ruby-mock#specifications).
16
22
 
17
23
  ## Features
18
24
 
@@ -23,12 +29,12 @@ In your gemfile:
23
29
 
24
30
  ### Requirements
25
31
 
26
- * ruby >= 2.0.0
27
- * stripe >= 2.0.3
32
+ * ruby >= 2.4.0
33
+ * stripe >= 5.0.0
28
34
 
29
35
  ### Specifications
30
36
 
31
- **STRIPE API TARGET VERSION:** 2017-06-05 (master)
37
+ **STRIPE API TARGET VERSION:** 2019-08-20 (master) - we try, but some features are not implemented yet.
32
38
 
33
39
  Older API version branches:
34
40
 
@@ -141,7 +147,7 @@ end
141
147
  ```
142
148
 
143
149
  ## Mocking Card Errors
144
-
150
+ ** Ensure you start StripeMock in a before filter `StripeMock.start`
145
151
  Tired of manually inputting fake credit card numbers to test against errors? Tire no more!
146
152
 
147
153
  ```ruby
@@ -176,7 +182,7 @@ StripeMock.prepare_card_error(:incorrect_zip)
176
182
  You can see the details of each error in [lib/stripe_mock/api/errors.rb](lib/stripe_mock/api/errors.rb)
177
183
 
178
184
  ### Specifying Card Errors
179
-
185
+ ** Ensure you start StripeMock in a before filter `StripeMock.start`
180
186
  By default, `prepare_card_error` only triggers for `:new_charge`, the event that happens when you run `Charge.create`. More explicitly, this is what happens by default:
181
187
 
182
188
  ```ruby
@@ -195,7 +201,7 @@ customer.cards.create
195
201
  `:new_charge` and `:create_card` are names of methods in the [StripeMock request handlers](lib/stripe_mock/request_handlers). You can also set `StripeMock.toggle_debug(true)` to see the event name for each Stripe request made in your tests.
196
202
 
197
203
  ### Custom Errors
198
-
204
+ ** Ensure you start StripeMock in a before filter `StripeMock.start`
199
205
  To raise an error on a specific type of request, take a look at the [request handlers folder](lib/stripe_mock/request_handlers/) and pass a method name to `StripeMock.prepare_error`.
200
206
 
201
207
  If you wanted to raise an error for creating a new customer, for instance, you would do the following:
data/lib/stripe_mock.rb CHANGED
@@ -47,6 +47,8 @@ require 'stripe_mock/request_handlers/helpers/token_helpers.rb'
47
47
 
48
48
  require 'stripe_mock/request_handlers/validators/param_validators.rb'
49
49
 
50
+ require 'stripe_mock/request_handlers/account_links.rb'
51
+ require 'stripe_mock/request_handlers/express_login_links.rb'
50
52
  require 'stripe_mock/request_handlers/accounts.rb'
51
53
  require 'stripe_mock/request_handlers/external_accounts.rb'
52
54
  require 'stripe_mock/request_handlers/balance.rb'
@@ -62,14 +64,23 @@ require 'stripe_mock/request_handlers/invoices.rb'
62
64
  require 'stripe_mock/request_handlers/invoice_items.rb'
63
65
  require 'stripe_mock/request_handlers/orders.rb'
64
66
  require 'stripe_mock/request_handlers/plans.rb'
67
+ require 'stripe_mock/request_handlers/prices.rb'
65
68
  require 'stripe_mock/request_handlers/recipients.rb'
66
69
  require 'stripe_mock/request_handlers/refunds.rb'
67
70
  require 'stripe_mock/request_handlers/transfers.rb'
71
+ require 'stripe_mock/request_handlers/payment_intents.rb'
72
+ require 'stripe_mock/request_handlers/payment_methods.rb'
73
+ require 'stripe_mock/request_handlers/setup_intents.rb'
68
74
  require 'stripe_mock/request_handlers/payouts.rb'
69
75
  require 'stripe_mock/request_handlers/subscriptions.rb'
76
+ require 'stripe_mock/request_handlers/subscription_items.rb'
70
77
  require 'stripe_mock/request_handlers/tokens.rb'
71
78
  require 'stripe_mock/request_handlers/country_spec.rb'
72
79
  require 'stripe_mock/request_handlers/ephemeral_key.rb'
80
+ require 'stripe_mock/request_handlers/products.rb'
81
+ require 'stripe_mock/request_handlers/tax_rates.rb'
82
+ require 'stripe_mock/request_handlers/checkout.rb'
83
+ require 'stripe_mock/request_handlers/checkout_session.rb'
73
84
  require 'stripe_mock/instance'
74
85
 
75
86
  require 'stripe_mock/test_strategies/base.rb'
@@ -8,7 +8,7 @@ module StripeMock
8
8
  return false if @state == 'live'
9
9
  return @client unless @client.nil?
10
10
 
11
- Stripe::StripeClient.send(:define_method, :execute_request) { |*args| StripeMock.redirect_to_mock_server(*args) }
11
+ Stripe::StripeClient.send(:define_method, :execute_request) { |*args, **keyword_args| StripeMock.redirect_to_mock_server(*args, **keyword_args) }
12
12
  @client = StripeMock::Client.new(port)
13
13
  @state = 'remote'
14
14
  @client
@@ -1,5 +1,4 @@
1
1
  module StripeMock
2
-
3
2
  def self.prepare_error(stripe_error, *handler_names)
4
3
  handler_names.push(:all) if handler_names.count == 0
5
4
 
@@ -15,28 +14,33 @@ module StripeMock
15
14
  def self.prepare_card_error(code, *handler_names)
16
15
  handler_names.push(:new_charge) if handler_names.count == 0
17
16
 
18
- args = CardErrors.argument_map[code]
19
- raise StripeMockError.new("Unrecognized stripe card error code: #{code}") if args.nil?
20
- self.prepare_error Stripe::CardError.new(*args), *handler_names
17
+ error = CardErrors.build_error_for(code)
18
+ if error.nil?
19
+ raise StripeMockError, "Unrecognized stripe card error code: #{code}"
20
+ end
21
+
22
+ prepare_error error, *handler_names
21
23
  end
22
24
 
23
25
  module CardErrors
24
-
25
- def self.argument_map
26
- @__map ||= {
27
- incorrect_number: add_json_body(["The card number is incorrect", 'number', 'incorrect_number', http_status: 402]),
28
- invalid_number: add_json_body(["The card number is not a valid credit card number", 'number', 'invalid_number', http_status: 402]),
29
- invalid_expiry_month: add_json_body(["The card's expiration month is invalid", 'exp_month', 'invalid_expiry_month', http_status: 402]),
30
- invalid_expiry_year: add_json_body(["The card's expiration year is invalid", 'exp_year', 'invalid_expiry_year', http_status: 402]),
31
- invalid_cvc: add_json_body(["The card's security code is invalid", 'cvc', 'invalid_cvc', http_status: 402]),
32
- expired_card: add_json_body(["The card has expired", 'exp_month', 'expired_card', http_status: 402]),
33
- incorrect_cvc: add_json_body(["The card's security code is incorrect", 'cvc', 'incorrect_cvc', http_status: 402]),
34
- card_declined: add_json_body(["The card was declined", nil, 'card_declined', http_status: 402]),
35
- missing: add_json_body(["There is no card on a customer that is being charged.", nil, 'missing', http_status: 402]),
36
- processing_error: add_json_body(["An error occurred while processing the card", nil, 'processing_error', http_status: 402]),
37
- card_error: add_json_body(['The card number is not a valid credit card number.', 'number', 'invalid_number', http_status: 402]),
38
- incorrect_zip: add_json_body(['The zip code you supplied failed validation.', 'address_zip', 'incorrect_zip', http_status: 402])
39
- }
26
+ def self.build_error_for(code)
27
+ case code
28
+ when :incorrect_number then build_card_error('The card number is incorrect', 'number', code: 'incorrect_number', http_status: 402)
29
+ when :invalid_number then build_card_error('The card number is not a valid credit card number', 'number', code: 'invalid_number', http_status: 402)
30
+ when :invalid_expiry_month then build_card_error("The card's expiration month is invalid", 'exp_month', code: 'invalid_expiry_month', http_status: 402)
31
+ when :invalid_expiry_year then build_card_error("The card's expiration year is invalid", 'exp_year', code: 'invalid_expiry_year', http_status: 402)
32
+ when :invalid_cvc then build_card_error("The card's security code is invalid", 'cvc', code: 'invalid_cvc', http_status: 402)
33
+ when :expired_card then build_card_error('The card has expired', 'exp_month', code: 'expired_card', http_status: 402)
34
+ when :incorrect_cvc then build_card_error("The card's security code is incorrect", 'cvc', code: 'incorrect_cvc', http_status: 402)
35
+ when :card_declined then build_card_error('The card was declined', nil, code: 'card_declined', http_status: 402)
36
+ when :missing then build_card_error('There is no card on a customer that is being charged.', nil, code: 'missing', http_status: 402)
37
+ when :processing_error then build_card_error('An error occurred while processing the card', nil, code: 'processing_error', http_status: 402)
38
+ when :card_error then build_card_error('The card number is not a valid credit card number.', 'number', code: 'invalid_number', http_status: 402)
39
+ when :incorrect_zip then build_card_error('The zip code you supplied failed validation.', 'address_zip', code: 'incorrect_zip', http_status: 402)
40
+ when :insufficient_funds then build_card_error('The card has insufficient funds to complete the purchase.', nil, code: 'insufficient_funds', http_status: 402)
41
+ when :lost_card then build_card_error('The payment has been declined because the card is reported lost.', nil, code: 'lost_card', http_status: 402)
42
+ when :stolen_card then build_card_error('The payment has been declined because the card is reported stolen.', nil, code: 'stolen_card', http_status: 402)
43
+ end
40
44
  end
41
45
 
42
46
  def self.get_decline_code(code)
@@ -50,16 +54,18 @@ module StripeMock
50
54
  decline_code_map[code_key]
51
55
  end
52
56
 
53
- def self.add_json_body(error_values)
54
- error_keys = [:message, :param, :code]
55
-
56
- json_hash = Hash[error_keys.zip error_values]
57
- json_hash[:type] = 'card_error'
58
- json_hash[:decline_code] = get_decline_code(json_hash[:code])
57
+ def self.build_card_error(message, param, **kwargs)
58
+ json_hash = {
59
+ message: message,
60
+ param: param,
61
+ code: kwargs[:code],
62
+ type: 'card_error',
63
+ decline_code: get_decline_code(kwargs[:code])
64
+ }
59
65
 
60
- error_values.last.merge!(json_body: { error: json_hash }, http_body: { error: json_hash })
66
+ error_keyword_args = kwargs.merge(json_body: { error: json_hash }, http_body: { error: json_hash }.to_json)
61
67
 
62
- error_values
68
+ Stripe::CardError.new(message, param, **error_keyword_args)
63
69
  end
64
70
  end
65
71
  end
@@ -7,7 +7,7 @@ module StripeMock
7
7
  def self.start
8
8
  return false if @state == 'live'
9
9
  @instance = instance = Instance.new
10
- Stripe::StripeClient.send(:define_method, :execute_request) { |*args| instance.mock_request(*args) }
10
+ Stripe::StripeClient.send(:define_method, :execute_request) { |*args, **keyword_args| instance.mock_request(*args, **keyword_args) }
11
11
  @state = 'local'
12
12
  end
13
13
 
@@ -50,6 +50,8 @@ module StripeMock
50
50
  'charge.dispute.created',
51
51
  'charge.dispute.updated',
52
52
  'charge.dispute.closed',
53
+ 'charge.dispute.funds_reinstated',
54
+ 'charge.dispute.funds_withdrawn',
53
55
  'customer.source.created',
54
56
  'customer.source.deleted',
55
57
  'customer.source.updated',
@@ -70,9 +72,14 @@ module StripeMock
70
72
  'invoiceitem.created',
71
73
  'invoiceitem.updated',
72
74
  'invoiceitem.deleted',
75
+ 'payment_intent.succeeded',
76
+ 'payment_intent.payment_failed',
73
77
  'plan.created',
74
78
  'plan.updated',
75
79
  'plan.deleted',
80
+ 'product.created',
81
+ 'product.updated',
82
+ 'product.deleted',
76
83
  'coupon.created',
77
84
  'coupon.deleted',
78
85
  'transfer.created',
@@ -18,7 +18,8 @@ module StripeMock
18
18
  @pipe.mock_request(method, url, api_key: api_key, params: params, headers: headers).tap {|result|
19
19
  response, api_key = result
20
20
  if response.is_a?(Hash) && response[:error_raised] == 'invalid_request'
21
- raise Stripe::InvalidRequestError.new(*response[:error_params])
21
+ args, keyword_args = response[:error_params].first(2), response[:error_params].last
22
+ raise Stripe::InvalidRequestError.new(*args, **keyword_args)
22
23
  end
23
24
  }
24
25
  end
@@ -101,9 +101,46 @@ module StripeMock
101
101
  }.merge(params)
102
102
  end
103
103
 
104
+ def self.mock_account_link(params = {})
105
+ now = Time.now.to_i
106
+ {
107
+ object: 'account_link',
108
+ created: now,
109
+ expires_at: now + 300,
110
+ url: 'https://connect.stripe.com/setup/c/iB0ph1cPnRLY',
111
+ data: {}
112
+ }.merge(params)
113
+ end
114
+
115
+ def self.mock_express_login_link(params = {})
116
+ now = Time.now.to_i
117
+ {
118
+ object: 'login_link',
119
+ created: now,
120
+ url: 'https://connect.stripe.com/express/Ln7FfnNpUcCU',
121
+ data: {}
122
+ }.merge(params)
123
+ end
124
+
125
+ def self.mock_tax_rate(params)
126
+ {
127
+ id: 'test_cus_default',
128
+ object: 'tax_rate',
129
+ active: true,
130
+ created: 1559079603,
131
+ description: nil,
132
+ display_name: 'VAT',
133
+ inclusive: false,
134
+ jurisdiction: 'EU',
135
+ livemode: false,
136
+ metadata: {},
137
+ percentage: 21.0
138
+ }.merge(params)
139
+ end
140
+
104
141
  def self.mock_customer(sources, params)
105
142
  cus_id = params[:id] || "test_cus_default"
106
- currency = params[:currency] || StripeMock.default_currency
143
+ currency = params[:currency]
107
144
  sources.each {|source| source[:customer] = cus_id}
108
145
  {
109
146
  email: 'stripe_mock@example.com',
@@ -111,20 +148,29 @@ module StripeMock
111
148
  object: "customer",
112
149
  created: 1372126710,
113
150
  id: cus_id,
151
+ name: nil,
152
+ preferred_locales: [],
114
153
  livemode: false,
115
154
  delinquent: false,
116
155
  discount: nil,
117
156
  account_balance: 0,
118
157
  currency: currency,
158
+ invoice_settings: {
159
+ default_payment_method: nil,
160
+ custom_fields: nil,
161
+ footer: nil
162
+ },
119
163
  sources: {
120
164
  object: "list",
121
165
  total_count: sources.size,
166
+ has_more: false,
122
167
  url: "/v1/customers/#{cus_id}/sources",
123
168
  data: sources
124
169
  },
125
170
  subscriptions: {
126
171
  object: "list",
127
172
  total_count: 0,
173
+ has_more: false,
128
174
  url: "/v1/customers/#{cus_id}/subscriptions",
129
175
  data: []
130
176
  },
@@ -143,6 +189,7 @@ module StripeMock
143
189
  paid: true,
144
190
  amount: 0,
145
191
  application_fee: nil,
192
+ application_fee_amount: nil,
146
193
  currency: currency,
147
194
  destination: nil,
148
195
  fraud_details: {},
@@ -182,7 +229,7 @@ module StripeMock
182
229
  data: []
183
230
  },
184
231
  transfer: nil,
185
- balance_transaction: "txn_2dyYXXP90MN26R",
232
+ balance_transaction: params[:balance_transaction] || "txn_2dyYXXP90MN26R",
186
233
  failure_message: nil,
187
234
  failure_code: nil,
188
235
  amount_refunded: 0,
@@ -316,6 +363,7 @@ module StripeMock
316
363
  },
317
364
  cancel_at_period_end: false,
318
365
  canceled_at: nil,
366
+ collection_method: 'charge_automatically',
319
367
  ended_at: nil,
320
368
  start: 1308595038,
321
369
  object: 'subscription',
@@ -325,7 +373,12 @@ module StripeMock
325
373
  quantity: 1,
326
374
  tax_percent: nil,
327
375
  discount: nil,
328
- metadata: {}
376
+ metadata: {},
377
+ default_tax_rates: nil,
378
+ default_payment_method: nil,
379
+ pending_invoice_item_interval: nil,
380
+ next_pending_invoice_item_invoice: nil,
381
+ latest_invoice: nil
329
382
  }, params)
330
383
  end
331
384
 
@@ -335,12 +388,17 @@ module StripeMock
335
388
  lines << Data.mock_line_item() if lines.empty?
336
389
  invoice = {
337
390
  id: 'in_test_invoice',
338
- date: 1349738950,
391
+ status: 'open',
392
+ invoice_pdf: 'pdf_url',
393
+ hosted_invoice_url: 'hosted_invoice_url',
394
+ created: 1349738950,
339
395
  period_end: 1349738950,
340
396
  period_start: 1349738950,
397
+ due_date: nil,
341
398
  lines: {
342
399
  object: "list",
343
400
  total_count: lines.count,
401
+ has_more: false,
344
402
  url: "/v1/invoices/#{in_id}/lines",
345
403
  data: lines
346
404
  },
@@ -356,15 +414,16 @@ module StripeMock
356
414
  paid: false,
357
415
  receipt_number: nil,
358
416
  statement_descriptor: nil,
359
- tax: nil,
417
+ tax: 10,
360
418
  tax_percent: nil,
361
419
  webhooks_delivered_at: 1349825350,
362
420
  livemode: false,
363
421
  attempt_count: 0,
364
- amount_due: nil,
422
+ amount_due: 100,
423
+ amount_paid: 0,
365
424
  currency: currency,
366
425
  starting_balance: 0,
367
- ending_balance: nil,
426
+ ending_balance: 0,
368
427
  next_payment_attempt: 1349825350,
369
428
  charge: nil,
370
429
  discount: nil,
@@ -378,6 +437,7 @@ module StripeMock
378
437
  end
379
438
  due = invoice[:total] + invoice[:starting_balance]
380
439
  invoice[:amount_due] = due < 0 ? 0 : due
440
+ invoice[:ending_balance] = invoice[:starting_balance] + invoice[:total] if invoice[:amount_due] == 0
381
441
  invoice
382
442
  end
383
443
 
@@ -396,6 +456,11 @@ module StripeMock
396
456
  start: 1349738920,
397
457
  end: 1349738920
398
458
  },
459
+ tax_amounts: [
460
+ {
461
+ amount: 10
462
+ }
463
+ ],
399
464
  quantity: nil,
400
465
  subscription: nil,
401
466
  plan: nil,
@@ -409,7 +474,7 @@ module StripeMock
409
474
  {
410
475
  id: "test_ii",
411
476
  object: "invoiceitem",
412
- date: 1349738920,
477
+ created: 1349738920,
413
478
  amount: 1099,
414
479
  livemode: false,
415
480
  proration: false,
@@ -495,18 +560,77 @@ module StripeMock
495
560
  def self.mock_plan(params={})
496
561
  currency = params[:currency] || StripeMock.default_currency
497
562
  {
498
- id: "2",
563
+ id: "mock_plan_123",
499
564
  object: "plan",
565
+ active: true,
566
+ aggregate_usage: nil,
500
567
  amount: 2300,
568
+ billing_scheme: "per_unit",
501
569
  created: 1466698898,
502
570
  currency: currency,
503
571
  interval: "month",
504
572
  interval_count: 1,
505
573
  livemode: false,
506
574
  metadata: {},
507
- name: "The Basic Plan",
575
+ nickname: "My Mock Plan",
576
+ product: "mock_prod_NONEXIST", # override this with your own existing product id
577
+ tiers: nil,
578
+ tiers_mode: nil,
579
+ transform_usage: nil,
580
+ trial_period_days: nil,
581
+ usage_type: "licensed"
582
+ }.merge(params)
583
+ end
584
+
585
+ def self.mock_price(params={})
586
+ currency = params[:currency] || StripeMock.default_currency
587
+ {
588
+ id: "mock_price_123",
589
+ object: "price",
590
+ active: true,
591
+ billing_scheme: "per_unit",
592
+ created: 1593044959,
593
+ currency: currency,
594
+ livemode: false,
595
+ lookup_key: nil,
596
+ metadata: {},
597
+ nickname: 'My Mock Price',
598
+ product: "mock_prod_NONEXIST", # override this with your own existing product id
599
+ recurring: {
600
+ aggregate_usage: nil,
601
+ interval: "month",
602
+ interval_count: 1,
603
+ usage_type: "licensed"
604
+ },
605
+ tiers_mode: nil,
606
+ transform_quantity: nil,
607
+ type: "recurring",
608
+ unit_amount: 2000,
609
+ unit_amount_decimal: "2000"
610
+ }.merge(params)
611
+ end
612
+
613
+ def self.mock_product(params={})
614
+ {
615
+ id: "mock_prod_abc123",
616
+ object: "product",
617
+ active: true,
618
+ attributes:[],
619
+ caption: nil,
620
+ created: 1466698000,
621
+ deactivate_on: [],
622
+ description: nil,
623
+ images: [],
624
+ livemode: false,
625
+ metadata: {},
626
+ name: "The Mock Product",
627
+ package_dimensions: nil,
628
+ shippable: nil,
508
629
  statement_descriptor: nil,
509
- trial_period_days: nil
630
+ type: "service",
631
+ unit_label: "my_unit",
632
+ updated: 1537939442,
633
+ url: nil
510
634
  }.merge(params)
511
635
  end
512
636
 
@@ -533,6 +657,7 @@ module StripeMock
533
657
  object: "list",
534
658
  url: "/v1/recipients/#{rp_id}/cards",
535
659
  data: cards,
660
+ has_more: false,
536
661
  total_count: cards.count
537
662
  },
538
663
  default_card: nil
@@ -940,6 +1065,16 @@ module StripeMock
940
1065
  bitcoin_receiver: 1545182
941
1066
  }
942
1067
  }],
1068
+ instant_available: [
1069
+ {
1070
+ currency: "usd",
1071
+ amount: usd_balance,
1072
+ source_types: {
1073
+ card: 25907032203,
1074
+ bank_account: 108476658,
1075
+ bitcoin_receiver: 1545182
1076
+ }
1077
+ }],
943
1078
  connect_reserved: [
944
1079
  {
945
1080
  currency: "usd",
@@ -1004,9 +1139,9 @@ module StripeMock
1004
1139
  end
1005
1140
 
1006
1141
  def self.mock_subscription_item(params = {})
1007
- iid = params[:id] || 'test_txn_default'
1142
+ id = params[:id] || 'test_si_default'
1008
1143
  {
1009
- id: iid,
1144
+ id: id,
1010
1145
  object: 'subscription_item',
1011
1146
  created: 1504716183,
1012
1147
  metadata: {
@@ -1047,5 +1182,180 @@ module StripeMock
1047
1182
  secret: "ek_test_default"
1048
1183
  }
1049
1184
  end
1185
+
1186
+ def self.mock_payment_intent(params = {})
1187
+ payment_intent_id = params[:id] || "pi_1EwXFB2eZvKYlo2CggNnFBo8"
1188
+ amount = params[:amount] || 49900
1189
+ currency = params[:currency] || StripeMock.default_currency
1190
+ {
1191
+ id: payment_intent_id,
1192
+ object: "payment_intent",
1193
+ amount: amount,
1194
+ amount_capturable: 0,
1195
+ amount_received: 0,
1196
+ application: nil,
1197
+ application_fee_amount: nil,
1198
+ canceled_at: nil,
1199
+ cancellation_reason: nil,
1200
+ capture_method: "automatic",
1201
+ charges: {
1202
+ object: "list",
1203
+ data: [],
1204
+ has_more: false,
1205
+ total_count: 1,
1206
+ url: "/v1/charges?payment_intent=pi_1EwXFB2eZvKYlo2CggNnFBo8"
1207
+ },
1208
+ client_secret: "pi_1EwXFB2eZvKYlo2CggNnFBo8_secret_vOMkpqZu8ca7hxhfiO80tpT3v",
1209
+ confirmation_method: "manual",
1210
+ created: 1563208901,
1211
+ currency: currency,
1212
+ customer: nil,
1213
+ description: nil,
1214
+ invoice: nil,
1215
+ last_payment_error: nil,
1216
+ livemode: false,
1217
+ metadata: {},
1218
+ next_action: { type: "use_stripe_sdk" },
1219
+ on_behalf_of: nil,
1220
+ payment_method: nil,
1221
+ payment_method_types: [
1222
+ "card"
1223
+ ],
1224
+ receipt_email: nil,
1225
+ review: nil,
1226
+ setup_future_usage: nil,
1227
+ shipping: nil,
1228
+ source: nil,
1229
+ statement_descriptor: nil,
1230
+ status: "requires_action",
1231
+ transfer_data: nil,
1232
+ transfer_group: nil
1233
+ }.merge(params)
1234
+ end
1235
+
1236
+ def self.mock_payment_method(params = {})
1237
+ payment_method_id = params[:id] || 'pm_1ExEuFL2DI6wht39WNJgbybl'
1238
+
1239
+ type = params[:type].to_sym
1240
+ data = {
1241
+ card: {
1242
+ brand: 'visa',
1243
+ checks: {
1244
+ address_line1_check: nil,
1245
+ address_postal_code_check: nil,
1246
+ cvc_check: 'pass'
1247
+ },
1248
+ country: 'FR',
1249
+ exp_month: 2,
1250
+ exp_year: 2022,
1251
+ fingerprint: 'Hr3Ly5z5IYxsokWA',
1252
+ funding: 'credit',
1253
+ generated_from: nil,
1254
+ last4: '3155',
1255
+ three_d_secure_usage: { supported: true },
1256
+ wallet: nil
1257
+ },
1258
+ ideal: {
1259
+ bank: 'ing',
1260
+ bic: 'INGBNL2A',
1261
+ iban_last4: '****',
1262
+ verified_name: 'JENNY ROSEN'
1263
+ },
1264
+ sepa_debit: {
1265
+ bank_code: '37040044',
1266
+ branch_code: '',
1267
+ country: 'DE',
1268
+ fingerprint: 'FD81kbVPe7M05BMj',
1269
+ last4: '3000'
1270
+ }
1271
+ }
1272
+
1273
+ {
1274
+ id: payment_method_id,
1275
+ object: 'payment_method',
1276
+ type: params[:type],
1277
+ billing_details: {
1278
+ address: {
1279
+ city: 'New Orleans',
1280
+ country: 'US',
1281
+ line1: 'Bourbon Street 23',
1282
+ line2: nil,
1283
+ postal_code: '10000',
1284
+ state: nil
1285
+ },
1286
+ email: 'foo@bar.com',
1287
+ name: 'John Dolton',
1288
+ phone: nil
1289
+ },
1290
+ customer: params[:customer] || nil,
1291
+ metadata: {
1292
+ order_id: '123456789'
1293
+ }
1294
+ }.merge(type => data[type]).merge(params)
1295
+ end
1296
+
1297
+ def self.mock_setup_intent(params = {})
1298
+ setup_intent_id = params[:id] || "seti_1F96eK2aLAadsDqo0AVIyPmC"
1299
+ {
1300
+ :id => setup_intent_id,
1301
+ :object => "setup_intent",
1302
+ :application => nil,
1303
+ :cancellation_reason => nil,
1304
+ :client_secret => "seti_1F96eK2aLAadsDqo0AVIyPmC_secret_FePTYgOoPFxDOUL53fFMSoTAyiXsWAV",
1305
+ :created => 1566204936,
1306
+ :customer => nil,
1307
+ :description => nil,
1308
+ :last_setup_error => nil,
1309
+ :livemode => false,
1310
+ :metadata => {},
1311
+ :next_action => nil,
1312
+ :on_behalf_of => nil,
1313
+ :payment_method => nil,
1314
+ :payment_method_options => {
1315
+ card: {request_three_d_secure: "automatic"}
1316
+ },
1317
+ :payment_method_types => ["card"],
1318
+ :status => "requires_payment_method",
1319
+ :usage => "off_session"
1320
+ }.merge(params)
1321
+ end
1322
+
1323
+ def self.mock_checkout_session(params = {})
1324
+ cs_id = params[:id] || "test_cs_default"
1325
+ currency = params[:currency] || StripeMock.default_currency
1326
+ {
1327
+ id: cs_id,
1328
+ object: 'checkout.session',
1329
+ billing_address_collection: nil,
1330
+ cancel_url: 'https://example.com/cancel',
1331
+ client_reference_id: nil,
1332
+ customer: nil,
1333
+ customer_email: nil,
1334
+ display_items: [
1335
+ {
1336
+ amount: 1500,
1337
+ currency: currency,
1338
+ custom: {
1339
+ description: 'Comfortable cotton t-shirt',
1340
+ images: nil,
1341
+ name: 'T-shirt'
1342
+ },
1343
+ quantity: 2,
1344
+ type: 'custom'
1345
+ }
1346
+ ],
1347
+ livemode: false,
1348
+ locale: nil,
1349
+ mode: nil,
1350
+ payment_intent: mock_payment_intent[:id],
1351
+ payment_method_types: [
1352
+ 'card'
1353
+ ],
1354
+ setup_intent: nil,
1355
+ submit_type: nil,
1356
+ subscription: nil,
1357
+ success_url: 'https://example.com/success'
1358
+ }.merge(params)
1359
+ end
1050
1360
  end
1051
1361
  end