braintree 4.40.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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/lib/braintree/client_token_gateway.rb +10 -1
  3. data/lib/braintree/credit_card_gateway.rb +8 -2
  4. data/lib/braintree/credit_card_verification_gateway.rb +2 -0
  5. data/lib/braintree/customer_gateway.rb +11 -3
  6. data/lib/braintree/http.rb +4 -2
  7. data/lib/braintree/merchant_account_gateway.rb +2 -0
  8. data/lib/braintree/payment_method_gateway.rb +6 -1
  9. data/lib/braintree/payment_method_nonce_gateway.rb +4 -0
  10. data/lib/braintree/paypal_account_gateway.rb +6 -1
  11. data/lib/braintree/plan_gateway.rb +4 -0
  12. data/lib/braintree/sepa_direct_debit_account_gateway.rb +4 -0
  13. data/lib/braintree/subscription_gateway.rb +6 -0
  14. data/lib/braintree/testing_gateway.rb +4 -0
  15. data/lib/braintree/transaction.rb +6 -0
  16. data/lib/braintree/transaction_gateway.rb +16 -7
  17. data/lib/braintree/transaction_line_item_gateway.rb +3 -1
  18. data/lib/braintree/transaction_search.rb +1 -0
  19. data/lib/braintree/us_bank_account_gateway.rb +2 -0
  20. data/lib/braintree/us_bank_account_verification_gateway.rb +4 -0
  21. data/lib/braintree/version.rb +1 -1
  22. data/spec/integration/braintree/client_api/client_token_spec.rb +14 -0
  23. data/spec/integration/braintree/customer_spec.rb +43 -0
  24. data/spec/integration/braintree/transaction_search_spec.rb +95 -0
  25. data/spec/integration/braintree/transaction_spec.rb +81 -1
  26. data/spec/unit/braintree/client_token_spec.rb +72 -0
  27. data/spec/unit/braintree/credit_card_spec.rb +26 -0
  28. data/spec/unit/braintree/credit_card_verification_spec.rb +8 -0
  29. data/spec/unit/braintree/customer_spec.rb +26 -0
  30. data/spec/unit/braintree/http_spec.rb +44 -0
  31. data/spec/unit/braintree/merchant_account_spec.rb +11 -0
  32. data/spec/unit/braintree/package_tracking_spec.rb +2 -2
  33. data/spec/unit/braintree/payment_method_nonce_spec.rb +14 -0
  34. data/spec/unit/braintree/payment_method_spec.rb +20 -0
  35. data/spec/unit/braintree/paypal_account_spec.rb +20 -0
  36. data/spec/unit/braintree/plan_gateway_spec.rb +30 -0
  37. data/spec/unit/braintree/sepa_debit_account_spec.rb +14 -0
  38. data/spec/unit/braintree/subscription_spec.rb +20 -0
  39. data/spec/unit/braintree/test_transaction_spec.rb +18 -0
  40. data/spec/unit/braintree/transaction_gateway_spec.rb +10 -0
  41. data/spec/unit/braintree/transaction_line_item_spec.rb +11 -0
  42. data/spec/unit/braintree/transaction_search_spec.rb +25 -0
  43. data/spec/unit/braintree/transaction_spec.rb +68 -6
  44. data/spec/unit/braintree/us_bank_account_spec.rb +8 -0
  45. data/spec/unit/braintree/us_bank_account_verification_spec.rb +14 -0
  46. data/spec/unit/braintree/util_spec.rb +37 -0
  47. metadata +7 -3
@@ -257,6 +257,93 @@ describe Braintree::Transaction, "search" do
257
257
  expect(collection.maximum_size).to eq(0)
258
258
  end
259
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
+
260
347
  it "searches on credit_card_customer_location" do
261
348
  transaction = Braintree::Transaction.sale!(
262
349
  :amount => Braintree::Test::TransactionAmounts::Authorize,
@@ -661,6 +748,14 @@ describe Braintree::Transaction, "search" do
661
748
  end
662
749
  end.to raise_error(ArgumentError)
663
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
664
759
  end
665
760
 
666
761
  context "range fields" do
@@ -5233,6 +5233,28 @@ describe Braintree::Transaction do
5233
5233
  transaction = Braintree::Transaction.find(transaction.id)
5234
5234
  expect(transaction.refund_ids.sort).to eq([transaction_1.id, transaction_2.id].sort)
5235
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
5236
5258
  end
5237
5259
 
5238
5260
  it "returns a successful result if successful" do
@@ -5272,6 +5294,28 @@ describe Braintree::Transaction do
5272
5294
  expect(result.success?).to eq(false)
5273
5295
  expect(result.errors.for(:transaction).on(:base)[0].code).to eq(Braintree::ErrorCodes::Transaction::CannotRefundUnlessSettled)
5274
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
5275
5319
  end
5276
5320
 
5277
5321
  describe "self.refund!" do
@@ -8179,7 +8223,7 @@ describe Braintree::Transaction do
8179
8223
  end
8180
8224
 
8181
8225
  context "Surcharge Amount" do
8182
- it "accepts surcharge_amount field" do
8226
+ it "accepts surcharge_amount field for sale transactions" do
8183
8227
  result = Braintree::Transaction.create(
8184
8228
  :type => "sale",
8185
8229
  :amount => "10.00",
@@ -8193,5 +8237,41 @@ describe Braintree::Transaction do
8193
8237
  expect(result.success?).to eq(true)
8194
8238
  expect(result.transaction.surcharge_amount).to eq(BigDecimal("1.00"))
8195
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
8196
8276
  end
8197
8277
  end
@@ -20,6 +20,78 @@ module Braintree
20
20
  )
21
21
  }.to raise_error(ArgumentError, /created_at, public_key/)
22
22
  end
23
+
24
+ context "with preferred_payment_method_token" do
25
+ let(:config) { SpecHelper::TestMerchantConfig }
26
+ let(:gateway) { Gateway.new(config) }
27
+ let(:http) { double(:http) }
28
+
29
+ before do
30
+ allow(config).to receive(:http).and_return(http)
31
+ allow(Configuration).to receive(:gateway).and_return(gateway)
32
+ end
33
+
34
+ def expect_client_token_post(options)
35
+ expect(http).to receive(:post).with(
36
+ "#{config.base_merchant_path}/client_token",
37
+ :client_token => options,
38
+ ).and_return(:client_token => {:value => "client-token"})
39
+ end
40
+
41
+ it "renames preferred_payment_method_token to payment_method_id" do
42
+ expect_client_token_post(
43
+ :payment_method_id => "a-pmt",
44
+ :version => ClientToken::DEFAULT_VERSION,
45
+ )
46
+
47
+ client_token = Braintree::ClientToken.generate(
48
+ :preferred_payment_method_token => "a-pmt",
49
+ )
50
+
51
+ expect(client_token).to eq("client-token")
52
+ end
53
+
54
+ it "renames string preferred_payment_method_token to payment_method_id" do
55
+ expect_client_token_post(
56
+ :payment_method_id => "a-pmt",
57
+ :version => ClientToken::DEFAULT_VERSION,
58
+ )
59
+
60
+ client_token = Braintree::ClientToken.generate(
61
+ "preferred_payment_method_token" => "a-pmt",
62
+ )
63
+
64
+ expect(client_token).to eq("client-token")
65
+ end
66
+
67
+ it "renames preferred_payment_method_token when the value is nil" do
68
+ expect_client_token_post(
69
+ :payment_method_id => nil,
70
+ :version => ClientToken::DEFAULT_VERSION,
71
+ )
72
+
73
+ client_token = Braintree::ClientToken.generate(
74
+ :preferred_payment_method_token => nil,
75
+ )
76
+
77
+ expect(client_token).to eq("client-token")
78
+ end
79
+
80
+ it "does not mutate the caller's options hash" do
81
+ options = {:preferred_payment_method_token => "a-pmt"}
82
+ expect(http).to receive(:post).twice.with(
83
+ "#{config.base_merchant_path}/client_token",
84
+ :client_token => {
85
+ :payment_method_id => "a-pmt",
86
+ :version => ClientToken::DEFAULT_VERSION,
87
+ },
88
+ ).and_return(:client_token => {:value => "client-token"})
89
+
90
+ expect(Braintree::ClientToken.generate(options)).to eq("client-token")
91
+ expect(Braintree::ClientToken.generate(options)).to eq("client-token")
92
+ expect(options).to eq(:preferred_payment_method_token => "a-pmt")
93
+ end
94
+ end
23
95
  end
24
96
 
25
97
  context "adding credit_card options with no customer ID" do
@@ -293,4 +293,30 @@ describe Braintree::CreditCard do
293
293
  card = Braintree::CreditCard._new(:gateway, {:purchase => "No"})
294
294
  expect(card.purchase).to eq("No")
295
295
  end
296
+
297
+ describe "path traversal" do
298
+ it "self.delete raises an exception if the token is a traversal segment" do
299
+ expect do
300
+ Braintree::CreditCard.delete("../payment_methods/paypal_account/victim_token")
301
+ end.to raise_error(ArgumentError, "token contains invalid characters")
302
+ end
303
+
304
+ it "self.find raises an exception if the token is a traversal segment" do
305
+ expect do
306
+ Braintree::CreditCard.find("../payment_methods/paypal_account/victim_token")
307
+ end.to raise_error(ArgumentError, "token contains invalid characters")
308
+ end
309
+
310
+ it "self.from_nonce raises an exception if the nonce is a traversal segment" do
311
+ expect do
312
+ Braintree::CreditCard.from_nonce("../payment_methods/paypal_account/victim_token")
313
+ end.to raise_error(ArgumentError, "nonce contains invalid characters")
314
+ end
315
+
316
+ it "self.update raises an exception if the token is a traversal segment" do
317
+ expect do
318
+ Braintree::CreditCard.update("../payment_methods/paypal_account/victim_token", :cvv => "123")
319
+ end.to raise_error(ArgumentError, "token contains invalid characters")
320
+ end
321
+ end
296
322
  end
@@ -183,4 +183,12 @@ describe Braintree::CreditCardVerification do
183
183
  expect(verification.credit_card[:payment_account_reference]).to eq("V0010013019339005665779448477")
184
184
  end
185
185
  end
186
+
187
+ describe "path traversal" do
188
+ it "self.find raises an exception if the id is a traversal segment" do
189
+ expect do
190
+ Braintree::CreditCardVerification.find("../verifications/victim_id")
191
+ end.to raise_error(ArgumentError, "id contains invalid characters")
192
+ end
193
+ end
186
194
  end
@@ -415,4 +415,30 @@ describe Braintree::Customer do
415
415
  end.to raise_error(NoMethodError, /protected method .new/)
416
416
  end
417
417
  end
418
+
419
+ describe "path traversal" do
420
+ it "self.delete raises an exception if the customer_id is a traversal segment" do
421
+ expect do
422
+ Braintree::Customer.delete("../transactions/some_id/void")
423
+ end.to raise_error(ArgumentError, "customer_id contains invalid characters")
424
+ end
425
+
426
+ it "self.find raises an exception if the customer_id is a traversal segment" do
427
+ expect do
428
+ Braintree::Customer.find("../transactions/some_id/void")
429
+ end.to raise_error(ArgumentError, "customer_id contains invalid characters")
430
+ end
431
+
432
+ it "self.update raises an exception if the customer_id is a traversal segment" do
433
+ expect do
434
+ Braintree::Customer.update("../transactions/some_id/void", :first_name => "HackerOne")
435
+ end.to raise_error(ArgumentError, "customer_id contains invalid characters")
436
+ end
437
+
438
+ it "self.transactions raises an exception if the customer_id is a traversal segment" do
439
+ expect do
440
+ Braintree::Customer.transactions("../transactions/some_id/void")
441
+ end.to raise_error(ArgumentError, "customer_id contains invalid characters")
442
+ end
443
+ end
418
444
  end
@@ -183,6 +183,50 @@ END
183
183
  end
184
184
  end
185
185
 
186
+ describe "#delete" do
187
+ it "appends the query string to the path when query_params are present" do
188
+ http = Braintree::Http.new(Braintree::Configuration.new)
189
+ response = double("response", :code => "200")
190
+
191
+ expect(http).to receive(:_http_do).with(Net::HTTP::Delete, "/customers?id=123").and_return(response)
192
+
193
+ http.delete("/customers", :id => 123)
194
+ end
195
+
196
+ it "does not append a query string when query_params are empty" do
197
+ http = Braintree::Http.new(Braintree::Configuration.new)
198
+ response = double("response", :code => "200")
199
+
200
+ expect(http).to receive(:_http_do).with(Net::HTTP::Delete, "/customers").and_return(response)
201
+
202
+ http.delete("/customers")
203
+ end
204
+ end
205
+
206
+ describe "#get" do
207
+ it "appends the query string to the path when query_params are present" do
208
+ http = Braintree::Http.new(Braintree::Configuration.new)
209
+ response = double("response", :code => "200")
210
+ allow(http).to receive(:_body).with(response).and_return("")
211
+ allow(Braintree::Xml).to receive(:hash_from_xml).with("").and_return({})
212
+
213
+ expect(http).to receive(:_http_do).with(Net::HTTP::Get, "/customers?id=123").and_return(response)
214
+
215
+ http.get("/customers", :id => 123)
216
+ end
217
+
218
+ it "does not append a query string when query_params are empty" do
219
+ http = Braintree::Http.new(Braintree::Configuration.new)
220
+ response = double("response", :code => "200")
221
+ allow(http).to receive(:_body).with(response).and_return("")
222
+ allow(Braintree::Xml).to receive(:hash_from_xml).with("").and_return({})
223
+
224
+ expect(http).to receive(:_http_do).with(Net::HTTP::Get, "/customers").and_return(response)
225
+
226
+ http.get("/customers")
227
+ end
228
+ end
229
+
186
230
  describe "_build_query_string" do
187
231
  it "returns an empty string for empty query params" do
188
232
  expect(Braintree::Http.new(:config)._build_query_string({})).to eq("")
@@ -0,0 +1,11 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe Braintree::MerchantAccount do
4
+ describe "path traversal" do
5
+ it "self.find raises an exception if the merchant_account_id is a traversal segment" do
6
+ expect do
7
+ Braintree::MerchantAccount.find("../transactions/some_id/void")
8
+ end.to raise_error(ArgumentError, "merchant_account_id contains invalid characters")
9
+ end
10
+ end
11
+ end
@@ -24,8 +24,8 @@ describe "Package Tracking Unit Tests" do
24
24
 
25
25
  it "raises an ArgumentError if transaction_id is an invalid format" do
26
26
  expect do
27
- Braintree::Transaction.package_tracking("invalid-transaction-id", {})
28
- end.to raise_error(ArgumentError, "transaction_id is invalid")
27
+ Braintree::Transaction.package_tracking("invalid/transaction/id", {})
28
+ end.to raise_error(ArgumentError, "transaction_id contains invalid characters")
29
29
  end
30
30
 
31
31
  it "raises an exception if attributes contain an invalid key" do
@@ -47,4 +47,18 @@ describe Braintree::PaymentMethodNonce do
47
47
  expect(payment_method_nonce.default?).to be true
48
48
  end
49
49
  end
50
+
51
+ describe "path traversal" do
52
+ it "self.create raises an exception if the payment_method_token is a traversal segment" do
53
+ expect do
54
+ Braintree::PaymentMethodNonce.create("../payment_method_nonces/victim_nonce")
55
+ end.to raise_error(ArgumentError, "payment_method_token contains invalid characters")
56
+ end
57
+
58
+ it "self.find raises an exception if the payment_method_nonce is a traversal segment" do
59
+ expect do
60
+ Braintree::PaymentMethodNonce.find("../payment_method_nonces/victim_nonce")
61
+ end.to raise_error(ArgumentError, "payment_method_nonce contains invalid characters")
62
+ end
63
+ end
50
64
  end
@@ -144,4 +144,24 @@ describe Braintree::PaymentMethod do
144
144
  end.to_not raise_error
145
145
  end
146
146
  end
147
+
148
+ describe "path traversal" do
149
+ it "self.find raises an exception if the token is a traversal segment" do
150
+ expect do
151
+ Braintree::PaymentMethod.find("../customers/some_id/transaction_ids")
152
+ end.to raise_error(ArgumentError, "token contains invalid characters")
153
+ end
154
+
155
+ it "self.update raises an exception if the token is a traversal segment" do
156
+ expect do
157
+ Braintree::PaymentMethod.update("../customers/some_id/transaction_ids", {})
158
+ end.to raise_error(ArgumentError, "token contains invalid characters")
159
+ end
160
+
161
+ it "self.delete raises an exception if the token is a traversal segment" do
162
+ expect do
163
+ Braintree::PaymentMethod.delete("../customers/some_id/transaction_ids")
164
+ end.to raise_error(ArgumentError, "token contains invalid characters")
165
+ end
166
+ end
147
167
  end
@@ -50,4 +50,24 @@ describe Braintree::PayPalAccount do
50
50
  expect(paypal_account.edit_paypal_vault_id).to eq(mock_edit_paypal_vault_id)
51
51
  end
52
52
  end
53
+
54
+ describe "path traversal" do
55
+ it "self.find raises an exception if the token is a traversal segment" do
56
+ expect do
57
+ Braintree::PayPalAccount.find("../payment_methods/credit_card/victim_token")
58
+ end.to raise_error(ArgumentError, "token contains invalid characters")
59
+ end
60
+
61
+ it "self.update raises an exception if the token is a traversal segment" do
62
+ expect do
63
+ Braintree::PayPalAccount.update("../payment_methods/credit_card/victim_token", {})
64
+ end.to raise_error(ArgumentError, "token contains invalid characters")
65
+ end
66
+
67
+ it "self.delete raises an exception if the token is a traversal segment" do
68
+ expect do
69
+ Braintree::PayPalAccount.delete("../payment_methods/credit_card/victim_token")
70
+ end.to raise_error(ArgumentError, "token contains invalid characters")
71
+ end
72
+ end
53
73
  end
@@ -0,0 +1,30 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe Braintree::PlanGateway do
4
+ let(:gateway) do
5
+ config = Braintree::Configuration.new(
6
+ :merchant_id => "merchant_id",
7
+ :public_key => "public_key",
8
+ :private_key => "private_key",
9
+ )
10
+ Braintree::Gateway.new(config)
11
+ end
12
+
13
+ describe "path traversal" do
14
+ it "find raises an exception if the id is a traversal segment" do
15
+ plan_gateway = Braintree::PlanGateway.new(gateway)
16
+
17
+ expect do
18
+ plan_gateway.find("../plans/victim_id")
19
+ end.to raise_error(ArgumentError, "id contains invalid characters")
20
+ end
21
+
22
+ it "update raises an exception if the plan_id is a traversal segment" do
23
+ plan_gateway = Braintree::PlanGateway.new(gateway)
24
+
25
+ expect do
26
+ plan_gateway.update("../plans/victim_id", {})
27
+ end.to raise_error(ArgumentError, "plan_id contains invalid characters")
28
+ end
29
+ end
30
+ end
@@ -83,4 +83,18 @@ describe Braintree::SepaDirectDebitAccount do
83
83
  it { is_expected.to be false }
84
84
  end
85
85
  end
86
+
87
+ describe "path traversal" do
88
+ it "self.find raises an exception if the token is a traversal segment" do
89
+ expect do
90
+ Braintree::SepaDirectDebitAccount.find("../payment_methods/credit_card/victim_token")
91
+ end.to raise_error(ArgumentError, "token contains invalid characters")
92
+ end
93
+
94
+ it "self.delete raises an exception if the token is a traversal segment" do
95
+ expect do
96
+ Braintree::SepaDirectDebitAccount.delete("../payment_methods/credit_card/victim_token")
97
+ end.to raise_error(ArgumentError, "token contains invalid characters")
98
+ end
99
+ end
86
100
  end
@@ -77,4 +77,24 @@ describe Braintree::Subscription do
77
77
  expect(subscription).not_to eq("not a subscription")
78
78
  end
79
79
  end
80
+
81
+ describe "path traversal" do
82
+ it "self.cancel raises an exception if the subscription_id is a traversal segment" do
83
+ expect do
84
+ Braintree::Subscription.cancel("../transactions/some_id/void")
85
+ end.to raise_error(ArgumentError, "subscription_id contains invalid characters")
86
+ end
87
+
88
+ it "self.find raises an exception if the id is a traversal segment" do
89
+ expect do
90
+ Braintree::Subscription.find("../transactions/some_id/void")
91
+ end.to raise_error(ArgumentError, "id contains invalid characters")
92
+ end
93
+
94
+ it "self.update raises an exception if the subscription_id is a traversal segment" do
95
+ expect do
96
+ Braintree::Subscription.update("../transactions/some_id/void", {})
97
+ end.to raise_error(ArgumentError, "subscription_id contains invalid characters")
98
+ end
99
+ end
80
100
  end
@@ -0,0 +1,18 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe Braintree::TestTransaction do
4
+ describe "path traversal" do
5
+ [
6
+ :settle,
7
+ :settlement_confirm,
8
+ :settlement_decline,
9
+ :settlement_pending,
10
+ ].each do |method_name|
11
+ it "self.#{method_name} raises an exception if the transaction_id is a traversal segment" do
12
+ expect do
13
+ Braintree::TestTransaction.public_send(method_name, "../transactions/victim_id/void")
14
+ end.to raise_error(ArgumentError, "transaction_id contains invalid characters")
15
+ end
16
+ end
17
+ end
18
+ end
@@ -200,5 +200,15 @@ describe Braintree::TransactionGateway do
200
200
  it "creates transaction gateway submit for partial settlement signature" do
201
201
  expect(Braintree::TransactionGateway._submit_for_partial_settlement_signature).to include(:final_capture)
202
202
  end
203
+
204
+ it "creates a transaction gateway refund signature" do
205
+ expect(Braintree::TransactionGateway._refund_signature).to match([
206
+ :amount,
207
+ :api_request_key,
208
+ :merchant_account_id,
209
+ :order_id,
210
+ :surcharge_amount,
211
+ ])
212
+ end
203
213
  end
204
214
  end
@@ -0,0 +1,11 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe Braintree::TransactionLineItem do
4
+ describe "path traversal" do
5
+ it "self.find_all raises an exception if the transaction_id is a traversal segment" do
6
+ expect do
7
+ Braintree::TransactionLineItem.find_all("../transactions/victim_id/void")
8
+ end.to raise_error(ArgumentError, "transaction_id contains invalid characters")
9
+ end
10
+ end
11
+ end