cbraspag 0.9.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.
@@ -0,0 +1,609 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Braspag::Connection do
4
+ let(:merchant_id) { "{12345678-1234-1234-1234-123456789000}" }
5
+ let(:connection) { Braspag::Connection.new(:merchant_id => merchant_id, :environment => :homologation)}
6
+
7
+ context ".authorize" do
8
+ let(:customer) do
9
+ Braspag::Customer.new(:name => "W" * 21)
10
+ end
11
+
12
+ let(:order) do
13
+ Braspag::Order.new(
14
+ :id => "um order id",
15
+ :amount => 1000.00,
16
+ :payment_method => Braspag::PAYMENT_METHOD[:redecard],
17
+ :installments => 1,
18
+ :installments_type => Braspag::INTEREST[:no],
19
+ :customer => customer
20
+ )
21
+ end
22
+
23
+ let(:credit_card) do
24
+ Braspag::CreditCard.new(
25
+ :holder_name => "Joao Maria Souza",
26
+ :number => "9" * 10,
27
+ :month => "10",
28
+ :year => "12",
29
+ :verification_value => "123"
30
+ )
31
+ end
32
+
33
+ let(:valid_xml) do
34
+ <<-EOXML
35
+ <?xml version="1.0" encoding="utf-8"?>
36
+ <PagadorReturn xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
37
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
38
+ xmlns="https://www.pagador.com.br/webservice/pagador">
39
+ <amount>1.000,00</amount>
40
+ <message>Transaction Successful</message>
41
+ <authorisationNumber>733610</authorisationNumber>
42
+ <returnCode>0</returnCode>
43
+ <status>1</status>
44
+ <transactionId>01231234</transactionId>
45
+ </PagadorReturn>
46
+ EOXML
47
+ end
48
+
49
+ let(:invalid_xml) do
50
+ <<-EOXML
51
+ <?xml version="1.0" encoding="utf-8"?>
52
+ <PagadorReturn xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
53
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
54
+ xmlns="https://www.pagador.com.br/webservice/pagador">
55
+ <amount>100</amount>
56
+ <authorisationNumber>null</authorisationNumber>
57
+ <message>Payment Server detected an error</message>
58
+ <returnCode>7</returnCode>
59
+ <status>2</status>
60
+ <transactionId>0</transactionId>
61
+ </PagadorReturn>
62
+ EOXML
63
+ end
64
+
65
+
66
+ it "should call gateway with correct data" do
67
+ Braspag::Poster.any_instance.should_receive(:do_post).with(:authorize, {
68
+ "merchantId" => "#{merchant_id}",
69
+ "orderId" => "#{order.id}",
70
+ "customerName" => "#{customer.name}",
71
+ "amount" => "1000,00",
72
+ "paymentMethod" => 20,
73
+ "holder" => "#{credit_card.holder_name}",
74
+ "cardNumber" => "#{credit_card.number}",
75
+ "expiration" => "10/12",
76
+ "securityCode" => "123",
77
+ "numberPayments" => order.installments,
78
+ "typePayment" => order.installments_type
79
+ }
80
+ ).and_return(mock(:body => valid_xml))
81
+ connection.authorize(order, credit_card)
82
+ end
83
+
84
+ it "should populate data" do
85
+ Braspag::Poster.any_instance.should_receive(:do_post).and_return(mock(:body => valid_xml))
86
+ connection.authorize(order, credit_card)
87
+
88
+ order.gateway_authorization.should eq('733610')
89
+ order.gateway_id.should eq('01231234')
90
+ order.gateway_return_code.should eq('0')
91
+ order.gateway_status.should eq('1')
92
+ order.gateway_message.should eq('Transaction Successful')
93
+ order.gateway_amount.should eq(1000.00)
94
+ end
95
+
96
+ it "should return response object" do
97
+ Braspag::Poster.any_instance.should_receive(:do_post).and_return(mock(:body => valid_xml))
98
+ response = connection.authorize(order, credit_card)
99
+
100
+ response.success?.should be(true)
101
+ response.message.should eq('Transaction Successful')
102
+ end
103
+
104
+ it "should return error in response" do
105
+ Braspag::Poster.any_instance.should_receive(:do_post).and_return(mock(:body => invalid_xml))
106
+ response = connection.authorize(order, credit_card)
107
+
108
+ response.success?.should be(false)
109
+ response.message.should eq('Payment Server detected an error')
110
+ response.params.should eq({"amount"=>"100", "number"=>"null", "message"=>"Payment Server detected an error", "return_code"=>"7", "status"=>"2", "transaction_id"=>"0"})
111
+ end
112
+ end
113
+
114
+ context ".capture" do
115
+ let(:order) do
116
+ Braspag::Order.new(
117
+ :id => "um order id"
118
+ )
119
+ end
120
+
121
+ let(:valid_xml) do
122
+ <<-EOXML
123
+ <?xml version="1.0" encoding="utf-8"?>
124
+ <PagadorReturn xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
125
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
126
+ xmlns="https://www.pagador.com.br/webservice/pagador">
127
+ <amount>2</amount>
128
+ <message>Approved</message>
129
+ <returnCode>0</returnCode>
130
+ <status>0</status>
131
+ </PagadorReturn>
132
+ EOXML
133
+ end
134
+
135
+ let(:invalid_xml) do
136
+ <<-EOXML
137
+ <?xml version="1.0" encoding="utf-8"?>
138
+ <PagadorReturn xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
139
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
140
+ xmlns="https://www.pagador.com.br/webservice/pagador">
141
+ <amount>100</amount>
142
+ <message>Payment Server detected an error</message>
143
+ <returnCode>7</returnCode>
144
+ <status>2</status>
145
+ <transactionId>0</transactionId>
146
+ </PagadorReturn>
147
+ EOXML
148
+ end
149
+
150
+
151
+ it "should call gateway with correct data" do
152
+ Braspag::Poster.any_instance.should_receive(:do_post).with(:capture, {
153
+ "merchantId" => "#{merchant_id}",
154
+ "orderId" => "#{order.id}"
155
+ }
156
+ ).and_return(mock(:body => valid_xml))
157
+ connection.capture(order)
158
+ end
159
+
160
+ it "should populate data" do
161
+ Braspag::Poster.any_instance.should_receive(:do_post).and_return(mock(:body => valid_xml))
162
+ connection.capture(order)
163
+
164
+ order.gateway_capture_return_code.should eq('0')
165
+ order.gateway_capture_status.should eq('0')
166
+ order.gateway_capture_message.should eq('Approved')
167
+ order.gateway_capture_amount.should eq(2.00)
168
+ end
169
+
170
+ it "should return response object" do
171
+ Braspag::Poster.any_instance.should_receive(:do_post).and_return(mock(:body => valid_xml))
172
+ response = connection.capture(order)
173
+
174
+ response.success?.should be(true)
175
+ response.message.should eq('Approved')
176
+ end
177
+
178
+ it "should return error in response" do
179
+ Braspag::Poster.any_instance.should_receive(:do_post).and_return(mock(:body => invalid_xml))
180
+ response = connection.capture(order)
181
+
182
+ response.success?.should be(false)
183
+ response.message.should eq('Payment Server detected an error')
184
+ response.params.should eq({"amount"=>"100", "message"=>"Payment Server detected an error", "return_code"=>"7", "status"=>"2", "transaction_id"=>"0"})
185
+ end
186
+ end
187
+
188
+ context ".void" do
189
+ let(:order) do
190
+ Braspag::Order.new(
191
+ :id => "um order id"
192
+ )
193
+ end
194
+
195
+ let(:valid_xml) do
196
+ <<-EOXML
197
+ <?xml version="1.0" encoding="utf-8"?>
198
+ <PagadorReturn xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
199
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
200
+ xmlns="https://www.pagador.com.br/webservice/pagador">
201
+ <orderId>1234</orderId>
202
+ <transactionId>0</transactionId>
203
+ <amount>100</amount>
204
+ <message>Approved</message>
205
+ <returnCode>0</returnCode>
206
+ <status>0</status>
207
+ </PagadorReturn>
208
+ EOXML
209
+ end
210
+
211
+ let(:invalid_xml) do
212
+ <<-EOXML
213
+ <?xml version="1.0" encoding="utf-8"?>
214
+ <PagadorReturn xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
215
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
216
+ xmlns="https://www.pagador.com.br/webservice/pagador">
217
+ <orderId>1234</orderId>
218
+ <amount>100</amount>
219
+ <message>Payment Server detected an error</message>
220
+ <returnCode>7</returnCode>
221
+ <status>2</status>
222
+ <transactionId>0</transactionId>
223
+ </PagadorReturn>
224
+ EOXML
225
+ end
226
+
227
+
228
+ it "should call gateway with correct data" do
229
+ Braspag::Poster.any_instance.should_receive(:do_post).with(:void, {
230
+ "merchantId" => "#{merchant_id}",
231
+ "orderId" => "#{order.id}"
232
+ }
233
+ ).and_return(mock(:body => valid_xml))
234
+ connection.void(order)
235
+ end
236
+
237
+ it "should populate data" do
238
+ Braspag::Poster.any_instance.should_receive(:do_post).and_return(mock(:body => valid_xml))
239
+ connection.void(order)
240
+
241
+ order.gateway_void_return_code.should eq('0')
242
+ order.gateway_void_status.should eq('0')
243
+ order.gateway_void_message.should eq('Approved')
244
+ order.gateway_void_amount.should eq(100.00)
245
+ end
246
+
247
+ it "should return response object" do
248
+ Braspag::Poster.any_instance.should_receive(:do_post).and_return(mock(:body => valid_xml))
249
+ response = connection.void(order)
250
+
251
+ response.success?.should be(true)
252
+ response.message.should eq('Approved')
253
+ end
254
+
255
+ it "should return error in response" do
256
+ Braspag::Poster.any_instance.should_receive(:do_post).and_return(mock(:body => invalid_xml))
257
+ response = connection.void(order)
258
+
259
+ response.success?.should be(false)
260
+ response.message.should eq('Payment Server detected an error')
261
+ response.params.should eq({"order_id"=>"1234", "amount"=>"100", "message"=>"Payment Server detected an error", "return_code"=>"7", "status"=>"2", "transaction_id"=>"0"})
262
+ end
263
+ end
264
+
265
+ pending ".save" do
266
+ let(:params) do
267
+ {
268
+ :customer_name => "W" * 21,
269
+ :holder => "Joao Maria Souza",
270
+ :card_number => "9" * 10,
271
+ :expiration => "10/12",
272
+ :order_id => "um order id",
273
+ :request_id => "00000000-0000-0000-0000-000000000044"
274
+ }
275
+ end
276
+
277
+ let(:params_with_merchant_id) do
278
+ params.merge!(:merchant_id => merchant_id)
279
+ end
280
+
281
+ let(:save_protected_card_url) { "http://braspag.com/bla" }
282
+
283
+ let(:savon_double) { double('Savon') }
284
+
285
+ before do
286
+ @connection.should_receive(:merchant_id)
287
+ end
288
+
289
+ context "with valid params" do
290
+ let(:valid_hash) do
291
+ {
292
+ :save_credit_card_response => {
293
+ :save_credit_card_result => {
294
+ :just_click_key => 'SAVE-PROTECTED-CARD-TOKEN',
295
+ :success => true
296
+ }
297
+ }
298
+ }
299
+ end
300
+
301
+ let(:response) do
302
+ double('Response', :to_hash => valid_hash)
303
+ end
304
+
305
+ before do
306
+ Braspag::ProtectedCreditCard.should_receive(:save_protected_card_url)
307
+ Braspag::ProtectedCreditCard.should_receive(:check_protected_card_params)
308
+ .and_return(true)
309
+ Savon::Client.should_receive(:new).and_return(savon_double)
310
+ savon_double.should_receive(:request).and_return(response)
311
+
312
+ @response = Braspag::ProtectedCreditCard.save(params)
313
+ end
314
+
315
+ it "should return a Hash" do
316
+ @response.should be_kind_of Hash
317
+ @response.should == {
318
+ :just_click_key => "SAVE-PROTECTED-CARD-TOKEN",
319
+ :success => true
320
+ }
321
+ end
322
+ end
323
+
324
+ context "with invalid params" do
325
+ let(:invalid_hash) do
326
+ {
327
+ :save_credit_card_response => {
328
+ :save_credit_card_result => {
329
+ :just_click_key => nil,
330
+ :success => false
331
+ }
332
+ }
333
+ }
334
+ end
335
+
336
+ let(:response) do
337
+ double('Response', :to_hash => invalid_hash)
338
+ end
339
+
340
+ before do
341
+ Braspag::ProtectedCreditCard.should_receive(:check_protected_card_params)
342
+ .and_return(true)
343
+ Braspag::ProtectedCreditCard.should_receive(:save_protected_card_url)
344
+ .and_return(save_protected_card_url)
345
+ Savon::Client.should_receive(:new).and_return(savon_double)
346
+ savon_double.should_receive(:request).and_return(response)
347
+
348
+ @response = Braspag::ProtectedCreditCard.save(params)
349
+ end
350
+
351
+ it "should return a Hash" do
352
+ @response.should be_kind_of Hash
353
+ @response.should == {
354
+ :just_click_key => nil,
355
+ :success => false
356
+ }
357
+ end
358
+ end
359
+ end
360
+
361
+ pending ".get" do
362
+ let(:get_protected_card_url) { "http://braspag/bla" }
363
+
364
+ let(:invalid_xml) do
365
+ <<-EOXML
366
+ <CartaoProtegidoReturn xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
367
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
368
+ xmlns="http://www.pagador.com.br/">
369
+ <CardHolder>Joao Maria Souza</CardHolder>
370
+ <CardNumber></CardNumber>
371
+ <CardExpiration>10/12</CardExpiration>
372
+ <MaskedCardNumber>******9999</MaskedCardNumber>
373
+ </CartaoProtegidoReturn>
374
+ EOXML
375
+ end
376
+
377
+ let(:valid_xml) do
378
+ <<-EOXML
379
+ <CartaoProtegidoReturn xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
380
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
381
+ xmlns="http://www.pagador.com.br/">
382
+ <CardHolder>Joao Maria Souza</CardHolder>
383
+ <CardNumber>9999999999</CardNumber>
384
+ <CardExpiration>10/12</CardExpiration>
385
+ <MaskedCardNumber>******9999</MaskedCardNumber>
386
+ </CartaoProtegidoReturn>
387
+ EOXML
388
+ end
389
+
390
+ it "should raise an error when just click key is not valid" do
391
+ Braspag::ProtectedCreditCard.should_receive(:valid_just_click_key?)
392
+ .with("bla")
393
+ .and_return(false)
394
+
395
+ expect {
396
+ Braspag::ProtectedCreditCard.get "bla"
397
+ }.to raise_error(Braspag::InvalidJustClickKey)
398
+ end
399
+
400
+ it "should raise an error when Braspag returned an invalid xml as response" do
401
+ FakeWeb.register_uri(:post, get_protected_card_url, :body => invalid_xml)
402
+
403
+ Braspag::ProtectedCreditCard.should_receive(:get_protected_card_url)
404
+ .and_return(get_protected_card_url)
405
+
406
+ expect {
407
+ Braspag::ProtectedCreditCard.get("b0b0b0b0-bbbb-4d4d-bd27-f1f1f1ededed")
408
+ }.to raise_error(Braspag::UnknownError)
409
+ end
410
+
411
+ it "should return a Hash when Braspag returned a valid xml as response" do
412
+ FakeWeb.register_uri(:post, get_protected_card_url, :body => valid_xml)
413
+
414
+ Braspag::ProtectedCreditCard.should_receive(:get_protected_card_url)
415
+ .and_return(get_protected_card_url)
416
+
417
+ response = Braspag::ProtectedCreditCard.get("b0b0b0b0-bbbb-4d4d-bd27-f1f1f1ededed")
418
+ response.should be_kind_of Hash
419
+
420
+ response.should == {
421
+ :holder => "Joao Maria Souza",
422
+ :expiration => "10/12",
423
+ :card_number => "9" * 10,
424
+ :masked_card_number => "*" * 6 + "9" * 4
425
+ }
426
+ end
427
+
428
+ end
429
+
430
+ pending ".just_click_shop" do
431
+ context "body" do
432
+ let(:params) { {
433
+ :request_id => "123",
434
+ :customer_name => "Joao Silva",
435
+ :order_id => "999",
436
+ :amount => 10.50,
437
+ :payment_method => :redecard,
438
+ :number_installments => 3,
439
+ :payment_type => "test",
440
+ :just_click_key => "key",
441
+ :security_code => "123"
442
+ } }
443
+
444
+ class SavonClientTest
445
+ attr_accessor :response
446
+ attr_reader :method
447
+
448
+ def request(web, method, &block)
449
+ @method = method
450
+ instance_eval &block
451
+
452
+ @response
453
+ end
454
+
455
+ def soap
456
+ @soap ||= OpenStruct.new
457
+ end
458
+ end
459
+
460
+ before :each do
461
+ @savon_client_test = SavonClientTest.new
462
+ @savon_client_test.response = {:just_click_shop_response => {}}
463
+ Savon::Client.stub(:new).with('https://www.cartaoprotegido.com.br/Services/TestEnvironment/CartaoProtegido.asmx?wsdl').and_return(@savon_client_test)
464
+ end
465
+
466
+ after :each do
467
+ Savon::Client.unstub(:new)
468
+ end
469
+
470
+ it "should have RequestId" do
471
+ described_class.just_click_shop(params)
472
+ @savon_client_test.soap.body['justClickShopRequestWS']['RequestId'].should eq '123'
473
+ end
474
+
475
+ it "should have MerchantKey" do
476
+ described_class.just_click_shop(params)
477
+ @savon_client_test.soap.body['justClickShopRequestWS']['MerchantKey'].should eq 'um id qualquer'
478
+ end
479
+
480
+ it "should have CustomerName" do
481
+ described_class.just_click_shop(params)
482
+ @savon_client_test.soap.body['justClickShopRequestWS']['CustomerName'].should eq 'Joao Silva'
483
+ end
484
+
485
+ it "should have OrderId" do
486
+ described_class.just_click_shop(params)
487
+ @savon_client_test.soap.body['justClickShopRequestWS']['OrderId'].should eq '999'
488
+ end
489
+
490
+ it "should have Amount" do
491
+ described_class.just_click_shop(params)
492
+ @savon_client_test.soap.body['justClickShopRequestWS']['Amount'].should eq 10.50
493
+ end
494
+
495
+ it "should have PaymentMethod" do
496
+ described_class.just_click_shop(params)
497
+ @savon_client_test.soap.body['justClickShopRequestWS']['PaymentMethod'].should eq 20
498
+ end
499
+
500
+ it "should have PaymentType" do
501
+ described_class.just_click_shop(params)
502
+ @savon_client_test.soap.body['justClickShopRequestWS']['PaymentType'].should eq 'test'
503
+ end
504
+
505
+ it "should have NumberInstallments" do
506
+ described_class.just_click_shop(params)
507
+ @savon_client_test.soap.body['justClickShopRequestWS']['NumberInstallments'].should eq 3
508
+ end
509
+
510
+ it "should have JustClickKey" do
511
+ described_class.just_click_shop(params)
512
+ @savon_client_test.soap.body['justClickShopRequestWS']['JustClickKey'].should eq 'key'
513
+ end
514
+
515
+ it "should have SecurityCode" do
516
+ described_class.just_click_shop(params)
517
+ @savon_client_test.soap.body['justClickShopRequestWS']['SecurityCode'].should eq '123'
518
+ end
519
+ end
520
+ end
521
+ end
522
+
523
+ describe Braspag::CreditCard do
524
+
525
+ [:purchase, :authorize, :archive].each do |context_type|
526
+ context "on #{context_type}" do
527
+ it "should validate minimum 1 length of holder_name" do
528
+ subject.holder_name = ''
529
+ subject.valid?(context_type)
530
+ subject.errors.messages[:holder_name].should include("is too short (minimum is 1 characters)")
531
+ end
532
+
533
+ it "should validate maximum 100 length of holder_name" do
534
+ subject.holder_name = '*' * 110
535
+ subject.valid?(context_type)
536
+ subject.errors.messages[:holder_name].should include("is too long (maximum is 100 characters)")
537
+ end
538
+
539
+ it "should not allow blank for number" do
540
+ subject.number = ''
541
+ subject.valid?(context_type)
542
+ subject.errors.messages[:number].should include("can't be blank")
543
+ end
544
+
545
+ it "should not allow blank for month" do
546
+ subject.month = ''
547
+ subject.valid?(context_type)
548
+ subject.errors.messages[:month].should include("can't be blank")
549
+ end
550
+
551
+ it "should not allow blank for year" do
552
+ subject.year = ''
553
+ subject.valid?(context_type)
554
+ subject.errors.messages[:year].should include("can't be blank")
555
+ end
556
+
557
+ it "should not allow invalid date for month & year" do
558
+ subject.month = "14"
559
+ subject.year = "2012"
560
+ subject.valid?(context_type)
561
+ subject.errors.messages[:month].should include("invalid date")
562
+ subject.errors.messages[:year].should include("invalid date")
563
+ end
564
+
565
+ it "should allow valid date for month & year" do
566
+ subject.month = "09"
567
+ subject.year = "12"
568
+ subject.valid?(context_type)
569
+ subject.errors.messages[:month].should be(nil)
570
+ subject.errors.messages[:year].should be(nil)
571
+ end
572
+
573
+ it "should allow valid date for month & year" do
574
+ subject.month = 12
575
+ subject.year = 2014
576
+ subject.valid?(context_type)
577
+ subject.errors.messages[:month].should be(nil)
578
+ subject.errors.messages[:year].should be(nil)
579
+ end
580
+ end
581
+ end
582
+
583
+ [:purchase, :authorize, :recurrency].each do |context_type|
584
+ context "on #{context_type}" do
585
+ it "should validate minimum 1 length of verification_value" do
586
+ subject.verification_value = ''
587
+ subject.valid?(context_type)
588
+ subject.errors.messages[:verification_value].should include("is too short (minimum is 1 characters)")
589
+ end
590
+
591
+ it "should validate maximum 4 length of verification_value" do
592
+ subject.verification_value = '*' * 5
593
+ subject.valid?(context_type)
594
+ subject.errors.messages[:verification_value].should include("is too long (maximum is 4 characters)")
595
+ end
596
+ end
597
+ end
598
+
599
+ [:get_recurrency, :recurrency].each do |context_type|
600
+ context "on #{context_type}" do
601
+ it "should validate length of id" do
602
+ subject.id = '*' * 37
603
+ subject.valid?(context_type)
604
+ subject.errors.messages[:id].should include("is the wrong length (should be 36 characters)")
605
+ end
606
+ end
607
+ end
608
+
609
+ end