braintree 4.5.0 → 4.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/braintree.gemspec +1 -1
- data/lib/braintree/enriched_customer_data.rb +21 -0
- data/lib/braintree/exchange_rate.rb +13 -0
- data/lib/braintree/exchange_rate_quote.rb +24 -0
- data/lib/braintree/exchange_rate_quote_gateway.rb +35 -0
- data/lib/braintree/exchange_rate_quote_input.rb +21 -0
- data/lib/braintree/exchange_rate_quote_request.rb +18 -0
- data/lib/braintree/exchange_rate_quote_response.rb +18 -0
- data/lib/braintree/gateway.rb +4 -0
- data/lib/braintree/payment_method_customer_data_updated_metadata.rb +24 -0
- data/lib/braintree/plan_gateway.rb +3 -3
- data/lib/braintree/risk_data/liability_shift.rb +22 -0
- data/lib/braintree/risk_data.rb +3 -1
- data/lib/braintree/successful_result.rb +2 -1
- data/lib/braintree/transaction.rb +24 -19
- data/lib/braintree/transaction_search.rb +2 -1
- data/lib/braintree/venmo_profile_data.rb +23 -0
- data/lib/braintree/version.rb +1 -1
- data/lib/braintree/webhook_notification.rb +5 -0
- data/lib/braintree/webhook_testing_gateway.rb +45 -15
- data/lib/braintree.rb +18 -8
- data/spec/integration/braintree/exchange_rate_quote_spec.rb +97 -0
- data/spec/integration/braintree/graphql_client_spec.rb +0 -2
- data/spec/integration/braintree/payment_method_nonce_spec.rb +2 -1
- data/spec/integration/braintree/payment_method_spec.rb +2 -2
- data/spec/integration/braintree/transaction_search_spec.rb +79 -0
- data/spec/integration/braintree/transaction_spec.rb +59 -6
- data/spec/integration/spec_helper.rb +6 -0
- data/spec/unit/braintree/enriched_customer_data_spec.rb +32 -0
- data/spec/unit/braintree/exchange_rate_quote_input_spec.rb +42 -0
- data/spec/unit/braintree/exchange_rate_quote_request_spec.rb +82 -0
- data/spec/unit/braintree/exchange_rate_quote_response_spec.rb +52 -0
- data/spec/unit/braintree/exchange_rate_quote_spec.rb +42 -0
- data/spec/unit/braintree/exchange_rate_spec.rb +23 -0
- data/spec/unit/braintree/payment_method_customer_data_updated_metadata_spec.rb +45 -0
- data/spec/unit/braintree/risk_data/liability_shift.rb +26 -0
- data/spec/unit/braintree/risk_data_spec.rb +33 -7
- data/spec/unit/braintree/transaction_spec.rb +8 -0
- data/spec/unit/braintree/venmo_profile_data_spec.rb +32 -0
- data/spec/unit/braintree/webhook_notification_spec.rb +26 -0
- metadata +24 -4
@@ -0,0 +1,97 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + "/client_api/spec_helper")
|
3
|
+
|
4
|
+
describe Braintree::ExchangeRateQuoteGateway do
|
5
|
+
let(:gateway) do
|
6
|
+
Braintree::Gateway.new(
|
7
|
+
:environment => :development,
|
8
|
+
:merchant_id => "integration_merchant_id",
|
9
|
+
:public_key => "integration_public_key",
|
10
|
+
:private_key => "integration_private_key",
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "generate" do
|
15
|
+
def quote_input_request
|
16
|
+
gateway.exchange_rate_quote.generate({quotes: [quote_input]})
|
17
|
+
end
|
18
|
+
|
19
|
+
let(:quote_input) do
|
20
|
+
{
|
21
|
+
:baseCurrency => "EUR",
|
22
|
+
:quoteCurrency => "GBP",
|
23
|
+
:baseAmount => "20.00",
|
24
|
+
:markup => "4.00"
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
it "generates exchange rate quotes" do
|
29
|
+
result = quote_input_request
|
30
|
+
quotes = result[:quotes]
|
31
|
+
|
32
|
+
expect(quotes[0][:id]).not_to be_nil
|
33
|
+
expect(quotes[0][:baseAmount]).not_to be_nil
|
34
|
+
expect(quotes[0][:quoteAmount]).not_to be_nil
|
35
|
+
expect(quotes[0][:exchangeRate]).not_to be_nil
|
36
|
+
expect(quotes[0][:expiresAt]).not_to be_nil
|
37
|
+
expect(quotes[0][:refreshesAt]).not_to be_nil
|
38
|
+
|
39
|
+
expect(quotes[1][:id]).not_to be_nil
|
40
|
+
expect(quotes[1][:baseAmount]).not_to be_nil
|
41
|
+
expect(quotes[1][:quoteAmount]).not_to be_nil
|
42
|
+
expect(quotes[1][:exchangeRate]).not_to be_nil
|
43
|
+
expect(quotes[1][:expiresAt]).not_to be_nil
|
44
|
+
expect(quotes[1][:refreshesAt]).not_to be_nil
|
45
|
+
end
|
46
|
+
|
47
|
+
context "when base currency input param is not passed" do
|
48
|
+
let(:quote_input) do
|
49
|
+
{
|
50
|
+
:quoteCurrency => "GBP",
|
51
|
+
:baseAmount => "20.00",
|
52
|
+
:markup => "4.00"
|
53
|
+
}
|
54
|
+
end
|
55
|
+
let(:error_message) { "baseCurrency" }
|
56
|
+
|
57
|
+
it "raises an UnexpectedError" do
|
58
|
+
expect do
|
59
|
+
quote_input_request
|
60
|
+
end.to raise_error(Braintree::UnexpectedError, /#{error_message}/)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context "when quote currency input param is not passed" do
|
65
|
+
let(:quote_input) do
|
66
|
+
{
|
67
|
+
:baseCurrency => "GBP",
|
68
|
+
:baseAmount => "20.00",
|
69
|
+
:markup => "4.00"
|
70
|
+
}
|
71
|
+
end
|
72
|
+
let(:error_message) { "quoteCurrency" }
|
73
|
+
|
74
|
+
it "raises an UnexpectedError" do
|
75
|
+
expect do
|
76
|
+
quote_input_request
|
77
|
+
end.to raise_error(Braintree::UnexpectedError, /#{error_message}/)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context "when base and quote currency input params are not passed" do
|
82
|
+
let(:quote_input) do
|
83
|
+
{
|
84
|
+
:baseAmount => "20.00",
|
85
|
+
:markup => "4.00"
|
86
|
+
}
|
87
|
+
end
|
88
|
+
let(:error_message) { "baseCurrency" }
|
89
|
+
|
90
|
+
it "raises an UnexpectedError" do
|
91
|
+
expect do
|
92
|
+
quote_input_request
|
93
|
+
end.to raise_error(Braintree::UnexpectedError, /#{error_message}/)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -28,7 +28,6 @@ describe Braintree::GraphQLClient do
|
|
28
28
|
definition = <<-GRAPHQL
|
29
29
|
mutation CreateClientToken($input: CreateClientTokenInput!) {
|
30
30
|
createClientToken(input: $input) {
|
31
|
-
clientMutationId
|
32
31
|
clientToken
|
33
32
|
}
|
34
33
|
}
|
@@ -36,7 +35,6 @@ mutation CreateClientToken($input: CreateClientTokenInput!) {
|
|
36
35
|
|
37
36
|
variables = {
|
38
37
|
input: {
|
39
|
-
clientMutationId: "abc123",
|
40
38
|
clientToken: {
|
41
39
|
merchantAccountId: "ABC123"
|
42
40
|
}
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
2
2
|
require File.expand_path(File.dirname(__FILE__) + "/client_api/spec_helper")
|
3
|
+
require "date"
|
3
4
|
|
4
5
|
describe Braintree::PaymentMethodNonce do
|
5
6
|
let(:config) { Braintree::Configuration.instantiate }
|
@@ -84,7 +85,7 @@ describe Braintree::PaymentMethodNonce do
|
|
84
85
|
nonce.details.bin.should == "401288"
|
85
86
|
nonce.details.card_type.should == "Visa"
|
86
87
|
nonce.details.expiration_month.should == "12"
|
87
|
-
nonce.details.expiration_year.should ==
|
88
|
+
nonce.details.expiration_year.should == Date.today.next_year.year.to_s
|
88
89
|
nonce.details.is_network_tokenized?.should be_nil
|
89
90
|
nonce.details.last_two.should == "81"
|
90
91
|
nonce.details.payer_info.should be_nil
|
@@ -200,7 +200,7 @@ describe Braintree::PaymentMethod do
|
|
200
200
|
venmo_account.default.should == true
|
201
201
|
venmo_account.token.should == token
|
202
202
|
venmo_account.username.should == "venmojoe"
|
203
|
-
venmo_account.venmo_user_id.should == "
|
203
|
+
venmo_account.venmo_user_id.should == "1234567891234567891"
|
204
204
|
venmo_account.image_url.should include(".png")
|
205
205
|
venmo_account.source_description.should == "Venmo Account: venmojoe"
|
206
206
|
venmo_account.customer_id.should == customer.id
|
@@ -1163,7 +1163,7 @@ describe Braintree::PaymentMethod do
|
|
1163
1163
|
venmo_account.default.should == true
|
1164
1164
|
venmo_account.image_url.should =~ /venmo/
|
1165
1165
|
venmo_account.username.should == "venmojoe"
|
1166
|
-
venmo_account.venmo_user_id.should == "
|
1166
|
+
venmo_account.venmo_user_id.should == "1234567891234567891"
|
1167
1167
|
venmo_account.source_description.should == "Venmo Account: venmojoe"
|
1168
1168
|
venmo_account.customer_id.should == customer.id
|
1169
1169
|
end
|
@@ -174,6 +174,29 @@ describe Braintree::Transaction, "search" do
|
|
174
174
|
collection.first.id.should == transaction_id
|
175
175
|
end
|
176
176
|
|
177
|
+
it "searches on reason_code" do
|
178
|
+
transaction_id = "ach_txn_ret1"
|
179
|
+
reason_code = "R01"
|
180
|
+
|
181
|
+
collection = Braintree::Transaction.search do |search|
|
182
|
+
search.reason_code.in reason_code
|
183
|
+
end
|
184
|
+
|
185
|
+
collection.maximum_size.should == 1
|
186
|
+
collection.first.id.should == transaction_id
|
187
|
+
collection.first.ach_return_responses.first[:reason_code].should == "R01"
|
188
|
+
end
|
189
|
+
|
190
|
+
it "searches on reason_codes" do
|
191
|
+
reason_code = "any_reason_code"
|
192
|
+
|
193
|
+
collection = Braintree::Transaction.search do |search|
|
194
|
+
search.reason_code.is reason_code
|
195
|
+
end
|
196
|
+
|
197
|
+
collection.maximum_size.should == 2
|
198
|
+
end
|
199
|
+
|
177
200
|
context "multiple value fields" do
|
178
201
|
it "searches on created_using" do
|
179
202
|
transaction = Braintree::Transaction.sale!(
|
@@ -419,6 +442,17 @@ describe Braintree::Transaction, "search" do
|
|
419
442
|
collection.maximum_size.should == 0
|
420
443
|
end
|
421
444
|
|
445
|
+
it "searches for settlement_confirmed transaction" do
|
446
|
+
transaction_id = "settlement_confirmed_txn"
|
447
|
+
|
448
|
+
collection = Braintree::Transaction.search do |search|
|
449
|
+
search.id.is transaction_id
|
450
|
+
end
|
451
|
+
|
452
|
+
collection.maximum_size.should == 1
|
453
|
+
collection.first.id.should == transaction_id
|
454
|
+
end
|
455
|
+
|
422
456
|
it "finds expired authorizations by status" do
|
423
457
|
collection = Braintree::Transaction.search do |search|
|
424
458
|
search.status.in Braintree::Transaction::Status::AuthorizationExpired
|
@@ -521,6 +555,29 @@ describe Braintree::Transaction, "search" do
|
|
521
555
|
collection.maximum_size.should == 1
|
522
556
|
collection.first.id.should == transaction_id
|
523
557
|
end
|
558
|
+
|
559
|
+
it "searches on reason_codes for 2 items" do
|
560
|
+
reason_code = ["R01", "R02"]
|
561
|
+
|
562
|
+
collection = Braintree::Transaction.search do |search|
|
563
|
+
search.reason_code.in reason_code
|
564
|
+
end
|
565
|
+
|
566
|
+
collection.maximum_size.should == 2
|
567
|
+
end
|
568
|
+
|
569
|
+
it "searches on a reason_code" do
|
570
|
+
reason_code = ["R01"]
|
571
|
+
transaction_id = "ach_txn_ret1"
|
572
|
+
|
573
|
+
collection = Braintree::Transaction.search do |search|
|
574
|
+
search.reason_code.in reason_code
|
575
|
+
end
|
576
|
+
|
577
|
+
collection.maximum_size.should == 1
|
578
|
+
collection.first.id.should == transaction_id
|
579
|
+
end
|
580
|
+
|
524
581
|
end
|
525
582
|
|
526
583
|
context "invalid search" do
|
@@ -725,6 +782,28 @@ describe Braintree::Transaction, "search" do
|
|
725
782
|
end
|
726
783
|
end
|
727
784
|
|
785
|
+
context "ach return response created at" do
|
786
|
+
it "it finds records within date range of the custom field" do
|
787
|
+
reason_code = "any_reason_code"
|
788
|
+
|
789
|
+
date_search = Braintree::Transaction.search do |search|
|
790
|
+
search.ach_return_responses_created_at.between(DateTime.now - 1.0, DateTime.now + 1.0)
|
791
|
+
end
|
792
|
+
|
793
|
+
date_search.maximum_size.should == 2
|
794
|
+
end
|
795
|
+
|
796
|
+
it "it does not find records not within date range of the custom field" do
|
797
|
+
reason_code = "any_reason_code"
|
798
|
+
|
799
|
+
neg_date_search = Braintree::Transaction.search do |search|
|
800
|
+
search.ach_return_responses_created_at.between(DateTime.now + 1.0, DateTime.now - 1.0)
|
801
|
+
end
|
802
|
+
|
803
|
+
neg_date_search.maximum_size.should == 0
|
804
|
+
end
|
805
|
+
end
|
806
|
+
|
728
807
|
context "disbursement_date" do
|
729
808
|
it "searches on disbursement_date in UTC, as a date" do
|
730
809
|
disbursement_time = Date.parse("2013-04-10")
|
@@ -133,16 +133,36 @@ describe Braintree::Transaction do
|
|
133
133
|
:expiration_date => "05/2009"
|
134
134
|
},
|
135
135
|
)
|
136
|
-
result.transaction.risk_data.
|
137
|
-
result.transaction.risk_data.id.
|
138
|
-
result.transaction.risk_data.decision.
|
139
|
-
result.transaction.risk_data.decision_reasons.
|
136
|
+
expect(result.transaction.risk_data).to be_a(Braintree::RiskData)
|
137
|
+
expect(result.transaction.risk_data.id).not_to be_nil
|
138
|
+
expect(result.transaction.risk_data.decision).not_to be_nil
|
139
|
+
expect(result.transaction.risk_data.decision_reasons).not_to be_nil
|
140
140
|
expect(result.transaction.risk_data).to respond_to(:device_data_captured)
|
141
141
|
expect(result.transaction.risk_data).to respond_to(:fraud_service_provider)
|
142
142
|
expect(result.transaction.risk_data).to respond_to(:transaction_risk_score)
|
143
143
|
end
|
144
144
|
end
|
145
145
|
|
146
|
+
it "returns decision, device_data_captured, id, liability_shift, and decision_reasons" do
|
147
|
+
with_chargeback_protection_merchant do
|
148
|
+
result = Braintree::Transaction.create(
|
149
|
+
:type => "sale",
|
150
|
+
:amount => 1_00,
|
151
|
+
:credit_card => {
|
152
|
+
:number => "4111111111111111",
|
153
|
+
:expiration_date => "05/2009"
|
154
|
+
},
|
155
|
+
)
|
156
|
+
expect(result.transaction.risk_data).to be_a(Braintree::RiskData)
|
157
|
+
expect(result.transaction.risk_data.id).not_to be_nil
|
158
|
+
expect(result.transaction.risk_data.decision).not_to be_nil
|
159
|
+
expect(result.transaction.risk_data.decision_reasons).not_to be_nil
|
160
|
+
expect(result.transaction.risk_data).to respond_to(:device_data_captured)
|
161
|
+
expect(result.transaction.risk_data).to respond_to(:fraud_service_provider)
|
162
|
+
expect(result.transaction.risk_data).to respond_to(:liability_shift)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
146
166
|
it "handles validation errors for invalid risk data attributes" do
|
147
167
|
with_advanced_fraud_kount_integration_merchant do
|
148
168
|
result = Braintree::Transaction.create(
|
@@ -160,7 +180,7 @@ describe Braintree::Transaction do
|
|
160
180
|
:customer_tenure => "20#{"0" * 500}"
|
161
181
|
},
|
162
182
|
)
|
163
|
-
result.success
|
183
|
+
expect(result.success?).to eq(false)
|
164
184
|
result.errors.for(:transaction).for(:risk_data).on(:customer_device_id).map { |e| e.code }.should include Braintree::ErrorCodes::RiskData::CustomerDeviceIdIsTooLong
|
165
185
|
result.errors.for(:transaction).for(:risk_data).on(:customer_location_zip).map { |e| e.code }.should include Braintree::ErrorCodes::RiskData::CustomerLocationZipInvalidCharacters
|
166
186
|
result.errors.for(:transaction).for(:risk_data).on(:customer_tenure).map { |e| e.code }.should include Braintree::ErrorCodes::RiskData::CustomerTenureIsTooLong
|
@@ -1947,7 +1967,7 @@ describe Braintree::Transaction do
|
|
1947
1967
|
venmo_account_details.should be_a(Braintree::Transaction::VenmoAccountDetails)
|
1948
1968
|
venmo_account_details.token.should respond_to(:to_str)
|
1949
1969
|
venmo_account_details.username.should == "venmojoe"
|
1950
|
-
venmo_account_details.venmo_user_id.should == "
|
1970
|
+
venmo_account_details.venmo_user_id.should == "1234567891234567891"
|
1951
1971
|
venmo_account_details.image_url.should include(".png")
|
1952
1972
|
venmo_account_details.source_description.should == "Venmo Account: venmojoe"
|
1953
1973
|
end
|
@@ -6941,6 +6961,39 @@ describe Braintree::Transaction do
|
|
6941
6961
|
end
|
6942
6962
|
end
|
6943
6963
|
|
6964
|
+
describe "retried flag presence in response" do
|
6965
|
+
it "creates a retried transaction" do
|
6966
|
+
result = Braintree::Transaction.sale(
|
6967
|
+
:amount => Braintree::Test::TransactionAmounts::Decline,
|
6968
|
+
:payment_method_token => "network_tokenized_credit_card",
|
6969
|
+
)
|
6970
|
+
transaction = result.transaction
|
6971
|
+
transaction.retried.should == true
|
6972
|
+
end
|
6973
|
+
|
6974
|
+
it "creates a non-retried transaction" do
|
6975
|
+
result = Braintree::Transaction.sale(
|
6976
|
+
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
6977
|
+
:payment_method_token => "network_tokenized_credit_card",
|
6978
|
+
)
|
6979
|
+
transaction = result.transaction
|
6980
|
+
transaction.retried.should == nil
|
6981
|
+
end
|
6982
|
+
|
6983
|
+
it "creates a transaction that is ineligible for retries" do
|
6984
|
+
result = Braintree::Transaction.sale(
|
6985
|
+
:merchant_account_id => SpecHelper::NonDefaultMerchantAccountId,
|
6986
|
+
:credit_card => {
|
6987
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
6988
|
+
:expiration_date => "05/2009"
|
6989
|
+
},
|
6990
|
+
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
6991
|
+
)
|
6992
|
+
transaction = result.transaction
|
6993
|
+
transaction.retried.should == nil
|
6994
|
+
end
|
6995
|
+
end
|
6996
|
+
|
6944
6997
|
describe "installments" do
|
6945
6998
|
it "creates a transaction with an installment count" do
|
6946
6999
|
result = Braintree::Transaction.create(
|
@@ -54,6 +54,12 @@ unless defined?(INTEGRATION_SPEC_HELPER_LOADED)
|
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
+
def with_chargeback_protection_merchant(&block)
|
58
|
+
with_other_merchant("fraud_protection_effortless_chargeback_protection_merchant_id", "effortless_chargeback_protection_public_key", "effortless_chargeback_protection_private_key") do
|
59
|
+
block.call
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
57
63
|
def with_altpay_merchant(&block)
|
58
64
|
with_other_merchant("altpay_merchant", "altpay_merchant_public_key", "altpay_merchant_private_key", &block)
|
59
65
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
2
|
+
|
3
|
+
describe Braintree::EnrichedCustomerData do
|
4
|
+
describe "self.new" do
|
5
|
+
it "is protected" do
|
6
|
+
expect do
|
7
|
+
Braintree::EnrichedCustomerData.new
|
8
|
+
end.to raise_error(NoMethodError, /protected method .new/)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "self._new" do
|
13
|
+
it "initializes the object with the appropriate attributes set" do
|
14
|
+
|
15
|
+
params = {
|
16
|
+
fields_updated: ["username"],
|
17
|
+
profile_data: {
|
18
|
+
username: "a-username",
|
19
|
+
first_name: "a-first-name",
|
20
|
+
last_name: "a-last-name",
|
21
|
+
phone_number: "a-phone-number",
|
22
|
+
email: "a-email",
|
23
|
+
},
|
24
|
+
}
|
25
|
+
|
26
|
+
payment_method_customer_data_updated = Braintree::EnrichedCustomerData._new(params)
|
27
|
+
|
28
|
+
payment_method_customer_data_updated.profile_data.should be_a(Braintree::VenmoProfileData)
|
29
|
+
payment_method_customer_data_updated.fields_updated.should eq(["username"])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
2
|
+
|
3
|
+
describe Braintree::ExchangeRateQuoteInput do
|
4
|
+
let(:exchange_rate_quote_input) do
|
5
|
+
{
|
6
|
+
base_currency: "USD",
|
7
|
+
quote_currency: "EUR",
|
8
|
+
base_amount: "10.00",
|
9
|
+
markup: "2.00"
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#initialize" do
|
14
|
+
it "initialize and sets the input keys to attrs variable" do
|
15
|
+
quote_input = described_class.new(exchange_rate_quote_input)
|
16
|
+
|
17
|
+
expect(quote_input.attrs).to include(:base_currency)
|
18
|
+
expect(quote_input.attrs).to include(:quote_currency)
|
19
|
+
expect(quote_input.attrs).to include(:base_amount)
|
20
|
+
expect(quote_input.attrs).to include(:markup)
|
21
|
+
expect(quote_input.attrs.length).to eq(4)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "inspect" do
|
26
|
+
it "includes the base_currency first" do
|
27
|
+
output = described_class.new(base_currency: "USD").inspect
|
28
|
+
|
29
|
+
expect(output).to include("#<Braintree::ExchangeRateQuoteInput base_currency:\"USD\">")
|
30
|
+
end
|
31
|
+
|
32
|
+
it "includes all quote input attributes" do
|
33
|
+
quote_input = described_class.new(exchange_rate_quote_input)
|
34
|
+
output = quote_input.inspect
|
35
|
+
|
36
|
+
expect(output).to include("base_currency:\"USD\"")
|
37
|
+
expect(output).to include("quote_currency:\"EUR\"")
|
38
|
+
expect(output).to include("base_amount:\"10.00\"")
|
39
|
+
expect(output).to include("markup:\"2.00\"")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
2
|
+
|
3
|
+
describe Braintree::ExchangeRateQuoteRequest do
|
4
|
+
describe "#initialize" do
|
5
|
+
it "creates and validates the exchange rate quote request" do
|
6
|
+
req = Braintree::ExchangeRateQuoteRequest.new(
|
7
|
+
:quotes => [
|
8
|
+
{
|
9
|
+
:base_currency => "USD",
|
10
|
+
:quote_currency => "EUR",
|
11
|
+
:base_amount => "10.00",
|
12
|
+
:markup => "2.00"
|
13
|
+
},
|
14
|
+
{
|
15
|
+
:base_currency => "EUR",
|
16
|
+
:quote_currency => "GBP",
|
17
|
+
:base_amount => "20.00",
|
18
|
+
:markup => "4.00"
|
19
|
+
}
|
20
|
+
],
|
21
|
+
)
|
22
|
+
|
23
|
+
expect(req.quotes[0].base_currency).to eq("USD")
|
24
|
+
expect(req.quotes[0].quote_currency).to eq("EUR")
|
25
|
+
expect(req.quotes[0].base_amount).to eq("10.00")
|
26
|
+
expect(req.quotes[0].markup).to eq("2.00")
|
27
|
+
|
28
|
+
expect(req.quotes[1].base_currency).to eq("EUR")
|
29
|
+
expect(req.quotes[1].quote_currency).to eq("GBP")
|
30
|
+
expect(req.quotes[1].base_amount).to eq("20.00")
|
31
|
+
expect(req.quotes[1].markup).to eq("4.00")
|
32
|
+
end
|
33
|
+
|
34
|
+
it "creates and validates the exchange rate quote request without amount and markup" do
|
35
|
+
req = Braintree::ExchangeRateQuoteRequest.new(
|
36
|
+
:quotes => [
|
37
|
+
{
|
38
|
+
:base_currency => "USD",
|
39
|
+
:quote_currency => "EUR",
|
40
|
+
},
|
41
|
+
{
|
42
|
+
:base_currency => "EUR",
|
43
|
+
:quote_currency => "GBP",
|
44
|
+
}
|
45
|
+
],
|
46
|
+
)
|
47
|
+
|
48
|
+
expect(req.quotes[0].base_currency).to eq("USD")
|
49
|
+
expect(req.quotes[0].quote_currency).to eq("EUR")
|
50
|
+
expect(req.quotes[0].base_amount).to be_nil
|
51
|
+
expect(req.quotes[0].markup).to be_nil
|
52
|
+
|
53
|
+
expect(req.quotes[1].base_currency).to eq("EUR")
|
54
|
+
expect(req.quotes[1].quote_currency).to eq("GBP")
|
55
|
+
expect(req.quotes[1].base_amount).to be_nil
|
56
|
+
expect(req.quotes[1].markup).to be_nil
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "inspect" do
|
62
|
+
it "prints the attributes" do
|
63
|
+
exchange_rate_req = Braintree::ExchangeRateQuoteRequest.new(
|
64
|
+
:quotes => [
|
65
|
+
{
|
66
|
+
:base_currency => "USD",
|
67
|
+
:quote_currency => "EUR",
|
68
|
+
:base_amount => "10.00",
|
69
|
+
:markup => "2.00"
|
70
|
+
},
|
71
|
+
{
|
72
|
+
:base_currency => "EUR",
|
73
|
+
:quote_currency => "GBP",
|
74
|
+
:base_amount => "20.00",
|
75
|
+
:markup => "4.00"
|
76
|
+
}
|
77
|
+
],
|
78
|
+
)
|
79
|
+
expect(exchange_rate_req.inspect).to eq(%(#<Braintree::ExchangeRateQuoteRequest quotes:[#<Braintree::ExchangeRateQuoteInput base_currency:"USD" quote_currency:"EUR" base_amount:"10.00" markup:"2.00">, #<Braintree::ExchangeRateQuoteInput base_currency:"EUR" quote_currency:"GBP" base_amount:"20.00" markup:"4.00">]>))
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
2
|
+
|
3
|
+
describe Braintree::ExchangeRateQuoteResponse do
|
4
|
+
describe "#initialize" do
|
5
|
+
it "creates and validated the exchange rate quote payload" do
|
6
|
+
quote_payload = Braintree::ExchangeRateQuoteResponse.new(
|
7
|
+
quotes: [
|
8
|
+
{
|
9
|
+
:base_amount => "10.00",
|
10
|
+
:quote_amount => "9.03",
|
11
|
+
:exchange_rate => "0.90"
|
12
|
+
},
|
13
|
+
{
|
14
|
+
:base_amount => "20.00",
|
15
|
+
:quote_amount => "18.06",
|
16
|
+
:exchange_rate => "0.90"
|
17
|
+
}
|
18
|
+
],
|
19
|
+
)
|
20
|
+
|
21
|
+
quote_1 = quote_payload.quotes[0]
|
22
|
+
quote_2 = quote_payload.quotes[1]
|
23
|
+
|
24
|
+
expect(quote_1.base_amount).to eq("10.00")
|
25
|
+
expect(quote_1.quote_amount).to eq("9.03")
|
26
|
+
expect(quote_1.exchange_rate).to eq("0.90")
|
27
|
+
|
28
|
+
expect(quote_2.base_amount).to eq("20.00")
|
29
|
+
expect(quote_2.quote_amount).to eq("18.06")
|
30
|
+
expect(quote_1.exchange_rate).to eq("0.90")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "inspect" do
|
35
|
+
it "prints the attributes" do
|
36
|
+
exchange_rate_quote_payload = Braintree::ExchangeRateQuoteResponse.new(
|
37
|
+
quotes: [
|
38
|
+
{
|
39
|
+
:base_amount => "10.00",
|
40
|
+
:quote_amount => "9.03"
|
41
|
+
},
|
42
|
+
{
|
43
|
+
:base_amount => "20.00",
|
44
|
+
:quote_amount => "18.06"
|
45
|
+
}
|
46
|
+
],
|
47
|
+
)
|
48
|
+
|
49
|
+
expect(exchange_rate_quote_payload.inspect).to eq(%(#<Braintree::ExchangeRateQuoteResponse quotes:[#<Braintree::ExchangeRateQuote base_amount:"10.00" quote_amount:"9.03">, #<Braintree::ExchangeRateQuote base_amount:"20.00" quote_amount:"18.06">]>))
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
2
|
+
|
3
|
+
describe Braintree::ExchangeRateQuote do
|
4
|
+
let(:rate_quote) do
|
5
|
+
{
|
6
|
+
id: "1234",
|
7
|
+
base_amount: "10.00",
|
8
|
+
exchange_rate: "74",
|
9
|
+
quote_amount: "740"
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#initialize" do
|
14
|
+
it "initialize and sets the input keys to attrs variable" do
|
15
|
+
quote = described_class.new(rate_quote)
|
16
|
+
|
17
|
+
expect(quote.attrs).to include(:id)
|
18
|
+
expect(quote.attrs).to include(:base_amount)
|
19
|
+
expect(quote.attrs).to include(:exchange_rate)
|
20
|
+
expect(quote.attrs).to include(:quote_amount)
|
21
|
+
expect(quote.attrs.length).to eq(4)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "inspect" do
|
26
|
+
it "includes the id first" do
|
27
|
+
output = described_class.new(id: "1234").inspect
|
28
|
+
|
29
|
+
expect(output).to include("#<Braintree::ExchangeRateQuote id:\"1234\">")
|
30
|
+
end
|
31
|
+
|
32
|
+
it "includes all quote attributes" do
|
33
|
+
quote = described_class.new(rate_quote)
|
34
|
+
output = quote.inspect
|
35
|
+
|
36
|
+
expect(output).to include("id:\"1234\"")
|
37
|
+
expect(output).to include("base_amount:\"10.00\"")
|
38
|
+
expect(output).to include("exchange_rate:\"74\"")
|
39
|
+
expect(output).to include("quote_amount:\"740\"")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
2
|
+
|
3
|
+
describe ::Braintree::ExchangeRate do
|
4
|
+
let(:rate_quote) do
|
5
|
+
{
|
6
|
+
id: "1234",
|
7
|
+
base_amount: "10.00",
|
8
|
+
exchange_rate: "74",
|
9
|
+
quote_amount: "740"
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#initialize" do
|
14
|
+
it "initialize and sets the attributes" do
|
15
|
+
exchange_rate = described_class.new(:gateway, rate_quote).inspect
|
16
|
+
|
17
|
+
expect(exchange_rate).to include("@id=\"1234\"")
|
18
|
+
expect(exchange_rate).to include("@base_amount=\"10.00\"")
|
19
|
+
expect(exchange_rate).to include("@exchange_rate=\"74\"")
|
20
|
+
expect(exchange_rate).to include("@quote_amount=\"740\"")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|