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.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/braintree.gemspec +5 -0
  3. data/lib/braintree/configuration.rb +39 -1
  4. data/lib/braintree/credit_card.rb +1 -0
  5. data/lib/braintree/error_codes.rb +8 -0
  6. data/lib/braintree/graphql_client.rb +28 -0
  7. data/lib/braintree/http.rb +21 -9
  8. data/lib/braintree/local_payment_completed.rb +20 -0
  9. data/lib/braintree/test/credit_card.rb +2 -0
  10. data/lib/braintree/transaction.rb +8 -0
  11. data/lib/braintree/transaction_gateway.rb +4 -0
  12. data/lib/braintree/util.rb +44 -3
  13. data/lib/braintree/validation_error.rb +10 -2
  14. data/lib/braintree/validation_error_collection.rb +2 -1
  15. data/lib/braintree/version.rb +1 -1
  16. data/lib/braintree/webhook_notification.rb +5 -1
  17. data/lib/braintree/webhook_testing_gateway.rb +34 -3
  18. data/lib/braintree.rb +3 -1
  19. data/spec/integration/braintree/credit_card_spec.rb +14 -0
  20. data/spec/integration/braintree/dispute_spec.rb +3 -0
  21. data/spec/integration/braintree/graphql_client_spec.rb +74 -0
  22. data/spec/integration/braintree/http_spec.rb +1 -1
  23. data/spec/integration/braintree/transaction_search_spec.rb +19 -0
  24. data/spec/integration/braintree/transaction_spec.rb +203 -2
  25. data/spec/spec_helper.rb +1 -0
  26. data/spec/unit/braintree/configuration_spec.rb +37 -0
  27. data/spec/unit/braintree/http_spec.rb +65 -0
  28. data/spec/unit/braintree/local_payment_completed_spec.rb +24 -0
  29. data/spec/unit/braintree/transaction_spec.rb +8 -0
  30. data/spec/unit/braintree/util_spec.rb +109 -0
  31. data/spec/unit/braintree/validation_error_collection_spec.rb +335 -132
  32. data/spec/unit/braintree/webhook_notification_spec.rb +31 -0
  33. 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}/downloads")
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::DefaultMerchantAccountId,
4812
- :payment_method_nonce => Braintree::Test::Nonce::AndroidPayDiscover
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