braintree 2.6.3 → 2.7.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.
data/lib/braintree.rb CHANGED
@@ -32,6 +32,8 @@ require File.dirname(__FILE__) + "/braintree/credit_card_gateway"
32
32
  require File.dirname(__FILE__) + "/braintree/credit_card_verification"
33
33
  require File.dirname(__FILE__) + "/braintree/customer"
34
34
  require File.dirname(__FILE__) + "/braintree/customer_gateway"
35
+ require File.dirname(__FILE__) + "/braintree/customer_search"
36
+ require File.dirname(__FILE__) + "/braintree/descriptor"
35
37
  require File.dirname(__FILE__) + "/braintree/digest"
36
38
  require File.dirname(__FILE__) + "/braintree/discount"
37
39
  require File.dirname(__FILE__) + "/braintree/error_codes"
@@ -67,6 +67,11 @@ module Braintree
67
67
  return_object_or_raise(:transaction) { sale(customer_id, transaction_attributes) }
68
68
  end
69
69
 
70
+ # See http://www.braintreepaymentsolutions.com/docs/ruby/customers/search
71
+ def self.search(&block)
72
+ Configuration.gateway.customer.search(&block)
73
+ end
74
+
70
75
  # Returns a ResourceCollection of transactions for the customer with the given +customer_id+.
71
76
  def self.transactions(customer_id, options = {})
72
77
  Configuration.gateway.customer.transactions(customer_id, options = {})
@@ -7,7 +7,7 @@ module Braintree
7
7
 
8
8
  def all
9
9
  response = @config.http.post "/customers/advanced_search_ids"
10
- ResourceCollection.new(response) { |ids| _fetch_customers(ids) }
10
+ ResourceCollection.new(response) { |ids| _fetch_customers(CustomerSearch.new, ids) }
11
11
  end
12
12
 
13
13
  def create(attributes = {})
@@ -40,6 +40,14 @@ module Braintree
40
40
  raise NotFoundError, "customer with id #{customer_id.inspect} not found"
41
41
  end
42
42
 
43
+ def search(&block)
44
+ search = CustomerSearch.new
45
+ block.call(search) if block
46
+
47
+ response = @config.http.post "/customers/advanced_search_ids", {:search => search.to_hash}
48
+ ResourceCollection.new(response) { |ids| _fetch_customers(search, ids) }
49
+ end
50
+
43
51
  def transactions(customer_id, options = {})
44
52
  response = @config.http.post "/customers/#{customer_id}/transaction_ids"
45
53
  ResourceCollection.new(response) { |ids| _fetch_transactions(customer_id, ids) }
@@ -93,8 +101,9 @@ module Braintree
93
101
  end
94
102
  end
95
103
 
96
- def _fetch_customers(ids) # :nodoc:
97
- response = @config.http.post "/customers/advanced_search", {:search => {:ids => ids}}
104
+ def _fetch_customers(search, ids) # :nodoc:
105
+ search.ids.in ids
106
+ response = @config.http.post "/customers/advanced_search", {:search => search.to_hash}
98
107
  attributes = response[:customers]
99
108
  Util.extract_attribute_as_array(attributes, :customer).map { |attrs| Customer._new(@gateway, attrs) }
100
109
  end
@@ -0,0 +1,31 @@
1
+ module Braintree
2
+ class CustomerSearch < AdvancedSearch # :nodoc:
3
+ text_fields(
4
+ :address_extended_address,
5
+ :address_first_name,
6
+ :address_last_name,
7
+ :address_locality,
8
+ :address_postal_code,
9
+ :address_region,
10
+ :address_street_address,
11
+ :cardholder_name,
12
+ :company,
13
+ :email,
14
+ :fax,
15
+ :first_name,
16
+ :id,
17
+ :last_name,
18
+ :payment_method_token,
19
+ :phone,
20
+ :website
21
+ )
22
+
23
+ equality_fields :credit_card_expiration_date
24
+
25
+ partial_match_fields :credit_card_number
26
+
27
+ multiple_value_field :ids
28
+
29
+ range_fields :created_at
30
+ end
31
+ end
@@ -0,0 +1,11 @@
1
+ module Braintree
2
+ class Descriptor # :nodoc:
3
+ include BaseModule
4
+
5
+ attr_reader :name, :phone
6
+
7
+ def initialize(attributes)
8
+ set_instance_variables_from_hash attributes unless attributes.nil?
9
+ end
10
+ end
11
+ end
@@ -78,6 +78,11 @@ module Braintree
78
78
  WebsiteIsTooLong = "81615"
79
79
  end
80
80
 
81
+ module Descriptor
82
+ PhoneFormatIsInvalid = "92202"
83
+ NameFormatIsInvalid = "92201"
84
+ end
85
+
81
86
  # See http://www.braintreepaymentsolutions.com/docs/ruby/subscriptions/validations
82
87
  module Subscription
83
88
  BillingDayOfMonthCannotBeUpdated = "91918"
@@ -102,6 +107,7 @@ module Braintree
102
107
  PaymentMethodTokenCardTypeIsNotAccepted = "91902"
103
108
  PaymentMethodTokenIsInvalid = "91903"
104
109
  PaymentMethodTokenNotAssociatedWithCustomer = "91905"
110
+ PlanBillingFrequencyCannotBeUpdated = "91922"
105
111
  PlanIdIsInvalid = "91904"
106
112
  PriceCannotBeBlank = "81903"
107
113
  PriceFormatIsInvalid = "81904"
@@ -136,8 +142,8 @@ module Braintree
136
142
  # See http://www.braintreepaymentsolutions.com/docs/ruby/transactions/validations
137
143
  module Transaction
138
144
  AmountCannotBeNegative = "81501"
139
- AmountIsRequired = "81502"
140
145
  AmountIsInvalid = "81503"
146
+ AmountIsRequired = "81502"
141
147
  AmountIsTooLarge = "81528"
142
148
  AmountMustBeGreaterThanZero = "81531"
143
149
  BillingAddressConflict = "91530"
@@ -146,15 +152,15 @@ module Braintree
146
152
  CannotRefundUnlessSettled = "91506"
147
153
  CannotSubmitForSettlement = "91507"
148
154
  CreditCardIsRequired = "91508"
149
- CustomerDefaultPaymentMethodCardTypeIsNotAccepted = "81509"
150
155
  CustomFieldIsInvalid = "91526"
151
156
  CustomFieldIsTooLong = "81527"
152
- CustomerIdIsInvalid = "91510"
157
+ CustomerDefaultPaymentMethodCardTypeIsNotAccepted = "81509"
153
158
  CustomerDoesNotHaveCreditCard = "91511"
159
+ CustomerIdIsInvalid = "91510"
154
160
  HasAlreadyBeenRefunded = "91512"
155
161
  MerchantAccountIdIsInvalid = "91513"
156
- MerchantAccountNameIsInvalid = "91513" # Deprecated
157
162
  MerchantAccountIsSuspended = "91514"
163
+ MerchantAccountNameIsInvalid = "91513" # Deprecated
158
164
  OrderIdIsTooLong = "91501"
159
165
  PaymentMethodConflict = "91515"
160
166
  PaymentMethodDoesNotBelongToCustomer = "91516"
@@ -163,11 +169,15 @@ module Braintree
163
169
  PaymentMethodTokenIsInvalid = "91518"
164
170
  ProcessorAuthorizationCodeCannotBeSet = "91519"
165
171
  ProcessorAuthorizationCodeIsInvalid = "81520"
172
+ PurchaseOrderNumberIsTooLong = "91537"
166
173
  RefundAmountIsTooLarge = "91521"
167
174
  SettlementAmountIsTooLarge = "91522"
168
175
  SubscriptionDoesNotBelongToCustomer = "91529"
169
176
  SubscriptionIdIsInvalid = "91528"
170
177
  SubscriptionStatusMustBePastDue = "91531"
178
+ TaxAmountCannotBeNegative = "81534"
179
+ TaxAmountFormatIsInvalid = "81535"
180
+ TaxAmountIsTooLarge = "81536"
171
181
  TypeIsInvalid = "91523"
172
182
  TypeIsRequired = "91524"
173
183
  module Options
@@ -48,6 +48,7 @@ module Braintree
48
48
 
49
49
  def _http_do(http_verb, path, body = nil)
50
50
  connection = Net::HTTP.new(@config.server, @config.port)
51
+ connection.read_timeout = 60
51
52
  if @config.ssl?
52
53
  connection.use_ssl = true
53
54
  connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
@@ -27,6 +27,7 @@ module Braintree
27
27
  attr_reader :next_billing_period_amount
28
28
  attr_reader :number_of_billing_cycles, :billing_day_of_month
29
29
  attr_reader :add_ons, :discounts
30
+ attr_reader :descriptor
30
31
 
31
32
  # See http://www.braintreepaymentsolutions.com/docs/ruby/subscriptions/cancel
32
33
  def self.cancel(subscription_id)
@@ -70,6 +71,7 @@ module Braintree
70
71
  set_instance_variables_from_hash(attributes)
71
72
  @balance = Util.to_big_decimal(balance)
72
73
  @price = Util.to_big_decimal(price)
74
+ @descriptor = Descriptor.new(@descriptor)
73
75
  transactions.map! { |attrs| Transaction._new(gateway, attrs) }
74
76
  add_ons.map! { |attrs| AddOn._new(attrs) }
75
77
  discounts.map! { |attrs| Discount._new(attrs) }
@@ -64,7 +64,8 @@ module Braintree
64
64
  :trial_duration,
65
65
  :trial_duration_unit,
66
66
  :trial_period,
67
- {:options => [:do_not_inherit_add_ons_or_discounts, :start_immediately]}
67
+ {:options => [:do_not_inherit_add_ons_or_discounts, :start_immediately]},
68
+ {:descriptor => [:name, :phone]}
68
69
  ] + _add_on_discount_signature
69
70
  end
70
71
 
@@ -81,7 +82,8 @@ module Braintree
81
82
  :prorate_charges,
82
83
  :replace_all_add_ons_and_discounts,
83
84
  :revert_subscription_on_proration_failure
84
- ]}
85
+ ]},
86
+ {:descriptor => [:name, :phone]}
85
87
  ] + _add_on_discount_signature
86
88
  end
87
89
 
@@ -45,6 +45,7 @@ module Braintree
45
45
  attr_reader :currency_iso_code
46
46
  attr_reader :custom_fields
47
47
  attr_reader :cvv_response_code
48
+ attr_reader :descriptor
48
49
  attr_reader :gateway_rejection_reason
49
50
  attr_reader :merchant_account_id
50
51
  attr_reader :order_id
@@ -55,12 +56,15 @@ module Braintree
55
56
  attr_reader :processor_response_code
56
57
  # The response text from the processor.
57
58
  attr_reader :processor_response_text
59
+ attr_reader :purchase_order_number
58
60
  attr_reader :refund_ids, :refunded_transaction_id
59
61
  attr_reader :settlement_batch_id
60
62
  # See Transaction::Status
61
63
  attr_reader :status
62
64
  attr_reader :status_history
63
65
  attr_reader :subscription_id
66
+ attr_reader :tax_amount
67
+ attr_reader :tax_exempt
64
68
  # Will either be "sale" or "credit"
65
69
  attr_reader :type
66
70
  attr_reader :updated_at
@@ -154,6 +158,8 @@ module Braintree
154
158
  @billing_details = AddressDetails.new(@billing)
155
159
  @shipping_details = AddressDetails.new(@shipping)
156
160
  @status_history = attributes[:status_history] ? attributes[:status_history].map { |s| StatusDetails.new(s) } : []
161
+ @tax_amount = Util.to_big_decimal(tax_amount)
162
+ @descriptor = Descriptor.new(@descriptor)
157
163
  add_ons.map! { |attrs| AddOn._new(attrs) } if add_ons
158
164
  discounts.map! { |attrs| Discount._new(attrs) } if discounts
159
165
  end
@@ -89,7 +89,8 @@ module Braintree
89
89
 
90
90
  def self._create_signature # :nodoc:
91
91
  [
92
- :amount, :customer_id, :merchant_account_id, :order_id, :payment_method_token, :shipping_address_id, :type,
92
+ :amount, :customer_id, :merchant_account_id, :order_id, :payment_method_token,
93
+ :purchase_order_number, :shipping_address_id, :type, :tax_amount, :tax_exempt,
93
94
  {:credit_card => [:token, :cardholder_name, :cvv, :expiration_date, :expiration_month, :expiration_year, :number]},
94
95
  {:customer => [:id, :company, :email, :fax, :first_name, :last_name, :phone, :website]},
95
96
  {
@@ -99,7 +100,8 @@ module Braintree
99
100
  :shipping => AddressGateway._shared_signature
100
101
  },
101
102
  {:options => [:store_in_vault, :submit_for_settlement, :add_billing_address_to_payment_method, :store_shipping_address_in_vault]},
102
- {:custom_fields => :_any_key_}
103
+ {:custom_fields => :_any_key_},
104
+ {:descriptor => [:name, :phone]}
103
105
  ]
104
106
  end
105
107
 
@@ -1,8 +1,8 @@
1
1
  module Braintree
2
2
  module Version
3
3
  Major = 2
4
- Minor = 6
5
- Tiny = 3
4
+ Minor = 7
5
+ Tiny = 0
6
6
 
7
7
  String = "#{Major}.#{Minor}.#{Tiny}"
8
8
  end
@@ -73,6 +73,17 @@ describe Braintree::CreditCard do
73
73
  credit_card.billing_address.last_name.should == "Tables"
74
74
  end
75
75
 
76
+ it "accepts empty options hash" do
77
+ customer = Braintree::Customer.create!
78
+ result = Braintree::CreditCard.create(
79
+ :customer_id => customer.id,
80
+ :number => Braintree::Test::CreditCardNumbers::FailsSandboxVerification::Visa,
81
+ :expiration_date => "05/2009",
82
+ :options => {}
83
+ )
84
+ result.success?.should == true
85
+ end
86
+
76
87
  it "verifies the credit card if options[verify_card]=true" do
77
88
  customer = Braintree::Customer.create!
78
89
  result = Braintree::CreditCard.create(
@@ -0,0 +1,146 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe Braintree::Transaction, "search" do
4
+ context "advanced" do
5
+ it "correctly returns a result with no matches" do
6
+ collection = Braintree::Customer.search do |search|
7
+ search.first_name.is "thisnameisnotreal"
8
+ end
9
+
10
+ collection.maximum_size.should == 0
11
+ end
12
+
13
+ it "can search on text fields" do
14
+ cctoken = "cctoken#{rand(1_000_000)}"
15
+ customer = Braintree::Customer.create!(
16
+ :first_name => "Timmy",
17
+ :last_name => "O'Toole",
18
+ :company => "O'Toole and #{rand(1_000_000)} Son(s)",
19
+ :email => "timmy@example.com",
20
+ :fax => "3145551234",
21
+ :phone => "5551231234",
22
+ :website => "http://example.com",
23
+ :credit_card => {
24
+ :cardholder_name => "Tim Tool",
25
+ :number => Braintree::Test::CreditCardNumbers::Visa,
26
+ :expiration_date => "05/2010",
27
+ :token => cctoken,
28
+ :billing_address => {
29
+ :first_name => "Thomas",
30
+ :last_name => "Otool",
31
+ :street_address => "1 E Main St",
32
+ :extended_address => "Suite 3",
33
+ :locality => "Chicago",
34
+ :region => "Illinois",
35
+ :postal_code => "60622",
36
+ :country_name => "United States of America"
37
+ }
38
+ }
39
+ )
40
+
41
+ customer = Braintree::Customer.find(customer.id)
42
+
43
+ search_criteria = {
44
+ :first_name => "Timmy",
45
+ :last_name => "O'Toole",
46
+ :company => customer.company,
47
+ :email => "timmy@example.com",
48
+ :phone => "5551231234",
49
+ :fax => "3145551234",
50
+ :website => "http://example.com",
51
+ :address_first_name => "Thomas",
52
+ :address_last_name => "Otool",
53
+ :address_street_address => "1 E Main St",
54
+ :address_postal_code => "60622",
55
+ :address_extended_address => "Suite 3",
56
+ :address_locality => "Chicago",
57
+ :address_region => "Illinois",
58
+ :payment_method_token => cctoken,
59
+ :cardholder_name => "Tim Tool",
60
+ :credit_card_expiration_date => "05/2010",
61
+ :credit_card_number => Braintree::Test::CreditCardNumbers::Visa
62
+ }
63
+
64
+ search_criteria.each do |criterion, value|
65
+ collection = Braintree::Customer.search do |search|
66
+ search.id.is customer.id
67
+ search.send(criterion).is value
68
+ end
69
+
70
+ collection.maximum_size.should == 1
71
+ collection.first.id.should == customer.id
72
+
73
+ collection = Braintree::Customer.search do |search|
74
+ search.id.is customer.id
75
+ search.send(criterion).is("invalid_attribute")
76
+ end
77
+ collection.should be_empty
78
+ end
79
+
80
+ collection = Braintree::Customer.search do |search|
81
+ search.id.is customer.id
82
+ search_criteria.each do |criterion, value|
83
+ search.send(criterion).is value
84
+ end
85
+ end
86
+
87
+ collection.maximum_size.should == 1
88
+ collection.first.id.should == customer.id
89
+ end
90
+
91
+ it "can search by created_at" do
92
+ company = "Company #{rand(1_000_000)}"
93
+ customer = Braintree::Customer.create!(
94
+ :company => company
95
+ )
96
+
97
+ created_at = customer.created_at
98
+ created_at.should be_utc
99
+
100
+ collection = Braintree::Customer.search do |search|
101
+ search.company.is company
102
+ search.created_at.between(
103
+ created_at - 60,
104
+ created_at + 60
105
+ )
106
+ end
107
+
108
+ collection.maximum_size.should == 1
109
+ collection.first.id.should == customer.id
110
+
111
+ collection = Braintree::Customer.search do |search|
112
+ search.company.is customer.company
113
+ search.created_at >= created_at - 1
114
+ end
115
+
116
+ collection.maximum_size.should == 1
117
+ collection.first.company.should == customer.company
118
+
119
+ collection = Braintree::Customer.search do |search|
120
+ search.company.is customer.company
121
+ search.created_at <= created_at + 1
122
+ end
123
+
124
+ collection.maximum_size.should == 1
125
+ collection.first.company.should == customer.company
126
+
127
+ collection = Braintree::Customer.search do |search|
128
+ search.company.is customer.company
129
+ search.created_at.between(
130
+ created_at - 300,
131
+ created_at - 100
132
+ )
133
+ end
134
+
135
+ collection.maximum_size.should == 0
136
+
137
+ collection = Braintree::Customer.search do |search|
138
+ search.company.is customer.company
139
+ search.created_at.is created_at
140
+ end
141
+
142
+ collection.maximum_size.should == 1
143
+ collection.first.company.should == customer.company
144
+ end
145
+ end
146
+ end
@@ -520,6 +520,42 @@ describe Braintree::Subscription do
520
520
  result.errors.for(:subscription).for(:add_ons).for(:update).for_index(1).on(:quantity)[0].code.should == Braintree::ErrorCodes::Subscription::Modification::QuantityIsInvalid
521
521
  end
522
522
  end
523
+
524
+ context "descriptors" do
525
+ it "accepts name and phone and copies them to the transaction" do
526
+ result = Braintree::Subscription.create(
527
+ :payment_method_token => @credit_card.token,
528
+ :plan_id => SpecHelper::TriallessPlan[:id],
529
+ :descriptor => {
530
+ :name => '123*123456789012345678',
531
+ :phone => '3334445555'
532
+ }
533
+ )
534
+
535
+ result.success?.should == true
536
+ result.subscription.descriptor.name.should == '123*123456789012345678'
537
+ result.subscription.descriptor.phone.should == '3334445555'
538
+
539
+ result.subscription.transactions.size.should == 1
540
+ transaction = result.subscription.transactions.first
541
+ transaction.descriptor.name.should == '123*123456789012345678'
542
+ transaction.descriptor.phone.should == '3334445555'
543
+ end
544
+
545
+ it "has validation errors if format is invalid" do
546
+ result = Braintree::Subscription.create(
547
+ :payment_method_token => @credit_card.token,
548
+ :plan_id => SpecHelper::TriallessPlan[:id],
549
+ :descriptor => {
550
+ :name => 'badcompanyname12*badproduct12',
551
+ :phone => '%bad4445555'
552
+ }
553
+ )
554
+ result.success?.should == false
555
+ result.errors.for(:subscription).for(:descriptor).on(:name)[0].code.should == Braintree::ErrorCodes::Descriptor::NameFormatIsInvalid
556
+ result.errors.for(:subscription).for(:descriptor).on(:phone)[0].code.should == Braintree::ErrorCodes::Descriptor::PhoneFormatIsInvalid
557
+ end
558
+ end
523
559
  end
524
560
 
525
561
  describe "self.create!" do
@@ -606,6 +642,19 @@ describe Braintree::Subscription do
606
642
  result.subscription.payment_method_token.should == new_credit_card.token
607
643
  end
608
644
 
645
+ it "allows chaning the descriptors" do
646
+ result = Braintree::Subscription.update(@subscription.id,
647
+ :descriptor => {
648
+ :name => 'aaa*1234',
649
+ :phone => '3334443333'
650
+ }
651
+ )
652
+
653
+ result.success?.should == true
654
+ result.subscription.descriptor.name.should == 'aaa*1234'
655
+ result.subscription.descriptor.phone.should == '3334443333'
656
+ end
657
+
609
658
  context "when successful" do
610
659
  it "returns a success response with the updated subscription if valid" do
611
660
  new_id = rand(36**9).to_s(36)
@@ -10,7 +10,7 @@ describe Braintree::Transaction, "search" do
10
10
  collection.maximum_size.should == 0
11
11
  end
12
12
 
13
- it "returns one result for text field search" do
13
+ it "can search on text fields" do
14
14
  first_name = "Tim#{rand(10000)}"
15
15
  token = "creditcard#{rand(10000)}"
16
16
  customer_id = "customer#{rand(10000)}"
@@ -115,92 +115,12 @@ describe Braintree::Transaction, "search" do
115
115
  end
116
116
  collection.should be_empty
117
117
  end
118
- end
119
-
120
- it "searches all fields at once" do
121
- first_name = "Tim#{rand(10000)}"
122
- token = "creditcard#{rand(10000)}"
123
- customer_id = "customer#{rand(10000)}"
124
-
125
- transaction = Braintree::Transaction.sale!(
126
- :amount => Braintree::Test::TransactionAmounts::Authorize,
127
- :credit_card => {
128
- :number => Braintree::Test::CreditCardNumbers::Visa,
129
- :expiration_date => "05/2012",
130
- :cardholder_name => "Tom Smith",
131
- :token => token,
132
- },
133
- :billing => {
134
- :company => "Braintree",
135
- :country_name => "United States of America",
136
- :extended_address => "Suite 123",
137
- :first_name => first_name,
138
- :last_name => "Smith",
139
- :locality => "Chicago",
140
- :postal_code => "12345",
141
- :region => "IL",
142
- :street_address => "123 Main St"
143
- },
144
- :customer => {
145
- :company => "Braintree",
146
- :email => "smith@example.com",
147
- :fax => "5551231234",
148
- :first_name => "Tom",
149
- :id => customer_id,
150
- :last_name => "Smith",
151
- :phone => "5551231234",
152
- :website => "http://example.com",
153
- },
154
- :options => {
155
- :store_in_vault => true
156
- },
157
- :order_id => "myorder",
158
- :shipping => {
159
- :company => "Braintree P.S.",
160
- :country_name => "Mexico",
161
- :extended_address => "Apt 456",
162
- :first_name => "Thomas",
163
- :last_name => "Smithy",
164
- :locality => "Braintree",
165
- :postal_code => "54321",
166
- :region => "MA",
167
- :street_address => "456 Road"
168
- })
169
118
 
170
119
  collection = Braintree::Transaction.search do |search|
171
- search.billing_company.is "Braintree"
172
- search.billing_country_name.is "United States of America"
173
- search.billing_extended_address.is "Suite 123"
174
- search.billing_first_name.is first_name
175
- search.billing_last_name.is "Smith"
176
- search.billing_locality.is "Chicago"
177
- search.billing_postal_code.is "12345"
178
- search.billing_region.is "IL"
179
- search.billing_street_address.is "123 Main St"
180
- search.credit_card_cardholder_name.is "Tom Smith"
181
- search.credit_card_expiration_date.is "05/2012"
182
- search.credit_card_number.is Braintree::Test::CreditCardNumbers::Visa
183
- search.customer_company.is "Braintree"
184
- search.customer_email.is "smith@example.com"
185
- search.customer_fax.is "5551231234"
186
- search.customer_first_name.is "Tom"
187
- search.customer_id.is customer_id
188
- search.customer_last_name.is "Smith"
189
- search.customer_phone.is "5551231234"
190
- search.customer_website.is "http://example.com"
191
- search.order_id.is "myorder"
192
- search.payment_method_token.is token
193
- search.processor_authorization_code.is transaction.processor_authorization_code
194
- search.shipping_company.is "Braintree P.S."
195
- search.shipping_country_name.is "Mexico"
196
- search.shipping_extended_address.is "Apt 456"
197
- search.shipping_first_name.is "Thomas"
198
- search.shipping_last_name.is "Smithy"
199
- search.shipping_locality.is "Braintree"
200
- search.shipping_postal_code.is "54321"
201
- search.shipping_region.is "MA"
202
- search.shipping_street_address.is "456 Road"
203
120
  search.id.is transaction.id
121
+ search_criteria.each do |criterion, value|
122
+ search.send(criterion).is value
123
+ end
204
124
  end
205
125
 
206
126
  collection.maximum_size.should == 1
@@ -518,9 +438,9 @@ describe Braintree::Transaction, "search" do
518
438
  transaction = Braintree::Transaction.sale!(
519
439
  :amount => Braintree::Test::TransactionAmounts::Authorize,
520
440
  :credit_card => {
521
- :number => Braintree::Test::CreditCardNumbers::Visa,
522
- :expiration_date => "05/12"
523
- }
441
+ :number => Braintree::Test::CreditCardNumbers::Visa,
442
+ :expiration_date => "05/12"
443
+ }
524
444
  )
525
445
 
526
446
  created_at = transaction.created_at
@@ -512,6 +512,92 @@ describe Braintree::Transaction do
512
512
  transaction.discounts.first.number_of_billing_cycles.should be_nil
513
513
  transaction.discounts.first.never_expires?.should be_true
514
514
  end
515
+
516
+ context "descriptors" do
517
+ it "accepts name and phone" do
518
+ result = Braintree::Transaction.sale(
519
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
520
+ :credit_card => {
521
+ :number => Braintree::Test::CreditCardNumbers::Visa,
522
+ :expiration_date => "05/2009"
523
+ },
524
+ :descriptor => {
525
+ :name => '123*123456789012345678',
526
+ :phone => '3334445555'
527
+ }
528
+ )
529
+ result.success?.should == true
530
+ result.transaction.descriptor.name.should == '123*123456789012345678'
531
+ result.transaction.descriptor.phone.should == '3334445555'
532
+ end
533
+
534
+ it "has validation errors if format is invalid" do
535
+ result = Braintree::Transaction.sale(
536
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
537
+ :credit_card => {
538
+ :number => Braintree::Test::CreditCardNumbers::Visa,
539
+ :expiration_date => "05/2009"
540
+ },
541
+ :descriptor => {
542
+ :name => 'badcompanyname12*badproduct12',
543
+ :phone => '%bad4445555'
544
+ }
545
+ )
546
+ result.success?.should == false
547
+ result.errors.for(:transaction).for(:descriptor).on(:name)[0].code.should == Braintree::ErrorCodes::Descriptor::NameFormatIsInvalid
548
+ result.errors.for(:transaction).for(:descriptor).on(:phone)[0].code.should == Braintree::ErrorCodes::Descriptor::PhoneFormatIsInvalid
549
+ end
550
+ end
551
+
552
+ context "level 2 fields" do
553
+ it "accepts tax_amount, tax_exempt, and purchase_order_number" do
554
+ result = Braintree::Transaction.sale(
555
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
556
+ :credit_card => {
557
+ :number => Braintree::Test::CreditCardNumbers::Visa,
558
+ :expiration_date => "05/2009"
559
+ },
560
+ :tax_amount => '0.05',
561
+ :tax_exempt => false,
562
+ :purchase_order_number => '12345678901234567'
563
+ )
564
+ result.success?.should == true
565
+ result.transaction.tax_amount.should == BigDecimal.new("0.05")
566
+ result.transaction.tax_exempt.should == false
567
+ result.transaction.purchase_order_number.should == '12345678901234567'
568
+ end
569
+
570
+ it "accepts tax_amount as a BigDecimal" do
571
+ result = Braintree::Transaction.sale(
572
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
573
+ :credit_card => {
574
+ :number => Braintree::Test::CreditCardNumbers::Visa,
575
+ :expiration_date => "05/2009"
576
+ },
577
+ :tax_amount => BigDecimal.new('1.99'),
578
+ :tax_exempt => true
579
+ )
580
+ result.success?.should == true
581
+ result.transaction.tax_amount.should == BigDecimal.new("1.99")
582
+ result.transaction.tax_exempt.should == true
583
+ result.transaction.purchase_order_number.should be_nil
584
+ end
585
+
586
+ it "has validation errors" do
587
+ result = Braintree::Transaction.sale(
588
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
589
+ :credit_card => {
590
+ :number => Braintree::Test::CreditCardNumbers::Visa,
591
+ :expiration_date => "05/2009"
592
+ },
593
+ :tax_amount => 'abcd',
594
+ :purchase_order_number => 'a' * 18
595
+ )
596
+ result.success?.should == false
597
+ result.errors.for(:transaction).on(:tax_amount)[0].code.should == Braintree::ErrorCodes::Transaction::TaxAmountFormatIsInvalid
598
+ result.errors.for(:transaction).on(:purchase_order_number)[0].code.should == Braintree::ErrorCodes::Transaction::PurchaseOrderNumberIsTooLong
599
+ end
600
+ end
515
601
  end
516
602
 
517
603
  describe "self.create!" do
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: braintree
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 2
8
- - 6
9
- - 3
10
- version: 2.6.3
8
+ - 7
9
+ - 0
10
+ version: 2.7.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Braintree Payment Solutions
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-01-10 00:00:00 -06:00
18
+ date: 2011-01-26 00:00:00 -06:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -55,6 +55,8 @@ files:
55
55
  - lib/braintree/credit_card_verification.rb
56
56
  - lib/braintree/customer.rb
57
57
  - lib/braintree/customer_gateway.rb
58
+ - lib/braintree/customer_search.rb
59
+ - lib/braintree/descriptor.rb
58
60
  - lib/braintree/digest.rb
59
61
  - lib/braintree/discount.rb
60
62
  - lib/braintree/error_codes.rb
@@ -94,6 +96,7 @@ files:
94
96
  - spec/integration/braintree/address_spec.rb
95
97
  - spec/integration/braintree/advanced_search_spec.rb
96
98
  - spec/integration/braintree/credit_card_spec.rb
99
+ - spec/integration/braintree/customer_search_spec.rb
97
100
  - spec/integration/braintree/customer_spec.rb
98
101
  - spec/integration/braintree/error_codes_spec.rb
99
102
  - spec/integration/braintree/http_spec.rb