braintree 2.90.0 → 2.91.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.
- checksums.yaml +4 -4
- data/braintree.gemspec +5 -0
- data/lib/braintree/configuration.rb +39 -1
- data/lib/braintree/credit_card.rb +1 -0
- data/lib/braintree/error_codes.rb +8 -0
- data/lib/braintree/graphql_client.rb +28 -0
- data/lib/braintree/http.rb +21 -9
- data/lib/braintree/local_payment_completed.rb +20 -0
- data/lib/braintree/test/credit_card.rb +2 -0
- data/lib/braintree/transaction.rb +8 -0
- data/lib/braintree/transaction_gateway.rb +4 -0
- data/lib/braintree/util.rb +44 -3
- data/lib/braintree/validation_error.rb +10 -2
- data/lib/braintree/validation_error_collection.rb +2 -1
- data/lib/braintree/version.rb +1 -1
- data/lib/braintree/webhook_notification.rb +5 -1
- data/lib/braintree/webhook_testing_gateway.rb +34 -3
- data/lib/braintree.rb +3 -1
- data/spec/integration/braintree/credit_card_spec.rb +14 -0
- data/spec/integration/braintree/dispute_spec.rb +3 -0
- data/spec/integration/braintree/graphql_client_spec.rb +74 -0
- data/spec/integration/braintree/http_spec.rb +1 -1
- data/spec/integration/braintree/transaction_search_spec.rb +19 -0
- data/spec/integration/braintree/transaction_spec.rb +203 -2
- data/spec/spec_helper.rb +1 -0
- data/spec/unit/braintree/configuration_spec.rb +37 -0
- data/spec/unit/braintree/http_spec.rb +65 -0
- data/spec/unit/braintree/local_payment_completed_spec.rb +24 -0
- data/spec/unit/braintree/transaction_spec.rb +8 -0
- data/spec/unit/braintree/util_spec.rb +109 -0
- data/spec/unit/braintree/validation_error_collection_spec.rb +335 -132
- data/spec/unit/braintree/webhook_notification_spec.rb +31 -0
- metadata +10 -3
@@ -18,7 +18,7 @@ describe Braintree::Http do
|
|
18
18
|
it "raises an AuthorizationError if authorization fails" do
|
19
19
|
expect do
|
20
20
|
config = Braintree::Configuration.instantiate
|
21
|
-
config.http.get("#{config.base_merchant_path}/
|
21
|
+
config.http.get("#{config.base_merchant_path}/home")
|
22
22
|
end.to raise_error(Braintree::AuthorizationError)
|
23
23
|
end
|
24
24
|
end
|
@@ -293,6 +293,25 @@ describe Braintree::Transaction, "search" do
|
|
293
293
|
collection.maximum_size.should == 0
|
294
294
|
end
|
295
295
|
|
296
|
+
it "searches for an Elo card" do
|
297
|
+
transaction = Braintree::Transaction.sale!(
|
298
|
+
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
299
|
+
:merchant_account_id => SpecHelper::AdyenMerchantAccountId,
|
300
|
+
:credit_card => {
|
301
|
+
:number => Braintree::Test::CreditCardNumbers::Elo,
|
302
|
+
:cvv => "737",
|
303
|
+
:expiration_date => "10/2020"
|
304
|
+
}
|
305
|
+
)
|
306
|
+
|
307
|
+
collection = Braintree::Transaction.search do |search|
|
308
|
+
search.id.is transaction.id
|
309
|
+
search.credit_card_card_type.is Braintree::CreditCard::CardType::Elo
|
310
|
+
end
|
311
|
+
|
312
|
+
collection.maximum_size.should == 1
|
313
|
+
end
|
314
|
+
|
296
315
|
it "searches by payment instrument type CreditCardDetail" do
|
297
316
|
transaction = Braintree::Transaction.sale!(
|
298
317
|
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
@@ -248,6 +248,31 @@ describe Braintree::Transaction do
|
|
248
248
|
end
|
249
249
|
end
|
250
250
|
|
251
|
+
context "elo" do
|
252
|
+
it "returns a successful result if successful" do
|
253
|
+
result = Braintree::Transaction.create(
|
254
|
+
:type => "sale",
|
255
|
+
:merchant_account_id => SpecHelper::AdyenMerchantAccountId,
|
256
|
+
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
257
|
+
:credit_card => {
|
258
|
+
:number => Braintree::Test::CreditCardNumbers::Elo,
|
259
|
+
:cvv => "737",
|
260
|
+
:expiration_date => "10/2020"
|
261
|
+
}
|
262
|
+
)
|
263
|
+
result.success?.should == true
|
264
|
+
result.transaction.id.should =~ /^\w{6,}$/
|
265
|
+
result.transaction.type.should == "sale"
|
266
|
+
result.transaction.amount.should == BigDecimal.new(Braintree::Test::TransactionAmounts::Authorize)
|
267
|
+
result.transaction.processor_authorization_code.should_not be_nil
|
268
|
+
result.transaction.voice_referral_number.should be_nil
|
269
|
+
result.transaction.credit_card_details.bin.should == Braintree::Test::CreditCardNumbers::Elo[0, 6]
|
270
|
+
result.transaction.credit_card_details.last_4.should == Braintree::Test::CreditCardNumbers::Elo[-4..-1]
|
271
|
+
result.transaction.credit_card_details.expiration_date.should == "10/2020"
|
272
|
+
result.transaction.credit_card_details.customer_location.should == "US"
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
251
276
|
it "returns a successful result if successful" do
|
252
277
|
result = Braintree::Transaction.create(
|
253
278
|
:type => "sale",
|
@@ -3617,6 +3642,182 @@ describe Braintree::Transaction do
|
|
3617
3642
|
result.errors.for(:transaction).on(:ships_from_postal_code)[0].code.should == Braintree::ErrorCodes::Transaction::ShipsFromPostalCodeInvalidCharacters
|
3618
3643
|
end
|
3619
3644
|
end
|
3645
|
+
|
3646
|
+
context "network_transaction_id" do
|
3647
|
+
it "receives network_transaction_id for visa transaction" do
|
3648
|
+
result = Braintree::Transaction.create(
|
3649
|
+
:type => "sale",
|
3650
|
+
:credit_card => {
|
3651
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
3652
|
+
:expiration_date => "05/2009"
|
3653
|
+
},
|
3654
|
+
:amount => "10.00",
|
3655
|
+
)
|
3656
|
+
result.success?.should == true
|
3657
|
+
result.transaction.network_transaction_id.should_not be_nil
|
3658
|
+
end
|
3659
|
+
end
|
3660
|
+
|
3661
|
+
context "external vault" do
|
3662
|
+
it "returns a validation error if used with an unsupported instrument type" do
|
3663
|
+
customer = Braintree::Customer.create!
|
3664
|
+
result = Braintree::PaymentMethod.create(
|
3665
|
+
:payment_method_nonce => Braintree::Test::Nonce::PayPalFuturePayment,
|
3666
|
+
:customer_id => customer.id
|
3667
|
+
)
|
3668
|
+
payment_method_token = result.payment_method.token
|
3669
|
+
|
3670
|
+
result = Braintree::Transaction.create(
|
3671
|
+
:type => "sale",
|
3672
|
+
:customer_id => customer.id,
|
3673
|
+
:payment_method_token => payment_method_token,
|
3674
|
+
:external_vault => {
|
3675
|
+
:status => Braintree::Transaction::ExternalVault::Status::WillVault,
|
3676
|
+
},
|
3677
|
+
:amount => "10.00",
|
3678
|
+
)
|
3679
|
+
result.success?.should == false
|
3680
|
+
result.errors.for(:transaction)[0].code.should == Braintree::ErrorCodes::Transaction::PaymentInstrumentWithExternalVaultIsInvalid
|
3681
|
+
end
|
3682
|
+
|
3683
|
+
it "reject invalid status" do
|
3684
|
+
result = Braintree::Transaction.create(
|
3685
|
+
:type => "sale",
|
3686
|
+
:credit_card => {
|
3687
|
+
:number => Braintree::Test::CreditCardNumbers::MasterCard,
|
3688
|
+
:expiration_date => "05/2009"
|
3689
|
+
},
|
3690
|
+
:external_vault => {
|
3691
|
+
:status => "not_valid",
|
3692
|
+
},
|
3693
|
+
:amount => "10.00",
|
3694
|
+
)
|
3695
|
+
result.success?.should == false
|
3696
|
+
result.errors.for(:transaction).for(:external_vault).on(:status)[0].code.should == Braintree::ErrorCodes::Transaction::ExternalVault::StatusIsInvalid
|
3697
|
+
end
|
3698
|
+
|
3699
|
+
context "Visa" do
|
3700
|
+
it "accepts status" do
|
3701
|
+
result = Braintree::Transaction.create(
|
3702
|
+
:type => "sale",
|
3703
|
+
:credit_card => {
|
3704
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
3705
|
+
:expiration_date => "05/2009"
|
3706
|
+
},
|
3707
|
+
:external_vault => {
|
3708
|
+
:status => Braintree::Transaction::ExternalVault::Status::WillVault,
|
3709
|
+
},
|
3710
|
+
:amount => "10.00",
|
3711
|
+
)
|
3712
|
+
result.success?.should == true
|
3713
|
+
result.transaction.network_transaction_id.should_not be_nil
|
3714
|
+
end
|
3715
|
+
|
3716
|
+
it "accepts previous_network_transaction_id" do
|
3717
|
+
result = Braintree::Transaction.create(
|
3718
|
+
:type => "sale",
|
3719
|
+
:credit_card => {
|
3720
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
3721
|
+
:expiration_date => "05/2009"
|
3722
|
+
},
|
3723
|
+
:external_vault => {
|
3724
|
+
:status => Braintree::Transaction::ExternalVault::Status::Vaulted,
|
3725
|
+
:previous_network_transaction_id => "123456789012345",
|
3726
|
+
},
|
3727
|
+
:amount => "10.00",
|
3728
|
+
)
|
3729
|
+
result.success?.should == true
|
3730
|
+
result.transaction.network_transaction_id.should_not be_nil
|
3731
|
+
end
|
3732
|
+
|
3733
|
+
it "rejects non-vaulted status with previous_network_transaction_id" do
|
3734
|
+
result = Braintree::Transaction.create(
|
3735
|
+
:type => "sale",
|
3736
|
+
:credit_card => {
|
3737
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
3738
|
+
:expiration_date => "05/2009"
|
3739
|
+
},
|
3740
|
+
:external_vault => {
|
3741
|
+
:status => Braintree::Transaction::ExternalVault::Status::WillVault,
|
3742
|
+
:previous_network_transaction_id => "123456789012345",
|
3743
|
+
},
|
3744
|
+
:amount => "10.00",
|
3745
|
+
)
|
3746
|
+
result.success?.should == false
|
3747
|
+
result.errors.for(:transaction).for(:external_vault).on(:status)[0].code.should == Braintree::ErrorCodes::Transaction::ExternalVault::StatusWithPreviousNetworkTransactionIdIsInvalid
|
3748
|
+
end
|
3749
|
+
|
3750
|
+
it "rejects invalid previous_network_transaction_id" do
|
3751
|
+
result = Braintree::Transaction.create(
|
3752
|
+
:type => "sale",
|
3753
|
+
:credit_card => {
|
3754
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
3755
|
+
:expiration_date => "05/2009"
|
3756
|
+
},
|
3757
|
+
:external_vault => {
|
3758
|
+
:status => Braintree::Transaction::ExternalVault::Status::Vaulted,
|
3759
|
+
:previous_network_transaction_id => "not_and_valid_id",
|
3760
|
+
},
|
3761
|
+
:amount => "10.00",
|
3762
|
+
)
|
3763
|
+
result.success?.should == false
|
3764
|
+
result.errors.for(:transaction).for(:external_vault).on(:previous_network_transaction_id)[0].code.should == Braintree::ErrorCodes::Transaction::ExternalVault::PreviousNetworkTransactionIdIsInvalid
|
3765
|
+
end
|
3766
|
+
end
|
3767
|
+
|
3768
|
+
context "Non-Visa" do
|
3769
|
+
it "accepts status" do
|
3770
|
+
result = Braintree::Transaction.create(
|
3771
|
+
:type => "sale",
|
3772
|
+
:credit_card => {
|
3773
|
+
:number => Braintree::Test::CreditCardNumbers::MasterCard,
|
3774
|
+
:expiration_date => "05/2009"
|
3775
|
+
},
|
3776
|
+
:external_vault => {
|
3777
|
+
:status => Braintree::Transaction::ExternalVault::Status::WillVault,
|
3778
|
+
},
|
3779
|
+
:amount => "10.00",
|
3780
|
+
)
|
3781
|
+
result.success?.should == true
|
3782
|
+
result.transaction.network_transaction_id.should be_nil
|
3783
|
+
end
|
3784
|
+
|
3785
|
+
it "accepts blank previous_network_transaction_id" do
|
3786
|
+
result = Braintree::Transaction.create(
|
3787
|
+
:type => "sale",
|
3788
|
+
:credit_card => {
|
3789
|
+
:number => Braintree::Test::CreditCardNumbers::MasterCard,
|
3790
|
+
:expiration_date => "05/2009"
|
3791
|
+
},
|
3792
|
+
:external_vault => {
|
3793
|
+
:status => Braintree::Transaction::ExternalVault::Status::Vaulted,
|
3794
|
+
:previous_network_transaction_id => "",
|
3795
|
+
},
|
3796
|
+
:amount => "10.00",
|
3797
|
+
)
|
3798
|
+
result.success?.should == true
|
3799
|
+
result.transaction.network_transaction_id.should be_nil
|
3800
|
+
end
|
3801
|
+
|
3802
|
+
it "rejects previous_network_transaction_id" do
|
3803
|
+
result = Braintree::Transaction.create(
|
3804
|
+
:type => "sale",
|
3805
|
+
:credit_card => {
|
3806
|
+
:number => Braintree::Test::CreditCardNumbers::Discover,
|
3807
|
+
:expiration_date => "05/2009"
|
3808
|
+
},
|
3809
|
+
:external_vault => {
|
3810
|
+
:status => Braintree::Transaction::ExternalVault::Status::Vaulted,
|
3811
|
+
:previous_network_transaction_id => "123456789012345",
|
3812
|
+
},
|
3813
|
+
:amount => "10.00",
|
3814
|
+
)
|
3815
|
+
result.success?.should == false
|
3816
|
+
result.errors.for(:transaction).for(:external_vault).on(:previous_network_transaction_id)[0].code.should == Braintree::ErrorCodes::Transaction::ExternalVault::CardTypeIsInvalid
|
3817
|
+
end
|
3818
|
+
end
|
3819
|
+
|
3820
|
+
end
|
3620
3821
|
end
|
3621
3822
|
|
3622
3823
|
describe "self.create!" do
|
@@ -4808,8 +5009,8 @@ describe Braintree::Transaction do
|
|
4808
5009
|
it "returns an error with an invalid payment instrument type" do
|
4809
5010
|
authorized_transaction = Braintree::Transaction.sale!(
|
4810
5011
|
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
4811
|
-
:merchant_account_id => SpecHelper::
|
4812
|
-
:payment_method_nonce => Braintree::Test::Nonce::
|
5012
|
+
:merchant_account_id => SpecHelper::FakeVenmoAccountMerchantAccountId,
|
5013
|
+
:payment_method_nonce => Braintree::Test::Nonce::VenmoAccount
|
4813
5014
|
)
|
4814
5015
|
|
4815
5016
|
result = Braintree::Transaction.submit_for_partial_settlement(authorized_transaction.id, 100)
|
data/spec/spec_helper.rb
CHANGED
@@ -42,6 +42,7 @@ unless defined?(SPEC_HELPER_LOADED)
|
|
42
42
|
UsBankMerchantAccountId = "us_bank_merchant_account"
|
43
43
|
AnotherUsBankMerchantAccountId = "another_us_bank_merchant_account"
|
44
44
|
IdealMerchantAccountId = "ideal_merchant_account"
|
45
|
+
AdyenMerchantAccountId = "adyen_ma"
|
45
46
|
|
46
47
|
TrialPlan = {
|
47
48
|
:description => "Plan for integration tests -- with trial",
|
@@ -167,6 +167,19 @@ describe Braintree::Configuration do
|
|
167
167
|
config = Braintree::Configuration.new :logger => nil
|
168
168
|
config.logger.should_not == nil
|
169
169
|
end
|
170
|
+
|
171
|
+
it "can set logger on gateway instance" do
|
172
|
+
gateway = Braintree::Configuration.gateway
|
173
|
+
old_logger = Braintree::Configuration.logger
|
174
|
+
|
175
|
+
new_logger = Logger.new("/dev/null")
|
176
|
+
|
177
|
+
gateway.config.logger = new_logger
|
178
|
+
|
179
|
+
expect(gateway.config.logger).to eq(new_logger)
|
180
|
+
|
181
|
+
gateway.config.logger = old_logger
|
182
|
+
end
|
170
183
|
end
|
171
184
|
|
172
185
|
describe "self.environment" do
|
@@ -183,6 +196,14 @@ describe Braintree::Configuration do
|
|
183
196
|
Braintree::Configuration.environment
|
184
197
|
end.to raise_error(Braintree::ConfigurationError, "Braintree::Configuration.environment needs to be set")
|
185
198
|
end
|
199
|
+
|
200
|
+
it "converts environment to symbol" do
|
201
|
+
config = Braintree::Configuration.new({
|
202
|
+
:environment => "sandbox"
|
203
|
+
})
|
204
|
+
|
205
|
+
expect(config.environment).to eq(:sandbox)
|
206
|
+
end
|
186
207
|
end
|
187
208
|
|
188
209
|
describe "self.gateway" do
|
@@ -335,6 +356,22 @@ describe Braintree::Configuration do
|
|
335
356
|
end
|
336
357
|
end
|
337
358
|
|
359
|
+
describe "graphql_server" do
|
360
|
+
it "is localhost or GRAPHQL_HOST environment variable for development" do
|
361
|
+
Braintree::Configuration.environment = :development
|
362
|
+
old_gateway_url = ENV['GRAPHQL_HOST']
|
363
|
+
begin
|
364
|
+
ENV['GRAPHQL_HOST'] = nil
|
365
|
+
Braintree::Configuration.instantiate.graphql_server.should == "graphql.bt.local"
|
366
|
+
|
367
|
+
ENV['GRAPHQL_HOST'] = 'gateway'
|
368
|
+
Braintree::Configuration.instantiate.graphql_server.should == 'gateway'
|
369
|
+
ensure
|
370
|
+
ENV['GRAPHQL_HOST'] = old_gateway_url
|
371
|
+
end
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
338
375
|
describe "server" do
|
339
376
|
it "is localhost or GATEWAY_HOST environment variable for development" do
|
340
377
|
Braintree::Configuration.environment = :development
|
@@ -59,7 +59,9 @@ END
|
|
59
59
|
END
|
60
60
|
Braintree::Http.new(:config)._format_and_sanitize_body_for_log(input_xml).should == expected_xml
|
61
61
|
end
|
62
|
+
end
|
62
63
|
|
64
|
+
describe "self._http_do" do
|
63
65
|
it "connects when proxy address is specified" do
|
64
66
|
config = Braintree::Configuration.new(
|
65
67
|
:proxy_address => "localhost",
|
@@ -116,6 +118,69 @@ END
|
|
116
118
|
end
|
117
119
|
end
|
118
120
|
|
121
|
+
describe "_compose_headers" do
|
122
|
+
before (:each) do
|
123
|
+
config = Braintree::Configuration.new
|
124
|
+
@http = Braintree::Http.new(config)
|
125
|
+
end
|
126
|
+
|
127
|
+
it "returns a hash of default headers" do
|
128
|
+
default_headers = @http._compose_headers
|
129
|
+
expect(default_headers["Accept"]).to eq("application/xml")
|
130
|
+
expect(default_headers["Accept-Encoding"]).to eq("gzip")
|
131
|
+
expect(default_headers["Content-Type"]).to eq("application/xml")
|
132
|
+
expect(default_headers["User-Agent"]).to match(/Braintree Ruby Gem .*/)
|
133
|
+
expect(default_headers["X-ApiVersion"]).to eq("5")
|
134
|
+
end
|
135
|
+
|
136
|
+
it "overwrites defaults with override headers" do
|
137
|
+
override_headers = {
|
138
|
+
"Accept" => "application/pdf",
|
139
|
+
"Authorization" => "token"
|
140
|
+
}
|
141
|
+
headers = @http._compose_headers(override_headers)
|
142
|
+
expect(headers["Accept"]).to eq("application/pdf")
|
143
|
+
expect(headers["Accept-Encoding"]).to eq("gzip")
|
144
|
+
expect(headers["Authorization"]).to eq("token")
|
145
|
+
expect(headers["Content-Type"]).to eq("application/xml")
|
146
|
+
expect(headers["User-Agent"]).to match(/Braintree Ruby Gem .*/)
|
147
|
+
expect(headers["X-ApiVersion"]).to eq("5")
|
148
|
+
end
|
149
|
+
|
150
|
+
it "extends default headers when new headers are specified" do
|
151
|
+
override_headers = {
|
152
|
+
"New-Header" => "New Value"
|
153
|
+
}
|
154
|
+
headers = @http._compose_headers(override_headers)
|
155
|
+
expect(headers["Accept"]).to eq("application/xml")
|
156
|
+
expect(headers["Accept-Encoding"]).to eq("gzip")
|
157
|
+
expect(headers["Content-Type"]).to eq("application/xml")
|
158
|
+
expect(headers["User-Agent"]).to match(/Braintree Ruby Gem .*/)
|
159
|
+
expect(headers["X-ApiVersion"]).to eq("5")
|
160
|
+
expect(headers["New-Header"]).to eq("New Value")
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe "_setup_connection" do
|
165
|
+
it "creates a new Net::HTTP object using default server and port" do
|
166
|
+
config = Braintree::Configuration.new
|
167
|
+
http = Braintree::Http.new(config)
|
168
|
+
|
169
|
+
connection = http._setup_connection
|
170
|
+
expect(connection.address).to eq(nil)
|
171
|
+
expect(connection.port).to eq(80)
|
172
|
+
end
|
173
|
+
|
174
|
+
it "overrides the default server and port when replacements are specified" do
|
175
|
+
config = Braintree::Configuration.new
|
176
|
+
http = Braintree::Http.new(config)
|
177
|
+
|
178
|
+
connection = http._setup_connection("localhost", 3443)
|
179
|
+
expect(connection.address).to eq("localhost")
|
180
|
+
expect(connection.port).to eq(3443)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
119
184
|
describe "_build_query_string" do
|
120
185
|
it "returns an empty string for empty query params" do
|
121
186
|
Braintree::Http.new(:config)._build_query_string({}).should == ""
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
2
|
+
|
3
|
+
describe Braintree::LocalPaymentCompleted do
|
4
|
+
describe "self.new" do
|
5
|
+
it "is protected" do
|
6
|
+
expect do
|
7
|
+
Braintree::LocalPaymentCompleted.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
|
+
params = {
|
15
|
+
payment_id: "a-payment-id",
|
16
|
+
payer_id: "a-payer-id",
|
17
|
+
}
|
18
|
+
local_payment_completed = Braintree::LocalPaymentCompleted._new(params)
|
19
|
+
|
20
|
+
local_payment_completed.payment_id.should eq("a-payment-id")
|
21
|
+
local_payment_completed.payer_id.should eq("a-payer-id")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -255,6 +255,14 @@ describe Braintree::Transaction do
|
|
255
255
|
)
|
256
256
|
transaction.risk_data.should be_nil
|
257
257
|
end
|
258
|
+
|
259
|
+
it "accepts network_transaction_id" do
|
260
|
+
transaction = Braintree::Transaction._new(
|
261
|
+
:gateway,
|
262
|
+
:network_transaction_id => "123456789012345"
|
263
|
+
)
|
264
|
+
transaction.network_transaction_id.should == "123456789012345"
|
265
|
+
end
|
258
266
|
end
|
259
267
|
|
260
268
|
describe "inspect" do
|
@@ -119,6 +119,58 @@ describe Braintree::Util do
|
|
119
119
|
end
|
120
120
|
end
|
121
121
|
|
122
|
+
describe "self.keys_valid?" do
|
123
|
+
it "returns true for wildcard matches" do
|
124
|
+
response = Braintree::Util.keys_valid?(
|
125
|
+
[:allowed, {:custom_fields => :_any_key_}],
|
126
|
+
:allowed => "ok",
|
127
|
+
:custom_fields => {
|
128
|
+
:custom_allowed => "ok",
|
129
|
+
:custom_allowed2 => "also ok",
|
130
|
+
}
|
131
|
+
)
|
132
|
+
expect(response).to eq(true)
|
133
|
+
end
|
134
|
+
it "raises an exception if the hash contains an invalid key" do
|
135
|
+
response = Braintree::Util.keys_valid?([:allowed], :allowed => "ok", :disallowed => "bad")
|
136
|
+
expect(response).to eq(false)
|
137
|
+
end
|
138
|
+
|
139
|
+
it "raises an exception with all keys listed if the hash contains invalid keys" do
|
140
|
+
response = Braintree::Util.keys_valid?([:allowed], :allowed => "ok", :disallowed => "bad", "also_invalid" => true)
|
141
|
+
expect(response).to eq(false)
|
142
|
+
end
|
143
|
+
|
144
|
+
it "returns false for invalid key inside of array" do
|
145
|
+
response = Braintree::Util.keys_valid?(
|
146
|
+
[{:add_ons => [{:update => [:amount]}, {:add => [:amount]}]}],
|
147
|
+
:add_ons => {
|
148
|
+
:update => [{:foo => 10}],
|
149
|
+
:add => [{:bar => 5}]
|
150
|
+
}
|
151
|
+
)
|
152
|
+
expect(response).to eq(false)
|
153
|
+
end
|
154
|
+
|
155
|
+
it "returns false if a deeply nested hash contains an invalid key" do
|
156
|
+
response = Braintree::Util.keys_valid?(
|
157
|
+
[:allowed, {:nested => [:nested_allowed, :nested_allowed2, {:deeply_allowed => [:super_deep_allowed]}]}],
|
158
|
+
:allowed => "ok",
|
159
|
+
:top_level_invalid => "bad",
|
160
|
+
:nested => {
|
161
|
+
:nested_allowed => "ok",
|
162
|
+
:nested_allowed2 => "also ok",
|
163
|
+
:nested_invalid => "bad",
|
164
|
+
:deeply_allowed => {
|
165
|
+
:super_deep_allowed => "yep",
|
166
|
+
:real_deep_invalid => "nope"
|
167
|
+
}
|
168
|
+
}
|
169
|
+
)
|
170
|
+
expect(response).to eq(false)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
122
174
|
describe "self._flatten_hash_keys" do
|
123
175
|
it "flattens hash keys" do
|
124
176
|
Braintree::Util._flatten_hash_keys(:nested => {
|
@@ -199,6 +251,63 @@ describe Braintree::Util do
|
|
199
251
|
end
|
200
252
|
end
|
201
253
|
|
254
|
+
describe "self.raise_exception_for_graphql_error" do
|
255
|
+
errors = {
|
256
|
+
"AUTHENTICATION" => Braintree::AuthenticationError,
|
257
|
+
"AUTHORIZATION" => Braintree::AuthorizationError,
|
258
|
+
"NOT_FOUND" => Braintree::NotFoundError,
|
259
|
+
"UNSUPPORTED_CLIENT" => Braintree::UpgradeRequiredError,
|
260
|
+
"RESOURCE_LIMIT" => Braintree::TooManyRequestsError,
|
261
|
+
"INTERNAL" => Braintree::ServerError,
|
262
|
+
"SERVICE_AVAILABILITY" => Braintree::DownForMaintenanceError,
|
263
|
+
}
|
264
|
+
|
265
|
+
errors.each do |graphQLError, exception|
|
266
|
+
it "raises an #{exception} when GraphQL returns an #{graphQLError} error" do
|
267
|
+
response = {
|
268
|
+
errors: [{
|
269
|
+
extensions: {
|
270
|
+
errorClass: graphQLError
|
271
|
+
}
|
272
|
+
}]
|
273
|
+
}
|
274
|
+
expect do
|
275
|
+
Braintree::Util.raise_exception_for_graphql_error(response)
|
276
|
+
end.to raise_error(exception)
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
it "does not raise an exception when GraphQL returns a validation error" do
|
281
|
+
response = {
|
282
|
+
errors: [{
|
283
|
+
extensions: {
|
284
|
+
errorClass: "VALIDATION"
|
285
|
+
}
|
286
|
+
}]
|
287
|
+
}
|
288
|
+
expect do
|
289
|
+
Braintree::Util.raise_exception_for_graphql_error(response)
|
290
|
+
end.to_not raise_error()
|
291
|
+
end
|
292
|
+
|
293
|
+
it "raises any non-validation errorClass response" do
|
294
|
+
response = {
|
295
|
+
errors: [{
|
296
|
+
extensions: {
|
297
|
+
errorClass: "VALIDATION"
|
298
|
+
}
|
299
|
+
}, {
|
300
|
+
extensions: {
|
301
|
+
errorClass: "NOT_FOUND"
|
302
|
+
}
|
303
|
+
}]
|
304
|
+
}
|
305
|
+
expect do
|
306
|
+
Braintree::Util.raise_exception_for_graphql_error(response)
|
307
|
+
end.to raise_error(Braintree::NotFoundError)
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
202
311
|
describe "self.raise_exception_for_status_code" do
|
203
312
|
it "raises an AuthenticationError if authentication fails" do
|
204
313
|
expect do
|