conekta 0.3.0

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 (43) hide show
  1. data/.gitignore +18 -0
  2. data/CONTRIBUTORS +9 -0
  3. data/Gemfile +2 -0
  4. data/Gemfile.lock +57 -0
  5. data/History.txt +4 -0
  6. data/LICENSE +23 -0
  7. data/README.rdoc +22 -0
  8. data/Rakefile +14 -0
  9. data/VERSION +1 -0
  10. data/bin/conekta-console +7 -0
  11. data/conekta.gemspec +27 -0
  12. data/gemfiles/default-with-activesupport.gemfile +3 -0
  13. data/gemfiles/json.gemfile +4 -0
  14. data/gemfiles/yajl.gemfile +4 -0
  15. data/lib/conekta.rb +292 -0
  16. data/lib/conekta/account.rb +4 -0
  17. data/lib/conekta/api_operations/create.rb +16 -0
  18. data/lib/conekta/api_operations/delete.rb +11 -0
  19. data/lib/conekta/api_operations/list.rb +16 -0
  20. data/lib/conekta/api_operations/update.rb +16 -0
  21. data/lib/conekta/api_resource.rb +33 -0
  22. data/lib/conekta/charge.rb +43 -0
  23. data/lib/conekta/conekta_object.rb +158 -0
  24. data/lib/conekta/errors/api_connection_error.rb +4 -0
  25. data/lib/conekta/errors/api_error.rb +4 -0
  26. data/lib/conekta/errors/authentication_error.rb +4 -0
  27. data/lib/conekta/errors/card_error.rb +11 -0
  28. data/lib/conekta/errors/conekta_error.rb +20 -0
  29. data/lib/conekta/errors/malformed_request_error.rb +10 -0
  30. data/lib/conekta/errors/parameter_validation_error.rb +10 -0
  31. data/lib/conekta/errors/resource_not_found_error.rb +10 -0
  32. data/lib/conekta/event.rb +5 -0
  33. data/lib/conekta/json.rb +21 -0
  34. data/lib/conekta/list_object.rb +35 -0
  35. data/lib/conekta/log.rb +5 -0
  36. data/lib/conekta/singleton_api_resource.rb +20 -0
  37. data/lib/conekta/util.rb +99 -0
  38. data/lib/conekta/version.rb +3 -0
  39. data/lib/data/ca-certificates.crt +3918 -0
  40. data/spec/conekta_spec.rb +743 -0
  41. data/spec/conekta_with_active_support_spec.rb +3 -0
  42. data/spec/test_helper.rb +302 -0
  43. metadata +177 -0
@@ -0,0 +1,743 @@
1
+ # -*- coding: utf-8 -*-
2
+ require File.expand_path('../test_helper', __FILE__)
3
+ #require 'test/unit'
4
+ #require 'shoulda'
5
+ require 'rspec'
6
+ require 'mocha/setup'
7
+ require 'pp'
8
+ require 'rest-client'
9
+ require 'cgi'
10
+ require 'uri'
11
+
12
+ class ConektaTest < Test::Unit::TestCase
13
+ include Mocha
14
+
15
+ describe Conekta::Util, "#symbolize_names" do
16
+ it "symbolize_names should convert names to symbols" do
17
+ start = {
18
+ 'foo' => 'bar',
19
+ 'array' => [{ 'foo' => 'bar' }],
20
+ 'nested' => {
21
+ 1 => 2,
22
+ :symbol => 9,
23
+ 'string' => nil
24
+ }
25
+ }
26
+ finish = {
27
+ :foo => 'bar',
28
+ :array => [{ :foo => 'bar' }],
29
+ :nested => {
30
+ 1 => 2,
31
+ :symbol => 9,
32
+ :string => nil
33
+ }
34
+ }
35
+
36
+ symbolized = Conekta::Util.symbolize_names(start)
37
+ finish.should eq(symbolized)
38
+ end
39
+ end
40
+
41
+ describe Conekta::ConektaObject, "#new" do
42
+
43
+ it "creating a new APIResource should not fetch over the network" do
44
+ @mock = double
45
+ Conekta.mock_rest_client = @mock
46
+ @mock.expects(:get).never
47
+ @mock.expects(:post).never
48
+ c = Conekta::Charge.new("someid")
49
+ Conekta.mock_rest_client = nil
50
+ end
51
+
52
+ it "creating a new APIResource from a hash should not fetch over the network" do
53
+ @mock = double
54
+ Conekta.mock_rest_client = @mock
55
+
56
+ @mock.expects(:get).never
57
+ @mock.expects(:post).never
58
+ c = Conekta::Charge.construct_from({
59
+ id: "somecharge",
60
+ amount: 10000,
61
+ currency: 'MXN',
62
+ card: {
63
+ number: '4242424242424242',
64
+ cvc:'123',
65
+ exp_month:12,
66
+ exp_year:19,
67
+ name:'Sebastian Q.'
68
+ }
69
+ })
70
+
71
+ Conekta.mock_rest_client = nil
72
+ end
73
+
74
+ it "setting an attribute should not cause a network request" do
75
+ @mock = double
76
+ Conekta.mock_rest_client = @mock
77
+
78
+ @mock.expects(:get).never
79
+ @mock.expects(:post).never
80
+ c = Conekta::Charge.new("test_charge");
81
+ c = Conekta::Charge.construct_from({
82
+ id: "somecharge",
83
+ amount: 10000,
84
+ card: {
85
+ number: '4242424242424242',
86
+ cvc:'123',
87
+ exp_month:12,
88
+ exp_year:19,
89
+ name:'Sebastian Q.'
90
+ }
91
+ })
92
+ c.currency = 'MXN'
93
+
94
+ Conekta.mock_rest_client = nil
95
+ end
96
+
97
+ it "accessing id should not issue a fetch" do
98
+ @mock = double
99
+ Conekta.mock_rest_client = @mock
100
+
101
+ @mock.expects(:get).never
102
+ c = Conekta::Charge.new("test_charge");
103
+ c.id
104
+
105
+ Conekta.mock_rest_client = nil
106
+ end
107
+ end
108
+
109
+ describe Conekta, "#api_key" do
110
+ it "not specifying api credentials should raise an exception" do
111
+ Conekta.api_key = nil
112
+ expect{Conekta::Charge.new("test_charge").refresh}.to raise_error(Conekta::AuthenticationError)
113
+ end
114
+
115
+ it "specifying api credentials containing whitespace should raise an exception" do
116
+ Conekta.api_key = "key "
117
+ expect{Conekta::Charge.new("test_charge").refresh}.to raise_error(Conekta::AuthenticationError)
118
+ end
119
+
120
+ it "specifying invalid api credentials should raise an exception" do
121
+ @mock = double
122
+ Conekta.mock_rest_client = @mock
123
+
124
+ Conekta.api_key = "invalid"
125
+ response = test_response(test_invalid_api_key_error, 401)
126
+
127
+ @mock.expects(:get).once.raises(RestClient::ExceptionWithResponse.new(response, 401))
128
+ expect{Conekta::Charge.retrieve("failing_charge")}.to raise_error(Conekta::AuthenticationError)
129
+
130
+ Conekta.mock_rest_client = nil
131
+ end
132
+
133
+ it "AuthenticationErrors should have an http status, http body, and JSON body" do
134
+ @mock = double
135
+ Conekta.mock_rest_client = @mock
136
+
137
+ Conekta.api_key = "invalid"
138
+ response = test_response(test_invalid_api_key_error, 401)
139
+
140
+ begin
141
+ @mock.expects(:get).once.raises(RestClient::ExceptionWithResponse.new(response, 401))
142
+ Conekta::Charge.retrieve("failing_charge")
143
+ rescue Conekta::AuthenticationError => e
144
+ 401.should eq(e.http_status)
145
+ true.should_not eq(e.http_body)
146
+ true.should_not eq(e.json_body[:message])
147
+ test_invalid_api_key_error['message'].should eq(e.json_body[:message])
148
+ end
149
+
150
+ Conekta.mock_rest_client = nil
151
+ end
152
+ end
153
+
154
+ describe Conekta::ConektaObject, "#create" do
155
+
156
+ it "when specifying per-object credentials with no global API key set, use the per-object credential when creating" do
157
+ Conekta.api_key = nil
158
+
159
+ Conekta.should_receive(:execute_request){|opts|
160
+ opts[:headers][:authorization].should eq("Token token='sk_test_local'")
161
+ test_response(test_charge)
162
+ }
163
+
164
+ Conekta::Charge.create({:card => {:number => '4242424242424242'}},
165
+ 'sk_test_local')
166
+ end
167
+
168
+ it "when specifying per-object credentials with global API key set, use the per-object credential when creating" do
169
+ Conekta.api_key = "global"
170
+
171
+ Conekta.should_receive(:execute_request){|opts|
172
+ opts[:headers][:authorization].should eq("Token token='sk_test_local'")
173
+ test_response(test_charge)
174
+ }
175
+
176
+ Conekta::Charge.create({:card => {:number => '4242424242424242'}},
177
+ 'sk_test_local')
178
+ end
179
+
180
+ it "when specifying per-object credentials with a global API key set, use the per-object credential when retrieving and making other calls" do
181
+ Conekta.api_key = "global"
182
+
183
+ Conekta.should_receive(:execute_request){|opts|
184
+ opts[:url].should eq("#{Conekta.api_base}/charges/ch_test_charge.json")
185
+ opts[:headers][:authorization].should eq("Token token='sk_test_local'")
186
+ test_response(test_charge)
187
+ }
188
+ Conekta.should_receive(:execute_request){|opts|
189
+ opts[:url].should eq("#{Conekta.api_base}/charges/ch_test_charge/refund.json")
190
+ opts[:headers][:authorization].should eq("Token token='sk_test_local'")
191
+ test_response(test_charge)
192
+ }
193
+
194
+ ch = Conekta::Charge.retrieve('ch_test_charge', 'sk_test_local')
195
+ ch.refund
196
+ end
197
+ end
198
+
199
+ describe Conekta, "#execute_request" do
200
+ it "with valid credential, urlencode values in GET params" do
201
+ @mock = double
202
+ Conekta.mock_rest_client = @mock
203
+
204
+ Conekta.api_key = 'foo'
205
+ response = test_response(test_charge_array)
206
+ @mock.should_receive(:get){|arg1, arg2, arg3|
207
+
208
+ arg1.should eq("#{Conekta.api_base}/charges.json?amount=500")
209
+ arg2.should eq(nil)
210
+ arg3.should eq(nil)
211
+ response
212
+ }
213
+ charges = Conekta::Charge.all(amount: 500).data
214
+ charges.should be_kind_of(Array)
215
+
216
+ Conekta.mock_rest_client = nil
217
+ end
218
+
219
+ it "with valid credential, construct URL properly with base query parameters" do
220
+ @mock = double
221
+ Conekta.mock_rest_client = @mock
222
+
223
+ response = test_response(test_charge_array)
224
+
225
+ Conekta.api_key = 'foo'
226
+ response = test_response(test_charge_array_filtered)
227
+ @mock.should_receive(:get){|arg1, arg2, arg3|
228
+ arg1.should eq("#{Conekta.api_base}/charges.json?amount=500")
229
+ arg2.should eq(nil)
230
+ arg3.should eq(nil)
231
+ response
232
+ }
233
+ charges = Conekta::Charge.all(amount: 500)
234
+
235
+ response = test_response(test_charge_array_filtered)
236
+ @mock.should_receive(:get){|arg1, arg2, arg3|
237
+ arg1.should eq("#{Conekta.api_base}/charges.json?amount=500&status=paid")
238
+ arg2.should eq(nil)
239
+ arg3.should eq(nil)
240
+ response
241
+ }
242
+ charges.all(:status=>'paid')
243
+
244
+ Conekta.mock_rest_client = nil
245
+ end
246
+
247
+ it "with valid credential, a 401 should give an AuthenticationError with http status, body, and JSON body" do
248
+ @mock = double
249
+ Conekta.mock_rest_client = @mock
250
+
251
+ response = test_response(test_missing_id_error, 401)
252
+ @mock.should_receive(:get){|args|
253
+ raise RestClient::ExceptionWithResponse.new(response, 401)
254
+ }.once
255
+
256
+ begin
257
+ Conekta::Charge.retrieve("foo")
258
+ rescue Conekta::AuthenticationError => e
259
+ e.http_status.should eq(401)
260
+ e.http_body.should_not eq(true)
261
+ e.json_body.should be_kind_of(Hash)
262
+ end
263
+
264
+ Conekta.mock_rest_client = nil
265
+ end
266
+
267
+ it "with valid credential, a 402 should give an CardError with http status, body, and JSON body" do
268
+ @mock = double
269
+ Conekta.mock_rest_client = @mock
270
+
271
+ response = test_response(test_missing_id_error, 402)
272
+ @mock.should_receive(:post){|args|
273
+ raise RestClient::ExceptionWithResponse.new(response, 402)
274
+ }.once
275
+
276
+ begin
277
+ Conekta::Charge.create({
278
+ amount:10000,
279
+ description:'Test',
280
+ card: {
281
+ name:'Leo Fischer',
282
+ number:4000000000000119,
283
+ cvc:123,
284
+ exp_month:8,
285
+ exp_year:19
286
+ }
287
+ })
288
+
289
+ rescue Conekta::CardError => e
290
+ e.http_status.should eq(402)
291
+ e.http_body.should_not eq(true)
292
+ e.json_body.should be_kind_of(Hash)
293
+ end
294
+
295
+ Conekta.mock_rest_client = nil
296
+ end
297
+
298
+ it "with valid credential, a 404 should give an ResourceNotFoundError with http status, body, and JSON body" do
299
+ @mock = double
300
+ Conekta.mock_rest_client = @mock
301
+
302
+ response = test_response(test_missing_id_error, 404)
303
+ @mock.should_receive(:get){|args|
304
+ raise RestClient::ExceptionWithResponse.new(response, 404)
305
+ }.once
306
+
307
+ begin
308
+ Conekta::Charge.retrieve("foo")
309
+ rescue Conekta::ResourceNotFoundError => e
310
+ e.http_status.should eq(404)
311
+ e.http_body.should_not eq(true)
312
+ e.json_body.should be_kind_of(Hash)
313
+ end
314
+
315
+ Conekta.mock_rest_client = nil
316
+ end
317
+
318
+ it "with valid credential, a 422 should give an ParameterValidationError with http status, body, and JSON body" do
319
+ @mock = double
320
+ Conekta.mock_rest_client = @mock
321
+
322
+ response = test_response(test_missing_id_error, 422)
323
+ @mock.should_receive(:post){|args|
324
+ raise RestClient::ExceptionWithResponse.new(response, 422)
325
+ }.once
326
+
327
+ begin
328
+ Conekta::Charge.create({amount:-10000})
329
+ rescue Conekta::ParameterValidationError => e
330
+ e.http_status.should eq(422)
331
+ e.http_body.should_not eq(true)
332
+ e.json_body.should be_kind_of(Hash)
333
+ end
334
+
335
+ Conekta.mock_rest_client = nil
336
+ end
337
+
338
+ it "with valid credential, setting a nil value for a param should exclude that param from the request" do
339
+ @mock = double
340
+ Conekta.mock_rest_client = @mock
341
+
342
+ @mock.should_receive(:get){|url, api_key, params|
343
+ uri = URI(url)
344
+ query = CGI.parse(uri.query)
345
+ url.should match(%r{^#{Conekta.api_base}/charges?})
346
+ query.keys.sort.should eq(['offset', 'sad'])
347
+
348
+ test_response({ :count => 1, :data => [test_charge] })
349
+ }
350
+ c = Conekta::Charge.all(:count => nil, :offset => 5, :sad => false)
351
+
352
+ @mock.should_receive(:post){|url, api_key, params|
353
+ "#{Conekta.api_base}/charges.json".should eq(url)
354
+ api_key.should eq(nil)
355
+ {:amount => 50, :currency=>'usd', :card=>{}}.should eq(params)
356
+
357
+ test_response({ :count => 1, :data => [test_charge] })
358
+ }
359
+ c = Conekta::Charge.create(:amount => 50, :currency => 'usd', :card => { :number => nil })
360
+ Conekta.mock_rest_client = nil
361
+ end
362
+
363
+ it "requesting with a unicode ID should result in a request" do
364
+ @mock = double
365
+ Conekta.mock_rest_client = @mock
366
+
367
+ response = test_response(test_missing_id_error, 400)
368
+ @mock.should_receive(:get){|arg1, arg2, arg3|
369
+ arg1.should eq("#{Conekta.api_base}/charges/%E2%98%83.json")
370
+ arg2.should eq(nil)
371
+ arg3.should eq(nil)
372
+ raise RestClient::ExceptionWithResponse.new(response, 400)
373
+ }.once
374
+ c = Conekta::Charge.new("☃")
375
+ expect{c.refresh}.to raise_error(Conekta::MalformedRequestError)
376
+
377
+ Conekta.mock_rest_client = nil
378
+ end
379
+
380
+ it "requesting with no ID should result in an ParameterValidationError with no request" do
381
+ c = Conekta::Charge.new
382
+ expect{c.refresh}.to raise_error(Conekta::ParameterValidationError)
383
+ end
384
+
385
+ it "making a GET request with parameters should have a query string and no body" do
386
+ @mock = double
387
+ Conekta.mock_rest_client = @mock
388
+
389
+ params = { :limit => 1 }
390
+ @mock.should_receive(:get){|arg1, arg2, arg3|
391
+ arg1.should eq("#{Conekta.api_base}/charges.json?limit=1")
392
+ arg2.should eq(nil)
393
+ arg3.should eq(nil)
394
+ test_response([test_charge])
395
+ }.once
396
+ c = Conekta::Charge.all(params)
397
+
398
+ Conekta.mock_rest_client = nil
399
+ end
400
+
401
+ it "making a POST request with parameters should have a body and no query string" do
402
+ @mock = double
403
+ Conekta.mock_rest_client = @mock
404
+
405
+ params = { :amount => 100, :currency => 'usd', :card => 'sc_token' }
406
+ @mock.should_receive(:post){|url, get, post|
407
+ get.should eq(nil)
408
+ post.should eq({:amount => 100, :currency => 'usd', :card => 'sc_token'})
409
+ test_response(test_charge)
410
+ }
411
+ c = Conekta::Charge.create(params)
412
+
413
+ Conekta.mock_rest_client = nil
414
+ end
415
+
416
+ it "loading an object should issue a GET request" do
417
+ @mock = double
418
+ Conekta.mock_rest_client = @mock
419
+
420
+ @mock.should_receive(:get){|arg1, arg2, arg3|
421
+ test_response(test_charge)
422
+ }.once
423
+ c = Conekta::Charge.new("test_charge")
424
+ c.refresh
425
+
426
+ Conekta.mock_rest_client = nil
427
+ end
428
+
429
+ it "using array accessors should be the same as the method interface" do
430
+ @mock = double
431
+ Conekta.mock_rest_client = @mock
432
+
433
+ @mock.should_receive(:get){|arg1, arg2, arg3|
434
+ test_response(test_charge)
435
+ }.once
436
+ c = Conekta::Charge.new("test_charge")
437
+ c.refresh
438
+ c.created.should eq(c[:created])
439
+ c.created.should eq(c['created'])
440
+ c['created'] = 12345
441
+ c.created.should eq(12345)
442
+
443
+ Conekta.mock_rest_client = nil
444
+ end
445
+
446
+ # it "accessing a property other than id or parent on an unfetched object should fetch it" do
447
+ # @mock = double
448
+ # Conekta.mock_rest_client = @mock
449
+ #
450
+ # @mock.should_receive(:get){
451
+ # test_response(test_charge)
452
+ # }.once
453
+ # c = Conekta::Charge.new("test_charge")
454
+ # c.card
455
+ #
456
+ # Conekta.mock_rest_client = nil
457
+ # end
458
+
459
+ it "updating an object should issue a POST request with only the changed properties" do
460
+ @mock = double
461
+ Conekta.mock_rest_client = @mock
462
+
463
+ @mock.should_receive(:post){|url, api_key, params|
464
+ url.should eq("#{Conekta.api_base}/charges/ch_test_charge.json")
465
+ api_key.should eq(nil)
466
+ params.should eq({:mnemonic => 'another_mn'})
467
+ test_response(test_charge)
468
+ }.once
469
+ c = Conekta::Charge.construct_from(test_charge)
470
+ c.mnemonic = "another_mn"
471
+ c.save
472
+
473
+ Conekta.mock_rest_client = nil
474
+ end
475
+
476
+ it "updating should merge in returned properties" do
477
+ @mock = double
478
+ Conekta.mock_rest_client = @mock
479
+
480
+ @mock = double
481
+ Conekta.mock_rest_client = @mock
482
+
483
+ @mock.should_receive(:post){
484
+ test_response(test_charge)
485
+ }.once
486
+ c = Conekta::Charge.new("c_test_charge")
487
+ c.mnemonic = "another_mn"
488
+ c.save
489
+ c.livemode.should eq(false)
490
+
491
+ Conekta.mock_rest_client = nil
492
+ end
493
+
494
+ # it "deleting should send no props and result in an object that has no props other deleted" do
495
+ # @mock = double
496
+ # Conekta.mock_rest_client = @mock
497
+ #
498
+ # @mock.expects(:get).never
499
+ # @mock.expects(:post).never
500
+ # @mock.should_receive(:delete){|arg1, arg2, arg3|
501
+ # arg1.should eq("#{Conekta.api_base}/v1/charges/ch_test_charge")
502
+ # arg2.should eq(nil)
503
+ # arg3.should eq(nil)
504
+ #
505
+ # test_response({ "id" => "test_charge", "deleted" => true })
506
+ # }.once
507
+ #
508
+ # c = Conekta::Customer.construct_from(test_charge)
509
+ # c.delete
510
+ # c.deleted.should eq(true)
511
+ #
512
+ # c.livemode.to raise_error(NoMethodError)
513
+ # end
514
+
515
+ it "loading an object with properties that have specific types should instantiate those classes" do
516
+ @mock = double
517
+ Conekta.mock_rest_client = @mock
518
+
519
+ @mock.should_receive(:get){
520
+ test_response(test_charge)
521
+ }.once
522
+
523
+ c = Conekta::Charge.retrieve("test_charge")
524
+ c.card.should be_kind_of(Conekta::ConektaObject)
525
+ #c.card.object == 'card'
526
+
527
+ Conekta.mock_rest_client = nil
528
+ end
529
+
530
+ it "loading all of an APIResource should return an array of recursively instantiated objects" do
531
+ @mock = double
532
+ Conekta.mock_rest_client = @mock
533
+
534
+ @mock.should_receive(:get){
535
+ test_response(test_charge_array)
536
+ }.once
537
+ c = Conekta::Charge.all
538
+ c = c.data
539
+ c.should be_kind_of(Array)
540
+ c[0].should be_kind_of(Conekta::Charge)
541
+ c[0].card.should be_kind_of(Conekta::ConektaObject)
542
+ #c[0].card.object == 'card'
543
+
544
+ Conekta.mock_rest_client = nil
545
+ end
546
+ end
547
+
548
+ describe Conekta::Account, "#retrieve" do
549
+ it "account should be retrievable" do
550
+ @mock = double
551
+ Conekta.mock_rest_client = @mock
552
+
553
+ resp = {:email => "test+bindings@conekta.com", :charge_enabled => false, :details_submitted => false}
554
+ @mock.should_receive(:get){test_response(resp)}.once
555
+ a = Conekta::Account.retrieve
556
+ "test+bindings@conekta.com".should eq(a.email)
557
+ a.charge_enabled.should eq(false)
558
+ a.details_submitted.should eq(false)
559
+
560
+ Conekta.mock_rest_client = nil
561
+ end
562
+ end
563
+
564
+ describe Conekta::ListObject, "#all" do
565
+ it "be able to retrieve full lists given a listobject" do
566
+ @mock = double
567
+ Conekta.mock_rest_client = @mock
568
+
569
+ @mock.should_receive(:get){
570
+ test_response(test_charge_array)
571
+ }.twice
572
+
573
+ c = Conekta::Charge.all
574
+ c.should be_kind_of(Conekta::ListObject)
575
+ '/charges'.should eq(c.url)
576
+ all = c.all
577
+ all.should be_kind_of(Conekta::ListObject)
578
+ '/charges'.should eq(all.url)
579
+ all.data.should be_kind_of(Array)
580
+
581
+ Conekta.mock_rest_client = nil
582
+ end
583
+ end
584
+
585
+
586
+ describe "charge tests" do
587
+ it "charges should be listable" do
588
+ @mock = double
589
+ Conekta.mock_rest_client = @mock
590
+
591
+ @mock.should_receive(:get){
592
+ test_response(test_charge_array)
593
+ }.once
594
+ c = Conekta::Charge.all
595
+ c.data.should be_kind_of(Array)
596
+ c.each do |charge|
597
+ charge.should be_kind_of(Conekta::Charge)
598
+ end
599
+
600
+ Conekta.mock_rest_client = nil
601
+ end
602
+
603
+ it "charges should be refundable" do
604
+ @mock = double
605
+ Conekta.mock_rest_client = @mock
606
+
607
+ @mock.expects(:get).never
608
+ @mock.should_receive(:post){test_response({:id => "ch_test_charge", :refunded => true})}.once
609
+ c = Conekta::Charge.new("test_charge")
610
+ c.refund
611
+ c.refunded.should eq(true)
612
+
613
+ Conekta.mock_rest_client = nil
614
+ end
615
+
616
+ it "charges should not be deletable" do
617
+ @mock = double
618
+ Conekta.mock_rest_client = @mock
619
+
620
+ @mock.should_receive(:get){test_response(test_charge)}.once
621
+ c = Conekta::Charge.retrieve("test_charge")
622
+ expect{c.delete}.to raise_error(NoMethodError)
623
+
624
+ Conekta.mock_rest_client = nil
625
+ end
626
+
627
+
628
+ it "charges should be updateable" do
629
+ @mock = double
630
+ Conekta.mock_rest_client = @mock
631
+
632
+ @mock.should_receive(:get){test_response(test_charge)}.once
633
+ @mock.should_receive(:post){test_response(test_charge)}.once
634
+ c = Conekta::Charge.new("test_charge")
635
+ c.refresh
636
+ c.mnemonic = "New charge description"
637
+ c.save
638
+
639
+ Conekta.mock_rest_client = nil
640
+ end
641
+
642
+ it "charges should have Card objects associated with their Card property" do
643
+ @mock = double
644
+ Conekta.mock_rest_client = @mock
645
+
646
+ @mock.should_receive(:get){test_response(test_charge)}.once
647
+ c = Conekta::Charge.retrieve("test_charge")
648
+ c.card.should be_kind_of(Conekta::ConektaObject)
649
+ #&& c.card.object == 'card'
650
+
651
+ Conekta.mock_rest_client = nil
652
+ end
653
+
654
+ it "execute should return a new, fully executed charge when passed correct parameters" do
655
+ @mock = double
656
+ Conekta.mock_rest_client = @mock
657
+
658
+ @mock.should_receive(:post){|url, api_key, params|
659
+ url.should eq("#{Conekta.api_base}/charges.json")
660
+ api_key.should eq(nil)
661
+ params.should eq({
662
+ :currency => 'usd',
663
+ :amount => 100,
664
+ :card=>{
665
+ :number => '4242424242424242',
666
+ :exp_month => 11,
667
+ :exp_year => 2012
668
+ }
669
+ })
670
+
671
+ test_response(test_charge)
672
+ }.once
673
+
674
+ c = Conekta::Charge.create({
675
+ :amount => 100,
676
+ :card => {
677
+ :number => "4242424242424242",
678
+ :exp_month => 11,
679
+ :exp_year => 2012,
680
+ },
681
+ :currency => "usd"
682
+ })
683
+ c.paid.should eq(true)
684
+
685
+ Conekta.mock_rest_client = nil
686
+ end
687
+ end
688
+
689
+ describe Conekta::ConektaError do
690
+ it "404s should raise an ResourceNotFoundError" do
691
+ @mock = double
692
+ Conekta.mock_rest_client = @mock
693
+
694
+ response = test_response(test_missing_id_error, 404)
695
+ @mock.should_receive(:get){raise RestClient::ExceptionWithResponse.new(response, 404)}.once
696
+
697
+ begin
698
+ Conekta::Charge.new("test_charge").refresh
699
+ rescue Conekta::ResourceNotFoundError => e # we don't use assert_raises because we want to examine e
700
+ e.should be_kind_of(Conekta::ResourceNotFoundError)
701
+ "id".should eq(e.param)
702
+ "Invalid id value".should eq(e.message)
703
+ end
704
+
705
+ Conekta.mock_rest_client = nil
706
+ end
707
+
708
+ it "5XXs should raise an APIError" do
709
+ @mock = double
710
+ Conekta.mock_rest_client = @mock
711
+
712
+ response = test_response(test_api_error, 500)
713
+ @mock.should_receive(:get){raise RestClient::ExceptionWithResponse.new(response, 500)}.once
714
+
715
+ begin
716
+ Conekta::Charge.new("test_charge").refresh
717
+ rescue Conekta::APIError => e # we don't use assert_raises because we want to examine e
718
+ e.should be_kind_of(Conekta::APIError)
719
+ end
720
+
721
+ Conekta.mock_rest_client = nil
722
+ end
723
+
724
+ it "402s should raise a CardError" do
725
+ @mock = double
726
+ Conekta.mock_rest_client = @mock
727
+
728
+ response = test_response(test_invalid_exp_year_error, 402)
729
+ @mock.should_receive(:get){raise RestClient::ExceptionWithResponse.new(response, 402)}.once
730
+
731
+ begin
732
+ Conekta::Charge.new("test_charge").refresh
733
+ rescue Conekta::CardError => e # we don't use assert_raises because we want to examine e
734
+ e.should be_kind_of(Conekta::CardError)
735
+ "invalid_expiry_year".should eq(e.code)
736
+ "exp_year".should eq(e.param)
737
+ "Your card's expiration year is invalid".should eq(e.message)
738
+ end
739
+
740
+ Conekta.mock_rest_client = nil
741
+ end
742
+ end
743
+ end