braspag-pagador 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +1 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.md +23 -0
  6. data/README.md +532 -0
  7. data/RELEASES.md +20 -0
  8. data/Rakefile +6 -0
  9. data/braspag-pagador.gemspec +32 -0
  10. data/coverage/.resultset.json +2732 -0
  11. data/coverage/assets/0.5.3/app.js +88 -0
  12. data/coverage/assets/0.5.3/fancybox/blank.gif +0 -0
  13. data/coverage/assets/0.5.3/fancybox/fancy_close.png +0 -0
  14. data/coverage/assets/0.5.3/fancybox/fancy_loading.png +0 -0
  15. data/coverage/assets/0.5.3/fancybox/fancy_nav_left.png +0 -0
  16. data/coverage/assets/0.5.3/fancybox/fancy_nav_right.png +0 -0
  17. data/coverage/assets/0.5.3/fancybox/fancy_shadow_e.png +0 -0
  18. data/coverage/assets/0.5.3/fancybox/fancy_shadow_n.png +0 -0
  19. data/coverage/assets/0.5.3/fancybox/fancy_shadow_ne.png +0 -0
  20. data/coverage/assets/0.5.3/fancybox/fancy_shadow_nw.png +0 -0
  21. data/coverage/assets/0.5.3/fancybox/fancy_shadow_s.png +0 -0
  22. data/coverage/assets/0.5.3/fancybox/fancy_shadow_se.png +0 -0
  23. data/coverage/assets/0.5.3/fancybox/fancy_shadow_sw.png +0 -0
  24. data/coverage/assets/0.5.3/fancybox/fancy_shadow_w.png +0 -0
  25. data/coverage/assets/0.5.3/fancybox/fancy_title_left.png +0 -0
  26. data/coverage/assets/0.5.3/fancybox/fancy_title_main.png +0 -0
  27. data/coverage/assets/0.5.3/fancybox/fancy_title_over.png +0 -0
  28. data/coverage/assets/0.5.3/fancybox/fancy_title_right.png +0 -0
  29. data/coverage/assets/0.5.3/fancybox/fancybox-x.png +0 -0
  30. data/coverage/assets/0.5.3/fancybox/fancybox-y.png +0 -0
  31. data/coverage/assets/0.5.3/fancybox/fancybox.png +0 -0
  32. data/coverage/assets/0.5.3/fancybox/jquery.fancybox-1.3.1.css +363 -0
  33. data/coverage/assets/0.5.3/fancybox/jquery.fancybox-1.3.1.pack.js +44 -0
  34. data/coverage/assets/0.5.3/favicon_green.png +0 -0
  35. data/coverage/assets/0.5.3/favicon_red.png +0 -0
  36. data/coverage/assets/0.5.3/favicon_yellow.png +0 -0
  37. data/coverage/assets/0.5.3/highlight.css +129 -0
  38. data/coverage/assets/0.5.3/highlight.pack.js +1 -0
  39. data/coverage/assets/0.5.3/jquery-1.6.2.min.js +18 -0
  40. data/coverage/assets/0.5.3/jquery.dataTables.min.js +152 -0
  41. data/coverage/assets/0.5.3/jquery.timeago.js +141 -0
  42. data/coverage/assets/0.5.3/jquery.url.js +174 -0
  43. data/coverage/assets/0.5.3/loading.gif +0 -0
  44. data/coverage/assets/0.5.3/magnify.png +0 -0
  45. data/coverage/assets/0.5.3/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  46. data/coverage/assets/0.5.3/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  47. data/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  48. data/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  49. data/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  50. data/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  51. data/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  52. data/coverage/assets/0.5.3/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  53. data/coverage/assets/0.5.3/smoothness/images/ui-icons_222222_256x240.png +0 -0
  54. data/coverage/assets/0.5.3/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  55. data/coverage/assets/0.5.3/smoothness/images/ui-icons_454545_256x240.png +0 -0
  56. data/coverage/assets/0.5.3/smoothness/images/ui-icons_888888_256x240.png +0 -0
  57. data/coverage/assets/0.5.3/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  58. data/coverage/assets/0.5.3/smoothness/jquery-ui-1.8.4.custom.css +295 -0
  59. data/coverage/assets/0.5.3/stylesheet.css +383 -0
  60. data/coverage/index.html +17219 -0
  61. data/lib/braspag.rb +96 -0
  62. data/lib/braspag/core/connection.rb +112 -0
  63. data/lib/braspag/core/converter.rb +63 -0
  64. data/lib/braspag/core/customer.rb +13 -0
  65. data/lib/braspag/core/order.rb +286 -0
  66. data/lib/braspag/core/poster.rb +40 -0
  67. data/lib/braspag/crypto/no_crypto.rb +6 -0
  68. data/lib/braspag/crypto/webservice.rb +63 -0
  69. data/lib/braspag/payment/billet.rb +79 -0
  70. data/lib/braspag/payment/credit_card.rb +190 -0
  71. data/lib/braspag/payment/eft.rb +65 -0
  72. data/lib/braspag/payment/recurrency_credit_card.rb +15 -0
  73. data/lib/braspag/templates/crypto/decrypt.xml.erb +10 -0
  74. data/lib/braspag/templates/crypto/encrypt.xml.erb +14 -0
  75. data/lib/braspag/templates/justclick/archive.xml.erb +16 -0
  76. data/lib/braspag/templates/justclick/get_recurrency.xml.erb +12 -0
  77. data/lib/braspag/templates/justclick/recurrency.xml.erb +23 -0
  78. data/lib/braspag/version.rb +3 -0
  79. data/spec/core/connection_spec.rb +149 -0
  80. data/spec/core/converter_spec.rb +123 -0
  81. data/spec/core/customer_spec.rb +49 -0
  82. data/spec/core/order_spec.rb +504 -0
  83. data/spec/core/poster_spec.rb +63 -0
  84. data/spec/crypto/webservice_spec.rb +136 -0
  85. data/spec/integration/billet_spec.rb +38 -0
  86. data/spec/integration/credit_card_spec.rb +0 -0
  87. data/spec/payment/billet_spec.rb +205 -0
  88. data/spec/payment/credit_card_spec.rb +385 -0
  89. data/spec/payment/eft_spec.rb +88 -0
  90. data/spec/payment/recurrency_credit_card_spec.rb +100 -0
  91. data/spec/spec_helper.rb +24 -0
  92. metadata +292 -0
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+ require 'ostruct'
3
+
4
+ describe Braspag::Poster do
5
+ let(:request) { OpenStruct.new(:url => 'http://foo/bar') }
6
+ let(:response) { mock(:body => 'success') }
7
+ let(:logger) { mock(:info => nil) }
8
+ let(:merchant_id) { "{12345678-1234-1234-1234-123456789000}" }
9
+ let(:connection) { Braspag::Connection.new(:merchant_id => merchant_id, :environment => :homologation)}
10
+ let(:connection_logger) { Braspag::Connection.new(:merchant_id => merchant_id, :environment => :homologation, :logger => logger)}
11
+ let(:connection_proxy) { Braspag::Connection.new(:merchant_id => merchant_id, :environment => :homologation, :proxy_address => 'http://proxy.com')}
12
+
13
+ describe "#do_post" do
14
+ before do
15
+ ::HTTPI::Request.should_receive(:new).with('http://foo/bar').and_return(request)
16
+ ::HTTPI.should_receive(:post).with(request).and_return(response)
17
+ end
18
+
19
+ context "without proxy and logger" do
20
+ subject { described_class.new(connection, 'http://foo/bar') }
21
+
22
+ it "should not set the proxy if the proxy_address is not set" do
23
+ request.should_not_receive(:proxy=)
24
+ subject.do_post(:foo, {})
25
+ end
26
+
27
+ it "should not raise an error if logger is not defined" do
28
+ expect {
29
+ subject.do_post(:doe, { :foo => :bar, :egg => :span })
30
+ }.to_not raise_error
31
+ end
32
+
33
+ end
34
+
35
+ context "with logger" do
36
+ subject { described_class.new(connection_logger, 'http://foo/bar') }
37
+
38
+ it "should log the request info" do
39
+ logger.should_receive(:info).with('[Braspag] #doe: http://foo/bar, data: {:foo=>:bar, :egg=>:span}')
40
+ subject.do_post(:doe, { :foo => :bar, :egg => :span })
41
+ end
42
+
43
+ it "should log the request info removing the credit card sensitive info" do
44
+ logger.should_receive(:info).with('[Braspag] #doe: http://foo/bar, data: {"cardNumber"=>"************", "securityCode"=>"***"}')
45
+ subject.do_post(:doe, { 'cardNumber' => '123', 'securityCode' => '456' })
46
+ end
47
+
48
+ it "should log response info" do
49
+ logger.should_receive(:info).with('[Braspag] #doe: http://foo/bar, data: {:foo=>:bar, :egg=>:span}')
50
+ subject.do_post(:doe, { :foo => :bar, :egg => :span })
51
+ end
52
+ end
53
+
54
+ context "with proxy" do
55
+ subject { described_class.new(connection_proxy, 'http://foo/bar') }
56
+
57
+ it "should set the proxy if the proxy_address is set" do
58
+ request.should_receive(:proxy=).with('http://proxy.com')
59
+ subject.do_post(:foo, {})
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,136 @@
1
+ #encoding: utf-8
2
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
3
+
4
+ describe Braspag::Crypto::Webservice do
5
+
6
+ let(:merchant_id) { "merchant_id" }
7
+ let(:connection) do
8
+ conn = double(Braspag::Connection)
9
+ conn.stub(:merchant_id => merchant_id)
10
+ conn.stub(:url_for => 'fakeurl')
11
+ conn
12
+ end
13
+
14
+ let(:poster) { mock }
15
+
16
+ describe "encrypt" do
17
+ let(:key) {"XXXXX"}
18
+
19
+ it "should return error with invalid data after process" do
20
+ body_invalid = <<-EOXML
21
+ SERVER was unable to process
22
+ EOXML
23
+ poster.stub(:do_post => mock(:body => body_invalid))
24
+ Braspag::Poster.should_receive(:new).with(connection, 'fakeurl').and_return(poster)
25
+
26
+ expect {
27
+ Braspag::Crypto::Webservice.new.encrypt(connection, {key: key})
28
+ }.to raise_error(RuntimeError, 'UnknownError')
29
+ end
30
+
31
+ it "should return error with invalid merchant_id" do
32
+ body_invalid = <<-EOXML
33
+ <?xml version="1.0" encoding="utf-8"?>
34
+ <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
35
+ <soap:Body><EncryptRequestResponse xmlns="https://www.pagador.com.br/webservice/BraspagGeneralService">
36
+ <EncryptRequestResult>Erro BP 011</EncryptRequestResult></EncryptRequestResponse>
37
+ </soap:Body></soap:Envelope>
38
+ EOXML
39
+
40
+ poster.stub(:do_post => mock(:body => body_invalid))
41
+ Braspag::Poster.should_receive(:new).with(connection, 'fakeurl').and_return(poster)
42
+
43
+ expect {
44
+ Braspag::Crypto::Webservice.new.encrypt(connection, {key: key})
45
+ }.to raise_error(RuntimeError, 'InvalidMerchantId')
46
+ end
47
+
48
+ it "should return error with invalid ip" do
49
+ body_invalid = <<-EOXML
50
+ <?xml version="1.0" encoding="utf-8"?>
51
+ <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
52
+ <soap:Body><EncryptRequestResponse xmlns="https://www.pagador.com.br/webservice/BraspagGeneralService">
53
+ <EncryptRequestResult>Erro BP 067</EncryptRequestResult></EncryptRequestResponse>
54
+ </soap:Body></soap:Envelope>
55
+ EOXML
56
+ poster.stub(:do_post => mock(:body => body_invalid))
57
+ Braspag::Poster.should_receive(:new).with(connection, 'fakeurl').and_return(poster)
58
+
59
+ expect {
60
+ Braspag::Crypto::Webservice.new.encrypt(connection, {key: key})
61
+ }.to raise_error(RuntimeError, 'InvalidIP')
62
+
63
+ end
64
+
65
+ it "should return a string" do
66
+ valid_body = <<-EOXML
67
+ <?xml version='1.0' encoding='utf-8'?>
68
+ <soap:Envelope xmlns:soap='http://www.w3.org/2003/05/soap-envelope' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
69
+ <soap:Body>
70
+ <EncryptRequestResponse xmlns='https://www.pagador.com.br/webservice/BraspagGeneralService'>
71
+ <EncryptRequestResult>#{key}</EncryptRequestResult>
72
+ </EncryptRequestResponse>
73
+ </soap:Body></soap:Envelope>
74
+ EOXML
75
+
76
+ poster.stub(:do_post => mock(:body => valid_body))
77
+ Braspag::Poster.should_receive(:new).with(connection, 'fakeurl').and_return(poster)
78
+
79
+ resp = Braspag::Crypto::Webservice.new.encrypt(connection, {key: key})
80
+ resp.should eq(key)
81
+ end
82
+ end
83
+
84
+ describe "decrypt" do
85
+ let(:crypt_string) {"{sdfsdf34543534}"}
86
+ it "should return error with invalid data" do
87
+ body_invalid = <<-EOXML
88
+ SERVER was unable to process
89
+ EOXML
90
+ poster.stub(:do_post => mock(:body => body_invalid))
91
+ Braspag::Poster.should_receive(:new).with(connection, 'fakeurl').and_return(poster)
92
+
93
+ expect {
94
+ Braspag::Crypto::Webservice.new.decrypt(connection, crypt_string)
95
+ }.to raise_error(RuntimeError, 'UnknownError')
96
+
97
+ end
98
+
99
+ it "should return error with invalid ip" do
100
+ body_invalid = <<-EOXML
101
+ <?xml version="1.0" encoding="utf-8"?>
102
+ <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
103
+ <soap:Body><DecryptRequestResponse xmlns="https://www.pagador.com.br/webservice/BraspagGeneralService">
104
+ <DecryptRequestResult><string>Erro BP 068</string></DecryptRequestResult>
105
+ </DecryptRequestResponse></soap:Body></soap:Envelope>
106
+ EOXML
107
+ poster.stub(:do_post => mock(:body => body_invalid))
108
+ Braspag::Poster.should_receive(:new).with(connection, 'fakeurl').and_return(poster)
109
+
110
+ expect {
111
+ Braspag::Crypto::Webservice.new.decrypt(connection, crypt_string)
112
+ }.to raise_error(RuntimeError, 'InvalidIP')
113
+ end
114
+
115
+ it "should return a string" do
116
+ valid_body = <<-EOXML
117
+ <?xml version='1.0' encoding='utf-8'?><soap:Envelope xmlns:soap='http://www.w3.org/2003/05/soap-envelope' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
118
+ <soap:Body><DecryptRequestResponse xmlns='https://www.pagador.com.br/webservice/BraspagGeneralService'>
119
+ <DecryptRequestResult>
120
+ <string>CODPAGAMENTO=18</string>
121
+ <string>VENDAID=teste123</string>
122
+ <string>VALOR=100</string>
123
+ <string>PARCELAS=1</string>
124
+ <string>NOME=comprador</string>
125
+ </DecryptRequestResult></DecryptRequestResponse>
126
+ </soap:Body></soap:Envelope>
127
+ EOXML
128
+
129
+ poster.stub(:do_post => mock(:body => valid_body))
130
+ Braspag::Poster.should_receive(:new).with(connection, 'fakeurl').and_return(poster)
131
+
132
+ resp = Braspag::Crypto::Webservice.new.decrypt(connection, crypt_string)
133
+ resp.should eq({:codpagamento=>"18", :vendaid=>"teste123", :valor=>"100", :parcelas=>"1", :nome=>"comprador"})
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
3
+
4
+ describe Braspag::Connection do
5
+ it "should generate a billet", :billet_integration => true do
6
+ gateway = Braspag::Connection.new(
7
+ :merchant_id => ENV['BRASPAG_MERCHANT_ID'],
8
+ :environment => :homologation
9
+ )
10
+
11
+ billet = Braspag::Billet.new(
12
+ :instructions => 'does not accepted after due date', # (optional)
13
+ :due_date_on => Date.today + 2
14
+ )
15
+
16
+ customer = Braspag::Customer.new(
17
+ :document => '21473696240', # (OPTIONAL)
18
+ :name => 'Bob Dela Bobsen',
19
+ :email => 'bob@mailinator.com' # send email to consumer (OPTIONAL)
20
+ )
21
+
22
+ order = Braspag::Order.new(
23
+ :payment_method => Braspag::PAYMENT_METHOD[:billet_santader],
24
+ :id => 11,
25
+ :amount => 10.00, # $10.00 (accepts all amounts as Integer values in cents)
26
+ :customer => customer
27
+ )
28
+
29
+ # Validating the card automatically detects the card type
30
+ if billet.valid?(:generate) && customer.valid?(:generate) && order.valid?(:generate)
31
+ response = gateway.generate_billet(order, billet)
32
+ response.success?.should eq(true)
33
+ puts "Successfully created billet, open in:#{billet.url}"
34
+ else
35
+ fail "Invalid Params"
36
+ end
37
+ end
38
+ end
File without changes
@@ -0,0 +1,205 @@
1
+ # encoding: utf-8
2
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
3
+
4
+ describe Braspag::Connection do
5
+ let(:merchant_id) { "{12345678-1234-1234-1234-123456789000}" }
6
+ let(:connection) { Braspag::Connection.new(:merchant_id => merchant_id, :environment => :homologation)}
7
+
8
+ context ".generate_billet" do
9
+ it "should return response" do
10
+ generate_billet = {
11
+ :status => "1",
12
+ :message => "BLA",
13
+ :number => "12345"
14
+ }
15
+
16
+ connection.should_receive(:post).and_return(generate_billet)
17
+
18
+ response = connection.generate_billet(mock, mock)
19
+
20
+ response.success?.should eq(false)
21
+ response.message.should eq(generate_billet[:message])
22
+ response.authorization.should eq(generate_billet[:number])
23
+ response.params.should eq({"status"=>"1", "message"=>"BLA", "number"=>"12345"})
24
+ response.test.should eq(true)
25
+ end
26
+
27
+ it "should return success when status is zero" do
28
+ generate_billet = {
29
+ :status => "0",
30
+ :message => "BLA",
31
+ :number => "12345"
32
+ }
33
+
34
+ connection.should_receive(:post).and_return(generate_billet)
35
+
36
+ response = connection.generate_billet(mock, mock)
37
+
38
+ response.success?.should eq(true)
39
+ end
40
+ end
41
+ end
42
+
43
+ describe Braspag::Billet do
44
+ context "on generate" do
45
+ it "should allow blank for id" do
46
+ subject.id = ''
47
+ subject.valid?(:generate)
48
+ subject.errors.messages[:id].should be(nil)
49
+ end
50
+
51
+ it "should validate maximum 255 length of id" do
52
+ subject.id = '*' * 260
53
+ subject.valid?(:generate)
54
+ subject.errors.messages[:id].should include("is too long (maximum is 255 characters)")
55
+ end
56
+
57
+ it "should allow blank for instructions" do
58
+ subject.instructions = ''
59
+ subject.valid?(:generate)
60
+ subject.errors.messages[:instructions].should be(nil)
61
+ end
62
+
63
+ it "should validate maximum 512 length of instructions" do
64
+ subject.instructions = '*' * 520
65
+ subject.valid?(:generate)
66
+ subject.errors.messages[:instructions].should include("is too long (maximum is 512 characters)")
67
+ end
68
+
69
+ it "should not allow blank for due_date_on" do
70
+ subject.due_date_on = ''
71
+ subject.valid?(:generate)
72
+ subject.errors.messages[:due_date_on].should include("can't be blank")
73
+ end
74
+
75
+ it "should not allow invalid date for due_date_on" do
76
+ subject.due_date_on = '12345'
77
+ subject.valid?(:generate)
78
+ subject.errors.messages[:due_date_on].should include("invalid date")
79
+ end
80
+
81
+ it "should allow date for due_date_on" do
82
+ subject.due_date_on = Date.parse('07/03/1988')
83
+ subject.valid?(:generate)
84
+ subject.errors.messages[:due_date_on].should be(nil)
85
+ end
86
+ end
87
+
88
+ context "on generate billet" do
89
+ let(:merchant_id) { "{12345678-1234-1234-1234-123456789000}" }
90
+ let(:connection) { Braspag::Connection.new(:merchant_id => merchant_id, :environment => :homologation)}
91
+
92
+ let(:customer) do
93
+ Braspag::Customer.new(
94
+ :document => '21473696240', # (OPTIONAL)
95
+ :name => 'Bob Dela Bobsen',
96
+ :email => 'bob@mailinator.com' # send email to consumer (OPTIONAL)
97
+ )
98
+ end
99
+
100
+ let(:order) do
101
+ Braspag::Order.new(
102
+ :id => "um order id",
103
+ :amount => 100.00,
104
+ :payment_method => Braspag::PAYMENT_METHOD[:billet_bradesco],
105
+ :customer => customer
106
+ )
107
+ end
108
+
109
+ let(:billet) do
110
+ Braspag::Billet.new(
111
+ :id => '123456',
112
+ :instructions => 'does not accepted after due date',
113
+ :due_date_on => Date.parse('2012-01-01')
114
+ )
115
+ end
116
+
117
+ let(:url) { "https://homologacao.pagador.com.br/pagador/reenvia.asp?Id_Transacao=722934be-6756-477a-87ab-42115ee1424d" }
118
+
119
+ let(:valid_xml) do
120
+ <<-EOXML
121
+ <?xml version="1.0" encoding="utf-8"?>
122
+ <PagadorBoletoReturn xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
123
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
124
+ xmlns="https://www.pagador.com.br/webservice/pagador">
125
+ <amount>3.00</amount>
126
+ <boletoNumber>123123</boletoNumber>
127
+ <expirationDate>2012-01-08T00:00:00</expirationDate>
128
+ <url>https://homologacao.pagador.com.br/pagador/reenvia.asp?Id_Transacao=722934be-6756-477a-87ab-42115ee1424d</url>
129
+ <returnCode>0</returnCode>
130
+ <status>0</status>
131
+ </PagadorBoletoReturn>
132
+ EOXML
133
+ end
134
+
135
+ let(:invalid_xml) do
136
+ <<-EOXML
137
+ <?xml version="1.0" encoding="utf-8"?>
138
+ <PagadorBoletoReturn 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 xsi:nil="true" />
142
+ <expirationDate xsi:nil="true" />
143
+ <returnCode>1</returnCode>
144
+ <message>Invalid merchantId</message>
145
+ <status xsi:nil="true" />
146
+ </PagadorBoletoReturn>
147
+ EOXML
148
+ end
149
+
150
+ it "should convert objects to hash" do
151
+ Braspag::Billet.to_generate_billet(connection, order, billet).should eq({
152
+ "merchantId" => connection.merchant_id,
153
+ "boletoNumber" => billet.id.to_s,
154
+ "instructions" => billet.instructions.to_s,
155
+ "expirationDate" => billet.due_date_on.strftime("%d/%m/%y"),
156
+ "customerName" => order.customer.name.to_s,
157
+ "customerIdNumber" => order.customer.document.to_s,
158
+ "emails" => order.customer.email.to_s,
159
+ "orderId" => order.id.to_s,
160
+ "amount" => Braspag::Converter::decimal_to_string(order.amount),
161
+ "paymentMethod" => order.payment_method
162
+ })
163
+ end
164
+
165
+
166
+ it "should convert response from xml" do
167
+ resp = Braspag::Billet.from_generate_billet(connection, order, billet, mock(:body => valid_xml))
168
+
169
+ billet.url.should eq(url)
170
+ order.gateway_return_code.should eq('0')
171
+ order.gateway_status.should eq('0')
172
+ order.gateway_amount.should eq(3.00)
173
+
174
+ resp.should eq({
175
+ :url => url,
176
+ :amount => "3.00",
177
+ :number => "123123",
178
+ :expiration_date => Date.parse('2012-01-08'),
179
+ :return_code => "0",
180
+ :status => "0",
181
+ :message => nil
182
+ })
183
+ end
184
+
185
+ it "should convert response from xml with invalid date" do
186
+ resp = Braspag::Billet.from_generate_billet(connection, order, billet, mock(:body => invalid_xml))
187
+
188
+ billet.url.should eq(nil)
189
+ order.gateway_return_code.should eq('1')
190
+ order.gateway_status.should eq(nil)
191
+ order.gateway_amount.should eq(nil)
192
+
193
+ resp.should eq({
194
+ :url => nil,
195
+ :amount => nil,
196
+ :number => nil,
197
+ :expiration_date => nil,
198
+ :return_code => "1",
199
+ :status => nil,
200
+ :message => "Invalid merchantId"
201
+ })
202
+ end
203
+ end
204
+ end
205
+
@@ -0,0 +1,385 @@
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 ".purchase" do
8
+ it "should return authorize when authroize response failed" do
9
+ auth = mock(:success? => false)
10
+ connection.stub(:authorize).and_return(auth)
11
+ connection.purchase(mock, mock).should eq(auth)
12
+ end
13
+
14
+ it "should return capture when authorize response success" do
15
+ cap = mock(:success? => true)
16
+ connection.stub(:authorize).and_return(mock(:success? => true))
17
+ connection.stub(:capture).and_return(cap)
18
+ connection.purchase(mock, mock).should eq(cap)
19
+ end
20
+ end
21
+
22
+ context ".authorize" do
23
+ it "should return response" do
24
+ authorize = {
25
+ :status => "2",
26
+ :message => "BLA",
27
+ :number => "12345"
28
+ }
29
+
30
+ connection.should_receive(:post).and_return(authorize)
31
+
32
+ response = connection.authorize(mock, mock)
33
+
34
+ response.success?.should eq(false)
35
+ response.message.should eq(authorize[:message])
36
+ response.authorization.should eq(authorize[:number])
37
+ response.params.should eq({"status"=>"2", "message"=>"BLA", "number"=>"12345"})
38
+ response.test.should eq(true)
39
+ end
40
+
41
+ it "should return success when status is zero" do
42
+ authorize = {
43
+ :status => "0",
44
+ :message => "BLA",
45
+ :number => "12345"
46
+ }
47
+
48
+ connection.should_receive(:post).and_return(authorize)
49
+
50
+ response = connection.authorize(mock, mock)
51
+
52
+ response.success?.should eq(true)
53
+ end
54
+
55
+ it "should return success when status is one" do
56
+ authorize = {
57
+ :status => "1",
58
+ :message => "BLA",
59
+ :number => "12345"
60
+ }
61
+
62
+ connection.should_receive(:post).and_return(authorize)
63
+
64
+ response = connection.authorize(mock, mock)
65
+
66
+ response.success?.should eq(true)
67
+ end
68
+ end
69
+
70
+ context ".capture" do
71
+ it "should return response" do
72
+ capture = {
73
+ :status => "1",
74
+ :message => "BLA",
75
+ :number => "12345"
76
+ }
77
+
78
+ connection.should_receive(:post).and_return(capture)
79
+
80
+ response = connection.capture(mock)
81
+
82
+ response.success?.should eq(false)
83
+ response.message.should eq(capture[:message])
84
+ response.authorization.should eq(capture[:number])
85
+ response.params.should eq({"status"=>"1", "message"=>"BLA", "number"=>"12345"})
86
+ response.test.should eq(true)
87
+ end
88
+
89
+ it "should return success when status is zero" do
90
+ capture = {
91
+ :status => "0",
92
+ :message => "BLA",
93
+ :number => "12345"
94
+ }
95
+
96
+ connection.should_receive(:post).and_return(capture)
97
+
98
+ response = connection.capture(mock)
99
+
100
+ response.success?.should eq(true)
101
+ end
102
+ end
103
+
104
+ context ".void" do
105
+ it "should return response" do
106
+ void = {
107
+ :status => "1",
108
+ :message => "BLA"
109
+ }
110
+
111
+ connection.should_receive(:post).and_return(void)
112
+
113
+ response = connection.void(mock)
114
+
115
+ response.success?.should eq(false)
116
+ response.message.should eq(void[:message])
117
+ response.params.should eq({"status"=>"1", "message"=>"BLA"})
118
+ response.test.should eq(true)
119
+ end
120
+
121
+ it "should return success when status is zero" do
122
+ void = {
123
+ :status => "0",
124
+ :message => "BLA"
125
+ }
126
+
127
+ connection.should_receive(:post).and_return(void)
128
+
129
+ response = connection.void(mock)
130
+
131
+ response.success?.should eq(true)
132
+ end
133
+ end
134
+ end
135
+
136
+ describe Braspag::CreditCard do
137
+
138
+ [:purchase, :authorize, :archive].each do |context_type|
139
+ context "on #{context_type}" do
140
+ it "should validate minimum 1 length of holder_name" do
141
+ subject.holder_name = ''
142
+ subject.valid?(context_type)
143
+ subject.errors.messages[:holder_name].should include("is too short (minimum is 1 characters)")
144
+ end
145
+
146
+ it "should validate maximum 100 length of holder_name" do
147
+ subject.holder_name = '*' * 110
148
+ subject.valid?(context_type)
149
+ subject.errors.messages[:holder_name].should include("is too long (maximum is 100 characters)")
150
+ end
151
+
152
+ it "should not allow blank for number" do
153
+ subject.number = ''
154
+ subject.valid?(context_type)
155
+ subject.errors.messages[:number].should include("can't be blank")
156
+ end
157
+
158
+ it "should not allow blank for month" do
159
+ subject.month = ''
160
+ subject.valid?(context_type)
161
+ subject.errors.messages[:month].should include("can't be blank")
162
+ end
163
+
164
+ it "should not allow blank for year" do
165
+ subject.year = ''
166
+ subject.valid?(context_type)
167
+ subject.errors.messages[:year].should include("can't be blank")
168
+ end
169
+
170
+ it "should not allow invalid date for month & year" do
171
+ subject.month = "14"
172
+ subject.year = "2012"
173
+ subject.valid?(context_type)
174
+ subject.errors.messages[:month].should include("invalid date")
175
+ subject.errors.messages[:year].should include("invalid date")
176
+ end
177
+
178
+ it "should allow valid date for month & year" do
179
+ subject.month = "09"
180
+ subject.year = "12"
181
+ subject.valid?(context_type)
182
+ subject.errors.messages[:month].should be(nil)
183
+ subject.errors.messages[:year].should be(nil)
184
+ end
185
+
186
+ it "should allow valid date for month & year" do
187
+ subject.month = 12
188
+ subject.year = 2014
189
+ subject.valid?(context_type)
190
+ subject.errors.messages[:month].should be(nil)
191
+ subject.errors.messages[:year].should be(nil)
192
+ end
193
+ end
194
+ end
195
+
196
+ [:purchase, :authorize, :recurrency].each do |context_type|
197
+ context "on #{context_type}" do
198
+ it "should validate minimum 1 length of verification_value" do
199
+ subject.verification_value = ''
200
+ subject.valid?(context_type)
201
+ subject.errors.messages[:verification_value].should include("is too short (minimum is 1 characters)")
202
+ end
203
+
204
+ it "should validate maximum 4 length of verification_value" do
205
+ subject.verification_value = '*' * 5
206
+ subject.valid?(context_type)
207
+ subject.errors.messages[:verification_value].should include("is too long (maximum is 4 characters)")
208
+ end
209
+ end
210
+ end
211
+
212
+ [:get_recurrency, :recurrency].each do |context_type|
213
+ context "on #{context_type}" do
214
+ it "should validate length of id" do
215
+ subject.id = '*' * 37
216
+ subject.valid?(context_type)
217
+ subject.errors.messages[:id].should include("is the wrong length (should be 36 characters)")
218
+ end
219
+ end
220
+ end
221
+
222
+ let(:customer) do
223
+ Braspag::Customer.new(:name => "W" * 21)
224
+ end
225
+
226
+ let(:order) do
227
+ Braspag::Order.new(
228
+ :id => "um order id",
229
+ :amount => 1000.00,
230
+ :payment_method => Braspag::PAYMENT_METHOD[:redecard],
231
+ :installments => 1,
232
+ :installments_type => Braspag::INTEREST[:no],
233
+ :customer => customer
234
+ )
235
+ end
236
+
237
+ let(:credit_card) do
238
+ Braspag::CreditCard.new(
239
+ :holder_name => "Joao Maria Souza",
240
+ :number => "9" * 10,
241
+ :month => "10",
242
+ :year => "12",
243
+ :verification_value => "123"
244
+ )
245
+ end
246
+
247
+ context "on authorize credit card" do
248
+ let(:merchant_id) { "{12345678-1234-1234-1234-123456789000}" }
249
+ let(:connection) { Braspag::Connection.new(:merchant_id => merchant_id, :environment => :homologation)}
250
+
251
+ let(:valid_xml) do
252
+ <<-EOXML
253
+ <?xml version="1.0" encoding="utf-8"?>
254
+ <PagadorReturn xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
255
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
256
+ xmlns="https://www.pagador.com.br/webservice/pagador">
257
+ <amount>1.000,00</amount>
258
+ <message>Transaction Successful</message>
259
+ <authorisationNumber>733610</authorisationNumber>
260
+ <returnCode>0</returnCode>
261
+ <status>1</status>
262
+ <transactionId>01231234</transactionId>
263
+ </PagadorReturn>
264
+ EOXML
265
+ end
266
+
267
+ it "should convert objects to hash" do
268
+ Braspag::CreditCard.to_authorize(connection, order, credit_card).should eq({
269
+ "merchantId" => "#{merchant_id}",
270
+ "orderId" => "#{order.id}",
271
+ "customerName" => "#{customer.name}",
272
+ "amount" => "1000,00",
273
+ "paymentMethod" => 20,
274
+ "holder" => "#{credit_card.holder_name}",
275
+ "cardNumber" => "#{credit_card.number}",
276
+ "expiration" => "10/12",
277
+ "securityCode" => "123",
278
+ "numberPayments" => order.installments,
279
+ "typePayment" => order.installments_type
280
+ })
281
+ end
282
+
283
+ it "should populate data" do
284
+ resp = Braspag::CreditCard.from_authorize(connection, order, credit_card, mock(:body => valid_xml))
285
+
286
+ order.gateway_authorization.should eq('733610')
287
+ order.gateway_id.should eq('01231234')
288
+ order.gateway_return_code.should eq('0')
289
+ order.gateway_status.should eq('1')
290
+ order.gateway_message.should eq('Transaction Successful')
291
+ order.gateway_amount.should eq(1000.00)
292
+
293
+ resp.should eq({
294
+ :amount=>"1.000,00",
295
+ :number=>"733610",
296
+ :message=>"Transaction Successful",
297
+ :return_code=>"0",
298
+ :status=>"1",
299
+ :transaction_id=>"01231234"})
300
+ end
301
+ end
302
+
303
+ context "on capture credit card" do
304
+ let(:merchant_id) { "{12345678-1234-1234-1234-123456789000}" }
305
+ let(:connection) { Braspag::Connection.new(:merchant_id => merchant_id, :environment => :homologation)}
306
+
307
+ let(:valid_xml) do
308
+ <<-EOXML
309
+ <?xml version="1.0" encoding="utf-8"?>
310
+ <PagadorReturn xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
311
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
312
+ xmlns="https://www.pagador.com.br/webservice/pagador">
313
+ <amount>2</amount>
314
+ <message>Approved</message>
315
+ <returnCode>0</returnCode>
316
+ <status>0</status>
317
+ </PagadorReturn>
318
+ EOXML
319
+ end
320
+
321
+ it "should convert objects to hash" do
322
+ Braspag::CreditCard.to_capture(connection, order).should eq({
323
+ "merchantId" => "#{merchant_id}",
324
+ "orderId" => "#{order.id}"
325
+ })
326
+ end
327
+
328
+ it "should populate data" do
329
+ resp = Braspag::CreditCard.from_capture(connection, order, mock(:body => valid_xml))
330
+
331
+ order.gateway_capture_return_code.should eq('0')
332
+ order.gateway_capture_status.should eq('0')
333
+ order.gateway_capture_message.should eq('Approved')
334
+ order.gateway_capture_amount.should eq(2.00)
335
+
336
+
337
+ resp.should eq({
338
+ :amount=>"2",
339
+ :message=>"Approved",
340
+ :return_code=>"0",
341
+ :status=>"0",
342
+ :transaction_id=>nil
343
+ })
344
+ end
345
+ end
346
+
347
+ context "on void credit card" do
348
+ let(:merchant_id) { "{12345678-1234-1234-1234-123456789000}" }
349
+ let(:connection) { Braspag::Connection.new(:merchant_id => merchant_id, :environment => :homologation)}
350
+
351
+ let(:valid_xml) do
352
+ <<-EOXML
353
+ <?xml version="1.0" encoding="utf-8"?>
354
+ <PagadorReturn xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
355
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
356
+ xmlns="https://www.pagador.com.br/webservice/pagador">
357
+ <orderId>1234</orderId>
358
+ <transactionId>0</transactionId>
359
+ <amount>100</amount>
360
+ <message>Approved</message>
361
+ <returnCode>0</returnCode>
362
+ <status>0</status>
363
+ </PagadorReturn>
364
+ EOXML
365
+ end
366
+
367
+ it "should convert objects to hash" do
368
+ Braspag::CreditCard.to_void(connection, order).should eq({
369
+ "merchantId" => "#{merchant_id}",
370
+ "order" => "#{order.id}"
371
+ })
372
+ end
373
+
374
+ it "should populate data" do
375
+ resp = Braspag::CreditCard.from_void(connection, order, mock(:body => valid_xml))
376
+
377
+ order.gateway_void_return_code.should eq('0')
378
+ order.gateway_void_status.should eq('0')
379
+ order.gateway_void_message.should eq('Approved')
380
+ order.gateway_void_amount.should eq(100.00)
381
+
382
+ resp.should eq({:order_id=>"1234", :amount=>"100", :message=>"Approved", :return_code=>"0", :status=>"0", :transaction_id=>"0"})
383
+ end
384
+ end
385
+ end