braintree 4.39.0 → 4.40.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.
@@ -92,8 +92,8 @@ describe Braintree::PaymentMethod do
92
92
  expect(apple_pay_card.bin).not_to be_nil
93
93
  expect(apple_pay_card.token).to eq(token)
94
94
  expect(apple_pay_card.card_type).to eq(Braintree::ApplePayCard::CardType::AmEx)
95
- expect(apple_pay_card.payment_instrument_name).to eq("AmEx 41002")
96
- expect(apple_pay_card.source_description).to eq("AmEx 41002")
95
+ expect(apple_pay_card.payment_instrument_name).to match(/\AAmEx \d{4,5}\z/)
96
+ expect(apple_pay_card.source_description).to match(/\AAmEx \d{4,5}\z/)
97
97
  expect(apple_pay_card.default).to eq(true)
98
98
  expect(apple_pay_card.image_url).to match(/apple_pay/)
99
99
  expect(apple_pay_card.expiration_month.to_i).to be > 0
@@ -127,8 +127,8 @@ describe Braintree::PaymentMethod do
127
127
  expect(apple_pay_card.bin).not_to be_nil
128
128
  expect(apple_pay_card.token).to eq(token)
129
129
  expect(apple_pay_card.card_type).to eq(Braintree::ApplePayCard::CardType::Visa)
130
- expect(apple_pay_card.payment_instrument_name).to eq("Visa 2006")
131
- expect(apple_pay_card.source_description).to eq("Visa 2006")
130
+ expect(apple_pay_card.payment_instrument_name).to match(/\AVisa \d{4}\z/)
131
+ expect(apple_pay_card.source_description).to match(/\AVisa \d{4}\z/)
132
132
  expect(apple_pay_card.default).to eq(true)
133
133
  expect(apple_pay_card.image_url).to match(/apple_pay/)
134
134
  expect(apple_pay_card.expiration_month.to_i).to be > 0
@@ -382,6 +382,76 @@ describe Braintree::PaymentMethod do
382
382
  expect(result).to be_success
383
383
  end
384
384
 
385
+ it "accepts a three_d_secure_pass_thru network specified in the request" do
386
+ customer = Braintree::Customer.create!
387
+ result = Braintree::PaymentMethod.create(
388
+ :customer_id => customer.id,
389
+ :payment_method_nonce => Braintree::Test::Nonce::TransactableVisa,
390
+ :three_d_secure_pass_thru => {
391
+ :eci_flag => "05",
392
+ :cavv => "some_cavv",
393
+ :xid => "some_xid",
394
+ :three_d_secure_version => "2.2.0",
395
+ :authentication_response => "Y",
396
+ :directory_response => "Y",
397
+ :cavv_algorithm => "2",
398
+ :ds_transaction_id => "some_ds_transaction_id",
399
+ :network => Braintree::ThreeDSecurePassThru::Network::Visa,
400
+ },
401
+ :options => {:verify_card => true},
402
+ )
403
+
404
+ expect(result).to be_success
405
+ end
406
+
407
+ it "rejects invalid network value in 3ds pass thru params" do
408
+ customer = Braintree::Customer.create!
409
+ result = Braintree::PaymentMethod.create(
410
+ :customer_id => customer.id,
411
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
412
+ :three_d_secure_pass_thru => {
413
+ :eci_flag => "05",
414
+ :cavv => "some_cavv",
415
+ :xid => "some_xid",
416
+ :three_d_secure_version => "2.2.0",
417
+ :authentication_response => "Y",
418
+ :directory_response => "Y",
419
+ :cavv_algorithm => "2",
420
+ :ds_transaction_id => "some_ds_transaction_id",
421
+ :network => "DISCOVER",
422
+ },
423
+ :options => {:verify_card => true},
424
+ )
425
+ expect(result).not_to be_success
426
+ error = result.errors.for(:verification).first
427
+ expect(error.code).to eq(Braintree::ErrorCodes::Verification::ThreeDSecurePassThru::NetworkIsInvalid)
428
+ expect(error.message).to eq("Network is invalid. Supported networks are eftpos, Visa, and Mastercard.")
429
+ end
430
+
431
+ it "rejects request where 3ds pass thru network does not match the payment instrument (VISA nonce, Mastercard network)" do
432
+ customer = Braintree::Customer.create!
433
+ result = Braintree::PaymentMethod.create(
434
+ :customer_id => customer.id,
435
+ :payment_method_nonce => Braintree::Test::Nonce::TransactableVisa,
436
+ :three_d_secure_pass_thru => {
437
+ :eci_flag => "05",
438
+ :cavv => "some_cavv",
439
+ :xid => "some_xid",
440
+ :three_d_secure_version => "2.2.0",
441
+ :authentication_response => "Y",
442
+ :directory_response => "Y",
443
+ :cavv_algorithm => "2",
444
+ :ds_transaction_id => "some_ds_transaction_id",
445
+ :network => Braintree::ThreeDSecurePassThru::Network::MasterCard,
446
+ },
447
+ :options => {:verify_card => true},
448
+ )
449
+ expect(result).not_to be_success
450
+ error = result.errors.for(:verification).first
451
+ expect(error.code).to eq(Braintree::ErrorCodes::Verification::ThreeDSecurePassThru::NetworkDoesNotMatchPaymentInstrument)
452
+ expect(error.message).to eq("Network does not match the payment instrument.")
453
+ end
454
+
385
455
  it "returns 3DS info on cc verification" do
386
456
  customer = Braintree::Customer.create.customer
387
457
  result = Braintree::PaymentMethod.create(
@@ -813,7 +883,7 @@ describe Braintree::PaymentMethod do
813
883
  expect(update_result.payment_method.verification.credit_card[:account_type]).to eq("credit")
814
884
  end
815
885
 
816
- xit "updates the credit card with account_type debit" do
886
+ it "updates the credit card with account_type debit" do
817
887
  customer = Braintree::Customer.create!
818
888
  credit_card = Braintree::CreditCard.create!(
819
889
  :cardholder_name => "Original Holder",
@@ -1404,7 +1474,7 @@ describe Braintree::PaymentMethod do
1404
1474
  expect(apple_pay_card.image_url).to match(/apple_pay/)
1405
1475
  expect(apple_pay_card.expiration_month.to_i).to be > 0
1406
1476
  expect(apple_pay_card.expiration_year.to_i).to be > 0
1407
- expect(apple_pay_card.source_description).to eq("AmEx 41002")
1477
+ expect(apple_pay_card.source_description).to match(/\AAmEx \d{4,5}\z/)
1408
1478
  expect(apple_pay_card.customer_id).to eq(customer.id)
1409
1479
  end
1410
1480
 
@@ -1427,7 +1497,7 @@ describe Braintree::PaymentMethod do
1427
1497
  expect(apple_pay_card.image_url).to match(/apple_pay/)
1428
1498
  expect(apple_pay_card.expiration_month.to_i).to be > 0
1429
1499
  expect(apple_pay_card.expiration_year.to_i).to be > 0
1430
- expect(apple_pay_card.source_description).to eq("Visa 2006")
1500
+ expect(apple_pay_card.source_description).to match(/\AVisa \d{4}\z/)
1431
1501
  expect(apple_pay_card.customer_id).to eq(customer.id)
1432
1502
  expect(apple_pay_card.is_device_token).to eq(false)
1433
1503
  apple_pay_card.merchant_token_identifier == "DNITHE302308980427388297"
@@ -3,7 +3,7 @@ require File.expand_path(File.dirname(__FILE__) + "/client_api/spec_helper")
3
3
 
4
4
  # NEXT_MAJOR_VERSION remove these tests
5
5
  # SamsungPayCard has been deprecated
6
- xdescribe Braintree::SamsungPayCard do
6
+ describe Braintree::SamsungPayCard do
7
7
  it "can create from payment method nonce" do
8
8
  customer = Braintree::Customer.create!
9
9
 
@@ -11,8 +11,7 @@ describe Braintree::Transaction, "search" do
11
11
  expect(collection.maximum_size).to eq(0)
12
12
  end
13
13
 
14
- #Disabling test until we have more stable CI
15
- xit "can search on text fields" do
14
+ it "can search on text fields" do
16
15
  first_name = "Tim_#{rand(10**10)}"
17
16
  token = "creditcard_#{rand(10**10)}"
18
17
  customer_id = "customer_#{rand(10**10)}"
@@ -132,8 +131,7 @@ describe Braintree::Transaction, "search" do
132
131
  expect(collection.first.id).to eq(transaction.id)
133
132
  end
134
133
 
135
- #Disabling test until we have more stable CI
136
- xit "searches on users" do
134
+ it "searches on users" do
137
135
  transaction = Braintree::Transaction.sale!(
138
136
  :amount => Braintree::Test::TransactionAmounts::Authorize,
139
137
  :payment_method_nonce => Braintree::Test::Nonce::PayPalBillingAgreement,
@@ -177,14 +175,15 @@ describe Braintree::Transaction, "search" do
177
175
  expect(collection.first.id).to eq(transaction_id)
178
176
  end
179
177
 
180
- it "searches on reason_codes for 3 items" do
178
+ it "searches on reason_codes for 2 items" do
181
179
  reason_code = ["R01", "R02"]
182
180
 
183
181
  collection = Braintree::Transaction.search do |search|
182
+ search.ids.in ["ach_txn_ret1", "ach_txn_ret2"]
184
183
  search.reason_code.in reason_code
185
184
  end
186
185
 
187
- expect(collection.maximum_size).to eq(3)
186
+ expect(collection.maximum_size).to eq(2)
188
187
  end
189
188
 
190
189
  it "searches on reason_code" do
@@ -192,6 +191,7 @@ describe Braintree::Transaction, "search" do
192
191
  reason_code = "R01"
193
192
 
194
193
  collection = Braintree::Transaction.search do |search|
194
+ search.ids.in [transaction_id]
195
195
  search.reason_code.in reason_code
196
196
  end
197
197
  item = collection.find { |t| t.id == transaction_id }
@@ -204,6 +204,7 @@ describe Braintree::Transaction, "search" do
204
204
  reason_code = "RJCT"
205
205
 
206
206
  collection = Braintree::Transaction.search do |search|
207
+ search.ids.in [transaction_id]
207
208
  search.reason_code.in reason_code
208
209
  end
209
210
  item = collection.find { |t| t.id == transaction_id }
@@ -217,10 +218,11 @@ describe Braintree::Transaction, "search" do
217
218
  reason_code = "any_reason_code"
218
219
 
219
220
  collection = Braintree::Transaction.search do |search|
221
+ search.ids.in ["ach_txn_ret1", "ach_txn_ret2", "ach_txn_ret3", "ach_txn_ret4"]
220
222
  search.reason_code.is reason_code
221
223
  end
222
224
 
223
- expect(collection.maximum_size).to eq(6)
225
+ expect(collection.maximum_size).to eq(4)
224
226
  end
225
227
 
226
228
  context "multiple value fields" do
@@ -512,6 +514,7 @@ describe Braintree::Transaction, "search" do
512
514
  end
513
515
 
514
516
  it "finds expired authorizations by status" do
517
+ skip "pending search fix"
515
518
  collection = Braintree::Transaction.search do |search|
516
519
  search.status.in Braintree::Transaction::Status::AuthorizationExpired
517
520
  end
@@ -614,7 +617,7 @@ describe Braintree::Transaction, "search" do
614
617
  expect(collection.first.id).to eq(transaction_id)
615
618
  end
616
619
 
617
- xit "searches on debit_network" do
620
+ it "searches on debit_network" do
618
621
  transaction = Braintree::Transaction.sale!(
619
622
  :amount => Braintree::Test::TransactionAmounts::Authorize,
620
623
  :merchant_account_id => SpecHelper::PinlessDebitMerchantAccountId,
@@ -854,6 +857,7 @@ describe Braintree::Transaction, "search" do
854
857
  context "ach return response created at" do
855
858
  it "it finds records within date range of the custom field" do
856
859
  date_search = Braintree::Transaction.search do |search|
860
+ search.ids.in ["ach_txn_ret1", "ach_txn_ret2", "ach_txn_ret3", "ach_txn_ret4"]
857
861
  search.ach_return_responses_created_at.between(DateTime.now - 1.0, DateTime.now + 1.0)
858
862
  end
859
863
 
@@ -862,6 +866,7 @@ describe Braintree::Transaction, "search" do
862
866
 
863
867
  it "it does not find records not within date range of the custom field" do
864
868
  neg_date_search = Braintree::Transaction.search do |search|
869
+ search.ids.in ["ach_txn_ret1", "ach_txn_ret2", "ach_txn_ret3", "ach_txn_ret4"]
865
870
  search.ach_return_responses_created_at.between(DateTime.now + 1.0, DateTime.now - 1.0)
866
871
  end
867
872
 
@@ -1006,7 +1011,7 @@ describe Braintree::Transaction, "search" do
1006
1011
  }
1007
1012
  end
1008
1013
 
1009
- xit "searches on dispute_date in UTC" do
1014
+ it "searches on dispute_date in UTC" do
1010
1015
  collection = Braintree::Transaction.search do |search|
1011
1016
  search.id.is @disputed_transaction.id
1012
1017
  search.dispute_date.between(
@@ -1043,7 +1048,7 @@ describe Braintree::Transaction, "search" do
1043
1048
  expect(collection.first.id).to eq(@disputed_transaction.id)
1044
1049
  end
1045
1050
 
1046
- xit "searches on dispute_date in local time" do
1051
+ it "searches on dispute_date in local time" do
1047
1052
  now = @disputed_time.localtime("-06:00")
1048
1053
 
1049
1054
  collection = Braintree::Transaction.search do |search|
@@ -1073,7 +1078,7 @@ describe Braintree::Transaction, "search" do
1073
1078
  expect(collection.maximum_size).to eq(1)
1074
1079
  end
1075
1080
 
1076
- xit "searches on dispute_date with date ranges" do
1081
+ it "searches on dispute_date with date ranges" do
1077
1082
  collection = Braintree::Transaction.search do |search|
1078
1083
  search.id.is @disputed_transaction.id
1079
1084
  search.dispute_date.between(
@@ -1151,6 +1156,7 @@ describe Braintree::Transaction, "search" do
1151
1156
  end
1152
1157
 
1153
1158
  it "finds expired authorizations in a given range" do
1159
+ skip "pending search fix"
1154
1160
  collection = Braintree::Transaction.search do |search|
1155
1161
  search.authorization_expired_at.between(
1156
1162
  Date.today - 2,
@@ -1379,8 +1385,7 @@ describe Braintree::Transaction, "search" do
1379
1385
  end
1380
1386
  end
1381
1387
 
1382
- #Disabling until we have a more stable CI
1383
- xit "returns multiple results" do
1388
+ it "returns multiple results" do
1384
1389
  collection = Braintree::Transaction.search
1385
1390
  expect(collection.maximum_size).to be > 100
1386
1391
 
@@ -336,7 +336,7 @@ describe Braintree::Transaction do
336
336
 
337
337
  describe "sca_exemption" do
338
338
  context "with a valid request" do
339
- xit "succeeds" do
339
+ it "succeeds with a valid sca_exemption request" do
340
340
  requested_exemption = "low_value"
341
341
  result = Braintree::Transaction.create(
342
342
  :type => "sale",
@@ -1370,7 +1370,7 @@ describe Braintree::Transaction do
1370
1370
  expect(result.transaction.gateway_rejection_reason).to eq(Braintree::Transaction::GatewayRejectionReason::TokenIssuance)
1371
1371
  end
1372
1372
 
1373
- xit "exposes the excessive_retry gateway rejection reason" do
1373
+ it "exposes the excessive_retry gateway rejection reason" do
1374
1374
  with_duplicate_checking_merchant do
1375
1375
  result = nil
1376
1376
  counter = 0
@@ -1749,7 +1749,7 @@ describe Braintree::Transaction do
1749
1749
  expect(result.transaction.descriptor.url).to eq("ebay.com")
1750
1750
  end
1751
1751
 
1752
- it "has validation errors if format is invalid" do
1752
+ it "has validation errors when the descriptor name is too long" do
1753
1753
  result = Braintree::Transaction.sale(
1754
1754
  :amount => Braintree::Test::TransactionAmounts::Authorize,
1755
1755
  :credit_card => {
@@ -1757,7 +1757,7 @@ describe Braintree::Transaction do
1757
1757
  :expiration_date => "05/2009"
1758
1758
  },
1759
1759
  :descriptor => {
1760
- :name => "badcompanyname12*badproduct12",
1760
+ :name => "badcompanyname12*badproductdescription",
1761
1761
  :phone => "%bad4445555",
1762
1762
  :url => "12345678901234"
1763
1763
  },
@@ -2221,8 +2221,8 @@ describe Braintree::Transaction do
2221
2221
  expect(apple_pay_details).not_to be_nil
2222
2222
  expect(apple_pay_details.bin).not_to be_nil
2223
2223
  expect(apple_pay_details.card_type).to eq(Braintree::ApplePayCard::CardType::Visa)
2224
- expect(apple_pay_details.payment_instrument_name).to eq("Visa 8886")
2225
- expect(apple_pay_details.source_description).to eq("Visa 8886")
2224
+ expect(apple_pay_details.payment_instrument_name).to match(/\AVisa \d{4}\z/)
2225
+ expect(apple_pay_details.source_description).to match(/\AVisa \d{4}\z/)
2226
2226
  expect(apple_pay_details.expiration_month.to_i).to be > 0
2227
2227
  expect(apple_pay_details.expiration_year.to_i).to be > 0
2228
2228
  expect(apple_pay_details.cardholder_name).not_to be_nil
@@ -2250,8 +2250,8 @@ describe Braintree::Transaction do
2250
2250
  expect(apple_pay_details).not_to be_nil
2251
2251
  expect(apple_pay_details.bin).not_to be_nil
2252
2252
  expect(apple_pay_details.card_type).to eq(Braintree::ApplePayCard::CardType::Visa)
2253
- expect(apple_pay_details.payment_instrument_name).to eq("Visa 2006")
2254
- expect(apple_pay_details.source_description).to eq("Visa 2006")
2253
+ expect(apple_pay_details.payment_instrument_name).to match(/\AVisa \d{4}\z/)
2254
+ expect(apple_pay_details.source_description).to match(/\AVisa \d{4}\z/)
2255
2255
  expect(apple_pay_details.expiration_month.to_i).to be > 0
2256
2256
  expect(apple_pay_details.expiration_year.to_i).to be > 0
2257
2257
  expect(apple_pay_details.cardholder_name).not_to be_nil
@@ -2280,8 +2280,8 @@ describe Braintree::Transaction do
2280
2280
  apple_pay_details = result.transaction.apple_pay_details
2281
2281
  expect(apple_pay_details).not_to be_nil
2282
2282
  expect(apple_pay_details.card_type).to eq(Braintree::ApplePayCard::CardType::Visa)
2283
- expect(apple_pay_details.payment_instrument_name).to eq("Visa 8886")
2284
- expect(apple_pay_details.source_description).to eq("Visa 8886")
2283
+ expect(apple_pay_details.payment_instrument_name).to match(/\AVisa \d{4}\z/)
2284
+ expect(apple_pay_details.source_description).to match(/\AVisa \d{4}\z/)
2285
2285
  expect(apple_pay_details.expiration_month.to_i).to be > 0
2286
2286
  expect(apple_pay_details.expiration_year.to_i).to be > 0
2287
2287
  expect(apple_pay_details.cardholder_name).not_to be_nil
@@ -2905,6 +2905,106 @@ describe Braintree::Transaction do
2905
2905
  expect(result.transaction.status).to eq(Braintree::Transaction::Status::Authorized)
2906
2906
  end
2907
2907
 
2908
+ it "can create a transaction with a three_d_secure_pass_thru network specified" do
2909
+ result = Braintree::Transaction.create(
2910
+ :type => "sale",
2911
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
2912
+ :credit_card => {
2913
+ :number => Braintree::Test::CreditCardNumbers::Visa,
2914
+ :expiration_date => "05/2009",
2915
+ },
2916
+ :three_d_secure_pass_thru => {
2917
+ :eci_flag => "05",
2918
+ :cavv => "some_cavv",
2919
+ :xid => "some_xid",
2920
+ :three_d_secure_version => "2.2.0",
2921
+ :authentication_response => "Y",
2922
+ :directory_response => "Y",
2923
+ :cavv_algorithm => "2",
2924
+ :network => Braintree::ThreeDSecurePassThru::Network::Visa,
2925
+ },
2926
+ )
2927
+
2928
+ expect(result.success?).to eq(true)
2929
+ expect(result.transaction.status).to eq(Braintree::Transaction::Status::Authorized)
2930
+ end
2931
+
2932
+ it "returns an error for transaction with three_d_secure_pass_thru network when submit_for_settlement is false" do
2933
+ result = Braintree::Transaction.create(
2934
+ :type => "sale",
2935
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
2936
+ :credit_card => {
2937
+ :number => Braintree::Test::CreditCardNumbers::Visa,
2938
+ :expiration_date => "05/2009",
2939
+ },
2940
+ :three_d_secure_pass_thru => {
2941
+ :eci_flag => "05",
2942
+ :cavv => "some_cavv",
2943
+ :xid => "some_xid",
2944
+ :three_d_secure_version => "2.2.0",
2945
+ :authentication_response => "Y",
2946
+ :directory_response => "Y",
2947
+ :cavv_algorithm => "2",
2948
+ :network => Braintree::ThreeDSecurePassThru::Network::Eftpos,
2949
+ },
2950
+ :options => {
2951
+ :submit_for_settlement => false,
2952
+ },
2953
+ )
2954
+
2955
+ expect(result.success?).to eq(false)
2956
+ expect(result.errors.for(:transaction).on(:base)[0].code).to eq(Braintree::ErrorCodes::Transaction::Options::SubmitForSettlementIsNotSupportedForNetwork)
2957
+ end
2958
+
2959
+ it "returns an error for transaction when the three_d_secure_pass_thru network does not support the presentment currency" do
2960
+ result = Braintree::Transaction.create(
2961
+ :type => "sale",
2962
+ :currency_iso_code => "USD",
2963
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
2964
+ :credit_card => {
2965
+ :number => Braintree::Test::CreditCardNumbers::Visa,
2966
+ :expiration_date => "05/2009",
2967
+ },
2968
+ :three_d_secure_pass_thru => {
2969
+ :eci_flag => "05",
2970
+ :cavv => "some_cavv",
2971
+ :xid => "some_xid",
2972
+ :three_d_secure_version => "2.2.0",
2973
+ :authentication_response => "Y",
2974
+ :directory_response => "Y",
2975
+ :cavv_algorithm => "2",
2976
+ :network => Braintree::ThreeDSecurePassThru::Network::Eftpos,
2977
+ },
2978
+ )
2979
+
2980
+ expect(result.success?).to eq(false)
2981
+ expect(result.errors.for(:transaction).for(:three_d_secure_pass_thru).on(:network)[0].code).to eq(Braintree::ErrorCodes::Transaction::ThreeDSecureNetworkDoesNotSupportCurrency)
2982
+ end
2983
+
2984
+ it "returns an error for transaction when the three_d_secure_pass_thru network does not support the merchant account currency" do
2985
+ result = Braintree::Transaction.create(
2986
+ :type => "sale",
2987
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
2988
+ :credit_card => {
2989
+ :number => Braintree::Test::CreditCardNumbers::Visa,
2990
+ :expiration_date => "05/2009",
2991
+ },
2992
+ :three_d_secure_pass_thru => {
2993
+ :eci_flag => "05",
2994
+ :cavv => "some_cavv",
2995
+ :xid => "some_xid",
2996
+ :three_d_secure_version => "2.2.0",
2997
+ :authentication_response => "Y",
2998
+ :directory_response => "Y",
2999
+ :cavv_algorithm => "2",
3000
+ :network => Braintree::ThreeDSecurePassThru::Network::Eftpos,
3001
+ },
3002
+ )
3003
+
3004
+ expect(result.success?).to eq(false)
3005
+ expect(result.errors.for(:transaction).for(:three_d_secure_pass_thru).on(:network)[0].code).to eq(Braintree::ErrorCodes::Transaction::ThreeDSecureNetworkDoesNotSupportMerchantAccountCurrency)
3006
+ end
3007
+
2908
3008
  it "returns an error for transaction with three_d_secure_pass_thru when processor settings do not support 3DS for card type" do
2909
3009
  result = Braintree::Transaction.create(
2910
3010
  :merchant_account_id => "heartland_ma",
@@ -5908,7 +6008,7 @@ describe Braintree::Transaction do
5908
6008
  end
5909
6009
  end
5910
6010
 
5911
- xit "Amex Pay with Points" do
6011
+ it "Amex Pay with Points" do
5912
6012
  context "transaction creation" do
5913
6013
  it "succeeds when submit_for_settlement is true" do
5914
6014
  result = Braintree::Transaction.sale(
@@ -6055,7 +6155,7 @@ describe Braintree::Transaction do
6055
6155
  end
6056
6156
 
6057
6157
  context "Pinless debit transaction" do
6058
- xit "succesfully submits for settlement" do
6158
+ it "successfully submits for settlement" do
6059
6159
  # Flaky test
6060
6160
  result = Braintree::Transaction.sale(
6061
6161
  :amount => Braintree::Test::TransactionAmounts::Authorize,
@@ -6367,7 +6467,7 @@ describe Braintree::Transaction do
6367
6467
  expect(leg_errors).to eq([Braintree::ErrorCodes::Transaction::Industry::Leg::TravelFlight::FareAmountCannotBeNegative])
6368
6468
  end
6369
6469
 
6370
- xit "succeeds when level 2 data is provided" do
6470
+ it "succeeds when level 2 data is provided" do
6371
6471
  result = Braintree::Transaction.sale(
6372
6472
  :amount => Braintree::Test::TransactionAmounts::Authorize,
6373
6473
  :merchant_account_id => SpecHelper::FakeAmexDirectMerchantAccountId,
@@ -6391,7 +6491,7 @@ describe Braintree::Transaction do
6391
6491
  expect(result.transaction.status).to eq(Braintree::Transaction::Status::SubmittedForSettlement)
6392
6492
  end
6393
6493
 
6394
- xit "succeeds when level 3 data is provided" do
6494
+ it "succeeds when level 3 data is provided" do
6395
6495
  result = Braintree::Transaction.sale(
6396
6496
  :amount => Braintree::Test::TransactionAmounts::Authorize,
6397
6497
  :merchant_account_id => SpecHelper::FakeAmexDirectMerchantAccountId,
@@ -6532,11 +6632,11 @@ describe Braintree::Transaction do
6532
6632
  expect(result.errors.for(:transaction).on(:amount)[0].code).to eq(Braintree::ErrorCodes::Transaction::SettlementAmountIsTooLarge)
6533
6633
  end
6534
6634
 
6535
- it "returns an error response when the descriptor is invalid" do
6635
+ it "returns an error response when the descriptor name is too long" do
6536
6636
  result = Braintree::Transaction.update_details(transaction.id, {
6537
6637
  :amount => Braintree::Test::TransactionAmounts::Authorize.to_f - 1,
6538
6638
  :descriptor => {
6539
- :name => "invalid descriptor name",
6639
+ :name => "invalid descriptor name that is way too long",
6540
6640
  :phone => "invalid phone",
6541
6641
  :url => "12345678901234"
6542
6642
  },
@@ -58,6 +58,20 @@ describe Braintree::Address do
58
58
  Braintree::Address.update("customer_id", "address_id", :street_address => "456 E Main", :invalid_key => "foo")
59
59
  end.to raise_error(ArgumentError, "invalid keys: invalid_key")
60
60
  end
61
+
62
+ it "raises an error if address_id contains invalid characters" do
63
+ expect do
64
+ Braintree::Address.update("customer_id", "../../foo", :street_address => "456 E Main")
65
+ end.to raise_error(ArgumentError, "address_id contains invalid characters")
66
+ end
67
+ end
68
+
69
+ describe "self.delete" do
70
+ it "raises an error if address_id contains invalid characters" do
71
+ expect do
72
+ Braintree::Address.delete("customer_id", "../../foo")
73
+ end.to raise_error(ArgumentError, "address_id contains invalid characters")
74
+ end
61
75
  end
62
76
 
63
77
  describe "self.find" do
@@ -85,6 +99,24 @@ describe Braintree::Address do
85
99
  Braintree::Address.find("customer_id", 8675309)
86
100
  end.to_not raise_error
87
101
  end
102
+
103
+ it "raises an error if address_id contains invalid characters" do
104
+ expect do
105
+ Braintree::Address.find("customer_id", "../../foo")
106
+ end.to raise_error(ArgumentError, "address_id contains invalid characters")
107
+ end
108
+
109
+ it "raises an error if address_id is a lone dot segment" do
110
+ expect do
111
+ Braintree::Address.find("customer_id", ".")
112
+ end.to raise_error(ArgumentError, "address_id contains invalid characters")
113
+ end
114
+
115
+ it "raises an error if address_id contains a dot" do
116
+ expect do
117
+ Braintree::Address.find("customer_id", "foo.bar")
118
+ end.to raise_error(ArgumentError, "address_id contains invalid characters")
119
+ end
88
120
  end
89
121
 
90
122
  describe "self.new" do
@@ -51,6 +51,7 @@ describe Braintree::CreditCard do
51
51
  :directory_response,
52
52
  :cavv_algorithm,
53
53
  :ds_transaction_id,
54
+ :network,
54
55
  ]},
55
56
  :customer_id,
56
57
  ])
@@ -100,6 +101,7 @@ describe Braintree::CreditCard do
100
101
  :directory_response,
101
102
  :cavv_algorithm,
102
103
  :ds_transaction_id,
104
+ :network,
103
105
  ]},
104
106
  ])
105
107
  end
@@ -164,6 +164,7 @@ describe Braintree::Customer do
164
164
  :directory_response,
165
165
  :cavv_algorithm,
166
166
  :ds_transaction_id,
167
+ :network,
167
168
  ]},
168
169
  ]},
169
170
  {:paypal_account => [
@@ -307,6 +308,7 @@ describe Braintree::Customer do
307
308
  :directory_response,
308
309
  :cavv_algorithm,
309
310
  :ds_transaction_id,
311
+ :network,
310
312
  ]},
311
313
  ]},
312
314
  {:tax_identifiers => [
@@ -278,6 +278,44 @@ describe Braintree::Dispute do
278
278
  end
279
279
  end
280
280
 
281
+ describe "path traversal" do
282
+ [
283
+ :accept,
284
+ :finalize,
285
+ :find,
286
+ ].each do |method_name|
287
+ it "self.#{method_name} raises an exception if the dispute_id is a traversal segment" do
288
+ expect do
289
+ Braintree::Dispute.public_send(method_name, "../../foo")
290
+ end.to raise_error(ArgumentError, "dispute_id contains invalid characters")
291
+ end
292
+ end
293
+
294
+ it "self.add_file_evidence raises an exception if the dispute_id is a traversal segment" do
295
+ expect do
296
+ Braintree::Dispute.add_file_evidence("../../foo", "document_id")
297
+ end.to raise_error(ArgumentError, "dispute_id contains invalid characters")
298
+ end
299
+
300
+ it "self.add_text_evidence raises an exception if the dispute_id is a traversal segment" do
301
+ expect do
302
+ Braintree::Dispute.add_text_evidence("../../foo", "text evidence")
303
+ end.to raise_error(ArgumentError, "dispute_id contains invalid characters")
304
+ end
305
+
306
+ it "self.remove_evidence raises an exception if the dispute_id is a traversal segment" do
307
+ expect do
308
+ Braintree::Dispute.remove_evidence("../../foo", "evidence_id")
309
+ end.to raise_error(ArgumentError, "dispute_id contains invalid characters")
310
+ end
311
+
312
+ it "self.remove_evidence raises an exception if the evidence_id is a traversal segment" do
313
+ expect do
314
+ Braintree::Dispute.remove_evidence("dispute_id", "../../foo")
315
+ end.to raise_error(ArgumentError, "evidence_id contains invalid characters")
316
+ end
317
+ end
318
+
281
319
  describe "initialize" do
282
320
  it "converts string amount_dispute and amount_won" do
283
321
  dispute = Braintree::Dispute._new(attributes)
@@ -128,6 +128,7 @@ describe Braintree::TransactionGateway do
128
128
  :directory_response,
129
129
  :cavv_algorithm,
130
130
  :ds_transaction_id,
131
+ :network,
131
132
  ]
132
133
  },
133
134
  {
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: braintree
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.39.0
4
+ version: 4.40.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Braintree
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-06-15 00:00:00.000000000 Z
11
+ date: 2026-08-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: builder
@@ -195,6 +195,7 @@ files:
195
195
  - lib/braintree/test_transaction.rb
196
196
  - lib/braintree/testing_gateway.rb
197
197
  - lib/braintree/three_d_secure_info.rb
198
+ - lib/braintree/three_d_secure_pass_thru.rb
198
199
  - lib/braintree/transaction.rb
199
200
  - lib/braintree/transaction/address_details.rb
200
201
  - lib/braintree/transaction/apple_pay_details.rb