Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

2.2.0

  • Loading branch information...
commit 2cfda43d4542a72813089686ce54541390a01a56 1 parent d103526
@braintreeps braintreeps authored
View
6 CHANGELOG.rdoc
@@ -1,3 +1,9 @@
+== 2.2.0
+
+* Prevent race condition when pulling back collection results -- search results represent the state of the data at the time the query was run
+* Rename ResourceCollection's approximate_size to maximum_size because items that no longer match the query will not be returned in the result set
+* Correctly handle HTTP error 426 (Upgrade Required) -- the error code is returned when your client library version is no longer compatible with the gateway
+
== 2.1.0
* Added transaction advanced search
View
3  lib/braintree.rb
@@ -1,7 +1,8 @@
-require 'bigdecimal'
+require "bigdecimal"
require "cgi"
require "date"
require "digest/sha1"
+require "enumerator"
require "logger"
require "net/http"
require "net/https"
View
35 lib/braintree/credit_card.rb
@@ -66,25 +66,17 @@ def self.credit!(token, transaction_attributes)
# Returns a ResourceCollection of expired credit cards.
def self.expired(options = {})
- page_number = options[:page] || 1
- response = Http.get("/payment_methods/all/expired?page=#{page_number}")
- attributes = response[:payment_methods]
- attributes[:items] = Util.extract_attribute_as_array(attributes, :credit_card).map do |payment_method_attributes|
- new payment_method_attributes
- end
- ResourceCollection.new(attributes) { |page_number| CreditCard.expired(:page => page_number) }
+ response = Http.post("/payment_methods/all/expired_ids")
+ ResourceCollection.new(response) { |ids| _fetch_expired(ids) }
end
# Returns a ResourceCollection of credit cards expiring between +start_date+ and +end_date+ inclusive.
# Only the month and year of the start and end dates are used.
def self.expiring_between(start_date, end_date, options = {})
- page_number = options[:page] || 1
- response = Http.get("/payment_methods/all/expiring?page=#{page_number}&start=#{start_date.strftime('%m%Y')}&end=#{end_date.strftime('%m%Y')}")
- attributes = response[:payment_methods]
- attributes[:items] = Util.extract_attribute_as_array(attributes, :credit_card).map do |payment_method_attributes|
- new payment_method_attributes
- end
- ResourceCollection.new(attributes) { |page_number| CreditCard.expiring_between(start_date, end_date, :page => page_number) }
+ formatted_start_date = start_date.strftime('%m%Y')
+ formatted_end_date = end_date.strftime('%m%Y')
+ response = Http.post("/payment_methods/all/expiring_ids?start=#{formatted_start_date}&end=#{formatted_end_date}")
+ ResourceCollection.new(response) { |ids| _fetch_expiring_between(formatted_start_date, formatted_end_date, ids) }
end
# Finds the credit card with the given +token+. Raises a NotFoundError if it cannot be found.
@@ -124,6 +116,21 @@ def self.update_credit_card_url
"#{Braintree::Configuration.base_merchant_url}/payment_methods/all/update_via_transparent_redirect_request"
end
+ def self._fetch_expired(ids)
+ response = Http.post("/payment_methods/all/expired", :search => {:ids => ids})
+ attributes = response[:payment_methods]
+ Util.extract_attribute_as_array(attributes, :credit_card).map { |attrs| _new(attrs) }
+ end
+
+ def self._fetch_expiring_between(formatted_start_date, formatted_end_date, ids)
+ response = Http.post(
+ "/payment_methods/all/expiring?start=#{formatted_start_date}&end=#{formatted_end_date}",
+ :search => {:ids => ids}
+ )
+ attributes = response[:payment_methods]
+ Util.extract_attribute_as_array(attributes, :credit_card).map { |attrs| _new(attrs) }
+ end
+
def initialize(attributes) # :nodoc:
_init attributes
@subscriptions = (@subscriptions || []).map { |subscription_hash| Subscription._new(subscription_hash) }
View
39 lib/braintree/customer.rb
@@ -8,25 +8,21 @@ class Customer
attr_reader :addresses, :company, :created_at, :credit_cards, :email, :fax, :first_name, :id, :last_name,
:phone, :updated_at, :website, :custom_fields
- # Returns a ResourceCollection of all customers stored in the vault. Due to race conditions, this method
- # may not reliably return all customers stored in the vault.
+ # Returns a ResourceCollection of all customers stored in the vault.
#
- # page = Braintree::Customer.all
- # loop do
- # page.each do |customer|
- # puts "Customer #{customer.id} email is #{customer.email}"
- # end
- # break if page.last_page?
- # page = page.next_page
+ # customers = Braintree::Customer.all
+ # customers.each do |customer|
+ # puts "Customer #{customer.id} email is #{customer.email}"
# end
- def self.all(options = {})
- page_number = options[:page] || 1
- response = Http.get("/customers?page=#{page_number}")
+ def self.all
+ response = Http.post "/customers/advanced_search_ids"
+ ResourceCollection.new(response) { |ids| _fetch_customers(ids) }
+ end
+
+ def self._fetch_customers(ids)
+ response = Http.post "/customers/advanced_search", {:search => {:ids => ids}}
attributes = response[:customers]
- attributes[:items] = Util.extract_attribute_as_array(attributes, :customer).map do |customer_attributes|
- new customer_attributes
- end
- ResourceCollection.new(attributes) { |page_number| Customer.all(:page => page_number) }
+ Util.extract_attribute_as_array(attributes, :customer).map { |attrs| _new(attrs) }
end
# Creates a customer using the given +attributes+. If <tt>:id</tt> is not passed,
@@ -100,13 +96,16 @@ def self.sale!(customer_id, transaction_attributes)
# Returns a ResourceCollection of transactions for the customer with the given +customer_id+.
def self.transactions(customer_id, options = {})
- page_number = options[:page] || 1
- response = Http.get "/customers/#{customer_id}/transactions?page=#{page_number}"
+ response = Http.post "/customers/#{customer_id}/transaction_ids"
+ ResourceCollection.new(response) { |ids| _fetch_transactions(customer_id, ids) }
+ end
+
+ def self._fetch_transactions(customer_id, ids)
+ response = Http.post "/customers/#{customer_id}/transactions", :search => {:ids => ids}
attributes = response[:credit_card_transactions]
- attributes[:items] = Util.extract_attribute_as_array(attributes, :transaction).map do |transaction_attributes|
+ Util.extract_attribute_as_array(attributes, :transaction).map do |transaction_attributes|
Transaction._new transaction_attributes
end
- ResourceCollection.new(attributes) { |page_number| Customer.transactions(customer_id, :page => page_number) }
end
def self.update(customer_id, attributes)
View
3  lib/braintree/exceptions.rb
@@ -38,6 +38,9 @@ class SSLCertificateError < BraintreeError; end
# This shouldn't happen.
class UnexpectedError < BraintreeError; end
+ # Raised when a client library that has been End of Life'd is being used.
+ class UpgradeRequiredError < BraintreeError; end
+
# Raised from bang methods when validations fail.
class ValidationsFailed < BraintreeError
attr_reader :error_result
View
52 lib/braintree/resource_collection.rb
@@ -1,55 +1,35 @@
module Braintree
class ResourceCollection
- include BaseModule
include Enumerable
- def initialize(attributes, &block) # :nodoc:
- set_instance_variables_from_hash attributes
+ def initialize(response, &block) # :nodoc:
+ @ids = Util.extract_attribute_as_array(response[:search_results], :ids)
+ @page_size = response[:search_results][:page_size]
@paging_block = block
end
- # Yields each item on the current page.
+ # Yields each item
def each(&block)
- @items.each(&block)
-
- _next_page.each(&block) unless _last_page?
+ @ids.each_slice(@page_size) do |page_of_ids|
+ resources = @paging_block.call(page_of_ids)
+ resources.each(&block)
+ end
end
def empty?
- @items.empty?
+ @ids.empty?
end
- # Returns the first item from the current page.
+ # Returns the first item in the collection or nil if the collection is empty
def first
- @items.first
- end
-
- # Returns true if the page is the last page. False otherwise.
- def _last_page?
- @current_page_number == _total_pages
- end
-
- # Retrieves the next page of records.
- def _next_page
- if _last_page?
- return nil
- end
- @paging_block.call(@current_page_number + 1)
+ @paging_block.call([@ids.first]).first
end
- # The size of a resource collection is only approximate due to race conditions when pulling back results. This method
- # should be avoided.
- def _approximate_size
- @total_items
- end
-
- # Returns the total number of pages.
- def _total_pages
- total = @total_items / @page_size
- if @total_items % @page_size != 0
- total += 1
- end
- total
+ # Only the maximum size of a resource collection can be determined since the data on the server can change while
+ # fetching blocks of results for iteration. For example, customers can be deleted while iterating, so the number
+ # of results iterated over may be less than the maximum_size. In general, this method should be avoided.
+ def maximum_size
+ @ids.size
end
end
end
View
15 lib/braintree/subscription.rb
@@ -97,14 +97,19 @@ def self.retry_charge(subscription_id, amount=nil)
# s.days_past_due.is "30"
# s.status.in [Subscription::Status::PastDue]
# end
- def self.search(page=1, &block)
+ def self.search(&block)
search = SubscriptionSearch.new
- block.call(search)
+ block.call(search) if block
- response = Http.post "/subscriptions/advanced_search?page=#{page}", {:search => search.to_hash}
+ response = Http.post "/subscriptions/advanced_search_ids", {:search => search.to_hash}
+ ResourceCollection.new(response) { |ids| _fetch_subscriptions(search, ids) }
+ end
+
+ def self._fetch_subscriptions(search, ids)
+ search.ids.in ids
+ response = Http.post "/subscriptions/advanced_search", {:search => search.to_hash}
attributes = response[:subscriptions]
- attributes[:items] = Util.extract_attribute_as_array(attributes, :subscription).map { |attrs| _new(attrs) }
- ResourceCollection.new(attributes) { |page_number| Subscription.search(page_number, &block) }
+ Util.extract_attribute_as_array(attributes, :subscription).map { |attrs| _new(attrs) }
end
def self.update(subscription_id, attributes)
View
1  lib/braintree/subscription_search.rb
@@ -1,5 +1,6 @@
module Braintree
class SubscriptionSearch < AdvancedSearch
+ multiple_value_field :ids
search_fields :plan_id, :days_past_due
multiple_value_field :status, :allows => [
Subscription::Status::Active,
View
40 lib/braintree/transaction.rb
@@ -223,14 +223,13 @@ def self.sale!(attributes)
# Returns a ResourceCollection of transactions matching the search query.
# If <tt>query</tt> is a string, the search will be a basic search.
# If <tt>query</tt> is a hash, the search will be an advanced search.
- def self.search(query = nil, page=1, &block)
- if block_given?
- _advanced_search page, &block
- elsif query.is_a?(String)
- _basic_search query, page
- else
- raise ArgumentError, "expected search to be a string or a block"
- end
+ # See: http://www.braintreepaymentsolutions.com/gateway/transaction-api#searching
+ def self.search(&block)
+ search = TransactionSearch.new
+ block.call(search) if block
+
+ response = Http.post "/transactions/advanced_search_ids", {:search => search.to_hash}
+ ResourceCollection.new(response) { |ids| _fetch_transactions(search, ids) }
end
# Submits transaction with +transaction_id+ for settlement.
@@ -395,28 +394,10 @@ def self._do_create(url, params) # :nodoc:
end
end
- def self._advanced_search(page, &block) # :nodoc:
- search = TransactionSearch.new
- block.call(search)
-
- response = Http.post "/transactions/advanced_search?page=#{page}", {:search => search.to_hash}
- attributes = response[:credit_card_transactions]
- attributes[:items] = Util.extract_attribute_as_array(attributes, :transaction).map { |attrs| _new(attrs) }
-
- ResourceCollection.new(attributes) { |page_number| Transaction.search(nil, page_number, &block) }
- end
-
def self._attributes # :nodoc:
[:amount, :created_at, :credit_card_details, :customer_details, :id, :status, :type, :updated_at]
end
- def self._basic_search(query, page) # :nodoc:
- response = Http.get "/transactions/all/search?q=#{Util.url_encode(query)}&page=#{Util.url_encode(page)}"
- attributes = response[:credit_card_transactions]
- attributes[:items] = Util.extract_attribute_as_array(attributes, :transaction).map { |attrs| _new(attrs) }
- ResourceCollection.new(attributes) { |page_number| Transaction.search(query, page_number) }
- end
-
def self._create_signature # :nodoc:
[
:amount, :customer_id, :merchant_account_id, :order_id, :payment_method_token, :type,
@@ -429,6 +410,13 @@ def self._create_signature # :nodoc:
]
end
+ def self._fetch_transactions(search, ids)
+ search.ids.in ids
+ response = Http.post "/transactions/advanced_search", {:search => search.to_hash}
+ attributes = response[:credit_card_transactions]
+ Util.extract_attribute_as_array(attributes, :transaction).map { |attrs| _new(attrs) }
+ end
+
def _init(attributes) # :nodoc:
set_instance_variables_from_hash(attributes)
@amount = Util.to_big_decimal(amount)
View
1  lib/braintree/transaction_search.rb
@@ -47,6 +47,7 @@ class TransactionSearch < AdvancedSearch
CreditCard::CustomerLocation::International,
CreditCard::CustomerLocation::US
]
+ multiple_value_field :ids
multiple_value_field :merchant_account_id
multiple_value_field :status, :allows => Transaction::Status::All
multiple_value_field :source, :allows => [
View
2  lib/braintree/transparent_redirect.rb
@@ -45,7 +45,7 @@ def self.parse_and_validate_query_string(query_string) # :nodoc:
if params[:http_status] == nil
raise UnexpectedError, "expected query string to have an http_status param"
elsif params[:http_status] != '200'
- Util.raise_exception_for_status_code(params[:http_status])
+ Util.raise_exception_for_status_code(params[:http_status], params[:bt_message])
end
if _hash(query_string_without_hash) == params[:hash]
View
6 lib/braintree/util.rb
@@ -41,14 +41,16 @@ def self.symbolize_keys(hash)
end
end
- def self.raise_exception_for_status_code(status_code)
+ def self.raise_exception_for_status_code(status_code, message=nil)
case status_code.to_i
when 401
raise AuthenticationError
when 403
- raise AuthorizationError
+ raise AuthorizationError, message
when 404
raise NotFoundError
+ when 426
+ raise UpgradeRequiredError, "Please upgrade your client library."
when 500
raise ServerError
when 503
View
2  lib/braintree/version.rb
@@ -1,7 +1,7 @@
module Braintree
module Version
Major = 2
- Minor = 1
+ Minor = 2
Tiny = 0
String = "#{Major}.#{Minor}.#{Tiny}"
View
2  lib/braintree/xml/parser.rb
@@ -23,7 +23,7 @@ def self._typecast_xml_value(value)
when 'Hash'
if value['type'] == 'array'
child_key, entries = value.detect { |k,v| k != 'type' } # child_key is throwaway
- if entries.nil? || (c = value[CONTENT_ROOT] && c.blank?)
+ if entries.nil? || ((c = value[CONTENT_ROOT]) && c.strip.empty?)
[]
else
case entries.class.to_s # something weird with classes not matching here. maybe singleton methods breaking is_a?
View
44 spec/integration/braintree/credit_card_spec.rb
@@ -518,7 +518,7 @@
updated_credit_card.last_4.should == Braintree::Test::CreditCardNumbers::MasterCard[-4..-1]
updated_credit_card.expiration_date.should == "06/2013"
updated_credit_card.cardholder_name.should == "New Holder"
- updated_credit_card.updated_at.between?(Time.now - 5, Time.now).should == true
+ updated_credit_card.updated_at.between?(Time.now - 60, Time.now).should == true
end
it "raises a ValidationsFailed if invalid" do
@@ -686,19 +686,55 @@
describe "self.expired" do
it "finds expired payment methods, paginated" do
collection = Braintree::CreditCard.expired
- collection._approximate_size.should > 0
+ collection.maximum_size.should > 0
collection.all? { |pm| pm.expired?.should == true }
end
+
+ it "can iterate over all items" do
+ customer = Braintree::Customer.all.first
+
+ (110 - Braintree::CreditCard.expired.maximum_size).times do
+ Braintree::CreditCard.create!(
+ :customer_id => customer.id,
+ :number => Braintree::Test::CreditCardNumbers::Visa,
+ :expiration_date => "01/2010"
+ )
+ end
+
+ collection = Braintree::CreditCard.expired
+ collection.maximum_size.should > 100
+
+ credit_card_ids = collection.map {|c| c.token }.uniq.compact
+ credit_card_ids.size.should == collection.maximum_size
+ end
end
describe "self.expiring_between" do
it "finds payment methods expiring between the given dates" do
next_year = Time.now.year + 1
collection = Braintree::CreditCard.expiring_between(Time.mktime(next_year, 1), Time.mktime(next_year, 12))
- collection._approximate_size.should > 0
+ collection.maximum_size.should > 0
collection.all? { |pm| pm.expired?.should == false }
collection.all? { |pm| pm.expiration_year.should == next_year.to_s }
end
+
+ it "can iterate over all items" do
+ customer = Braintree::Customer.all.first
+
+ (110 - Braintree::CreditCard.expiring_between(Time.mktime(2010, 1, 1), Time.mktime(2010,3, 1)).maximum_size).times do
+ Braintree::CreditCard.create!(
+ :customer_id => customer.id,
+ :number => Braintree::Test::CreditCardNumbers::Visa,
+ :expiration_date => "01/2010"
+ )
+ end
+
+ collection = Braintree::CreditCard.expiring_between(Time.mktime(2010, 1, 1), Time.mktime(2010,3, 1))
+ collection.maximum_size.should > 100
+
+ credit_card_ids = collection.map {|c| c.token }.uniq.compact
+ credit_card_ids.size.should == collection.maximum_size
+ end
end
describe "self.find" do
@@ -967,7 +1003,7 @@
credit_card.last_4.should == Braintree::Test::CreditCardNumbers::MasterCard[-4..-1]
credit_card.expiration_date.should == "06/2013"
credit_card.cardholder_name.should == "New Holder"
- credit_card.updated_at.between?(Time.now - 5, Time.now).should == true
+ credit_card.updated_at.between?(Time.now - 60, Time.now).should == true
end
it "raises a ValidationsFailed if invalid" do
View
8 spec/integration/braintree/customer_spec.rb
@@ -4,10 +4,10 @@
describe "self.all" do
it "gets more than a page of customers" do
customers = Braintree::Customer.all
- customers._approximate_size.should > 100
+ customers.maximum_size.should > 100
customer_ids = customers.map {|c| c.id }.uniq.compact
- customer_ids.size.should == customers._approximate_size
+ customer_ids.size.should == customers.maximum_size
end
end
@@ -578,7 +578,7 @@
)
updated_customer.first_name.should == "Mr. Joe"
updated_customer.last_name.should == "Super Cool"
- updated_customer.updated_at.between?(Time.now - 5, Time.now).should == true
+ updated_customer.updated_at.between?(Time.now - 60, Time.now).should == true
end
it "raises an error if unsuccessful" do
@@ -630,7 +630,7 @@
).should == customer
customer.first_name.should == "Mr. Joe"
customer.last_name.should == "Super Cool"
- customer.updated_at.between?(Time.now - 5, Time.now).should == true
+ customer.updated_at.between?(Time.now - 60, Time.now).should == true
end
it "raises an error if unsuccessful" do
View
2  spec/integration/braintree/http_spec.rb
@@ -32,7 +32,7 @@
Braintree::Configuration.logger.level = Logger::INFO
Braintree::Customer.all
utc_or_gmt = Time.now.utc.strftime("%Z")
- output.string.should include("[Braintree] [10/Oct/2009 13:55:36 #{utc_or_gmt}] GET /customers?page=1 200")
+ output.string.should include("[Braintree] [10/Oct/2009 13:55:36 #{utc_or_gmt}] POST /customers/advanced_search_ids 200")
end
ensure
Braintree::Configuration.logger = old_logger
View
15 spec/integration/braintree/subscription_spec.rb
@@ -416,7 +416,7 @@
search.plan_id.is "not_a_real_plan_id"
end
- collection._approximate_size.should == 0
+ collection.maximum_size.should == 0
end
context "is statement" do
@@ -612,6 +612,19 @@
end
end
end
+
+ it "returns multiple results" do
+ (110 - Braintree::Subscription.search.maximum_size).times do
+ Braintree::Subscription.create(:payment_method_token => @credit_card.token, :plan_id => TriallessPlan[:id])
+ end
+
+ collection = Braintree::Subscription.search
+ collection.maximum_size.should > 100
+
+ subscriptions_ids = collection.map {|t| t.id }.uniq.compact
+ subscriptions_ids.size.should == collection.maximum_size
+ end
+
end
describe "self.retry_charge" do
View
119 spec/integration/braintree/transaction_search_spec.rb
@@ -7,7 +7,7 @@
search.billing_first_name.is "thisnameisnotreal"
end
- collection._approximate_size.should == 0
+ collection.maximum_size.should == 0
end
it "returns one result for text field search" do
@@ -101,7 +101,7 @@
search.id.is transaction.id
search.send(criterion).is value
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection.first.id.should == transaction.id
collection = Braintree::Transaction.search do |search|
@@ -198,7 +198,7 @@
search.id.is transaction.id
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection.first.id.should == transaction.id
end
@@ -217,21 +217,21 @@
search.created_using.is Braintree::Transaction::CreatedUsing::FullInformation
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection = Braintree::Transaction.search do |search|
search.id.is transaction.id
search.created_using.in Braintree::Transaction::CreatedUsing::FullInformation, Braintree::Transaction::CreatedUsing::Token
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection = Braintree::Transaction.search do |search|
search.id.is transaction.id
search.created_using.is Braintree::Transaction::CreatedUsing::Token
end
- collection._approximate_size.should == 0
+ collection.maximum_size.should == 0
end
it "searches on credit_card_customer_location" do
@@ -248,21 +248,21 @@
search.credit_card_customer_location.is Braintree::CreditCard::CustomerLocation::US
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection = Braintree::Transaction.search do |search|
search.id.is transaction.id
search.credit_card_customer_location.in Braintree::CreditCard::CustomerLocation::US, Braintree::CreditCard::CustomerLocation::International
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection = Braintree::Transaction.search do |search|
search.id.is transaction.id
search.credit_card_customer_location.is Braintree::CreditCard::CustomerLocation::International
end
- collection._approximate_size.should == 0
+ collection.maximum_size.should == 0
end
it "searches on merchant_account_id" do
@@ -279,21 +279,21 @@
search.merchant_account_id.is transaction.merchant_account_id
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection = Braintree::Transaction.search do |search|
search.id.is transaction.id
search.merchant_account_id.in transaction.merchant_account_id, "bogus_merchant_account_id"
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection = Braintree::Transaction.search do |search|
search.id.is transaction.id
search.merchant_account_id.is "bogus_merchant_account_id"
end
- collection._approximate_size.should == 0
+ collection.maximum_size.should == 0
end
it "searches on credit_card_card_type" do
@@ -310,28 +310,28 @@
search.credit_card_card_type.is Braintree::CreditCard::CardType::Visa
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection = Braintree::Transaction.search do |search|
search.id.is transaction.id
search.credit_card_card_type.is transaction.credit_card_details.card_type
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection = Braintree::Transaction.search do |search|
search.id.is transaction.id
search.credit_card_card_type.in Braintree::CreditCard::CardType::Visa, Braintree::CreditCard::CardType::MasterCard
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection = Braintree::Transaction.search do |search|
search.id.is transaction.id
search.credit_card_card_type.is Braintree::CreditCard::CardType::MasterCard
end
- collection._approximate_size.should == 0
+ collection.maximum_size.should == 0
end
it "searches on status" do
@@ -348,21 +348,21 @@
search.status.is Braintree::Transaction::Status::Authorized
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection = Braintree::Transaction.search do |search|
search.id.is transaction.id
search.status.in Braintree::Transaction::Status::Authorized, Braintree::Transaction::Status::ProcessorDeclined
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection = Braintree::Transaction.search do |search|
search.id.is transaction.id
search.status.is Braintree::Transaction::Status::ProcessorDeclined
end
- collection._approximate_size.should == 0
+ collection.maximum_size.should == 0
end
it "searches on source" do
@@ -379,21 +379,21 @@
search.source.is Braintree::Transaction::Source::Api
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection = Braintree::Transaction.search do |search|
search.id.is transaction.id
search.source.in Braintree::Transaction::Source::Api, Braintree::Transaction::Source::ControlPanel
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection = Braintree::Transaction.search do |search|
search.id.is transaction.id
search.source.is Braintree::Transaction::Source::ControlPanel
end
- collection._approximate_size.should == 0
+ collection.maximum_size.should == 0
end
it "searches on type" do
@@ -425,7 +425,7 @@
search.type.is Braintree::Transaction::Type::Credit
end
- collection._approximate_size.should == 2
+ collection.maximum_size.should == 2
collection = Braintree::Transaction.search do |search|
search.credit_card_cardholder_name.is cardholder_name
@@ -433,7 +433,7 @@
search.refund.is true
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection.first.id.should == refund_transaction.id
collection = Braintree::Transaction.search do |search|
@@ -442,7 +442,7 @@
search.refund.is false
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection.first.id.should == credit_transaction.id
end
end
@@ -463,7 +463,7 @@
search.amount.between "500.00", "1500.00"
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection.first.id.should == transaction.id
collection = Braintree::Transaction.search do |search|
@@ -471,7 +471,7 @@
search.amount >= "500.00"
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection.first.id.should == transaction.id
collection = Braintree::Transaction.search do |search|
@@ -479,7 +479,7 @@
search.amount <= "1500.00"
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection.first.id.should == transaction.id
collection = Braintree::Transaction.search do |search|
@@ -487,7 +487,7 @@
search.amount.between "500.00", "900.00"
end
- collection._approximate_size.should == 0
+ collection.maximum_size.should == 0
end
it "can also take BigDecimal for amount" do
@@ -504,7 +504,7 @@
search.amount <= BigDecimal.new("1000.00")
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
end
end
@@ -528,7 +528,7 @@
)
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection.first.id.should == transaction.id
collection = Braintree::Transaction.search do |search|
@@ -536,7 +536,7 @@
search.created_at >= created_at - 1
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection.first.id.should == transaction.id
collection = Braintree::Transaction.search do |search|
@@ -544,7 +544,7 @@
search.created_at <= created_at + 1
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection.first.id.should == transaction.id
collection = Braintree::Transaction.search do |search|
@@ -555,7 +555,7 @@
)
end
- collection._approximate_size.should == 0
+ collection.maximum_size.should == 0
end
it "searches on created_at in local time" do
@@ -577,7 +577,7 @@
)
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection.first.id.should == transaction.id
collection = Braintree::Transaction.search do |search|
@@ -585,7 +585,7 @@
search.created_at >= now - 60
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection.first.id.should == transaction.id
collection = Braintree::Transaction.search do |search|
@@ -593,7 +593,7 @@
search.created_at <= now + 60
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection.first.id.should == transaction.id
collection = Braintree::Transaction.search do |search|
@@ -604,18 +604,16 @@
)
end
- collection._approximate_size.should == 0
+ collection.maximum_size.should == 0
end
end
it "returns multiple results" do
- collection = Braintree::Transaction.search do |search|
- search.credit_card_number.starts_with "411"
- end
- collection._approximate_size.should > 100
+ collection = Braintree::Transaction.search
+ collection.maximum_size.should > 100
transaction_ids = collection.map {|t| t.id }.uniq.compact
- transaction_ids.size.should == collection._approximate_size
+ transaction_ids.size.should == collection.maximum_size
end
context "text node operations" do
@@ -636,7 +634,7 @@
search.credit_card_cardholder_name.is "Tom Smith"
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection.first.id.should == @transaction.id
collection = Braintree::Transaction.search do |search|
@@ -644,7 +642,7 @@
search.credit_card_cardholder_name.is "Invalid"
end
- collection._approximate_size.should == 0
+ collection.maximum_size.should == 0
end
it "is_not" do
@@ -653,7 +651,7 @@
search.credit_card_cardholder_name.is_not "Anybody Else"
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection.first.id.should == @transaction.id
collection = Braintree::Transaction.search do |search|
@@ -661,7 +659,7 @@
search.credit_card_cardholder_name.is_not "Tom Smith"
end
- collection._approximate_size.should == 0
+ collection.maximum_size.should == 0
end
it "ends_with" do
@@ -670,7 +668,7 @@
search.credit_card_cardholder_name.ends_with "m Smith"
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection.first.id.should == @transaction.id
collection = Braintree::Transaction.search do |search|
@@ -678,7 +676,7 @@
search.credit_card_cardholder_name.ends_with "Tom S"
end
- collection._approximate_size.should == 0
+ collection.maximum_size.should == 0
end
it "starts_with" do
@@ -687,7 +685,7 @@
search.credit_card_cardholder_name.starts_with "Tom S"
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection.first.id.should == @transaction.id
collection = Braintree::Transaction.search do |search|
@@ -695,7 +693,7 @@
search.credit_card_cardholder_name.starts_with "m Smith"
end
- collection._approximate_size.should == 0
+ collection.maximum_size.should == 0
end
it "contains" do
@@ -704,7 +702,7 @@
search.credit_card_cardholder_name.contains "m Sm"
end
- collection._approximate_size.should == 1
+ collection.maximum_size.should == 1
collection.first.id.should == @transaction.id
collection = Braintree::Transaction.search do |search|
@@ -712,23 +710,8 @@
search.credit_card_cardholder_name.contains "Anybody Else"
end
- collection._approximate_size.should == 0
+ collection.maximum_size.should == 0
end
end
end
-
- context "basic" do
- it "returns transactions matching the given search terms" do
- transactions = Braintree::Transaction.search "1111"
- transactions._approximate_size.should > 0
- end
-
- it "can iterate over the entire collection" do
- transactions = Braintree::Transaction.search "411111"
- transactions._approximate_size.should > 100
-
- transaction_ids = transactions.map {|t| t.id }.uniq.compact
- transaction_ids.size.should == transactions._approximate_size
- end
- end
end
View
26 spec/integration/braintree/transaction_spec.rb
@@ -636,7 +636,7 @@
result.success?.should == true
result.transaction.amount.should == BigDecimal.new("999.99")
result.transaction.status.should == Braintree::Transaction::Status::SubmittedForSettlement
- result.transaction.updated_at.between?(Time.now - 5, Time.now).should == true
+ result.transaction.updated_at.between?(Time.now - 60, Time.now).should == true
end
it "returns an error result if settlement is too large" do
@@ -816,6 +816,30 @@
transaction.credit_card_details.expiration_date.should == "05/2009"
end
+ it "raises an error with a message if given invalid params" do
+ params = {
+ :transaction => {
+ :bad => "value",
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
+ :credit_card => {
+ :number => Braintree::Test::CreditCardNumbers::Visa,
+ :expiration_date => "05/2009"
+ }
+ }
+ }
+ tr_data_params = {
+ :transaction => {
+ :type => "sale"
+ }
+ }
+ tr_data = Braintree::TransparentRedirect.transaction_data({:redirect_url => "http://example.com"}.merge(tr_data_params))
+ query_string_response = SpecHelper.simulate_form_post_for_tr(Braintree::Transaction.create_transaction_url, tr_data, params)
+
+ expect do
+ Braintree::Transaction.create_from_transparent_redirect(query_string_response)
+ end.to raise_error(Braintree::AuthorizationError, "Invalid params: transaction[bad]")
+ end
+
it "can put any param in tr_data" do
params = {
View
70 spec/unit/braintree/resource_collection_spec.rb
@@ -1,68 +1,20 @@
require File.dirname(__FILE__) + "/../spec_helper"
describe "Braintree::ResourceCollection" do
- it "includes enumerable" do
- collection = Braintree::ResourceCollection.new(:items => ["a"])
- collection.detect { |item| item == "a" }.should == "a"
- end
-
- describe "each" do
- it "iterates over the contents" do
- expected = ["apples", "bananas", "cherries"]
- collection = Braintree::ResourceCollection.new(
- :current_page_number => 1,
- :items => expected,
- :page_size => 5,
- :total_items => expected.size
- )
- actual = []
- collection.each do |item|
- actual << item
+ describe "enumeration" do
+ it "iterates over the elements, yielding to the block in pages" do
+ values = %w(a b c d e)
+ collection = Braintree::ResourceCollection.new(:search_results => {:ids => [0,1,2,3,4], :page_size => 2}) do |ids|
+ ids.map {|id| values[id] }
end
- actual.should == expected
- end
- end
-
- describe "empty?" do
- it "returns true if there are no items" do
- collection = Braintree::ResourceCollection.new(
- :current_page_number => 1,
- :items => [],
- :page_size => 5,
- :total_items => 0
- )
- collection.should be_empty
- end
-
- it "returns false if there are items" do
- collection = Braintree::ResourceCollection.new(
- :current_page_number => 1,
- :items => ["one"],
- :page_size => 5,
- :total_items => 1
- )
- collection.should_not be_empty
- end
- end
- describe "first" do
- it "returns the first element" do
- collection = Braintree::ResourceCollection.new(
- :items => ["apples", "bananas", "cherries"]
- )
- collection.first.should == "apples"
- end
- end
-
- describe "_last_page?" do
- it "returns true if the page is the last page" do
- collection = Braintree::ResourceCollection.new(:current_page_number => 3, :page_size => 50, :total_items => 150)
- collection._last_page?.should == true
- end
+ count = 0
+ collection.each_with_index do |item, index|
+ item.should == values[index]
+ count += 1
+ end
- it "returns false if the page is not the last page" do
- collection = Braintree::ResourceCollection.new(:current_page_number => 3, :page_size => 50, :total_items => 151)
- collection._last_page?.should == false
+ count.should == 5
end
end
end
View
6 spec/unit/braintree/util_spec.rb
@@ -183,6 +183,12 @@
end.to raise_error(Braintree::AuthorizationError)
end
+ it "raises an UpgradeRequired if the client library is EOL'd" do
+ expect do
+ Braintree::Util.raise_exception_for_status_code(426)
+ end.to raise_error(Braintree::UpgradeRequiredError, "Please upgrade your client library.")
+ end
+
it "raises a ServerError if the server 500's" do
expect do
Braintree::Util.raise_exception_for_status_code(500)
Please sign in to comment.
Something went wrong with that request. Please try again.