braintree 1.0.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.
- 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
|