Skip to content
Browse files

1.2.0

  • Loading branch information...
1 parent 31f9019 commit 168d742c1ad956815cce47545e76ccc298f64b8d @braintreeps braintreeps committed Apr 9, 2010
Showing with 892 additions and 138 deletions.
  1. +7 −0 CHANGELOG.rdoc
  2. +1 −1 Rakefile
  3. +1 −0 bt_rdoc_template/braintree.rb
  4. +1 −1 cruise_config.rb
  5. +2 −0 lib/braintree.rb
  6. +69 −0 lib/braintree/advanced_search.rb
  7. +2 −2 lib/braintree/configuration.rb
  8. +2 −1 lib/braintree/credit_card.rb
  9. +50 −1 lib/braintree/subscription.rb
  10. +10 −0 lib/braintree/subscription_search.rb
  11. +8 −5 lib/braintree/transparent_redirect.rb
  12. +2 −2 lib/braintree/version.rb
  13. +7 −2 lib/braintree/xml/generator.rb
  14. +1 −0 lib/ssl/{valicert_ca.crt → sandbox_braintreegateway_com.ca.crt}
  15. +202 −0 lib/ssl/www_braintreegateway_com.ca.crt
  16. +27 −35 spec/integration/braintree/credit_card_spec.rb
  17. +37 −36 spec/integration/braintree/customer_spec.rb
  18. +17 −0 spec/integration/braintree/http_spec.rb
  19. +244 −3 spec/integration/braintree/subscription_spec.rb
  20. +9 −18 spec/integration/braintree/transaction_spec.rb
  21. +21 −0 spec/integration/braintree/transparent_redirect_spec.rb
  22. +0 −23 spec/integration/spec_helper.rb
  23. +34 −0 spec/spec_helper.rb
  24. +24 −0 spec/support/matchers/include_on_any_page.rb
  25. +3 −3 spec/unit/braintree/configuration_spec.rb
  26. +1 −1 spec/unit/braintree/credit_card_spec.rb
  27. +1 −1 spec/unit/braintree/customer_spec.rb
  28. +50 −0 spec/unit/braintree/paged_collection_spec.rb
  29. +35 −0 spec/unit/braintree/subscription_search_spec.rb
  30. +10 −0 spec/unit/braintree/subscription_spec.rb
  31. +1 −1 spec/unit/braintree/transaction_spec.rb
  32. +8 −2 spec/unit/braintree/transparent_redirect_spec.rb
  33. +5 −0 spec/unit/braintree/xml_spec.rb
View
7 CHANGELOG.rdoc
@@ -1,3 +1,10 @@
+== 1.2.0
+
+* Added Subscription search
+* Updated production CA SSL certificate authority
+* Updated credit cards to include associated subscriptions when finding in vault
+* Fixed bug where we used to raise a "forged query string" exception when we were down for maintenance.
+
== 1.1.3
* Fixed a bug with empty search results
View
2 Rakefile
@@ -23,7 +23,7 @@ Spec::Rake::SpecTask.new("spec:integration") do |t|
end
desc "run specs after preping the gateway"
-task :run_specs_for_cruise do
+task :cruise do
begin
Rake::Task["prep_gateway"].invoke
Rake::Task["spec:unit"].invoke
View
1 bt_rdoc_template/braintree.rb
@@ -66,6 +66,7 @@ module Page
<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/Subscription.html">Subscription</a></li>
</ul>
</div>
View
2 cruise_config.rb
@@ -3,7 +3,7 @@
case project.name
when "client_library_ruby_integration_master"
- project.build_command = "CRUISE_BUILD=#{project.name} GATEWAY_PORT=3010 SPHINX_PORT=3322 rake run_specs_for_cruise --trace"
+ project.build_command = "CRUISE_BUILD=#{project.name} GATEWAY_PORT=3010 SPHINX_PORT=3322 rake cruise --trace"
project.triggered_by :gateway_master
end
end
View
2 lib/braintree.rb
@@ -23,6 +23,7 @@ module Braintree
require "braintree/base_module"
require "braintree/address.rb"
+require "braintree/advanced_search.rb"
require "braintree/configuration.rb"
require "braintree/credit_card.rb"
require "braintree/credit_card_verification.rb"
@@ -35,6 +36,7 @@ module Braintree
require "braintree/paged_collection.rb"
require "braintree/ssl_expiration_check.rb"
require "braintree/subscription"
+require "braintree/subscription_search"
require "braintree/successful_result.rb"
require "braintree/test/credit_card_numbers.rb"
require "braintree/test/transaction_amounts.rb"
View
69 lib/braintree/advanced_search.rb
@@ -0,0 +1,69 @@
+module Braintree
+ class AdvancedSearch
+ class SearchNode
+ def self.operators(*operator_names)
+ operator_names.each do |operator|
+ define_method(operator) do |value|
+ @parent.add_criteria(@node_name, operator => value.to_s)
+ end
+ end
+ end
+
+ def initialize(name, parent)
+ @node_name, @parent = name, parent
+ end
+ end
+
+ class TextNode < SearchNode
+ operators :is, :is_not, :ends_with, :starts_with, :contains
+ end
+
+ class MultipleValueNode < SearchNode
+ def in(*values)
+ values.flatten!
+
+ unless allowed_values.nil?
+ bad_values = values - allowed_values
+ raise ArgumentError.new("Invalid argument(s) for #{@node_name}: #{bad_values.join(", ")}") if bad_values.any?
+ end
+
+ @parent.add_criteria(@node_name, values)
+ end
+
+ def initialize(name, parent, options)
+ super(name, parent)
+ @options = options
+ end
+
+ def allowed_values
+ @options[:allows]
+ end
+ end
+
+ def self.search_fields(*fields)
+ fields.each do |field|
+ define_method(field) do
+ TextNode.new(field, self)
+ end
+ end
+ end
+
+ def self.multiple_value_field(field, options={})
+ define_method(field) do
+ MultipleValueNode.new(field, self, options)
+ end
+ end
+
+ def initialize
+ @criteria = {}
+ end
+
+ def add_criteria(key, value)
+ @criteria[key] = value
+ end
+
+ def to_hash
+ @criteria
+ end
+ end
+end
View
4 lib/braintree/configuration.rb
@@ -37,9 +37,9 @@ def self.base_merchant_path # :nodoc:
def self.ca_file # :nodoc:
case environment
when :qa, :sandbox
- File.expand_path(File.join(File.dirname(__FILE__), "..", "ssl", "valicert_ca.crt"))
+ File.expand_path(File.join(File.dirname(__FILE__), "..", "ssl", "sandbox_braintreegateway_com.ca.crt"))
when :production
- File.expand_path(File.join(File.dirname(__FILE__), "..", "ssl", "securetrust_ca.crt"))
+ File.expand_path(File.join(File.dirname(__FILE__), "..", "ssl", "www_braintreegateway_com.ca.crt"))
end
end
View
3 lib/braintree/credit_card.rb
@@ -3,7 +3,7 @@ class CreditCard
include BaseModule # :nodoc:
attr_reader :billing_address, :bin, :card_type, :cardholder_name, :created_at, :customer_id, :expiration_month,
- :expiration_year, :last_4, :token, :updated_at
+ :expiration_year, :last_4, :subscriptions, :token, :updated_at
def self.create(attributes)
if attributes.has_key?(:expiration_date) && (attributes.has_key?(:expiration_month) || attributes.has_key?(:expiration_year))
@@ -99,6 +99,7 @@ def self.update_credit_card_url
def initialize(attributes) # :nodoc:
_init attributes
+ @subscriptions = (@subscriptions || []).map { |subscription_hash| Subscription.new(subscription_hash) }
end
# Creates a credit transaction for this credit card.
View
51 lib/braintree/subscription.rb
@@ -1,4 +1,25 @@
module Braintree
+ # == Creating a Subscription
+ #
+ # At minimum, a plan_id and payment_method_token are required. Any other values not
+ # provided will be defaulted to the plan's values:
+ #
+ # Braintree::Subscription.create(
+ # :payment_method_token => "my_token",
+ # :plan_id => "my_plan"
+ # )
+ #
+ # Full example:
+ #
+ # Braintree::Subscription.create(
+ # :id => "my_id",
+ # :payment_method_token => "my_token",
+ # :plan_id => "my_plan",
+ # :price => "1.00",
+ # :trial_period => true,
+ # :trial_duration => "2",
+ # :trial_duration_unit => Subscription::TrialDurationUnit::Day
+ # )
class Subscription
include BaseModule
@@ -13,7 +34,7 @@ module TrialDurationUnit
Month = "month"
end
- attr_reader :price, :plan_id, :id, :status, :payment_method_token
+ attr_reader :price, :plan_id, :id, :status, :payment_method_token, :merchant_account_id
attr_reader :first_billing_date, :next_billing_date, :billing_period_start_date, :billing_period_end_date
attr_reader :trial_period, :trial_duration, :trial_duration_unit
attr_reader :failure_count
@@ -46,6 +67,32 @@ def self.find(id)
raise NotFoundError, "subscription with id #{id.inspect} not found"
end
+ # Allows searching on subscriptions. There are two types of fields that are searchable: text and
+ # multiple value fields. Searchable text fields are:
+ # - plan_id
+ # - days_past_due
+ #
+ # Searchable multiple value fields are:
+ # - status
+ #
+ # For text fields, you can search using the following operators: is, is_not, starts_with, ends_with
+ # and contains. For mutiple value fields, you can search using the in operator. An example:
+ #
+ # Subscription.search do |s|
+ # s.plan_id.starts_with "abc"
+ # s.days_past_due.is "30"
+ # s.status.in [Subscription::Status::PastDue]
+ # end
+ def self.search(page=1, &block)
+ search = SubscriptionSearch.new
+ block.call(search)
+
+ 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) }
+ end
+
def self.update(subscription_id, attributes)
Util.verify_keys(_update_signature, attributes)
response = Http.put "/subscriptions/#{subscription_id}", :subscription => attributes
@@ -61,6 +108,7 @@ def self.update(subscription_id, attributes)
def self._create_signature # :nodoc:
[
:id,
+ :merchant_account_id,
:payment_method_token,
:plan_id,
:price,
@@ -100,6 +148,7 @@ def _init(attributes) # :nodoc:
def self._update_signature # :nodoc:
[
:id,
+ :merchant_account_id,
:plan_id,
:price
]
View
10 lib/braintree/subscription_search.rb
@@ -0,0 +1,10 @@
+module Braintree
+ class SubscriptionSearch < AdvancedSearch
+ search_fields :plan_id, :days_past_due
+ multiple_value_field :status, :allows => [
+ Subscription::Status::Active,
+ Subscription::Status::Canceled,
+ Subscription::Status::PastDue
+ ]
+ end
+end
View
13 lib/braintree/transparent_redirect.rb
@@ -41,12 +41,15 @@ def self.create_customer_data(params)
def self.parse_and_validate_query_string(query_string) # :nodoc:
params = Util.symbolize_keys(Util.parse_query_string(query_string))
query_string_without_hash = query_string[/(.*)&hash=.*/, 1]
+
+ 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])
+ end
+
if _hash(query_string_without_hash) == params[:hash]
- if params[:http_status] == '200'
- params
- else
- Util.raise_exception_for_status_code(params[:http_status])
- end
+ params
else
raise ForgedQueryString
end
View
4 lib/braintree/version.rb
@@ -1,8 +1,8 @@
module Braintree
module Version
Major = 1
- Minor = 1
- Tiny = 3
+ Minor = 2
+ Tiny = 0
String = "#{Major}.#{Minor}.#{Tiny}"
end
View
9 lib/braintree/xml/generator.rb
@@ -62,7 +62,6 @@ def self._convert_to_xml(hash_to_convert, options = {})
end
def self._array_to_xml(array, options = {})
- raise "expected all elements to be hashes" unless array.all? { |e| e.is_a?(Hash) }
raise "expected options[:root]" unless options[:root]
raise "expected options[:builder]" unless options[:builder]
options[:indent] ||= 2
@@ -71,7 +70,13 @@ def self._array_to_xml(array, options = {})
options[:builder].tag!(root, :type => "array")
else
options[:builder].tag!(root, :type => "array") do
- array.each { |e| _convert_to_xml(e, options.merge(:root => "item", :skip_instruct => true)) }
+ array.each do |e|
+ if e.is_a?(Hash)
+ _convert_to_xml(e, options.merge(:root => "item", :skip_instruct => true))
+ else
+ options[:builder].tag!("item", e)
+ end
+ end
end
end
end
View
1 lib/ssl/valicert_ca.crt → lib/ssl/sandbox_braintreegateway_com.ca.crt
@@ -1,3 +1,4 @@
+Subject: L=ValiCert Validation Network, O=ValiCert, Inc., OU=ValiCert Class 2 Policy Validation Authority, CN=http://www.valicert.com//emailAddress=info@valicert.com
-----BEGIN CERTIFICATE-----
MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz
View
202 lib/ssl/www_braintreegateway_com.ca.crt
@@ -0,0 +1,202 @@
+Subject: O=Entrust.net, OU=www.entrust.net/GCCA_CPS incorp. by ref. (limits liab.), OU=(c) 2000 Entrust.net Limited, CN=Entrust.net Client Certification Authority
+-----BEGIN CERTIFICATE-----
+MIIEgzCCA+ygAwIBAgIEOJ725DANBgkqhkiG9w0BAQQFADCBtDEUMBIGA1UE
+ChMLRW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9HQ0NB
+X0NQUyBpbmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsT
+HChjKSAyMDAwIEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1
+c3QubmV0IENsaWVudCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMDAy
+MDcxNjE2NDBaFw0yMDAyMDcxNjQ2NDBaMIG0MRQwEgYDVQQKEwtFbnRydXN0
+Lm5ldDFAMD4GA1UECxQ3d3d3LmVudHJ1c3QubmV0L0dDQ0FfQ1BTIGluY29y
+cC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDIwMDAg
+RW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2xp
+ZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA
+A4GNADCBiQKBgQCTdLS25MVL1qFof2LV7PdRV7NySpj10InJrWPNTTVRaoTU
+rcloeW+46xHbh65cJFET8VQlhK8pK5/jgOLZy93GRUk0iJBeAZfv6lOm3fzB
+3ksqJeTpNfpVBQbliXrqpBFXO/x8PTbNZzVtpKklWb1m9fkn5JVn1j+SgF7y
+NH0rhQIDAQABo4IBnjCCAZowEQYJYIZIAYb4QgEBBAQDAgAHMIHdBgNVHR8E
+gdUwgdIwgc+ggcyggcmkgcYwgcMxFDASBgNVBAoTC0VudHJ1c3QubmV0MUAw
+PgYDVQQLFDd3d3cuZW50cnVzdC5uZXQvR0NDQV9DUFMgaW5jb3JwLiBieSBy
+ZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMjAwMCBFbnRydXN0
+Lm5ldCBMaW1pdGVkMTMwMQYDVQQDEypFbnRydXN0Lm5ldCBDbGllbnQgQ2Vy
+dGlmaWNhdGlvbiBBdXRob3JpdHkxDTALBgNVBAMTBENSTDEwKwYDVR0QBCQw
+IoAPMjAwMDAyMDcxNjE2NDBagQ8yMDIwMDIwNzE2NDY0MFowCwYDVR0PBAQD
+AgEGMB8GA1UdIwQYMBaAFISLdP3FjcD/J20gN0V8/i3OutN9MB0GA1UdDgQW
+BBSEi3T9xY3A/ydtIDdFfP4tzrrTfTAMBgNVHRMEBTADAQH/MB0GCSqGSIb2
+fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0BAQQFAAOBgQBObzWA
+O9GK9Q6nIMstZVXQkvTnhLUGJoMShAusO7JE7r3PQNsgDrpuFOow4DtifH+L
+a3xKp9U1PL6oXOpLu5OOgGarDyn9TS2/GpsKkMWr2tGzhtQvJFJcem3G8v7l
+TRowjJDyutdKPkN+1MhQGof4T4HHdguEOnKdzmVml64mXg==
+-----END CERTIFICATE-----
+
+Subject: O=Entrust.net, OU=www.entrust.net/SSL_CPS incorp. by ref. (limits liab.), OU=(c) 2000 Entrust.net Limited, CN=Entrust.net Secure Server Certification Authority
+-----BEGIN CERTIFICATE-----
+MIIElTCCA/6gAwIBAgIEOJsRPDANBgkqhkiG9w0BAQQFADCBujEUMBIGA1UE
+ChMLRW50cnVzdC5uZXQxPzA9BgNVBAsUNnd3dy5lbnRydXN0Lm5ldC9TU0xf
+Q1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc
+KGMpIDIwMDAgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVz
+dC5uZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
+Fw0wMDAyMDQxNzIwMDBaFw0yMDAyMDQxNzUwMDBaMIG6MRQwEgYDVQQKEwtF
+bnRydXN0Lm5ldDE/MD0GA1UECxQ2d3d3LmVudHJ1c3QubmV0L1NTTF9DUFMg
+aW5jb3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykg
+MjAwMCBFbnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5l
+dCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0G
+CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHwV9OcfHO8GCGD9JYf9Mzly0XonUw
+tZZkJi9ow0SrqHXmAGc0V55lxyKbc+bT3QgON1WqJUaBbL3+qPZ1V1eMkGxK
+wz6LS0MKyRFWmponIpnPVZ5h2QLifLZ8OAfc439PmrkDQYC2dWcTC5/oVzbI
+XQA23mYU2m52H083jIITiQIDAQABo4IBpDCCAaAwEQYJYIZIAYb4QgEBBAQD
+AgAHMIHjBgNVHR8EgdswgdgwgdWggdKggc+kgcwwgckxFDASBgNVBAoTC0Vu
+dHJ1c3QubmV0MT8wPQYDVQQLFDZ3d3cuZW50cnVzdC5uZXQvU1NMX0NQUyBp
+bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAy
+MDAwIEVudHJ1c3QubmV0IExpbWl0ZWQxOjA4BgNVBAMTMUVudHJ1c3QubmV0
+IFNlY3VyZSBTZXJ2ZXIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxDTALBgNV
+BAMTBENSTDEwKwYDVR0QBCQwIoAPMjAwMDAyMDQxNzIwMDBagQ8yMDIwMDIw
+NDE3NTAwMFowCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFMtswGvjuz7L/CKc
+/vuLkpyw8m4iMB0GA1UdDgQWBBTLbMBr47s+y/winP77i5KcsPJuIjAMBgNV
+HRMEBTADAQH/MB0GCSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkq
+hkiG9w0BAQQFAAOBgQBi24GRzsiad0Iv7L0no1MPUBvqTpLwqa+poLpIYcvv
+yQbvH9X07t9WLebKahlzqlO+krNQAraFJnJj2HVQYnUUt7NQGj/KEQALhUVp
+bbalrlHhStyCP2yMNLJ3a9kC9n8O6mUE8c1UyrrJzOCE98g+EZfTYAkYvAX/
+bIkz8OwVDw==
+-----END CERTIFICATE-----
+
+Subject: O=Entrust.net, OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.), OU=(c) 1999 Entrust.net Limited, CN=Entrust.net Certification Authority (2048)
+-----BEGIN CERTIFICATE-----
+MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UE
+ChMLRW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNf
+MjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsT
+HChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1
+c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEy
+MjQxNzUwNTFaFw0xOTEyMjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0
+Lm5ldDFAMD4GA1UECxQ3d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29y
+cC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDE5OTkg
+RW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2Vy
+dGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEF
+AAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4
+QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/EC
+DNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuXMlBvPci6Zgzj
+/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzWnLLP
+KQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZd
+enoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH
+4QIDAQABo3QwcjARBglghkgBhvhCAQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB
+0RGAvtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdERgL7YibkIozH5oSQJ
+FrlwMB0GCSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0B
+AQUFAAOCAQEAWUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFh
+fGPjK50xA3B20qMooPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVU
+KcgF7bISKo30Axv/55IQh7A6tcOdBTcSo8f0FbnVpDkWm1M6I5HxqIKiaoho
+wXkCIryqptau37AUX7iH0N18f3v/rxzP5tsHrV7bhZ3QKw0z2wTR5klAEyt2
++z7pnIkPFc4YsIV4IU9rTw76NmfNB/L/CNDi3tm/Kq+4h4YhPATKt5Rof888
+6ZjXOP/swNlQ8C5LWK5Gb9Auw2DaclVyvUxFnmG6v4SBkgPR0ml8xQ==
+-----END CERTIFICATE-----
+
+Subject: C=US, O=Entrust.net, OU=www.entrust.net/Client_CA_Info/CPS incorp. by ref. limits liab., OU=(c) 1999 Entrust.net Limited, CN=Entrust.net Client Certification Authority
+-----BEGIN CERTIFICATE-----
+MIIE7TCCBFagAwIBAgIEOAOR7jANBgkqhkiG9w0BAQQFADCByTELMAkGA1UE
+BhMCVVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MUgwRgYDVQQLFD93d3cuZW50
+cnVzdC5uZXQvQ2xpZW50X0NBX0luZm8vQ1BTIGluY29ycC4gYnkgcmVmLiBs
+aW1pdHMgbGlhYi4xJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExp
+bWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENsaWVudCBDZXJ0aWZpY2F0
+aW9uIEF1dGhvcml0eTAeFw05OTEwMTIxOTI0MzBaFw0xOTEwMTIxOTU0MzBa
+MIHJMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxSDBGBgNV
+BAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0FfSW5mby9DUFMgaW5jb3Jw
+LiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UECxMcKGMpIDE5OTkgRW50
+cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2xpZW50
+IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GL
+ADCBhwKBgQDIOpleMRffrCdvkHvkGf9FozTC28GoT/Bo6oT9n3V5z8GKUZSv
+x1cDR2SerYIbWtp/N3hHuzeYEpbOxhN979IMMFGpOZ5V+Pux5zDeg7K6PvHV
+iTs7hbqqdCz+PzFur5GVbgbUB01LLFZHGARS2g4Qk79jkJvh34zmAqTmT173
+iwIBA6OCAeAwggHcMBEGCWCGSAGG+EIBAQQEAwIABzCCASIGA1UdHwSCARkw
+ggEVMIHkoIHhoIHepIHbMIHYMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50
+cnVzdC5uZXQxSDBGBgNVBAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0Ff
+SW5mby9DUFMgaW5jb3JwLiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UE
+CxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50
+cnVzdC5uZXQgQ2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYD
+VQQDEwRDUkwxMCygKqAohiZodHRwOi8vd3d3LmVudHJ1c3QubmV0L0NSTC9D
+bGllbnQxLmNybDArBgNVHRAEJDAigA8xOTk5MTAxMjE5MjQzMFqBDzIwMTkx
+MDEyMTkyNDMwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUxPucKXuXzUyW
+/O5bs8qZdIuV6kwwHQYDVR0OBBYEFMT7nCl7l81MlvzuW7PKmXSLlepMMAwG
+A1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI
+hvcNAQEEBQADgYEAP66K8ddmAwWePvrqHEa7pFuPeJoSSJn59DXeDDYHAmsQ
+OokUgZwxpnyyQbJq5wcBoUv5nyU7lsqZwz6hURzzwy5E97BnRqqS5TvaHBkU
+ODDV4qIxJS7x7EU47fgGWANzYrAQMY9Av2TgXD7FTx/aEkP/TOYGJqibGapE
+PHayXOw=
+-----END CERTIFICATE-----
+
+Subject: C=US, O=Entrust.net, OU=www.entrust.net/CPS incorp. by ref. (limits liab.), OU=(c) 1999 Entrust.net Limited, CN=Entrust.net Secure Server Certification Authority
+-----BEGIN CERTIFICATE-----
+MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UE
+BhMCVVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50
+cnVzdC5uZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl
+MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UE
+AxMxRW50cnVzdC5uZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1
+dGhvcml0eTAeFw05OTA1MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQsw
+CQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3
+dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1pdHMgbGlh
+Yi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVkMTow
+OAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp
+b24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQDNKIM0
+VBuJ8w+vN5Ex/68xYMmo6LIQaO2f55M28Qpku0f1BBc/I0dNxScZgSYMVHIN
+iC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5gXpa0zf3wkrYKZImZNHk
+mGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OCAdcwggHT
+MBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHboIHY
+pIHVMIHSMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5
+BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChs
+aW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBM
+aW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENl
+cnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNo
+dHRwOi8vd3d3LmVudHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAi
+gA8xOTk5MDUyNTE2MDk0MFqBDzIwMTkwNTI1MTYwOTQwWjALBgNVHQ8EBAMC
+AQYwHwYDVR0jBBgwFoAU8BdiE1U9s/8KAGv7UISX8+1i0BowHQYDVR0OBBYE
+FPAXYhNVPbP/CgBr+1CEl/PtYtAaMAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9
+B0EABAwwChsEVjQuMAMCBJAwDQYJKoZIhvcNAQEFBQADgYEAkNwwAvpkdMKn
+CqV8IY00F6j7Rw7/JXyNEwr75Ji174z4xRAN95K+8cPV1ZVqBLssziY2Zcgx
+xufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9n9cd2cNgQ4xYDiKWL2KjLB+6
+rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI=
+-----END CERTIFICATE-----
+
+Subject: C=US, O=SecureTrust Corporation, CN=SecureTrust CA
+-----BEGIN CERTIFICATE-----
+MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI
+MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
+FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz
+MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv
+cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN
+AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz
+Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO
+0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao
+wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj
+7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS
+8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT
+BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB
+/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg
+JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC
+NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3
+6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/
+3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm
+D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS
+CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR
+3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=
+-----END CERTIFICATE-----
+
+Subject: C=US, O=SecureTrust Corporation, CN=Secure Global CA
+-----BEGIN CERTIFICATE-----
+MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK
+MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
+GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx
+MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg
+Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ
+iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa
+/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ
+jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI
+HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7
+sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w
+gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF
+MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw
+KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG
+AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L
+URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO
+H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm
+I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY
+iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc
+f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW
+-----END CERTIFICATE-----
View
62 spec/integration/braintree/credit_card_spec.rb
@@ -207,7 +207,8 @@
:customer_id => customer.id
}
}
- query_string_response = create_credit_card_via_tr(params, tr_data_params)
+ tr_data = Braintree::TransparentRedirect.create_credit_card_data({:redirect_url => "http://example.com"}.merge(tr_data_params))
+ query_string_response = SpecHelper.simulate_form_post_for_tr(Braintree::CreditCard.create_credit_card_url, tr_data, params)
result = Braintree::CreditCard.create_from_transparent_redirect(query_string_response)
result.success?.should == true
credit_card = result.credit_card
@@ -234,7 +235,8 @@
:customer_id => customer.id
}
}
- query_string_response = create_credit_card_via_tr(params, tr_data_params)
+ tr_data = Braintree::TransparentRedirect.create_credit_card_data({:redirect_url => "http://example.com"}.merge(tr_data_params))
+ query_string_response = SpecHelper.simulate_form_post_for_tr(Braintree::CreditCard.create_credit_card_url, tr_data, params)
result = Braintree::CreditCard.create_from_transparent_redirect(query_string_response)
result.success?.should == false
result.params[:customer_id] == customer.id
@@ -439,7 +441,8 @@
:token => new_token
}
}
- query_string_response = update_credit_card_via_tr(params, tr_data_params)
+ tr_data = Braintree::TransparentRedirect.update_credit_card_data({:redirect_url => "http://example.com"}.merge(tr_data_params))
+ query_string_response = SpecHelper.simulate_form_post_for_tr(Braintree::CreditCard.update_credit_card_url, tr_data, params)
result = Braintree::CreditCard.update_from_transparent_redirect(query_string_response)
result.success?.should == true
credit_card = result.credit_card
@@ -578,6 +581,27 @@
credit_card.expiration_date.should == "05/2012"
end
+ it "returns associated subscriptions with the credit card" do
+ customer = Braintree::Customer.create.customer
+ credit_card = Braintree::CreditCard.create(
+ :customer_id => customer.id,
+ :number => Braintree::Test::CreditCardNumbers::Visa,
+ :expiration_date => "05/2012"
+ ).credit_card
+
+ subscription = Braintree::Subscription.create(
+ :payment_method_token => credit_card.token,
+ :plan_id => "integration_trialless_plan",
+ :price => "1.00"
+ ).subscription
+
+ found_card = Braintree::CreditCard.find(credit_card.token)
+ found_card.subscriptions.first.id.should == subscription.id
+ found_card.subscriptions.first.plan_id.should == "integration_trialless_plan"
+ found_card.subscriptions.first.payment_method_token.should == credit_card.token
+ found_card.subscriptions.first.price.should == BigDecimal.new("1.00")
+ end
+
it "raises a NotFoundError exception if payment method cannot be found" do
expect do
Braintree::CreditCard.find("invalid-token")
@@ -827,36 +851,4 @@
end.to raise_error(Braintree::ValidationsFailed)
end
end
-
- def create_credit_card_via_tr(regular_params, tr_params = {})
- response = nil
- Net::HTTP.start("localhost", Braintree::Configuration.port) do |http|
- request = Net::HTTP::Post.new("/" + Braintree::CreditCard.create_credit_card_url.split("/", 4)[3])
- request.add_field "Content-Type", "application/x-www-form-urlencoded"
- tr_data = Braintree::TransparentRedirect.create_credit_card_data({:redirect_url => "http://example.com"}.merge(tr_params))
- request.body = Braintree::Util.hash_to_query_string({:tr_data => tr_data}.merge(regular_params))
- response = http.request(request)
- end
- if response.code.to_i == 303
- query_string = response["Location"].split("?", 2).last
- else
- raise "did not receive a valid tr response: #{response.body[0,1000].inspect}"
- end
- end
-
- def update_credit_card_via_tr(regular_params, tr_params = {})
- response = nil
- Net::HTTP.start("localhost", Braintree::Configuration.port) do |http|
- request = Net::HTTP::Post.new("/" + Braintree::CreditCard.update_credit_card_url.split("/", 4)[3])
- request.add_field "Content-Type", "application/x-www-form-urlencoded"
- tr_data = Braintree::TransparentRedirect.update_credit_card_data({:redirect_url => "http://example.com"}.merge(tr_params))
- request.body = Braintree::Util.hash_to_query_string({:tr_data => tr_data}.merge(regular_params))
- response = http.request(request)
- end
- if response.code.to_i == 303
- query_string = response["Location"].split("?", 2).last
- else
- raise "did not receive a valid tr response: #{response.body[0,1000].inspect}"
- end
- end
end
View
73 spec/integration/braintree/customer_spec.rb
@@ -416,8 +416,11 @@
:website => "www.johndoe.com"
}
}
- query_string_response = create_customer_via_tr(params)
+
+ tr_data = Braintree::TransparentRedirect.create_customer_data({:redirect_url => "http://example.com"}.merge({}))
+ query_string_response = SpecHelper.simulate_form_post_for_tr(Braintree::Customer.create_customer_url, tr_data, params)
result = Braintree::Customer.create_from_transparent_redirect(query_string_response)
+
result.success?.should == true
customer = result.customer
customer.first_name.should == "John"
@@ -443,8 +446,11 @@
:website => "www.johndoe.com"
}
}
- query_string_response = create_customer_via_tr({}, tr_data_params)
+
+ tr_data = Braintree::TransparentRedirect.create_customer_data({:redirect_url => "http://example.com"}.merge(tr_data_params))
+ query_string_response = SpecHelper.simulate_form_post_for_tr(Braintree::Customer.create_customer_url, tr_data, {})
result = Braintree::Customer.create_from_transparent_redirect(query_string_response)
+
result.success?.should == true
customer = result.customer
customer.id.should == customer_id
@@ -489,6 +495,27 @@
customer.last_name.should == "Cool"
end
+ it "returns associated subscriptions" do
+ customer = Braintree::Customer.create.customer
+ credit_card = Braintree::CreditCard.create(
+ :customer_id => customer.id,
+ :number => Braintree::Test::CreditCardNumbers::Visa,
+ :expiration_date => "05/2012"
+ ).credit_card
+
+ subscription = Braintree::Subscription.create(
+ :payment_method_token => credit_card.token,
+ :plan_id => "integration_trialless_plan",
+ :price => "1.00"
+ ).subscription
+
+ found_customer = Braintree::Customer.find(customer.id)
+ found_customer.credit_cards.first.subscriptions.first.id.should == subscription.id
+ found_customer.credit_cards.first.subscriptions.first.plan_id.should == "integration_trialless_plan"
+ found_customer.credit_cards.first.subscriptions.first.payment_method_token.should == credit_card.token
+ found_customer.credit_cards.first.subscriptions.first.price.should == BigDecimal.new("1.00")
+ end
+
it "works for a blank customer" do
created_customer = Braintree::Customer.create!
found_customer = Braintree::Customer.find(created_customer.id)
@@ -651,8 +678,11 @@
tr_data_params = {
:customer_id => original_customer.id
}
- query_string_response = update_customer_via_tr(params, tr_data_params)
+
+ tr_data = Braintree::TransparentRedirect.update_customer_data({:redirect_url => "http://example.com"}.merge(tr_data_params))
+ query_string_response = SpecHelper.simulate_form_post_for_tr(Braintree::Customer.update_customer_url, tr_data, params)
result = Braintree::Customer.update_from_transparent_redirect(query_string_response)
+
result.success?.should == true
customer = result.customer
customer.id.should == original_customer.id
@@ -689,8 +719,11 @@
:website => "new.website.com"
}
}
- query_string_response = update_customer_via_tr({}, tr_data_params)
+
+ tr_data = Braintree::TransparentRedirect.update_customer_data({:redirect_url => "http://example.com"}.merge(tr_data_params))
+ query_string_response = SpecHelper.simulate_form_post_for_tr(Braintree::Customer.update_customer_url, tr_data, {})
result = Braintree::Customer.update_from_transparent_redirect(query_string_response)
+
result.success?.should == true
customer = result.customer
customer.id.should == new_customer_id
@@ -703,36 +736,4 @@
customer.website.should == "new.website.com"
end
end
-
- def create_customer_via_tr(regular_params, tr_data_params = {})
- response = nil
- Net::HTTP.start(Braintree::Configuration.server, Braintree::Configuration.port) do |http|
- request = Net::HTTP::Post.new("/" + Braintree::Customer.create_customer_url.split("/", 4)[3])
- request.add_field "Content-Type", "application/x-www-form-urlencoded"
- params = {
- :tr_data => Braintree::TransparentRedirect.create_customer_data(
- {:redirect_url => "http://testing.com"}.merge(tr_data_params)
- )
- }.merge(regular_params)
- request.body = Braintree::Util.hash_to_query_string(params)
- response = http.request(request)
- end
- query_string = response["Location"].split("?", 2).last
- query_string
- end
-
- def update_customer_via_tr(regular_params, tr_data_params = {})
- raise "need a customer_id (of the customer to update) in tr_data_params" unless tr_data_params[:customer_id]
- response = nil
- Net::HTTP.start(Braintree::Configuration.server, Braintree::Configuration.port) do |http|
- request = Net::HTTP::Post.new("/" + Braintree::Customer.update_customer_url.split("/", 4)[3])
- request.add_field "Content-Type", "application/x-www-form-urlencoded"
- tr_data = Braintree::TransparentRedirect.update_customer_data(
- {:redirect_url => "http://testing.com"}.merge(tr_data_params)
- )
- request.body = Braintree::Util.hash_to_query_string({ :tr_data => tr_data }.merge(regular_params))
- response = http.request(request)
- end
- query_string = response["Location"].split("?", 2).last
- end
end
View
17 spec/integration/braintree/http_spec.rb
@@ -67,6 +67,23 @@
end
end
+ describe "user_agent" do
+ after do
+ Braintree::Configuration.custom_user_agent = nil
+ end
+
+ it "sets the User-Agent header using the default user agent" do
+ response = Braintree::Http.get("/test/headers")
+ response[:headers][:HTTP_USER_AGENT].should == "Braintree Ruby Gem #{Braintree::Version::String}"
+ end
+
+ it "sets the User-Agent header using a customer user agent" do
+ Braintree::Configuration.custom_user_agent = "ActiveMerchant 1.2.3"
+ response = Braintree::Http.get("/test/headers")
+ response[:headers][:HTTP_USER_AGENT].should == "Braintree Ruby Gem #{Braintree::Version::String} (ActiveMerchant 1.2.3)"
+ end
+ end
+
describe "ssl verification" do
it "rejects when the certificate isn't verified by our certificate authority (self-signed)" do
begin
View
247 spec/integration/braintree/subscription_spec.rb
@@ -1,7 +1,6 @@
require File.dirname(__FILE__) + "/../spec_helper"
describe Braintree::Subscription do
-
TrialPlan = {
:description => "Plan for integration tests -- with trial",
:id => "integration_trial_plan",
@@ -18,6 +17,9 @@
:trial_period => false
}
+ DefaultMerchantAccountId = "sandbox_credit_card"
+ NonDefaultMerchantAccountId = "sandbox_credit_card_non_default"
+
before(:each) do
@credit_card = Braintree::Customer.create!(
:credit_card => {
@@ -62,6 +64,29 @@
result.subscription.id.should == new_id
end
+ context "merchant_account_id" do
+ it "defaults to the default merchant account if no merchant_account_id is provided" do
+ result = Braintree::Subscription.create(
+ :payment_method_token => @credit_card.token,
+ :plan_id => TriallessPlan[:id]
+ )
+
+ result.success?.should == true
+ result.subscription.merchant_account_id.should == DefaultMerchantAccountId
+ end
+
+ it "allows setting the merchant_account_id" do
+ result = Braintree::Subscription.create(
+ :payment_method_token => @credit_card.token,
+ :plan_id => TriallessPlan[:id],
+ :merchant_account_id => NonDefaultMerchantAccountId
+ )
+
+ result.success?.should == true
+ result.subscription.merchant_account_id.should == NonDefaultMerchantAccountId
+ end
+ end
+
context "trial period" do
context "defaults to the plan's trial period settings" do
it "with no trial" do
@@ -190,7 +215,7 @@
:trial_duration => nil
)
result.success?.should == false
- result.errors.for(:subscription)[0].message.should == "Trial Duration is required."
+ result.errors.for(:subscription).on(:trial_duration)[0].message.should == "Trial Duration is required."
end
it "trial duration unit required" do
@@ -235,6 +260,17 @@
).subscription
end
+ context "merchant_account_id" do
+ it "allows changing the merchant_account_id" do
+ result = Braintree::Subscription.update(@subscription.id,
+ :merchant_account_id => NonDefaultMerchantAccountId
+ )
+
+ result.success?.should == true
+ result.subscription.merchant_account_id.should == NonDefaultMerchantAccountId
+ end
+ end
+
context "when successful" do
it "returns a success response with the updated subscription if valid" do
new_id = rand(36**9).to_s(36)
@@ -359,7 +395,7 @@
}.to raise_error(Braintree::NotFoundError, 'subscription with id "noSuchSubscription" not found')
end
- it "cannot be canceled if already canceld" do
+ it "cannot be canceled if already canceled" do
subscription = Braintree::Subscription.create(
:payment_method_token => @credit_card.token,
:price => 54.32,
@@ -375,4 +411,209 @@
result.errors.for(:subscription)[0].code.should == "81905"
end
end
+
+ describe "self.search" do
+ context "search_fields" do
+ it "correctly returns a result with no matches" do
+ collection = Braintree::Subscription.search do |search|
+ search.plan_id.is "not_a_real_plan_id"
+ end
+
+ collection.items.size.should == 0
+ end
+
+ context "is statement" do
+ it "returns paged collection with matching results" do
+ trialless_subscription = Braintree::Subscription.create(
+ :payment_method_token => @credit_card.token,
+ :plan_id => TriallessPlan[:id]
+ ).subscription
+
+ trial_subscription = Braintree::Subscription.create(
+ :payment_method_token => @credit_card.token,
+ :plan_id => TrialPlan[:id]
+ ).subscription
+
+ collection = Braintree::Subscription.search do |search|
+ search.plan_id.is TriallessPlan[:id]
+ end
+
+ collection.should include_on_any_page(trialless_subscription)
+ collection.should_not include_on_any_page(trial_subscription)
+ end
+ end
+
+ context "is_not statement" do
+ it "returns paged collection without matching results" do
+ trialless_subscription = Braintree::Subscription.create(
+ :payment_method_token => @credit_card.token,
+ :plan_id => TriallessPlan[:id]
+ ).subscription
+
+ trial_subscription = Braintree::Subscription.create(
+ :payment_method_token => @credit_card.token,
+ :plan_id => TrialPlan[:id]
+ ).subscription
+
+ collection = Braintree::Subscription.search do |search|
+ 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)
+ end
+ end
+
+ context "ends_with statement" do
+ it "returns paged collection with matching results" do
+ trialless_subscription = Braintree::Subscription.create(
+ :payment_method_token => @credit_card.token,
+ :plan_id => TriallessPlan[:id]
+ ).subscription
+
+ trial_subscription = Braintree::Subscription.create(
+ :payment_method_token => @credit_card.token,
+ :plan_id => TrialPlan[:id]
+ ).subscription
+
+ collection = Braintree::Subscription.search do |search|
+ 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)
+ end
+ end
+
+ context "starts_with statement" do
+ it "returns paged collection with matching results" do
+ trialless_subscription = Braintree::Subscription.create(
+ :payment_method_token => @credit_card.token,
+ :plan_id => TriallessPlan[:id]
+ ).subscription
+
+ trial_subscription = Braintree::Subscription.create(
+ :payment_method_token => @credit_card.token,
+ :plan_id => TrialPlan[:id]
+ ).subscription
+
+ collection = Braintree::Subscription.search do |search|
+ 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)
+ end
+ end
+
+ context "contains statement" do
+ it "returns paged collection with matching results" do
+ trialless_subscription = Braintree::Subscription.create(
+ :payment_method_token => @credit_card.token,
+ :plan_id => TriallessPlan[:id]
+ ).subscription
+
+ trial_subscription = Braintree::Subscription.create(
+ :payment_method_token => @credit_card.token,
+ :plan_id => TrialPlan[:id]
+ ).subscription
+
+ collection = Braintree::Subscription.search do |search|
+ search.plan_id.contains "trial_p"
+ end
+
+ collection.should include_on_any_page(trial_subscription)
+ collection.should_not include_on_any_page(trialless_subscription)
+ end
+ end
+ end
+
+ context "multiple_value_fields" do
+ context "in" do
+ it "matches all values if none are specified" do
+ subscription1 = Braintree::Subscription.create(
+ :payment_method_token => @credit_card.token,
+ :plan_id => TriallessPlan[:id]
+ ).subscription
+
+ subscription2 = Braintree::Subscription.create(
+ :payment_method_token => @credit_card.token,
+ :plan_id => TriallessPlan[:id]
+ ).subscription
+
+ Braintree::Subscription.cancel(subscription2.id)
+
+ collection = Braintree::Subscription.search do |search|
+ search.plan_id.is TriallessPlan[:id]
+ end
+
+ collection.should include_on_any_page(subscription1)
+ collection.should include_on_any_page(subscription2)
+ end
+
+ it "returns only matching results" do
+ subscription1 = Braintree::Subscription.create(
+ :payment_method_token => @credit_card.token,
+ :plan_id => TriallessPlan[:id]
+ ).subscription
+
+ subscription2 = Braintree::Subscription.create(
+ :payment_method_token => @credit_card.token,
+ :plan_id => TriallessPlan[:id]
+ ).subscription
+
+ Braintree::Subscription.cancel(subscription2.id)
+
+ collection = Braintree::Subscription.search do |search|
+ search.status.in Braintree::Subscription::Status::Active
+ end
+
+ collection.should include_on_any_page(subscription1)
+ collection.should_not include_on_any_page(subscription2)
+ end
+
+ it "returns only matching results given an argument list" do
+ subscription1 = Braintree::Subscription.create(
+ :payment_method_token => @credit_card.token,
+ :plan_id => TriallessPlan[:id]
+ ).subscription
+
+ subscription2 = Braintree::Subscription.create(
+ :payment_method_token => @credit_card.token,
+ :plan_id => TriallessPlan[:id]
+ ).subscription
+
+ Braintree::Subscription.cancel(subscription2.id)
+
+ collection = Braintree::Subscription.search do |search|
+ 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)
+ end
+
+ it "returns only matching results given an array" do
+ subscription1 = Braintree::Subscription.create(
+ :payment_method_token => @credit_card.token,
+ :plan_id => TriallessPlan[:id]
+ ).subscription
+
+ subscription2 = Braintree::Subscription.create(
+ :payment_method_token => @credit_card.token,
+ :plan_id => TriallessPlan[:id]
+ ).subscription
+
+ Braintree::Subscription.cancel(subscription2.id)
+
+ collection = Braintree::Subscription.search do |search|
+ 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)
+ end
+ end
+ end
+ end
end
View
27 spec/integration/braintree/transaction_spec.rb
@@ -706,8 +706,10 @@
:type => "sale"
}
}
- query_string_response = create_transaction_via_tr(params, tr_data_params)
+ 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)
result = Braintree::Transaction.create_from_transparent_redirect(query_string_response)
+
result.success?.should == true
transaction = result.transaction
transaction.type.should == "sale"
@@ -764,8 +766,10 @@
}
}
}
- query_string_response = create_transaction_via_tr(params, tr_data_params)
+ 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)
result = Braintree::Transaction.create_from_transparent_redirect(query_string_response)
+
transaction = result.transaction
transaction.id.should =~ /\A\w{6}\z/
transaction.type.should == "sale"
@@ -825,8 +829,10 @@
:type => "sale"
}
}
- query_string_response = create_transaction_via_tr(params, tr_data_params)
+ 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)
result = Braintree::Transaction.create_from_transparent_redirect(query_string_response)
+
result.success?.should == false
result.params[:transaction].should == {:amount => "", :type => "sale", :credit_card => {:expiration_date => "05/2009"}}
result.errors.for(:transaction).on(:amount)[0].code.should == Braintree::ErrorCodes::Transaction::AmountIsRequired
@@ -1260,21 +1266,6 @@
end
end
- def create_transaction_via_tr(params, tr_data_params)
- response = nil
- Net::HTTP.start(Braintree::Configuration.server, Braintree::Configuration.port) do |http|
- request = Net::HTTP::Post.new("/" + Braintree::Transaction.create_transaction_url.split("/", 4)[3])
- request.add_field "Content-Type", "application/x-www-form-urlencoded"
- params = {
- :tr_data => Braintree::TransparentRedirect.transaction_data({:redirect_url => "http://testing.com"}.merge(tr_data_params))
- }.merge(params)
- request.body = Braintree::Util.hash_to_query_string(params)
- response = http.request(request)
- end
- query_string = response["Location"].split("?", 2).last
- query_string
- end
-
def create_transaction_to_refund
transaction = Braintree::Transaction.sale!(
:amount => Braintree::Test::TransactionAmounts::Authorize,
View
21 spec/integration/braintree/transparent_redirect_spec.rb
@@ -0,0 +1,21 @@
+require File.dirname(__FILE__) + "/../spec_helper"
+
+describe Braintree::TransparentRedirect do
+ it "raises a DownForMaintenanceError when app is in maintenance mode on TR requests" do
+ tr_data = Braintree::TransparentRedirect.create_customer_data({:redirect_url => "http://example.com"}.merge({}))
+ query_string_response = SpecHelper.simulate_form_post_for_tr(Braintree::Configuration.base_merchant_url + "/test/maintenance", tr_data, {})
+ expect do
+ Braintree::Customer.create_from_transparent_redirect(query_string_response)
+ end.to raise_error(Braintree::DownForMaintenanceError)
+ end
+
+ it "raises an AuthenticationError when authentication fails on TR requests" do
+ SpecHelper.using_configuration(:private_key => "incorrect") do
+ tr_data = Braintree::TransparentRedirect.create_customer_data({:redirect_url => "http://example.com"}.merge({}))
+ query_string_response = SpecHelper.simulate_form_post_for_tr(Braintree::Customer.create_customer_url, tr_data, {})
+ expect do
+ Braintree::Customer.create_from_transparent_redirect(query_string_response)
+ end.to raise_error(Braintree::AuthenticationError)
+ end
+ end
+end
View
23 spec/integration/spec_helper.rb
@@ -4,29 +4,6 @@
require File.dirname(__FILE__) + "/../spec_helper"
require File.dirname(__FILE__) + "/../hacks/tcp_socket"
- Spec::Runner.configure do |config|
- CLIENT_LIB_ROOT = File.expand_path(File.dirname(__FILE__) + "/../..")
- GATEWAY_ROOT = File.expand_path("#{CLIENT_LIB_ROOT}/../gateway")
- GATEWAY_PID_FILE = "/tmp/gateway_server_#{Braintree::Configuration.port}.pid"
- SPHINX_PID_FILE = "#{GATEWAY_ROOT}/log/searchd.integration.pid"
-
- gateway_already_started = File.exist?(GATEWAY_PID_FILE)
- sphinx_already_started = File.exist?(SPHINX_PID_FILE)
- config.before(:suite) do
- Dir.chdir(CLIENT_LIB_ROOT) do
- system "rake start_gateway" or raise "rake start_gateway failed" unless gateway_already_started
- system "rake start_sphinx" or raise "rake start_sphinx failed" unless sphinx_already_started
- end
- end
-
- config.after(:suite) do
- Dir.chdir(CLIENT_LIB_ROOT) do
- system "rake stop_gateway" or raise "rake stop_gateway failed" unless gateway_already_started
- system "rake stop_sphinx" or raise "rake stop_sphinx failed" unless sphinx_already_started
- end
- end
- end
-
def start_ssl_server
web_server_pid_file = File.expand_path(File.join(File.dirname(__FILE__), "..", "httpsd.pid"))
View
34 spec/spec_helper.rb
@@ -34,5 +34,39 @@ class << self
end
end
end
+
+ def self.simulate_form_post_for_tr(url, tr_data_string, form_data_hash)
+ response = nil
+ Net::HTTP.start("localhost", Braintree::Configuration.port) do |http|
+ request = Net::HTTP::Post.new("/" + url.split("/", 4)[3])
+ request.add_field "Content-Type", "application/x-www-form-urlencoded"
+ request.body = Braintree::Util.hash_to_query_string({:tr_data => tr_data_string}.merge(form_data_hash))
+ response = http.request(request)
+ end
+ if response.code.to_i == 303
+ response["Location"].split("?", 2).last
+ else
+ raise "did not receive a valid tr response: #{response.body[0,1000].inspect}"
+ end
+ end
+
+ def self.using_configuration(config = {}, &block)
+ original_values = {}
+ [:merchant_id, :public_key, :private_key].each do |key|
+ if config[key]
+ original_values[key] = Braintree::Configuration.send(key)
+ Braintree::Configuration.send("#{key}=", config[key])
+ end
+ end
+ begin
+ yield
+ ensure
+ original_values.each do |key, value|
+ Braintree::Configuration.send("#{key}=", value)
+ end
+ end
+ end
end
end
+
+Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each {|f| require f}
View
24 spec/support/matchers/include_on_any_page.rb
@@ -0,0 +1,24 @@
+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
6 spec/unit/braintree/configuration_spec.rb
@@ -44,21 +44,21 @@
it "qa" do
Braintree::Configuration.environment = :qa
ca_file = Braintree::Configuration.ca_file
- ca_file.should match(/valicert_ca.crt$/)
+ ca_file.should match(/sandbox_braintreegateway_com.ca.crt$/)
File.exists?(ca_file).should == true
end
it "sandbox" do
Braintree::Configuration.environment = :sandbox
ca_file = Braintree::Configuration.ca_file
- ca_file.should match(/valicert_ca.crt$/)
+ ca_file.should match(/sandbox_braintreegateway_com.ca.crt$/)
File.exists?(ca_file).should == true
end
it "production" do
Braintree::Configuration.environment = :production
ca_file = Braintree::Configuration.ca_file
- ca_file.should match(/securetrust_ca.crt$/)
+ ca_file.should match(/www_braintreegateway_com.ca.crt$/)
File.exists?(ca_file).should == true
end
end
View
2 spec/unit/braintree/credit_card_spec.rb
@@ -24,7 +24,7 @@
describe "self.create_from_transparent_redirect" do
it "raises an exception if the query string is forged" do
expect do
- Braintree::CreditCard.create_from_transparent_redirect("forged=query_string")
+ Braintree::CreditCard.create_from_transparent_redirect("http_status=200&forged=query_string")
end.to raise_error(Braintree::ForgedQueryString)
end
end
View
2 spec/unit/braintree/customer_spec.rb
@@ -51,7 +51,7 @@
describe "self.create_from_transparent_redirect" do
it "raises an exception if the query string is forged" do
expect do
- Braintree::Customer.create_from_transparent_redirect("forged=query_string")
+ Braintree::Customer.create_from_transparent_redirect("http_status=200&forged=query_string")
end.to raise_error(Braintree::ForgedQueryString)
end
end
View
50 spec/unit/braintree/paged_collection_spec.rb
@@ -125,4 +125,54 @@
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
35 spec/unit/braintree/subscription_search_spec.rb
@@ -0,0 +1,35 @@
+require File.dirname(__FILE__) + "/../spec_helper"
+
+module Braintree
+ describe SubscriptionSearch do
+ context "status" do
+ it "allows Active, Canceled and PastDue" do
+ search = SubscriptionSearch.new
+
+ lambda do
+ search.status.in(
+ Subscription::Status::Active,
+ Subscription::Status::Canceled,
+ Subscription::Status::PastDue
+ )
+ end.should_not raise_error
+ end
+ end
+
+ context "days_past_due" do
+ it "correctly builds a hash with the criteria" do
+ search = SubscriptionSearch.new
+ search.days_past_due.is "30"
+
+ search.to_hash.should == {:days_past_due => {:is => "30"}}
+ end
+
+ it "coverts ints to strings" do
+ search = SubscriptionSearch.new
+ search.days_past_due.is 30
+
+ search.to_hash.should == {:days_past_due => {:is => "30"}}
+ end
+ end
+ end
+end
View
10 spec/unit/braintree/subscription_spec.rb
@@ -13,4 +13,14 @@
}.to raise_error(/Argument must be a String or BigDecimal/)
end
end
+
+ describe "self.search" do
+ it "only allows specified values for status" do
+ lambda do
+ Braintree::Subscription.search do |search|
+ search.status.in "Hammer"
+ end
+ end.should raise_error(ArgumentError)
+ end
+ end
end
View
2 spec/unit/braintree/transaction_spec.rb
@@ -12,7 +12,7 @@
describe "self.create_from_transparent_redirect" do
it "raises an exception if the query string is forged" do
expect do
- Braintree::Transaction.create_from_transparent_redirect("forged=query_string")
+ Braintree::Transaction.create_from_transparent_redirect("http_status=200&forged=query_string")
end.to raise_error(Braintree::ForgedQueryString)
end
end
View
10 spec/unit/braintree/transparent_redirect_spec.rb
@@ -32,7 +32,7 @@
end
it "raises Braintree::ForgedQueryString if the hash param is not valid" do
- query_string_without_hash = "one=1&two=2"
+ query_string_without_hash = "http_status=200&one=1&two=2"
hash = Digest::SHA1.hexdigest("invalid#{query_string_without_hash}")
query_string_with_hash = "#{query_string_without_hash}&hash=#{hash}"
@@ -43,7 +43,7 @@
it "raises Braintree::ForgedQueryString if hash is missing from the query string" do
expect do
- Braintree::TransparentRedirect.parse_and_validate_query_string "query_string=without_a_hash"
+ Braintree::TransparentRedirect.parse_and_validate_query_string "http_status=200&query_string=without_a_hash"
end.to raise_error(Braintree::ForgedQueryString)
end
@@ -59,6 +59,12 @@
end.to raise_error(Braintree::AuthorizationError)
end
+ it "raises an UnexpectedError if http_status is not in query string" do
+ expect do
+ Braintree::TransparentRedirect.parse_and_validate_query_string add_hash_to_query_string("no_http_status=x")
+ end.to raise_error(Braintree::UnexpectedError, "expected query string to have an http_status param")
+ end
+
it "raises a ServerError if the server 500's" do
expect do
Braintree::TransparentRedirect.parse_and_validate_query_string add_hash_to_query_string("http_status=500")
View
5 spec/unit/braintree/xml_spec.rb
@@ -94,6 +94,11 @@ def verify_to_xml_and_back(hash)
verify_to_xml_and_back hash
end
+ it "works for arrays of strings" do
+ hash = {:root => {:items => ["first", "second"]}}
+ verify_to_xml_and_back hash
+ end
+
it "type casts booleans" do
hash = {:root => {:string_true => "true", :bool_true => true, :bool_false => false, :string_false => "false"}}
verify_to_xml_and_back hash

0 comments on commit 168d742

Please sign in to comment.
Something went wrong with that request. Please try again.