conekta 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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