braintree 4.39.0 → 4.41.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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/lib/braintree/address_gateway.rb +13 -3
  3. data/lib/braintree/client_token_gateway.rb +10 -1
  4. data/lib/braintree/credit_card_gateway.rb +9 -2
  5. data/lib/braintree/credit_card_verification_gateway.rb +3 -0
  6. data/lib/braintree/customer_gateway.rb +11 -3
  7. data/lib/braintree/dispute_gateway.rb +7 -7
  8. data/lib/braintree/error_codes.rb +11 -0
  9. data/lib/braintree/http.rb +4 -2
  10. data/lib/braintree/merchant_account_gateway.rb +2 -0
  11. data/lib/braintree/payment_method_gateway.rb +7 -1
  12. data/lib/braintree/payment_method_nonce_gateway.rb +4 -0
  13. data/lib/braintree/paypal_account_gateway.rb +6 -1
  14. data/lib/braintree/plan_gateway.rb +4 -0
  15. data/lib/braintree/sepa_direct_debit_account_gateway.rb +4 -0
  16. data/lib/braintree/subscription_gateway.rb +6 -0
  17. data/lib/braintree/testing_gateway.rb +4 -0
  18. data/lib/braintree/three_d_secure_pass_thru.rb +11 -0
  19. data/lib/braintree/transaction.rb +6 -0
  20. data/lib/braintree/transaction_gateway.rb +17 -7
  21. data/lib/braintree/transaction_line_item_gateway.rb +3 -1
  22. data/lib/braintree/transaction_search.rb +1 -0
  23. data/lib/braintree/us_bank_account_gateway.rb +2 -0
  24. data/lib/braintree/us_bank_account_verification_gateway.rb +4 -0
  25. data/lib/braintree/util.rb +5 -0
  26. data/lib/braintree/version.rb +1 -1
  27. data/lib/braintree.rb +1 -0
  28. data/spec/integration/braintree/advanced_search_spec.rb +4 -7
  29. data/spec/integration/braintree/braintree_gateway_spec.rb +1 -2
  30. data/spec/integration/braintree/client_api/client_token_spec.rb +14 -0
  31. data/spec/integration/braintree/credit_card_spec.rb +94 -2
  32. data/spec/integration/braintree/credit_card_verification_spec.rb +33 -0
  33. data/spec/integration/braintree/customer_spec.rb +196 -5
  34. data/spec/integration/braintree/http_spec.rb +1 -1
  35. data/spec/integration/braintree/payment_method_spec.rb +77 -7
  36. data/spec/integration/braintree/samsung_pay_card_spec.rb +1 -1
  37. data/spec/integration/braintree/transaction_search_spec.rb +113 -13
  38. data/spec/integration/braintree/transaction_spec.rb +197 -17
  39. data/spec/unit/braintree/address_spec.rb +32 -0
  40. data/spec/unit/braintree/client_token_spec.rb +72 -0
  41. data/spec/unit/braintree/credit_card_spec.rb +28 -0
  42. data/spec/unit/braintree/credit_card_verification_spec.rb +8 -0
  43. data/spec/unit/braintree/customer_spec.rb +28 -0
  44. data/spec/unit/braintree/dispute_spec.rb +38 -0
  45. data/spec/unit/braintree/http_spec.rb +44 -0
  46. data/spec/unit/braintree/merchant_account_spec.rb +11 -0
  47. data/spec/unit/braintree/package_tracking_spec.rb +2 -2
  48. data/spec/unit/braintree/payment_method_nonce_spec.rb +14 -0
  49. data/spec/unit/braintree/payment_method_spec.rb +20 -0
  50. data/spec/unit/braintree/paypal_account_spec.rb +20 -0
  51. data/spec/unit/braintree/plan_gateway_spec.rb +30 -0
  52. data/spec/unit/braintree/sepa_debit_account_spec.rb +14 -0
  53. data/spec/unit/braintree/subscription_spec.rb +20 -0
  54. data/spec/unit/braintree/test_transaction_spec.rb +18 -0
  55. data/spec/unit/braintree/transaction_gateway_spec.rb +11 -0
  56. data/spec/unit/braintree/transaction_line_item_spec.rb +11 -0
  57. data/spec/unit/braintree/transaction_search_spec.rb +25 -0
  58. data/spec/unit/braintree/transaction_spec.rb +68 -6
  59. data/spec/unit/braintree/us_bank_account_spec.rb +8 -0
  60. data/spec/unit/braintree/us_bank_account_verification_spec.rb +14 -0
  61. data/spec/unit/braintree/util_spec.rb +37 -0
  62. metadata +8 -3
@@ -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
@@ -255,6 +257,93 @@ describe Braintree::Transaction, "search" do
255
257
  expect(collection.maximum_size).to eq(0)
256
258
  end
257
259
 
260
+ it "searches on ach_type" do
261
+ same_day_transaction = Braintree::Transaction.find("sameday_ach_sameday_requested")
262
+ standard_transaction = Braintree::Transaction.find("standard_ach_standard_requested")
263
+
264
+ collection = Braintree::Transaction.search do |search|
265
+ search.id.is same_day_transaction.id
266
+ search.ach_type.is Braintree::Transaction::AchType::SameDay
267
+ end
268
+
269
+ expect(collection.maximum_size).to eq(1)
270
+ expect(collection.first.id).to eq(same_day_transaction.id)
271
+
272
+ collection = Braintree::Transaction.search do |search|
273
+ search.id.is same_day_transaction.id
274
+ search.ach_type.is Braintree::Transaction::AchType::Standard
275
+ end
276
+
277
+ expect(collection.maximum_size).to eq(0)
278
+
279
+ collection = Braintree::Transaction.search do |search|
280
+ search.id.is standard_transaction.id
281
+ search.ach_type.is Braintree::Transaction::AchType::Standard
282
+ end
283
+
284
+ expect(collection.maximum_size).to eq(1)
285
+ expect(collection.first.id).to eq(standard_transaction.id)
286
+
287
+ collection = Braintree::Transaction.search do |search|
288
+ search.id.is standard_transaction.id
289
+ search.ach_type.is Braintree::Transaction::AchType::SameDay
290
+ end
291
+
292
+ expect(collection.maximum_size).to eq(0)
293
+
294
+ collection = Braintree::Transaction.search do |search|
295
+ search.id.is same_day_transaction.id
296
+ search.ach_type.in [
297
+ Braintree::Transaction::AchType::SameDay,
298
+ Braintree::Transaction::AchType::Standard
299
+ ]
300
+ end
301
+
302
+ expect(collection.maximum_size).to eq(1)
303
+ expect(collection.first.id).to eq(same_day_transaction.id)
304
+
305
+ collection = Braintree::Transaction.search do |search|
306
+ search.id.is standard_transaction.id
307
+ search.ach_type.in [
308
+ Braintree::Transaction::AchType::SameDay,
309
+ Braintree::Transaction::AchType::Standard
310
+ ]
311
+ end
312
+
313
+ expect(collection.maximum_size).to eq(1)
314
+ expect(collection.first.id).to eq(standard_transaction.id)
315
+
316
+ divergent_transaction = Braintree::Transaction.find("standard_ach_sameday_requested")
317
+ expect(divergent_transaction.ach_type).to eq(Braintree::Transaction::AchType::Standard)
318
+ expect(divergent_transaction.requested_ach_type).to eq(Braintree::Transaction::AchType::SameDay)
319
+
320
+ collection = Braintree::Transaction.search do |search|
321
+ search.id.is divergent_transaction.id
322
+ search.ach_type.is Braintree::Transaction::AchType::Standard
323
+ end
324
+
325
+ expect(collection.maximum_size).to eq(1)
326
+ expect(collection.first.id).to eq(divergent_transaction.id)
327
+
328
+ collection = Braintree::Transaction.search do |search|
329
+ search.id.is divergent_transaction.id
330
+ search.ach_type.is Braintree::Transaction::AchType::SameDay
331
+ end
332
+
333
+ expect(collection.maximum_size).to eq(0)
334
+
335
+ collection = Braintree::Transaction.search do |search|
336
+ search.id.is divergent_transaction.id
337
+ search.ach_type.in [
338
+ Braintree::Transaction::AchType::SameDay,
339
+ Braintree::Transaction::AchType::Standard
340
+ ]
341
+ end
342
+
343
+ expect(collection.maximum_size).to eq(1)
344
+ expect(collection.first.id).to eq(divergent_transaction.id)
345
+ end
346
+
258
347
  it "searches on credit_card_customer_location" do
259
348
  transaction = Braintree::Transaction.sale!(
260
349
  :amount => Braintree::Test::TransactionAmounts::Authorize,
@@ -512,6 +601,7 @@ describe Braintree::Transaction, "search" do
512
601
  end
513
602
 
514
603
  it "finds expired authorizations by status" do
604
+ skip "pending search fix"
515
605
  collection = Braintree::Transaction.search do |search|
516
606
  search.status.in Braintree::Transaction::Status::AuthorizationExpired
517
607
  end
@@ -614,7 +704,7 @@ describe Braintree::Transaction, "search" do
614
704
  expect(collection.first.id).to eq(transaction_id)
615
705
  end
616
706
 
617
- xit "searches on debit_network" do
707
+ it "searches on debit_network" do
618
708
  transaction = Braintree::Transaction.sale!(
619
709
  :amount => Braintree::Test::TransactionAmounts::Authorize,
620
710
  :merchant_account_id => SpecHelper::PinlessDebitMerchantAccountId,
@@ -658,6 +748,14 @@ describe Braintree::Transaction, "search" do
658
748
  end
659
749
  end.to raise_error(ArgumentError)
660
750
  end
751
+
752
+ it "raises an exception on invalid ach_type" do
753
+ expect do
754
+ Braintree::Transaction.search do |search|
755
+ search.ach_type.is "invalid_ach_type"
756
+ end
757
+ end.to raise_error(ArgumentError)
758
+ end
661
759
  end
662
760
 
663
761
  context "range fields" do
@@ -854,6 +952,7 @@ describe Braintree::Transaction, "search" do
854
952
  context "ach return response created at" do
855
953
  it "it finds records within date range of the custom field" do
856
954
  date_search = Braintree::Transaction.search do |search|
955
+ search.ids.in ["ach_txn_ret1", "ach_txn_ret2", "ach_txn_ret3", "ach_txn_ret4"]
857
956
  search.ach_return_responses_created_at.between(DateTime.now - 1.0, DateTime.now + 1.0)
858
957
  end
859
958
 
@@ -862,6 +961,7 @@ describe Braintree::Transaction, "search" do
862
961
 
863
962
  it "it does not find records not within date range of the custom field" do
864
963
  neg_date_search = Braintree::Transaction.search do |search|
964
+ search.ids.in ["ach_txn_ret1", "ach_txn_ret2", "ach_txn_ret3", "ach_txn_ret4"]
865
965
  search.ach_return_responses_created_at.between(DateTime.now + 1.0, DateTime.now - 1.0)
866
966
  end
867
967
 
@@ -1006,7 +1106,7 @@ describe Braintree::Transaction, "search" do
1006
1106
  }
1007
1107
  end
1008
1108
 
1009
- xit "searches on dispute_date in UTC" do
1109
+ it "searches on dispute_date in UTC" do
1010
1110
  collection = Braintree::Transaction.search do |search|
1011
1111
  search.id.is @disputed_transaction.id
1012
1112
  search.dispute_date.between(
@@ -1043,7 +1143,7 @@ describe Braintree::Transaction, "search" do
1043
1143
  expect(collection.first.id).to eq(@disputed_transaction.id)
1044
1144
  end
1045
1145
 
1046
- xit "searches on dispute_date in local time" do
1146
+ it "searches on dispute_date in local time" do
1047
1147
  now = @disputed_time.localtime("-06:00")
1048
1148
 
1049
1149
  collection = Braintree::Transaction.search do |search|
@@ -1073,7 +1173,7 @@ describe Braintree::Transaction, "search" do
1073
1173
  expect(collection.maximum_size).to eq(1)
1074
1174
  end
1075
1175
 
1076
- xit "searches on dispute_date with date ranges" do
1176
+ it "searches on dispute_date with date ranges" do
1077
1177
  collection = Braintree::Transaction.search do |search|
1078
1178
  search.id.is @disputed_transaction.id
1079
1179
  search.dispute_date.between(
@@ -1151,6 +1251,7 @@ describe Braintree::Transaction, "search" do
1151
1251
  end
1152
1252
 
1153
1253
  it "finds expired authorizations in a given range" do
1254
+ skip "pending search fix"
1154
1255
  collection = Braintree::Transaction.search do |search|
1155
1256
  search.authorization_expired_at.between(
1156
1257
  Date.today - 2,
@@ -1379,8 +1480,7 @@ describe Braintree::Transaction, "search" do
1379
1480
  end
1380
1481
  end
1381
1482
 
1382
- #Disabling until we have a more stable CI
1383
- xit "returns multiple results" do
1483
+ it "returns multiple results" do
1384
1484
  collection = Braintree::Transaction.search
1385
1485
  expect(collection.maximum_size).to be > 100
1386
1486
 
@@ -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",
@@ -5133,6 +5233,28 @@ describe Braintree::Transaction do
5133
5233
  transaction = Braintree::Transaction.find(transaction.id)
5134
5234
  expect(transaction.refund_ids.sort).to eq([transaction_1.id, transaction_2.id].sort)
5135
5235
  end
5236
+
5237
+ it "allows partial refund with surcharge_amount" do
5238
+ transaction = Braintree::Transaction.sale!(
5239
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
5240
+ :surcharge_amount => "1.00",
5241
+ :credit_card => {
5242
+ :number => Braintree::Test::CreditCardNumbers::Visa,
5243
+ :expiration_date => "05/2009"
5244
+ },
5245
+ :options => {
5246
+ :submit_for_settlement => true
5247
+ },
5248
+ )
5249
+ config = Braintree::Configuration.instantiate
5250
+ config.http.put("#{config.base_merchant_path}/transactions/#{transaction.id}/settle")
5251
+ transaction = Braintree::Transaction.find(transaction.id)
5252
+
5253
+ result = Braintree::Transaction.refund(transaction.id, :amount => transaction.amount / 2, :surcharge_amount => "0.50")
5254
+ expect(result.success?).to eq(true)
5255
+ expect(result.transaction.type).to eq("credit")
5256
+ expect(result.transaction.surcharge_amount).to eq(BigDecimal("0.50"))
5257
+ end
5136
5258
  end
5137
5259
 
5138
5260
  it "returns a successful result if successful" do
@@ -5172,6 +5294,28 @@ describe Braintree::Transaction do
5172
5294
  expect(result.success?).to eq(false)
5173
5295
  expect(result.errors.for(:transaction).on(:base)[0].code).to eq(Braintree::ErrorCodes::Transaction::CannotRefundUnlessSettled)
5174
5296
  end
5297
+
5298
+ it "accepts surcharge_amount field in refund" do
5299
+ transaction = Braintree::Transaction.sale!(
5300
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
5301
+ :surcharge_amount => "1.00",
5302
+ :credit_card => {
5303
+ :number => Braintree::Test::CreditCardNumbers::Visa,
5304
+ :expiration_date => "05/2009"
5305
+ },
5306
+ :options => {
5307
+ :submit_for_settlement => true
5308
+ },
5309
+ )
5310
+ config = Braintree::Configuration.instantiate
5311
+ config.http.put("#{config.base_merchant_path}/transactions/#{transaction.id}/settle")
5312
+ transaction = Braintree::Transaction.find(transaction.id)
5313
+
5314
+ result = Braintree::Transaction.refund(transaction.id, :surcharge_amount => "1.00")
5315
+ expect(result.success?).to eq(true)
5316
+ expect(result.transaction.type).to eq("credit")
5317
+ expect(result.transaction.surcharge_amount).to eq(BigDecimal("1.00"))
5318
+ end
5175
5319
  end
5176
5320
 
5177
5321
  describe "self.refund!" do
@@ -5908,7 +6052,7 @@ describe Braintree::Transaction do
5908
6052
  end
5909
6053
  end
5910
6054
 
5911
- xit "Amex Pay with Points" do
6055
+ it "Amex Pay with Points" do
5912
6056
  context "transaction creation" do
5913
6057
  it "succeeds when submit_for_settlement is true" do
5914
6058
  result = Braintree::Transaction.sale(
@@ -6055,7 +6199,7 @@ describe Braintree::Transaction do
6055
6199
  end
6056
6200
 
6057
6201
  context "Pinless debit transaction" do
6058
- xit "succesfully submits for settlement" do
6202
+ it "successfully submits for settlement" do
6059
6203
  # Flaky test
6060
6204
  result = Braintree::Transaction.sale(
6061
6205
  :amount => Braintree::Test::TransactionAmounts::Authorize,
@@ -6367,7 +6511,7 @@ describe Braintree::Transaction do
6367
6511
  expect(leg_errors).to eq([Braintree::ErrorCodes::Transaction::Industry::Leg::TravelFlight::FareAmountCannotBeNegative])
6368
6512
  end
6369
6513
 
6370
- xit "succeeds when level 2 data is provided" do
6514
+ it "succeeds when level 2 data is provided" do
6371
6515
  result = Braintree::Transaction.sale(
6372
6516
  :amount => Braintree::Test::TransactionAmounts::Authorize,
6373
6517
  :merchant_account_id => SpecHelper::FakeAmexDirectMerchantAccountId,
@@ -6391,7 +6535,7 @@ describe Braintree::Transaction do
6391
6535
  expect(result.transaction.status).to eq(Braintree::Transaction::Status::SubmittedForSettlement)
6392
6536
  end
6393
6537
 
6394
- xit "succeeds when level 3 data is provided" do
6538
+ it "succeeds when level 3 data is provided" do
6395
6539
  result = Braintree::Transaction.sale(
6396
6540
  :amount => Braintree::Test::TransactionAmounts::Authorize,
6397
6541
  :merchant_account_id => SpecHelper::FakeAmexDirectMerchantAccountId,
@@ -6532,11 +6676,11 @@ describe Braintree::Transaction do
6532
6676
  expect(result.errors.for(:transaction).on(:amount)[0].code).to eq(Braintree::ErrorCodes::Transaction::SettlementAmountIsTooLarge)
6533
6677
  end
6534
6678
 
6535
- it "returns an error response when the descriptor is invalid" do
6679
+ it "returns an error response when the descriptor name is too long" do
6536
6680
  result = Braintree::Transaction.update_details(transaction.id, {
6537
6681
  :amount => Braintree::Test::TransactionAmounts::Authorize.to_f - 1,
6538
6682
  :descriptor => {
6539
- :name => "invalid descriptor name",
6683
+ :name => "invalid descriptor name that is way too long",
6540
6684
  :phone => "invalid phone",
6541
6685
  :url => "12345678901234"
6542
6686
  },
@@ -8079,7 +8223,7 @@ describe Braintree::Transaction do
8079
8223
  end
8080
8224
 
8081
8225
  context "Surcharge Amount" do
8082
- it "accepts surcharge_amount field" do
8226
+ it "accepts surcharge_amount field for sale transactions" do
8083
8227
  result = Braintree::Transaction.create(
8084
8228
  :type => "sale",
8085
8229
  :amount => "10.00",
@@ -8093,5 +8237,41 @@ describe Braintree::Transaction do
8093
8237
  expect(result.success?).to eq(true)
8094
8238
  expect(result.transaction.surcharge_amount).to eq(BigDecimal("1.00"))
8095
8239
  end
8240
+
8241
+ it "accepts surcharge_amount field for blind credit" do
8242
+ result = Braintree::Transaction.create(
8243
+ :type => "credit",
8244
+ :amount => "10.00",
8245
+ :surcharge_amount => "1.00",
8246
+ :credit_card => {
8247
+ :number => Braintree::Test::CreditCardNumbers::Visa,
8248
+ :expiration_date => "05/2029"
8249
+ },
8250
+ )
8251
+
8252
+ expect(result.success?).to eq(true)
8253
+ expect(result.transaction.surcharge_amount).to eq(BigDecimal("1.00"))
8254
+ end
8255
+ end
8256
+
8257
+ describe "path traversal" do
8258
+ it "self.void rejects a traversal transaction_id and does not void the victim transaction" do
8259
+ victim_transaction = Braintree::Transaction.sale!(
8260
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
8261
+ :credit_card => {
8262
+ :number => Braintree::Test::CreditCardNumbers::Visa,
8263
+ :expiration_date => "05/2009"
8264
+ },
8265
+ :options => {:submit_for_settlement => false},
8266
+ )
8267
+ traversal_id = "../transactions/#{victim_transaction.id}"
8268
+
8269
+ expect do
8270
+ Braintree::Transaction.void(traversal_id)
8271
+ end.to raise_error(ArgumentError, "transaction_id contains invalid characters")
8272
+
8273
+ unaffected_transaction = Braintree::Transaction.find(victim_transaction.id)
8274
+ expect(unaffected_transaction.status).to eq(Braintree::Transaction::Status::Authorized)
8275
+ end
8096
8276
  end
8097
8277
  end
@@ -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