braintree 1.1.3 → 1.2.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 (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: []