braintree 2.80.1 → 2.81.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 (81) hide show
  1. checksums.yaml +7 -0
  2. data/lib/braintree.rb +4 -1
  3. data/lib/braintree/account_updater_daily_report.rb +1 -1
  4. data/lib/braintree/ach_mandate.rb +2 -1
  5. data/lib/braintree/address.rb +16 -3
  6. data/lib/braintree/amex_express_checkout_card.rb +14 -2
  7. data/lib/braintree/android_pay_card.rb +16 -3
  8. data/lib/braintree/apple_pay_card.rb +15 -3
  9. data/lib/braintree/bin_data.rb +9 -2
  10. data/lib/braintree/coinbase_account.rb +10 -1
  11. data/lib/braintree/connected_merchant_paypal_status_changed.rb +3 -1
  12. data/lib/braintree/connected_merchant_status_transitioned.rb +3 -1
  13. data/lib/braintree/credentials_parser.rb +5 -1
  14. data/lib/braintree/credit_card.rb +25 -10
  15. data/lib/braintree/credit_card_verification.rb +32 -14
  16. data/lib/braintree/customer.rb +24 -11
  17. data/lib/braintree/descriptor.rb +3 -1
  18. data/lib/braintree/disbursement.rb +9 -1
  19. data/lib/braintree/dispute.rb +1 -6
  20. data/lib/braintree/dispute/transaction_details.rb +2 -1
  21. data/lib/braintree/document_upload.rb +6 -7
  22. data/lib/braintree/error_codes.rb +30 -0
  23. data/lib/braintree/error_result.rb +8 -1
  24. data/lib/braintree/europe_bank_account.rb +3 -1
  25. data/lib/braintree/facilitated_details.rb +3 -1
  26. data/lib/braintree/facilitator_details.rb +2 -1
  27. data/lib/braintree/gateway.rb +4 -0
  28. data/lib/braintree/granted_payment_instrument_update.rb +5 -1
  29. data/lib/braintree/ideal_payment.rb +15 -2
  30. data/lib/braintree/masterpass_card.rb +26 -11
  31. data/lib/braintree/merchant.rb +8 -1
  32. data/lib/braintree/merchant_account.rb +8 -3
  33. data/lib/braintree/merchant_account/address_details.rb +4 -1
  34. data/lib/braintree/merchant_account/business_details.rb +4 -1
  35. data/lib/braintree/merchant_account/funding_details.rb +6 -1
  36. data/lib/braintree/merchant_account/individual_details.rb +7 -2
  37. data/lib/braintree/oauth_credentials.rb +4 -1
  38. data/lib/braintree/paginated_result.rb +3 -1
  39. data/lib/braintree/payment_method_nonce.rb +5 -1
  40. data/lib/braintree/paypal_account.rb +8 -1
  41. data/lib/braintree/plan.rb +4 -4
  42. data/lib/braintree/risk_data.rb +3 -1
  43. data/lib/braintree/settlement_batch_summary.rb +1 -0
  44. data/lib/braintree/subscription.rb +27 -17
  45. data/lib/braintree/subscription/status_details.rb +8 -1
  46. data/lib/braintree/successful_result.rb +19 -1
  47. data/lib/braintree/three_d_secure_info.rb +5 -1
  48. data/lib/braintree/transaction.rb +54 -48
  49. data/lib/braintree/transaction/address_details.rb +13 -4
  50. data/lib/braintree/transaction/amex_express_checkout_details.rb +9 -2
  51. data/lib/braintree/transaction/android_pay_details.rb +10 -3
  52. data/lib/braintree/transaction/apple_pay_details.rb +7 -2
  53. data/lib/braintree/transaction/coinbase_details.rb +4 -1
  54. data/lib/braintree/transaction/credit_card_details.rb +40 -6
  55. data/lib/braintree/transaction/customer_details.rb +8 -1
  56. data/lib/braintree/transaction/disbursement_details.rb +5 -1
  57. data/lib/braintree/transaction/ideal_payment_details.rb +5 -1
  58. data/lib/braintree/transaction/masterpass_card_details.rb +18 -4
  59. data/lib/braintree/transaction/paypal_details.rb +18 -4
  60. data/lib/braintree/transaction/status_details.rb +5 -1
  61. data/lib/braintree/transaction/subscription_details.rb +2 -1
  62. data/lib/braintree/transaction/us_bank_account_details.rb +8 -1
  63. data/lib/braintree/transaction/venmo_account_details.rb +5 -1
  64. data/lib/braintree/transaction/visa_checkout_card_details.rb +19 -4
  65. data/lib/braintree/transaction_gateway.rb +1 -0
  66. data/lib/braintree/transaction_line_item.rb +34 -0
  67. data/lib/braintree/transaction_line_item_gateway.rb +19 -0
  68. data/lib/braintree/unknown_payment_method.rb +2 -1
  69. data/lib/braintree/us_bank_account.rb +9 -1
  70. data/lib/braintree/util.rb +14 -0
  71. data/lib/braintree/validation_error.rb +3 -1
  72. data/lib/braintree/venmo_account.rb +10 -3
  73. data/lib/braintree/version.rb +2 -2
  74. data/lib/braintree/visa_checkout_card.rb +27 -11
  75. data/lib/braintree/webhook_notification.rb +9 -9
  76. data/spec/httpsd.pid +1 -0
  77. data/spec/integration/braintree/apple_pay_spec.rb +2 -31
  78. data/spec/integration/braintree/http_spec.rb +1 -1
  79. data/spec/integration/braintree/transaction_spec.rb +1142 -0
  80. metadata +205 -207
  81. data/README.rdoc +0 -102
@@ -3,7 +3,11 @@ module Braintree
3
3
  class StatusDetails # :nodoc:
4
4
  include BaseModule
5
5
 
6
- attr_reader :amount, :status, :timestamp, :transaction_source, :user
6
+ attr_reader :amount
7
+ attr_reader :status
8
+ attr_reader :timestamp
9
+ attr_reader :transaction_source
10
+ attr_reader :user
7
11
 
8
12
  def initialize(attributes)
9
13
  set_instance_variables_from_hash attributes unless attributes.nil?
@@ -3,7 +3,8 @@ module Braintree
3
3
  class SubscriptionDetails # :nodoc:
4
4
  include BaseModule
5
5
 
6
- attr_reader :billing_period_start_date, :billing_period_end_date
6
+ attr_reader :billing_period_end_date
7
+ attr_reader :billing_period_start_date
7
8
 
8
9
  def initialize(attributes)
9
10
  set_instance_variables_from_hash attributes unless attributes.nil?
@@ -3,7 +3,14 @@ module Braintree
3
3
  class UsBankAccountDetails # :nodoc:
4
4
  include BaseModule
5
5
 
6
- attr_reader :routing_number, :last_4, :account_type, :account_holder_name, :token, :image_url, :bank_name, :ach_mandate
6
+ attr_reader :account_holder_name
7
+ attr_reader :account_type
8
+ attr_reader :ach_mandate
9
+ attr_reader :bank_name
10
+ attr_reader :image_url
11
+ attr_reader :last_4
12
+ attr_reader :routing_number
13
+ attr_reader :token
7
14
 
8
15
  def initialize(attributes)
9
16
  set_instance_variables_from_hash attributes unless attributes.nil?
@@ -3,7 +3,11 @@ module Braintree
3
3
  class VenmoAccountDetails
4
4
  include BaseModule
5
5
 
6
- attr_reader :username, :venmo_user_id, :token, :source_description, :image_url
6
+ attr_reader :image_url
7
+ attr_reader :source_description
8
+ attr_reader :token
9
+ attr_reader :username
10
+ attr_reader :venmo_user_id
7
11
 
8
12
  def initialize(attributes)
9
13
  set_instance_variables_from_hash attributes unless attributes.nil?
@@ -3,10 +3,25 @@ module Braintree
3
3
  class VisaCheckoutCardDetails # :nodoc:
4
4
  include BaseModule
5
5
 
6
- attr_reader :bin, :card_type, :cardholder_name, :commercial, :country_of_issuance,
7
- :customer_location, :debit, :durbin_regulated, :expiration_month, :expiration_year,
8
- :healthcare, :image_url, :issuing_bank, :last_4, :payroll, :prepaid, :product_id,
9
- :token, :call_id
6
+ attr_reader :bin
7
+ attr_reader :call_id
8
+ attr_reader :card_type
9
+ attr_reader :cardholder_name
10
+ attr_reader :commercial
11
+ attr_reader :country_of_issuance
12
+ attr_reader :customer_location
13
+ attr_reader :debit
14
+ attr_reader :durbin_regulated
15
+ attr_reader :expiration_month
16
+ attr_reader :expiration_year
17
+ attr_reader :healthcare
18
+ attr_reader :image_url
19
+ attr_reader :issuing_bank
20
+ attr_reader :last_4
21
+ attr_reader :payroll
22
+ attr_reader :prepaid
23
+ attr_reader :product_id
24
+ attr_reader :token
10
25
 
11
26
  def initialize(attributes)
12
27
  set_instance_variables_from_hash attributes unless attributes.nil?
@@ -149,6 +149,7 @@ module Braintree
149
149
  :shipping_amount, :discount_amount, :ships_from_postal_code,
150
150
  :billing_address_id, :payment_method_nonce, :three_d_secure_token,
151
151
  :shared_payment_method_token, :shared_billing_address_id, :shared_customer_id, :shared_shipping_address_id, :shared_payment_method_nonce,
152
+ {:line_items => [:quantity, :name, :description, :kind, :unit_amount, :unit_tax_amount, :total_amount, :discount_amount, :unit_of_measure, :product_code, :commodity_code, :url]},
152
153
  {:risk_data => [:customer_browser, :customer_ip]},
153
154
  {:credit_card => [:token, :cardholder_name, :cvv, :expiration_date, :expiration_month, :expiration_year, :number]},
154
155
  {:customer => [:id, :company, :email, :fax, :first_name, :last_name, :phone, :website]},
@@ -0,0 +1,34 @@
1
+ module Braintree
2
+ class TransactionLineItem
3
+ include BaseModule
4
+ attr_reader :quantity
5
+ attr_reader :name
6
+ attr_reader :description
7
+ attr_reader :kind
8
+ attr_reader :unit_amount
9
+ attr_reader :unit_tax_amount
10
+ attr_reader :unit_of_measure
11
+ attr_reader :discount_amount
12
+ attr_reader :total_amount
13
+ attr_reader :product_code
14
+ attr_reader :commodity_code
15
+ attr_reader :url
16
+
17
+ def initialize(gateway, attributes) # :nodoc:
18
+ @gateway = gateway
19
+ set_instance_variables_from_hash(attributes)
20
+ @quantity = Util.to_big_decimal(quantity)
21
+ @unit_amount = Util.to_big_decimal(unit_amount)
22
+ @unit_tax_amount = Util.to_big_decimal(unit_tax_amount)
23
+ @discount_amount = Util.to_big_decimal(discount_amount)
24
+ @total_amount = Util.to_big_decimal(total_amount)
25
+ end
26
+
27
+ class << self
28
+ protected :new
29
+ def _new(*args) # :nodoc:
30
+ self.new *args
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,19 @@
1
+ module Braintree
2
+ class TransactionLineItemGateway # :nodoc:
3
+ def initialize(gateway)
4
+ @gateway = gateway
5
+ @config = gateway.config
6
+ @config.assert_has_access_token_or_keys
7
+ end
8
+
9
+ def find_all(transaction_id)
10
+ raise ArgumentError, "transaction_id cannot be blank" if transaction_id.nil? || transaction_id.strip.to_s == ""
11
+ response = @config.http.get("#{@config.base_merchant_path}/transactions/#{transaction_id}/line_items")
12
+ response[:line_items].map do |line_item_params|
13
+ TransactionLineItem._new(@gateway, line_item_params)
14
+ end
15
+ rescue NotFoundError
16
+ raise NotFoundError, "transaction with id #{transaction_id.inspect} not found"
17
+ end
18
+ end
19
+ end
@@ -2,7 +2,8 @@ module Braintree
2
2
  class UnknownPaymentMethod
3
3
  include BaseModule
4
4
 
5
- attr_reader :token, :customer_id
5
+ attr_reader :customer_id
6
+ attr_reader :token
6
7
 
7
8
  def initialize(gateway, attributes)
8
9
  @gateway = gateway
@@ -2,7 +2,15 @@ module Braintree
2
2
  class UsBankAccount
3
3
  include BaseModule
4
4
 
5
- attr_reader :routing_number, :last_4, :account_type, :account_holder_name, :token, :image_url, :bank_name, :ach_mandate, :default
5
+ attr_reader :account_holder_name
6
+ attr_reader :account_type
7
+ attr_reader :ach_mandate
8
+ attr_reader :bank_name
9
+ attr_reader :default
10
+ attr_reader :image_url
11
+ attr_reader :last_4
12
+ attr_reader :routing_number
13
+ attr_reader :token
6
14
 
7
15
  def initialize(gateway, attributes) # :nodoc:
8
16
  @gateway = gateway
@@ -137,5 +137,19 @@ module Braintree
137
137
  end
138
138
  end
139
139
  end
140
+
141
+ module IdEquality
142
+ def ==(other) # :nodoc:
143
+ return false unless other.is_a?(self.class)
144
+ id == other.id
145
+ end
146
+ end
147
+
148
+ module TokenEquality
149
+ def ==(other) # :nodoc:
150
+ return false unless other.is_a?(self.class)
151
+ token == other.token
152
+ end
153
+ end
140
154
  end
141
155
  end
@@ -2,7 +2,9 @@ module Braintree
2
2
  class ValidationError
3
3
  include BaseModule
4
4
 
5
- attr_reader :attribute, :code, :message
5
+ attr_reader :attribute
6
+ attr_reader :code
7
+ attr_reader :message
6
8
 
7
9
  def initialize(attributes)
8
10
  set_instance_variables_from_hash attributes
@@ -2,8 +2,16 @@ module Braintree
2
2
  class VenmoAccount
3
3
  include BaseModule # :nodoc:
4
4
 
5
- attr_reader :customer_id, :username, :venmo_user_id, :token, :source_description, :subscriptions,
6
- :image_url, :default, :updated_at, :created_at
5
+ attr_reader :created_at
6
+ attr_reader :customer_id
7
+ attr_reader :default
8
+ attr_reader :image_url
9
+ attr_reader :source_description
10
+ attr_reader :subscriptions
11
+ attr_reader :token
12
+ attr_reader :updated_at
13
+ attr_reader :username
14
+ attr_reader :venmo_user_id
7
15
 
8
16
  def initialize(gateway, attributes) # :nodoc:
9
17
  @gateway = gateway
@@ -24,4 +32,3 @@ module Braintree
24
32
  end
25
33
  end
26
34
  end
27
-
@@ -1,8 +1,8 @@
1
1
  module Braintree
2
2
  module Version
3
3
  Major = 2
4
- Minor = 80
5
- Tiny = 1
4
+ Minor = 81
5
+ Tiny = 0
6
6
 
7
7
  String = "#{Major}.#{Minor}.#{Tiny}"
8
8
  end
@@ -1,13 +1,34 @@
1
1
  module Braintree
2
2
  class VisaCheckoutCard
3
3
  include BaseModule # :nodoc:
4
+ include Braintree::Util::TokenEquality
4
5
 
5
- attr_reader :billing_address, :bin, :card_type, :cardholder_name,
6
- :commercial, :country_of_issuance, :created_at, :customer_id,
7
- :customer_location, :debit, :durbin_regulated, :expiration_month,
8
- :expiration_year, :healthcare, :issuing_bank, :last_4, :payroll,
9
- :prepaid, :product_id, :subscriptions, :token, :unique_number_identifier,
10
- :updated_at, :image_url, :verification, :call_id
6
+ attr_reader :billing_address
7
+ attr_reader :bin
8
+ attr_reader :call_id
9
+ attr_reader :card_type
10
+ attr_reader :cardholder_name
11
+ attr_reader :commercial
12
+ attr_reader :country_of_issuance
13
+ attr_reader :created_at
14
+ attr_reader :customer_id
15
+ attr_reader :customer_location
16
+ attr_reader :debit
17
+ attr_reader :durbin_regulated
18
+ attr_reader :expiration_month
19
+ attr_reader :expiration_year
20
+ attr_reader :healthcare
21
+ attr_reader :image_url
22
+ attr_reader :issuing_bank
23
+ attr_reader :last_4
24
+ attr_reader :payroll
25
+ attr_reader :prepaid
26
+ attr_reader :product_id
27
+ attr_reader :subscriptions
28
+ attr_reader :token
29
+ attr_reader :unique_number_identifier
30
+ attr_reader :updated_at
31
+ attr_reader :verification
11
32
 
12
33
  def initialize(gateway, attributes) # :nodoc:
13
34
  @gateway = gateway
@@ -48,11 +69,6 @@ module Braintree
48
69
  "#{bin}******#{last_4}"
49
70
  end
50
71
 
51
- def ==(other)
52
- return false unless other.is_a?(VisaCheckoutCard)
53
- token == other.token
54
- end
55
-
56
72
  class << self
57
73
  protected :new
58
74
  end
@@ -42,18 +42,18 @@ module Braintree
42
42
  GrantedPaymentInstrumentUpdate = "granted_payment_instrument_update"
43
43
  end
44
44
 
45
- attr_reader :subscription
46
- attr_reader :kind
47
- attr_reader :timestamp
48
- attr_reader :transaction
49
- attr_reader :partner_merchant
50
- attr_reader :disbursement
51
- attr_reader :dispute
52
45
  attr_reader :account_updater_daily_report
53
- attr_reader :ideal_payment
54
- attr_reader :connected_merchant_status_transitioned
55
46
  attr_reader :connected_merchant_paypal_status_changed
47
+ attr_reader :connected_merchant_status_transitioned
48
+ attr_reader :disbursement
49
+ attr_reader :dispute
56
50
  attr_reader :granted_payment_instrument_update
51
+ attr_reader :ideal_payment
52
+ attr_reader :kind
53
+ attr_reader :partner_merchant
54
+ attr_reader :subscription
55
+ attr_reader :timestamp
56
+ attr_reader :transaction
57
57
 
58
58
  def self.parse(signature, payload)
59
59
  Configuration.gateway.webhook_notification.parse(signature, payload)
@@ -0,0 +1 @@
1
+ 32587
@@ -36,57 +36,28 @@ describe Braintree::ApplePayGateway do
36
36
  describe "unregister_domain" do
37
37
  it "unregisters an apple pay domain" do
38
38
  domain = "example.org"
39
- result = @gateway.apple_pay.register_domain(domain)
40
- result.should be_success
41
-
42
39
  result = @gateway.apple_pay.unregister_domain(domain)
43
40
  result.should be_success
44
- @gateway.apple_pay.registered_domains.apple_pay_options.domains.should be_empty
45
41
  end
46
42
 
47
43
  it "unregisters an apple pay domain with scheme in url" do
48
44
  domain = "http://example.org"
49
- result = @gateway.apple_pay.register_domain(domain)
50
- result.should be_success
51
-
52
45
  result = @gateway.apple_pay.unregister_domain(domain)
53
46
  result.should be_success
54
- @gateway.apple_pay.registered_domains.apple_pay_options.domains.should be_empty
55
- end
56
-
57
- it "does not fail when unregistering a non-registered domain" do
58
- result = @gateway.apple_pay.unregister_domain("unregistered.com")
59
- result.should be_success
60
47
  end
61
48
 
62
49
  it "escapes the unregistered domain query parameter" do
63
50
  domain = "ex&mple.org"
64
- result = @gateway.apple_pay.register_domain(domain)
65
- result.should be_success
66
- @gateway.apple_pay.registered_domains.apple_pay_options.domains.should_not be_empty
67
-
68
51
  result = @gateway.apple_pay.unregister_domain(domain)
69
52
  result.should be_success
70
- @gateway.apple_pay.registered_domains.apple_pay_options.domains.should be_empty
71
53
  end
72
54
  end
73
55
 
74
56
  describe "registered_domains" do
75
- it "returns registered domains" do
76
- result = @gateway.apple_pay.register_domain("www.example.com")
77
- result.should be_success
78
- result = @gateway.apple_pay.register_domain("www.example.org")
79
- result.should be_success
80
-
81
- result = @gateway.apple_pay.registered_domains
82
- result.should be_success
83
- result.apple_pay_options.domains.should =~ ["www.example.org", "www.example.com"]
84
- end
85
-
86
- it "returns an empty list if no domains are registered" do
57
+ it "returns stubbed registered domains" do
87
58
  result = @gateway.apple_pay.registered_domains
88
59
  result.should be_success
89
- result.apple_pay_options.domains.should == []
60
+ result.apple_pay_options.domains.should == ["www.example.com"]
90
61
  end
91
62
  end
92
63
  end
@@ -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}/users")
21
+ config.http.get("#{config.base_merchant_path}/downloads")
22
22
  end.to raise_error(Braintree::AuthorizationError)
23
23
  end
24
24
  end
@@ -2243,6 +2243,1052 @@ describe Braintree::Transaction do
2243
2243
  end
2244
2244
  end
2245
2245
 
2246
+ context "line items" do
2247
+ it "allows creation with empty line items and returns none" do
2248
+ result = Braintree::Transaction.create(
2249
+ :type => "sale",
2250
+ :amount => "35.05",
2251
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
2252
+ :line_items => [],
2253
+ )
2254
+ result.success?.should == true
2255
+ result.transaction.line_items.should == []
2256
+ end
2257
+
2258
+ it "allows creation with single line item with minimal fields and returns it" do
2259
+ result = Braintree::Transaction.create(
2260
+ :type => "sale",
2261
+ :amount => "45.15",
2262
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
2263
+ :line_items => [
2264
+ {
2265
+ :quantity => "1.0232",
2266
+ :name => "Name #1",
2267
+ :kind => "debit",
2268
+ :unit_amount => "45.1232",
2269
+ :total_amount => "45.15",
2270
+ },
2271
+ ],
2272
+ )
2273
+ result.success?.should == true
2274
+ result.transaction.line_items.length.should == 1
2275
+ line_item = result.transaction.line_items[0]
2276
+ line_item.quantity.should == BigDecimal.new("1.0232")
2277
+ line_item.name.should == "Name #1"
2278
+ line_item.kind.should == "debit"
2279
+ line_item.unit_amount.should == BigDecimal.new("45.1232")
2280
+ line_item.total_amount.should == BigDecimal.new("45.15")
2281
+ end
2282
+
2283
+ it "allows creation with single line item and returns it" do
2284
+ result = Braintree::Transaction.create(
2285
+ :type => "sale",
2286
+ :amount => "45.15",
2287
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
2288
+ :line_items => [
2289
+ {
2290
+ :quantity => "1.0232",
2291
+ :name => "Name #1",
2292
+ :description => "Description #1",
2293
+ :kind => "debit",
2294
+ :unit_amount => "45.1232",
2295
+ :unit_tax_amount => "1.23",
2296
+ :unit_of_measure => "gallon",
2297
+ :discount_amount => "1.02",
2298
+ :total_amount => "45.15",
2299
+ :product_code => "23434",
2300
+ :commodity_code => "9SAASSD8724",
2301
+ :url => "https://example.com/products/23434",
2302
+ },
2303
+ ],
2304
+ )
2305
+ result.success?.should == true
2306
+ result.transaction.line_items.length.should == 1
2307
+ line_item = result.transaction.line_items[0]
2308
+ line_item.quantity.should == BigDecimal.new("1.0232")
2309
+ line_item.name.should == "Name #1"
2310
+ line_item.description.should == "Description #1"
2311
+ line_item.kind.should == "debit"
2312
+ line_item.unit_amount.should == BigDecimal.new("45.1232")
2313
+ line_item.unit_tax_amount.should == BigDecimal.new("1.23")
2314
+ line_item.unit_of_measure.should == "gallon"
2315
+ line_item.discount_amount.should == BigDecimal.new("1.02")
2316
+ line_item.total_amount.should == BigDecimal.new("45.15")
2317
+ line_item.product_code.should == "23434"
2318
+ line_item.commodity_code.should == "9SAASSD8724"
2319
+ line_item.url.should == "https://example.com/products/23434"
2320
+ end
2321
+
2322
+ it "allows creation with multiple line items and returns them" do
2323
+ result = Braintree::Transaction.create(
2324
+ :type => "sale",
2325
+ :amount => "35.05",
2326
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
2327
+ :line_items => [
2328
+ {
2329
+ :quantity => "1.0232",
2330
+ :name => "Name #1",
2331
+ :kind => "debit",
2332
+ :unit_amount => "45.1232",
2333
+ :unit_of_measure => "gallon",
2334
+ :discount_amount => "1.02",
2335
+ :total_amount => "45.15",
2336
+ :product_code => "23434",
2337
+ :commodity_code => "9SAASSD8724",
2338
+ },
2339
+ {
2340
+ :quantity => "2.02",
2341
+ :name => "Name #2",
2342
+ :kind => "credit",
2343
+ :unit_amount => "5",
2344
+ :unit_of_measure => "gallon",
2345
+ :total_amount => "10.1",
2346
+ },
2347
+ ],
2348
+ )
2349
+ result.success?.should == true
2350
+ result.transaction.line_items.length.should == 2
2351
+ line_item_1 = result.transaction.line_items.find { |line_item| line_item.name == "Name #1" }
2352
+ line_item_1.quantity.should == BigDecimal.new("1.0232")
2353
+ line_item_1.name.should == "Name #1"
2354
+ line_item_1.kind.should == "debit"
2355
+ line_item_1.unit_amount.should == BigDecimal.new("45.1232")
2356
+ line_item_1.unit_of_measure.should == "gallon"
2357
+ line_item_1.discount_amount.should == BigDecimal.new("1.02")
2358
+ line_item_1.total_amount.should == BigDecimal.new("45.15")
2359
+ line_item_1.product_code.should == "23434"
2360
+ line_item_1.commodity_code.should == "9SAASSD8724"
2361
+ line_item_2 = result.transaction.line_items.find { |line_item| line_item.name == "Name #2" }
2362
+ line_item_2.quantity.should == BigDecimal.new("2.02")
2363
+ line_item_2.name.should == "Name #2"
2364
+ line_item_2.kind.should == "credit"
2365
+ line_item_2.unit_amount.should == BigDecimal.new("5")
2366
+ line_item_2.unit_of_measure.should == "gallon"
2367
+ line_item_2.total_amount.should == BigDecimal.new("10.1")
2368
+ line_item_2.discount_amount.should == nil
2369
+ line_item_2.product_code.should == nil
2370
+ line_item_2.commodity_code.should == nil
2371
+ end
2372
+
2373
+ it "handles validation error commodity code is too long" do
2374
+ result = Braintree::Transaction.create(
2375
+ :type => "sale",
2376
+ :amount => "35.05",
2377
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
2378
+ :line_items => [
2379
+ {
2380
+ :quantity => "1.2322",
2381
+ :name => "Name #1",
2382
+ :kind => "debit",
2383
+ :unit_amount => "45.1232",
2384
+ :unit_of_measure => "gallon",
2385
+ :discount_amount => "1.02",
2386
+ :total_amount => "45.15",
2387
+ :product_code => "23434",
2388
+ :commodity_code => "9SAASSD8724",
2389
+ },
2390
+ {
2391
+ :quantity => "1.2322",
2392
+ :name => "Name #2",
2393
+ :kind => "credit",
2394
+ :unit_amount => "45.1232",
2395
+ :unit_of_measure => "gallon",
2396
+ :discount_amount => "1.02",
2397
+ :total_amount => "45.15",
2398
+ :product_code => "23434",
2399
+ :commodity_code => "1234567890123",
2400
+ },
2401
+ ],
2402
+ )
2403
+ result.success?.should == false
2404
+ result.errors.for(:transaction).for(:line_items).for(:index_1).on(:commodity_code)[0].code.should == Braintree::ErrorCodes::TransactionLineItem::CommodityCodeIsTooLong
2405
+ end
2406
+
2407
+ it "handles validation error description is too long" do
2408
+ result = Braintree::Transaction.create(
2409
+ :type => "sale",
2410
+ :amount => "35.05",
2411
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
2412
+ :line_items => [
2413
+ {
2414
+ :quantity => "1.2322",
2415
+ :name => "Name #1",
2416
+ :kind => "debit",
2417
+ :unit_amount => "45.1232",
2418
+ :unit_of_measure => "gallon",
2419
+ :discount_amount => "1.02",
2420
+ :total_amount => "45.15",
2421
+ :product_code => "23434",
2422
+ :commodity_code => "9SAASSD8724",
2423
+ },
2424
+ {
2425
+ :quantity => "1.2322",
2426
+ :name => "Name #2",
2427
+ :description => "X" * 128,
2428
+ :kind => "credit",
2429
+ :unit_amount => "45.1232",
2430
+ :unit_of_measure => "gallon",
2431
+ :discount_amount => "1.02",
2432
+ :total_amount => "45.15",
2433
+ :product_code => "23434",
2434
+ :commodity_code => "9SAASSD8724",
2435
+ },
2436
+ ],
2437
+ )
2438
+ result.success?.should == false
2439
+ result.errors.for(:transaction).for(:line_items).for(:index_1).on(:description)[0].code.should == Braintree::ErrorCodes::TransactionLineItem::DescriptionIsTooLong
2440
+ end
2441
+
2442
+ it "handles validation error discount amount format is invalid" do
2443
+ result = Braintree::Transaction.create(
2444
+ :type => "sale",
2445
+ :amount => "35.05",
2446
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
2447
+ :line_items => [
2448
+ {
2449
+ :quantity => "1.2322",
2450
+ :name => "Name #1",
2451
+ :kind => "debit",
2452
+ :unit_amount => "45.1232",
2453
+ :unit_of_measure => "gallon",
2454
+ :discount_amount => "1.02",
2455
+ :total_amount => "45.15",
2456
+ :product_code => "23434",
2457
+ :commodity_code => "9SAASSD8724",
2458
+ },
2459
+ {
2460
+ :quantity => "1.2322",
2461
+ :name => "Name #2",
2462
+ :kind => "credit",
2463
+ :unit_amount => "45.1232",
2464
+ :unit_of_measure => "gallon",
2465
+ :discount_amount => "$1.02",
2466
+ :total_amount => "45.15",
2467
+ :product_code => "23434",
2468
+ :commodity_code => "9SAASSD8724",
2469
+ },
2470
+ ],
2471
+ )
2472
+ result.success?.should == false
2473
+ result.errors.for(:transaction).for(:line_items).for(:index_1).on(:discount_amount)[0].code.should == Braintree::ErrorCodes::TransactionLineItem::DiscountAmountFormatIsInvalid
2474
+ end
2475
+
2476
+ it "handles validation error discount amount is too large" do
2477
+ result = Braintree::Transaction.create(
2478
+ :type => "sale",
2479
+ :amount => "35.05",
2480
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
2481
+ :line_items => [
2482
+ {
2483
+ :quantity => "1.2322",
2484
+ :name => "Name #1",
2485
+ :kind => "debit",
2486
+ :unit_amount => "45.1232",
2487
+ :unit_of_measure => "gallon",
2488
+ :discount_amount => "1.02",
2489
+ :total_amount => "45.15",
2490
+ :product_code => "23434",
2491
+ :commodity_code => "9SAASSD8724",
2492
+ },
2493
+ {
2494
+ :quantity => "1.2322",
2495
+ :name => "Name #2",
2496
+ :kind => "credit",
2497
+ :unit_amount => "45.1232",
2498
+ :unit_of_measure => "gallon",
2499
+ :discount_amount => "2147483648",
2500
+ :total_amount => "45.15",
2501
+ :product_code => "23434",
2502
+ :commodity_code => "9SAASSD8724",
2503
+ },
2504
+ ],
2505
+ )
2506
+ result.success?.should == false
2507
+ result.errors.for(:transaction).for(:line_items).for(:index_1).on(:discount_amount)[0].code.should == Braintree::ErrorCodes::TransactionLineItem::DiscountAmountIsTooLarge
2508
+ end
2509
+
2510
+ it "handles validation error discount amount must be greater than zero" do
2511
+ result = Braintree::Transaction.create(
2512
+ :type => "sale",
2513
+ :amount => "35.05",
2514
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
2515
+ :line_items => [
2516
+ {
2517
+ :quantity => "1.2322",
2518
+ :name => "Name #1",
2519
+ :kind => "debit",
2520
+ :unit_amount => "45.1232",
2521
+ :unit_of_measure => "gallon",
2522
+ :discount_amount => "1.02",
2523
+ :total_amount => "45.15",
2524
+ :product_code => "23434",
2525
+ :commodity_code => "9SAASSD8724",
2526
+ },
2527
+ {
2528
+ :quantity => "1.2322",
2529
+ :name => "Name #2",
2530
+ :kind => "credit",
2531
+ :unit_amount => "45.1232",
2532
+ :unit_of_measure => "gallon",
2533
+ :discount_amount => "-2",
2534
+ :total_amount => "45.15",
2535
+ :product_code => "23434",
2536
+ :commodity_code => "9SAASSD8724",
2537
+ },
2538
+ ],
2539
+ )
2540
+ result.success?.should == false
2541
+ result.errors.for(:transaction).for(:line_items).for(:index_1).on(:discount_amount)[0].code.should == Braintree::ErrorCodes::TransactionLineItem::DiscountAmountMustBeGreaterThanZero
2542
+ end
2543
+
2544
+ it "handles validation error kind is invalid" do
2545
+ result = Braintree::Transaction.create(
2546
+ :type => "sale",
2547
+ :amount => "35.05",
2548
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
2549
+ :line_items => [
2550
+ {
2551
+ :quantity => "1.2322",
2552
+ :name => "Name #1",
2553
+ :kind => "debit",
2554
+ :unit_amount => "45.1232",
2555
+ :unit_of_measure => "gallon",
2556
+ :discount_amount => "1.02",
2557
+ :total_amount => "45.15",
2558
+ :product_code => "23434",
2559
+ :commodity_code => "9SAASSD8724",
2560
+ },
2561
+ {
2562
+ :quantity => "1.2322",
2563
+ :name => "Name #2",
2564
+ :kind => "sale",
2565
+ :unit_amount => "45.1232",
2566
+ :unit_of_measure => "gallon",
2567
+ :discount_amount => "1.02",
2568
+ :total_amount => "45.15",
2569
+ :product_code => "23434",
2570
+ :commodity_code => "9SAASSD8724",
2571
+ },
2572
+ ],
2573
+ )
2574
+ result.success?.should == false
2575
+ result.errors.for(:transaction).for(:line_items).for(:index_1).on(:kind)[0].code.should == Braintree::ErrorCodes::TransactionLineItem::KindIsInvalid
2576
+ end
2577
+
2578
+ it "handles validation error kind is required" do
2579
+ result = Braintree::Transaction.create(
2580
+ :type => "sale",
2581
+ :amount => "35.05",
2582
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
2583
+ :line_items => [
2584
+ {
2585
+ :quantity => "1.2322",
2586
+ :name => "Name #1",
2587
+ :kind => "debit",
2588
+ :unit_amount => "45.1232",
2589
+ :unit_of_measure => "gallon",
2590
+ :discount_amount => "1.02",
2591
+ :total_amount => "45.15",
2592
+ :product_code => "23434",
2593
+ :commodity_code => "9SAASSD8724",
2594
+ },
2595
+ {
2596
+ :quantity => "1.2322",
2597
+ :name => "Name #2",
2598
+ :unit_amount => "45.1232",
2599
+ :unit_of_measure => "gallon",
2600
+ :discount_amount => "1.02",
2601
+ :total_amount => "45.15",
2602
+ :product_code => "23434",
2603
+ :commodity_code => "9SAASSD8724",
2604
+ },
2605
+ ],
2606
+ )
2607
+ result.success?.should == false
2608
+ result.errors.for(:transaction).for(:line_items).for(:index_1).on(:kind)[0].code.should == Braintree::ErrorCodes::TransactionLineItem::KindIsRequired
2609
+ end
2610
+
2611
+ it "handles validation error name is required" do
2612
+ result = Braintree::Transaction.create(
2613
+ :type => "sale",
2614
+ :amount => "35.05",
2615
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
2616
+ :line_items => [
2617
+ {
2618
+ :quantity => "1.2322",
2619
+ :name => "Name #1",
2620
+ :kind => "debit",
2621
+ :unit_amount => "45.1232",
2622
+ :unit_of_measure => "gallon",
2623
+ :discount_amount => "1.02",
2624
+ :total_amount => "45.15",
2625
+ :product_code => "23434",
2626
+ :commodity_code => "9SAASSD8724",
2627
+ },
2628
+ {
2629
+ :quantity => "1.2322",
2630
+ :kind => "debit",
2631
+ :unit_amount => "45.1232",
2632
+ :unit_of_measure => "gallon",
2633
+ :discount_amount => "1.02",
2634
+ :total_amount => "45.15",
2635
+ :product_code => "23434",
2636
+ :commodity_code => "9SAASSD8724",
2637
+ },
2638
+ ],
2639
+ )
2640
+ result.success?.should == false
2641
+ result.errors.for(:transaction).for(:line_items).for(:index_1).on(:name)[0].code.should == Braintree::ErrorCodes::TransactionLineItem::NameIsRequired
2642
+ end
2643
+
2644
+ it "handles validation error name is too long" do
2645
+ result = Braintree::Transaction.create(
2646
+ :type => "sale",
2647
+ :amount => "35.05",
2648
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
2649
+ :line_items => [
2650
+ {
2651
+ :quantity => "1.2322",
2652
+ :name => "Name #1",
2653
+ :kind => "debit",
2654
+ :unit_amount => "45.1232",
2655
+ :unit_of_measure => "gallon",
2656
+ :discount_amount => "1.02",
2657
+ :total_amount => "45.15",
2658
+ :product_code => "23434",
2659
+ :commodity_code => "9SAASSD8724",
2660
+ },
2661
+ {
2662
+ :quantity => "1.2322",
2663
+ :name => "X"*36,
2664
+ :kind => "debit",
2665
+ :unit_amount => "45.1232",
2666
+ :unit_of_measure => "gallon",
2667
+ :discount_amount => "1.02",
2668
+ :total_amount => "45.15",
2669
+ :product_code => "23434",
2670
+ :commodity_code => "9SAASSD8724",
2671
+ },
2672
+ ],
2673
+ )
2674
+ result.success?.should == false
2675
+ result.errors.for(:transaction).for(:line_items).for(:index_1).on(:name)[0].code.should == Braintree::ErrorCodes::TransactionLineItem::NameIsTooLong
2676
+ end
2677
+
2678
+ it "handles validation error product code is too long" do
2679
+ result = Braintree::Transaction.create(
2680
+ :type => "sale",
2681
+ :amount => "35.05",
2682
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
2683
+ :line_items => [
2684
+ {
2685
+ :quantity => "1.2322",
2686
+ :name => "Name #1",
2687
+ :kind => "debit",
2688
+ :unit_amount => "45.1232",
2689
+ :unit_of_measure => "gallon",
2690
+ :discount_amount => "1.02",
2691
+ :total_amount => "45.15",
2692
+ :product_code => "23434",
2693
+ :commodity_code => "9SAASSD8724",
2694
+ },
2695
+ {
2696
+ :quantity => "1.2322",
2697
+ :name => "Name #2",
2698
+ :kind => "credit",
2699
+ :unit_amount => "45.1232",
2700
+ :unit_of_measure => "gallon",
2701
+ :discount_amount => "1.02",
2702
+ :total_amount => "45.15",
2703
+ :product_code => "1234567890123",
2704
+ :commodity_code => "9SAASSD8724",
2705
+ },
2706
+ ],
2707
+ )
2708
+ result.success?.should == false
2709
+ result.errors.for(:transaction).for(:line_items).for(:index_1).on(:product_code)[0].code.should == Braintree::ErrorCodes::TransactionLineItem::ProductCodeIsTooLong
2710
+ end
2711
+
2712
+ it "handles validation error quantity format is invalid" do
2713
+ result = Braintree::Transaction.create(
2714
+ :type => "sale",
2715
+ :amount => "35.05",
2716
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
2717
+ :line_items => [
2718
+ {
2719
+ :quantity => "1.2322",
2720
+ :name => "Name #1",
2721
+ :kind => "debit",
2722
+ :unit_amount => "45.1232",
2723
+ :unit_of_measure => "gallon",
2724
+ :discount_amount => "1.02",
2725
+ :total_amount => "45.15",
2726
+ :product_code => "23434",
2727
+ :commodity_code => "9SAASSD8724",
2728
+ },
2729
+ {
2730
+ :quantity => "1,2322",
2731
+ :name => "Name #2",
2732
+ :kind => "credit",
2733
+ :unit_amount => "45.1232",
2734
+ :unit_of_measure => "gallon",
2735
+ :discount_amount => "1.02",
2736
+ :total_amount => "45.15",
2737
+ :product_code => "23434",
2738
+ :commodity_code => "9SAASSD8724",
2739
+ },
2740
+ ],
2741
+ )
2742
+ result.success?.should == false
2743
+ result.errors.for(:transaction).for(:line_items).for(:index_1).on(:quantity)[0].code.should == Braintree::ErrorCodes::TransactionLineItem::QuantityFormatIsInvalid
2744
+ end
2745
+
2746
+ it "handles validation error quantity is required" do
2747
+ result = Braintree::Transaction.create(
2748
+ :type => "sale",
2749
+ :amount => "35.05",
2750
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
2751
+ :line_items => [
2752
+ {
2753
+ :quantity => "1.2322",
2754
+ :name => "Name #1",
2755
+ :kind => "debit",
2756
+ :unit_amount => "45.1232",
2757
+ :unit_of_measure => "gallon",
2758
+ :discount_amount => "1.02",
2759
+ :total_amount => "45.15",
2760
+ :product_code => "23434",
2761
+ :commodity_code => "9SAASSD8724",
2762
+ },
2763
+ {
2764
+ :name => "Name #2",
2765
+ :kind => "credit",
2766
+ :unit_amount => "45.1232",
2767
+ :unit_of_measure => "gallon",
2768
+ :discount_amount => "1.02",
2769
+ :total_amount => "45.15",
2770
+ :product_code => "23434",
2771
+ :commodity_code => "9SAASSD8724",
2772
+ },
2773
+ ],
2774
+ )
2775
+ result.success?.should == false
2776
+ result.errors.for(:transaction).for(:line_items).for(:index_1).on(:quantity)[0].code.should == Braintree::ErrorCodes::TransactionLineItem::QuantityIsRequired
2777
+ end
2778
+
2779
+ it "handles validation error quantity is too large" do
2780
+ result = Braintree::Transaction.create(
2781
+ :type => "sale",
2782
+ :amount => "35.05",
2783
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
2784
+ :line_items => [
2785
+ {
2786
+ :quantity => "1.2322",
2787
+ :name => "Name #1",
2788
+ :kind => "debit",
2789
+ :unit_amount => "45.1232",
2790
+ :unit_of_measure => "gallon",
2791
+ :discount_amount => "1.02",
2792
+ :total_amount => "45.15",
2793
+ :product_code => "23434",
2794
+ :commodity_code => "9SAASSD8724",
2795
+ },
2796
+ {
2797
+ :quantity => "2147483648",
2798
+ :name => "Name #2",
2799
+ :kind => "credit",
2800
+ :unit_amount => "45.1232",
2801
+ :unit_of_measure => "gallon",
2802
+ :discount_amount => "1.02",
2803
+ :total_amount => "45.15",
2804
+ :product_code => "23434",
2805
+ :commodity_code => "9SAASSD8724",
2806
+ },
2807
+ ],
2808
+ )
2809
+ result.success?.should == false
2810
+ result.errors.for(:transaction).for(:line_items).for(:index_1).on(:quantity)[0].code.should == Braintree::ErrorCodes::TransactionLineItem::QuantityIsTooLarge
2811
+ end
2812
+
2813
+ it "handles validation error total amount format is invalid" do
2814
+ result = Braintree::Transaction.create(
2815
+ :type => "sale",
2816
+ :amount => "35.05",
2817
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
2818
+ :line_items => [
2819
+ {
2820
+ :quantity => "1.2322",
2821
+ :name => "Name #1",
2822
+ :kind => "debit",
2823
+ :unit_amount => "45.1232",
2824
+ :unit_of_measure => "gallon",
2825
+ :discount_amount => "1.02",
2826
+ :total_amount => "45.15",
2827
+ :product_code => "23434",
2828
+ :commodity_code => "9SAASSD8724",
2829
+ },
2830
+ {
2831
+ :quantity => "1.2322",
2832
+ :name => "Name #2",
2833
+ :kind => "credit",
2834
+ :unit_amount => "45.1232",
2835
+ :unit_of_measure => "gallon",
2836
+ :discount_amount => "1.02",
2837
+ :total_amount => "$45.15",
2838
+ :product_code => "23434",
2839
+ :commodity_code => "9SAASSD8724",
2840
+ },
2841
+ ],
2842
+ )
2843
+ result.success?.should == false
2844
+ result.errors.for(:transaction).for(:line_items).for(:index_1).on(:total_amount)[0].code.should == Braintree::ErrorCodes::TransactionLineItem::TotalAmountFormatIsInvalid
2845
+ end
2846
+
2847
+ it "handles validation error total amount is required" do
2848
+ result = Braintree::Transaction.create(
2849
+ :type => "sale",
2850
+ :amount => "35.05",
2851
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
2852
+ :line_items => [
2853
+ {
2854
+ :quantity => "1.2322",
2855
+ :name => "Name #1",
2856
+ :kind => "debit",
2857
+ :unit_amount => "45.1232",
2858
+ :unit_of_measure => "gallon",
2859
+ :discount_amount => "1.02",
2860
+ :total_amount => "45.15",
2861
+ :product_code => "23434",
2862
+ :commodity_code => "9SAASSD8724",
2863
+ },
2864
+ {
2865
+ :quantity => "1.2322",
2866
+ :name => "Name #2",
2867
+ :kind => "credit",
2868
+ :unit_amount => "45.1232",
2869
+ :unit_of_measure => "gallon",
2870
+ :discount_amount => "1.02",
2871
+ :product_code => "23434",
2872
+ :commodity_code => "9SAASSD8724",
2873
+ },
2874
+ ],
2875
+ )
2876
+ result.success?.should == false
2877
+ result.errors.for(:transaction).for(:line_items).for(:index_1).on(:total_amount)[0].code.should == Braintree::ErrorCodes::TransactionLineItem::TotalAmountIsRequired
2878
+ end
2879
+
2880
+ it "handles validation error total amount is too large" do
2881
+ result = Braintree::Transaction.create(
2882
+ :type => "sale",
2883
+ :amount => "35.05",
2884
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
2885
+ :line_items => [
2886
+ {
2887
+ :quantity => "1.2322",
2888
+ :name => "Name #1",
2889
+ :kind => "debit",
2890
+ :unit_amount => "45.1232",
2891
+ :unit_of_measure => "gallon",
2892
+ :discount_amount => "1.02",
2893
+ :total_amount => "45.15",
2894
+ :product_code => "23434",
2895
+ :commodity_code => "9SAASSD8724",
2896
+ },
2897
+ {
2898
+ :quantity => "1.2322",
2899
+ :name => "Name #2",
2900
+ :kind => "credit",
2901
+ :unit_amount => "45.1232",
2902
+ :unit_of_measure => "gallon",
2903
+ :discount_amount => "1.02",
2904
+ :total_amount => "2147483648",
2905
+ :product_code => "23434",
2906
+ :commodity_code => "9SAASSD8724",
2907
+ },
2908
+ ],
2909
+ )
2910
+ result.success?.should == false
2911
+ result.errors.for(:transaction).for(:line_items).for(:index_1).on(:total_amount)[0].code.should == Braintree::ErrorCodes::TransactionLineItem::TotalAmountIsTooLarge
2912
+ end
2913
+
2914
+ it "handles validation error total amount must be greater than zero" do
2915
+ result = Braintree::Transaction.create(
2916
+ :type => "sale",
2917
+ :amount => "35.05",
2918
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
2919
+ :line_items => [
2920
+ {
2921
+ :quantity => "1.2322",
2922
+ :name => "Name #1",
2923
+ :kind => "debit",
2924
+ :unit_amount => "45.1232",
2925
+ :unit_of_measure => "gallon",
2926
+ :discount_amount => "1.02",
2927
+ :total_amount => "45.15",
2928
+ :product_code => "23434",
2929
+ :commodity_code => "9SAASSD8724",
2930
+ },
2931
+ {
2932
+ :quantity => "1.2322",
2933
+ :name => "Name #2",
2934
+ :kind => "credit",
2935
+ :unit_amount => "45.1232",
2936
+ :unit_of_measure => "gallon",
2937
+ :discount_amount => "1.02",
2938
+ :total_amount => "-2",
2939
+ :product_code => "23434",
2940
+ :commodity_code => "9SAASSD8724",
2941
+ },
2942
+ ],
2943
+ )
2944
+ result.success?.should == false
2945
+ result.errors.for(:transaction).for(:line_items).for(:index_1).on(:total_amount)[0].code.should == Braintree::ErrorCodes::TransactionLineItem::TotalAmountMustBeGreaterThanZero
2946
+ end
2947
+
2948
+ it "handles validation error unit amount format is invalid" do
2949
+ result = Braintree::Transaction.create(
2950
+ :type => "sale",
2951
+ :amount => "35.05",
2952
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
2953
+ :line_items => [
2954
+ {
2955
+ :quantity => "1.2322",
2956
+ :name => "Name #1",
2957
+ :kind => "debit",
2958
+ :unit_amount => "45.1232",
2959
+ :unit_of_measure => "gallon",
2960
+ :discount_amount => "1.02",
2961
+ :total_amount => "45.15",
2962
+ :product_code => "23434",
2963
+ :commodity_code => "9SAASSD8724",
2964
+ },
2965
+ {
2966
+ :quantity => "1.2322",
2967
+ :name => "Name #2",
2968
+ :kind => "credit",
2969
+ :unit_amount => "45.01232",
2970
+ :unit_of_measure => "gallon",
2971
+ :discount_amount => "1.02",
2972
+ :total_amount => "45.15",
2973
+ :product_code => "23434",
2974
+ :commodity_code => "9SAASSD8724",
2975
+ },
2976
+ ],
2977
+ )
2978
+ result.success?.should == false
2979
+ result.errors.for(:transaction).for(:line_items).for(:index_1).on(:unit_amount)[0].code.should == Braintree::ErrorCodes::TransactionLineItem::UnitAmountFormatIsInvalid
2980
+ end
2981
+
2982
+ it "handles validation error unit amount is required" do
2983
+ result = Braintree::Transaction.create(
2984
+ :type => "sale",
2985
+ :amount => "35.05",
2986
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
2987
+ :line_items => [
2988
+ {
2989
+ :quantity => "1.2322",
2990
+ :name => "Name #1",
2991
+ :kind => "debit",
2992
+ :unit_amount => "45.1232",
2993
+ :unit_of_measure => "gallon",
2994
+ :discount_amount => "1.02",
2995
+ :total_amount => "45.15",
2996
+ :product_code => "23434",
2997
+ :commodity_code => "9SAASSD8724",
2998
+ },
2999
+ {
3000
+ :quantity => "1.2322",
3001
+ :name => "Name #2",
3002
+ :kind => "credit",
3003
+ :unit_of_measure => "gallon",
3004
+ :discount_amount => "1.02",
3005
+ :product_code => "23434",
3006
+ :commodity_code => "9SAASSD8724",
3007
+ },
3008
+ ],
3009
+ )
3010
+ result.success?.should == false
3011
+ result.errors.for(:transaction).for(:line_items).for(:index_1).on(:unit_amount)[0].code.should == Braintree::ErrorCodes::TransactionLineItem::UnitAmountIsRequired
3012
+ end
3013
+
3014
+ it "handles validation error unit amount is too large" do
3015
+ result = Braintree::Transaction.create(
3016
+ :type => "sale",
3017
+ :amount => "35.05",
3018
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
3019
+ :line_items => [
3020
+ {
3021
+ :quantity => "1.2322",
3022
+ :name => "Name #1",
3023
+ :kind => "debit",
3024
+ :unit_amount => "45.1232",
3025
+ :unit_of_measure => "gallon",
3026
+ :discount_amount => "1.02",
3027
+ :total_amount => "45.15",
3028
+ :product_code => "23434",
3029
+ :commodity_code => "9SAASSD8724",
3030
+ },
3031
+ {
3032
+ :quantity => "1.2322",
3033
+ :name => "Name #2",
3034
+ :kind => "credit",
3035
+ :unit_amount => "2147483648",
3036
+ :unit_of_measure => "gallon",
3037
+ :discount_amount => "1.02",
3038
+ :total_amount => "45.15",
3039
+ :product_code => "23434",
3040
+ :commodity_code => "9SAASSD8724",
3041
+ },
3042
+ ],
3043
+ )
3044
+ result.success?.should == false
3045
+ result.errors.for(:transaction).for(:line_items).for(:index_1).on(:unit_amount)[0].code.should == Braintree::ErrorCodes::TransactionLineItem::UnitAmountIsTooLarge
3046
+ end
3047
+
3048
+ it "handles validation error unit amount must be greater than zero" do
3049
+ result = Braintree::Transaction.create(
3050
+ :type => "sale",
3051
+ :amount => "35.05",
3052
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
3053
+ :line_items => [
3054
+ {
3055
+ :quantity => "1.2322",
3056
+ :name => "Name #1",
3057
+ :kind => "debit",
3058
+ :unit_amount => "45.1232",
3059
+ :unit_of_measure => "gallon",
3060
+ :discount_amount => "1.02",
3061
+ :total_amount => "45.15",
3062
+ :product_code => "23434",
3063
+ :commodity_code => "9SAASSD8724",
3064
+ },
3065
+ {
3066
+ :quantity => "1.2322",
3067
+ :name => "Name #2",
3068
+ :kind => "credit",
3069
+ :unit_amount => "-2",
3070
+ :unit_of_measure => "gallon",
3071
+ :discount_amount => "1.02",
3072
+ :total_amount => "45.15",
3073
+ :product_code => "23434",
3074
+ :commodity_code => "9SAASSD8724",
3075
+ },
3076
+ ],
3077
+ )
3078
+ result.success?.should == false
3079
+ result.errors.for(:transaction).for(:line_items).for(:index_1).on(:unit_amount)[0].code.should == Braintree::ErrorCodes::TransactionLineItem::UnitAmountMustBeGreaterThanZero
3080
+ end
3081
+
3082
+ it "handles validation error unit of measure is too long" do
3083
+ result = Braintree::Transaction.create(
3084
+ :type => "sale",
3085
+ :amount => "35.05",
3086
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
3087
+ :line_items => [
3088
+ {
3089
+ :quantity => "1.2322",
3090
+ :name => "Name #1",
3091
+ :kind => "debit",
3092
+ :unit_amount => "45.1232",
3093
+ :unit_of_measure => "gallon",
3094
+ :discount_amount => "1.02",
3095
+ :total_amount => "45.15",
3096
+ :product_code => "23434",
3097
+ :commodity_code => "9SAASSD8724",
3098
+ },
3099
+ {
3100
+ :quantity => "1.2322",
3101
+ :name => "Name #2",
3102
+ :kind => "credit",
3103
+ :unit_amount => "45.1232",
3104
+ :unit_of_measure => "1234567890123",
3105
+ :discount_amount => "1.02",
3106
+ :total_amount => "45.15",
3107
+ :product_code => "23434",
3108
+ :commodity_code => "9SAASSD8724",
3109
+ },
3110
+ ],
3111
+ )
3112
+ result.success?.should == false
3113
+ result.errors.for(:transaction).for(:line_items).for(:index_1).on(:unit_of_measure)[0].code.should == Braintree::ErrorCodes::TransactionLineItem::UnitOfMeasureIsTooLong
3114
+ end
3115
+
3116
+ it "handles validation error unit tax amount format is invalid" do
3117
+ result = Braintree::Transaction.create(
3118
+ :type => "sale",
3119
+ :amount => "35.05",
3120
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
3121
+ :line_items => [
3122
+ {
3123
+ :quantity => "1.2322",
3124
+ :name => "Name #1",
3125
+ :kind => "debit",
3126
+ :unit_amount => "45.1232",
3127
+ :unit_tax_amount => "2.34",
3128
+ :unit_of_measure => "gallon",
3129
+ :discount_amount => "1.02",
3130
+ :total_amount => "45.15",
3131
+ :product_code => "23434",
3132
+ :commodity_code => "9SAASSD8724",
3133
+ },
3134
+ {
3135
+ :quantity => "1.2322",
3136
+ :name => "Name #2",
3137
+ :kind => "credit",
3138
+ :unit_amount => "45.0122",
3139
+ :unit_tax_amount => "2.012",
3140
+ :unit_of_measure => "gallon",
3141
+ :discount_amount => "1.02",
3142
+ :total_amount => "45.15",
3143
+ :product_code => "23434",
3144
+ :commodity_code => "9SAASSD8724",
3145
+ },
3146
+ ],
3147
+ )
3148
+ result.success?.should == false
3149
+ result.errors.for(:transaction).for(:line_items).for(:index_1).on(:unit_tax_amount)[0].code.should == Braintree::ErrorCodes::TransactionLineItem::UnitTaxAmountFormatIsInvalid
3150
+ end
3151
+
3152
+ it "handles validation error unit tax amount is too large" do
3153
+ result = Braintree::Transaction.create(
3154
+ :type => "sale",
3155
+ :amount => "35.05",
3156
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
3157
+ :line_items => [
3158
+ {
3159
+ :quantity => "1.2322",
3160
+ :name => "Name #1",
3161
+ :kind => "debit",
3162
+ :unit_amount => "45.1232",
3163
+ :unit_tax_amount => "1.23",
3164
+ :unit_of_measure => "gallon",
3165
+ :discount_amount => "1.02",
3166
+ :total_amount => "45.15",
3167
+ :product_code => "23434",
3168
+ :commodity_code => "9SAASSD8724",
3169
+ },
3170
+ {
3171
+ :quantity => "1.2322",
3172
+ :name => "Name #2",
3173
+ :kind => "credit",
3174
+ :unit_amount => "45.0122",
3175
+ :unit_tax_amount => "2147483648",
3176
+ :unit_of_measure => "gallon",
3177
+ :discount_amount => "1.02",
3178
+ :total_amount => "45.15",
3179
+ :product_code => "23434",
3180
+ :commodity_code => "9SAASSD8724",
3181
+ },
3182
+ ],
3183
+ )
3184
+ result.success?.should == false
3185
+ result.errors.for(:transaction).for(:line_items).for(:index_1).on(:unit_tax_amount)[0].code.should == Braintree::ErrorCodes::TransactionLineItem::UnitTaxAmountIsTooLarge
3186
+ end
3187
+
3188
+ it "handles validation error unit tax amount must be greater than zero" do
3189
+ result = Braintree::Transaction.create(
3190
+ :type => "sale",
3191
+ :amount => "35.05",
3192
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
3193
+ :line_items => [
3194
+ {
3195
+ :quantity => "1.2322",
3196
+ :name => "Name #1",
3197
+ :kind => "debit",
3198
+ :unit_amount => "45.1232",
3199
+ :unit_of_measure => "gallon",
3200
+ :discount_amount => "1.02",
3201
+ :total_amount => "45.15",
3202
+ :product_code => "23434",
3203
+ :commodity_code => "9SAASSD8724",
3204
+ },
3205
+ {
3206
+ :quantity => "1.2322",
3207
+ :name => "Name #2",
3208
+ :kind => "credit",
3209
+ :unit_amount => "45.0122",
3210
+ :unit_tax_amount => "-1.23",
3211
+ :unit_of_measure => "gallon",
3212
+ :discount_amount => "1.02",
3213
+ :total_amount => "45.15",
3214
+ :product_code => "23434",
3215
+ :commodity_code => "9SAASSD8724",
3216
+ },
3217
+ ],
3218
+ )
3219
+ result.success?.should == false
3220
+ result.errors.for(:transaction).for(:line_items).for(:index_1).on(:unit_tax_amount)[0].code.should == Braintree::ErrorCodes::TransactionLineItem::UnitTaxAmountMustBeGreaterThanZero
3221
+ end
3222
+
3223
+ it "handles validation errors on line items structure" do
3224
+ result = Braintree::Transaction.create(
3225
+ :type => "sale",
3226
+ :amount => "35.05",
3227
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
3228
+ :line_items => {
3229
+ :quantity => "2.02",
3230
+ :name => "Name #2",
3231
+ :kind => "credit",
3232
+ :unit_amount => "5",
3233
+ :unit_of_measure => "gallon",
3234
+ :total_amount => "10.1",
3235
+ },
3236
+ )
3237
+ result.success?.should == false
3238
+ result.errors.for(:transaction).on(:line_items)[0].code.should == Braintree::ErrorCodes::Transaction::LineItemsExpected
3239
+ end
3240
+
3241
+ it "handles invalid arguments on line items structure" do
3242
+ expect do
3243
+ Braintree::Transaction.create(
3244
+ :type => "sale",
3245
+ :amount => "35.05",
3246
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
3247
+ :line_items => [
3248
+ {
3249
+ :quantity => "2.02",
3250
+ :name => "Name #1",
3251
+ :kind => "credit",
3252
+ :unit_amount => "5",
3253
+ :unit_of_measure => "gallon",
3254
+ :total_amount => "10.1",
3255
+ },
3256
+ ['Name #2'],
3257
+ {
3258
+ :quantity => "2.02",
3259
+ :name => "Name #3",
3260
+ :kind => "credit",
3261
+ :unit_amount => "5",
3262
+ :unit_of_measure => "gallon",
3263
+ :total_amount => "10.1",
3264
+ },
3265
+ ],
3266
+ )
3267
+ end.to raise_error(ArgumentError)
3268
+ end
3269
+
3270
+ it "handles validation errors on too many line items" do
3271
+ line_items = 250.times.map do |i|
3272
+ {
3273
+ :quantity => "2.02",
3274
+ :name => "Line item ##{i}",
3275
+ :kind => "credit",
3276
+ :unit_amount => "5",
3277
+ :unit_of_measure => "gallon",
3278
+ :total_amount => "10.1",
3279
+ }
3280
+ end
3281
+ result = Braintree::Transaction.create(
3282
+ :type => "sale",
3283
+ :amount => "35.05",
3284
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
3285
+ :line_items => line_items,
3286
+ )
3287
+ result.success?.should == false
3288
+ result.errors.for(:transaction).on(:line_items)[0].code.should == Braintree::ErrorCodes::Transaction::TooManyLineItems
3289
+ end
3290
+ end
3291
+
2246
3292
  context "level 3 summary data" do
2247
3293
  it "accepts level 3 summary data" do
2248
3294
  result = Braintree::Transaction.create(
@@ -2275,6 +3321,102 @@ describe Braintree::Transaction do
2275
3321
  result.errors.for(:transaction).on(:discount_amount)[0].code.should == Braintree::ErrorCodes::Transaction::DiscountAmountCannotBeNegative
2276
3322
  result.errors.for(:transaction).on(:ships_from_postal_code)[0].code.should == Braintree::ErrorCodes::Transaction::ShipsFromPostalCodeInvalidCharacters
2277
3323
  end
3324
+
3325
+ it "handles validation error discount amount format is invalid" do
3326
+ result = Braintree::Transaction.create(
3327
+ :type => "sale",
3328
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
3329
+ :amount => "10.00",
3330
+ :discount_amount => "2.001",
3331
+ )
3332
+
3333
+ result.success?.should == false
3334
+ result.errors.for(:transaction).on(:discount_amount)[0].code.should == Braintree::ErrorCodes::Transaction::DiscountAmountFormatIsInvalid
3335
+ end
3336
+
3337
+ it "handles validation error discount amount cannot be negative" do
3338
+ result = Braintree::Transaction.create(
3339
+ :type => "sale",
3340
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
3341
+ :amount => "10.00",
3342
+ :discount_amount => "-2",
3343
+ )
3344
+
3345
+ result.success?.should == false
3346
+ result.errors.for(:transaction).on(:discount_amount)[0].code.should == Braintree::ErrorCodes::Transaction::DiscountAmountCannotBeNegative
3347
+ end
3348
+
3349
+ it "handles validation error discount amount is too large" do
3350
+ result = Braintree::Transaction.create(
3351
+ :type => "sale",
3352
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
3353
+ :amount => "10.00",
3354
+ :discount_amount => "2147483648",
3355
+ )
3356
+
3357
+ result.success?.should == false
3358
+ result.errors.for(:transaction).on(:discount_amount)[0].code.should == Braintree::ErrorCodes::Transaction::DiscountAmountIsTooLarge
3359
+ end
3360
+
3361
+ it "handles validation error shipping amount format is invalid" do
3362
+ result = Braintree::Transaction.create(
3363
+ :type => "sale",
3364
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
3365
+ :amount => "10.00",
3366
+ :shipping_amount => "2.001",
3367
+ )
3368
+
3369
+ result.success?.should == false
3370
+ result.errors.for(:transaction).on(:shipping_amount)[0].code.should == Braintree::ErrorCodes::Transaction::ShippingAmountFormatIsInvalid
3371
+ end
3372
+
3373
+ it "handles validation error shipping amount cannot be negative" do
3374
+ result = Braintree::Transaction.create(
3375
+ :type => "sale",
3376
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
3377
+ :amount => "10.00",
3378
+ :shipping_amount => "-2",
3379
+ )
3380
+
3381
+ result.success?.should == false
3382
+ result.errors.for(:transaction).on(:shipping_amount)[0].code.should == Braintree::ErrorCodes::Transaction::ShippingAmountCannotBeNegative
3383
+ end
3384
+
3385
+ it "handles validation error shipping amount is too large" do
3386
+ result = Braintree::Transaction.create(
3387
+ :type => "sale",
3388
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
3389
+ :amount => "10.00",
3390
+ :shipping_amount => "2147483648",
3391
+ )
3392
+
3393
+ result.success?.should == false
3394
+ result.errors.for(:transaction).on(:shipping_amount)[0].code.should == Braintree::ErrorCodes::Transaction::ShippingAmountIsTooLarge
3395
+ end
3396
+
3397
+ it "handles validation error ships from postal code is too long" do
3398
+ result = Braintree::Transaction.create(
3399
+ :type => "sale",
3400
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
3401
+ :amount => "10.00",
3402
+ :ships_from_postal_code => "1234567890",
3403
+ )
3404
+
3405
+ result.success?.should == false
3406
+ result.errors.for(:transaction).on(:ships_from_postal_code)[0].code.should == Braintree::ErrorCodes::Transaction::ShipsFromPostalCodeIsTooLong
3407
+ end
3408
+
3409
+ it "handles validation error ships from postal code invalid characters" do
3410
+ result = Braintree::Transaction.create(
3411
+ :type => "sale",
3412
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
3413
+ :amount => "10.00",
3414
+ :ships_from_postal_code => "12345%78",
3415
+ )
3416
+
3417
+ result.success?.should == false
3418
+ result.errors.for(:transaction).on(:ships_from_postal_code)[0].code.should == Braintree::ErrorCodes::Transaction::ShipsFromPostalCodeInvalidCharacters
3419
+ end
2278
3420
  end
2279
3421
  end
2280
3422