stripe 3.2.0 → 5.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (230) hide show
  1. checksums.yaml +5 -5
  2. data/.editorconfig +10 -0
  3. data/.gitignore +3 -0
  4. data/.rubocop.yml +80 -0
  5. data/.rubocop_todo.yml +33 -0
  6. data/.travis.yml +9 -7
  7. data/.vscode/extensions.json +7 -0
  8. data/.vscode/settings.json +8 -0
  9. data/CHANGELOG.md +876 -0
  10. data/CODE_OF_CONDUCT.md +77 -0
  11. data/Gemfile +21 -21
  12. data/History.txt +1 -678
  13. data/README.md +195 -53
  14. data/Rakefile +18 -12
  15. data/VERSION +1 -1
  16. data/bin/stripe-console +5 -3
  17. data/lib/stripe/api_operations/create.rb +3 -1
  18. data/lib/stripe/api_operations/delete.rb +26 -2
  19. data/lib/stripe/api_operations/list.rb +3 -12
  20. data/lib/stripe/api_operations/nested_resource.rb +72 -0
  21. data/lib/stripe/api_operations/request.rb +33 -15
  22. data/lib/stripe/api_operations/save.rb +18 -9
  23. data/lib/stripe/api_resource.rb +60 -10
  24. data/lib/stripe/connection_manager.rb +159 -0
  25. data/lib/stripe/error_object.rb +94 -0
  26. data/lib/stripe/errors.rb +39 -19
  27. data/lib/stripe/instrumentation.rb +82 -0
  28. data/lib/stripe/list_object.rb +54 -22
  29. data/lib/stripe/multipart_encoder.rb +131 -0
  30. data/lib/stripe/oauth.rb +22 -14
  31. data/lib/stripe/object_types.rb +96 -0
  32. data/lib/stripe/{account.rb → resources/account.rb} +72 -34
  33. data/lib/stripe/resources/account_link.rb +9 -0
  34. data/lib/stripe/resources/alipay_account.rb +34 -0
  35. data/lib/stripe/{apple_pay_domain.rb → resources/apple_pay_domain.rb} +4 -2
  36. data/lib/stripe/resources/application_fee.rb +13 -0
  37. data/lib/stripe/resources/application_fee_refund.rb +30 -0
  38. data/lib/stripe/{balance.rb → resources/balance.rb} +3 -1
  39. data/lib/stripe/{balance_transaction.rb → resources/balance_transaction.rb} +3 -5
  40. data/lib/stripe/resources/bank_account.rb +42 -0
  41. data/lib/stripe/{bitcoin_receiver.rb → resources/bitcoin_receiver.rb} +6 -5
  42. data/lib/stripe/resources/bitcoin_transaction.rb +15 -0
  43. data/lib/stripe/resources/capability.rb +33 -0
  44. data/lib/stripe/resources/card.rb +37 -0
  45. data/lib/stripe/resources/charge.rb +22 -0
  46. data/lib/stripe/resources/checkout/session.rb +12 -0
  47. data/lib/stripe/{country_spec.rb → resources/country_spec.rb} +3 -5
  48. data/lib/stripe/{coupon.rb → resources/coupon.rb} +4 -2
  49. data/lib/stripe/resources/credit_note.rb +32 -0
  50. data/lib/stripe/resources/credit_note_line_item.rb +7 -0
  51. data/lib/stripe/resources/customer.rb +35 -0
  52. data/lib/stripe/resources/customer_balance_transaction.rb +30 -0
  53. data/lib/stripe/resources/discount.rb +7 -0
  54. data/lib/stripe/resources/dispute.rb +21 -0
  55. data/lib/stripe/resources/ephemeral_key.rb +19 -0
  56. data/lib/stripe/{event.rb → resources/event.rb} +3 -1
  57. data/lib/stripe/resources/exchange_rate.rb +9 -0
  58. data/lib/stripe/resources/file.rb +34 -0
  59. data/lib/stripe/resources/file_link.rb +11 -0
  60. data/lib/stripe/resources/invoice.rb +73 -0
  61. data/lib/stripe/{invoice_item.rb → resources/invoice_item.rb} +4 -2
  62. data/lib/stripe/{invoice_line_item.rb → resources/invoice_line_item.rb} +3 -1
  63. data/lib/stripe/resources/issuing/authorization.rb +33 -0
  64. data/lib/stripe/resources/issuing/card.rb +24 -0
  65. data/lib/stripe/resources/issuing/card_details.rb +9 -0
  66. data/lib/stripe/resources/issuing/cardholder.rb +13 -0
  67. data/lib/stripe/resources/issuing/dispute.rb +13 -0
  68. data/lib/stripe/resources/issuing/transaction.rb +12 -0
  69. data/lib/stripe/resources/login_link.rb +14 -0
  70. data/lib/stripe/resources/mandate.rb +7 -0
  71. data/lib/stripe/resources/order.rb +32 -0
  72. data/lib/stripe/{order_return.rb → resources/order_return.rb} +3 -5
  73. data/lib/stripe/resources/payment_intent.rb +42 -0
  74. data/lib/stripe/resources/payment_method.rb +32 -0
  75. data/lib/stripe/resources/payout.rb +22 -0
  76. data/lib/stripe/resources/person.rb +31 -0
  77. data/lib/stripe/{plan.rb → resources/plan.rb} +3 -1
  78. data/lib/stripe/{product.rb → resources/product.rb} +5 -3
  79. data/lib/stripe/resources/radar/early_fraud_warning.rb +11 -0
  80. data/lib/stripe/resources/radar/value_list.rb +14 -0
  81. data/lib/stripe/resources/radar/value_list_item.rb +13 -0
  82. data/lib/stripe/{recipient.rb → resources/recipient.rb} +5 -6
  83. data/lib/stripe/resources/recipient_transfer.rb +7 -0
  84. data/lib/stripe/{refund.rb → resources/refund.rb} +3 -1
  85. data/lib/stripe/resources/reporting/report_run.rb +12 -0
  86. data/lib/stripe/resources/reporting/report_type.rb +12 -0
  87. data/lib/stripe/resources/reversal.rb +29 -0
  88. data/lib/stripe/resources/review.rb +20 -0
  89. data/lib/stripe/resources/setup_intent.rb +32 -0
  90. data/lib/stripe/resources/sigma/scheduled_query_run.rb +15 -0
  91. data/lib/stripe/{sku.rb → resources/sku.rb} +5 -3
  92. data/lib/stripe/resources/source.rb +46 -0
  93. data/lib/stripe/resources/source_transaction.rb +7 -0
  94. data/lib/stripe/resources/subscription.rb +25 -0
  95. data/lib/stripe/resources/subscription_item.rb +25 -0
  96. data/lib/stripe/resources/subscription_schedule.rb +32 -0
  97. data/lib/stripe/resources/tax_id.rb +26 -0
  98. data/lib/stripe/resources/tax_rate.rb +11 -0
  99. data/lib/stripe/resources/terminal/connection_token.rb +11 -0
  100. data/lib/stripe/resources/terminal/location.rb +14 -0
  101. data/lib/stripe/resources/terminal/reader.rb +14 -0
  102. data/lib/stripe/{three_d_secure.rb → resources/three_d_secure.rb} +3 -1
  103. data/lib/stripe/{token.rb → resources/token.rb} +3 -1
  104. data/lib/stripe/resources/topup.rb +22 -0
  105. data/lib/stripe/resources/transfer.rb +26 -0
  106. data/lib/stripe/resources/usage_record.rb +7 -0
  107. data/lib/stripe/resources/usage_record_summary.rb +7 -0
  108. data/lib/stripe/resources/webhook_endpoint.rb +12 -0
  109. data/lib/stripe/resources.rb +79 -0
  110. data/lib/stripe/singleton_api_resource.rb +10 -4
  111. data/lib/stripe/stripe_client.rb +658 -337
  112. data/lib/stripe/stripe_object.rb +248 -126
  113. data/lib/stripe/stripe_response.rb +55 -21
  114. data/lib/stripe/util.rb +145 -187
  115. data/lib/stripe/version.rb +3 -1
  116. data/lib/stripe/webhook.rb +27 -16
  117. data/lib/stripe.rb +139 -90
  118. data/stripe.gemspec +26 -14
  119. data/test/openapi/README.md +9 -0
  120. data/test/stripe/account_link_test.rb +18 -0
  121. data/test/stripe/account_test.rb +311 -101
  122. data/test/stripe/alipay_account_test.rb +21 -1
  123. data/test/stripe/api_operations_test.rb +57 -8
  124. data/test/stripe/api_resource_test.rb +359 -271
  125. data/test/stripe/apple_pay_domain_test.rb +26 -11
  126. data/test/stripe/application_fee_refund_test.rb +10 -8
  127. data/test/stripe/application_fee_test.rb +49 -3
  128. data/test/stripe/balance_test.rb +4 -2
  129. data/test/stripe/balance_transaction_test.rb +20 -0
  130. data/test/stripe/bank_account_test.rb +11 -11
  131. data/test/stripe/capability_test.rb +45 -0
  132. data/test/stripe/charge_test.rb +25 -18
  133. data/test/stripe/checkout/session_test.rb +41 -0
  134. data/test/stripe/connection_manager_test.rb +163 -0
  135. data/test/stripe/country_spec_test.rb +6 -4
  136. data/test/stripe/coupon_test.rb +29 -10
  137. data/test/stripe/credit_note_test.rb +90 -0
  138. data/test/stripe/customer_balance_transaction_test.rb +37 -0
  139. data/test/stripe/customer_card_test.rb +13 -17
  140. data/test/stripe/customer_test.rb +161 -49
  141. data/test/stripe/dispute_test.rb +19 -8
  142. data/test/stripe/ephemeral_key_test.rb +23 -14
  143. data/test/stripe/errors_test.rb +32 -9
  144. data/test/stripe/exchange_rate_test.rb +20 -0
  145. data/test/stripe/file_link_test.rb +41 -0
  146. data/test/stripe/file_test.rb +87 -0
  147. data/test/stripe/instrumentation_test.rb +74 -0
  148. data/test/stripe/invoice_item_test.rb +31 -18
  149. data/test/stripe/invoice_line_item_test.rb +3 -1
  150. data/test/stripe/invoice_test.rb +158 -39
  151. data/test/stripe/issuing/authorization_test.rb +72 -0
  152. data/test/stripe/issuing/card_test.rb +62 -0
  153. data/test/stripe/issuing/cardholder_test.rb +53 -0
  154. data/test/stripe/issuing/dispute_test.rb +45 -0
  155. data/test/stripe/issuing/transaction_test.rb +48 -0
  156. data/test/stripe/list_object_test.rb +120 -88
  157. data/test/stripe/login_link_test.rb +16 -14
  158. data/test/stripe/mandate_test.rb +14 -0
  159. data/test/stripe/multipart_encoder_test.rb +130 -0
  160. data/test/stripe/oauth_test.rb +69 -50
  161. data/test/stripe/order_return_test.rb +7 -5
  162. data/test/stripe/order_test.rb +39 -14
  163. data/test/stripe/payment_intent_test.rb +107 -0
  164. data/test/stripe/payment_method_test.rb +84 -0
  165. data/test/stripe/payout_test.rb +18 -9
  166. data/test/stripe/person_test.rb +46 -0
  167. data/test/stripe/plan_test.rb +67 -19
  168. data/test/stripe/product_test.rb +28 -14
  169. data/test/stripe/radar/early_fraud_warning_test.rb +22 -0
  170. data/test/stripe/radar/value_list_item_test.rb +48 -0
  171. data/test/stripe/radar/value_list_test.rb +61 -0
  172. data/test/stripe/recipient_test.rb +27 -13
  173. data/test/stripe/refund_test.rb +11 -9
  174. data/test/stripe/reporting/report_run_test.rb +33 -0
  175. data/test/stripe/reporting/report_type_test.rb +22 -0
  176. data/test/stripe/reversal_test.rb +12 -10
  177. data/test/stripe/review_test.rb +27 -0
  178. data/test/stripe/setup_intent_test.rb +84 -0
  179. data/test/stripe/sigma/scheduled_query_run_test.rb +22 -0
  180. data/test/stripe/sku_test.rb +24 -12
  181. data/test/stripe/source_test.rb +70 -19
  182. data/test/stripe/stripe_client_test.rb +867 -326
  183. data/test/stripe/stripe_object_test.rb +284 -182
  184. data/test/stripe/stripe_response_test.rb +73 -24
  185. data/test/stripe/subscription_item_test.rb +47 -15
  186. data/test/stripe/subscription_schedule_test.rb +82 -0
  187. data/test/stripe/subscription_test.rb +41 -19
  188. data/test/stripe/tax_id_test.rb +31 -0
  189. data/test/stripe/tax_rate_test.rb +43 -0
  190. data/test/stripe/terminal/connection_token_test.rb +16 -0
  191. data/test/stripe/terminal/location_test.rb +68 -0
  192. data/test/stripe/terminal/reader_test.rb +62 -0
  193. data/test/stripe/three_d_secure_test.rb +4 -2
  194. data/test/stripe/topup_test.rb +62 -0
  195. data/test/stripe/transfer_test.rb +55 -8
  196. data/test/stripe/usage_record_summary_test.rb +29 -0
  197. data/test/stripe/util_test.rb +173 -84
  198. data/test/stripe/webhook_endpoint_test.rb +59 -0
  199. data/test/stripe/webhook_test.rb +21 -17
  200. data/test/stripe_mock.rb +78 -0
  201. data/test/stripe_test.rb +6 -15
  202. data/test/test_data.rb +28 -26
  203. data/test/test_helper.rb +48 -29
  204. metadata +183 -70
  205. data/lib/stripe/alipay_account.rb +0 -22
  206. data/lib/stripe/application_fee.rb +0 -22
  207. data/lib/stripe/application_fee_refund.rb +0 -20
  208. data/lib/stripe/bank_account.rb +0 -30
  209. data/lib/stripe/bitcoin_transaction.rb +0 -11
  210. data/lib/stripe/card.rb +0 -27
  211. data/lib/stripe/charge.rb +0 -82
  212. data/lib/stripe/customer.rb +0 -79
  213. data/lib/stripe/dispute.rb +0 -17
  214. data/lib/stripe/ephemeral_key.rb +0 -18
  215. data/lib/stripe/file_upload.rb +0 -33
  216. data/lib/stripe/invoice.rb +0 -29
  217. data/lib/stripe/login_link.rb +0 -9
  218. data/lib/stripe/order.rb +0 -29
  219. data/lib/stripe/payout.rb +0 -18
  220. data/lib/stripe/recipient_transfer.rb +0 -6
  221. data/lib/stripe/reversal.rb +0 -20
  222. data/lib/stripe/source.rb +0 -23
  223. data/lib/stripe/subscription.rb +0 -33
  224. data/lib/stripe/subscription_item.rb +0 -14
  225. data/lib/stripe/transfer.rb +0 -18
  226. data/test/api_stub_helpers.rb +0 -0
  227. data/test/stripe/bitcoin_receiver_test.rb +0 -67
  228. data/test/stripe/bitcoin_transaction_test.rb +0 -19
  229. data/test/stripe/file_upload_test.rb +0 -66
  230. data/test/stripe/recipient_card_test.rb +0 -44
@@ -1,12 +1,34 @@
1
- # -*- coding: utf-8 -*-
2
- require File.expand_path('../../test_helper', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ require ::File.expand_path("../test_helper", __dir__)
3
4
 
4
5
  module Stripe
5
6
  class ApiResourceTest < Test::Unit::TestCase
6
- class NestedTestAPIResource < Stripe::APIResource
7
+ class CustomMethodAPIResource < APIResource
8
+ OBJECT_NAME = "custom_method"
9
+ custom_method :my_method, http_verb: :post
10
+ end
11
+
12
+ class NestedTestAPIResource < APIResource
7
13
  save_nested_resource :external_account
8
14
  end
9
15
 
16
+ context ".custom_method" do
17
+ should "call to an RPC-style method" do
18
+ stub_request(:post, "#{Stripe.api_base}/v1/custom_methods/ch_123/my_method")
19
+ .to_return(body: JSON.generate({}))
20
+ CustomMethodAPIResource.my_method("ch_123")
21
+ end
22
+
23
+ should "raise an error if a non-ID is passed" do
24
+ e = assert_raises ArgumentError do
25
+ CustomMethodAPIResource.my_method(id: "ch_123")
26
+ end
27
+ assert_equal "id should be a string representing the ID of an API resource",
28
+ e.message
29
+ end
30
+ end
31
+
10
32
  context ".save_nested_resource" do
11
33
  should "can have a scalar set" do
12
34
  r = NestedTestAPIResource.new("test_resource")
@@ -17,7 +39,7 @@ module Stripe
17
39
  should "set a flag if given an object source" do
18
40
  r = NestedTestAPIResource.new("test_resource")
19
41
  r.external_account = {
20
- :object => 'card'
42
+ object: "card",
21
43
  }
22
44
  assert_equal true, r.external_account.save_with_parent
23
45
  end
@@ -29,17 +51,15 @@ module Stripe
29
51
  end
30
52
 
31
53
  should "creating a new APIResource from a hash should not fetch over the network" do
32
- Stripe::Customer.construct_from({
33
- :id => "somecustomer",
34
- :card => {:id => "somecard", :object => "card"},
35
- :object => "customer"
36
- })
54
+ Stripe::Customer.construct_from(id: "somecustomer",
55
+ card: { id: "somecard", object: "card" },
56
+ object: "customer")
37
57
  assert_not_requested :get, %r{#{Stripe.api_base}/.*}
38
58
  end
39
59
 
40
60
  should "setting an attribute should not cause a network request" do
41
- c = Stripe::Customer.new("cus_123");
42
- c.card = {:id => "somecard", :object => "card"}
61
+ c = Stripe::Customer.new("cus_123")
62
+ c.card = { id: "somecard", object: "card" }
43
63
  assert_not_requested :get, %r{#{Stripe.api_base}/.*}
44
64
  assert_not_requested :post, %r{#{Stripe.api_base}/.*}
45
65
  end
@@ -62,7 +82,7 @@ module Stripe
62
82
  Stripe::Customer.list({}, nil)
63
83
  end
64
84
  assert_raises TypeError do
65
- Stripe::Customer.list({}, { :api_key => nil })
85
+ Stripe::Customer.list({}, api_key: nil)
66
86
  end
67
87
  end
68
88
 
@@ -74,43 +94,43 @@ module Stripe
74
94
  end
75
95
 
76
96
  should "send expand on fetch properly" do
77
- stub_request(:get, "#{Stripe.api_base}/v1/charges/ch_123").
78
- with(query: { "expand" => ["customer"] }).
79
- to_return(body: JSON.generate(charge_fixture))
97
+ stub_request(:get, "#{Stripe.api_base}/v1/charges/ch_123")
98
+ .with(query: { "expand" => ["customer"] })
99
+ .to_return(body: JSON.generate(charge_fixture))
80
100
 
81
- Stripe::Charge.retrieve({:id => 'ch_123', :expand => [:customer]})
101
+ Stripe::Charge.retrieve(id: "ch_123", expand: [:customer])
82
102
  end
83
103
 
84
104
  should "preserve expand across refreshes" do
85
- stub_request(:get, "#{Stripe.api_base}/v1/charges/ch_123").
86
- with(query: { "expand" => ["customer"] }).
87
- to_return(body: JSON.generate(charge_fixture))
105
+ stub_request(:get, "#{Stripe.api_base}/v1/charges/ch_123")
106
+ .with(query: { "expand" => ["customer"] })
107
+ .to_return(body: JSON.generate(charge_fixture))
88
108
 
89
- ch = Stripe::Charge.retrieve({:id => 'ch_123', :expand => :customer})
109
+ ch = Stripe::Charge.retrieve(id: "ch_123", expand: [:customer])
90
110
  ch.refresh
91
111
  end
92
112
 
93
113
  should "send expand when fetching through ListObject" do
94
- stub_request(:get, "#{Stripe.api_base}/v1/customers/cus_123").
95
- to_return(body: JSON.generate(customer_fixture))
114
+ stub_request(:get, "#{Stripe.api_base}/v1/customers/cus_123")
115
+ .to_return(body: JSON.generate(customer_fixture))
96
116
 
97
- stub_request(:get, "#{Stripe.api_base}/v1/customers/cus_123/sources/cc_test_card").
98
- with(query: { "expand" => ["customer"] }).
99
- to_return(body: JSON.generate(customer_fixture))
117
+ stub_request(:get, "#{Stripe.api_base}/v1/customers/cus_123/sources/cc_test_card")
118
+ .with(query: { "expand" => ["customer"] })
119
+ .to_return(body: JSON.generate(customer_fixture))
100
120
 
101
- customer = Stripe::Customer.retrieve('cus_123')
102
- customer.sources.retrieve({:id => 'cc_test_card', :expand => :customer})
121
+ customer = Stripe::Customer.retrieve("cus_123")
122
+ customer.sources.retrieve(id: "cc_test_card", expand: [:customer])
103
123
  end
104
124
 
105
125
  context "when specifying per-object credentials" do
106
126
  context "with no global API key set" do
107
127
  should "use the per-object credential when creating" do
108
- stub_request(:post, "#{Stripe.api_base}/v1/charges").
109
- with(headers: {"Authorization" => "Bearer sk_test_local"}).
110
- to_return(body: JSON.generate(charge_fixture))
128
+ stub_request(:post, "#{Stripe.api_base}/v1/charges")
129
+ .with(headers: { "Authorization" => "Bearer sk_test_local" })
130
+ .to_return(body: JSON.generate(charge_fixture))
111
131
 
112
- Stripe::Charge.create({:source => 'tok_visa'},
113
- 'sk_test_local')
132
+ Stripe::Charge.create({ source: "tok_visa" },
133
+ "sk_test_local")
114
134
  end
115
135
  end
116
136
 
@@ -124,23 +144,23 @@ module Stripe
124
144
  end
125
145
 
126
146
  should "use the per-object credential when creating" do
127
- stub_request(:post, "#{Stripe.api_base}/v1/charges").
128
- with(headers: {"Authorization" => "Bearer sk_test_local"}).
129
- to_return(body: JSON.generate(charge_fixture))
147
+ stub_request(:post, "#{Stripe.api_base}/v1/charges")
148
+ .with(headers: { "Authorization" => "Bearer sk_test_local" })
149
+ .to_return(body: JSON.generate(charge_fixture))
130
150
 
131
- Stripe::Charge.create({:source => 'tok_visa'},
132
- 'sk_test_local')
151
+ Stripe::Charge.create({ source: "tok_visa" },
152
+ "sk_test_local")
133
153
  end
134
154
 
135
155
  should "use the per-object credential when retrieving and making other calls" do
136
- stub_request(:get, "#{Stripe.api_base}/v1/charges/ch_123").
137
- with(headers: {"Authorization" => "Bearer sk_test_local"}).
138
- to_return(body: JSON.generate(charge_fixture))
139
- stub_request(:post, "#{Stripe.api_base}/v1/charges/ch_123/refunds").
140
- with(headers: {"Authorization" => "Bearer sk_test_local"}).
141
- to_return(body: "{}")
142
-
143
- ch = Stripe::Charge.retrieve('ch_123', 'sk_test_local')
156
+ stub_request(:get, "#{Stripe.api_base}/v1/charges/ch_123")
157
+ .with(headers: { "Authorization" => "Bearer sk_test_local" })
158
+ .to_return(body: JSON.generate(charge_fixture))
159
+ stub_request(:post, "#{Stripe.api_base}/v1/charges/ch_123/refunds")
160
+ .with(headers: { "Authorization" => "Bearer sk_test_local" })
161
+ .to_return(body: "{}")
162
+
163
+ ch = Stripe::Charge.retrieve("ch_123", "sk_test_local")
144
164
  ch.refunds.create
145
165
  end
146
166
  end
@@ -148,52 +168,46 @@ module Stripe
148
168
 
149
169
  context "with valid credentials" do
150
170
  should "urlencode values in GET params" do
151
- stub_request(:get, "#{Stripe.api_base}/v1/charges").
152
- with(query: { customer: "test customer" }).
153
- to_return(body: JSON.generate({
154
- data: [charge_fixture]
155
- }))
156
- charges = Stripe::Charge.list(:customer => 'test customer').data
157
- assert charges.kind_of? Array
171
+ stub_request(:get, "#{Stripe.api_base}/v1/charges")
172
+ .with(query: { customer: "test customer" })
173
+ .to_return(body: JSON.generate(data: [charge_fixture]))
174
+ charges = Stripe::Charge.list(customer: "test customer").data
175
+ assert charges.is_a? Array
158
176
  end
159
177
 
160
178
  should "construct URL properly with base query parameters" do
161
- stub_request(:get, "#{Stripe.api_base}/v1/charges").
162
- with(query: { customer: "cus_123" }).
163
- to_return(body: JSON.generate({
164
- data: [charge_fixture],
165
- url: "/v1/charges"
166
- }))
167
- charges = Stripe::Invoice.list(:customer => 'cus_123')
168
-
169
- stub_request(:get, "#{Stripe.api_base}/v1/charges").
170
- with(query: { customer: "cus_123", created: "123" }).
171
- to_return(body: JSON.generate({
172
- data: [charge_fixture],
173
- url: "/v1/charges"
174
- }))
175
- charges.list(:created => 123)
179
+ stub_request(:get, "#{Stripe.api_base}/v1/charges")
180
+ .with(query: { customer: "cus_123" })
181
+ .to_return(body: JSON.generate(data: [charge_fixture],
182
+ url: "/v1/charges"))
183
+ charges = Stripe::Charge.list(customer: "cus_123")
184
+
185
+ stub_request(:get, "#{Stripe.api_base}/v1/charges")
186
+ .with(query: { customer: "cus_123", created: "123" })
187
+ .to_return(body: JSON.generate(data: [charge_fixture],
188
+ url: "/v1/charges"))
189
+ charges.list(created: 123)
176
190
  end
177
191
 
178
192
  should "setting a nil value for a param should exclude that param from the request" do
179
- stub_request(:get, "#{Stripe.api_base}/v1/charges").
180
- with(query: { offset: 5, sad: false }).
181
- to_return(body: JSON.generate({ :count => 1, :data => [charge_fixture] }))
182
- Stripe::Charge.list(:count => nil, :offset => 5, :sad => false)
193
+ stub_request(:get, "#{Stripe.api_base}/v1/charges")
194
+ .with(query: { offset: 5, sad: false })
195
+ .to_return(body: JSON.generate(count: 1, data: [charge_fixture]))
196
+ Stripe::Charge.list(count: nil, offset: 5, sad: false)
183
197
 
184
- stub_request(:post, "#{Stripe.api_base}/v1/charges").
185
- with(body: { 'amount' => '50', 'currency' => 'usd' }).
186
- to_return(body: JSON.generate({ :count => 1, :data => [charge_fixture] }))
187
- Stripe::Charge.create(:amount => 50, :currency => 'usd', :card => { :number => nil })
198
+ stub_request(:post, "#{Stripe.api_base}/v1/charges")
199
+ .with(body: { "amount" => "50", "currency" => "usd" })
200
+ .to_return(body: JSON.generate(count: 1, data: [charge_fixture]))
201
+ Stripe::Charge.create(amount: 50, currency: "usd", card: { number: nil })
188
202
  end
189
203
 
190
204
  should "not trigger a warning if a known opt, such as idempotency_key, is in opts" do
191
- stub_request(:post, "#{Stripe.api_base}/v1/charges").
192
- to_return(body: JSON.generate(charge_fixture))
205
+ stub_request(:post, "#{Stripe.api_base}/v1/charges")
206
+ .to_return(body: JSON.generate(charge_fixture))
193
207
  old_stderr = $stderr
194
208
  $stderr = StringIO.new
195
209
  begin
196
- Stripe::Charge.create({ :amount => 100, :currency => 'usd', :card => 'sc_token' }, { :idempotency_key => '12345' })
210
+ Stripe::Charge.create({ amount: 100, currency: "usd", card: "sc_token" }, idempotency_key: "12345")
197
211
  assert $stderr.string.empty?
198
212
  ensure
199
213
  $stderr = old_stderr
@@ -201,21 +215,54 @@ module Stripe
201
215
  end
202
216
 
203
217
  should "trigger a warning if a known opt, such as idempotency_key, is in params" do
204
- stub_request(:post, "#{Stripe.api_base}/v1/charges").
205
- to_return(body: JSON.generate(charge_fixture))
218
+ stub_request(:post, "#{Stripe.api_base}/v1/charges")
219
+ .to_return(body: JSON.generate(charge_fixture))
206
220
  old_stderr = $stderr
207
221
  $stderr = StringIO.new
208
222
  begin
209
- Stripe::Charge.create({ :amount => 100, :currency => 'usd', :card => 'sc_token', :idempotency_key => '12345' })
210
- assert_match Regexp.new('WARNING:'), $stderr.string
223
+ Stripe::Charge.create(amount: 100, currency: "usd", card: "sc_token", idempotency_key: "12345")
224
+ assert_match Regexp.new("WARNING:"), $stderr.string
211
225
  ensure
212
226
  $stderr = old_stderr
213
227
  end
214
228
  end
215
229
 
230
+ should "error if the params is not a Hash" do
231
+ stub_request(:post, "#{Stripe.api_base}/v1/charges/ch_123/capture")
232
+ .to_return(body: JSON.generate(charge_fixture))
233
+
234
+ e = assert_raises(ArgumentError) { Stripe::Charge.capture("ch_123", "sk_test_secret") }
235
+
236
+ assert_equal "request params should be either a Hash or nil (was a String)", e.message
237
+ end
238
+
239
+ should "allow making a request with params set to nil" do
240
+ stub_request(:post, "#{Stripe.api_base}/v1/charges/ch_123/capture")
241
+ .to_return(body: JSON.generate(charge_fixture))
242
+
243
+ Stripe::Charge.capture("ch_123", nil, "sk_test_secret")
244
+ end
245
+
246
+ should "error if a user-specified opt is given a non-nil non-string value" do
247
+ stub_request(:post, "#{Stripe.api_base}/v1/charges")
248
+ .to_return(body: JSON.generate(charge_fixture))
249
+
250
+ # Works fine if not included or a string.
251
+ Stripe::Charge.create({ amount: 100, currency: "usd" }, {})
252
+ Stripe::Charge.create({ amount: 100, currency: "usd" }, idempotency_key: "12345")
253
+
254
+ # Errors on a non-string.
255
+ e = assert_raises(ArgumentError) do
256
+ Stripe::Charge.create({ amount: 100, currency: "usd" }, idempotency_key: :foo)
257
+ end
258
+ assert_equal "request option 'idempotency_key' should be a string value " \
259
+ "(was a Symbol)",
260
+ e.message
261
+ end
262
+
216
263
  should "requesting with a unicode ID should result in a request" do
217
- stub_request(:get, "#{Stripe.api_base}/v1/customers/%E2%98%83").
218
- to_return(body: JSON.generate(make_missing_id_error), status: 404)
264
+ stub_request(:get, "#{Stripe.api_base}/v1/customers/%E2%98%83")
265
+ .to_return(body: JSON.generate(make_missing_id_error), status: 404)
219
266
  c = Stripe::Customer.new("☃")
220
267
  assert_raises(Stripe::InvalidRequestError) { c.refresh }
221
268
  end
@@ -226,58 +273,50 @@ module Stripe
226
273
  end
227
274
 
228
275
  should "making a GET request with parameters should have a query string and no body" do
229
- stub_request(:get, "#{Stripe.api_base}/v1/charges").
230
- with(query: { limit: 1 }).
231
- to_return(body: JSON.generate({ :data => [charge_fixture] }))
232
- Stripe::Charge.list({ :limit => 1 })
276
+ stub_request(:get, "#{Stripe.api_base}/v1/charges")
277
+ .with(query: { limit: 1 })
278
+ .to_return(body: JSON.generate(data: [charge_fixture]))
279
+ Stripe::Charge.list(limit: 1)
233
280
  end
234
281
 
235
282
  should "making a POST request with parameters should have a body and no query string" do
236
- stub_request(:post, "#{Stripe.api_base}/v1/charges").
237
- with(body: {'amount' => '100', 'currency' => 'usd', 'card' => 'sc_token'}).
238
- to_return(body: JSON.generate(charge_fixture))
239
- Stripe::Charge.create({ :amount => 100, :currency => 'usd', :card => 'sc_token' })
283
+ stub_request(:post, "#{Stripe.api_base}/v1/charges")
284
+ .with(body: { "amount" => "100", "currency" => "usd", "card" => "sc_token" })
285
+ .to_return(body: JSON.generate(charge_fixture))
286
+ Stripe::Charge.create(amount: 100, currency: "usd", card: "sc_token")
240
287
  end
241
288
 
242
289
  should "loading an object should issue a GET request" do
243
- stub_request(:get, "#{Stripe.api_base}/v1/charges/ch_123").
244
- to_return(body: JSON.generate(charge_fixture))
290
+ stub_request(:get, "#{Stripe.api_base}/v1/charges/ch_123")
291
+ .to_return(body: JSON.generate(charge_fixture))
245
292
  c = Stripe::Charge.new("ch_123")
246
293
  c.refresh
247
294
  end
248
295
 
249
296
  should "using array accessors should be the same as the method interface" do
250
- stub_request(:get, "#{Stripe.api_base}/v1/charges/ch_123").
251
- to_return(body: JSON.generate(charge_fixture))
297
+ stub_request(:get, "#{Stripe.api_base}/v1/charges/ch_123")
298
+ .to_return(body: JSON.generate(charge_fixture))
252
299
  c = Stripe::Charge.new("cus_123")
253
300
  c.refresh
254
301
  assert_equal c.created, c[:created]
255
- assert_equal c.created, c['created']
256
- c['created'] = 12345
257
- assert_equal c.created, 12345
258
- end
259
-
260
- should "accessing a property other than id or parent on an unfetched object should fetch it" do
261
- stub_request(:get, "#{Stripe.api_base}/v1/charges").
262
- with(query: { customer: "cus_123" }).
263
- to_return(body: JSON.generate(customer_fixture))
264
- c = Stripe::Customer.new("cus_123")
265
- c.charges
302
+ assert_equal c.created, c["created"]
303
+ c["created"] = 12_345
304
+ assert_equal c.created, 12_345
266
305
  end
267
306
 
268
307
  should "updating an object should issue a POST request with only the changed properties" do
269
- stub_request(:post, "#{Stripe.api_base}/v1/customers/cus_123").
270
- with(body: { 'description' => 'another_mn' }).
271
- to_return(body: JSON.generate(customer_fixture))
308
+ stub_request(:post, "#{Stripe.api_base}/v1/customers/cus_123")
309
+ .with(body: { "description" => "another_mn" })
310
+ .to_return(body: JSON.generate(customer_fixture))
272
311
  c = Stripe::Customer.construct_from(customer_fixture)
273
312
  c.description = "another_mn"
274
313
  c.save
275
314
  end
276
315
 
277
316
  should "updating should merge in returned properties" do
278
- stub_request(:post, "#{Stripe.api_base}/v1/customers/cus_123").
279
- with(body: { 'description' => 'another_mn' }).
280
- to_return(body: JSON.generate(customer_fixture))
317
+ stub_request(:post, "#{Stripe.api_base}/v1/customers/cus_123")
318
+ .with(body: { "description" => "another_mn" })
319
+ .to_return(body: JSON.generate(customer_fixture))
281
320
  c = Stripe::Customer.new("cus_123")
282
321
  c.description = "another_mn"
283
322
  c.save
@@ -287,267 +326,316 @@ module Stripe
287
326
  should "updating should fail if api_key is overwritten with nil" do
288
327
  c = Stripe::Customer.new
289
328
  assert_raises TypeError do
290
- c.save({}, { :api_key => nil })
329
+ c.save({}, api_key: nil)
291
330
  end
292
331
  end
293
332
 
294
333
  should "updating should use the supplied api_key" do
295
- stub_request(:post, "#{Stripe.api_base}/v1/customers").
296
- with(headers: {"Authorization" => "Bearer sk_test_local"}).
297
- to_return(body: JSON.generate(customer_fixture))
334
+ stub_request(:post, "#{Stripe.api_base}/v1/customers")
335
+ .with(headers: { "Authorization" => "Bearer sk_test_local" })
336
+ .to_return(body: JSON.generate(customer_fixture))
298
337
  c = Stripe::Customer.new
299
- c.save({}, { :api_key => 'sk_test_local' })
338
+ c.save({}, api_key: "sk_test_local")
300
339
  assert_equal false, c.livemode
301
340
  end
302
341
 
303
342
  should "deleting should send no props and result in an object that has no props other deleted" do
304
- stub_request(:delete, "#{Stripe.api_base}/v1/customers/cus_123").
305
- to_return(body: JSON.generate({ "id" => "cus_123", "deleted" => true }))
343
+ stub_request(:delete, "#{Stripe.api_base}/v1/customers/cus_123")
344
+ .to_return(body: JSON.generate("id" => "cus_123", "deleted" => true))
306
345
  c = Stripe::Customer.construct_from(customer_fixture)
307
346
  c.delete
308
347
  end
309
348
 
310
349
  should "loading all of an APIResource should return an array of recursively instantiated objects" do
311
- stub_request(:get, "#{Stripe.api_base}/v1/charges").
312
- to_return(body: JSON.generate({
313
- data: [charge_fixture]
314
- }))
350
+ stub_request(:get, "#{Stripe.api_base}/v1/charges")
351
+ .to_return(body: JSON.generate(data: [charge_fixture]))
315
352
  charges = Stripe::Charge.list.data
316
- assert charges.kind_of? Array
317
- assert charges[0].kind_of? Stripe::Charge
318
- assert charges[0].source.kind_of?(Stripe::StripeObject)
353
+ assert charges.is_a? Array
354
+ assert charges[0].is_a? Stripe::Charge
355
+ assert charges[0].payment_method_details.is_a?(Stripe::StripeObject)
319
356
  end
320
357
 
321
358
  should "passing in a stripe_account header should pass it through on call" do
322
- stub_request(:get, "#{Stripe.api_base}/v1/customers/cus_123").
323
- with(headers: {"Stripe-Account" => "acct_123"}).
324
- to_return(body: JSON.generate(customer_fixture))
325
- Stripe::Customer.retrieve("cus_123", {:stripe_account => 'acct_123'})
359
+ stub_request(:get, "#{Stripe.api_base}/v1/customers/cus_123")
360
+ .with(headers: { "Stripe-Account" => "acct_123" })
361
+ .to_return(body: JSON.generate(customer_fixture))
362
+ Stripe::Customer.retrieve("cus_123", stripe_account: "acct_123")
326
363
  end
327
364
 
328
365
  should "passing in a stripe_account header should pass it through on save" do
329
- stub_request(:get, "#{Stripe.api_base}/v1/customers/cus_123").
330
- with(headers: {"Stripe-Account" => "acct_123"}).
331
- to_return(body: JSON.generate(customer_fixture))
332
- c = Stripe::Customer.retrieve("cus_123", {:stripe_account => 'acct_123'})
333
-
334
- stub_request(:post, "#{Stripe.api_base}/v1/customers/cus_123").
335
- with(headers: {"Stripe-Account" => "acct_123"}).
336
- to_return(body: JSON.generate(customer_fixture))
337
- c.description = 'FOO'
366
+ stub_request(:get, "#{Stripe.api_base}/v1/customers/cus_123")
367
+ .with(headers: { "Stripe-Account" => "acct_123" })
368
+ .to_return(body: JSON.generate(customer_fixture))
369
+ c = Stripe::Customer.retrieve("cus_123", stripe_account: "acct_123")
370
+
371
+ stub_request(:post, "#{Stripe.api_base}/v1/customers/cus_123")
372
+ .with(headers: { "Stripe-Account" => "acct_123" })
373
+ .to_return(body: JSON.generate(customer_fixture))
374
+ c.description = "FOO"
338
375
  c.save
339
376
  end
340
377
 
341
- should 'add key to nested objects' do
342
- acct = Stripe::Account.construct_from({
343
- :id => 'myid',
344
- :legal_entity => {
345
- :size => 'l',
346
- :score => 4,
347
- :height => 10
348
- }
349
- })
378
+ should "add key to nested objects" do
379
+ acct = Stripe::Account.construct_from(id: "myid",
380
+ legal_entity: {
381
+ size: "l",
382
+ score: 4,
383
+ height: 10,
384
+ })
350
385
 
351
- stub_request(:post, "#{Stripe.api_base}/v1/accounts/myid").
352
- with(body: { legal_entity: { first_name: "Bob" } }).
353
- to_return(body: JSON.generate({ "id" => "myid" }))
386
+ stub_request(:post, "#{Stripe.api_base}/v1/accounts/myid")
387
+ .with(body: { legal_entity: { first_name: "Bob" } })
388
+ .to_return(body: JSON.generate("id" => "myid"))
354
389
 
355
- acct.legal_entity.first_name = 'Bob'
390
+ acct.legal_entity.first_name = "Bob"
356
391
  acct.save
357
392
  end
358
393
 
359
- should 'save nothing if nothing changes' do
360
- acct = Stripe::Account.construct_from({
361
- :id => 'acct_id',
362
- :metadata => {
363
- :key => 'value'
364
- }
365
- })
394
+ should "save nothing if nothing changes" do
395
+ acct = Stripe::Account.construct_from(id: "acct_id",
396
+ metadata: {
397
+ key: "value",
398
+ })
366
399
 
367
- stub_request(:post, "#{Stripe.api_base}/v1/accounts/acct_id").
368
- with(body: {}).
369
- to_return(body: JSON.generate({ "id" => "acct_id" }))
400
+ stub_request(:post, "#{Stripe.api_base}/v1/accounts/acct_id")
401
+ .with(body: {})
402
+ .to_return(body: JSON.generate("id" => "acct_id"))
370
403
 
371
404
  acct.save
372
405
  end
373
406
 
374
- should 'not save nested API resources' do
375
- ch = Stripe::Charge.construct_from({
376
- :id => 'ch_id',
377
- :customer => {
378
- :object => 'customer',
379
- :id => 'customer_id'
380
- }
381
- })
407
+ should "not save nested API resources" do
408
+ ch = Stripe::Charge.construct_from(id: "ch_id",
409
+ customer: {
410
+ object: "customer",
411
+ id: "customer_id",
412
+ })
382
413
 
383
- stub_request(:post, "#{Stripe.api_base}/v1/charges/ch_id").
384
- with(body: {}).
385
- to_return(body: JSON.generate({ "id" => "ch_id" }))
414
+ stub_request(:post, "#{Stripe.api_base}/v1/charges/ch_id")
415
+ .with(body: {})
416
+ .to_return(body: JSON.generate("id" => "ch_id"))
386
417
 
387
- ch.customer.description = 'Bob'
418
+ ch.customer.description = "Bob"
388
419
  ch.save
389
420
  end
390
421
 
391
- should 'correctly handle replaced nested objects' do
392
- acct = Stripe::Account.construct_from({
393
- :id => 'myid',
394
- :legal_entity => {
395
- :last_name => 'Smith',
396
- :address => {
397
- :line1 => "test",
398
- :city => "San Francisco"
399
- }
422
+ should "correctly handle replaced nested objects" do
423
+ acct = Stripe::Account.construct_from(
424
+ id: "acct_123",
425
+ company: {
426
+ name: "company_name",
427
+ address: {
428
+ line1: "test",
429
+ city: "San Francisco",
430
+ },
400
431
  }
401
- })
432
+ )
402
433
 
403
- stub_request(:post, "#{Stripe.api_base}/v1/accounts/myid").
404
- with(body: { legal_entity: { address: { line1: "Test2", city: "" } } }).
405
- to_return(body: JSON.generate({ "id" => "my_id" }))
434
+ stub_request(:post, "#{Stripe.api_base}/v1/accounts/acct_123")
435
+ .with(body: { company: { address: { line1: "Test2", city: "" } } })
436
+ .to_return(body: JSON.generate("id" => "my_id"))
406
437
 
407
- acct.legal_entity.address = {:line1 => 'Test2'}
438
+ acct.company.address = { line1: "Test2" }
408
439
  acct.save
409
440
  end
410
441
 
411
- should 'correctly handle array setting' do
412
- acct = Stripe::Account.construct_from({
413
- :id => 'myid',
414
- :legal_entity => {}
415
- })
442
+ should "correctly handle array setting" do
443
+ acct = Stripe::Account.construct_from(id: "myid",
444
+ legal_entity: {})
416
445
 
417
- stub_request(:post, "#{Stripe.api_base}/v1/accounts/myid").
418
- with(body: { legal_entity: { additional_owners: [{ first_name: "Bob" }] } }).
419
- to_return(body: JSON.generate({ "id" => "myid" }))
446
+ stub_request(:post, "#{Stripe.api_base}/v1/accounts/myid")
447
+ .with(body: { legal_entity: { additional_owners: [{ first_name: "Bob" }] } })
448
+ .to_return(body: JSON.generate("id" => "myid"))
420
449
 
421
- acct.legal_entity.additional_owners = [{:first_name => 'Bob'}]
450
+ acct.legal_entity.additional_owners = [{ first_name: "Bob" }]
422
451
  acct.save
423
452
  end
424
453
 
425
- should 'correctly handle array insertion' do
426
- acct = Stripe::Account.construct_from({
427
- :id => 'myid',
428
- :legal_entity => {
429
- :additional_owners => []
430
- }
431
- })
454
+ should "correctly handle array insertion" do
455
+ acct = Stripe::Account.construct_from(id: "myid",
456
+ legal_entity: {
457
+ additional_owners: [],
458
+ })
432
459
 
433
460
  # Note that this isn't a perfect check because we're using webmock's
434
461
  # data decoding, which isn't aware of the Stripe array encoding that we
435
462
  # use here.
436
- stub_request(:post, "#{Stripe.api_base}/v1/accounts/myid").
437
- with(body: { legal_entity: { additional_owners: [{ first_name: "Bob" }] } }).
438
- to_return(body: JSON.generate({ "id" => "myid" }))
463
+ stub_request(:post, "#{Stripe.api_base}/v1/accounts/myid")
464
+ .with(body: { legal_entity: { additional_owners: [{ first_name: "Bob" }] } })
465
+ .to_return(body: JSON.generate("id" => "myid"))
439
466
 
440
- acct.legal_entity.additional_owners << {:first_name => 'Bob'}
467
+ acct.legal_entity.additional_owners << { first_name: "Bob" }
441
468
  acct.save
442
469
  end
443
470
 
444
- should 'correctly handle array updates' do
445
- acct = Stripe::Account.construct_from({
446
- :id => 'myid',
447
- :legal_entity => {
448
- :additional_owners => [{:first_name => 'Bob'}, {:first_name => 'Jane'}]
449
- }
450
- })
471
+ should "correctly handle array updates" do
472
+ acct = Stripe::Account.construct_from(id: "myid",
473
+ legal_entity: {
474
+ additional_owners: [{ first_name: "Bob" }, { first_name: "Jane" }],
475
+ })
451
476
 
452
477
  # Note that this isn't a perfect check because we're using webmock's
453
478
  # data decoding, which isn't aware of the Stripe array encoding that we
454
479
  # use here.
455
- stub_request(:post, "#{Stripe.api_base}/v1/accounts/myid").
456
- with(body: { legal_entity: { additional_owners: [{ first_name: "Janet" }] } }).
457
- to_return(body: JSON.generate({ "id" => "myid" }))
480
+ stub_request(:post, "#{Stripe.api_base}/v1/accounts/myid")
481
+ .with(body: { legal_entity: { additional_owners: [{ first_name: "Janet" }] } })
482
+ .to_return(body: JSON.generate("id" => "myid"))
458
483
 
459
- acct.legal_entity.additional_owners[1].first_name = 'Janet'
484
+ acct.legal_entity.additional_owners[1].first_name = "Janet"
460
485
  acct.save
461
486
  end
462
487
 
463
- should 'correctly handle array noops' do
464
- acct = Stripe::Account.construct_from({
465
- :id => 'myid',
466
- :legal_entity => {
467
- :additional_owners => [{:first_name => 'Bob'}]
468
- },
469
- :currencies_supported => ['usd', 'cad']
470
- })
488
+ should "correctly handle array noops" do
489
+ acct = Stripe::Account.construct_from(id: "myid",
490
+ legal_entity: {
491
+ additional_owners: [{ first_name: "Bob" }],
492
+ },
493
+ currencies_supported: %w[usd cad])
471
494
 
472
- stub_request(:post, "#{Stripe.api_base}/v1/accounts/myid").
473
- with(body: {}).
474
- to_return(body: JSON.generate({ "id" => "myid" }))
495
+ stub_request(:post, "#{Stripe.api_base}/v1/accounts/myid")
496
+ .with(body: {})
497
+ .to_return(body: JSON.generate("id" => "myid"))
475
498
 
476
499
  acct.save
477
500
  end
478
501
 
479
- should 'correctly handle hash noops' do
480
- acct = Stripe::Account.construct_from({
481
- :id => 'myid',
482
- :legal_entity => {
483
- :address => {:line1 => '1 Two Three'}
484
- }
485
- })
502
+ should "correctly handle hash noops" do
503
+ acct = Stripe::Account.construct_from(id: "myid",
504
+ legal_entity: {
505
+ address: { line1: "1 Two Three" },
506
+ })
486
507
 
487
- stub_request(:post, "#{Stripe.api_base}/v1/accounts/myid").
488
- with(body: {}).
489
- to_return(body: JSON.generate({ "id" => "myid" }))
508
+ stub_request(:post, "#{Stripe.api_base}/v1/accounts/myid")
509
+ .with(body: {})
510
+ .to_return(body: JSON.generate("id" => "myid"))
490
511
 
491
512
  acct.save
492
513
  end
493
514
 
494
- should 'should create a new resource when an object without an id is saved' do
495
- account = Stripe::Account.construct_from({
496
- :id => nil,
497
- :display_name => nil,
498
- })
515
+ should "should create a new resource when an object without an id is saved" do
516
+ account = Stripe::Account.construct_from(id: nil,
517
+ display_name: nil)
499
518
 
500
- stub_request(:post, "#{Stripe.api_base}/v1/accounts").
501
- with(body: { display_name: "stripe" }).
502
- to_return(body: JSON.generate({ "id" => "acct_123" }))
519
+ stub_request(:post, "#{Stripe.api_base}/v1/accounts")
520
+ .with(body: { display_name: "stripe" })
521
+ .to_return(body: JSON.generate("id" => "acct_123"))
503
522
 
504
- account.display_name = 'stripe'
523
+ account.display_name = "stripe"
505
524
  account.save
506
525
  end
507
526
 
508
- should 'set attributes as part of save' do
509
- account = Stripe::Account.construct_from({
510
- :id => nil,
511
- :display_name => nil,
512
- })
527
+ should "set attributes as part of save" do
528
+ account = Stripe::Account.construct_from(id: nil,
529
+ display_name: nil)
513
530
 
514
- stub_request(:post, "#{Stripe.api_base}/v1/accounts").
515
- with(body: { display_name: "stripe", metadata: { key: "value" } }).
516
- to_return(body: JSON.generate({ "id" => "acct_123" }))
531
+ stub_request(:post, "#{Stripe.api_base}/v1/accounts")
532
+ .with(body: { display_name: "stripe", metadata: { key: "value" } })
533
+ .to_return(body: JSON.generate("id" => "acct_123"))
517
534
 
518
- account.save(:display_name => 'stripe', :metadata => {:key => 'value' })
535
+ account.save(display_name: "stripe", metadata: { key: "value" })
519
536
  end
520
537
  end
521
538
 
522
- @@fixtures = {}
539
+ context "#request_stripe_object" do
540
+ class HelloTestAPIResource < APIResource
541
+ OBJECT_NAME = "hello"
542
+ def say_hello(params = {}, opts = {})
543
+ request_stripe_object(
544
+ method: :post,
545
+ path: resource_url + "/say",
546
+ params: params,
547
+ opts: opts
548
+ )
549
+ end
550
+ end
551
+
552
+ setup do
553
+ Util.instance_variable_set(
554
+ :@object_classes,
555
+ Stripe::ObjectTypes.object_names_to_classes.merge(
556
+ "hello" => HelloTestAPIResource
557
+ )
558
+ )
559
+ end
560
+ teardown do
561
+ Util.class.instance_variable_set(:@object_classes, Stripe::ObjectTypes.object_names_to_classes)
562
+ end
563
+
564
+ should "make requests appropriately" do
565
+ stub_request(:post, "#{Stripe.api_base}/v1/hellos/hi_123/say")
566
+ .with(body: { foo: "bar" }, headers: { "Stripe-Account" => "acct_hi" })
567
+ .to_return(body: JSON.generate("object" => "hello"))
568
+
569
+ hello = HelloTestAPIResource.new(id: "hi_123")
570
+ hello.say_hello({ foo: "bar" }, stripe_account: "acct_hi")
571
+ end
572
+
573
+ should "update attributes in-place when it returns the same thing" do
574
+ stub_request(:post, "#{Stripe.api_base}/v1/hellos/hi_123/say")
575
+ .to_return(body: JSON.generate("object" => "hello", "additional" => "attribute"))
576
+
577
+ hello = HelloTestAPIResource.new(id: "hi_123")
578
+ hello.unsaved = "a value"
579
+ new_hello = hello.say_hello
580
+
581
+ # Doesn't matter if you use the return variable or the instance.
582
+ assert_equal(hello, new_hello)
583
+
584
+ # It updates new attributes in-place.
585
+ assert_equal("attribute", hello.additional)
586
+
587
+ # It removes unsaved attributes, but at least lets you know about them.
588
+ e = assert_raises(NoMethodError) { hello.unsaved }
589
+ assert_match("The 'unsaved' attribute was set in the past", e.message)
590
+ end
591
+
592
+ should "instantiate a new object of the appropriate class when it is different than the host class" do
593
+ stub_request(:post, "#{Stripe.api_base}/v1/hellos/hi_123/say")
594
+ .to_return(body: JSON.generate("object" => "goodbye", "additional" => "attribute"))
595
+
596
+ hello = HelloTestAPIResource.new(id: "hi_123")
597
+ hello.unsaved = "a value"
598
+ new_goodbye = hello.say_hello
599
+
600
+ # The returned value and the instance are different objects.
601
+ refute_equal(new_goodbye, hello)
602
+
603
+ # The returned value has stuff from the server.
604
+ assert_equal("attribute", new_goodbye.additional)
605
+ assert_equal("goodbye", new_goodbye.object)
606
+
607
+ # You instance doesn't have stuff from the server.
608
+ e = assert_raises(NoMethodError) { hello.additional }
609
+ refute_match(/was set in the past/, e.message)
610
+
611
+ # The instance preserves unset attributes on the original instance (not sure this is good behavior?)
612
+ assert_equal("a value", hello.unsaved)
613
+ end
614
+ end
615
+
616
+ @@fixtures = {} # rubocop:disable Style/ClassVars
523
617
  setup do
524
618
  if @@fixtures.empty?
525
- set_fixture(:charge) do
619
+ cache_fixture(:charge) do
526
620
  Charge.retrieve("ch_123")
527
621
  end
528
- set_fixture(:customer) do
622
+ cache_fixture(:customer) do
529
623
  Customer.retrieve("cus_123")
530
624
  end
531
625
  end
532
626
  end
533
627
 
534
- private
535
-
536
- def charge_fixture
628
+ private def charge_fixture
537
629
  @@fixtures[:charge]
538
630
  end
539
631
 
540
- def customer_fixture
632
+ private def customer_fixture
541
633
  @@fixtures[:customer]
542
634
  end
543
635
 
544
- def get_fixture(key)
545
- @@fixtures.fetch(key)
546
- end
547
-
548
636
  # Expects to retrieve a fixture from stripe-mock (an API call should be
549
637
  # included in the block to yield to) and does very simple memoization.
550
- def set_fixture(key)
638
+ private def cache_fixture(key)
551
639
  return @@fixtures[key] if @@fixtures.key?(key)
552
640
 
553
641
  obj = yield