Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

2.0.0

  • Loading branch information...
commit c96ee39e9416d25cb6e3362b726d8ae6c50f21c2 1 parent 041f256
@braintreeps braintreeps authored
Showing with 248 additions and 371 deletions.
  1. +6 −0 CHANGELOG.rdoc
  2. +6 −8 README.rdoc
  3. +3 −0  Rakefile
  4. +15 −14 bt_rdoc_template/braintree.rb
  5. +1 −1  lib/braintree.rb
  6. +1 −1  lib/braintree/configuration.rb
  7. +8 −4 lib/braintree/credit_card.rb
  8. +8 −5 lib/braintree/customer.rb
  9. +3 −4 lib/braintree/error_result.rb
  10. +19 −19 lib/braintree/{paged_collection.rb → resource_collection.rb}
  11. +5 −1 lib/braintree/subscription.rb
  12. +12 −6 lib/braintree/transaction.rb
  13. +2 −2 lib/braintree/transaction/credit_card_details.rb
  14. +4 −0 lib/braintree/validation_error_collection.rb
  15. +3 −3 lib/braintree/version.rb
  16. +7 −5 lib/braintree/xml/generator.rb
  17. +7 −30 spec/integration/braintree/credit_card_spec.rb
  18. +7 −15 spec/integration/braintree/customer_spec.rb
  19. +24 −24 spec/integration/braintree/subscription_spec.rb
  20. +2 −2 spec/integration/braintree/test/transaction_amounts_spec.rb
  21. +25 −24 spec/integration/braintree/transaction_spec.rb
  22. +0 −24 spec/support/matchers/include_on_any_page.rb
  23. +0 −178 spec/unit/braintree/paged_collection_spec.rb
  24. +68 −0 spec/unit/braintree/resource_collection_spec.rb
  25. +2 −1  spec/unit/braintree/transaction/credit_card_details_spec.rb
  26. +10 −0 spec/unit/braintree/xml_spec.rb
View
6 CHANGELOG.rdoc
@@ -1,3 +1,9 @@
+== 2.0.0
+
+* Updated success? on transaction responses to return false on declined transactions
+* Search results now include Enumerable and will automatically paginate data
+* Added credit_card[cardholder_name] to allowed transaction params and CreditCardDetails (thanks chrismcc[http://github.com/chrismcc])
+
== 1.2.1
* Added ValidationErrorCollection#shallow_errors to get all of the ValidationErrors at a given level in the error hierarchy
View
14 README.rdoc
@@ -26,13 +26,11 @@ The Braintree gem provides integration access to the Braintree Gateway.
)
if result.success?
- if result.transaction.status == Braintree::Transaction::Status::Authorized
- puts "success!: #{result.transaction.id}"
- else
- puts "Error processing transaction:"
- puts " code: #{result.transaction.processor_response_code}"
- puts " text: #{result.transaction.processor_response_text}"
- end
+ puts "success!: #{result.transaction.id}"
+ elsif result.transaction
+ puts "Error processing transaction:"
+ puts " code: #{result.transaction.processor_response_code}"
+ puts " text: #{result.transaction.processor_response_text}"
else
p result.errors
end
@@ -45,7 +43,7 @@ the created or updated resource, or it will raise a ValidationsFailed exception.
Example of using non-bang method:
- result = Braintree::Customer.create!(:first_name => "Josh")
+ result = Braintree::Customer.create(:first_name => "Josh")
if result.success?
puts "Created customer #{result.customer.id}
else
View
3  Rakefile
@@ -50,6 +50,7 @@ Rake::RDocTask.new(:bt_rdoc) do |t|
t.rdoc_dir = "bt_rdoc"
t.template = "bt_rdoc_template/braintree"
end
+Rake::Task["bt_rdoc"].prerequisites.unshift "clean"
task :bt_rdoc_postprocessing do
FileUtils.cp "bt_rdoc_template/braintree.gif", "bt_rdoc"
@@ -76,6 +77,8 @@ gem_spec = Gem::Specification.new do |s|
s.rubyforge_project = "braintree"
s.has_rdoc = false
s.files = FileList["README.rdoc", "LICENSE", "{lib,spec}/**/*.rb", "lib/**/*.crt"]
+ s.add_dependency "builder"
+ s.add_dependency "libxml-ruby"
end
task :gem do
View
29 bt_rdoc_template/braintree.rb
@@ -53,20 +53,20 @@ module Page
<div class="box">
<h3>Files</h3>
<ul>
- <li><a href="BASE_URL/files/README_rdoc.html">README</a></li>
<li><a href="BASE_URL/files/CHANGELOG_rdoc.html">CHANGELOG</a></li>
<li><a href="BASE_URL/files/LICENSE.html">LICENSE</a></li>
+ <li><a href="BASE_URL/files/README_rdoc.html">README</a></li>
</ul>
</div>
<div class="box">
<h3>Resources</h3>
<ul>
- <li><a href="BASE_URL/classes/Braintree/Transaction.html">Transaction</a></li>
- <li><a href="BASE_URL/classes/Braintree/Customer.html">Customer</a></li>
- <li><a href="BASE_URL/classes/Braintree/CreditCard.html">CreditCard</a></li>
<li><a href="BASE_URL/classes/Braintree/Address.html">Address</a></li>
+ <li><a href="BASE_URL/classes/Braintree/CreditCard.html">CreditCard</a></li>
+ <li><a href="BASE_URL/classes/Braintree/Customer.html">Customer</a></li>
<li><a href="BASE_URL/classes/Braintree/Subscription.html">Subscription</a></li>
+ <li><a href="BASE_URL/classes/Braintree/Transaction.html">Transaction</a></li>
</ul>
</div>
@@ -74,15 +74,16 @@ module Page
<h3>Classes</h3>
<ul>
<li><a href="BASE_URL/classes/Braintree/Configuration.html">Configuration</a></li>
- <li><a href="BASE_URL/classes/Braintree/SuccessfulResult.html">SuccessfulResult</a></li>
<li><a href="BASE_URL/classes/Braintree/ErrorResult.html">ErrorResult</a></li>
<li><a href="BASE_URL/classes/Braintree/Errors.html">Errors</a></li>
- <li><a href="BASE_URL/classes/Braintree/ValidationErrorCollection.html">ValidationErrorCollection</a></li>
- <li><a href="BASE_URL/classes/Braintree/PagedCollection.html">PagedCollection</a></li>
- <li><a href="BASE_URL/classes/Braintree/TransparentRedirect.html">TransparentRedirect</a></li>
- <li><a href="BASE_URL/classes/Braintree/Version.html">Version</a></li>
+ <li><a href="BASE_URL/classes/Braintree/ResourceCollection.html">ResourceCollection</a></li>
+ <li><a href="BASE_URL/classes/Braintree/SuccessfulResult.html">SuccessfulResult</a></li>
<li><a href="BASE_URL/classes/Braintree/Test/CreditCardNumbers.html">Test::CreditCardNumbers</a></li>
<li><a href="BASE_URL/classes/Braintree/Test/TransactionAmounts.html">Test::TransactionAmounts</a></li>
+ <li><a href="BASE_URL/classes/Braintree/Transaction/Status.html">Transaction::Status</a></li>
+ <li><a href="BASE_URL/classes/Braintree/TransparentRedirect.html">TransparentRedirect</a></li>
+ <li><a href="BASE_URL/classes/Braintree/ValidationErrorCollection.html">ValidationErrorCollection</a></li>
+ <li><a href="BASE_URL/classes/Braintree/Version.html">Version</a></li>
</ul>
</div>
@@ -90,25 +91,25 @@ module Page
<h3>Error Codes</h3>
<ul>
<li><a href="BASE_URL/classes/Braintree/ErrorCodes.html">ErrorCodes</a></li>
- <li><a href="BASE_URL/classes/Braintree/ErrorCodes/Transaction.html">ErrorCodes::Transaction</a></li>
- <li><a href="BASE_URL/classes/Braintree/ErrorCodes/Customer.html">ErrorCodes::Customer</a></li>
- <li><a href="BASE_URL/classes/Braintree/ErrorCodes/CreditCard.html">ErrorCodes::CreditCard</a></li>
<li><a href="BASE_URL/classes/Braintree/ErrorCodes/Address.html">ErrorCodes::Address</a></li>
+ <li><a href="BASE_URL/classes/Braintree/ErrorCodes/CreditCard.html">ErrorCodes::CreditCard</a></li>
+ <li><a href="BASE_URL/classes/Braintree/ErrorCodes/Customer.html">ErrorCodes::Customer</a></li>
+ <li><a href="BASE_URL/classes/Braintree/ErrorCodes/Transaction.html">ErrorCodes::Transaction</a></li>
</ul>
</div>
<div class="box">
<h3>Exceptions</h3>
<ul>
- <li><a href="BASE_URL/classes/Braintree/BraintreeError.html">BraintreeError</a></li>
<li><a href="BASE_URL/classes/Braintree/AuthenticationError.html">AuthenticationError</a></li>
<li><a href="BASE_URL/classes/Braintree/AuthorizationError.html">AuthorizationError</a></li>
+ <li><a href="BASE_URL/classes/Braintree/BraintreeError.html">BraintreeError</a></li>
<li><a href="BASE_URL/classes/Braintree/ConfigurationError.html">ConfigurationError</a></li>
<li><a href="BASE_URL/classes/Braintree/DownForMaintenanceError.html">DownForMaintenanceError</a></li>
<li><a href="BASE_URL/classes/Braintree/ForgedQueryString.html">ForgedQueryString</a></li>
<li><a href="BASE_URL/classes/Braintree/NotFoundError.html">NotFoundError</a></li>
- <li><a href="BASE_URL/classes/Braintree/ServerError.html">ServerError</a></li>
<li><a href="BASE_URL/classes/Braintree/SSLCertificateError.html">SSLCertificateError</a></li>
+ <li><a href="BASE_URL/classes/Braintree/ServerError.html">ServerError</a></li>
<li><a href="BASE_URL/classes/Braintree/UnexpectedError.html">UnexpectedError</a></li>
<li><a href="BASE_URL/classes/Braintree/ValidationsFailed.html">ValidationsFailed</a></li>
</ul>
View
2  lib/braintree.rb
@@ -33,7 +33,7 @@ module Braintree
require "braintree/error_result.rb"
require "braintree/errors.rb"
require "braintree/http.rb"
-require "braintree/paged_collection.rb"
+require "braintree/resource_collection.rb"
require "braintree/ssl_expiration_check.rb"
require "braintree/subscription"
require "braintree/subscription_search"
View
2  lib/braintree/configuration.rb
@@ -8,7 +8,7 @@ module Braintree
# By default, the logger will log to +STDOUT+. The log level is set to info.
# The logger can be set to any Logger object.
module Configuration
- API_VERSION = "1" # :nodoc:
+ API_VERSION = "2" # :nodoc:
class << self
attr_accessor :logger
View
12 lib/braintree/credit_card.rb
@@ -1,4 +1,8 @@
module Braintree
+ # == More Information
+ #
+ # For more detailed documentation on CreditCards, see http://www.braintreepaymentsolutions.com/gateway/credit-card-api
+ # For more detailed documentation on CreditCard verification, see http://www.braintreepaymentsolutions.com/gateway/credit-card-verification-api
class CreditCard
include BaseModule # :nodoc:
@@ -37,7 +41,7 @@ def self.credit!(token, transaction_attributes)
return_object_or_raise(:transaction) { credit(token, transaction_attributes) }
end
- # Returns a PagedCollection of expired credit cards.
+ # 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}")
@@ -45,10 +49,10 @@ def self.expired(options = {})
attributes[:items] = Util.extract_attribute_as_array(attributes, :credit_card).map do |payment_method_attributes|
new payment_method_attributes
end
- PagedCollection.new(attributes) { |page_number| CreditCard.expired(:page => page_number) }
+ ResourceCollection.new(attributes) { |page_number| CreditCard.expired(:page => page_number) }
end
- # Returns a PagedCollection of credit cards expiring between +start_date+ and +end_date+ inclusive.
+ # 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
@@ -57,7 +61,7 @@ def self.expiring_between(start_date, end_date, options = {})
attributes[:items] = Util.extract_attribute_as_array(attributes, :credit_card).map do |payment_method_attributes|
new payment_method_attributes
end
- PagedCollection.new(attributes) { |page_number| CreditCard.expiring_between(start_date, end_date, :page => page_number) }
+ ResourceCollection.new(attributes) { |page_number| CreditCard.expiring_between(start_date, end_date, :page => page_number) }
end
# Finds the credit card with the given +token+. Raises a NotFoundError if it cannot be found.
View
13 lib/braintree/customer.rb
@@ -1,11 +1,14 @@
module Braintree
+ # == More Information
+ #
+ # For more detailed documentation on Customers, see http://www.braintreepaymentsolutions.com/gateway/customer-api
class Customer
include BaseModule
attr_reader :addresses, :company, :created_at, :credit_cards, :email, :fax, :first_name, :id, :last_name,
:phone, :updated_at, :website, :custom_fields
- # Returns a PagedCollection of all customers stored in the vault. Due to race conditions, this method
+ # 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.
#
# page = Braintree::Customer.all
@@ -23,7 +26,7 @@ def self.all(options = {})
attributes[:items] = Util.extract_attribute_as_array(attributes, :customer).map do |customer_attributes|
new customer_attributes
end
- PagedCollection.new(attributes) { |page_number| Customer.all(:page => page_number) }
+ ResourceCollection.new(attributes) { |page_number| Customer.all(:page => page_number) }
end
# Creates a customer using the given +attributes+. If <tt>:id</tt> is not passed,
@@ -95,7 +98,7 @@ def self.sale!(customer_id, transaction_attributes)
return_object_or_raise(:transaction){ sale(customer_id, transaction_attributes) }
end
- # Returns a PagedCollection of transactions for the customer with the given +customer_id+.
+ # 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}"
@@ -103,7 +106,7 @@ def self.transactions(customer_id, options = {})
attributes[:items] = Util.extract_attribute_as_array(attributes, :transaction).map do |transaction_attributes|
Transaction._new transaction_attributes
end
- PagedCollection.new(attributes) { |page_number| Customer.transactions(customer_id, :page => page_number) }
+ ResourceCollection.new(attributes) { |page_number| Customer.transactions(customer_id, :page => page_number) }
end
def self.update(customer_id, attributes)
@@ -160,7 +163,7 @@ def sale!(transaction_attributes)
return_object_or_raise(:transaction) { sale(transaction_attributes) }
end
- # Returns a PagedCollection of transactions for the customer.
+ # Returns a ResourceCollection of transactions for the customer.
def transactions(options = {})
Customer.transactions(id, options)
end
View
7 lib/braintree/error_result.rb
@@ -17,13 +17,12 @@ module Braintree
# end
class ErrorResult
- attr_reader :credit_card_verification, :errors, :params
+ attr_reader :credit_card_verification, :transaction, :errors, :params
def initialize(data) # :nodoc:
@params = data[:params]
- if data[:verification]
- @credit_card_verification = CreditCardVerification._new(data[:verification])
- end
+ @credit_card_verification = CreditCardVerification._new(data[:verification]) if data[:verification]
+ @transaction = Transaction._new(data[:transaction]) if data[:transaction]
@errors = Errors.new(data[:errors])
end
View
38 lib/braintree/paged_collection.rb → lib/braintree/resource_collection.rb
@@ -1,23 +1,22 @@
module Braintree
- class PagedCollection
+ class ResourceCollection
include BaseModule
include Enumerable
- attr_reader :current_page_number, :items, :next_page_number, :page_size, :previous_page_number, :total_items
-
def initialize(attributes, &block) # :nodoc:
set_instance_variables_from_hash attributes
@paging_block = block
end
- # Returns the item from the current page at the given +index+.
- def [](index)
- @items[index]
- end
-
# Yields each item on the current page.
def each(&block)
@items.each(&block)
+
+ _next_page.each(&block) unless _last_page?
+ end
+
+ def empty?
+ @items.empty?
end
# Returns the first item from the current page.
@@ -26,27 +25,28 @@ def first
end
# Returns true if the page is the last page. False otherwise.
- def last_page?
- current_page_number == total_pages
+ def _last_page?
+ @current_page_number == _total_pages
end
# Retrieves the next page of records.
- def next_page
- if last_page?
+ def _next_page
+ if _last_page?
return nil
end
- @paging_block.call(next_page_number)
+ @paging_block.call(@current_page_number + 1)
end
- # The next page number. Returns +nil+ if on the last page.
- def next_page_number
- last_page? ? nil : current_page_number + 1
+ # 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
+ def _total_pages
+ total = @total_items / @page_size
+ if @total_items % @page_size != 0
total += 1
end
total
View
6 lib/braintree/subscription.rb
@@ -20,6 +20,10 @@ module Braintree
# :trial_duration => "2",
# :trial_duration_unit => Subscription::TrialDurationUnit::Day
# )
+ #
+ # == More Information
+ #
+ # For more detailed documentation on Subscriptions, see http://www.braintreepaymentsolutions.com/gateway/subscription-api
class Subscription
include BaseModule
@@ -90,7 +94,7 @@ def self.search(page=1, &block)
response = Http.post "/subscriptions/advanced_search?page=#{page}", {:search => search.to_hash}
attributes = response[:subscriptions]
attributes[:items] = Util.extract_attribute_as_array(attributes, :subscription).map { |attrs| new(attrs) }
- PagedCollection.new(attributes) { |page_number| Subscription.search(page_number, &block) }
+ ResourceCollection.new(attributes) { |page_number| Subscription.search(page_number, &block) }
end
def self.update(subscription_id, attributes)
View
18 lib/braintree/transaction.rb
@@ -116,6 +116,10 @@ module Braintree
# :submit_for_settlement => true
# }
# )
+ #
+ # == More Information
+ #
+ # For more detailed documentation on Transactions, see http://www.braintreepaymentsolutions.com/gateway/transaction-api
class Transaction
include BaseModule
@@ -138,18 +142,20 @@ module Type # :nodoc:
end
attr_reader :avs_error_response_code, :avs_postal_code_response_code, :avs_street_address_response_code
- attr_reader :amount, :created_at, :credit_card_details, :customer_details, :id, :status
+ attr_reader :amount, :created_at, :credit_card_details, :customer_details, :id
attr_reader :custom_fields
attr_reader :cvv_response_code
attr_reader :order_id
attr_reader :billing_details, :shipping_details
- attr_reader :status_history
# The authorization code from the processor.
attr_reader :processor_authorization_code
# The response code from the processor.
attr_reader :processor_response_code
# The response text from the processor.
attr_reader :processor_response_text
+ # See Transaction::Status
+ attr_reader :status
+ attr_reader :status_history
# Will either be "sale" or "credit"
attr_reader :type
attr_reader :updated_at
@@ -200,7 +206,7 @@ def self.sale!(attributes)
return_object_or_raise(:transaction) { sale(attributes) }
end
- # Returns a PagedCollection of transactions matching the search query.
+ # 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, options = {})
@@ -379,7 +385,7 @@ def self._advanced_search(query, options) # :nodoc:
response = Http.post "/transactions/advanced_search?page=#{Util.url_encode(page)}", :search => query
attributes = response[:credit_card_transactions]
attributes[:items] = Util.extract_attribute_as_array(attributes, :transaction).map { |attrs| _new(attrs) }
- PagedCollection.new(attributes) { |page_number| Transaction.search(query, :page => page_number) }
+ ResourceCollection.new(attributes) { |page_number| Transaction.search(query, :page => page_number) }
end
def self._attributes # :nodoc:
@@ -391,13 +397,13 @@ def self._basic_search(query, options) # :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) }
- PagedCollection.new(attributes) { |page_number| Transaction.search(query, :page => page_number) }
+ ResourceCollection.new(attributes) { |page_number| Transaction.search(query, :page => page_number) }
end
def self._create_signature # :nodoc:
[
:amount, :customer_id, :order_id, :payment_method_token, :type,
- {:credit_card => [:token, :cvv, :expiration_date, :expiration_month, :expiration_year, :number]},
+ {:credit_card => [:token, :cardholder_name, :cvv, :expiration_date, :expiration_month, :expiration_year, :number]},
{:customer => [:id, :company, :email, :fax, :first_name, :last_name, :phone, :website]},
{:billing => [:first_name, :last_name, :company, :country_name, :extended_address, :locality, :postal_code, :region, :street_address]},
{:shipping => [:first_name, :last_name, :company, :country_name, :extended_address, :locality, :postal_code, :region, :street_address]},
View
4 lib/braintree/transaction/credit_card_details.rb
@@ -3,7 +3,7 @@ class Transaction
class CreditCardDetails # :nodoc:
include BaseModule
- attr_reader :bin, :card_type, :customer_location, :expiration_month,
+ attr_reader :bin, :card_type, :cardholder_name, :customer_location, :expiration_month,
:expiration_year, :last_4, :token
def initialize(attributes)
@@ -11,7 +11,7 @@ def initialize(attributes)
end
def inspect
- attr_order = [:token, :bin, :last_4, :card_type, :expiration_date, :customer_location]
+ attr_order = [:token, :bin, :last_4, :card_type, :expiration_date, :cardholder_name, :customer_location]
formatted_attrs = attr_order.map do |attr|
"#{attr}: #{send(attr).inspect}"
end
View
4 lib/braintree/validation_error_collection.rb
@@ -18,6 +18,10 @@ module Braintree
# #=> [#<Braintree::ValidationError (81715) Credit card number is invalid.>]
# result.errors.for(:customer).for(:credit_card).for(:billing_address).on(:country_name)
# #=> [#<Braintree::ValidationError (91803) Country name is not an accepted country.>]
+ #
+ # == More Information
+ #
+ # For more detailed documentation on ValidationErrors, see http://www.braintreepaymentsolutions.com/gateway/validation-errors
class ValidationErrorCollection
include Enumerable
View
6 lib/braintree/version.rb
@@ -1,8 +1,8 @@
module Braintree
module Version
- Major = 1
- Minor = 2
- Tiny = 1
+ Major = 2
+ Minor = 0
+ Tiny = 0
String = "#{Major}.#{Minor}.#{Tiny}"
end
View
12 lib/braintree/xml/generator.rb
@@ -21,7 +21,7 @@ def self.hash_to_xml(hash)
if contents.is_a?(String)
builder = Builder::XmlMarkup.new
- builder.__send__(root) { |b| b.text! contents }
+ builder.__send__(_xml_escape(root)) { |b| b.text! contents }
else
_convert_to_xml contents, :root => root
end
@@ -32,7 +32,7 @@ def self._convert_to_xml(hash_to_convert, options = {})
options[:indent] ||= 2
options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent])
options[:builder].instruct! unless options.delete(:skip_instruct)
- root = options[:root].to_s.tr("_", "-")
+ root = _xml_escape(options[:root])
options[:builder].__send__(:method_missing, root) do
hash_to_convert.each do |key, value|
@@ -44,14 +44,12 @@ def self._convert_to_xml(hash_to_convert, options = {})
else
type_name = XML_TYPE_NAMES[value.class.name]
- key = key.to_s.tr("_", "-")
-
attributes = ((value.nil? || type_name.nil?) ? {} : { :type => type_name })
if value.nil?
attributes[:nil] = true
end
- options[:builder].tag!(key,
+ options[:builder].tag!(_xml_escape(key),
XML_FORMATTING[type_name] ? XML_FORMATTING[type_name].call(value) : value,
attributes
)
@@ -80,6 +78,10 @@ def self._array_to_xml(array, options = {})
end
end
end
+
+ def self._xml_escape(key)
+ key.to_s.tr("_", "-").to_xs
+ end
end
end
end
View
37 spec/integration/braintree/credit_card_spec.rb
@@ -638,42 +638,19 @@
describe "self.expired" do
it "finds expired payment methods, paginated" do
- first_page = Braintree::CreditCard.expired
- first_page.current_page_number.should == 1
- first_page.total_items.should > 0
- first_page.all? { |pm| pm.expired?.should == true }
- end
-
- it "can get the next_page" do
- first_page = Braintree::CreditCard.expired
- first_page.current_page_number.should == 1
- first_page.all? { |pm| pm.expired?.should == true }
- second_page = first_page.next_page
- # TODO: we don't have enough expired payment methods to go onto a second page
- # second_page.current_page_number.should == 2
- # second_page.all? { |pm| pm.expired?.should == true }
+ collection = Braintree::CreditCard.expired
+ collection._approximate_size.should > 0
+ collection.all? { |pm| pm.expired?.should == true }
end
end
describe "self.expiring_between" do
it "finds payment methods expiring between the given dates" do
next_year = Time.now.year + 1
- first_page = Braintree::CreditCard.expiring_between(Time.mktime(next_year, 1), Time.mktime(next_year, 12))
- first_page.current_page_number.should == 1
- first_page.total_items.should > 0
- first_page.all? { |pm| pm.expired?.should == false }
- first_page.all? { |pm| pm.expiration_year.should == next_year.to_s }
- end
-
- it "can get the next_page" do
- next_year = Time.now.year + 1
- first_page = Braintree::CreditCard.expiring_between(Time.mktime(next_year, 1), Time.mktime(next_year, 12))
- first_page.current_page_number.should == 1
- second_page = first_page.next_page
- # TODO: we don't have enough expired payment methods to go onto a second page
- # second_page.current_page_number.should == 2
- # second_page.all? { |pm| pm.expired?.should == false }
- # second_page.all? { |pm| pm.expiration_year.should == next_year.to_s }
+ collection = Braintree::CreditCard.expiring_between(Time.mktime(next_year, 1), Time.mktime(next_year, 12))
+ collection._approximate_size.should > 0
+ collection.all? { |pm| pm.expired?.should == false }
+ collection.all? { |pm| pm.expiration_year.should == next_year.to_s }
end
end
View
22 spec/integration/braintree/customer_spec.rb
@@ -2,16 +2,12 @@
describe Braintree::Customer do
describe "self.all" do
- it "returns page 1 if page isn't specified" do
- first_page = Braintree::Customer.all
- first_page.current_page_number.should == 1
- end
+ it "gets more than a page of customers" do
+ customers = Braintree::Customer.all
+ customers._approximate_size.should > 100
- it "can get the next_page" do
- first_page = Braintree::Customer.all
- first_page.current_page_number.should == 1
- second_page = first_page.next_page
- second_page.current_page_number.should == 2
+ customer_ids = customers.map {|c| c.id }.uniq.compact
+ customer_ids.size.should == customers._approximate_size
end
end
@@ -298,9 +294,7 @@
)
transaction = customer.sale!(:amount => "100.00")
collection = Braintree::Customer.transactions(customer.id)
- collection.current_page_number.should == 1
- collection.total_items.should == 1
- collection[0].should == transaction
+ collection.first.should == transaction
end
end
@@ -356,9 +350,7 @@
)
transaction = customer.sale!(:amount => "100.00")
collection = customer.transactions
- collection.current_page_number.should == 1
- collection.total_items.should == 1
- collection[0].should == transaction
+ collection.first.should == transaction
end
end
View
48 spec/integration/braintree/subscription_spec.rb
@@ -419,11 +419,11 @@
search.plan_id.is "not_a_real_plan_id"
end
- collection.items.size.should == 0
+ collection._approximate_size.should == 0
end
context "is statement" do
- it "returns paged collection with matching results" do
+ it "returns resource collection with matching results" do
trialless_subscription = Braintree::Subscription.create(
:payment_method_token => @credit_card.token,
:plan_id => TriallessPlan[:id]
@@ -438,13 +438,13 @@
search.plan_id.is TriallessPlan[:id]
end
- collection.should include_on_any_page(trialless_subscription)
- collection.should_not include_on_any_page(trial_subscription)
+ collection.should include(trialless_subscription)
+ collection.should_not include(trial_subscription)
end
end
context "is_not statement" do
- it "returns paged collection without matching results" do
+ it "returns resource collection without matching results" do
trialless_subscription = Braintree::Subscription.create(
:payment_method_token => @credit_card.token,
:plan_id => TriallessPlan[:id]
@@ -459,13 +459,13 @@
search.plan_id.is_not TriallessPlan[:id]
end
- collection.should_not include_on_any_page(trialless_subscription)
- collection.should include_on_any_page(trial_subscription)
+ collection.should_not include(trialless_subscription)
+ collection.should include(trial_subscription)
end
end
context "ends_with statement" do
- it "returns paged collection with matching results" do
+ it "returns resource collection with matching results" do
trialless_subscription = Braintree::Subscription.create(
:payment_method_token => @credit_card.token,
:plan_id => TriallessPlan[:id]
@@ -480,13 +480,13 @@
search.plan_id.ends_with "trial_plan"
end
- collection.should include_on_any_page(trial_subscription)
- collection.should_not include_on_any_page(trialless_subscription)
+ collection.should include(trial_subscription)
+ collection.should_not include(trialless_subscription)
end
end
context "starts_with statement" do
- it "returns paged collection with matching results" do
+ it "returns resource collection with matching results" do
trialless_subscription = Braintree::Subscription.create(
:payment_method_token => @credit_card.token,
:plan_id => TriallessPlan[:id]
@@ -501,13 +501,13 @@
search.plan_id.starts_with "integration_trial_p"
end
- collection.should include_on_any_page(trial_subscription)
- collection.should_not include_on_any_page(trialless_subscription)
+ collection.should include(trial_subscription)
+ collection.should_not include(trialless_subscription)
end
end
context "contains statement" do
- it "returns paged collection with matching results" do
+ it "returns resource collection with matching results" do
trialless_subscription = Braintree::Subscription.create(
:payment_method_token => @credit_card.token,
:plan_id => TriallessPlan[:id]
@@ -522,8 +522,8 @@
search.plan_id.contains "trial_p"
end
- collection.should include_on_any_page(trial_subscription)
- collection.should_not include_on_any_page(trialless_subscription)
+ collection.should include(trial_subscription)
+ collection.should_not include(trialless_subscription)
end
end
end
@@ -547,8 +547,8 @@
search.plan_id.is TriallessPlan[:id]
end
- collection.should include_on_any_page(subscription1)
- collection.should include_on_any_page(subscription2)
+ collection.should include(subscription1)
+ collection.should include(subscription2)
end
it "returns only matching results" do
@@ -568,8 +568,8 @@
search.status.in Braintree::Subscription::Status::Active
end
- collection.should include_on_any_page(subscription1)
- collection.should_not include_on_any_page(subscription2)
+ collection.should include(subscription1)
+ collection.should_not include(subscription2)
end
it "returns only matching results given an argument list" do
@@ -589,8 +589,8 @@
search.status.in Braintree::Subscription::Status::Active, Braintree::Subscription::Status::Canceled
end
- collection.should include_on_any_page(subscription1)
- collection.should include_on_any_page(subscription2)
+ collection.should include(subscription1)
+ collection.should include(subscription2)
end
it "returns only matching results given an array" do
@@ -610,8 +610,8 @@
search.status.in [Braintree::Subscription::Status::Active, Braintree::Subscription::Status::Canceled]
end
- collection.should include_on_any_page(subscription1)
- collection.should include_on_any_page(subscription2)
+ collection.should include(subscription1)
+ collection.should include(subscription2)
end
end
end
View
4 spec/integration/braintree/test/transaction_amounts_spec.rb
@@ -16,14 +16,14 @@
describe "Decline" do
it "creates a transaction with status processor_declined" do
- transaction = Braintree::Transaction.sale!(
+ result = Braintree::Transaction.sale(
:amount => Braintree::Test::TransactionAmounts::Decline,
:credit_card => {
:number => Braintree::Test::CreditCardNumbers::Visa,
:expiration_date => "12/2012"
}
)
- transaction.status.should == Braintree::Transaction::Status::ProcessorDeclined
+ result.transaction.status.should == Braintree::Transaction::Status::ProcessorDeclined
end
end
end
View
49 spec/integration/braintree/transaction_spec.rb
@@ -31,7 +31,7 @@
:expiration_date => "05/2009"
}
)
- result.success?.should == true
+ result.success?.should == false
result.transaction.id.should =~ /^\w{6}$/
result.transaction.type.should == "sale"
result.transaction.status.should == Braintree::Transaction::Status::ProcessorDeclined
@@ -42,7 +42,7 @@
it "accepts credit card expiration month and expiration year" do
result = Braintree::Transaction.create(
:type => "sale",
- :amount => Braintree::Test::TransactionAmounts::Decline,
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
:credit_card => {
:number => Braintree::Test::CreditCardNumbers::Visa,
:expiration_month => "05",
@@ -256,6 +256,7 @@
:amount => "100.00",
:order_id => "123",
:credit_card => {
+ :cardholder_name => "The Cardholder",
:number => "5105105105105100",
:expiration_date => "05/2011",
:cvv => "123"
@@ -303,6 +304,7 @@
transaction.created_at.between?(Time.now - 5, Time.now).should == true
transaction.updated_at.between?(Time.now - 5, Time.now).should == true
transaction.credit_card_details.bin.should == "510510"
+ transaction.credit_card_details.cardholder_name.should == "The Cardholder"
transaction.credit_card_details.last_4.should == "5100"
transaction.credit_card_details.masked_number.should == "510510******5100"
transaction.credit_card_details.card_type.should == "MasterCard"
@@ -583,13 +585,13 @@
end
it "returns an error result if status is not authorized" do
- transaction = Braintree::Transaction.sale!(
+ transaction = Braintree::Transaction.sale(
:amount => Braintree::Test::TransactionAmounts::Decline,
:credit_card => {
:number => Braintree::Test::CreditCardNumbers::Visa,
:expiration_date => "06/2009"
}
- )
+ ).transaction
result = Braintree::Transaction.submit_for_settlement(transaction.id)
result.success?.should == false
result.errors.for(:transaction).on(:base)[0].code.should == Braintree::ErrorCodes::Transaction::CannotSubmitForSettlement
@@ -729,6 +731,7 @@
:order_id => "123",
:type => "sale",
:credit_card => {
+ :cardholder_name => "The Cardholder",
:number => "5105105105105100",
:expiration_date => "05/2011",
:cvv => "123"
@@ -781,6 +784,7 @@
transaction.updated_at.between?(Time.now - 60, Time.now).should == true
transaction.credit_card_details.bin.should == "510510"
transaction.credit_card_details.last_4.should == "5100"
+ transaction.credit_card_details.cardholder_name.should == "The Cardholder"
transaction.credit_card_details.masked_number.should == "510510******5100"
transaction.credit_card_details.card_type.should == "MasterCard"
transaction.avs_error_response_code.should == nil
@@ -878,13 +882,13 @@
end
it "returns an error result if unsuccessful" do
- transaction = Braintree::Transaction.sale!(
+ transaction = Braintree::Transaction.sale(
:amount => Braintree::Test::TransactionAmounts::Decline,
:credit_card => {
:number => Braintree::Test::CreditCardNumbers::Visa,
:expiration_date => "05/2009"
}
- )
+ ).transaction
result = Braintree::Transaction.void(transaction.id)
result.success?.should == false
result.errors.for(:transaction).on(:base)[0].code.should == Braintree::ErrorCodes::Transaction::CannotBeVoided
@@ -906,13 +910,13 @@
end
it "raises a ValidationsFailed if unsuccessful" do
- transaction = Braintree::Transaction.sale!(
+ transaction = Braintree::Transaction.sale(
:amount => Braintree::Test::TransactionAmounts::Decline,
:credit_card => {
:number => Braintree::Test::CreditCardNumbers::Visa,
:expiration_date => "05/2009"
}
- )
+ ).transaction
expect do
Braintree::Transaction.void!(transaction.id)
end.to raise_error(Braintree::ValidationsFailed)
@@ -992,7 +996,7 @@
result.success?.should == true
transaction.amount.should == BigDecimal.new("999.99")
transaction.status.should == Braintree::Transaction::Status::SubmittedForSettlement
- transaction.updated_at.between?(Time.now - 5, Time.now).should == true
+ transaction.updated_at.between?(Time.now - 60, Time.now).should == true
end
it "returns an error result if unsuccessful" do
@@ -1115,25 +1119,22 @@
}
)
search_results = Braintree::Transaction.search(:transaction_id => {:is => transaction.id})
- search_results.total_items.should == 1
- search_results[0].should == transaction
+ search_results.first.should == transaction
end
end
describe "basic" do
- it "returns paged transactions matching the given search terms" do
+ it "returns transactions matching the given search terms" do
transactions = Braintree::Transaction.search "1111"
- transactions.total_items.should > 0
+ transactions._approximate_size.should > 0
end
- it "is paged" do
- transactions = Braintree::Transaction.search "1111", :page => 2
- transactions.current_page_number.should == 2
- end
+ it "can iterate over the entire collection" do
+ transactions = Braintree::Transaction.search "411111"
+ transactions._approximate_size.should > 100
- it "can traverse pages" do
- transactions = Braintree::Transaction.search "1111", :page => 1
- transactions.next_page.current_page_number.should == 2
+ transaction_ids = transactions.map {|t| t.id }.uniq.compact
+ transaction_ids.size.should == transactions._approximate_size
end
end
end
@@ -1224,13 +1225,13 @@
end
it "returns an error result if unsuccessful" do
- transaction = Braintree::Transaction.sale!(
+ transaction = Braintree::Transaction.sale(
:amount => Braintree::Test::TransactionAmounts::Decline,
:credit_card => {
:number => Braintree::Test::CreditCardNumbers::Visa,
:expiration_date => "05/2009"
}
- )
+ ).transaction
transaction.status.should == Braintree::Transaction::Status::ProcessorDeclined
result = transaction.void
result.success?.should == false
@@ -1252,13 +1253,13 @@
end
it "raises a ValidationsFailed if unsuccessful" do
- transaction = Braintree::Transaction.sale!(
+ transaction = Braintree::Transaction.sale(
:amount => Braintree::Test::TransactionAmounts::Decline,
:credit_card => {
:number => Braintree::Test::CreditCardNumbers::Visa,
:expiration_date => "05/2009"
}
- )
+ ).transaction
transaction.status.should == Braintree::Transaction::Status::ProcessorDeclined
expect do
transaction.void!
View
24 spec/support/matchers/include_on_any_page.rb
@@ -1,24 +0,0 @@
-Spec::Matchers.define :include_on_any_page do |expected|
- match do |collection|
- on_any_page?(collection, expected)
- end
-
- def on_any_page?(collection, expected)
- return true if collection.any? { |item| item.id == expected.id }
- return false if collection.last_page?
-
- on_any_page?(collection.next_page, expected)
- end
-
- failure_message_for_should do |collection|
- "expected that the paged collection would include an item with id #{expected.id}"
- end
-
- failure_message_for_should_not do |collection|
- "expected that the paged collection would not include an item with id #{expected.id}"
- end
-
- description do
- "include the given subsription in the paged collection"
- end
-end
View
178 spec/unit/braintree/paged_collection_spec.rb
@@ -1,178 +0,0 @@
-require File.dirname(__FILE__) + "/../spec_helper"
-
-describe "Braintree::PagedCollection" do
- it "includes enumerable" do
- collection = Braintree::PagedCollection.new(:items => ["a"])
- collection.detect { |item| item == "a" }.should == "a"
- end
-
- describe "[]" do
- it "returns the element at the given index" do
- collection = Braintree::PagedCollection.new(:items => ["one", "two", "three"])
- collection[0].should == "one"
- collection[2].should == "three"
- collection[3].should == nil
- end
- end
-
- describe "each" do
- it "iterates over the contents" do
- expected = ["apples", "bananas", "cherries"]
- collection = Braintree::PagedCollection.new(
- :items => expected
- )
- actual = []
- collection.each do |item|
- actual << item
- end
- actual.should == expected
- end
- end
-
- describe "first" do
- it "returns the first element" do
- collection = Braintree::PagedCollection.new(
- :items => ["apples", "bananas", "cherries"]
- )
- collection.first.should == "apples"
- end
- end
-
- describe "initialize" do
- it "initializes attributes as expected" do
- collection = Braintree::PagedCollection.new(
- :current_page_number => 1,
- :page_size => 2,
- :total_items => 4,
- :items => ["apples", "bananas", "cherries"]
- )
- collection.current_page_number.should == 1
- collection.page_size.should == 2
- collection.total_items.should == 4
- collection.items.should == ["apples", "bananas", "cherries"]
- end
- end
-
- describe "last_page?" do
- it "returns true if the page is the last page" do
- collection = Braintree::PagedCollection.new(:current_page_number => 3, :page_size => 50, :total_items => 150)
- collection.last_page?.should == true
- end
-
- it "returns false if the page is not the last page" do
- collection = Braintree::PagedCollection.new(:current_page_number => 3, :page_size => 50, :total_items => 151)
- collection.last_page?.should == false
- end
- end
-
- describe "next_page" do
- it "returns the next page of results" do
- collection = Braintree::PagedCollection.new(
- :current_page_number => 1,
- :page_size => 1,
- :total_items => 2
- ) do |page_num|
- "contents of page #{page_num}"
- end
- collection.next_page.should == "contents of page 2"
- end
-
- it "returns nil if on last page" do
- collection = Braintree::PagedCollection.new(
- :current_page_number => 2,
- :page_size => 2,
- :total_items => 4
- )
- collection.next_page.should == nil
- end
- end
-
- describe "next_page_number" do
- it "returns the next page number when not on the last page" do
- collection = Braintree::PagedCollection.new(
- :current_page_number => 2,
- :page_size => 1,
- :total_items => 50
- )
- collection.next_page_number.should == 3
- end
-
- it "returns nil when on the last page" do
- collection = Braintree::PagedCollection.new(
- :current_page_number => 1,
- :page_size => 1,
- :total_items => 1
- )
- collection.next_page_number.should == nil
- end
- end
-
- describe "total_pages" do
- it "calculates the total number of pages when total items is not evenly divisible by page size" do
- collection = Braintree::PagedCollection.new(
- :page_size => 5,
- :total_items => 13
- )
- collection.total_pages.should == 3
- end
-
- it "calculates the total number of pages when total items is not evenly divisible by page size" do
- collection = Braintree::PagedCollection.new(
- :page_size => 5,
- :total_items => 20
- )
- collection.total_pages.should == 4
- end
- end
-
- context "custom matchers" do
- require 'enumerator'
-
- DummyItem = Struct.new(:id)
-
- def paged_collection(items, page_size)
- pages = []
- items.each_slice(page_size) do |slice|
- pages << slice
- end
-
- _build_collection(pages, page_size, items.size, 1)
- end
-
- def _build_collection(paged_items, page_size, total_size, current_page)
- Braintree::PagedCollection.new(:items => paged_items[current_page - 1], :total_items => total_size, :page_size => page_size, :current_page_number => current_page) do |page|
- _build_collection(paged_items, page_size, total_size, page)
- end
- end
-
- describe "include_on_any_page" do
- it "finds a match in a simple collection" do
- element = DummyItem.new(123)
- collection = paged_collection([element], 10)
-
- collection.should include_on_any_page(element)
- end
-
- it "does not find a match in a simple collection" do
- element = DummyItem.new(1)
- collection = paged_collection([DummyItem.new(2)], 10)
-
- collection.should_not include_on_any_page(element)
- end
-
- it "finds a match on a subsequent page" do
- element = DummyItem.new(1)
- collection = paged_collection([DummyItem.new(2), element], 1)
-
- collection.should include_on_any_page(element)
- end
-
- it "does not find a match on a subsequent page" do
- element = DummyItem.new(1)
- collection = paged_collection([DummyItem.new(2), DummyItem.new(3)], 1)
-
- collection.should_not include_on_any_page(element)
- end
- end
- end
-end
View
68 spec/unit/braintree/resource_collection_spec.rb
@@ -0,0 +1,68 @@
+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
+ 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
+
+ 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
+ end
+ end
+end
View
3  spec/unit/braintree/transaction/credit_card_details_spec.rb
@@ -16,13 +16,14 @@
details = Braintree::Transaction::CreditCardDetails.new(
:bin => "123456",
:card_type => "Visa",
+ :cardholder_name => "The Cardholder",
:expiration_month => "05",
:expiration_year => "2012",
:last_4 => "6789",
:token => "token",
:customer_location => "US"
)
- details.inspect.should == %(#<token: "token", bin: "123456", last_4: "6789", card_type: "Visa", expiration_date: "05/2012", customer_location: "US">)
+ details.inspect.should == %(#<token: "token", bin: "123456", last_4: "6789", card_type: "Visa", expiration_date: "05/2012", cardholder_name: "The Cardholder", customer_location: "US">)
end
end
View
10 spec/unit/braintree/xml_spec.rb
@@ -123,5 +123,15 @@ def verify_to_xml_and_back(hash)
hash = {:id => "123"}
verify_to_xml_and_back hash
end
+
+ it "escapes keys and values" do
+ hash = { "ke<y" => "val>ue" }
+ Braintree::Xml.hash_to_xml(hash).should include("<ke&lt;y>val&gt;ue</ke&lt;y>")
+ end
+
+ it "escapes nested keys and values" do
+ hash = { "top<" => { "ke<y" => "val>ue" } }
+ Braintree::Xml.hash_to_xml(hash).gsub(/\s/, '').should include("<top&lt;><ke&lt;y>val&gt;ue</ke&lt;y></top&lt;>")
+ end
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.