braintree-rails 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. data/Gemfile +10 -0
  2. data/Gemfile.lock +34 -0
  3. data/README.md +2 -0
  4. data/Rakefile +4 -0
  5. data/braintree-rails.gemspec +18 -0
  6. data/lib/braintree-rails.rb +17 -0
  7. data/lib/braintree_rails/address.rb +75 -0
  8. data/lib/braintree_rails/addresses.rb +24 -0
  9. data/lib/braintree_rails/credit_card.rb +67 -0
  10. data/lib/braintree_rails/credit_cards.rb +24 -0
  11. data/lib/braintree_rails/customer.rb +37 -0
  12. data/lib/braintree_rails/exceptions.rb +2 -0
  13. data/lib/braintree_rails/model.rb +192 -0
  14. data/lib/env.rb +3 -0
  15. data/lib/tasks/test.rake +18 -0
  16. data/lib/test_env.rb +4 -0
  17. data/log/braintree_test.log +225696 -0
  18. data/test/config/braintree_auth.yml +4 -0
  19. data/test/config/braintree_auth.yml.example +4 -0
  20. data/test/fixtures/address.xml +19 -0
  21. data/test/fixtures/credit_card.xml +36 -0
  22. data/test/fixtures/credit_card_validation_error.xml +26 -0
  23. data/test/fixtures/customer.xml +90 -0
  24. data/test/integration/braintree_rails/address_integration_test.rb +72 -0
  25. data/test/integration/braintree_rails/credit_card_integration_test.rb +147 -0
  26. data/test/integration/braintree_rails/customer_integration_test.rb +41 -0
  27. data/test/integration/integration_test_helper.rb +13 -0
  28. data/test/test_helper.rb +28 -0
  29. data/test/unit/braintree_rails/address_test.rb +87 -0
  30. data/test/unit/braintree_rails/addresses_test.rb +38 -0
  31. data/test/unit/braintree_rails/credit_card_test.rb +240 -0
  32. data/test/unit/braintree_rails/credit_cards_test.rb +38 -0
  33. data/test/unit/braintree_rails/customer_test.rb +171 -0
  34. data/test/unit/unit_test_helper.rb +3 -0
  35. metadata +176 -0
@@ -0,0 +1,13 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../test_helper'))
2
+ config = File.join(TEST_PATH, 'config/braintree_auth.yml')
3
+ if auth = YAML.load_file(config)
4
+ Braintree::Configuration.environment = :sandbox
5
+ Braintree::Configuration.merchant_id = auth['merchant_id']
6
+ Braintree::Configuration.public_key = auth['public_key']
7
+ Braintree::Configuration.private_key = auth['private_key']
8
+ else
9
+ puts '*' * 80
10
+ puts "You need to provide real credentials in #{config} to run integration tests"
11
+ puts '*' * 80
12
+ exit(0)
13
+ end
@@ -0,0 +1,28 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../lib/test_env'))
2
+
3
+ TEST_PATH = File.expand_path(File.dirname(__FILE__))
4
+ FIXTURE_PATH = File.join(TEST_PATH, 'fixtures')
5
+
6
+ Braintree::Configuration.environment = :sandbox
7
+ Braintree::Configuration.merchant_id = 'merchant_id'
8
+ Braintree::Configuration.public_key = 'public_key'
9
+ Braintree::Configuration.private_key = 'private_key'
10
+ Braintree::Configuration.logger = Logger.new(File.join(ROOT_PATH, 'log/braintree_test.log'))
11
+ BraintreeBaseUri = "https://#{Braintree::Configuration.public_key}:#{Braintree::Configuration.private_key}@#{Braintree::Configuration.environment}.braintreegateway.com/merchants/#{Braintree::Configuration.merchant_id}"
12
+
13
+ MiniTest::Unit::TestCase.class_eval do
14
+ def fixture(name)
15
+ File.read(File.join(FIXTURE_PATH, name)).gzip
16
+ end
17
+
18
+ def stub_braintree_request(method, path, response)
19
+ response = response.reverse_merge(:headers => {'Content-Type' => ['application/xml', 'charset=utf-8'], 'Content-Encoding' => 'gzip'})
20
+ stub_request(method, BraintreeBaseUri+path).to_return(response)
21
+ end
22
+ end
23
+
24
+ String.class_eval do
25
+ def gzip
26
+ Zlib::GzipWriter.wrap(StringIO.new(gzipped = '')) { |gz| gz.write(self); gzipped }
27
+ end
28
+ end
@@ -0,0 +1,87 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../unit_test_helper'))
2
+
3
+ describe BraintreeRails::Address do
4
+ describe '#initialize' do
5
+ before do
6
+ stub_braintree_request(:get, '/customers/customer_id', :body => fixture('customer.xml'))
7
+ end
8
+
9
+ it 'should wrap a Braintree::Address' do
10
+ braintree_address = Braintree::Customer.find('customer_id').addresses.first
11
+ address = BraintreeRails::Address.new(braintree_address)
12
+
13
+ address.persisted?.must_equal true
14
+ BraintreeRails::Address::Attributes.each do |attribute|
15
+ address.send(attribute).must_equal braintree_address.send(attribute)
16
+ end
17
+ end
18
+
19
+ it 'should extract values from hash' do
20
+ address = BraintreeRails::Address.new(:id => 'new_id')
21
+
22
+ address.persisted?.must_equal false
23
+ address.id.must_equal 'new_id'
24
+ end
25
+
26
+ it 'should try to extract value from other types' do
27
+ address = BraintreeRails::Address.new(OpenStruct.new(:id => 'foobar', :first_name => 'Foo', :last_name => 'Bar', :persisted? => true))
28
+
29
+ address.persisted?.must_equal true
30
+ address.id.must_equal 'foobar'
31
+ address.first_name.must_equal 'Foo'
32
+ address.last_name.must_equal 'Bar'
33
+
34
+ address = BraintreeRails::Address.new(Object.new)
35
+ address.persisted?.must_equal false
36
+ end
37
+ end
38
+
39
+ describe 'country_code_alpha2' do
40
+ it 'should always convert to country_code_alpha2' do
41
+ {:country_name => 'United States of America', :country_code_alpha3 => 'USA', :country_code_numeric => '840'}.each_pair do |key, value|
42
+ address = BraintreeRails::Address.new(key => value)
43
+ address.country_code_alpha2.must_equal 'US'
44
+ end
45
+ end
46
+ end
47
+
48
+ describe 'validations' do
49
+ [:first_name, :last_name, :company, :street_address, :extended_address, :locality, :region].each do |attribute|
50
+ it "should validate length of #{attribute}" do
51
+ address = BraintreeRails::Address.new(attribute => 'f')
52
+ address.valid?
53
+ address.errors[attribute].must_be :blank?
54
+
55
+ address = BraintreeRails::Address.new(attribute => 'f' * 255)
56
+ address.valid?
57
+ address.errors[attribute].must_be :blank?
58
+
59
+ address = BraintreeRails::Address.new(attribute => 'foo' * 256)
60
+ address.valid?
61
+ address.errors[attribute].wont_be :blank?
62
+ end
63
+ end
64
+
65
+ [:street_address, :postal_code].each do |attribute|
66
+ it "should validate presence of #{attribute}" do
67
+ address = BraintreeRails::Address.new(attribute => 'foo')
68
+ address.valid?
69
+ address.errors[attribute].must_be :blank?
70
+
71
+ address = BraintreeRails::Address.new({})
72
+ address.valid?
73
+ address.errors[attribute].wont_be :blank?
74
+ end
75
+ end
76
+
77
+ it 'should validate format of postal_code' do
78
+ address = BraintreeRails::Address.new({:postal_code => 'CA 94025'})
79
+ address.valid?
80
+ address.errors[:postal_code].must_be :blank?
81
+
82
+ address = BraintreeRails::Address.new({:postal_code => '^$'})
83
+ address.valid?
84
+ address.errors[:postal_code].wont_be :blank?
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,38 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../unit_test_helper'))
2
+
3
+ describe BraintreeRails::Addresses do
4
+ before do
5
+ stub_braintree_request(:get, '/customers/customer_id', :body => fixture('customer.xml'))
6
+ end
7
+
8
+ describe '#initialize' do
9
+ it 'should wrap an array of Braintree::Address' do
10
+ braintree_customer = Braintree::Customer.find('customer_id')
11
+ braintree_addresses = braintree_customer.addresses
12
+ addresses = BraintreeRails::Addresses.new(braintree_customer, braintree_addresses)
13
+
14
+ addresses.size.must_equal braintree_addresses.size
15
+
16
+ braintree_addresses.each do |braintree_address|
17
+ address = addresses.find(braintree_address.id)
18
+ BraintreeRails::Address::Attributes.each do |attribute|
19
+ address.send(attribute).must_equal braintree_address.send(attribute)
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ describe '#build' do
26
+ it 'should build new Address object with customer_id and params' do
27
+ braintree_customer = Braintree::Customer.find('customer_id')
28
+ braintree_addresses = braintree_customer.addresses
29
+ addresses = BraintreeRails::Addresses.new(braintree_customer, braintree_addresses)
30
+ address = addresses.build({:first_name => 'foo', :last_name => 'bar'})
31
+
32
+ address.persisted?.must_equal false
33
+ address.customer_id.must_equal braintree_customer.id
34
+ address.first_name.must_equal 'foo'
35
+ address.last_name.must_equal 'bar'
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,240 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../unit_test_helper'))
2
+
3
+ describe BraintreeRails::CreditCard do
4
+ before do
5
+ stub_braintree_request(:get, '/payment_methods/credit_card_id', :body => fixture('credit_card.xml'))
6
+ end
7
+
8
+ describe '#initialize' do
9
+ it 'should find credit_card from braintree when given a credit_card id' do
10
+ credit_card = BraintreeRails::CreditCard.new('credit_card_id')
11
+ braintree_credit_card = Braintree::CreditCard.find('credit_card_id')
12
+
13
+ credit_card.persisted?.must_equal true
14
+ BraintreeRails::CreditCard::Attributes.each do |attribute|
15
+ credit_card.send(attribute).must_equal(braintree_credit_card.send(attribute)) if braintree_credit_card.respond_to?(attribute)
16
+ end
17
+ end
18
+
19
+ it 'should wrap a Braintree::CreditCard' do
20
+ braintree_credit_card = Braintree::CreditCard.find('credit_card_id')
21
+ credit_card = BraintreeRails::CreditCard.new(braintree_credit_card)
22
+
23
+ credit_card.persisted?.must_equal true
24
+ BraintreeRails::CreditCard::Attributes.each do |attribute|
25
+ credit_card.send(attribute).must_equal(braintree_credit_card.send(attribute)) if braintree_credit_card.respond_to?(attribute)
26
+ end
27
+ end
28
+
29
+ it 'should extract values from hash' do
30
+ credit_card = BraintreeRails::CreditCard.new(:token => 'new_id')
31
+
32
+ credit_card.persisted?.must_equal false
33
+ credit_card.token.must_equal 'new_id'
34
+ end
35
+
36
+ it 'should try to extract value from other types' do
37
+ credit_card = BraintreeRails::CreditCard.new(OpenStruct.new(:token => 'foobar', :cardholder_name => 'Foo Bar', :persisted? => true))
38
+
39
+ credit_card.persisted?.must_equal true
40
+ credit_card.token.must_equal 'foobar'
41
+ credit_card.cardholder_name.must_equal 'Foo Bar'
42
+
43
+ credit_card = BraintreeRails::CreditCard.new(OpenStruct.new({}))
44
+ credit_card.persisted?.must_equal false
45
+ end
46
+ end
47
+
48
+ describe '#billing_address' do
49
+ it 'should wrap billing_address with Address object' do
50
+ credit_card = BraintreeRails::CreditCard.new(OpenStruct.new(:billing_address => nil))
51
+ credit_card.billing_address.class.ancestors.must_include BraintreeRails::Address
52
+
53
+ credit_card = BraintreeRails::CreditCard.new(OpenStruct.new(:billing_address => {}))
54
+ credit_card.billing_address.class.ancestors.must_include BraintreeRails::Address
55
+
56
+ credit_card.billing_address= BraintreeRails::Address.new({})
57
+ credit_card.billing_address.class.ancestors.must_include BraintreeRails::Address
58
+ end
59
+ end
60
+
61
+ describe 'validations' do
62
+ it 'should validate precence of customer_id if new_record?' do
63
+ credit_card = BraintreeRails::CreditCard.new({})
64
+ credit_card.valid?
65
+ credit_card.errors[:customer_id].wont_be :blank?
66
+
67
+ credit_card = BraintreeRails::CreditCard.new({:customer_id => 'foo'})
68
+ credit_card.valid?
69
+ credit_card.errors[:customer_id].must_be :blank?
70
+ end
71
+
72
+ it 'should validate length of customer_id' do
73
+ credit_card = BraintreeRails::CreditCard.new({:customer_id => 'foo' * 13})
74
+ credit_card.valid?
75
+ credit_card.errors[:customer_id].wont_be :blank?
76
+
77
+ credit_card = BraintreeRails::CreditCard.new({:customer_id => 'foo'})
78
+ credit_card.valid?
79
+ credit_card.errors[:customer_id].must_be :blank?
80
+
81
+ credit_card = BraintreeRails::CreditCard.new({:customer_id => 'foo' * 12})
82
+ credit_card.valid?
83
+ credit_card.errors[:customer_id].must_be :blank?
84
+ end
85
+
86
+ it 'should validate precence of number if new_record?' do
87
+ credit_card = BraintreeRails::CreditCard.new({})
88
+ credit_card.valid?
89
+ credit_card.errors[:number].wont_be :blank?
90
+
91
+ credit_card = BraintreeRails::CreditCard.new({:number => '4111111111111'})
92
+ credit_card.valid?
93
+ credit_card.errors[:number].must_be :blank?
94
+ end
95
+
96
+ it 'should validate numericality of number' do
97
+ credit_card = BraintreeRails::CreditCard.new({:number => 'foobar'})
98
+ credit_card.valid?
99
+ credit_card.errors[:number].wont_be :blank?
100
+
101
+ credit_card = BraintreeRails::CreditCard.new({:number => '4111111111111'})
102
+ credit_card.valid?
103
+ credit_card.errors[:number].must_be :blank?
104
+ end
105
+
106
+ it 'should validate length of number' do
107
+ credit_card = BraintreeRails::CreditCard.new({:number => '1'})
108
+ credit_card.valid?
109
+ credit_card.errors[:number].wont_be :blank?
110
+
111
+ credit_card = BraintreeRails::CreditCard.new({:number => '1' * 20})
112
+ credit_card.valid?
113
+ credit_card.errors[:number].wont_be :blank?
114
+
115
+ credit_card = BraintreeRails::CreditCard.new({:number => '1' * 12})
116
+ credit_card.valid?
117
+ credit_card.errors[:number].must_be :blank?
118
+
119
+ credit_card = BraintreeRails::CreditCard.new({:number => '1' * 19})
120
+ credit_card.valid?
121
+ credit_card.errors[:number].must_be :blank?
122
+ end
123
+
124
+ it 'should validate precence of cvv' do
125
+ credit_card = BraintreeRails::CreditCard.new({})
126
+ credit_card.valid?
127
+ credit_card.errors[:cvv].wont_be :blank?
128
+
129
+ credit_card = BraintreeRails::CreditCard.new({:cvv => '111'})
130
+ credit_card.valid?
131
+ credit_card.errors[:cvv].must_be :blank?
132
+ end
133
+
134
+ it 'should validate numericality of cvv' do
135
+ credit_card = BraintreeRails::CreditCard.new({:cvv => 'foo'})
136
+ credit_card.valid?
137
+ credit_card.errors[:cvv].wont_be :blank?
138
+
139
+ credit_card = BraintreeRails::CreditCard.new({:cvv => '111'})
140
+ credit_card.valid?
141
+ credit_card.errors[:cvv].must_be :blank?
142
+ end
143
+
144
+ it 'should validate length of cvv' do
145
+ credit_card = BraintreeRails::CreditCard.new({:cvv => '1'})
146
+ credit_card.valid?
147
+ credit_card.errors[:cvv].wont_be :blank?
148
+
149
+ credit_card = BraintreeRails::CreditCard.new({:cvv => '1' * 5})
150
+ credit_card.valid?
151
+ credit_card.errors[:cvv].wont_be :blank?
152
+
153
+ credit_card = BraintreeRails::CreditCard.new({:cvv => '111'})
154
+ credit_card.valid?
155
+ credit_card.errors[:cvv].must_be :blank?
156
+
157
+ credit_card = BraintreeRails::CreditCard.new({:cvv => '1111'})
158
+ credit_card.valid?
159
+ credit_card.errors[:cvv].must_be :blank?
160
+ end
161
+
162
+ it 'should validate length of cardholder_name' do
163
+ credit_card = BraintreeRails::CreditCard.new({:cardholder_name => 'f' * 256})
164
+ credit_card.valid?
165
+ credit_card.errors[:cardholder_name].wont_be :blank?
166
+
167
+ credit_card = BraintreeRails::CreditCard.new({:cardholder_name => 'f'})
168
+ credit_card.valid?
169
+ credit_card.errors[:cardholder_name].must_be :blank?
170
+
171
+ credit_card = BraintreeRails::CreditCard.new({:cardholder_name => 'f' * 255})
172
+ credit_card.valid?
173
+ credit_card.errors[:cardholder_name].must_be :blank?
174
+ end
175
+
176
+ it 'should validate expiration month' do
177
+ credit_card = BraintreeRails::CreditCard.new({})
178
+ credit_card.valid?
179
+ credit_card.errors[:expiration_month].wont_be :blank?
180
+
181
+ credit_card = BraintreeRails::CreditCard.new({:expiration_month => 0})
182
+ credit_card.valid?
183
+ credit_card.errors[:expiration_month].wont_be :blank?
184
+
185
+ credit_card = BraintreeRails::CreditCard.new({:expiration_month => 13})
186
+ credit_card.valid?
187
+ credit_card.errors[:expiration_month].wont_be :blank?
188
+
189
+ credit_card = BraintreeRails::CreditCard.new({:expiration_month => 1})
190
+ credit_card.valid?
191
+ credit_card.errors[:expiration_month].must_be :blank?
192
+
193
+ credit_card = BraintreeRails::CreditCard.new({:expiration_month => '12'})
194
+ credit_card.valid?
195
+ credit_card.errors[:expiration_month].must_be :blank?
196
+ end
197
+
198
+ it 'should validate expiration year' do
199
+ credit_card = BraintreeRails::CreditCard.new({})
200
+ credit_card.valid?
201
+ credit_card.errors[:expiration_year].wont_be :blank?
202
+
203
+ credit_card = BraintreeRails::CreditCard.new({:expiration_year => 1975})
204
+ credit_card.valid?
205
+ credit_card.errors[:expiration_year].wont_be :blank?
206
+
207
+ credit_card = BraintreeRails::CreditCard.new({:expiration_year => 2201})
208
+ credit_card.valid?
209
+ credit_card.errors[:expiration_year].wont_be :blank?
210
+
211
+ credit_card = BraintreeRails::CreditCard.new({:expiration_year => 1976})
212
+ credit_card.valid?
213
+ credit_card.errors[:expiration_year].must_be :blank?
214
+
215
+ credit_card = BraintreeRails::CreditCard.new({:expiration_year => '2200'})
216
+ credit_card.valid?
217
+ credit_card.errors[:expiration_year].must_be :blank?
218
+ end
219
+
220
+ it 'should validate billing_address' do
221
+ credit_card = BraintreeRails::CreditCard.new({:billing_address => OpenStruct.new(:valid? => false)})
222
+ credit_card.valid?
223
+ credit_card.errors[:billing_address].wont_be :blank?
224
+
225
+ braintree_credit_card = Braintree::CreditCard.find('credit_card_id')
226
+ credit_card = BraintreeRails::CreditCard.new(:billing_address => braintree_credit_card.billing_address)
227
+ credit_card.valid?
228
+ credit_card.errors[:billing_address].must_be :blank?
229
+ end
230
+ end
231
+
232
+ describe 'persistence' do
233
+ it 'should add validation errors returned from Braintree' do
234
+ stub_braintree_request(:put, '/payment_methods/credit_card_id', :status => 422, :body => fixture('credit_card_validation_error.xml'))
235
+ credit_card = BraintreeRails::CreditCard.new('credit_card_id')
236
+ credit_card.update_attributes(:number => '1' * 15, :cvv => '111')
237
+ credit_card.errors[:number].wont_be :blank?
238
+ end
239
+ end
240
+ end
@@ -0,0 +1,38 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../unit_test_helper'))
2
+
3
+ describe BraintreeRails::CreditCards do
4
+ before do
5
+ stub_braintree_request(:get, '/customers/customer_id', :body => fixture('customer.xml'))
6
+ end
7
+
8
+ describe '#initialize' do
9
+ it 'should wrap an array of Braintree::CreditCard' do
10
+ braintree_customer = Braintree::Customer.find('customer_id')
11
+ braintree_credit_cards = braintree_customer.credit_cards
12
+ credit_cards = BraintreeRails::CreditCards.new(braintree_customer, braintree_credit_cards)
13
+
14
+ credit_cards.size.must_equal braintree_credit_cards.size
15
+
16
+ braintree_credit_cards.each do |braintree_credit_card|
17
+ credit_card = credit_cards.find(braintree_credit_card.token)
18
+ BraintreeRails::CreditCard::Attributes.each do |attribute|
19
+ credit_card.send(attribute).must_equal braintree_credit_card.send(attribute) if braintree_credit_card.respond_to?(attribute)
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ describe '#build' do
26
+ it 'should build new CreditCard object with customer_id and params' do
27
+ braintree_customer = Braintree::Customer.find('customer_id')
28
+ braintree_credit_cards = braintree_customer.credit_cards
29
+ credit_cards = BraintreeRails::CreditCards.new(braintree_customer, braintree_credit_cards)
30
+ credit_card = credit_cards.build({:first_name => 'foo', :last_name => 'bar'})
31
+
32
+ credit_card.persisted?.must_equal false
33
+ credit_card.customer_id.must_equal braintree_customer.id
34
+ credit_card.first_name.must_equal 'foo'
35
+ credit_card.last_name.must_equal 'bar'
36
+ end
37
+ end
38
+ end