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,664 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
+
3
+ describe Braintree::Customer do
4
+ describe "self.all" do
5
+ it "returns page 1 if page isn't specified" do
6
+ first_page = Braintree::Customer.all
7
+ first_page.current_page_number.should == 1
8
+ end
9
+
10
+ it "can get the next_page" do
11
+ first_page = Braintree::Customer.all
12
+ first_page.current_page_number.should == 1
13
+ second_page = first_page.next_page
14
+ second_page.current_page_number.should == 2
15
+ end
16
+ end
17
+
18
+ describe "self.delete" do
19
+ it "deletes the customer with the given id" do
20
+ create_result = Braintree::Customer.create(
21
+ :first_name => "Joe",
22
+ :last_name => "Cool"
23
+ )
24
+ create_result.success?.should == true
25
+ customer = create_result.customer
26
+
27
+ delete_result = Braintree::Customer.delete(customer.id)
28
+ delete_result.success?.should == true
29
+ expect do
30
+ Braintree::Customer.find(customer.id)
31
+ end.to raise_error(Braintree::NotFoundError)
32
+ end
33
+ end
34
+
35
+ describe "self.create" do
36
+ it "returns a successful result if successful" do
37
+ result = Braintree::Customer.create(
38
+ :first_name => "Bill",
39
+ :last_name => "Gates",
40
+ :company => "Microsoft",
41
+ :email => "bill@microsoft.com",
42
+ :phone => "312.555.1234",
43
+ :fax => "614.555.5678",
44
+ :website => "www.microsoft.com"
45
+ )
46
+ result.success?.should == true
47
+ result.customer.id.should =~ /^\d{6}$/
48
+ result.customer.first_name.should == "Bill"
49
+ result.customer.last_name.should == "Gates"
50
+ result.customer.company.should == "Microsoft"
51
+ result.customer.email.should == "bill@microsoft.com"
52
+ result.customer.phone.should == "312.555.1234"
53
+ result.customer.fax.should == "614.555.5678"
54
+ result.customer.website.should == "www.microsoft.com"
55
+ result.customer.created_at.between?(Time.now - 10, Time.now).should == true
56
+ result.customer.updated_at.between?(Time.now - 10, Time.now).should == true
57
+ end
58
+
59
+ it "can create without any attributes" do
60
+ result = Braintree::Customer.create
61
+ result.success?.should == true
62
+ end
63
+
64
+ it "returns an error response if invalid" do
65
+ result = Braintree::Customer.create(
66
+ :email => "@invalid.com"
67
+ )
68
+ result.success?.should == false
69
+ result.errors.for(:customer).on(:email)[0].message.should == "Email is an invalid format."
70
+ end
71
+
72
+ it "can create a customer and a payment method at the same time" do
73
+ result = Braintree::Customer.create(
74
+ :first_name => "Mike",
75
+ :last_name => "Jones",
76
+ :credit_card => {
77
+ :number => Braintree::Test::CreditCardNumbers::MasterCard,
78
+ :expiration_date => "05/2010",
79
+ :cvv => "100"
80
+ }
81
+ )
82
+ result.success?.should == true
83
+ result.customer.first_name.should == "Mike"
84
+ result.customer.last_name.should == "Jones"
85
+ result.customer.credit_cards[0].bin.should == Braintree::Test::CreditCardNumbers::MasterCard[0, 6]
86
+ result.customer.credit_cards[0].last_4.should == Braintree::Test::CreditCardNumbers::MasterCard[-4..-1]
87
+ result.customer.credit_cards[0].expiration_date.should == "05/2010"
88
+ end
89
+
90
+ it "verifies the card if credit_card[options][verify_card]=true" do
91
+ result = Braintree::Customer.create(
92
+ :first_name => "Mike",
93
+ :last_name => "Jones",
94
+ :credit_card => {
95
+ :number => Braintree::Test::CreditCardNumbers::FailsSandboxVerification::MasterCard,
96
+ :expiration_date => "05/2010",
97
+ :options => {:verify_card => true}
98
+ }
99
+ )
100
+ result.success?.should == false
101
+ result.credit_card_verification.status.should == "processor_declined"
102
+ end
103
+
104
+ it "can create a customer, payment method, and billing address at the same time" do
105
+ result = Braintree::Customer.create(
106
+ :first_name => "Mike",
107
+ :last_name => "Jones",
108
+ :credit_card => {
109
+ :number => Braintree::Test::CreditCardNumbers::MasterCard,
110
+ :expiration_date => "05/2010",
111
+ :billing_address => {
112
+ :street_address => "1 E Main St",
113
+ :extended_address => "Suite 3",
114
+ :locality => "Chicago",
115
+ :region => "Illinois",
116
+ :postal_code => "60622",
117
+ :country_name => "United States of America"
118
+ }
119
+ }
120
+ )
121
+ result.success?.should == true
122
+ result.customer.first_name.should == "Mike"
123
+ result.customer.last_name.should == "Jones"
124
+ result.customer.credit_cards[0].bin.should == Braintree::Test::CreditCardNumbers::MasterCard[0, 6]
125
+ result.customer.credit_cards[0].last_4.should == Braintree::Test::CreditCardNumbers::MasterCard[-4..-1]
126
+ result.customer.credit_cards[0].expiration_date.should == "05/2010"
127
+ result.customer.credit_cards[0].billing_address.id.should == result.customer.addresses[0].id
128
+ result.customer.addresses[0].id.should =~ /\w+/
129
+ result.customer.addresses[0].street_address.should == "1 E Main St"
130
+ result.customer.addresses[0].extended_address.should == "Suite 3"
131
+ result.customer.addresses[0].locality.should == "Chicago"
132
+ result.customer.addresses[0].region.should == "Illinois"
133
+ result.customer.addresses[0].postal_code.should == "60622"
134
+ result.customer.addresses[0].country_name.should == "United States of America"
135
+ end
136
+
137
+ it "returns nested errors if credit card and/or billing address are invalid" do
138
+ result = Braintree::Customer.create(
139
+ :email => "invalid",
140
+ :credit_card => {
141
+ :number => "invalidnumber",
142
+ :billing_address => {
143
+ :country_name => "invalid"
144
+ }
145
+ }
146
+ )
147
+ result.success?.should == false
148
+ result.errors.for(:customer).on(:email)[0].message.should == "Email is an invalid format."
149
+ result.errors.for(:customer).for(:credit_card).on(:number)[0].message.should == "Credit card number is invalid."
150
+ result.errors.for(:customer).for(:credit_card).for(:billing_address).on(:country_name)[0].message.should == "Country name is not an accepted country."
151
+ end
152
+ end
153
+
154
+ describe "self.create!" do
155
+ it "returns the customer if successful" do
156
+ customer = Braintree::Customer.create!(
157
+ :first_name => "Jim",
158
+ :last_name => "Smith"
159
+ )
160
+ customer.id.should =~ /\d+/
161
+ customer.first_name.should == "Jim"
162
+ customer.last_name.should == "Smith"
163
+ end
164
+
165
+ it "can create without any attributes" do
166
+ customer = Braintree::Customer.create!
167
+ customer.id.should =~ /\d+/
168
+ end
169
+
170
+ it "raises an exception if not successful" do
171
+ expect do
172
+ Braintree::Customer.create!(:email => "@foo.com")
173
+ end.to raise_error(Braintree::ValidationsFailed)
174
+ end
175
+ end
176
+
177
+ describe "self.credit" do
178
+ it "creates a credit transaction for given customer id, returning a result object" do
179
+ customer = Braintree::Customer.create!(
180
+ :credit_card => {
181
+ :number => Braintree::Test::CreditCardNumbers::Visa,
182
+ :expiration_date => "05/2010"
183
+ }
184
+ )
185
+ result = Braintree::Customer.credit(customer.id, :amount => "100.00")
186
+ result.success?.should == true
187
+ result.transaction.amount.should == "100.00"
188
+ result.transaction.type.should == "credit"
189
+ result.transaction.customer_details.id.should == customer.id
190
+ result.transaction.credit_card_details.token.should == customer.credit_cards[0].token
191
+ result.transaction.credit_card_details.bin.should == Braintree::Test::CreditCardNumbers::Visa[0, 6]
192
+ result.transaction.credit_card_details.last_4.should == Braintree::Test::CreditCardNumbers::Visa[-4..-1]
193
+ result.transaction.credit_card_details.expiration_date.should == "05/2010"
194
+ end
195
+ end
196
+
197
+ describe "self.credit!" do
198
+ it "creates a credit transaction for given customer id, returning a result object" do
199
+ customer = Braintree::Customer.create!(
200
+ :credit_card => {
201
+ :number => Braintree::Test::CreditCardNumbers::Visa,
202
+ :expiration_date => "05/2010"
203
+ }
204
+ )
205
+ transaction = Braintree::Customer.credit!(customer.id, :amount => "100.00")
206
+ transaction.amount.should == "100.00"
207
+ transaction.type.should == "credit"
208
+ transaction.customer_details.id.should == customer.id
209
+ transaction.credit_card_details.token.should == customer.credit_cards[0].token
210
+ transaction.credit_card_details.bin.should == Braintree::Test::CreditCardNumbers::Visa[0, 6]
211
+ transaction.credit_card_details.last_4.should == Braintree::Test::CreditCardNumbers::Visa[-4..-1]
212
+ transaction.credit_card_details.expiration_date.should == "05/2010"
213
+ end
214
+ end
215
+
216
+ describe "self.sale" do
217
+ it "creates a sale transaction for given customer id, returning a result object" do
218
+ customer = Braintree::Customer.create!(
219
+ :credit_card => {
220
+ :number => Braintree::Test::CreditCardNumbers::Visa,
221
+ :expiration_date => "05/2010"
222
+ }
223
+ )
224
+ result = Braintree::Customer.sale(customer.id, :amount => "100.00")
225
+ result.success?.should == true
226
+ result.transaction.amount.should == "100.00"
227
+ result.transaction.type.should == "sale"
228
+ result.transaction.customer_details.id.should == customer.id
229
+ result.transaction.credit_card_details.token.should == customer.credit_cards[0].token
230
+ result.transaction.credit_card_details.bin.should == Braintree::Test::CreditCardNumbers::Visa[0, 6]
231
+ result.transaction.credit_card_details.last_4.should == Braintree::Test::CreditCardNumbers::Visa[-4..-1]
232
+ result.transaction.credit_card_details.expiration_date.should == "05/2010"
233
+ end
234
+ end
235
+
236
+ describe "self.sale!" do
237
+ it "creates a sale transaction for given customer id, returning the transaction" do
238
+ customer = Braintree::Customer.create!(
239
+ :credit_card => {
240
+ :number => Braintree::Test::CreditCardNumbers::Visa,
241
+ :expiration_date => "05/2010"
242
+ }
243
+ )
244
+ transaction = Braintree::Customer.sale!(customer.id, :amount => "100.00")
245
+ transaction.amount.should == "100.00"
246
+ transaction.type.should == "sale"
247
+ transaction.customer_details.id.should == customer.id
248
+ transaction.credit_card_details.token.should == customer.credit_cards[0].token
249
+ transaction.credit_card_details.bin.should == Braintree::Test::CreditCardNumbers::Visa[0, 6]
250
+ transaction.credit_card_details.last_4.should == Braintree::Test::CreditCardNumbers::Visa[-4..-1]
251
+ transaction.credit_card_details.expiration_date.should == "05/2010"
252
+ end
253
+ end
254
+
255
+
256
+ describe "sale" do
257
+ it "creates a sale transaction using the customer, returning a result object" do
258
+ customer = Braintree::Customer.create!(
259
+ :credit_card => {
260
+ :number => Braintree::Test::CreditCardNumbers::Visa,
261
+ :expiration_date => "05/2010"
262
+ }
263
+ )
264
+ result = customer.sale(
265
+ :amount => "100.00"
266
+ )
267
+ result.success?.should == true
268
+ result.transaction.amount.should == "100.00"
269
+ result.transaction.type.should == "sale"
270
+ result.transaction.customer_details.id.should == customer.id
271
+ result.transaction.credit_card_details.token.should == customer.credit_cards[0].token
272
+ result.transaction.credit_card_details.bin.should == Braintree::Test::CreditCardNumbers::Visa[0, 6]
273
+ result.transaction.credit_card_details.last_4.should == Braintree::Test::CreditCardNumbers::Visa[-4..-1]
274
+ result.transaction.credit_card_details.expiration_date.should == "05/2010"
275
+ end
276
+ end
277
+
278
+ describe "sale!" do
279
+ it "returns the created sale tranaction if valid" do
280
+ customer = Braintree::Customer.create!(
281
+ :credit_card => {
282
+ :number => Braintree::Test::CreditCardNumbers::Visa,
283
+ :expiration_date => "05/2010"
284
+ }
285
+ )
286
+ transaction = customer.sale!(:amount => "100.00")
287
+ transaction.amount.should == "100.00"
288
+ transaction.type.should == "sale"
289
+ transaction.customer_details.id.should == customer.id
290
+ transaction.credit_card_details.token.should == customer.credit_cards[0].token
291
+ transaction.credit_card_details.bin.should == Braintree::Test::CreditCardNumbers::Visa[0, 6]
292
+ transaction.credit_card_details.last_4.should == Braintree::Test::CreditCardNumbers::Visa[-4..-1]
293
+ transaction.credit_card_details.expiration_date.should == "05/2010"
294
+ end
295
+ end
296
+
297
+ describe "transactions" do
298
+ it "finds transactions for the customer" do
299
+ customer = Braintree::Customer.create!(
300
+ :credit_card => {
301
+ :number => Braintree::Test::CreditCardNumbers::Visa,
302
+ :expiration_date => "05/2010"
303
+ }
304
+ )
305
+ transaction = customer.sale!(:amount => "100.00")
306
+ collection = customer.transactions
307
+ collection.current_page_number.should == 1
308
+ collection.total_items.should == 1
309
+ collection[0].should == transaction
310
+ end
311
+ end
312
+
313
+ describe "credit" do
314
+ it "creates a credit transaction using the customer, returning a result object" do
315
+ customer = Braintree::Customer.create!(
316
+ :credit_card => {
317
+ :number => Braintree::Test::CreditCardNumbers::Visa,
318
+ :expiration_date => "05/2010"
319
+ }
320
+ )
321
+ result = customer.credit(
322
+ :amount => "100.00"
323
+ )
324
+ result.success?.should == true
325
+ result.transaction.amount.should == "100.00"
326
+ result.transaction.type.should == "credit"
327
+ result.transaction.customer_details.id.should == customer.id
328
+ result.transaction.credit_card_details.token.should == customer.credit_cards[0].token
329
+ result.transaction.credit_card_details.bin.should == Braintree::Test::CreditCardNumbers::Visa[0, 6]
330
+ result.transaction.credit_card_details.last_4.should == Braintree::Test::CreditCardNumbers::Visa[-4..-1]
331
+ result.transaction.credit_card_details.expiration_date.should == "05/2010"
332
+ end
333
+ end
334
+
335
+ describe "credit!" do
336
+ it "returns the created credit tranaction if valid" do
337
+ customer = Braintree::Customer.create!(
338
+ :credit_card => {
339
+ :number => Braintree::Test::CreditCardNumbers::Visa,
340
+ :expiration_date => "05/2010"
341
+ }
342
+ )
343
+ transaction = customer.credit!(:amount => "100.00")
344
+ transaction.amount.should == "100.00"
345
+ transaction.type.should == "credit"
346
+ transaction.customer_details.id.should == customer.id
347
+ transaction.credit_card_details.token.should == customer.credit_cards[0].token
348
+ transaction.credit_card_details.bin.should == Braintree::Test::CreditCardNumbers::Visa[0, 6]
349
+ transaction.credit_card_details.last_4.should == Braintree::Test::CreditCardNumbers::Visa[-4..-1]
350
+ transaction.credit_card_details.expiration_date.should == "05/2010"
351
+ end
352
+ end
353
+
354
+ describe "create_from_transparent_redirect" do
355
+ it "returns a successful result if successful" do
356
+ params = {
357
+ :customer => {
358
+ :first_name => "John",
359
+ :last_name => "Doe",
360
+ :company => "Doe Co",
361
+ :email => "john@doe.com",
362
+ :phone => "312.555.2323",
363
+ :fax => "614.555.5656",
364
+ :website => "www.johndoe.com"
365
+ }
366
+ }
367
+ query_string_response = create_customer_via_tr(params)
368
+ result = Braintree::Customer.create_from_transparent_redirect(query_string_response)
369
+ result.success?.should == true
370
+ customer = result.customer
371
+ customer.first_name.should == "John"
372
+ customer.last_name.should == "Doe"
373
+ customer.company.should == "Doe Co"
374
+ customer.email.should == "john@doe.com"
375
+ customer.phone.should == "312.555.2323"
376
+ customer.fax.should == "614.555.5656"
377
+ customer.website.should == "www.johndoe.com"
378
+ end
379
+
380
+ it "can pass any attribute through tr_data" do
381
+ customer_id = "customer_#{rand(1_000_000)}"
382
+ tr_data_params = {
383
+ :customer => {
384
+ :id => customer_id,
385
+ :first_name => "John",
386
+ :last_name => "Doe",
387
+ :company => "Doe Co",
388
+ :email => "john@doe.com",
389
+ :phone => "312.555.2323",
390
+ :fax => "614.555.5656",
391
+ :website => "www.johndoe.com"
392
+ }
393
+ }
394
+ query_string_response = create_customer_via_tr({}, tr_data_params)
395
+ result = Braintree::Customer.create_from_transparent_redirect(query_string_response)
396
+ result.success?.should == true
397
+ customer = result.customer
398
+ customer.id.should == customer_id
399
+ customer.first_name.should == "John"
400
+ customer.last_name.should == "Doe"
401
+ customer.company.should == "Doe Co"
402
+ customer.email.should == "john@doe.com"
403
+ customer.phone.should == "312.555.2323"
404
+ customer.fax.should == "614.555.5656"
405
+ customer.website.should == "www.johndoe.com"
406
+ end
407
+ end
408
+
409
+ describe "delete" do
410
+ it "deletes the customer" do
411
+ result = Braintree::Customer.create(
412
+ :first_name => "Joe",
413
+ :last_name => "Cool"
414
+ )
415
+ result.success?.should == true
416
+
417
+ customer = result.customer
418
+ customer.delete.success?.should == true
419
+ expect do
420
+ Braintree::Customer.find(customer.id)
421
+ end.to raise_error(Braintree::NotFoundError)
422
+ end
423
+ end
424
+
425
+
426
+ describe "self.find" do
427
+ it "finds the customer with the given id" do
428
+ result = Braintree::Customer.create(
429
+ :first_name => "Joe",
430
+ :last_name => "Cool"
431
+ )
432
+ result.success?.should == true
433
+
434
+ customer = Braintree::Customer.find(result.customer.id)
435
+ customer.id.should == result.customer.id
436
+ customer.first_name.should == "Joe"
437
+ customer.last_name.should == "Cool"
438
+ end
439
+
440
+ it "raises a NotFoundError exception if customer cannot be found" do
441
+ expect do
442
+ Braintree::Customer.find("invalid-id")
443
+ end.to raise_error(Braintree::NotFoundError, 'customer with id "invalid-id" not found')
444
+ end
445
+ end
446
+
447
+ describe "self.update" do
448
+ it "updates the customer with the given id if successful" do
449
+ customer = Braintree::Customer.create!(
450
+ :first_name => "Joe",
451
+ :last_name => "Cool"
452
+ )
453
+ result = Braintree::Customer.update(
454
+ customer.id,
455
+ :first_name => "Mr. Joe",
456
+ :last_name => "Super Cool"
457
+ )
458
+ result.success?.should == true
459
+ result.customer.id.should == customer.id
460
+ result.customer.first_name.should == "Mr. Joe"
461
+ result.customer.last_name.should == "Super Cool"
462
+ end
463
+
464
+ it "returns an error response if invalid" do
465
+ customer = Braintree::Customer.create!(:email => "valid@email.com")
466
+ result = Braintree::Customer.update(
467
+ customer.id,
468
+ :email => "@invalid.com"
469
+ )
470
+ result.success?.should == false
471
+ result.errors.for(:customer).on(:email)[0].message.should == "Email is an invalid format."
472
+ end
473
+ end
474
+
475
+ describe "self.update!" do
476
+ it "returns the updated customer if successful" do
477
+ customer = Braintree::Customer.create!(
478
+ :first_name => "Joe",
479
+ :last_name => "Cool"
480
+ )
481
+ updated_customer = Braintree::Customer.update!(
482
+ customer.id,
483
+ :first_name => "Mr. Joe",
484
+ :last_name => "Super Cool"
485
+ )
486
+ updated_customer.first_name.should == "Mr. Joe"
487
+ updated_customer.last_name.should == "Super Cool"
488
+ updated_customer.updated_at.between?(Time.now - 5, Time.now).should == true
489
+ end
490
+
491
+ it "raises an error if unsuccessful" do
492
+ customer = Braintree::Customer.create!(:email => "valid@email.com")
493
+ expect do
494
+ Braintree::Customer.update!(customer.id, :email => "@invalid.com")
495
+ end.to raise_error(Braintree::ValidationsFailed)
496
+ end
497
+ end
498
+
499
+ describe "update" do
500
+ it "updates the customer" do
501
+ customer = Braintree::Customer.create!(
502
+ :first_name => "Joe",
503
+ :last_name => "Cool"
504
+ )
505
+ update_result = customer.update(
506
+ :first_name => "Mr. Joe",
507
+ :last_name => "Super Cool"
508
+ )
509
+ update_result.success?.should == true
510
+ update_result.customer.should == customer
511
+ updated_customer = update_result.customer
512
+ updated_customer.first_name.should == "Mr. Joe"
513
+ updated_customer.last_name.should == "Super Cool"
514
+ end
515
+
516
+ it "returns an error response if invalid" do
517
+ customer = Braintree::Customer.create!(
518
+ :email => "valid@email.com"
519
+ )
520
+ result = customer.update(
521
+ :email => "@invalid.com"
522
+ )
523
+ result.success?.should == false
524
+ result.errors.for(:customer).on(:email)[0].message.should == "Email is an invalid format."
525
+ end
526
+ end
527
+
528
+ describe "update!" do
529
+ it "returns the customer and updates the customer if successful" do
530
+ customer = Braintree::Customer.create!(
531
+ :first_name => "Joe",
532
+ :last_name => "Cool"
533
+ )
534
+ customer.update!(
535
+ :first_name => "Mr. Joe",
536
+ :last_name => "Super Cool"
537
+ ).should == customer
538
+ customer.first_name.should == "Mr. Joe"
539
+ customer.last_name.should == "Super Cool"
540
+ customer.updated_at.between?(Time.now - 5, Time.now).should == true
541
+ end
542
+
543
+ it "raises an error if unsuccessful" do
544
+ customer = Braintree::Customer.create!(
545
+ :email => "valid@email.com"
546
+ )
547
+ expect do
548
+ customer.update!(:email => "@invalid.com")
549
+ end.to raise_error(Braintree::ValidationsFailed)
550
+ end
551
+ end
552
+
553
+ describe "update_from_transparent_redirect" do
554
+ it "returns a successful result if successful" do
555
+ result = Braintree::Customer.create(
556
+ :first_name => "Old First",
557
+ :last_name => "Old Last",
558
+ :company => "Old Company",
559
+ :email => "old@email.com",
560
+ :phone => "000.111.2222",
561
+ :fax => "000.222.3333",
562
+ :website => "old.website.com"
563
+ )
564
+ result.success?.should == true
565
+ original_customer = result.customer
566
+ params = {
567
+ :customer => {
568
+ :first_name => "New First",
569
+ :last_name => "New Last",
570
+ :company => "New Company",
571
+ :email => "new@email.com",
572
+ :phone => "888.111.2222",
573
+ :fax => "999.222.3333",
574
+ :website => "new.website.com"
575
+ }
576
+ }
577
+ tr_data_params = {
578
+ :customer_id => original_customer.id
579
+ }
580
+ query_string_response = update_customer_via_tr(params, tr_data_params)
581
+ result = Braintree::Customer.update_from_transparent_redirect(query_string_response)
582
+ result.success?.should == true
583
+ customer = result.customer
584
+ customer.id.should == original_customer.id
585
+ customer.first_name.should == "New First"
586
+ customer.last_name.should == "New Last"
587
+ customer.company.should == "New Company"
588
+ customer.email.should == "new@email.com"
589
+ customer.phone.should == "888.111.2222"
590
+ customer.fax.should == "999.222.3333"
591
+ customer.website.should == "new.website.com"
592
+ end
593
+
594
+ it "can pass any attribute through tr_data" do
595
+ original_customer = Braintree::Customer.create!(
596
+ :first_name => "Old First",
597
+ :last_name => "Old Last",
598
+ :company => "Old Company",
599
+ :email => "old@email.com",
600
+ :phone => "000.111.2222",
601
+ :fax => "000.222.3333",
602
+ :website => "old.website.com"
603
+ )
604
+ new_customer_id = "customer_#{rand(1_000_000)}"
605
+ tr_data_params = {
606
+ :customer_id => original_customer.id,
607
+ :customer => {
608
+ :id => new_customer_id,
609
+ :first_name => "New First",
610
+ :last_name => "New Last",
611
+ :company => "New Company",
612
+ :email => "new@email.com",
613
+ :phone => "888.111.2222",
614
+ :fax => "999.222.3333",
615
+ :website => "new.website.com"
616
+ }
617
+ }
618
+ query_string_response = update_customer_via_tr({}, tr_data_params)
619
+ result = Braintree::Customer.update_from_transparent_redirect(query_string_response)
620
+ result.success?.should == true
621
+ customer = result.customer
622
+ customer.id.should == new_customer_id
623
+ customer.first_name.should == "New First"
624
+ customer.last_name.should == "New Last"
625
+ customer.company.should == "New Company"
626
+ customer.email.should == "new@email.com"
627
+ customer.phone.should == "888.111.2222"
628
+ customer.fax.should == "999.222.3333"
629
+ customer.website.should == "new.website.com"
630
+ end
631
+ end
632
+
633
+ def create_customer_via_tr(regular_params, tr_data_params = {})
634
+ response = nil
635
+ Net::HTTP.start(Braintree::Configuration.server, Braintree::Configuration.port) do |http|
636
+ request = Net::HTTP::Post.new("/" + Braintree::Customer.create_customer_url.split("/", 4)[3])
637
+ request.add_field "Content-Type", "application/x-www-form-urlencoded"
638
+ params = {
639
+ :tr_data => Braintree::TransparentRedirect.create_customer_data(
640
+ {:redirect_url => "http://testing.com"}.merge(tr_data_params)
641
+ )
642
+ }.merge(regular_params)
643
+ request.body = Braintree::Util.hash_to_query_string(params)
644
+ response = http.request(request)
645
+ end
646
+ query_string = response["Location"].split("?", 2).last
647
+ query_string
648
+ end
649
+
650
+ def update_customer_via_tr(regular_params, tr_data_params = {})
651
+ raise "need a customer_id (of the customer to update) in tr_data_params" unless tr_data_params[:customer_id]
652
+ response = nil
653
+ Net::HTTP.start(Braintree::Configuration.server, Braintree::Configuration.port) do |http|
654
+ request = Net::HTTP::Post.new("/" + Braintree::Customer.update_customer_url.split("/", 4)[3])
655
+ request.add_field "Content-Type", "application/x-www-form-urlencoded"
656
+ tr_data = Braintree::TransparentRedirect.update_customer_data(
657
+ {:redirect_url => "http://testing.com"}.merge(tr_data_params)
658
+ )
659
+ request.body = Braintree::Util.hash_to_query_string({ :tr_data => tr_data }.merge(regular_params))
660
+ response = http.request(request)
661
+ end
662
+ query_string = response["Location"].split("?", 2).last
663
+ end
664
+ end