braintree 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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