braintree 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. data/LICENSE +22 -0
  2. data/README.rdoc +62 -0
  3. data/lib/braintree.rb +66 -0
  4. data/lib/braintree/address.rb +122 -0
  5. data/lib/braintree/base_module.rb +29 -0
  6. data/lib/braintree/configuration.rb +99 -0
  7. data/lib/braintree/credit_card.rb +231 -0
  8. data/lib/braintree/credit_card_verification.rb +31 -0
  9. data/lib/braintree/customer.rb +231 -0
  10. data/lib/braintree/digest.rb +20 -0
  11. data/lib/braintree/error_codes.rb +95 -0
  12. data/lib/braintree/error_result.rb +39 -0
  13. data/lib/braintree/errors.rb +29 -0
  14. data/lib/braintree/http.rb +105 -0
  15. data/lib/braintree/paged_collection.rb +55 -0
  16. data/lib/braintree/ssl_expiration_check.rb +28 -0
  17. data/lib/braintree/successful_result.rb +38 -0
  18. data/lib/braintree/test/credit_card_numbers.rb +50 -0
  19. data/lib/braintree/test/transaction_amounts.rb +10 -0
  20. data/lib/braintree/transaction.rb +360 -0
  21. data/lib/braintree/transaction/address_details.rb +15 -0
  22. data/lib/braintree/transaction/credit_card_details.rb +22 -0
  23. data/lib/braintree/transaction/customer_details.rb +13 -0
  24. data/lib/braintree/transparent_redirect.rb +110 -0
  25. data/lib/braintree/util.rb +94 -0
  26. data/lib/braintree/validation_error.rb +15 -0
  27. data/lib/braintree/validation_error_collection.rb +80 -0
  28. data/lib/braintree/version.rb +9 -0
  29. data/lib/braintree/xml.rb +12 -0
  30. data/lib/braintree/xml/generator.rb +80 -0
  31. data/lib/braintree/xml/libxml.rb +69 -0
  32. data/lib/braintree/xml/parser.rb +93 -0
  33. data/lib/ssl/securetrust_ca.crt +44 -0
  34. data/lib/ssl/valicert_ca.crt +18 -0
  35. data/spec/integration/braintree/address_spec.rb +352 -0
  36. data/spec/integration/braintree/credit_card_spec.rb +676 -0
  37. data/spec/integration/braintree/customer_spec.rb +664 -0
  38. data/spec/integration/braintree/http_spec.rb +201 -0
  39. data/spec/integration/braintree/test/transaction_amounts_spec.rb +29 -0
  40. data/spec/integration/braintree/transaction_spec.rb +900 -0
  41. data/spec/integration/spec_helper.rb +38 -0
  42. data/spec/script/httpsd.rb +27 -0
  43. data/spec/spec_helper.rb +41 -0
  44. data/spec/unit/braintree/address_spec.rb +86 -0
  45. data/spec/unit/braintree/configuration_spec.rb +190 -0
  46. data/spec/unit/braintree/credit_card_spec.rb +137 -0
  47. data/spec/unit/braintree/credit_card_verification_spec.rb +17 -0
  48. data/spec/unit/braintree/customer_spec.rb +103 -0
  49. data/spec/unit/braintree/digest_spec.rb +28 -0
  50. data/spec/unit/braintree/error_result_spec.rb +42 -0
  51. data/spec/unit/braintree/errors_spec.rb +81 -0
  52. data/spec/unit/braintree/http_spec.rb +42 -0
  53. data/spec/unit/braintree/paged_collection_spec.rb +128 -0
  54. data/spec/unit/braintree/ssl_expiration_check_spec.rb +92 -0
  55. data/spec/unit/braintree/successful_result_spec.rb +27 -0
  56. data/spec/unit/braintree/transaction/credit_card_details_spec.rb +22 -0
  57. data/spec/unit/braintree/transaction_spec.rb +136 -0
  58. data/spec/unit/braintree/transparent_redirect_spec.rb +154 -0
  59. data/spec/unit/braintree/util_spec.rb +142 -0
  60. data/spec/unit/braintree/validation_error_collection_spec.rb +128 -0
  61. data/spec/unit/braintree/validation_error_spec.rb +19 -0
  62. data/spec/unit/braintree/xml/libxml_spec.rb +51 -0
  63. data/spec/unit/braintree/xml_spec.rb +122 -0
  64. data/spec/unit/spec_helper.rb +1 -0
  65. metadata +118 -0
@@ -0,0 +1,69 @@
1
+ # Portions of this code were copied and modified from Ruby on Rails, released
2
+ # under the MIT license, copyright (c) 2005-2009 David Heinemeier Hansson
3
+ module Braintree
4
+ module Xml
5
+ module Libxml # :nodoc:
6
+ LIB_XML_LIMIT = 30000000
7
+
8
+ def self.parse(xml_string)
9
+ old_keep_blanks_setting = ::LibXML::XML.default_keep_blanks
10
+ ::LibXML::XML.default_keep_blanks = false
11
+ root_node = LibXML::XML::Parser.string(xml_string.strip).parse.root
12
+ _node_to_hash(root_node)
13
+ ensure
14
+ ::LibXML::XML.default_keep_blanks = old_keep_blanks_setting
15
+ end
16
+
17
+ def self._node_to_hash(node, hash = {})
18
+ if node.text?
19
+ raise ::LibXML::XML::Error if node.content.length >= LIB_XML_LIMIT
20
+ hash[CONTENT_ROOT] = node.content
21
+ else
22
+ sub_hash = _build_sub_hash(hash, node.name)
23
+ _attributes_to_hash(node, sub_hash)
24
+ if _array?(node)
25
+ _children_array_to_hash(node, sub_hash)
26
+ else
27
+ _children_to_hash(node, sub_hash)
28
+ end
29
+ end
30
+ hash
31
+ end
32
+
33
+ def self._build_sub_hash(hash, name)
34
+ sub_hash = {}
35
+ if hash[name]
36
+ if !hash[name].kind_of? Array
37
+ hash[name] = [hash[name]]
38
+ end
39
+ hash[name] << sub_hash
40
+ else
41
+ hash[name] = sub_hash
42
+ end
43
+ sub_hash
44
+ end
45
+
46
+ def self._children_to_hash(node, hash={})
47
+ node.each { |child| _node_to_hash(child, hash) }
48
+ _attributes_to_hash(node, hash)
49
+ hash
50
+ end
51
+
52
+ def self._attributes_to_hash(node, hash={})
53
+ node.each_attr { |attr| hash[attr.name] = attr.value }
54
+ hash
55
+ end
56
+
57
+ def self._children_array_to_hash(node, hash={})
58
+ hash[node.child.name] = node.map do |child|
59
+ _children_to_hash(child, {})
60
+ end
61
+ hash
62
+ end
63
+
64
+ def self._array?(node)
65
+ node.child? && node.child.next? && node.child.name == node.child.next.name
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,93 @@
1
+ # Portions of this code were copied and modified from Ruby on Rails, released
2
+ # under the MIT license, copyright (c) 2005-2009 David Heinemeier Hansson
3
+ module Braintree
4
+ module Xml
5
+ CONTENT_ROOT = '__content__'
6
+
7
+ module Parser # :nodoc:
8
+ XML_PARSING = {
9
+ "datetime" => Proc.new { |time| ::Time.parse(time).utc },
10
+ "integer" => Proc.new { |integer| integer.to_i },
11
+ "boolean" => Proc.new { |boolean| %w(1 true).include?(boolean.strip) },
12
+ }
13
+
14
+ def self.hash_from_xml(xml)
15
+ standardized_hash_structure = ::Braintree::Xml::Libxml.parse(xml)
16
+ with_underscores_in_keys = _unrename_keys(standardized_hash_structure)
17
+ typecasted_xml = _typecast_xml_value(with_underscores_in_keys)
18
+ Util.symbolize_keys(typecasted_xml)
19
+ end
20
+
21
+ def self._typecast_xml_value(value)
22
+ case value.class.to_s
23
+ when 'Hash'
24
+ if value['type'] == 'array'
25
+ child_key, entries = value.detect { |k,v| k != 'type' } # child_key is throwaway
26
+ if entries.nil? || (c = value[CONTENT_ROOT] && c.blank?)
27
+ []
28
+ else
29
+ case entries.class.to_s # something weird with classes not matching here. maybe singleton methods breaking is_a?
30
+ when "Array"
31
+ entries.collect { |v| _typecast_xml_value(v) }
32
+ when "Hash"
33
+ [_typecast_xml_value(entries)]
34
+ else
35
+ raise "can't typecast #{entries.inspect}"
36
+ end
37
+ end
38
+ elsif value.has_key?(CONTENT_ROOT)
39
+ content = value[CONTENT_ROOT]
40
+ if parser = XML_PARSING[value["type"]]
41
+ XML_PARSING[value["type"]].call(content)
42
+ else
43
+ content
44
+ end
45
+ elsif value['type'] == 'string' && value['nil'] != 'true'
46
+ ""
47
+ elsif value == {}
48
+ ""
49
+ elsif value.nil? || value['nil'] == 'true'
50
+ nil
51
+ # If the type is the only element which makes it then
52
+ # this still makes the value nil, except if type is
53
+ # a XML node(where type['value'] is a Hash)
54
+ elsif value['type'] && value.size == 1 && !value['type'].is_a?(::Hash)
55
+ raise "is this needed?"
56
+ nil
57
+ else
58
+ xml_value = value.inject({}) do |h,(k,v)|
59
+ h[k] = _typecast_xml_value(v)
60
+ h
61
+ end
62
+ xml_value
63
+ end
64
+ when 'Array'
65
+ value.map! { |i| _typecast_xml_value(i) }
66
+ case value.length
67
+ when 0 then nil
68
+ when 1 then value.first
69
+ else value
70
+ end
71
+ when 'String'
72
+ value
73
+ else
74
+ raise "can't typecast #{value.class.name} - #{value.inspect}"
75
+ end
76
+ end
77
+
78
+ def self._unrename_keys(params)
79
+ case params.class.to_s
80
+ when "Hash"
81
+ params.inject({}) do |h,(k,v)|
82
+ h[k.to_s.tr("-", "_")] = _unrename_keys(v)
83
+ h
84
+ end
85
+ when "Array"
86
+ params.map { |v| _unrename_keys(v) }
87
+ else
88
+ params
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,44 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI
3
+ MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
4
+ FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz
5
+ MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv
6
+ cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN
7
+ AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz
8
+ Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO
9
+ 0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao
10
+ wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj
11
+ 7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS
12
+ 8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT
13
+ BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB
14
+ /zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg
15
+ JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC
16
+ NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3
17
+ 6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/
18
+ 3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm
19
+ D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS
20
+ CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR
21
+ 3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=
22
+ -----END CERTIFICATE-----
23
+ -----BEGIN CERTIFICATE-----
24
+ MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK
25
+ MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
26
+ GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx
27
+ MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg
28
+ Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG
29
+ SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ
30
+ iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa
31
+ /FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ
32
+ jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI
33
+ HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7
34
+ sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w
35
+ gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF
36
+ MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw
37
+ KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG
38
+ AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L
39
+ URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO
40
+ H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm
41
+ I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY
42
+ iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc
43
+ f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW
44
+ -----END CERTIFICATE-----
@@ -0,0 +1,18 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
3
+ IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz
4
+ BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y
5
+ aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG
6
+ 9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy
7
+ NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y
8
+ azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
9
+ YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw
10
+ Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl
11
+ cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY
12
+ dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9
13
+ WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS
14
+ v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v
15
+ UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu
16
+ IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC
17
+ W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd
18
+ -----END CERTIFICATE-----
@@ -0,0 +1,352 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
+
3
+ describe Braintree::Address do
4
+ describe "self.create" do
5
+ it "returns a successful result if valid" do
6
+ customer = Braintree::Customer.create!(:last_name => "Wilson")
7
+ result = Braintree::Address.create(
8
+ :customer_id => customer.id,
9
+ :first_name => "Ben",
10
+ :last_name => "Moore",
11
+ :company => "Moore Co.",
12
+ :street_address => "1811 E Main St",
13
+ :extended_address => "Suite 200",
14
+ :locality => "Chicago",
15
+ :region => "Illinois",
16
+ :postal_code => "60622",
17
+ :country_name => "United States of America"
18
+ )
19
+ result.success?.should == true
20
+ result.address.customer_id.should == customer.id
21
+ result.address.first_name.should == "Ben"
22
+ result.address.last_name.should == "Moore"
23
+ result.address.company.should == "Moore Co."
24
+ result.address.street_address.should == "1811 E Main St"
25
+ result.address.extended_address.should == "Suite 200"
26
+ result.address.locality.should == "Chicago"
27
+ result.address.region.should == "Illinois"
28
+ result.address.postal_code.should == "60622"
29
+ result.address.country_name.should == "United States of America"
30
+ end
31
+
32
+ it "returns an error response if invalid" do
33
+ customer = Braintree::Customer.create!(:last_name => "Wilson")
34
+ result = Braintree::Address.create(
35
+ :customer_id => customer.id,
36
+ :country_name => "United States of Invalid"
37
+ )
38
+ result.success?.should == false
39
+ result.errors.for(:address).on(:country_name)[0].message.should == "Country name is not an accepted country."
40
+ end
41
+
42
+ it "allows -, _, A-Z, a-z, and 0-9 in customer_id without raising an ArgumentError" do
43
+ expect do
44
+ Braintree::Address.create(:customer_id => "hyphen-")
45
+ end.to raise_error(Braintree::NotFoundError)
46
+ expect do
47
+ Braintree::Address.create(:customer_id => "underscore_")
48
+ end.to raise_error(Braintree::NotFoundError)
49
+ expect do
50
+ Braintree::Address.create(:customer_id => "CAPS")
51
+ end.to raise_error(Braintree::NotFoundError)
52
+ end
53
+ end
54
+
55
+ describe "self.create!" do
56
+ it "returns the address if valid" do
57
+ customer = Braintree::Customer.create!(:last_name => "Miller")
58
+ address = Braintree::Address.create!(
59
+ :customer_id => customer.id,
60
+ :street_address => "1812 E Main St",
61
+ :extended_address => "Suite 201",
62
+ :locality => "Bartlett",
63
+ :region => "IL",
64
+ :postal_code => "60623",
65
+ :country_name => "United States of America"
66
+ )
67
+ address.customer_id.should == customer.id
68
+ address.street_address.should == "1812 E Main St"
69
+ address.extended_address.should == "Suite 201"
70
+ address.locality.should == "Bartlett"
71
+ address.region.should == "IL"
72
+ address.postal_code.should == "60623"
73
+ address.country_name.should == "United States of America"
74
+ end
75
+
76
+ it "raises a ValidationsFailed if invalid" do
77
+ customer = Braintree::Customer.create!(:last_name => "Wilson")
78
+ expect do
79
+ Braintree::Address.create!(
80
+ :customer_id => customer.id,
81
+ :country_name => "United States of Invalid"
82
+ )
83
+ end.to raise_error(Braintree::ValidationsFailed)
84
+ end
85
+ end
86
+
87
+ describe "self.delete" do
88
+ it "deletes the address given a customer id and an address id" do
89
+ customer = Braintree::Customer.create!(:last_name => "Wilson")
90
+ address = Braintree::Address.create!(:customer_id => customer.id, :street_address => "123 E Main St")
91
+ Braintree::Address.delete(customer.id, address.id).success?.should == true
92
+ expect do
93
+ Braintree::Address.find(customer.id, address.id)
94
+ end.to raise_error(Braintree::NotFoundError)
95
+ end
96
+
97
+ it "deletes the address given a customer and an address id" do
98
+ customer = Braintree::Customer.create!(:last_name => "Wilson")
99
+ address = Braintree::Address.create!(:customer_id => customer.id, :street_address => "123 E Main St")
100
+ Braintree::Address.delete(customer, address.id).success?.should == true
101
+ expect do
102
+ Braintree::Address.find(customer.id, address.id)
103
+ end.to raise_error(Braintree::NotFoundError)
104
+ end
105
+ end
106
+
107
+ describe "self.find" do
108
+ it "finds the address given a customer and an address id" do
109
+ customer = Braintree::Customer.create!(:last_name => "Wilson")
110
+ address = Braintree::Address.create!(:customer_id => customer.id, :street_address => "123 E Main St")
111
+ Braintree::Address.find(customer, address.id).should == address
112
+ end
113
+
114
+ it "finds the address given a customer id and an address id" do
115
+ customer = Braintree::Customer.create!(:last_name => "Wilson")
116
+ address = Braintree::Address.create!(:customer_id => customer.id, :street_address => "123 E Main St")
117
+ Braintree::Address.find(customer.id, address.id).should == address
118
+ end
119
+
120
+ it "raises a NotFoundError if it cannot be found because of customer id" do
121
+ customer = Braintree::Customer.create!(:last_name => "Wilson")
122
+ address = Braintree::Address.create!(:customer_id => customer.id, :street_address => "123 E Main St")
123
+ expect do
124
+ Braintree::Address.find("invalid", address.id)
125
+ end.to raise_error(
126
+ Braintree::NotFoundError,
127
+ "address for customer \"invalid\" with id #{address.id.inspect} not found")
128
+ end
129
+
130
+ it "raises a NotFoundError if it cannot be found because of address id" do
131
+ customer = Braintree::Customer.create!(:last_name => "Wilson")
132
+ address = Braintree::Address.create!(:customer_id => customer.id, :street_address => "123 E Main St")
133
+ expect do
134
+ Braintree::Address.find(customer, "invalid")
135
+ end.to raise_error(
136
+ Braintree::NotFoundError,
137
+ "address for customer \"#{customer.id}\" with id \"invalid\" not found")
138
+ end
139
+ end
140
+
141
+ describe "self.update" do
142
+ it "raises NotFoundError if the address can't be found" do
143
+ customer = Braintree::Customer.create!(:last_name => "Wilson")
144
+ address = Braintree::Address.create!(:customer_id => customer.id, :street_address => "123 E Main St")
145
+ expect do
146
+ Braintree::Address.update(customer.id, "bad-id", {})
147
+ end.to raise_error(Braintree::NotFoundError)
148
+ end
149
+
150
+ it "returns a success response with the updated address if valid" do
151
+ customer = Braintree::Customer.create!(:last_name => "Miller")
152
+ address = Braintree::Address.create!(
153
+ :customer_id => customer.id,
154
+ :street_address => "1812 E Old St",
155
+ :extended_address => "Suite Old 201",
156
+ :locality => "Old Chicago",
157
+ :region => "IL",
158
+ :postal_code => "60620",
159
+ :country_name => "United States of America"
160
+ )
161
+ result = Braintree::Address.update(
162
+ customer.id,
163
+ address.id,
164
+ :street_address => "123 E New St",
165
+ :extended_address => "New Suite 3",
166
+ :locality => "Chicago",
167
+ :region => "Illinois",
168
+ :postal_code => "60621",
169
+ :country_name => "United States of America"
170
+ )
171
+ result.success?.should == true
172
+ result.address.street_address.should == "123 E New St"
173
+ result.address.extended_address.should == "New Suite 3"
174
+ result.address.locality.should == "Chicago"
175
+ result.address.region.should == "Illinois"
176
+ result.address.postal_code.should == "60621"
177
+ result.address.country_name.should == "United States of America"
178
+ end
179
+
180
+ it "returns an error response if invalid" do
181
+ customer = Braintree::Customer.create!(:last_name => "Miller")
182
+ address = Braintree::Address.create!(
183
+ :customer_id => customer.id,
184
+ :country_name => "United States of America"
185
+ )
186
+ result = Braintree::Address.update(
187
+ customer.id,
188
+ address.id,
189
+ :street_address => "123 E New St",
190
+ :country_name => "United States of Invalid"
191
+ )
192
+ result.success?.should == false
193
+ result.errors.for(:address).on(:country_name)[0].message.should == "Country name is not an accepted country."
194
+ end
195
+ end
196
+
197
+ describe "self.update!" do
198
+ it "raises NotFoundError if the address can't be found" do
199
+ customer = Braintree::Customer.create!(:last_name => "Wilson")
200
+ address = Braintree::Address.create!(:customer_id => customer.id, :street_address => "123 E Main St")
201
+ expect do
202
+ Braintree::Address.update!(customer.id, "bad-id", {})
203
+ end.to raise_error(Braintree::NotFoundError)
204
+ end
205
+
206
+ it "returns the updated address if valid" do
207
+ customer = Braintree::Customer.create!(:last_name => "Miller")
208
+ address = Braintree::Address.create!(
209
+ :customer_id => customer.id,
210
+ :street_address => "1812 E Old St",
211
+ :extended_address => "Suite Old 201",
212
+ :locality => "Old Chicago",
213
+ :region => "IL",
214
+ :postal_code => "60620",
215
+ :country_name => "United States of America"
216
+ )
217
+ updated_address = Braintree::Address.update!(
218
+ customer.id,
219
+ address.id,
220
+ :street_address => "123 E New St",
221
+ :extended_address => "New Suite 3",
222
+ :locality => "Chicago",
223
+ :region => "Illinois",
224
+ :postal_code => "60621",
225
+ :country_name => "United States of America"
226
+ )
227
+ updated_address.should == address
228
+ updated_address.street_address.should == "123 E New St"
229
+ updated_address.extended_address.should == "New Suite 3"
230
+ updated_address.locality.should == "Chicago"
231
+ updated_address.region.should == "Illinois"
232
+ updated_address.postal_code.should == "60621"
233
+ updated_address.country_name.should == "United States of America"
234
+ end
235
+
236
+ it "raises a ValidationsFailed invalid" do
237
+ customer = Braintree::Customer.create!(:last_name => "Miller")
238
+ address = Braintree::Address.create!(
239
+ :customer_id => customer.id,
240
+ :country_name => "United States of America"
241
+ )
242
+ expect do
243
+ Braintree::Address.update!(
244
+ customer.id,
245
+ address.id,
246
+ :street_address => "123 E New St",
247
+ :country_name => "United States of Invalid"
248
+ )
249
+ end.to raise_error(Braintree::ValidationsFailed)
250
+ end
251
+ end
252
+
253
+
254
+ describe "delete" do
255
+ it "deletes the address" do
256
+ customer = Braintree::Customer.create!(:last_name => "Wilson")
257
+ address = Braintree::Address.create!(:customer_id => customer.id, :street_address => "123 E Main St")
258
+ address.delete.success?.should == true
259
+ expect do
260
+ Braintree::Address.find(customer.id, address.id)
261
+ end.to raise_error(Braintree::NotFoundError)
262
+ end
263
+ end
264
+
265
+ describe "update" do
266
+ it "returns a success response and updates the address if valid" do
267
+ customer = Braintree::Customer.create!(:last_name => "Miller")
268
+ address = Braintree::Address.create!(
269
+ :customer_id => customer.id,
270
+ :street_address => "1812 E Old St",
271
+ :extended_address => "Suite Old 201",
272
+ :locality => "Old Chicago",
273
+ :region => "IL",
274
+ :postal_code => "60620",
275
+ :country_name => "United States of America"
276
+ )
277
+ result = address.update(
278
+ :street_address => "123 E New St",
279
+ :extended_address => "New Suite 3",
280
+ :locality => "Chicago",
281
+ :region => "Illinois",
282
+ :postal_code => "60621",
283
+ :country_name => "United States of America"
284
+ )
285
+ result.success?.should == true
286
+ result.address.should == address
287
+ address.street_address.should == "123 E New St"
288
+ address.extended_address.should == "New Suite 3"
289
+ address.locality.should == "Chicago"
290
+ address.region.should == "Illinois"
291
+ address.postal_code.should == "60621"
292
+ address.country_name.should == "United States of America"
293
+ end
294
+
295
+ it "returns an error response if invalid" do
296
+ customer = Braintree::Customer.create!(:last_name => "Miller")
297
+ address = Braintree::Address.create!(
298
+ :customer_id => customer.id,
299
+ :country_name => "United States of America"
300
+ )
301
+ result = address.update(
302
+ :street_address => "123 E New St",
303
+ :country_name => "United States of Invalid"
304
+ )
305
+ result.success?.should == false
306
+ result.errors.for(:address).on(:country_name)[0].message.should == "Country name is not an accepted country."
307
+ end
308
+ end
309
+
310
+ describe "update!" do
311
+ it "returns true and updates the address if valid" do
312
+ customer = Braintree::Customer.create!(:last_name => "Miller")
313
+ address = Braintree::Address.create!(
314
+ :customer_id => customer.id,
315
+ :street_address => "1812 E Old St",
316
+ :extended_address => "Suite Old 201",
317
+ :locality => "Old Chicago",
318
+ :region => "IL",
319
+ :postal_code => "60620",
320
+ :country_name => "United States of America"
321
+ )
322
+ address.update!(
323
+ :street_address => "123 E New St",
324
+ :extended_address => "New Suite 3",
325
+ :locality => "Chicago",
326
+ :region => "Illinois",
327
+ :postal_code => "60621",
328
+ :country_name => "United States of America"
329
+ ).should == address
330
+ address.street_address.should == "123 E New St"
331
+ address.extended_address.should == "New Suite 3"
332
+ address.locality.should == "Chicago"
333
+ address.region.should == "Illinois"
334
+ address.postal_code.should == "60621"
335
+ address.country_name.should == "United States of America"
336
+ end
337
+
338
+ it "raises a ValidationsFailed invalid" do
339
+ customer = Braintree::Customer.create!(:last_name => "Miller")
340
+ address = Braintree::Address.create!(
341
+ :customer_id => customer.id,
342
+ :country_name => "United States of America"
343
+ )
344
+ expect do
345
+ address.update!(
346
+ :street_address => "123 E New St",
347
+ :country_name => "United States of Invalid"
348
+ )
349
+ end.to raise_error(Braintree::ValidationsFailed)
350
+ end
351
+ end
352
+ end