braintree 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +22 -0
- data/README.rdoc +62 -0
- data/lib/braintree.rb +66 -0
- data/lib/braintree/address.rb +122 -0
- data/lib/braintree/base_module.rb +29 -0
- data/lib/braintree/configuration.rb +99 -0
- data/lib/braintree/credit_card.rb +231 -0
- data/lib/braintree/credit_card_verification.rb +31 -0
- data/lib/braintree/customer.rb +231 -0
- data/lib/braintree/digest.rb +20 -0
- data/lib/braintree/error_codes.rb +95 -0
- data/lib/braintree/error_result.rb +39 -0
- data/lib/braintree/errors.rb +29 -0
- data/lib/braintree/http.rb +105 -0
- data/lib/braintree/paged_collection.rb +55 -0
- data/lib/braintree/ssl_expiration_check.rb +28 -0
- data/lib/braintree/successful_result.rb +38 -0
- data/lib/braintree/test/credit_card_numbers.rb +50 -0
- data/lib/braintree/test/transaction_amounts.rb +10 -0
- data/lib/braintree/transaction.rb +360 -0
- data/lib/braintree/transaction/address_details.rb +15 -0
- data/lib/braintree/transaction/credit_card_details.rb +22 -0
- data/lib/braintree/transaction/customer_details.rb +13 -0
- data/lib/braintree/transparent_redirect.rb +110 -0
- data/lib/braintree/util.rb +94 -0
- data/lib/braintree/validation_error.rb +15 -0
- data/lib/braintree/validation_error_collection.rb +80 -0
- data/lib/braintree/version.rb +9 -0
- data/lib/braintree/xml.rb +12 -0
- data/lib/braintree/xml/generator.rb +80 -0
- data/lib/braintree/xml/libxml.rb +69 -0
- data/lib/braintree/xml/parser.rb +93 -0
- data/lib/ssl/securetrust_ca.crt +44 -0
- data/lib/ssl/valicert_ca.crt +18 -0
- data/spec/integration/braintree/address_spec.rb +352 -0
- data/spec/integration/braintree/credit_card_spec.rb +676 -0
- data/spec/integration/braintree/customer_spec.rb +664 -0
- data/spec/integration/braintree/http_spec.rb +201 -0
- data/spec/integration/braintree/test/transaction_amounts_spec.rb +29 -0
- data/spec/integration/braintree/transaction_spec.rb +900 -0
- data/spec/integration/spec_helper.rb +38 -0
- data/spec/script/httpsd.rb +27 -0
- data/spec/spec_helper.rb +41 -0
- data/spec/unit/braintree/address_spec.rb +86 -0
- data/spec/unit/braintree/configuration_spec.rb +190 -0
- data/spec/unit/braintree/credit_card_spec.rb +137 -0
- data/spec/unit/braintree/credit_card_verification_spec.rb +17 -0
- data/spec/unit/braintree/customer_spec.rb +103 -0
- data/spec/unit/braintree/digest_spec.rb +28 -0
- data/spec/unit/braintree/error_result_spec.rb +42 -0
- data/spec/unit/braintree/errors_spec.rb +81 -0
- data/spec/unit/braintree/http_spec.rb +42 -0
- data/spec/unit/braintree/paged_collection_spec.rb +128 -0
- data/spec/unit/braintree/ssl_expiration_check_spec.rb +92 -0
- data/spec/unit/braintree/successful_result_spec.rb +27 -0
- data/spec/unit/braintree/transaction/credit_card_details_spec.rb +22 -0
- data/spec/unit/braintree/transaction_spec.rb +136 -0
- data/spec/unit/braintree/transparent_redirect_spec.rb +154 -0
- data/spec/unit/braintree/util_spec.rb +142 -0
- data/spec/unit/braintree/validation_error_collection_spec.rb +128 -0
- data/spec/unit/braintree/validation_error_spec.rb +19 -0
- data/spec/unit/braintree/xml/libxml_spec.rb +51 -0
- data/spec/unit/braintree/xml_spec.rb +122 -0
- data/spec/unit/spec_helper.rb +1 -0
- metadata +118 -0
@@ -0,0 +1,92 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../spec_helper"
|
2
|
+
|
3
|
+
# Helper method to confirm we have the right values
|
4
|
+
def fetch_expiration_date(host, port=443)
|
5
|
+
cmd = "echo | openssl s_client -connect #{host}:#{port} 2>&1 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | openssl x509 -noout -subject -dates | grep notAfter"
|
6
|
+
date = `#{cmd}`.sub(/^.*=/, '')
|
7
|
+
|
8
|
+
Date.parse(date)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe Braintree::SSLExpirationCheck do
|
12
|
+
SANDBOX = "sandbox.braintreegateway.com"
|
13
|
+
QA = "qa.braintreegateway.com"
|
14
|
+
PRODUCTION = "www.braintreegateway.com"
|
15
|
+
|
16
|
+
describe "check_dates" do
|
17
|
+
it "is done when the client library is loaded" do
|
18
|
+
Braintree::SSLExpirationCheck.ssl_expiration_dates_checked.should == true
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "QA Cert" do
|
22
|
+
it "logs when the cert is expired" do
|
23
|
+
Braintree::SSLExpirationCheck.stub(:qa_expiration_date).and_return(Date.today - 1)
|
24
|
+
|
25
|
+
output = StringIO.new
|
26
|
+
Braintree::Configuration.logger = Logger.new(output)
|
27
|
+
Braintree::Configuration.logger.level = Logger::WARN
|
28
|
+
|
29
|
+
Braintree::SSLExpirationCheck.check_dates
|
30
|
+
|
31
|
+
output.string.should match(/\[Braintree\] The SSL Certificate for the QA environment will expire on \d{4}-\d{2}-\d{2}\. Please check for an updated client library\./)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "logs when the cert is close to expiring" do
|
35
|
+
Braintree::SSLExpirationCheck.stub(:qa_expiration_date).and_return(Date.today)
|
36
|
+
output = StringIO.new
|
37
|
+
Braintree::Configuration.logger = Logger.new(output)
|
38
|
+
Braintree::Configuration.logger.level = Logger::WARN
|
39
|
+
|
40
|
+
Braintree::SSLExpirationCheck.check_dates
|
41
|
+
|
42
|
+
output.string.should match(/\[Braintree\] The SSL Certificate for the QA environment will expire on \d{4}-\d{2}-\d{2}\. Please check for an updated client library\./)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "doesn't log when the cert is not expired" do
|
46
|
+
Braintree::SSLExpirationCheck.stub(:qa_expiration_date).and_return(Date.today + 365)
|
47
|
+
output = StringIO.new
|
48
|
+
Braintree::Configuration.logger = Logger.new(output)
|
49
|
+
Braintree::Configuration.logger.level = Logger::WARN
|
50
|
+
|
51
|
+
Braintree::SSLExpirationCheck.check_dates
|
52
|
+
|
53
|
+
output.string.should == ""
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# We assume that testing logging for one is good enough for all, so we won't duplicate those tests from above
|
58
|
+
it "checks the sandbox cert" do
|
59
|
+
Braintree::SSLExpirationCheck.stub(:sandbox_expiration_date).and_return(Date.today)
|
60
|
+
output = StringIO.new
|
61
|
+
Braintree::Configuration.logger = Logger.new(output)
|
62
|
+
Braintree::Configuration.logger.level = Logger::WARN
|
63
|
+
|
64
|
+
Braintree::SSLExpirationCheck.check_dates
|
65
|
+
|
66
|
+
output.string.should match(/\[Braintree\] The SSL Certificate for the Sandbox environment will expire on \d{4}-\d{2}-\d{2}\. Please check for an updated client library\./)
|
67
|
+
end
|
68
|
+
|
69
|
+
xit "Patrick -- waiting on a production box -- checks the production server cert"
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "production_expiration_date" do
|
73
|
+
xit "Patrick -- waiting on a production box -- is the date the production cert expires" do
|
74
|
+
Braintree::SSLExpirationCheck.production_expiration_date.should be_a(Date)
|
75
|
+
Braintree::SSLExpirationCheck.qa_expiration_date.should == fetch_expiration_date(PRODUCTION)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "qa_expiration_date" do
|
80
|
+
it "is the date the QA cert expires" do
|
81
|
+
Braintree::SSLExpirationCheck.qa_expiration_date.should be_a(Date)
|
82
|
+
Braintree::SSLExpirationCheck.qa_expiration_date.should == fetch_expiration_date(QA)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "sandbox_expiration_date" do
|
87
|
+
it "is the date the Sandbox cert expires" do
|
88
|
+
Braintree::SSLExpirationCheck.sandbox_expiration_date.should be_a(Date)
|
89
|
+
Braintree::SSLExpirationCheck.sandbox_expiration_date.should == fetch_expiration_date(SANDBOX)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../spec_helper"
|
2
|
+
|
3
|
+
describe Braintree::SuccessfulResult do
|
4
|
+
describe "initialize" do
|
5
|
+
it "creates attr readers the values in the hash" do
|
6
|
+
result = Braintree::SuccessfulResult.new(
|
7
|
+
:foo => "foo_value",
|
8
|
+
:bar => "bar_value"
|
9
|
+
)
|
10
|
+
result.success?.should == true
|
11
|
+
result.foo.should == "foo_value"
|
12
|
+
result.bar.should == "bar_value"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "can be initialized without any values" do
|
16
|
+
result = Braintree::SuccessfulResult.new
|
17
|
+
result.success?.should == true
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "inspect" do
|
22
|
+
it "is pretty" do
|
23
|
+
result = Braintree::SuccessfulResult.new(:foo => "foo_value")
|
24
|
+
result.inspect.should == "#<Braintree::SuccessfulResult foo:\"foo_value\">"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../../spec_helper"
|
2
|
+
|
3
|
+
describe Braintree::Transaction::CreditCardDetails do
|
4
|
+
describe "expiration_date" do
|
5
|
+
it "concats expiration_month and expiration_year" do
|
6
|
+
details = Braintree::Transaction::CreditCardDetails.new(
|
7
|
+
:expiration_month => "08",
|
8
|
+
:expiration_year => "2009"
|
9
|
+
)
|
10
|
+
details.expiration_date.should == "08/2009"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "masked_number" do
|
15
|
+
it "concatenates the bin, some *'s, and the last_4" do
|
16
|
+
details = Braintree::Transaction::CreditCardDetails.new(
|
17
|
+
:bin => "510510", :last_4 => "5100"
|
18
|
+
)
|
19
|
+
details.masked_number.should == "510510******5100"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../spec_helper"
|
2
|
+
|
3
|
+
describe Braintree::Transaction do
|
4
|
+
describe "self.create" do
|
5
|
+
it "raises an exception if hash includes an invalid key" do
|
6
|
+
expect do
|
7
|
+
Braintree::Transaction.create(:amount => "Joe", :invalid_key => "foo")
|
8
|
+
end.to raise_error(ArgumentError, "invalid keys: invalid_key")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "self.create_from_transparent_redirect" do
|
13
|
+
it "raises an exception if the query string is forged" do
|
14
|
+
expect do
|
15
|
+
Braintree::Transaction.create_from_transparent_redirect("forged=query_string")
|
16
|
+
end.to raise_error(Braintree::ForgedQueryString)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "self.create_transaction_url" do
|
21
|
+
it "returns the url" do
|
22
|
+
Braintree::Transaction.create_transaction_url.should == "http://localhost:3000/merchants/integration_merchant_id/transactions/all/create_via_transparent_redirect_request"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "self.submit_for_settlement" do
|
27
|
+
it "raises an ArgumentError if transaction_id is an invalid format" do
|
28
|
+
expect do
|
29
|
+
Braintree::Transaction.submit_for_settlement("invalid-transaction-id")
|
30
|
+
end.to raise_error(ArgumentError, "transaction_id is invalid")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "initialize" do
|
35
|
+
it "sets up customer attributes in customer_details" do
|
36
|
+
transaction = Braintree::Transaction._new(
|
37
|
+
:customer => {
|
38
|
+
:id => "123",
|
39
|
+
:first_name => "Adam",
|
40
|
+
:last_name => "Taylor",
|
41
|
+
:company => "Ledner LLC",
|
42
|
+
:email => "adam.taylor@lednerllc.com",
|
43
|
+
:website => "lednerllc.com",
|
44
|
+
:phone => "1-999-652-4189 x56883",
|
45
|
+
:fax => "012-161-8055"
|
46
|
+
}
|
47
|
+
)
|
48
|
+
transaction.customer_details.id.should == "123"
|
49
|
+
transaction.customer_details.first_name.should == "Adam"
|
50
|
+
transaction.customer_details.last_name.should == "Taylor"
|
51
|
+
transaction.customer_details.company.should == "Ledner LLC"
|
52
|
+
transaction.customer_details.email.should == "adam.taylor@lednerllc.com"
|
53
|
+
transaction.customer_details.website.should == "lednerllc.com"
|
54
|
+
transaction.customer_details.phone.should == "1-999-652-4189 x56883"
|
55
|
+
transaction.customer_details.fax.should == "012-161-8055"
|
56
|
+
end
|
57
|
+
|
58
|
+
it "sets up credit card attributes in credit_card_details" do
|
59
|
+
transaction = Braintree::Transaction._new(
|
60
|
+
:credit_card => {
|
61
|
+
:token => "mzg2",
|
62
|
+
:bin => "411111",
|
63
|
+
:last_4 => "1111",
|
64
|
+
:card_type => "Visa",
|
65
|
+
:expiration_month => "08",
|
66
|
+
:expiration_year => "2009",
|
67
|
+
:issuer_location => "US"
|
68
|
+
}
|
69
|
+
)
|
70
|
+
transaction.credit_card_details.token.should == "mzg2"
|
71
|
+
transaction.credit_card_details.bin.should == "411111"
|
72
|
+
transaction.credit_card_details.last_4.should == "1111"
|
73
|
+
transaction.credit_card_details.card_type.should == "Visa"
|
74
|
+
transaction.credit_card_details.expiration_month.should == "08"
|
75
|
+
transaction.credit_card_details.expiration_year.should == "2009"
|
76
|
+
transaction.credit_card_details.issuer_location.should == "US"
|
77
|
+
end
|
78
|
+
|
79
|
+
it "handles receiving custom as an empty string" do
|
80
|
+
transaction = Braintree::Transaction._new(
|
81
|
+
:custom => "\n "
|
82
|
+
)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "inspect" do
|
87
|
+
it "includes the id, type, amount, and status first" do
|
88
|
+
transaction = Braintree::Transaction._new(
|
89
|
+
:id => "1234",
|
90
|
+
:type => "sale",
|
91
|
+
:amount => "100.00",
|
92
|
+
:status => "authorized"
|
93
|
+
)
|
94
|
+
output = transaction.inspect
|
95
|
+
output.should include(%Q(#<Braintree::Transaction id: "1234", type: "sale", amount: "100.00", status: "authorized"))
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "==" do
|
100
|
+
it "returns true when it should" do
|
101
|
+
first = Braintree::Transaction._new(:id => 123)
|
102
|
+
second = Braintree::Transaction._new(:id => 123)
|
103
|
+
|
104
|
+
first.should == second
|
105
|
+
second.should == first
|
106
|
+
end
|
107
|
+
|
108
|
+
it "returns false when it should" do
|
109
|
+
first = Braintree::Transaction._new(:id => 123)
|
110
|
+
second = Braintree::Transaction._new(:id => 124)
|
111
|
+
|
112
|
+
first.should_not == second
|
113
|
+
second.should_not == first
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "new" do
|
118
|
+
it "is protected" do
|
119
|
+
expect do
|
120
|
+
Braintree::Transaction.new
|
121
|
+
end.to raise_error(NoMethodError, /protected method .new/)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe "refunded?" do
|
126
|
+
it "is true if the transaciton has been refunded" do
|
127
|
+
transaction = Braintree::Transaction._new(:refund_id => "123")
|
128
|
+
transaction.refunded?.should == true
|
129
|
+
end
|
130
|
+
|
131
|
+
it "is false if the transaciton has not been refunded" do
|
132
|
+
transaction = Braintree::Transaction._new(:refund_id => nil)
|
133
|
+
transaction.refunded?.should == false
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../spec_helper"
|
2
|
+
|
3
|
+
describe Braintree::TransparentRedirect do
|
4
|
+
describe "self.create_credit_card_data" do
|
5
|
+
it "raises an exception if any keys are invalid" do
|
6
|
+
expect do
|
7
|
+
Braintree::TransparentRedirect.create_credit_card_data(
|
8
|
+
:credit_card => {:number => "ok", :invalid_key => "bad"}
|
9
|
+
)
|
10
|
+
end.to raise_error(ArgumentError, "invalid keys: credit_card[invalid_key]")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "self.create_customer_data" do
|
15
|
+
it "raises an exception if any keys are invalid" do
|
16
|
+
expect do
|
17
|
+
Braintree::TransparentRedirect.create_customer_data(
|
18
|
+
:customer => {:first_name => "ok", :invalid_key => "bad"}
|
19
|
+
)
|
20
|
+
end.to raise_error(ArgumentError, "invalid keys: customer[invalid_key]")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "self.parse_and_validate_query_string" do
|
25
|
+
it "returns the parsed query string params if the hash is valid" do
|
26
|
+
query_string_without_hash = "one=1&two=2&http_status=200"
|
27
|
+
hash = Braintree::Digest.hexdigest(query_string_without_hash)
|
28
|
+
|
29
|
+
query_string_with_hash = "#{query_string_without_hash}&hash=#{hash}"
|
30
|
+
result = Braintree::TransparentRedirect.parse_and_validate_query_string query_string_with_hash
|
31
|
+
result.should == {:one => "1", :two => "2", :http_status => "200", :hash => hash}
|
32
|
+
end
|
33
|
+
|
34
|
+
it "raises Braintree::ForgedQueryString if the hash param is not valid" do
|
35
|
+
query_string_without_hash = "one=1&two=2"
|
36
|
+
hash = Digest::SHA1.hexdigest("invalid#{query_string_without_hash}")
|
37
|
+
|
38
|
+
query_string_with_hash = "#{query_string_without_hash}&hash=#{hash}"
|
39
|
+
expect do
|
40
|
+
Braintree::TransparentRedirect.parse_and_validate_query_string query_string_with_hash
|
41
|
+
end.to raise_error(Braintree::ForgedQueryString)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "raises Braintree::ForgedQueryString if hash is missing from the query string" do
|
45
|
+
expect do
|
46
|
+
Braintree::TransparentRedirect.parse_and_validate_query_string "query_string=without_a_hash"
|
47
|
+
end.to raise_error(Braintree::ForgedQueryString)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "raises an AuthenticationError if authentication fails" do
|
51
|
+
expect do
|
52
|
+
Braintree::TransparentRedirect.parse_and_validate_query_string add_hash_to_query_string("http_status=401")
|
53
|
+
end.to raise_error(Braintree::AuthenticationError)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "raises an AuthorizationError if authorization fails" do
|
57
|
+
expect do
|
58
|
+
Braintree::TransparentRedirect.parse_and_validate_query_string add_hash_to_query_string("http_status=403")
|
59
|
+
end.to raise_error(Braintree::AuthorizationError)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "raises a ServerError if the server 500's" do
|
63
|
+
expect do
|
64
|
+
Braintree::TransparentRedirect.parse_and_validate_query_string add_hash_to_query_string("http_status=500")
|
65
|
+
end.to raise_error(Braintree::ServerError)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "raises a DownForMaintenanceError if the server is down for maintenance" do
|
69
|
+
expect do
|
70
|
+
Braintree::TransparentRedirect.parse_and_validate_query_string add_hash_to_query_string("http_status=503")
|
71
|
+
end.to raise_error(Braintree::DownForMaintenanceError)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "raises an UnexpectedError if some other code is returned" do
|
75
|
+
expect do
|
76
|
+
Braintree::TransparentRedirect.parse_and_validate_query_string add_hash_to_query_string("http_status=600")
|
77
|
+
end.to raise_error(Braintree::UnexpectedError, "Unexpected HTTP_RESPONSE 600")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "self.transaction_data" do
|
82
|
+
it "raises an exception if any keys are invalid" do
|
83
|
+
expect do
|
84
|
+
Braintree::TransparentRedirect.transaction_data(
|
85
|
+
:transaction => {:amount => "100.00", :invalid_key => "bad"}
|
86
|
+
)
|
87
|
+
end.to raise_error(ArgumentError, "invalid keys: transaction[invalid_key]")
|
88
|
+
end
|
89
|
+
|
90
|
+
it "raises an exception if not given a type" do
|
91
|
+
expect do
|
92
|
+
Braintree::TransparentRedirect.transaction_data(
|
93
|
+
:redirect_url => "http://example.com",
|
94
|
+
:transaction => {:amount => "100.00"}
|
95
|
+
)
|
96
|
+
end.to raise_error(ArgumentError, "expected transaction[type] of sale or credit, was: nil")
|
97
|
+
end
|
98
|
+
|
99
|
+
it "raises an exception if not given a type of sale or credit" do
|
100
|
+
expect do
|
101
|
+
Braintree::TransparentRedirect.transaction_data(
|
102
|
+
:redirect_url => "http://example.com",
|
103
|
+
:transaction => {:amount => "100.00", :type => "auth"}
|
104
|
+
)
|
105
|
+
end.to raise_error(ArgumentError, "expected transaction[type] of sale or credit, was: \"auth\"")
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe "self.update_credit_card_data" do
|
110
|
+
it "raises an exception if any keys are invalid" do
|
111
|
+
expect do
|
112
|
+
Braintree::TransparentRedirect.update_credit_card_data(
|
113
|
+
:credit_card => {:number => "ok", :invalid_key => "bad"}
|
114
|
+
)
|
115
|
+
end.to raise_error(ArgumentError, "invalid keys: credit_card[invalid_key]")
|
116
|
+
end
|
117
|
+
|
118
|
+
it "raises an exception if not given a payment_method_token" do
|
119
|
+
expect do
|
120
|
+
Braintree::TransparentRedirect.update_credit_card_data({})
|
121
|
+
end.to raise_error(ArgumentError, "expected params to contain :payment_method_token of payment method to update")
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe "self.update_customer_data" do
|
126
|
+
it "raises an exception if any keys are invalid" do
|
127
|
+
expect do
|
128
|
+
Braintree::TransparentRedirect.update_customer_data(
|
129
|
+
:customer => {:first_name => "ok", :invalid_key => "bad"}
|
130
|
+
)
|
131
|
+
end.to raise_error(ArgumentError, "invalid keys: customer[invalid_key]")
|
132
|
+
end
|
133
|
+
|
134
|
+
it "raises an exception if not given a customer_id" do
|
135
|
+
expect do
|
136
|
+
Braintree::TransparentRedirect.update_customer_data({})
|
137
|
+
end.to raise_error(ArgumentError, "expected params to contain :customer_id of customer to update")
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe "self._data" do
|
142
|
+
it "raises an exception if :redirect_url isn't given" do
|
143
|
+
expect do
|
144
|
+
Braintree::TransparentRedirect._data(:redirect_url => nil)
|
145
|
+
end.to raise_error(ArgumentError, "expected params to contain :redirect_url")
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def add_hash_to_query_string(query_string_without_hash)
|
150
|
+
hash = Braintree::TransparentRedirect._hash(query_string_without_hash)
|
151
|
+
query_string_without_hash + "&hash=" + hash
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../spec_helper"
|
2
|
+
|
3
|
+
describe Braintree::Util do
|
4
|
+
describe "self.verify_keys" do
|
5
|
+
it "raises an exception if the hash contains an invalid key" do
|
6
|
+
expect do
|
7
|
+
Braintree::Util.verify_keys([:allowed], :allowed => "ok", :disallowed => "bad")
|
8
|
+
end.to raise_error(ArgumentError, "invalid keys: disallowed")
|
9
|
+
end
|
10
|
+
|
11
|
+
it "raises an exception with all keys listed if the hash contains invalid keys" do
|
12
|
+
expect do
|
13
|
+
Braintree::Util.verify_keys([:allowed], :allowed => "ok", :disallowed => "bad", "also_invalid" => true)
|
14
|
+
end.to raise_error(ArgumentError, "invalid keys: also_invalid, disallowed")
|
15
|
+
end
|
16
|
+
|
17
|
+
it "raises an exception if a nested hash contains an invalid key" do
|
18
|
+
expect do
|
19
|
+
Braintree::Util.verify_keys(
|
20
|
+
[:allowed, {:nested => [:nested_allowed, :nested_allowed2]}],
|
21
|
+
:allowed => "ok",
|
22
|
+
:top_level_invalid => "bad",
|
23
|
+
:nested => {
|
24
|
+
:nested_allowed => "ok",
|
25
|
+
:nested_allowed2 => "also ok",
|
26
|
+
:nested_invalid => "bad"
|
27
|
+
}
|
28
|
+
)
|
29
|
+
end.to raise_error(ArgumentError, "invalid keys: nested[nested_invalid], top_level_invalid")
|
30
|
+
end
|
31
|
+
|
32
|
+
it "raises an exception if a deeply nested hash contains an invalid key" do
|
33
|
+
expect do
|
34
|
+
Braintree::Util.verify_keys(
|
35
|
+
[:allowed, {:nested => [:nested_allowed, :nested_allowed2, {:deeply_allowed => [:super_deep_allowed]}]}],
|
36
|
+
:allowed => "ok",
|
37
|
+
:top_level_invalid => "bad",
|
38
|
+
:nested => {
|
39
|
+
:nested_allowed => "ok",
|
40
|
+
:nested_allowed2 => "also ok",
|
41
|
+
:nested_invalid => "bad",
|
42
|
+
:deeply_allowed => {
|
43
|
+
:super_deep_allowed => "yep",
|
44
|
+
:real_deep_invalid => "nope"
|
45
|
+
}
|
46
|
+
}
|
47
|
+
)
|
48
|
+
end.to raise_error(ArgumentError, "invalid keys: nested[deeply_allowed][real_deep_invalid], nested[nested_invalid], top_level_invalid")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "self._flatten_hash_keys" do
|
53
|
+
it "flattens hash keys" do
|
54
|
+
Braintree::Util._flatten_hash_keys(:nested => {
|
55
|
+
:nested_allowed => "ok",
|
56
|
+
:nested_allowed2 => "also ok",
|
57
|
+
:nested_invalid => "bad"
|
58
|
+
}).should == ["nested[nested_allowed2]", "nested[nested_allowed]", "nested[nested_invalid]"]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "self._flatten_valid_keys" do
|
63
|
+
it "flattens hash keys" do
|
64
|
+
Braintree::Util._flatten_valid_keys(
|
65
|
+
[:top_level, {:nested => [:nested_allowed, :nested_allowed2]}]
|
66
|
+
).should == ["nested[nested_allowed2]", "nested[nested_allowed]", "top_level"]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "self.extract_attribute_as_array" do
|
71
|
+
it "delets the attribute from the hash" do
|
72
|
+
hash = {:foo => ["x"], :bar => :baz}
|
73
|
+
Braintree::Util.extract_attribute_as_array(hash, :foo)
|
74
|
+
hash.should == {:bar => :baz}
|
75
|
+
end
|
76
|
+
|
77
|
+
it "puts the attribute in an array if it's not an array" do
|
78
|
+
hash = {:foo => "x", :bar => :baz}
|
79
|
+
result = Braintree::Util.extract_attribute_as_array(hash, :foo)
|
80
|
+
result.should == ["x"]
|
81
|
+
end
|
82
|
+
|
83
|
+
it "returns the value if it's already an array" do
|
84
|
+
hash = {:foo => ["one", "two"], :bar => :baz}
|
85
|
+
result = Braintree::Util.extract_attribute_as_array(hash, :foo)
|
86
|
+
result.should == ["one", "two"]
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "self.hash_to_query_string" do
|
91
|
+
it "generates a query string from the hash" do
|
92
|
+
hash = {:foo => {:key_one => "value_one", :key_two => "value_two"}}
|
93
|
+
Braintree::Util.hash_to_query_string(hash).should == "foo%5Bkey_one%5D=value_one&foo%5Bkey_two%5D=value_two"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "self.parse_query_string" do
|
98
|
+
it "parses the query string" do
|
99
|
+
query_string = "foo=bar%20baz&hash=a1b2c3"
|
100
|
+
Braintree::Util.parse_query_string(query_string).should == {:foo => "bar baz", :hash => "a1b2c3"}
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "self.raise_exception_for_status_code" do
|
105
|
+
it "raises an AuthenticationError if authentication fails" do
|
106
|
+
expect do
|
107
|
+
Braintree::Util.raise_exception_for_status_code(401)
|
108
|
+
end.to raise_error(Braintree::AuthenticationError)
|
109
|
+
end
|
110
|
+
|
111
|
+
it "raises an AuthorizationError if authorization fails" do
|
112
|
+
expect do
|
113
|
+
Braintree::Util.raise_exception_for_status_code(403)
|
114
|
+
end.to raise_error(Braintree::AuthorizationError)
|
115
|
+
end
|
116
|
+
|
117
|
+
it "raises a ServerError if the server 500's" do
|
118
|
+
expect do
|
119
|
+
Braintree::Util.raise_exception_for_status_code(500)
|
120
|
+
end.to raise_error(Braintree::ServerError)
|
121
|
+
end
|
122
|
+
|
123
|
+
it "raises a DownForMaintenanceError if the server is down for maintenance" do
|
124
|
+
expect do
|
125
|
+
Braintree::Util.raise_exception_for_status_code(503)
|
126
|
+
end.to raise_error(Braintree::DownForMaintenanceError)
|
127
|
+
end
|
128
|
+
|
129
|
+
it "raises an UnexpectedError if some other code is returned" do
|
130
|
+
expect do
|
131
|
+
Braintree::Util.raise_exception_for_status_code(600)
|
132
|
+
end.to raise_error(Braintree::UnexpectedError, "Unexpected HTTP_RESPONSE 600")
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
describe "self.url_encode" do
|
138
|
+
it "url encodes the given text" do
|
139
|
+
Braintree::Util.url_encode("foo?bar").should == "foo%3Fbar"
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|