braintree 2.0.0 → 2.1.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.
@@ -199,6 +199,51 @@ describe Braintree::Transaction do
199
199
  result.success?.should == false
200
200
  result.errors.for(:transaction).on(:base)[0].code.should == Braintree::ErrorCodes::Transaction::PaymentMethodDoesNotBelongToCustomer
201
201
  end
202
+
203
+ context "new credit card for existing customer" do
204
+ it "allows a new credit card to be used for an existing customer" do
205
+ customer = Braintree::Customer.create!(
206
+ :credit_card => {
207
+ :number => Braintree::Test::CreditCardNumbers::Visa,
208
+ :expiration_date => "05/2010"
209
+ }
210
+ )
211
+ result = Braintree::Transaction.create(
212
+ :type => "sale",
213
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
214
+ :customer_id => customer.id,
215
+ :credit_card => {
216
+ :number => Braintree::Test::CreditCardNumbers::Visa,
217
+ :expiration_date => "12/12"
218
+ }
219
+ )
220
+ result.success?.should == true
221
+ result.transaction.credit_card_details.masked_number.should == "401288******1881"
222
+ result.transaction.vault_credit_card.should be_nil
223
+ end
224
+
225
+ it "allows a new credit card to be used and stored in the vault" do
226
+ customer = Braintree::Customer.create!(
227
+ :credit_card => {
228
+ :number => Braintree::Test::CreditCardNumbers::Visa,
229
+ :expiration_date => "05/2010"
230
+ }
231
+ )
232
+ result = Braintree::Transaction.create(
233
+ :type => "sale",
234
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
235
+ :customer_id => customer.id,
236
+ :credit_card => {
237
+ :number => Braintree::Test::CreditCardNumbers::Visa,
238
+ :expiration_date => "12/12",
239
+ },
240
+ :options => { :store_in_vault => true }
241
+ )
242
+ result.success?.should == true
243
+ result.transaction.credit_card_details.masked_number.should == "401288******1881"
244
+ result.transaction.vault_credit_card.masked_number.should == "401288******1881"
245
+ end
246
+ end
202
247
  end
203
248
 
204
249
  describe "self.create!" do
@@ -301,8 +346,8 @@ describe Braintree::Transaction do
301
346
  transaction.amount.should == BigDecimal.new("100.00")
302
347
  transaction.order_id.should == "123"
303
348
  transaction.processor_response_code.should == "1000"
304
- transaction.created_at.between?(Time.now - 5, Time.now).should == true
305
- transaction.updated_at.between?(Time.now - 5, Time.now).should == true
349
+ transaction.created_at.between?(Time.now - 60, Time.now).should == true
350
+ transaction.updated_at.between?(Time.now - 60, Time.now).should == true
306
351
  transaction.credit_card_details.bin.should == "510510"
307
352
  transaction.credit_card_details.cardholder_name.should == "The Cardholder"
308
353
  transaction.credit_card_details.last_4.should == "5100"
@@ -339,6 +384,31 @@ describe Braintree::Transaction do
339
384
  transaction.shipping_details.country_name.should == "United States of America"
340
385
  end
341
386
 
387
+ it "allows merchant account to be specified" do
388
+ result = Braintree::Transaction.sale(
389
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
390
+ :merchant_account_id => SpecHelper::NonDefaultMerchantAccountId,
391
+ :credit_card => {
392
+ :number => Braintree::Test::CreditCardNumbers::Visa,
393
+ :expiration_date => "05/2009"
394
+ }
395
+ )
396
+ result.success?.should == true
397
+ result.transaction.merchant_account_id.should == SpecHelper::NonDefaultMerchantAccountId
398
+ end
399
+
400
+ it "uses default merchant account when it is not specified" do
401
+ result = Braintree::Transaction.sale(
402
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
403
+ :credit_card => {
404
+ :number => Braintree::Test::CreditCardNumbers::Visa,
405
+ :expiration_date => "05/2009"
406
+ }
407
+ )
408
+ result.success?.should == true
409
+ result.transaction.merchant_account_id.should == SpecHelper::DefaultMerchantAccountId
410
+ end
411
+
342
412
  it "can store customer and credit card in the vault" do
343
413
  result = Braintree::Transaction.sale(
344
414
  :amount => "100",
@@ -660,6 +730,31 @@ describe Braintree::Transaction do
660
730
  result.params.should == {:transaction => {:type => 'credit', :amount => nil, :credit_card => {:expiration_date => "05/2009"}}}
661
731
  result.errors.for(:transaction).on(:amount)[0].code.should == Braintree::ErrorCodes::Transaction::AmountIsRequired
662
732
  end
733
+
734
+ it "allows merchant account to be specified" do
735
+ result = Braintree::Transaction.credit(
736
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
737
+ :merchant_account_id => SpecHelper::NonDefaultMerchantAccountId,
738
+ :credit_card => {
739
+ :number => Braintree::Test::CreditCardNumbers::Visa,
740
+ :expiration_date => "05/2009"
741
+ }
742
+ )
743
+ result.success?.should == true
744
+ result.transaction.merchant_account_id.should == SpecHelper::NonDefaultMerchantAccountId
745
+ end
746
+
747
+ it "uses default merchant account when it is not specified" do
748
+ result = Braintree::Transaction.credit(
749
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
750
+ :credit_card => {
751
+ :number => Braintree::Test::CreditCardNumbers::Visa,
752
+ :expiration_date => "05/2009"
753
+ }
754
+ )
755
+ result.success?.should == true
756
+ result.transaction.merchant_account_id.should == SpecHelper::DefaultMerchantAccountId
757
+ end
663
758
  end
664
759
 
665
760
  describe "self.credit!" do
@@ -721,6 +816,30 @@ describe Braintree::Transaction do
721
816
  transaction.credit_card_details.expiration_date.should == "05/2009"
722
817
  end
723
818
 
819
+ it "raises an error with a message if given invalid params" do
820
+ params = {
821
+ :transaction => {
822
+ :bad => "value",
823
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
824
+ :credit_card => {
825
+ :number => Braintree::Test::CreditCardNumbers::Visa,
826
+ :expiration_date => "05/2009"
827
+ }
828
+ }
829
+ }
830
+ tr_data_params = {
831
+ :transaction => {
832
+ :type => "sale"
833
+ }
834
+ }
835
+ tr_data = Braintree::TransparentRedirect.transaction_data({:redirect_url => "http://example.com"}.merge(tr_data_params))
836
+ query_string_response = SpecHelper.simulate_form_post_for_tr(Braintree::Transaction.create_transaction_url, tr_data, params)
837
+
838
+ expect do
839
+ Braintree::Transaction.create_from_transparent_redirect(query_string_response)
840
+ end.to raise_error(Braintree::AuthorizationError, "Invalid params: transaction[bad]")
841
+ end
842
+
724
843
  it "can put any param in tr_data" do
725
844
  params = {
726
845
 
@@ -924,6 +1043,23 @@ describe Braintree::Transaction do
924
1043
  end
925
1044
 
926
1045
  describe "refund" do
1046
+ context "partial refunds" do
1047
+ it "allows partial refunds" do
1048
+ transaction = create_transaction_to_refund
1049
+ result = transaction.refund(transaction.amount / 2)
1050
+ result.success?.should == true
1051
+ result.new_transaction.type.should == "credit"
1052
+ end
1053
+
1054
+ it "does not all multiple refunds" do
1055
+ transaction = create_transaction_to_refund
1056
+ transaction.refund(transaction.amount / 2)
1057
+ result = transaction.refund(BigDecimal.new("1"))
1058
+ result.success?.should == false
1059
+ result.errors.for(:transaction).on(:base)[0].code.should == Braintree::ErrorCodes::Transaction::HasAlreadyBeenRefunded
1060
+ end
1061
+ end
1062
+
927
1063
  it "returns a successful result if successful" do
928
1064
  transaction = create_transaction_to_refund
929
1065
  transaction.status.should == Braintree::Transaction::Status::Settled
@@ -1044,101 +1180,6 @@ describe Braintree::Transaction do
1044
1180
  end
1045
1181
  end
1046
1182
 
1047
- describe "search" do
1048
- describe "advanced" do
1049
- it "pretty much works in one big fell swoop/hash" do
1050
- result = Braintree::Transaction.create(
1051
- :type => "sale",
1052
- :amount => Braintree::Test::TransactionAmounts::Authorize,
1053
- :credit_card => {
1054
- :number => Braintree::Test::CreditCardNumbers::Visa,
1055
- :expiration_date => "05/2009"
1056
- },
1057
- :order_id => "123",
1058
- :customer => {
1059
- :company => "Apple",
1060
- :fax => "312-555-1234",
1061
- :first_name => "Steve",
1062
- :last_name => "Jobs",
1063
- :phone => "614-555-1234",
1064
- :website => "http://www.apple.com",
1065
- },
1066
- :billing => {
1067
- :country_name => "United States of America",
1068
- :extended_address => "Apt 1F",
1069
- :locality => "Chicago",
1070
- :postal_code => "60622",
1071
- :region => "Illinois",
1072
- :street_address => "1234 W North Ave",
1073
- },
1074
- :shipping => {
1075
- :country_name => "United States of America",
1076
- :extended_address => "Apt 123",
1077
- :locality => "Bartlett",
1078
- :postal_code => "60004",
1079
- :region => "Illinois",
1080
- :street_address => "123 Main St",
1081
- }
1082
- )
1083
- result.success?.should == true
1084
- expected_transaction = result.transaction
1085
- search_criteria = {
1086
- :billing_country_name => {:is => "United States of America"},
1087
- :billing_extended_address => {:is => "Apt 1F"},
1088
- :billing_locality => {:is => "Chicago"},
1089
- :billing_postal_code => {:is => "60622"},
1090
- :billing_region => {:is => "Illinois"},
1091
- :billing_street_address => {:is => "1234 W North Ave"},
1092
- :credit_card_number => {:is => Braintree::Test::CreditCardNumbers::Visa},
1093
- :customer_company => {:is => "Apple"},
1094
- :customer_fax => {:is => "312-555-1234"},
1095
- :customer_first_name => {:is => "Steve"},
1096
- :customer_last_name => {:is => "Jobs"},
1097
- :customer_phone => {:is => "614-555-1234"},
1098
- :customer_website => {:is => "http://www.apple.com"},
1099
- :expiration_date => {:is => "05/2009"},
1100
- :order_id => {:is => "123"},
1101
- :shipping_country_name => {:is => "United States of America"},
1102
- :shipping_extended_address => {:is => "Apt 123"},
1103
- :shipping_locality => {:is => "Bartlett"},
1104
- :shipping_postal_code => {:is => "60004"},
1105
- :shipping_region => {:is => "Illinois"},
1106
- :shipping_street_address => {:is => "123 Main St"},
1107
- }
1108
- search_results = Braintree::Transaction.search(search_criteria)
1109
- search_results.should include(expected_transaction)
1110
- end
1111
-
1112
- it "properly parses the xml if only one transaction is found" do
1113
- transaction = Braintree::Transaction.create!(
1114
- :type => "sale",
1115
- :amount => Braintree::Test::TransactionAmounts::Authorize,
1116
- :credit_card => {
1117
- :number => Braintree::Test::CreditCardNumbers::Visa,
1118
- :expiration_date => "05/2009"
1119
- }
1120
- )
1121
- search_results = Braintree::Transaction.search(:transaction_id => {:is => transaction.id})
1122
- search_results.first.should == transaction
1123
- end
1124
- end
1125
-
1126
- describe "basic" do
1127
- it "returns transactions matching the given search terms" do
1128
- transactions = Braintree::Transaction.search "1111"
1129
- transactions._approximate_size.should > 0
1130
- end
1131
-
1132
- it "can iterate over the entire collection" do
1133
- transactions = Braintree::Transaction.search "411111"
1134
- transactions._approximate_size.should > 100
1135
-
1136
- transaction_ids = transactions.map {|t| t.id }.uniq.compact
1137
- transaction_ids.size.should == transactions._approximate_size
1138
- end
1139
- end
1140
- end
1141
-
1142
1183
  describe "status_history" do
1143
1184
  it "returns an array of StatusDetail" do
1144
1185
  transaction = Braintree::Transaction.sale!(
@@ -17,6 +17,10 @@ unless defined?(SPEC_HELPER_LOADED)
17
17
  Braintree::Configuration.logger.level = Logger::INFO
18
18
 
19
19
  module SpecHelper
20
+
21
+ DefaultMerchantAccountId = "sandbox_credit_card"
22
+ NonDefaultMerchantAccountId = "sandbox_credit_card_non_default"
23
+
20
24
  def self.stub_time_dot_now(desired_time)
21
25
  Time.class_eval do
22
26
  class << self
@@ -10,14 +10,56 @@ describe Braintree::CreditCard do
10
10
  end
11
11
 
12
12
  describe "self.create_signature" do
13
- it "should include customer_id" do
14
- Braintree::CreditCard._create_signature.should include(:customer_id)
13
+ it "should be what we expect" do
14
+ Braintree::CreditCard._create_signature.should == [
15
+ :cardholder_name,
16
+ :cvv,
17
+ :expiration_date,
18
+ :expiration_month,
19
+ :expiration_year,
20
+ :number,
21
+ :token,
22
+ {:options => [:make_default, :verify_card]},
23
+ {:billing_address => [
24
+ :company,
25
+ :country_name,
26
+ :extended_address,
27
+ :first_name,
28
+ :last_name,
29
+ :locality,
30
+ :postal_code,
31
+ :region,
32
+ :street_address
33
+ ]},
34
+ :customer_id
35
+ ]
15
36
  end
16
37
  end
17
38
 
18
39
  describe "self.update_signature" do
19
- it "should not include customer_id" do
20
- Braintree::CreditCard._update_signature.should_not include(:customer_id)
40
+ it "should be what we expect" do
41
+ Braintree::CreditCard._update_signature.should == [
42
+ :cardholder_name,
43
+ :cvv,
44
+ :expiration_date,
45
+ :expiration_month,
46
+ :expiration_year,
47
+ :number,
48
+ :token,
49
+ {:options => [:make_default, :verify_card]},
50
+ {:billing_address => [
51
+ :company,
52
+ :country_name,
53
+ :extended_address,
54
+ :first_name,
55
+ :last_name,
56
+ :locality,
57
+ :postal_code,
58
+ :region,
59
+ :street_address,
60
+ {:options => [:update_existing]}
61
+ ]}
62
+ ]
21
63
  end
22
64
  end
23
65
 
@@ -3,13 +3,13 @@ require File.dirname(__FILE__) + "/../spec_helper"
3
3
  describe Braintree::Subscription do
4
4
  context "price" do
5
5
  it "accepts price as either a String or a BigDecimal" do
6
- Braintree::Subscription.new(:price => "12.34", :transactions => []).price.should == BigDecimal.new("12.34")
7
- Braintree::Subscription.new(:price => BigDecimal.new("12.34"), :transactions => []).price.should == BigDecimal.new("12.34")
6
+ Braintree::Subscription._new(:price => "12.34", :transactions => []).price.should == BigDecimal.new("12.34")
7
+ Braintree::Subscription._new(:price => BigDecimal.new("12.34"), :transactions => []).price.should == BigDecimal.new("12.34")
8
8
  end
9
9
 
10
10
  it "blows up if price is not a string or BigDecimal" do
11
11
  expect {
12
- Braintree::Subscription.new(:price => 12.34, :transactions => [])
12
+ Braintree::Subscription._new(:price => 12.34, :transactions => [])
13
13
  }.to raise_error(/Argument must be a String or BigDecimal/)
14
14
  end
15
15
  end
@@ -23,4 +23,23 @@ describe Braintree::Subscription do
23
23
  end.should raise_error(ArgumentError)
24
24
  end
25
25
  end
26
+
27
+ describe "==" do
28
+ it "returns true for subscriptions with the same id" do
29
+ subscription1 = Braintree::Subscription._new(:id => "123", :transactions => [])
30
+ subscription2 = Braintree::Subscription._new(:id => "123", :transactions => [])
31
+ subscription1.should == subscription2
32
+ end
33
+
34
+ it "returns false for subscriptions with different ids" do
35
+ subscription1 = Braintree::Subscription._new(:id => "123", :transactions => [])
36
+ subscription2 = Braintree::Subscription._new(:id => "not_123", :transactions => [])
37
+ subscription1.should_not == subscription2
38
+ end
39
+
40
+ it "returns false if not comparing to a subscription" do
41
+ subscription = Braintree::Subscription._new(:id => "123", :transactions => [])
42
+ subscription.should_not == "not a subscription"
43
+ end
44
+ end
26
45
  end
@@ -0,0 +1,24 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
+
3
+ describe Braintree::TransactionSearch do
4
+ it "overrides previous 'is' with new 'is' for the same field" do
5
+ search = Braintree::TransactionSearch.new
6
+ search.billing_company.is "one"
7
+ search.billing_company.is "two"
8
+ search.to_hash.should == {:billing_company => {:is => "two"}}
9
+ end
10
+
11
+ it "overrides previous 'in' with new 'in' for the same field" do
12
+ search = Braintree::TransactionSearch.new
13
+ search.status.in Braintree::Transaction::Status::Authorized
14
+ search.status.in Braintree::Transaction::Status::SubmittedForSettlement
15
+ search.to_hash.should == {:status => [Braintree::Transaction::Status::SubmittedForSettlement]}
16
+ end
17
+
18
+ it "raises if the operator 'is' is left off" do
19
+ search = Braintree::TransactionSearch.new
20
+ expect do
21
+ search.billing_company "one"
22
+ end.to raise_error(RuntimeError, "An operator is required")
23
+ end
24
+ end
@@ -127,7 +127,7 @@ describe Braintree::Transaction do
127
127
  end
128
128
 
129
129
  describe "==" do
130
- it "returns true when it should" do
130
+ it "returns true for transactions with the same id" do
131
131
  first = Braintree::Transaction._new(:id => 123)
132
132
  second = Braintree::Transaction._new(:id => 123)
133
133
 
@@ -135,13 +135,24 @@ describe Braintree::Transaction do
135
135
  second.should == first
136
136
  end
137
137
 
138
- it "returns false when it should" do
138
+ it "returns false for transactions with different ids" do
139
139
  first = Braintree::Transaction._new(:id => 123)
140
140
  second = Braintree::Transaction._new(:id => 124)
141
141
 
142
142
  first.should_not == second
143
143
  second.should_not == first
144
144
  end
145
+
146
+ it "returns false when comparing to nil" do
147
+ Braintree::Transaction._new({}).should_not == nil
148
+ end
149
+
150
+ it "returns false when comparing to non-transactions" do
151
+ same_id_different_object = Object.new
152
+ def same_id_different_object.id; 123; end
153
+ transaction = Braintree::Transaction._new(:id => 123)
154
+ transaction.should_not == same_id_different_object
155
+ end
145
156
  end
146
157
 
147
158
  describe "new" do