braintree 1.1.3 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. data/lib/braintree.rb +2 -0
  2. data/lib/braintree/advanced_search.rb +69 -0
  3. data/lib/braintree/configuration.rb +2 -2
  4. data/lib/braintree/credit_card.rb +2 -1
  5. data/lib/braintree/subscription.rb +50 -1
  6. data/lib/braintree/subscription_search.rb +10 -0
  7. data/lib/braintree/transparent_redirect.rb +8 -5
  8. data/lib/braintree/version.rb +2 -2
  9. data/lib/braintree/xml/generator.rb +7 -2
  10. data/lib/ssl/{valicert_ca.crt → sandbox_braintreegateway_com.ca.crt} +1 -0
  11. data/lib/ssl/www_braintreegateway_com.ca.crt +202 -0
  12. data/spec/integration/braintree/credit_card_spec.rb +27 -35
  13. data/spec/integration/braintree/customer_spec.rb +37 -36
  14. data/spec/integration/braintree/http_spec.rb +17 -0
  15. data/spec/integration/braintree/subscription_spec.rb +244 -3
  16. data/spec/integration/braintree/transaction_spec.rb +9 -18
  17. data/spec/integration/braintree/transparent_redirect_spec.rb +21 -0
  18. data/spec/integration/spec_helper.rb +0 -23
  19. data/spec/spec_helper.rb +34 -0
  20. data/spec/support/matchers/include_on_any_page.rb +24 -0
  21. data/spec/unit/braintree/configuration_spec.rb +3 -3
  22. data/spec/unit/braintree/credit_card_spec.rb +1 -1
  23. data/spec/unit/braintree/customer_spec.rb +1 -1
  24. data/spec/unit/braintree/paged_collection_spec.rb +50 -0
  25. data/spec/unit/braintree/subscription_search_spec.rb +35 -0
  26. data/spec/unit/braintree/subscription_spec.rb +10 -0
  27. data/spec/unit/braintree/transaction_spec.rb +1 -1
  28. data/spec/unit/braintree/transparent_redirect_spec.rb +8 -2
  29. data/spec/unit/braintree/xml_spec.rb +5 -0
  30. metadata +11 -5
@@ -706,8 +706,10 @@ describe Braintree::Transaction do
706
706
  :type => "sale"
707
707
  }
708
708
  }
709
- query_string_response = create_transaction_via_tr(params, tr_data_params)
709
+ tr_data = Braintree::TransparentRedirect.transaction_data({:redirect_url => "http://example.com"}.merge(tr_data_params))
710
+ query_string_response = SpecHelper.simulate_form_post_for_tr(Braintree::Transaction.create_transaction_url, tr_data, params)
710
711
  result = Braintree::Transaction.create_from_transparent_redirect(query_string_response)
712
+
711
713
  result.success?.should == true
712
714
  transaction = result.transaction
713
715
  transaction.type.should == "sale"
@@ -764,8 +766,10 @@ describe Braintree::Transaction do
764
766
  }
765
767
  }
766
768
  }
767
- query_string_response = create_transaction_via_tr(params, tr_data_params)
769
+ tr_data = Braintree::TransparentRedirect.transaction_data({:redirect_url => "http://example.com"}.merge(tr_data_params))
770
+ query_string_response = SpecHelper.simulate_form_post_for_tr(Braintree::Transaction.create_transaction_url, tr_data, params)
768
771
  result = Braintree::Transaction.create_from_transparent_redirect(query_string_response)
772
+
769
773
  transaction = result.transaction
770
774
  transaction.id.should =~ /\A\w{6}\z/
771
775
  transaction.type.should == "sale"
@@ -825,8 +829,10 @@ describe Braintree::Transaction do
825
829
  :type => "sale"
826
830
  }
827
831
  }
828
- query_string_response = create_transaction_via_tr(params, tr_data_params)
832
+ tr_data = Braintree::TransparentRedirect.transaction_data({:redirect_url => "http://example.com"}.merge(tr_data_params))
833
+ query_string_response = SpecHelper.simulate_form_post_for_tr(Braintree::Transaction.create_transaction_url, tr_data, params)
829
834
  result = Braintree::Transaction.create_from_transparent_redirect(query_string_response)
835
+
830
836
  result.success?.should == false
831
837
  result.params[:transaction].should == {:amount => "", :type => "sale", :credit_card => {:expiration_date => "05/2009"}}
832
838
  result.errors.for(:transaction).on(:amount)[0].code.should == Braintree::ErrorCodes::Transaction::AmountIsRequired
@@ -1260,21 +1266,6 @@ describe Braintree::Transaction do
1260
1266
  end
1261
1267
  end
1262
1268
 
1263
- def create_transaction_via_tr(params, tr_data_params)
1264
- response = nil
1265
- Net::HTTP.start(Braintree::Configuration.server, Braintree::Configuration.port) do |http|
1266
- request = Net::HTTP::Post.new("/" + Braintree::Transaction.create_transaction_url.split("/", 4)[3])
1267
- request.add_field "Content-Type", "application/x-www-form-urlencoded"
1268
- params = {
1269
- :tr_data => Braintree::TransparentRedirect.transaction_data({:redirect_url => "http://testing.com"}.merge(tr_data_params))
1270
- }.merge(params)
1271
- request.body = Braintree::Util.hash_to_query_string(params)
1272
- response = http.request(request)
1273
- end
1274
- query_string = response["Location"].split("?", 2).last
1275
- query_string
1276
- end
1277
-
1278
1269
  def create_transaction_to_refund
1279
1270
  transaction = Braintree::Transaction.sale!(
1280
1271
  :amount => Braintree::Test::TransactionAmounts::Authorize,
@@ -0,0 +1,21 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
+
3
+ describe Braintree::TransparentRedirect do
4
+ it "raises a DownForMaintenanceError when app is in maintenance mode on TR requests" do
5
+ tr_data = Braintree::TransparentRedirect.create_customer_data({:redirect_url => "http://example.com"}.merge({}))
6
+ query_string_response = SpecHelper.simulate_form_post_for_tr(Braintree::Configuration.base_merchant_url + "/test/maintenance", tr_data, {})
7
+ expect do
8
+ Braintree::Customer.create_from_transparent_redirect(query_string_response)
9
+ end.to raise_error(Braintree::DownForMaintenanceError)
10
+ end
11
+
12
+ it "raises an AuthenticationError when authentication fails on TR requests" do
13
+ SpecHelper.using_configuration(:private_key => "incorrect") do
14
+ tr_data = Braintree::TransparentRedirect.create_customer_data({:redirect_url => "http://example.com"}.merge({}))
15
+ query_string_response = SpecHelper.simulate_form_post_for_tr(Braintree::Customer.create_customer_url, tr_data, {})
16
+ expect do
17
+ Braintree::Customer.create_from_transparent_redirect(query_string_response)
18
+ end.to raise_error(Braintree::AuthenticationError)
19
+ end
20
+ end
21
+ end
@@ -4,29 +4,6 @@ unless defined?(INTEGRATION_SPEC_HELPER_LOADED)
4
4
  require File.dirname(__FILE__) + "/../spec_helper"
5
5
  require File.dirname(__FILE__) + "/../hacks/tcp_socket"
6
6
 
7
- Spec::Runner.configure do |config|
8
- CLIENT_LIB_ROOT = File.expand_path(File.dirname(__FILE__) + "/../..")
9
- GATEWAY_ROOT = File.expand_path("#{CLIENT_LIB_ROOT}/../gateway")
10
- GATEWAY_PID_FILE = "/tmp/gateway_server_#{Braintree::Configuration.port}.pid"
11
- SPHINX_PID_FILE = "#{GATEWAY_ROOT}/log/searchd.integration.pid"
12
-
13
- gateway_already_started = File.exist?(GATEWAY_PID_FILE)
14
- sphinx_already_started = File.exist?(SPHINX_PID_FILE)
15
- config.before(:suite) do
16
- Dir.chdir(CLIENT_LIB_ROOT) do
17
- system "rake start_gateway" or raise "rake start_gateway failed" unless gateway_already_started
18
- system "rake start_sphinx" or raise "rake start_sphinx failed" unless sphinx_already_started
19
- end
20
- end
21
-
22
- config.after(:suite) do
23
- Dir.chdir(CLIENT_LIB_ROOT) do
24
- system "rake stop_gateway" or raise "rake stop_gateway failed" unless gateway_already_started
25
- system "rake stop_sphinx" or raise "rake stop_sphinx failed" unless sphinx_already_started
26
- end
27
- end
28
- end
29
-
30
7
  def start_ssl_server
31
8
  web_server_pid_file = File.expand_path(File.join(File.dirname(__FILE__), "..", "httpsd.pid"))
32
9
 
@@ -34,5 +34,39 @@ unless defined?(SPEC_HELPER_LOADED)
34
34
  end
35
35
  end
36
36
  end
37
+
38
+ def self.simulate_form_post_for_tr(url, tr_data_string, form_data_hash)
39
+ response = nil
40
+ Net::HTTP.start("localhost", Braintree::Configuration.port) do |http|
41
+ request = Net::HTTP::Post.new("/" + url.split("/", 4)[3])
42
+ request.add_field "Content-Type", "application/x-www-form-urlencoded"
43
+ request.body = Braintree::Util.hash_to_query_string({:tr_data => tr_data_string}.merge(form_data_hash))
44
+ response = http.request(request)
45
+ end
46
+ if response.code.to_i == 303
47
+ response["Location"].split("?", 2).last
48
+ else
49
+ raise "did not receive a valid tr response: #{response.body[0,1000].inspect}"
50
+ end
51
+ end
52
+
53
+ def self.using_configuration(config = {}, &block)
54
+ original_values = {}
55
+ [:merchant_id, :public_key, :private_key].each do |key|
56
+ if config[key]
57
+ original_values[key] = Braintree::Configuration.send(key)
58
+ Braintree::Configuration.send("#{key}=", config[key])
59
+ end
60
+ end
61
+ begin
62
+ yield
63
+ ensure
64
+ original_values.each do |key, value|
65
+ Braintree::Configuration.send("#{key}=", value)
66
+ end
67
+ end
68
+ end
37
69
  end
38
70
  end
71
+
72
+ Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each {|f| require f}
@@ -0,0 +1,24 @@
1
+ Spec::Matchers.define :include_on_any_page do |expected|
2
+ match do |collection|
3
+ on_any_page?(collection, expected)
4
+ end
5
+
6
+ def on_any_page?(collection, expected)
7
+ return true if collection.any? { |item| item.id == expected.id }
8
+ return false if collection.last_page?
9
+
10
+ on_any_page?(collection.next_page, expected)
11
+ end
12
+
13
+ failure_message_for_should do |collection|
14
+ "expected that the paged collection would include an item with id #{expected.id}"
15
+ end
16
+
17
+ failure_message_for_should_not do |collection|
18
+ "expected that the paged collection would not include an item with id #{expected.id}"
19
+ end
20
+
21
+ description do
22
+ "include the given subsription in the paged collection"
23
+ end
24
+ end
@@ -44,21 +44,21 @@ describe Braintree::Configuration do
44
44
  it "qa" do
45
45
  Braintree::Configuration.environment = :qa
46
46
  ca_file = Braintree::Configuration.ca_file
47
- ca_file.should match(/valicert_ca.crt$/)
47
+ ca_file.should match(/sandbox_braintreegateway_com.ca.crt$/)
48
48
  File.exists?(ca_file).should == true
49
49
  end
50
50
 
51
51
  it "sandbox" do
52
52
  Braintree::Configuration.environment = :sandbox
53
53
  ca_file = Braintree::Configuration.ca_file
54
- ca_file.should match(/valicert_ca.crt$/)
54
+ ca_file.should match(/sandbox_braintreegateway_com.ca.crt$/)
55
55
  File.exists?(ca_file).should == true
56
56
  end
57
57
 
58
58
  it "production" do
59
59
  Braintree::Configuration.environment = :production
60
60
  ca_file = Braintree::Configuration.ca_file
61
- ca_file.should match(/securetrust_ca.crt$/)
61
+ ca_file.should match(/www_braintreegateway_com.ca.crt$/)
62
62
  File.exists?(ca_file).should == true
63
63
  end
64
64
  end
@@ -24,7 +24,7 @@ describe Braintree::CreditCard do
24
24
  describe "self.create_from_transparent_redirect" do
25
25
  it "raises an exception if the query string is forged" do
26
26
  expect do
27
- Braintree::CreditCard.create_from_transparent_redirect("forged=query_string")
27
+ Braintree::CreditCard.create_from_transparent_redirect("http_status=200&forged=query_string")
28
28
  end.to raise_error(Braintree::ForgedQueryString)
29
29
  end
30
30
  end
@@ -51,7 +51,7 @@ describe Braintree::Customer do
51
51
  describe "self.create_from_transparent_redirect" do
52
52
  it "raises an exception if the query string is forged" do
53
53
  expect do
54
- Braintree::Customer.create_from_transparent_redirect("forged=query_string")
54
+ Braintree::Customer.create_from_transparent_redirect("http_status=200&forged=query_string")
55
55
  end.to raise_error(Braintree::ForgedQueryString)
56
56
  end
57
57
  end
@@ -125,4 +125,54 @@ describe "Braintree::PagedCollection" do
125
125
  end
126
126
  end
127
127
 
128
+ context "custom matchers" do
129
+ require 'enumerator'
130
+
131
+ DummyItem = Struct.new(:id)
132
+
133
+ def paged_collection(items, page_size)
134
+ pages = []
135
+ items.each_slice(page_size) do |slice|
136
+ pages << slice
137
+ end
138
+
139
+ _build_collection(pages, page_size, items.size, 1)
140
+ end
141
+
142
+ def _build_collection(paged_items, page_size, total_size, current_page)
143
+ Braintree::PagedCollection.new(:items => paged_items[current_page - 1], :total_items => total_size, :page_size => page_size, :current_page_number => current_page) do |page|
144
+ _build_collection(paged_items, page_size, total_size, page)
145
+ end
146
+ end
147
+
148
+ describe "include_on_any_page" do
149
+ it "finds a match in a simple collection" do
150
+ element = DummyItem.new(123)
151
+ collection = paged_collection([element], 10)
152
+
153
+ collection.should include_on_any_page(element)
154
+ end
155
+
156
+ it "does not find a match in a simple collection" do
157
+ element = DummyItem.new(1)
158
+ collection = paged_collection([DummyItem.new(2)], 10)
159
+
160
+ collection.should_not include_on_any_page(element)
161
+ end
162
+
163
+ it "finds a match on a subsequent page" do
164
+ element = DummyItem.new(1)
165
+ collection = paged_collection([DummyItem.new(2), element], 1)
166
+
167
+ collection.should include_on_any_page(element)
168
+ end
169
+
170
+ it "does not find a match on a subsequent page" do
171
+ element = DummyItem.new(1)
172
+ collection = paged_collection([DummyItem.new(2), DummyItem.new(3)], 1)
173
+
174
+ collection.should_not include_on_any_page(element)
175
+ end
176
+ end
177
+ end
128
178
  end
@@ -0,0 +1,35 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
+
3
+ module Braintree
4
+ describe SubscriptionSearch do
5
+ context "status" do
6
+ it "allows Active, Canceled and PastDue" do
7
+ search = SubscriptionSearch.new
8
+
9
+ lambda do
10
+ search.status.in(
11
+ Subscription::Status::Active,
12
+ Subscription::Status::Canceled,
13
+ Subscription::Status::PastDue
14
+ )
15
+ end.should_not raise_error
16
+ end
17
+ end
18
+
19
+ context "days_past_due" do
20
+ it "correctly builds a hash with the criteria" do
21
+ search = SubscriptionSearch.new
22
+ search.days_past_due.is "30"
23
+
24
+ search.to_hash.should == {:days_past_due => {:is => "30"}}
25
+ end
26
+
27
+ it "coverts ints to strings" do
28
+ search = SubscriptionSearch.new
29
+ search.days_past_due.is 30
30
+
31
+ search.to_hash.should == {:days_past_due => {:is => "30"}}
32
+ end
33
+ end
34
+ end
35
+ end
@@ -13,4 +13,14 @@ describe Braintree::Subscription do
13
13
  }.to raise_error(/Argument must be a String or BigDecimal/)
14
14
  end
15
15
  end
16
+
17
+ describe "self.search" do
18
+ it "only allows specified values for status" do
19
+ lambda do
20
+ Braintree::Subscription.search do |search|
21
+ search.status.in "Hammer"
22
+ end
23
+ end.should raise_error(ArgumentError)
24
+ end
25
+ end
16
26
  end
@@ -12,7 +12,7 @@ describe Braintree::Transaction do
12
12
  describe "self.create_from_transparent_redirect" do
13
13
  it "raises an exception if the query string is forged" do
14
14
  expect do
15
- Braintree::Transaction.create_from_transparent_redirect("forged=query_string")
15
+ Braintree::Transaction.create_from_transparent_redirect("http_status=200&forged=query_string")
16
16
  end.to raise_error(Braintree::ForgedQueryString)
17
17
  end
18
18
  end
@@ -32,7 +32,7 @@ describe Braintree::TransparentRedirect do
32
32
  end
33
33
 
34
34
  it "raises Braintree::ForgedQueryString if the hash param is not valid" do
35
- query_string_without_hash = "one=1&two=2"
35
+ query_string_without_hash = "http_status=200&one=1&two=2"
36
36
  hash = Digest::SHA1.hexdigest("invalid#{query_string_without_hash}")
37
37
 
38
38
  query_string_with_hash = "#{query_string_without_hash}&hash=#{hash}"
@@ -43,7 +43,7 @@ describe Braintree::TransparentRedirect do
43
43
 
44
44
  it "raises Braintree::ForgedQueryString if hash is missing from the query string" do
45
45
  expect do
46
- Braintree::TransparentRedirect.parse_and_validate_query_string "query_string=without_a_hash"
46
+ Braintree::TransparentRedirect.parse_and_validate_query_string "http_status=200&query_string=without_a_hash"
47
47
  end.to raise_error(Braintree::ForgedQueryString)
48
48
  end
49
49
 
@@ -59,6 +59,12 @@ describe Braintree::TransparentRedirect do
59
59
  end.to raise_error(Braintree::AuthorizationError)
60
60
  end
61
61
 
62
+ it "raises an UnexpectedError if http_status is not in query string" do
63
+ expect do
64
+ Braintree::TransparentRedirect.parse_and_validate_query_string add_hash_to_query_string("no_http_status=x")
65
+ end.to raise_error(Braintree::UnexpectedError, "expected query string to have an http_status param")
66
+ end
67
+
62
68
  it "raises a ServerError if the server 500's" do
63
69
  expect do
64
70
  Braintree::TransparentRedirect.parse_and_validate_query_string add_hash_to_query_string("http_status=500")
@@ -94,6 +94,11 @@ describe Braintree::Xml do
94
94
  verify_to_xml_and_back hash
95
95
  end
96
96
 
97
+ it "works for arrays of strings" do
98
+ hash = {:root => {:items => ["first", "second"]}}
99
+ verify_to_xml_and_back hash
100
+ end
101
+
97
102
  it "type casts booleans" do
98
103
  hash = {:root => {:string_true => "true", :bool_true => true, :bool_false => false, :string_false => "false"}}
99
104
  verify_to_xml_and_back hash
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 1
7
- - 1
8
- - 3
9
- version: 1.1.3
7
+ - 2
8
+ - 0
9
+ version: 1.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Braintree Payment Solutions
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-04-01 00:00:00 -05:00
17
+ date: 2010-04-09 00:00:00 -05:00
18
18
  default_executable:
19
19
  dependencies: []
20
20
 
@@ -30,6 +30,7 @@ files:
30
30
  - README.rdoc
31
31
  - LICENSE
32
32
  - lib/braintree/address.rb
33
+ - lib/braintree/advanced_search.rb
33
34
  - lib/braintree/base_module.rb
34
35
  - lib/braintree/configuration.rb
35
36
  - lib/braintree/credit_card.rb
@@ -44,6 +45,7 @@ files:
44
45
  - lib/braintree/paged_collection.rb
45
46
  - lib/braintree/ssl_expiration_check.rb
46
47
  - lib/braintree/subscription.rb
48
+ - lib/braintree/subscription_search.rb
47
49
  - lib/braintree/successful_result.rb
48
50
  - lib/braintree/test/credit_card_numbers.rb
49
51
  - lib/braintree/test/transaction_amounts.rb
@@ -71,9 +73,11 @@ files:
71
73
  - spec/integration/braintree/subscription_spec.rb
72
74
  - spec/integration/braintree/test/transaction_amounts_spec.rb
73
75
  - spec/integration/braintree/transaction_spec.rb
76
+ - spec/integration/braintree/transparent_redirect_spec.rb
74
77
  - spec/integration/spec_helper.rb
75
78
  - spec/script/httpsd.rb
76
79
  - spec/spec_helper.rb
80
+ - spec/support/matchers/include_on_any_page.rb
77
81
  - spec/unit/braintree/address_spec.rb
78
82
  - spec/unit/braintree/base_module_spec.rb
79
83
  - spec/unit/braintree/configuration_spec.rb
@@ -86,6 +90,7 @@ files:
86
90
  - spec/unit/braintree/http_spec.rb
87
91
  - spec/unit/braintree/paged_collection_spec.rb
88
92
  - spec/unit/braintree/ssl_expiration_check_spec.rb
93
+ - spec/unit/braintree/subscription_search_spec.rb
89
94
  - spec/unit/braintree/subscription_spec.rb
90
95
  - spec/unit/braintree/successful_result_spec.rb
91
96
  - spec/unit/braintree/transaction/credit_card_details_spec.rb
@@ -99,8 +104,9 @@ files:
99
104
  - spec/unit/braintree/xml_spec.rb
100
105
  - spec/unit/braintree_spec.rb
101
106
  - spec/unit/spec_helper.rb
107
+ - lib/ssl/sandbox_braintreegateway_com.ca.crt
102
108
  - lib/ssl/securetrust_ca.crt
103
- - lib/ssl/valicert_ca.crt
109
+ - lib/ssl/www_braintreegateway_com.ca.crt
104
110
  has_rdoc: true
105
111
  homepage: http://www.braintreepaymentsolutions.com/gateway
106
112
  licenses: []