epopia-stripe-ruby-mock 2.5.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. checksums.yaml +7 -0
  2. data/.env +2 -0
  3. data/.gitignore +8 -0
  4. data/.rspec +1 -0
  5. data/.travis.yml +28 -0
  6. data/Gemfile +12 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +413 -0
  9. data/Rakefile +14 -0
  10. data/bin/stripe-mock-server +19 -0
  11. data/lib/stripe_mock.rb +95 -0
  12. data/lib/stripe_mock/api/account_balance.rb +14 -0
  13. data/lib/stripe_mock/api/bank_tokens.rb +13 -0
  14. data/lib/stripe_mock/api/card_tokens.rb +13 -0
  15. data/lib/stripe_mock/api/client.rb +41 -0
  16. data/lib/stripe_mock/api/conversion_rate.rb +14 -0
  17. data/lib/stripe_mock/api/debug.rb +11 -0
  18. data/lib/stripe_mock/api/errors.rb +65 -0
  19. data/lib/stripe_mock/api/global_id_prefix.rb +22 -0
  20. data/lib/stripe_mock/api/instance.rb +38 -0
  21. data/lib/stripe_mock/api/live.rb +15 -0
  22. data/lib/stripe_mock/api/server.rb +39 -0
  23. data/lib/stripe_mock/api/test_helpers.rb +24 -0
  24. data/lib/stripe_mock/api/webhooks.rb +88 -0
  25. data/lib/stripe_mock/client.rb +127 -0
  26. data/lib/stripe_mock/data.rb +1193 -0
  27. data/lib/stripe_mock/data/list.rb +73 -0
  28. data/lib/stripe_mock/error_queue.rb +27 -0
  29. data/lib/stripe_mock/errors/closed_client_connection_error.rb +9 -0
  30. data/lib/stripe_mock/errors/server_timeout_error.rb +12 -0
  31. data/lib/stripe_mock/errors/stripe_mock_error.rb +15 -0
  32. data/lib/stripe_mock/errors/uninitialized_instance_error.rb +9 -0
  33. data/lib/stripe_mock/errors/unstarted_state_error.rb +9 -0
  34. data/lib/stripe_mock/errors/unsupported_request_error.rb +4 -0
  35. data/lib/stripe_mock/instance.rb +237 -0
  36. data/lib/stripe_mock/request_handlers/accounts.rb +86 -0
  37. data/lib/stripe_mock/request_handlers/balance.rb +17 -0
  38. data/lib/stripe_mock/request_handlers/balance_transactions.rb +37 -0
  39. data/lib/stripe_mock/request_handlers/cards.rb +35 -0
  40. data/lib/stripe_mock/request_handlers/charges.rb +177 -0
  41. data/lib/stripe_mock/request_handlers/country_spec.rb +22 -0
  42. data/lib/stripe_mock/request_handlers/coupons.rb +35 -0
  43. data/lib/stripe_mock/request_handlers/customers.rb +137 -0
  44. data/lib/stripe_mock/request_handlers/disputes.rb +35 -0
  45. data/lib/stripe_mock/request_handlers/ephemeral_key.rb +13 -0
  46. data/lib/stripe_mock/request_handlers/events.rb +21 -0
  47. data/lib/stripe_mock/request_handlers/external_accounts.rb +55 -0
  48. data/lib/stripe_mock/request_handlers/helpers/bank_account_helpers.rb +14 -0
  49. data/lib/stripe_mock/request_handlers/helpers/card_helpers.rb +127 -0
  50. data/lib/stripe_mock/request_handlers/helpers/charge_helpers.rb +16 -0
  51. data/lib/stripe_mock/request_handlers/helpers/coupon_helpers.rb +17 -0
  52. data/lib/stripe_mock/request_handlers/helpers/external_account_helpers.rb +49 -0
  53. data/lib/stripe_mock/request_handlers/helpers/subscription_helpers.rb +119 -0
  54. data/lib/stripe_mock/request_handlers/helpers/token_helpers.rb +44 -0
  55. data/lib/stripe_mock/request_handlers/invoice_items.rb +45 -0
  56. data/lib/stripe_mock/request_handlers/invoices.rb +177 -0
  57. data/lib/stripe_mock/request_handlers/orders.rb +80 -0
  58. data/lib/stripe_mock/request_handlers/payment_intents.rb +203 -0
  59. data/lib/stripe_mock/request_handlers/payment_methods.rb +112 -0
  60. data/lib/stripe_mock/request_handlers/payouts.rb +32 -0
  61. data/lib/stripe_mock/request_handlers/plans.rb +42 -0
  62. data/lib/stripe_mock/request_handlers/products.rb +43 -0
  63. data/lib/stripe_mock/request_handlers/recipients.rb +60 -0
  64. data/lib/stripe_mock/request_handlers/refunds.rb +91 -0
  65. data/lib/stripe_mock/request_handlers/sources.rb +55 -0
  66. data/lib/stripe_mock/request_handlers/subscription_items.rb +36 -0
  67. data/lib/stripe_mock/request_handlers/subscriptions.rb +296 -0
  68. data/lib/stripe_mock/request_handlers/tax_rates.rb +36 -0
  69. data/lib/stripe_mock/request_handlers/tokens.rb +75 -0
  70. data/lib/stripe_mock/request_handlers/transfers.rb +65 -0
  71. data/lib/stripe_mock/request_handlers/validators/param_validators.rb +32 -0
  72. data/lib/stripe_mock/server.rb +93 -0
  73. data/lib/stripe_mock/test_strategies/base.rb +81 -0
  74. data/lib/stripe_mock/test_strategies/live.rb +40 -0
  75. data/lib/stripe_mock/test_strategies/mock.rb +27 -0
  76. data/lib/stripe_mock/util.rb +44 -0
  77. data/lib/stripe_mock/version.rb +4 -0
  78. data/lib/stripe_mock/webhook_fixtures/account.application.deauthorized.json +12 -0
  79. data/lib/stripe_mock/webhook_fixtures/account.external_account.created.json +27 -0
  80. data/lib/stripe_mock/webhook_fixtures/account.external_account.deleted.json +27 -0
  81. data/lib/stripe_mock/webhook_fixtures/account.external_account.updated.json +27 -0
  82. data/lib/stripe_mock/webhook_fixtures/account.updated.json +26 -0
  83. data/lib/stripe_mock/webhook_fixtures/balance.available.json +25 -0
  84. data/lib/stripe_mock/webhook_fixtures/charge.dispute.closed.json +22 -0
  85. data/lib/stripe_mock/webhook_fixtures/charge.dispute.created.json +22 -0
  86. data/lib/stripe_mock/webhook_fixtures/charge.dispute.funds_reinstated.json +88 -0
  87. data/lib/stripe_mock/webhook_fixtures/charge.dispute.funds_withdrawn.json +88 -0
  88. data/lib/stripe_mock/webhook_fixtures/charge.dispute.updated.json +25 -0
  89. data/lib/stripe_mock/webhook_fixtures/charge.failed.json +56 -0
  90. data/lib/stripe_mock/webhook_fixtures/charge.refunded.json +69 -0
  91. data/lib/stripe_mock/webhook_fixtures/charge.succeeded.json +55 -0
  92. data/lib/stripe_mock/webhook_fixtures/charge.updated.json +58 -0
  93. data/lib/stripe_mock/webhook_fixtures/coupon.created.json +23 -0
  94. data/lib/stripe_mock/webhook_fixtures/coupon.deleted.json +23 -0
  95. data/lib/stripe_mock/webhook_fixtures/customer.created.json +54 -0
  96. data/lib/stripe_mock/webhook_fixtures/customer.deleted.json +42 -0
  97. data/lib/stripe_mock/webhook_fixtures/customer.discount.created.json +28 -0
  98. data/lib/stripe_mock/webhook_fixtures/customer.discount.deleted.json +28 -0
  99. data/lib/stripe_mock/webhook_fixtures/customer.discount.updated.json +43 -0
  100. data/lib/stripe_mock/webhook_fixtures/customer.source.created.json +32 -0
  101. data/lib/stripe_mock/webhook_fixtures/customer.source.deleted.json +32 -0
  102. data/lib/stripe_mock/webhook_fixtures/customer.source.updated.json +36 -0
  103. data/lib/stripe_mock/webhook_fixtures/customer.subscription.created.json +66 -0
  104. data/lib/stripe_mock/webhook_fixtures/customer.subscription.deleted.json +65 -0
  105. data/lib/stripe_mock/webhook_fixtures/customer.subscription.trial_will_end.json +65 -0
  106. data/lib/stripe_mock/webhook_fixtures/customer.subscription.updated.json +78 -0
  107. data/lib/stripe_mock/webhook_fixtures/customer.updated.json +57 -0
  108. data/lib/stripe_mock/webhook_fixtures/invoice.created.json +71 -0
  109. data/lib/stripe_mock/webhook_fixtures/invoice.payment_failed.json +105 -0
  110. data/lib/stripe_mock/webhook_fixtures/invoice.payment_succeeded.json +112 -0
  111. data/lib/stripe_mock/webhook_fixtures/invoice.updated.json +74 -0
  112. data/lib/stripe_mock/webhook_fixtures/invoiceitem.created.json +21 -0
  113. data/lib/stripe_mock/webhook_fixtures/invoiceitem.deleted.json +21 -0
  114. data/lib/stripe_mock/webhook_fixtures/invoiceitem.updated.json +24 -0
  115. data/lib/stripe_mock/webhook_fixtures/plan.created.json +20 -0
  116. data/lib/stripe_mock/webhook_fixtures/plan.deleted.json +20 -0
  117. data/lib/stripe_mock/webhook_fixtures/plan.updated.json +23 -0
  118. data/lib/stripe_mock/webhook_fixtures/transfer.created.json +89 -0
  119. data/lib/stripe_mock/webhook_fixtures/transfer.failed.json +89 -0
  120. data/lib/stripe_mock/webhook_fixtures/transfer.paid.json +89 -0
  121. data/lib/stripe_mock/webhook_fixtures/transfer.updated.json +92 -0
  122. data/lib/trollop.rb +782 -0
  123. data/spec/_dummy/webhooks/dummy.event.json +6 -0
  124. data/spec/api/instance_spec.rb +30 -0
  125. data/spec/fixtures/create_refund.yml +126 -0
  126. data/spec/fixtures/stripe_webhooks/account.updated.json +7 -0
  127. data/spec/fixtures/stripe_webhooks/custom.account.updated.json +5 -0
  128. data/spec/instance_spec.rb +100 -0
  129. data/spec/integration_examples/charge_token_examples.rb +51 -0
  130. data/spec/integration_examples/customer_card_examples.rb +42 -0
  131. data/spec/integration_examples/prepare_error_examples.rb +38 -0
  132. data/spec/list_spec.rb +140 -0
  133. data/spec/readme_spec.rb +75 -0
  134. data/spec/server_spec.rb +139 -0
  135. data/spec/shared_stripe_examples/account_examples.rb +96 -0
  136. data/spec/shared_stripe_examples/balance_examples.rb +11 -0
  137. data/spec/shared_stripe_examples/balance_transaction_examples.rb +63 -0
  138. data/spec/shared_stripe_examples/bank_examples.rb +229 -0
  139. data/spec/shared_stripe_examples/bank_token_examples.rb +59 -0
  140. data/spec/shared_stripe_examples/card_examples.rb +307 -0
  141. data/spec/shared_stripe_examples/card_token_examples.rb +185 -0
  142. data/spec/shared_stripe_examples/charge_examples.rb +510 -0
  143. data/spec/shared_stripe_examples/country_specs_examples.rb +18 -0
  144. data/spec/shared_stripe_examples/coupon_examples.rb +85 -0
  145. data/spec/shared_stripe_examples/customer_examples.rb +453 -0
  146. data/spec/shared_stripe_examples/dispute_examples.rb +98 -0
  147. data/spec/shared_stripe_examples/ephemeral_key_examples.rb +17 -0
  148. data/spec/shared_stripe_examples/error_mock_examples.rb +162 -0
  149. data/spec/shared_stripe_examples/external_account_examples.rb +170 -0
  150. data/spec/shared_stripe_examples/extra_features_examples.rb +36 -0
  151. data/spec/shared_stripe_examples/invoice_examples.rb +524 -0
  152. data/spec/shared_stripe_examples/invoice_item_examples.rb +69 -0
  153. data/spec/shared_stripe_examples/payment_intent_examples.rb +131 -0
  154. data/spec/shared_stripe_examples/payment_method_examples.rb +175 -0
  155. data/spec/shared_stripe_examples/payout_examples.rb +68 -0
  156. data/spec/shared_stripe_examples/plan_examples.rb +194 -0
  157. data/spec/shared_stripe_examples/product_example.rb +65 -0
  158. data/spec/shared_stripe_examples/recipient_examples.rb +118 -0
  159. data/spec/shared_stripe_examples/refund_examples.rb +472 -0
  160. data/spec/shared_stripe_examples/subscription_examples.rb +1148 -0
  161. data/spec/shared_stripe_examples/subscription_items_examples.rb +75 -0
  162. data/spec/shared_stripe_examples/tax_rate_examples.rb +42 -0
  163. data/spec/shared_stripe_examples/transfer_examples.rb +130 -0
  164. data/spec/shared_stripe_examples/validation_examples.rb +19 -0
  165. data/spec/shared_stripe_examples/webhook_event_examples.rb +261 -0
  166. data/spec/spec_helper.rb +58 -0
  167. data/spec/stripe_mock_spec.rb +123 -0
  168. data/spec/support/stripe_examples.rb +42 -0
  169. data/spec/util_spec.rb +121 -0
  170. data/stripe-ruby-mock.gemspec +27 -0
  171. metadata +344 -0
@@ -0,0 +1,17 @@
1
+ module StripeMock
2
+ module RequestHandlers
3
+ module Balance
4
+
5
+ def Balance.included(klass)
6
+ klass.add_handler 'get /v1/balance', :get_balance
7
+ end
8
+
9
+ def get_balance(route, method_url, params, headers)
10
+ route =~ method_url
11
+
12
+ return_balance = Data.mock_balance(account_balance)
13
+ return_balance
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,37 @@
1
+ module StripeMock
2
+ module RequestHandlers
3
+ module BalanceTransactions
4
+
5
+ def BalanceTransactions.included(klass)
6
+ klass.add_handler 'get /v1/balance/history/(.*)', :get_balance_transaction
7
+ klass.add_handler 'get /v1/balance/history', :list_balance_transactions
8
+ end
9
+
10
+ def get_balance_transaction(route, method_url, params, headers)
11
+ route =~ method_url
12
+ assert_existence :balance_transaction, $1, hide_additional_attributes(balance_transactions[$1])
13
+ end
14
+
15
+ def list_balance_transactions(route, method_url, params, headers)
16
+ values = balance_transactions.values
17
+ if params.has_key?(:transfer)
18
+ # If transfer supplied as params, need to filter the btxns returned to only include those with the specified transfer id
19
+ values = values.select{|btxn| btxn[:transfer] == params[:transfer]}
20
+ end
21
+ Data.mock_list_object(values.map{|btxn| hide_additional_attributes(btxn)}, params)
22
+ end
23
+
24
+ private
25
+
26
+ def hide_additional_attributes(btxn)
27
+ # For automatic Stripe transfers, the transfer attribute on balance_transaction stores the transfer which
28
+ # included this balance_transaction. However, it is not exposed as a field returned on a balance_transaction.
29
+ # Therefore, need to not show this attribute if it exists.
30
+ if !btxn.nil?
31
+ btxn.reject{|k,v| k == :transfer }
32
+ end
33
+ end
34
+
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,35 @@
1
+ module StripeMock
2
+ module RequestHandlers
3
+ module Cards
4
+
5
+ def Cards.included(klass)
6
+ klass.add_handler 'get /v1/recipients/(.*)/cards', :retrieve_recipient_cards
7
+ klass.add_handler 'get /v1/recipients/(.*)/cards/(.*)', :retrieve_recipient_card
8
+ klass.add_handler 'post /v1/recipients/(.*)/cards', :create_recipient_card
9
+ klass.add_handler 'delete /v1/recipients/(.*)/cards/(.*)', :delete_recipient_card
10
+ end
11
+
12
+ def create_recipient_card(route, method_url, params, headers)
13
+ route =~ method_url
14
+ add_card_to(:recipient, $1, params, recipients)
15
+ end
16
+
17
+ def retrieve_recipient_cards(route, method_url, params, headers)
18
+ route =~ method_url
19
+ retrieve_object_cards(:recipient, $1, recipients)
20
+ end
21
+
22
+ def retrieve_recipient_card(route, method_url, params, headers)
23
+ route =~ method_url
24
+ recipient = assert_existence :recipient, $1, recipients[$1]
25
+
26
+ assert_existence :card, $2, get_card(recipient, $2, "Recipient")
27
+ end
28
+
29
+ def delete_recipient_card(route, method_url, params, headers)
30
+ route =~ method_url
31
+ delete_card_from(:recipient, $1, $2, recipients)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,177 @@
1
+ module StripeMock
2
+ module RequestHandlers
3
+ module Charges
4
+
5
+ def Charges.included(klass)
6
+ klass.add_handler 'post /v1/charges', :new_charge
7
+ klass.add_handler 'get /v1/charges', :get_charges
8
+ klass.add_handler 'get /v1/charges/(.*)', :get_charge
9
+ klass.add_handler 'post /v1/charges/(.*)/capture', :capture_charge
10
+ klass.add_handler 'post /v1/charges/(.*)/refund', :refund_charge
11
+ klass.add_handler 'post /v1/charges/(.*)/refunds', :refund_charge
12
+ klass.add_handler 'post /v1/charges/(.*)', :update_charge
13
+ end
14
+
15
+ def new_charge(route, method_url, params, headers)
16
+ if headers && headers[:idempotency_key]
17
+ params[:idempotency_key] = headers[:idempotency_key]
18
+ if charges.any?
19
+ original_charge = charges.values.find { |c| c[:idempotency_key] == headers[:idempotency_key]}
20
+ return charges[original_charge[:id]] if original_charge
21
+ end
22
+ end
23
+
24
+ id = new_id('ch')
25
+
26
+ if params[:source]
27
+ if params[:source].is_a?(String)
28
+ # if a customer is provided, the card parameter is assumed to be the actual
29
+ # card id, not a token. in this case we'll find the card in the customer
30
+ # object and return that.
31
+ if params[:customer]
32
+ params[:source] = get_card(customers[params[:customer]], params[:source])
33
+ else
34
+ params[:source] = get_card_or_bank_by_token(params[:source])
35
+ end
36
+ elsif params[:source][:id]
37
+ raise Stripe::InvalidRequestError.new("Invalid token id: #{params[:source]}", 'card', http_status: 400)
38
+ end
39
+ elsif params[:customer]
40
+ customer = customers[params[:customer]]
41
+ if customer && customer[:default_source]
42
+ params[:source] = get_card(customer, customer[:default_source])
43
+ end
44
+ end
45
+
46
+ ensure_required_params(params)
47
+ bal_trans_params = { amount: params[:amount], source: id, application_fee: params[:application_fee] }
48
+
49
+ balance_transaction_id = new_balance_transaction('txn', bal_trans_params)
50
+
51
+ charges[id] = Data.mock_charge(
52
+ params.merge :id => id,
53
+ :balance_transaction => balance_transaction_id)
54
+
55
+ charge = charges[id].clone
56
+ if params[:expand] == ['balance_transaction']
57
+ charge[:balance_transaction] =
58
+ balance_transactions[balance_transaction_id]
59
+ end
60
+
61
+ charge
62
+ end
63
+
64
+ def update_charge(route, method_url, params, headers)
65
+ route =~ method_url
66
+ id = $1
67
+
68
+ charge = assert_existence :charge, id, charges[id]
69
+ allowed = allowed_params(params)
70
+ disallowed = params.keys - allowed
71
+ if disallowed.count > 0
72
+ raise Stripe::InvalidRequestError.new("Received unknown parameters: #{disallowed.join(', ')}" , '', http_status: 400)
73
+ end
74
+
75
+ charges[id] = Util.rmerge(charge, params)
76
+ end
77
+
78
+ def get_charges(route, method_url, params, headers)
79
+ params[:offset] ||= 0
80
+ params[:limit] ||= 10
81
+
82
+ clone = charges.clone
83
+
84
+ if params[:customer]
85
+ clone.delete_if { |k,v| v[:customer] != params[:customer] }
86
+ end
87
+
88
+ Data.mock_list_object(clone.values, params)
89
+ end
90
+
91
+ def get_charge(route, method_url, params, headers)
92
+ route =~ method_url
93
+ charge_id = $1 || params[:charge]
94
+ charge = assert_existence :charge, charge_id, charges[charge_id]
95
+
96
+ charge = charge.clone
97
+ if params[:expand] == ['balance_transaction']
98
+ balance_transaction = balance_transactions[charge[:balance_transaction]]
99
+ charge[:balance_transaction] = balance_transaction
100
+ end
101
+
102
+ charge
103
+ end
104
+
105
+ def capture_charge(route, method_url, params, headers)
106
+ route =~ method_url
107
+ charge = assert_existence :charge, $1, charges[$1]
108
+
109
+ if params[:amount]
110
+ refund = Data.mock_refund(
111
+ :balance_transaction => new_balance_transaction('txn'),
112
+ :id => new_id('re'),
113
+ :amount => charge[:amount] - params[:amount]
114
+ )
115
+ add_refund_to_charge(refund, charge)
116
+ end
117
+
118
+ if params[:application_fee]
119
+ charge[:application_fee] = params[:application_fee]
120
+ end
121
+
122
+ charge[:captured] = true
123
+ charge
124
+ end
125
+
126
+ def refund_charge(route, method_url, params, headers)
127
+ charge = get_charge(route, method_url, params, headers)
128
+
129
+ new_refund(
130
+ route,
131
+ method_url,
132
+ params.merge(:charge => charge[:id]),
133
+ headers
134
+ )
135
+ end
136
+
137
+ private
138
+
139
+ def ensure_required_params(params)
140
+ if params[:amount].nil?
141
+ require_param(:amount)
142
+ elsif params[:currency].nil?
143
+ require_param(:currency)
144
+ elsif non_integer_charge_amount?(params)
145
+ raise Stripe::InvalidRequestError.new("Invalid integer: #{params[:amount]}", 'amount', http_status: 400)
146
+ elsif non_positive_charge_amount?(params)
147
+ raise Stripe::InvalidRequestError.new('Invalid positive integer', 'amount', http_status: 400)
148
+ elsif params[:source].nil? && params[:customer].nil?
149
+ raise Stripe::InvalidRequestError.new('Must provide source or customer.', http_status: nil)
150
+ end
151
+ end
152
+
153
+ def non_integer_charge_amount?(params)
154
+ params[:amount] && !params[:amount].is_a?(Integer)
155
+ end
156
+
157
+ def non_positive_charge_amount?(params)
158
+ params[:amount] && params[:amount] < 1
159
+ end
160
+
161
+ def allowed_params(params)
162
+ allowed = [:description, :metadata, :receipt_email, :fraud_details, :shipping, :destination]
163
+
164
+ # This is a workaround for the way the Stripe API sends params even when they aren't modified.
165
+ # Stipe will include those params even when they aren't modified.
166
+ allowed << :fee_details if params.has_key?(:fee_details) && params[:fee_details].nil?
167
+ allowed << :source if params.has_key?(:source) && params[:source].empty?
168
+ if params.has_key?(:refunds) && (params[:refunds].empty? ||
169
+ params[:refunds].has_key?(:data) && params[:refunds][:data].nil?)
170
+ allowed << :refunds
171
+ end
172
+
173
+ allowed
174
+ end
175
+ end
176
+ end
177
+ end
@@ -0,0 +1,22 @@
1
+ module StripeMock
2
+ module RequestHandlers
3
+ module CountrySpec
4
+
5
+ def CountrySpec.included(klass)
6
+ klass.add_handler 'get /v1/country_specs/(.*)', :retrieve_country_spec
7
+ end
8
+
9
+ def retrieve_country_spec(route, method_url, params, headers)
10
+ route =~ method_url
11
+
12
+ unless ["AT", "AU", "BE", "CA", "DE", "DK", "ES", "FI", "FR", "GB", "IE", "IT", "JP", "LU", "NL", "NO", "SE", "SG", "US"].include?($1)
13
+ raise Stripe::InvalidRequestError.new("#{$1} is not currently supported by Stripe.", $1.to_s)
14
+ end
15
+
16
+ country_spec[$1] ||= Data.mock_country_spec($1)
17
+
18
+ assert_existence :country_spec, $1, country_spec[$1]
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,35 @@
1
+ module StripeMock
2
+ module RequestHandlers
3
+ module Coupons
4
+
5
+ def Coupons.included(klass)
6
+ klass.add_handler 'post /v1/coupons', :new_coupon
7
+ klass.add_handler 'get /v1/coupons/(.*)', :get_coupon
8
+ klass.add_handler 'delete /v1/coupons/(.*)', :delete_coupon
9
+ klass.add_handler 'get /v1/coupons', :list_coupons
10
+ end
11
+
12
+ def new_coupon(route, method_url, params, headers)
13
+ params[:id] ||= new_id('coupon')
14
+ raise Stripe::InvalidRequestError.new('Missing required param: duration', 'coupon', http_status: 400) unless params[:duration]
15
+ raise Stripe::InvalidRequestError.new('You must pass currency when passing amount_off', 'coupon', http_status: 400) if params[:amount_off] && !params[:currency]
16
+ coupons[ params[:id] ] = Data.mock_coupon({amount_off: nil, percent_off:nil}.merge(params))
17
+ end
18
+
19
+ def get_coupon(route, method_url, params, headers)
20
+ route =~ method_url
21
+ assert_existence :coupon, $1, coupons[$1]
22
+ end
23
+
24
+ def delete_coupon(route, method_url, params, headers)
25
+ route =~ method_url
26
+ assert_existence :coupon, $1, coupons.delete($1)
27
+ end
28
+
29
+ def list_coupons(route, method_url, params, headers)
30
+ Data.mock_list_object(coupons.values, params)
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,137 @@
1
+ module StripeMock
2
+ module RequestHandlers
3
+ module Customers
4
+
5
+ def Customers.included(klass)
6
+ klass.add_handler 'post /v1/customers', :new_customer
7
+ klass.add_handler 'post /v1/customers/([^/]*)', :update_customer
8
+ klass.add_handler 'get /v1/customers/([^/]*)', :get_customer
9
+ klass.add_handler 'delete /v1/customers/([^/]*)', :delete_customer
10
+ klass.add_handler 'get /v1/customers', :list_customers
11
+ klass.add_handler 'delete /v1/customers/([^/]*)/discount', :delete_customer_discount
12
+ end
13
+
14
+ def new_customer(route, method_url, params, headers)
15
+ params[:id] ||= new_id('cus')
16
+ sources = []
17
+
18
+ if params[:source]
19
+ new_card =
20
+ if params[:source].is_a?(Hash)
21
+ unless params[:source][:object] && params[:source][:number] && params[:source][:exp_month] && params[:source][:exp_year]
22
+ raise Stripe::InvalidRequestError.new('You must supply a valid card', nil, http_status: 400)
23
+ end
24
+ card_from_params(params[:source])
25
+ else
26
+ get_card_or_bank_by_token(params.delete(:source))
27
+ end
28
+ sources << new_card
29
+ params[:default_source] = sources.first[:id]
30
+ end
31
+
32
+ customers[ params[:id] ] = Data.mock_customer(sources, params)
33
+
34
+ if params[:plan]
35
+ plan_id = params[:plan].to_s
36
+ plan = assert_existence :plan, plan_id, plans[plan_id]
37
+
38
+ if params[:default_source].nil? && params[:trial_end].nil? && plan[:trial_period_days].nil? && plan[:amount] != 0
39
+ raise Stripe::InvalidRequestError.new('You must supply a valid card', nil, http_status: 400)
40
+ end
41
+
42
+ subscription = Data.mock_subscription({ id: new_id('su') })
43
+ subscription = resolve_subscription_changes(subscription, [plan], customers[ params[:id] ], params)
44
+ add_subscription_to_customer(customers[ params[:id] ], subscription)
45
+ subscriptions[subscription[:id]] = subscription
46
+ elsif params[:trial_end]
47
+ raise Stripe::InvalidRequestError.new('Received unknown parameter: trial_end', nil, http_status: 400)
48
+ end
49
+
50
+ if params[:coupon]
51
+ coupon = coupons[ params[:coupon] ]
52
+ assert_existence :coupon, params[:coupon], coupon
53
+
54
+ add_coupon_to_object(customers[params[:id]], coupon)
55
+ end
56
+
57
+ customers[ params[:id] ]
58
+ end
59
+
60
+ def update_customer(route, method_url, params, headers)
61
+ route =~ method_url
62
+ cus = assert_existence :customer, $1, customers[$1]
63
+
64
+ # Delete those params if their value is nil. Workaround of the problematic way Stripe serialize objects
65
+ params.delete(:sources) if params[:sources] && params[:sources][:data].nil?
66
+ params.delete(:subscriptions) if params[:subscriptions] && params[:subscriptions][:data].nil?
67
+ # Delete those params if their values aren't valid. Workaround of the problematic way Stripe serialize objects
68
+ if params[:sources] && !params[:sources][:data].nil?
69
+ params.delete(:sources) unless params[:sources][:data].any?{ |v| !!v[:type]}
70
+ end
71
+ if params[:subscriptions] && !params[:subscriptions][:data].nil?
72
+ params.delete(:subscriptions) unless params[:subscriptions][:data].any?{ |v| !!v[:type]}
73
+ end
74
+ cus.merge!(params)
75
+
76
+ if params[:source]
77
+ if params[:source].is_a?(String)
78
+ new_card = get_card_or_bank_by_token(params.delete(:source))
79
+ elsif params[:source].is_a?(Hash)
80
+ unless params[:source][:object] && params[:source][:number] && params[:source][:exp_month] && params[:source][:exp_year]
81
+ raise Stripe::InvalidRequestError.new('You must supply a valid card', nil, http_status: 400)
82
+ end
83
+ new_card = card_from_params(params.delete(:source))
84
+ end
85
+ add_card_to_object(:customer, new_card, cus, true)
86
+ cus[:default_source] = new_card[:id]
87
+ end
88
+
89
+ if params[:coupon]
90
+ coupon = coupons[ params[:coupon] ]
91
+ assert_existence :coupon, params[:coupon], coupon
92
+
93
+ add_coupon_to_object(cus, coupon)
94
+ end
95
+
96
+ cus
97
+ end
98
+
99
+ def delete_customer(route, method_url, params, headers)
100
+ route =~ method_url
101
+ assert_existence :customer, $1, customers[$1]
102
+
103
+ customers[$1] = {
104
+ id: customers[$1][:id],
105
+ deleted: true
106
+ }
107
+ end
108
+
109
+ def get_customer(route, method_url, params, headers)
110
+ route =~ method_url
111
+ customer = assert_existence :customer, $1, customers[$1]
112
+
113
+ customer = customer.clone
114
+ if params[:expand] == ['default_source']
115
+ customer[:default_source] = customer[:sources][:data].detect do |source|
116
+ source[:id] == customer[:default_source]
117
+ end
118
+ end
119
+
120
+ customer
121
+ end
122
+
123
+ def list_customers(route, method_url, params, headers)
124
+ Data.mock_list_object(customers.values, params)
125
+ end
126
+
127
+ def delete_customer_discount(route, method_url, params, headers)
128
+ route =~ method_url
129
+ cus = assert_existence :customer, $1, customers[$1]
130
+
131
+ cus[:discount] = nil
132
+
133
+ cus
134
+ end
135
+ end
136
+ end
137
+ end