stripe 1.18.0 → 1.30.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.travis.yml +11 -1
  4. data/History.txt +98 -0
  5. data/README.rdoc +19 -10
  6. data/VERSION +1 -1
  7. data/lib/stripe/account.rb +46 -4
  8. data/lib/stripe/api_operations/create.rb +3 -10
  9. data/lib/stripe/api_operations/delete.rb +4 -4
  10. data/lib/stripe/api_operations/list.rb +17 -9
  11. data/lib/stripe/api_operations/request.rb +41 -0
  12. data/lib/stripe/api_operations/update.rb +41 -40
  13. data/lib/stripe/api_resource.rb +7 -4
  14. data/lib/stripe/application_fee.rb +3 -4
  15. data/lib/stripe/application_fee_refund.rb +1 -1
  16. data/lib/stripe/balance_transaction.rb +1 -1
  17. data/lib/stripe/bank_account.rb +19 -0
  18. data/lib/stripe/bitcoin_receiver.rb +12 -2
  19. data/lib/stripe/bitcoin_transaction.rb +5 -0
  20. data/lib/stripe/card.rb +6 -4
  21. data/lib/stripe/charge.rb +14 -22
  22. data/lib/stripe/coupon.rb +2 -2
  23. data/lib/stripe/customer.rb +24 -26
  24. data/lib/stripe/dispute.rb +16 -0
  25. data/lib/stripe/errors/card_error.rb +3 -2
  26. data/lib/stripe/errors/invalid_request_error.rb +3 -2
  27. data/lib/stripe/errors/rate_limit_error.rb +4 -0
  28. data/lib/stripe/errors/stripe_error.rb +8 -2
  29. data/lib/stripe/event.rb +1 -1
  30. data/lib/stripe/file_upload.rb +12 -22
  31. data/lib/stripe/invoice.rb +8 -8
  32. data/lib/stripe/invoice_item.rb +2 -2
  33. data/lib/stripe/list_object.rb +77 -13
  34. data/lib/stripe/order.rb +19 -0
  35. data/lib/stripe/plan.rb +2 -2
  36. data/lib/stripe/product.rb +16 -0
  37. data/lib/stripe/recipient.rb +2 -2
  38. data/lib/stripe/refund.rb +2 -9
  39. data/lib/stripe/reversal.rb +14 -0
  40. data/lib/stripe/singleton_api_resource.rb +2 -2
  41. data/lib/stripe/sku.rb +8 -0
  42. data/lib/stripe/stripe_object.rb +232 -46
  43. data/lib/stripe/subscription.rb +3 -3
  44. data/lib/stripe/token.rb +1 -1
  45. data/lib/stripe/transfer.rb +3 -3
  46. data/lib/stripe/util.rb +64 -21
  47. data/lib/stripe/version.rb +1 -1
  48. data/lib/stripe.rb +102 -67
  49. data/stripe.gemspec +0 -2
  50. data/test/stripe/account_test.rb +135 -6
  51. data/test/stripe/api_resource_test.rb +326 -42
  52. data/test/stripe/application_fee_refund_test.rb +6 -6
  53. data/test/stripe/application_fee_test.rb +3 -3
  54. data/test/stripe/balance_test.rb +11 -0
  55. data/test/stripe/bitcoin_receiver_test.rb +30 -7
  56. data/test/stripe/bitcoin_transaction_test.rb +29 -0
  57. data/test/stripe/charge_refund_test.rb +55 -0
  58. data/test/stripe/charge_test.rb +32 -13
  59. data/test/stripe/coupon_test.rb +3 -3
  60. data/test/stripe/customer_card_test.rb +20 -14
  61. data/test/stripe/customer_test.rb +15 -15
  62. data/test/stripe/dispute_test.rb +45 -0
  63. data/test/stripe/file_upload_test.rb +17 -6
  64. data/test/stripe/invoice_test.rb +18 -4
  65. data/test/stripe/list_object_test.rb +126 -2
  66. data/test/stripe/metadata_test.rb +28 -13
  67. data/test/stripe/order_test.rb +52 -0
  68. data/test/stripe/product_test.rb +41 -0
  69. data/test/stripe/recipient_card_test.rb +9 -9
  70. data/test/stripe/refund_test.rb +23 -15
  71. data/test/stripe/reversal_test.rb +47 -0
  72. data/test/stripe/sku_test.rb +24 -0
  73. data/test/stripe/stripe_object_test.rb +67 -6
  74. data/test/stripe/subscription_test.rb +13 -13
  75. data/test/stripe/transfer_test.rb +4 -4
  76. data/test/stripe/util_test.rb +45 -29
  77. data/test/stripe_test.rb +16 -0
  78. data/test/test_data.rb +273 -66
  79. metadata +47 -76
  80. data/lib/stripe/certificate_blacklist.rb +0 -55
  81. data/test/stripe/certificate_blacklist_test.rb +0 -18
@@ -37,6 +37,15 @@ module Stripe
37
37
  end
38
38
  end
39
39
 
40
+ should "using a nil api key should raise an exception" do
41
+ assert_raises TypeError do
42
+ Stripe::Customer.list({}, nil)
43
+ end
44
+ assert_raises TypeError do
45
+ Stripe::Customer.list({}, { :api_key => nil })
46
+ end
47
+ end
48
+
40
49
  should "specifying api credentials containing whitespace should raise an exception" do
41
50
  Stripe.api_key = "key "
42
51
  assert_raises Stripe::AuthenticationError do
@@ -46,7 +55,7 @@ module Stripe
46
55
 
47
56
  should "specifying invalid api credentials should raise an exception" do
48
57
  Stripe.api_key = "invalid"
49
- response = test_response(test_invalid_api_key_error, 401)
58
+ response = make_response(make_invalid_api_key_error, 401)
50
59
  assert_raises Stripe::AuthenticationError do
51
60
  @mock.expects(:get).once.raises(RestClient::ExceptionWithResponse.new(response, 401))
52
61
  Stripe::Customer.retrieve("failing_customer")
@@ -55,7 +64,7 @@ module Stripe
55
64
 
56
65
  should "AuthenticationErrors should have an http status, http body, and JSON body" do
57
66
  Stripe.api_key = "invalid"
58
- response = test_response(test_invalid_api_key_error, 401)
67
+ response = make_response(make_invalid_api_key_error, 401)
59
68
  begin
60
69
  @mock.expects(:get).once.raises(RestClient::ExceptionWithResponse.new(response, 401))
61
70
  Stripe::Customer.retrieve("failing_customer")
@@ -63,15 +72,45 @@ module Stripe
63
72
  assert_equal(401, e.http_status)
64
73
  assert_equal(true, !!e.http_body)
65
74
  assert_equal(true, !!e.json_body[:error][:message])
66
- assert_equal(test_invalid_api_key_error[:error][:message], e.json_body[:error][:message])
75
+ assert_equal(make_invalid_api_key_error[:error][:message], e.json_body[:error][:message])
67
76
  end
68
77
  end
69
78
 
79
+ should "send expand on fetch properly" do
80
+ @mock.expects(:get).once.
81
+ with("#{Stripe.api_base}/v1/charges/ch_test_charge?expand[]=customer", nil, nil).
82
+ returns(make_response(make_charge))
83
+
84
+ Stripe::Charge.retrieve({:id => 'ch_test_charge', :expand => [:customer]})
85
+ end
86
+
87
+ should "preserve expand across refreshes" do
88
+ @mock.expects(:get).twice.
89
+ with("#{Stripe.api_base}/v1/charges/ch_test_charge?expand[]=customer", nil, nil).
90
+ returns(make_response(make_charge))
91
+
92
+ ch = Stripe::Charge.retrieve({:id => 'ch_test_charge', :expand => [:customer]})
93
+ ch.refresh
94
+ end
95
+
96
+ should "send expand when fetching through ListObject" do
97
+ @mock.expects(:get).once.
98
+ with("#{Stripe.api_base}/v1/customers/c_test_customer", nil, nil).
99
+ returns(make_response(make_customer))
100
+
101
+ @mock.expects(:get).once.
102
+ with("#{Stripe.api_base}/v1/customers/c_test_customer/sources/cc_test_card?expand[]=customer", nil, nil).
103
+ returns(make_response(make_card))
104
+
105
+ customer = Stripe::Customer.retrieve('c_test_customer')
106
+ customer.sources.retrieve({:id => 'cc_test_card', :expand => [:customer]})
107
+ end
108
+
70
109
  should "send stripe account as header when set" do
71
110
  stripe_account = "acct_0000"
72
111
  Stripe.expects(:execute_request).with do |opts|
73
112
  opts[:headers][:stripe_account] == stripe_account
74
- end.returns(test_response(test_charge))
113
+ end.returns(make_response(make_charge))
75
114
 
76
115
  Stripe::Charge.create({:card => {:number => '4242424242424242'}},
77
116
  {:stripe_account => stripe_account, :api_key => 'sk_test_local'})
@@ -80,18 +119,63 @@ module Stripe
80
119
  should "not send stripe account as header when not set" do
81
120
  Stripe.expects(:execute_request).with do |opts|
82
121
  opts[:headers][:stripe_account].nil?
83
- end.returns(test_response(test_charge))
122
+ end.returns(make_response(make_charge))
84
123
 
85
124
  Stripe::Charge.create({:card => {:number => '4242424242424242'}},
86
125
  'sk_test_local')
87
126
  end
88
127
 
128
+ should "handle error response with empty body" do
129
+ response = make_response('', 500)
130
+ @mock.expects(:post).once.raises(RestClient::ExceptionWithResponse.new(response, 500))
131
+
132
+ e = assert_raises Stripe::APIError do
133
+ Stripe::Charge.create
134
+ end
135
+
136
+ assert_equal 'Invalid response object from API: "" (HTTP response code was 500)', e.message
137
+ end
138
+
139
+ should "handle error response with non-object error value" do
140
+ response = make_response('{"error": "foo"}', 500)
141
+ @mock.expects(:post).once.raises(RestClient::ExceptionWithResponse.new(response, 500))
142
+
143
+ e = assert_raises Stripe::APIError do
144
+ Stripe::Charge.create
145
+ end
146
+
147
+ assert_equal 'Invalid response object from API: "{\"error\": \"foo\"}" (HTTP response code was 500)', e.message
148
+ end
149
+
150
+ should "have default open and read timeouts" do
151
+ assert_equal Stripe.open_timeout, 30
152
+ assert_equal Stripe.read_timeout, 80
153
+ end
154
+
155
+ should "allow configurable open and read timeouts" do
156
+ original_timeouts = Stripe.open_timeout, Stripe.read_timeout
157
+
158
+ begin
159
+ Stripe.open_timeout = 999
160
+ Stripe.read_timeout = 998
161
+
162
+ Stripe.expects(:execute_request).with do |opts|
163
+ opts[:open_timeout] == 999 && opts[:timeout] == 998
164
+ end.returns(make_response(make_charge))
165
+
166
+ Stripe::Charge.create({:card => {:number => '4242424242424242'}},
167
+ 'sk_test_local')
168
+ ensure
169
+ Stripe.open_timeout, Stripe.read_timeout = original_timeouts
170
+ end
171
+ end
172
+
89
173
  context "when specifying per-object credentials" do
90
174
  context "with no global API key set" do
91
175
  should "use the per-object credential when creating" do
92
176
  Stripe.expects(:execute_request).with do |opts|
93
177
  opts[:headers][:authorization] == 'Bearer sk_test_local'
94
- end.returns(test_response(test_charge))
178
+ end.returns(make_response(make_charge))
95
179
 
96
180
  Stripe::Charge.create({:card => {:number => '4242424242424242'}},
97
181
  'sk_test_local')
@@ -110,7 +194,7 @@ module Stripe
110
194
  should "use the per-object credential when creating" do
111
195
  Stripe.expects(:execute_request).with do |opts|
112
196
  opts[:headers][:authorization] == 'Bearer local'
113
- end.returns(test_response(test_charge))
197
+ end.returns(make_response(make_charge))
114
198
 
115
199
  Stripe::Charge.create({:card => {:number => '4242424242424242'}},
116
200
  'local')
@@ -120,11 +204,11 @@ module Stripe
120
204
  Stripe.expects(:execute_request).with do |opts|
121
205
  opts[:url] == "#{Stripe.api_base}/v1/charges/ch_test_charge" &&
122
206
  opts[:headers][:authorization] == 'Bearer local'
123
- end.returns(test_response(test_charge))
207
+ end.returns(make_response(make_charge))
124
208
  Stripe.expects(:execute_request).with do |opts|
125
209
  opts[:url] == "#{Stripe.api_base}/v1/charges/ch_test_charge/refund" &&
126
210
  opts[:headers][:authorization] == 'Bearer local'
127
- end.returns(test_response(test_charge))
211
+ end.returns(make_response(make_charge))
128
212
 
129
213
  ch = Stripe::Charge.retrieve('ch_test_charge', 'local')
130
214
  ch.refund
@@ -136,7 +220,7 @@ module Stripe
136
220
  should "send along the idempotency-key header" do
137
221
  Stripe.expects(:execute_request).with do |opts|
138
222
  opts[:headers][:idempotency_key] == 'bar'
139
- end.returns(test_response(test_charge))
223
+ end.returns(make_response(make_charge))
140
224
 
141
225
  Stripe::Charge.create({:card => {:number => '4242424242424242'}}, {
142
226
  :idempotency_key => 'bar',
@@ -145,23 +229,23 @@ module Stripe
145
229
  end
146
230
 
147
231
  should "urlencode values in GET params" do
148
- response = test_response(test_charge_array)
149
- @mock.expects(:get).with("#{Stripe.api_base}/v1/charges?customer=test%20customer", nil, nil).returns(response)
150
- charges = Stripe::Charge.all(:customer => 'test customer').data
232
+ response = make_response(make_charge_array)
233
+ @mock.expects(:get).with("#{Stripe.api_base}/v1/charges?customer=test+customer", nil, nil).returns(response)
234
+ charges = Stripe::Charge.list(:customer => 'test customer').data
151
235
  assert charges.kind_of? Array
152
236
  end
153
237
 
154
238
  should "construct URL properly with base query parameters" do
155
- response = test_response(test_invoice_customer_array)
239
+ response = make_response(make_invoice_customer_array)
156
240
  @mock.expects(:get).with("#{Stripe.api_base}/v1/invoices?customer=test_customer", nil, nil).returns(response)
157
- invoices = Stripe::Invoice.all(:customer => 'test_customer')
241
+ invoices = Stripe::Invoice.list(:customer => 'test_customer')
158
242
 
159
243
  @mock.expects(:get).with("#{Stripe.api_base}/v1/invoices?customer=test_customer&paid=true", nil, nil).returns(response)
160
- invoices.all(:paid => true)
244
+ invoices.list(:paid => true)
161
245
  end
162
246
 
163
247
  should "a 400 should give an InvalidRequestError with http status, body, and JSON body" do
164
- response = test_response(test_missing_id_error, 400)
248
+ response = make_response(make_missing_id_error, 400)
165
249
  @mock.expects(:get).once.raises(RestClient::ExceptionWithResponse.new(response, 404))
166
250
  begin
167
251
  Stripe::Customer.retrieve("foo")
@@ -173,7 +257,7 @@ module Stripe
173
257
  end
174
258
 
175
259
  should "a 401 should give an AuthenticationError with http status, body, and JSON body" do
176
- response = test_response(test_missing_id_error, 401)
260
+ response = make_response(make_missing_id_error, 401)
177
261
  @mock.expects(:get).once.raises(RestClient::ExceptionWithResponse.new(response, 404))
178
262
  begin
179
263
  Stripe::Customer.retrieve("foo")
@@ -185,7 +269,7 @@ module Stripe
185
269
  end
186
270
 
187
271
  should "a 402 should give a CardError with http status, body, and JSON body" do
188
- response = test_response(test_missing_id_error, 402)
272
+ response = make_response(make_missing_id_error, 402)
189
273
  @mock.expects(:get).once.raises(RestClient::ExceptionWithResponse.new(response, 404))
190
274
  begin
191
275
  Stripe::Customer.retrieve("foo")
@@ -197,7 +281,7 @@ module Stripe
197
281
  end
198
282
 
199
283
  should "a 404 should give an InvalidRequestError with http status, body, and JSON body" do
200
- response = test_response(test_missing_id_error, 404)
284
+ response = make_response(make_missing_id_error, 404)
201
285
  @mock.expects(:get).once.raises(RestClient::ExceptionWithResponse.new(response, 404))
202
286
  begin
203
287
  Stripe::Customer.retrieve("foo")
@@ -208,25 +292,37 @@ module Stripe
208
292
  end
209
293
  end
210
294
 
295
+ should "a 429 should give a RateLimitError with http status, body, and JSON body" do
296
+ response = make_response(make_rate_limit_error, 429)
297
+ @mock.expects(:get).once.raises(RestClient::ExceptionWithResponse.new(response, 429))
298
+ begin
299
+ Stripe::Customer.retrieve("foo")
300
+ rescue Stripe::RateLimitError => e
301
+ assert_equal(429, e.http_status)
302
+ assert_equal(true, !!e.http_body)
303
+ assert_equal(true, e.json_body.kind_of?(Hash))
304
+ end
305
+ end
306
+
211
307
  should "setting a nil value for a param should exclude that param from the request" do
212
308
  @mock.expects(:get).with do |url, api_key, params|
213
309
  uri = URI(url)
214
310
  query = CGI.parse(uri.query)
215
311
  (url =~ %r{^#{Stripe.api_base}/v1/charges?} &&
216
312
  query.keys.sort == ['offset', 'sad'])
217
- end.returns(test_response({ :count => 1, :data => [test_charge] }))
218
- Stripe::Charge.all(:count => nil, :offset => 5, :sad => false)
313
+ end.returns(make_response({ :count => 1, :data => [make_charge] }))
314
+ Stripe::Charge.list(:count => nil, :offset => 5, :sad => false)
219
315
 
220
316
  @mock.expects(:post).with do |url, api_key, params|
221
317
  url == "#{Stripe.api_base}/v1/charges" &&
222
318
  api_key.nil? &&
223
319
  CGI.parse(params) == { 'amount' => ['50'], 'currency' => ['usd'] }
224
- end.returns(test_response({ :count => 1, :data => [test_charge] }))
320
+ end.returns(make_response({ :count => 1, :data => [make_charge] }))
225
321
  Stripe::Charge.create(:amount => 50, :currency => 'usd', :card => { :number => nil })
226
322
  end
227
323
 
228
324
  should "requesting with a unicode ID should result in a request" do
229
- response = test_response(test_missing_id_error, 404)
325
+ response = make_response(make_missing_id_error, 404)
230
326
  @mock.expects(:get).once.with("#{Stripe.api_base}/v1/customers/%E2%98%83", nil, nil).raises(RestClient::ExceptionWithResponse.new(response, 404))
231
327
  c = Stripe::Customer.new("☃")
232
328
  assert_raises(Stripe::InvalidRequestError) { c.refresh }
@@ -239,26 +335,27 @@ module Stripe
239
335
 
240
336
  should "making a GET request with parameters should have a query string and no body" do
241
337
  params = { :limit => 1 }
242
- @mock.expects(:get).once.with("#{Stripe.api_base}/v1/charges?limit=1", nil, nil).returns(test_response([test_charge]))
243
- Stripe::Charge.all(params)
338
+ @mock.expects(:get).once.with("#{Stripe.api_base}/v1/charges?limit=1", nil, nil).
339
+ returns(make_response({ :data => [make_charge] }))
340
+ Stripe::Charge.list(params)
244
341
  end
245
342
 
246
343
  should "making a POST request with parameters should have a body and no query string" do
247
344
  params = { :amount => 100, :currency => 'usd', :card => 'sc_token' }
248
345
  @mock.expects(:post).once.with do |url, get, post|
249
346
  get.nil? && CGI.parse(post) == {'amount' => ['100'], 'currency' => ['usd'], 'card' => ['sc_token']}
250
- end.returns(test_response(test_charge))
347
+ end.returns(make_response(make_charge))
251
348
  Stripe::Charge.create(params)
252
349
  end
253
350
 
254
351
  should "loading an object should issue a GET request" do
255
- @mock.expects(:get).once.returns(test_response(test_customer))
352
+ @mock.expects(:get).once.returns(make_response(make_customer))
256
353
  c = Stripe::Customer.new("test_customer")
257
354
  c.refresh
258
355
  end
259
356
 
260
357
  should "using array accessors should be the same as the method interface" do
261
- @mock.expects(:get).once.returns(test_response(test_customer))
358
+ @mock.expects(:get).once.returns(make_response(make_customer))
262
359
  c = Stripe::Customer.new("test_customer")
263
360
  c.refresh
264
361
  assert_equal c.created, c[:created]
@@ -268,7 +365,7 @@ module Stripe
268
365
  end
269
366
 
270
367
  should "accessing a property other than id or parent on an unfetched object should fetch it" do
271
- @mock.expects(:get).once.returns(test_response(test_customer))
368
+ @mock.expects(:get).once.returns(make_response(make_customer))
272
369
  c = Stripe::Customer.new("test_customer")
273
370
  c.charges
274
371
  end
@@ -276,14 +373,14 @@ module Stripe
276
373
  should "updating an object should issue a POST request with only the changed properties" do
277
374
  @mock.expects(:post).with do |url, api_key, params|
278
375
  url == "#{Stripe.api_base}/v1/customers/c_test_customer" && api_key.nil? && CGI.parse(params) == {'description' => ['another_mn']}
279
- end.once.returns(test_response(test_customer))
280
- c = Stripe::Customer.construct_from(test_customer)
376
+ end.once.returns(make_response(make_customer))
377
+ c = Stripe::Customer.construct_from(make_customer)
281
378
  c.description = "another_mn"
282
379
  c.save
283
380
  end
284
381
 
285
382
  should "updating should merge in returned properties" do
286
- @mock.expects(:post).once.returns(test_response(test_customer))
383
+ @mock.expects(:post).once.returns(make_response(make_customer))
287
384
  c = Stripe::Customer.new("c_test_customer")
288
385
  c.description = "another_mn"
289
386
  c.save
@@ -293,9 +390,8 @@ module Stripe
293
390
  should "deleting should send no props and result in an object that has no props other deleted" do
294
391
  @mock.expects(:get).never
295
392
  @mock.expects(:post).never
296
- @mock.expects(:delete).with("#{Stripe.api_base}/v1/customers/c_test_customer", nil, nil).once.returns(test_response({ "id" => "test_customer", "deleted" => true }))
297
-
298
- c = Stripe::Customer.construct_from(test_customer)
393
+ @mock.expects(:delete).with("#{Stripe.api_base}/v1/customers/c_test_customer", nil, nil).once.returns(make_response({ "id" => "test_customer", "deleted" => true }))
394
+ c = Stripe::Customer.construct_from(make_customer)
299
395
  c.delete
300
396
  assert_equal true, c.deleted
301
397
 
@@ -305,23 +401,50 @@ module Stripe
305
401
  end
306
402
 
307
403
  should "loading an object with properties that have specific types should instantiate those classes" do
308
- @mock.expects(:get).once.returns(test_response(test_charge))
404
+ @mock.expects(:get).once.returns(make_response(make_charge))
309
405
  c = Stripe::Charge.retrieve("test_charge")
310
406
  assert c.card.kind_of?(Stripe::StripeObject) && c.card.object == 'card'
311
407
  end
312
408
 
313
409
  should "loading all of an APIResource should return an array of recursively instantiated objects" do
314
- @mock.expects(:get).once.returns(test_response(test_charge_array))
315
- c = Stripe::Charge.all.data
410
+ @mock.expects(:get).once.returns(make_response(make_charge_array))
411
+ c = Stripe::Charge.list.data
316
412
  assert c.kind_of? Array
317
413
  assert c[0].kind_of? Stripe::Charge
318
414
  assert c[0].card.kind_of?(Stripe::StripeObject) && c[0].card.object == 'card'
319
415
  end
320
416
 
417
+ should "passing in a stripe_account header should pass it through on call" do
418
+ Stripe.expects(:execute_request).with do |opts|
419
+ opts[:method] == :get &&
420
+ opts[:url] == "#{Stripe.api_base}/v1/customers/c_test_customer" &&
421
+ opts[:headers][:stripe_account] == 'acct_abc'
422
+ end.once.returns(make_response(make_customer))
423
+ c = Stripe::Customer.retrieve("c_test_customer", {:stripe_account => 'acct_abc'})
424
+ end
425
+
426
+ should "passing in a stripe_account header should pass it through on save" do
427
+ Stripe.expects(:execute_request).with do |opts|
428
+ opts[:method] == :get &&
429
+ opts[:url] == "#{Stripe.api_base}/v1/customers/c_test_customer" &&
430
+ opts[:headers][:stripe_account] == 'acct_abc'
431
+ end.once.returns(make_response(make_customer))
432
+ c = Stripe::Customer.retrieve("c_test_customer", {:stripe_account => 'acct_abc'})
433
+
434
+ Stripe.expects(:execute_request).with do |opts|
435
+ opts[:method] == :post &&
436
+ opts[:url] == "#{Stripe.api_base}/v1/customers/c_test_customer" &&
437
+ opts[:headers][:stripe_account] == 'acct_abc' &&
438
+ opts[:payload] == 'description=FOO'
439
+ end.once.returns(make_response(make_customer))
440
+ c.description = 'FOO'
441
+ c.save
442
+ end
443
+
321
444
  context "error checking" do
322
445
 
323
446
  should "404s should raise an InvalidRequestError" do
324
- response = test_response(test_missing_id_error, 404)
447
+ response = make_response(make_missing_id_error, 404)
325
448
  @mock.expects(:get).once.raises(RestClient::ExceptionWithResponse.new(response, 404))
326
449
 
327
450
  rescued = false
@@ -339,7 +462,7 @@ module Stripe
339
462
  end
340
463
 
341
464
  should "5XXs should raise an APIError" do
342
- response = test_response(test_api_error, 500)
465
+ response = make_response(make_api_error, 500)
343
466
  @mock.expects(:get).once.raises(RestClient::ExceptionWithResponse.new(response, 500))
344
467
 
345
468
  rescued = false
@@ -355,7 +478,7 @@ module Stripe
355
478
  end
356
479
 
357
480
  should "402s should raise a CardError" do
358
- response = test_response(test_invalid_exp_year_error, 402)
481
+ response = make_response(make_invalid_exp_year_error, 402)
359
482
  @mock.expects(:get).once.raises(RestClient::ExceptionWithResponse.new(response, 402))
360
483
 
361
484
  rescued = false
@@ -373,6 +496,167 @@ module Stripe
373
496
  assert_equal true, rescued
374
497
  end
375
498
  end
499
+
500
+ should 'add key to nested objects' do
501
+ acct = Stripe::Account.construct_from({
502
+ :id => 'myid',
503
+ :legal_entity => {
504
+ :size => 'l',
505
+ :score => 4,
506
+ :height => 10
507
+ }
508
+ })
509
+
510
+ @mock.expects(:post).once.with("#{Stripe.api_base}/v1/accounts/myid", nil, 'legal_entity[first_name]=Bob').returns(make_response({"id" => "myid"}))
511
+
512
+ acct.legal_entity.first_name = 'Bob'
513
+ acct.save
514
+ end
515
+
516
+ should 'save nothing if nothing changes' do
517
+ acct = Stripe::Account.construct_from({
518
+ :id => 'myid',
519
+ :metadata => {
520
+ :key => 'value'
521
+ }
522
+ })
523
+
524
+ @mock.expects(:post).once.with("#{Stripe.api_base}/v1/accounts/myid", nil, '').returns(make_response({"id" => "myid"}))
525
+
526
+ acct.save
527
+ end
528
+
529
+ should 'not save nested API resources' do
530
+ ch = Stripe::Charge.construct_from({
531
+ :id => 'charge_id',
532
+ :customer => {
533
+ :object => 'customer',
534
+ :id => 'customer_id'
535
+ }
536
+ })
537
+
538
+ @mock.expects(:post).once.with("#{Stripe.api_base}/v1/charges/charge_id", nil, '').returns(make_response({"id" => "charge_id"}))
539
+
540
+ ch.customer.description = 'Bob'
541
+ ch.save
542
+ end
543
+
544
+ should 'correctly handle replaced nested objects' do
545
+ acct = Stripe::Account.construct_from({
546
+ :id => 'myid',
547
+ :legal_entity => {
548
+ :last_name => 'Smith',
549
+ :address => {
550
+ :line1 => "test",
551
+ :city => "San Francisco"
552
+ }
553
+ }
554
+ })
555
+
556
+ @mock.expects(:post).once.with(
557
+ "#{Stripe.api_base}/v1/accounts/myid",
558
+ nil,
559
+ any_of(
560
+ 'legal_entity[address][line1]=Test2&legal_entity[address][city]=',
561
+ 'legal_entity[address][city]=&legal_entity[address][line1]=Test2'
562
+ )
563
+ ).returns(make_response({"id" => "myid"}))
564
+
565
+ acct.legal_entity.address = {:line1 => 'Test2'}
566
+ acct.save
567
+ end
568
+
569
+ should 'correctly handle array setting' do
570
+ acct = Stripe::Account.construct_from({
571
+ :id => 'myid',
572
+ :legal_entity => {}
573
+ })
574
+
575
+ @mock.expects(:post).once.with("#{Stripe.api_base}/v1/accounts/myid", nil, 'legal_entity[additional_owners][0][first_name]=Bob').returns(make_response({"id" => "myid"}))
576
+
577
+ acct.legal_entity.additional_owners = [{:first_name => 'Bob'}]
578
+ acct.save
579
+ end
580
+
581
+ should 'correctly handle array insertion' do
582
+ acct = Stripe::Account.construct_from({
583
+ :id => 'myid',
584
+ :legal_entity => {
585
+ :additional_owners => []
586
+ }
587
+ })
588
+
589
+ @mock.expects(:post).once.with("#{Stripe.api_base}/v1/accounts/myid", nil, 'legal_entity[additional_owners][0][first_name]=Bob').returns(make_response({"id" => "myid"}))
590
+
591
+ acct.legal_entity.additional_owners << {:first_name => 'Bob'}
592
+ acct.save
593
+ end
594
+
595
+ should 'correctly handle array updates' do
596
+ acct = Stripe::Account.construct_from({
597
+ :id => 'myid',
598
+ :legal_entity => {
599
+ :additional_owners => [{:first_name => 'Bob'}, {:first_name => 'Jane'}]
600
+ }
601
+ })
602
+
603
+ @mock.expects(:post).once.with("#{Stripe.api_base}/v1/accounts/myid", nil, 'legal_entity[additional_owners][1][first_name]=Janet').returns(make_response({"id" => "myid"}))
604
+
605
+ acct.legal_entity.additional_owners[1].first_name = 'Janet'
606
+ acct.save
607
+ end
608
+
609
+ should 'correctly handle array noops' do
610
+ acct = Stripe::Account.construct_from({
611
+ :id => 'myid',
612
+ :legal_entity => {
613
+ :additional_owners => [{:first_name => 'Bob'}]
614
+ },
615
+ :currencies_supported => ['usd', 'cad']
616
+ })
617
+
618
+ @mock.expects(:post).once.with("#{Stripe.api_base}/v1/accounts/myid", nil, '').returns(make_response({"id" => "myid"}))
619
+
620
+ acct.save
621
+ end
622
+
623
+ should 'correctly handle hash noops' do
624
+ acct = Stripe::Account.construct_from({
625
+ :id => 'myid',
626
+ :legal_entity => {
627
+ :address => {:line1 => '1 Two Three'}
628
+ }
629
+ })
630
+
631
+ @mock.expects(:post).once.with("#{Stripe.api_base}/v1/accounts/myid", nil, '').returns(make_response({"id" => "myid"}))
632
+
633
+ acct.save
634
+ end
635
+
636
+ should 'should create a new resource when an object without an id is saved' do
637
+ account = Stripe::Account.construct_from({
638
+ :id => nil,
639
+ :display_name => nil,
640
+ })
641
+
642
+ @mock.expects(:post).once.with("#{Stripe.api_base}/v1/accounts", nil, 'display_name=stripe').
643
+ returns(make_response({"id" => "charge_id"}))
644
+
645
+ account.display_name = 'stripe'
646
+ account.save
647
+ end
648
+
649
+ should 'set attributes as part of save' do
650
+ account = Stripe::Account.construct_from({
651
+ :id => nil,
652
+ :display_name => nil,
653
+ })
654
+
655
+ @mock.expects(:post).once.with("#{Stripe.api_base}/v1/accounts", nil, 'display_name=stripe').
656
+ returns(make_response({"id" => "charge_id"}))
657
+
658
+ account.save(:display_name => 'stripe')
659
+ end
376
660
  end
377
661
  end
378
662
  end
@@ -3,7 +3,7 @@ require File.expand_path('../../test_helper', __FILE__)
3
3
  module Stripe
4
4
  class ApplicationFeeRefundTest < Test::Unit::TestCase
5
5
  should "refunds should be listable" do
6
- @mock.expects(:get).once.returns(test_response(test_application_fee))
6
+ @mock.expects(:get).once.returns(make_response(make_application_fee))
7
7
 
8
8
  application_fee = Stripe::ApplicationFee.retrieve('test_application_fee')
9
9
 
@@ -11,7 +11,7 @@ module Stripe
11
11
  end
12
12
 
13
13
  should "refunds should be refreshable" do
14
- @mock.expects(:get).twice.returns(test_response(test_application_fee), test_response(test_application_fee_refund(:id => 'refreshed_refund')))
14
+ @mock.expects(:get).twice.returns(make_response(make_application_fee), make_response(make_application_fee_refund(:id => 'refreshed_refund')))
15
15
 
16
16
  application_fee = Stripe::ApplicationFee.retrieve('test_application_fee')
17
17
  refund = application_fee.refunds.first
@@ -21,8 +21,8 @@ module Stripe
21
21
  end
22
22
 
23
23
  should "refunds should be updateable" do
24
- @mock.expects(:get).once.returns(test_response(test_application_fee))
25
- @mock.expects(:post).once.returns(test_response(test_application_fee_refund(:metadata => {'key' => 'value'})))
24
+ @mock.expects(:get).once.returns(make_response(make_application_fee))
25
+ @mock.expects(:post).once.returns(make_response(make_application_fee_refund(:metadata => {'key' => 'value'})))
26
26
 
27
27
  application_fee = Stripe::ApplicationFee.retrieve('test_application_fee')
28
28
  refund = application_fee.refunds.first
@@ -36,8 +36,8 @@ module Stripe
36
36
  end
37
37
 
38
38
  should "create should return a new refund" do
39
- @mock.expects(:get).once.returns(test_response(test_application_fee))
40
- @mock.expects(:post).once.returns(test_response(test_application_fee_refund(:id => 'test_new_refund')))
39
+ @mock.expects(:get).once.returns(make_response(make_application_fee))
40
+ @mock.expects(:post).once.returns(make_response(make_application_fee_refund(:id => 'test_new_refund')))
41
41
 
42
42
  application_fee = Stripe::ApplicationFee.retrieve('test_application_fee')
43
43
  refund = application_fee.refunds.create(:amount => 20)
@@ -3,8 +3,8 @@ require File.expand_path('../../test_helper', __FILE__)
3
3
  module Stripe
4
4
  class ApplicationFeeTest < Test::Unit::TestCase
5
5
  should "application fees should be listable" do
6
- @mock.expects(:get).once.returns(test_response(test_application_fee_array))
7
- fees = Stripe::ApplicationFee.all
6
+ @mock.expects(:get).once.returns(make_response(make_application_fee_array))
7
+ fees = Stripe::ApplicationFee.list
8
8
  assert fees.data.kind_of? Array
9
9
  fees.each do |fee|
10
10
  assert fee.kind_of?(Stripe::ApplicationFee)
@@ -13,7 +13,7 @@ module Stripe
13
13
 
14
14
  should "application fees should be refundable" do
15
15
  @mock.expects(:get).never
16
- @mock.expects(:post).once.returns(test_response({:id => "fee_test_fee", :refunded => true}))
16
+ @mock.expects(:post).once.returns(make_response({:id => "fee_test_fee", :refunded => true}))
17
17
  fee = Stripe::ApplicationFee.new("test_application_fee")
18
18
  fee.refund
19
19
  assert fee.refunded
@@ -0,0 +1,11 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ module Stripe
4
+ class BalanceTest < Test::Unit::TestCase
5
+ should "balance should be retrievable" do
6
+ @mock.expects(:get).once.returns(make_response(make_balance))
7
+ balance = Stripe::Balance.retrieve
8
+ assert_equal('balance', balance['object'])
9
+ end
10
+ end
11
+ end