stripe 4.24.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +17 -4
  3. data/.rubocop_todo.yml +10 -9
  4. data/.travis.yml +1 -5
  5. data/CHANGELOG.md +22 -0
  6. data/Gemfile +2 -12
  7. data/README.md +10 -10
  8. data/Rakefile +8 -7
  9. data/VERSION +1 -1
  10. data/lib/stripe.rb +56 -15
  11. data/lib/stripe/api_operations/list.rb +0 -6
  12. data/lib/stripe/connection_manager.rb +131 -0
  13. data/lib/stripe/error_object.rb +94 -0
  14. data/lib/stripe/errors.rb +15 -2
  15. data/lib/stripe/list_object.rb +2 -1
  16. data/lib/stripe/multipart_encoder.rb +131 -0
  17. data/lib/stripe/object_types.rb +0 -1
  18. data/lib/stripe/resources.rb +0 -1
  19. data/lib/stripe/resources/account.rb +1 -5
  20. data/lib/stripe/resources/account_link.rb +1 -1
  21. data/lib/stripe/resources/alipay_account.rb +1 -1
  22. data/lib/stripe/resources/apple_pay_domain.rb +1 -1
  23. data/lib/stripe/resources/application_fee.rb +1 -12
  24. data/lib/stripe/resources/application_fee_refund.rb +1 -1
  25. data/lib/stripe/resources/balance.rb +1 -1
  26. data/lib/stripe/resources/balance_transaction.rb +1 -1
  27. data/lib/stripe/resources/bank_account.rb +1 -1
  28. data/lib/stripe/resources/bitcoin_receiver.rb +1 -1
  29. data/lib/stripe/resources/bitcoin_transaction.rb +1 -1
  30. data/lib/stripe/resources/capability.rb +1 -1
  31. data/lib/stripe/resources/card.rb +1 -1
  32. data/lib/stripe/resources/charge.rb +7 -69
  33. data/lib/stripe/resources/checkout/session.rb +1 -1
  34. data/lib/stripe/resources/country_spec.rb +1 -1
  35. data/lib/stripe/resources/coupon.rb +1 -1
  36. data/lib/stripe/resources/credit_note.rb +1 -1
  37. data/lib/stripe/resources/customer.rb +3 -63
  38. data/lib/stripe/resources/customer_balance_transaction.rb +1 -1
  39. data/lib/stripe/resources/discount.rb +1 -1
  40. data/lib/stripe/resources/dispute.rb +1 -7
  41. data/lib/stripe/resources/ephemeral_key.rb +1 -1
  42. data/lib/stripe/resources/event.rb +1 -1
  43. data/lib/stripe/resources/exchange_rate.rb +1 -1
  44. data/lib/stripe/resources/file.rb +3 -13
  45. data/lib/stripe/resources/file_link.rb +1 -1
  46. data/lib/stripe/resources/invoice.rb +6 -1
  47. data/lib/stripe/resources/invoice_item.rb +1 -1
  48. data/lib/stripe/resources/invoice_line_item.rb +1 -1
  49. data/lib/stripe/resources/issuing/authorization.rb +1 -1
  50. data/lib/stripe/resources/issuing/card.rb +1 -1
  51. data/lib/stripe/resources/issuing/card_details.rb +1 -1
  52. data/lib/stripe/resources/issuing/cardholder.rb +1 -1
  53. data/lib/stripe/resources/issuing/dispute.rb +1 -1
  54. data/lib/stripe/resources/issuing/transaction.rb +1 -1
  55. data/lib/stripe/resources/login_link.rb +1 -1
  56. data/lib/stripe/resources/order.rb +1 -9
  57. data/lib/stripe/resources/order_return.rb +1 -1
  58. data/lib/stripe/resources/payment_intent.rb +1 -1
  59. data/lib/stripe/resources/payment_method.rb +1 -1
  60. data/lib/stripe/resources/payout.rb +1 -7
  61. data/lib/stripe/resources/person.rb +1 -1
  62. data/lib/stripe/resources/plan.rb +1 -1
  63. data/lib/stripe/resources/product.rb +1 -1
  64. data/lib/stripe/resources/radar/early_fraud_warning.rb +1 -1
  65. data/lib/stripe/resources/radar/value_list.rb +1 -1
  66. data/lib/stripe/resources/radar/value_list_item.rb +1 -1
  67. data/lib/stripe/resources/recipient.rb +1 -5
  68. data/lib/stripe/resources/recipient_transfer.rb +1 -1
  69. data/lib/stripe/resources/refund.rb +1 -1
  70. data/lib/stripe/resources/reporting/report_run.rb +1 -1
  71. data/lib/stripe/resources/reporting/report_type.rb +1 -1
  72. data/lib/stripe/resources/reversal.rb +1 -1
  73. data/lib/stripe/resources/review.rb +1 -1
  74. data/lib/stripe/resources/setup_intent.rb +1 -1
  75. data/lib/stripe/resources/sigma/scheduled_query_run.rb +1 -1
  76. data/lib/stripe/resources/sku.rb +1 -1
  77. data/lib/stripe/resources/source.rb +1 -7
  78. data/lib/stripe/resources/source_transaction.rb +1 -1
  79. data/lib/stripe/resources/subscription.rb +9 -9
  80. data/lib/stripe/resources/subscription_item.rb +1 -1
  81. data/lib/stripe/resources/subscription_schedule.rb +1 -1
  82. data/lib/stripe/resources/tax_id.rb +1 -1
  83. data/lib/stripe/resources/tax_rate.rb +1 -1
  84. data/lib/stripe/resources/terminal/connection_token.rb +1 -1
  85. data/lib/stripe/resources/terminal/location.rb +1 -1
  86. data/lib/stripe/resources/terminal/reader.rb +1 -1
  87. data/lib/stripe/resources/three_d_secure.rb +1 -1
  88. data/lib/stripe/resources/token.rb +1 -1
  89. data/lib/stripe/resources/topup.rb +1 -1
  90. data/lib/stripe/resources/transfer.rb +1 -6
  91. data/lib/stripe/resources/usage_record.rb +1 -17
  92. data/lib/stripe/resources/usage_record_summary.rb +1 -1
  93. data/lib/stripe/resources/webhook_endpoint.rb +1 -1
  94. data/lib/stripe/stripe_client.rb +281 -183
  95. data/lib/stripe/stripe_object.rb +4 -23
  96. data/lib/stripe/stripe_response.rb +53 -21
  97. data/lib/stripe/util.rb +10 -11
  98. data/lib/stripe/version.rb +1 -1
  99. data/lib/stripe/webhook.rb +1 -1
  100. data/stripe.gemspec +6 -9
  101. data/test/stripe/account_test.rb +0 -16
  102. data/test/stripe/api_operations_test.rb +2 -2
  103. data/test/stripe/api_resource_test.rb +2 -10
  104. data/test/stripe/charge_test.rb +0 -16
  105. data/test/stripe/connection_manager_test.rb +138 -0
  106. data/test/stripe/customer_test.rb +1 -44
  107. data/test/stripe/errors_test.rb +29 -8
  108. data/test/stripe/file_test.rb +0 -10
  109. data/test/stripe/invoice_test.rb +17 -1
  110. data/test/stripe/list_object_test.rb +0 -16
  111. data/test/stripe/login_link_test.rb +1 -1
  112. data/test/stripe/multipart_encoder_test.rb +130 -0
  113. data/test/stripe/payment_intent_test.rb +1 -1
  114. data/test/stripe/setup_intent_test.rb +1 -1
  115. data/test/stripe/source_test.rb +0 -18
  116. data/test/stripe/stripe_client_test.rb +214 -29
  117. data/test/stripe/stripe_object_test.rb +7 -35
  118. data/test/stripe/stripe_response_test.rb +70 -24
  119. data/test/stripe/subscription_test.rb +2 -2
  120. data/test/stripe/webhook_test.rb +2 -2
  121. data/test/stripe_mock.rb +4 -3
  122. data/test/stripe_test.rb +0 -13
  123. data/test/test_helper.rb +10 -5
  124. metadata +11 -39
  125. data/lib/stripe/resources/issuer_fraud_record.rb +0 -9
  126. data/test/stripe/file_upload_test.rb +0 -79
  127. data/test/stripe/issuer_fraud_record_test.rb +0 -20
  128. data/test/stripe/usage_record_test.rb +0 -28
@@ -127,18 +127,6 @@ module Stripe
127
127
  JSON.pretty_generate(@values)
128
128
  end
129
129
 
130
- # Re-initializes the object based on a hash of values (usually one that's
131
- # come back from an API call). Adds or removes value accessors as necessary
132
- # and updates the state of internal data.
133
- #
134
- # Please don't use this method. If you're trying to do mass assignment, try
135
- # #initialize_from instead.
136
- def refresh_from(values, opts, partial = false)
137
- initialize_from(values, opts, partial)
138
- end
139
- extend Gem::Deprecate
140
- deprecate :refresh_from, "#update_attributes", 2016, 1
141
-
142
130
  # Mass assigns attributes on the model.
143
131
  #
144
132
  # This is a version of +update_attributes+ that takes some extra options
@@ -192,7 +180,9 @@ module Stripe
192
180
 
193
181
  def to_hash
194
182
  maybe_to_hash = lambda do |value|
195
- value && value.respond_to?(:to_hash) ? value.to_hash : value
183
+ return nil if value.nil?
184
+
185
+ value.respond_to?(:to_hash) ? value.to_hash : value
196
186
  end
197
187
 
198
188
  @values.each_with_object({}) do |(key, value), acc|
@@ -256,6 +246,7 @@ module Stripe
256
246
  #
257
247
  unsaved = @unsaved_values.include?(k)
258
248
  next unless options[:force] || unsaved || v.is_a?(StripeObject)
249
+
259
250
  update_hash[k.to_sym] = serialize_params_value(
260
251
  @values[k], @original_values[k], unsaved, options[:force], key: k
261
252
  )
@@ -268,16 +259,6 @@ module Stripe
268
259
  update_hash
269
260
  end
270
261
 
271
- class << self
272
- # This class method has been deprecated in favor of the instance method
273
- # of the same name.
274
- def serialize_params(obj, options = {})
275
- obj.serialize_params(options)
276
- end
277
- extend Gem::Deprecate
278
- deprecate :serialize_params, "#serialize_params", 2016, 9
279
- end
280
-
281
262
  # A protected field is one that doesn't get an accessor assigned to it
282
263
  # (i.e. `obj.public = ...`) and one which is not allowed to be updated via
283
264
  # the class level `Model.update(id, { ... })`.
@@ -4,6 +4,53 @@ module Stripe
4
4
  # StripeResponse encapsulates some vitals of a response that came back from
5
5
  # the Stripe API.
6
6
  class StripeResponse
7
+ # Headers provides an access wrapper to an API response's header data. It
8
+ # mainly exists so that we don't need to expose the entire
9
+ # `Net::HTTPResponse` object while still getting some of its benefits like
10
+ # case-insensitive access to header names and flattening of header values.
11
+ class Headers
12
+ # Initializes a Headers object from a Net::HTTP::HTTPResponse object.
13
+ def self.from_net_http(resp)
14
+ new(resp.to_hash)
15
+ end
16
+
17
+ # `hash` is expected to be a hash mapping header names to arrays of
18
+ # header values. This is the default format generated by calling
19
+ # `#to_hash` on a `Net::HTTPResponse` object because headers can be
20
+ # repeated multiple times. Using `#[]` will collapse values down to just
21
+ # the first.
22
+ def initialize(hash)
23
+ if !hash.is_a?(Hash) ||
24
+ !hash.keys.all? { |n| n.is_a?(String) } ||
25
+ !hash.values.all? { |a| a.is_a?(Array) } ||
26
+ !hash.values.all? { |a| a.all? { |v| v.is_a?(String) } }
27
+ raise ArgumentError,
28
+ "expect hash to be a map of string header names to arrays of " \
29
+ "header values"
30
+ end
31
+
32
+ @hash = {}
33
+
34
+ # This shouldn't be strictly necessary because `Net::HTTPResponse` will
35
+ # produce a hash with all headers downcased, but do it anyway just in
36
+ # case an object of this class was constructed manually.
37
+ #
38
+ # Also has the effect of duplicating the hash, which is desirable for a
39
+ # little extra object safety.
40
+ hash.each do |k, v|
41
+ @hash[k.downcase] = v
42
+ end
43
+ end
44
+
45
+ def [](name)
46
+ values = @hash[name.downcase]
47
+ if values && values.count > 1
48
+ warn("Duplicate header values for `#{name}`; returning only first")
49
+ end
50
+ values ? values.first : nil
51
+ end
52
+ end
53
+
7
54
  # The data contained by the HTTP body of the response deserialized from
8
55
  # JSON.
9
56
  attr_accessor :data
@@ -20,30 +67,15 @@ module Stripe
20
67
  # The Stripe request ID of the response.
21
68
  attr_accessor :request_id
22
69
 
23
- # Initializes a StripeResponse object from a Hash like the kind returned as
24
- # part of a Faraday exception.
25
- #
26
- # This may throw JSON::ParserError if the response body is not valid JSON.
27
- def self.from_faraday_hash(http_resp)
28
- resp = StripeResponse.new
29
- resp.data = JSON.parse(http_resp[:body], symbolize_names: true)
30
- resp.http_body = http_resp[:body]
31
- resp.http_headers = http_resp[:headers]
32
- resp.http_status = http_resp[:status]
33
- resp.request_id = http_resp[:headers]["Request-Id"]
34
- resp
35
- end
36
-
37
- # Initializes a StripeResponse object from a Faraday HTTP response object.
38
- #
39
- # This may throw JSON::ParserError if the response body is not valid JSON.
40
- def self.from_faraday_response(http_resp)
70
+ # Initializes a StripeResponse object from a Net::HTTP::HTTPResponse
71
+ # object.
72
+ def self.from_net_http(http_resp)
41
73
  resp = StripeResponse.new
42
74
  resp.data = JSON.parse(http_resp.body, symbolize_names: true)
43
75
  resp.http_body = http_resp.body
44
- resp.http_headers = http_resp.headers
45
- resp.http_status = http_resp.status
46
- resp.request_id = http_resp.headers["Request-Id"]
76
+ resp.http_headers = Headers.from_net_http(http_resp)
77
+ resp.http_status = http_resp.code.to_i
78
+ resp.request_id = http_resp["request-id"]
47
79
  resp
48
80
  end
49
81
  end
@@ -198,11 +198,13 @@ module Stripe
198
198
 
199
199
  def self.check_string_argument!(key)
200
200
  raise TypeError, "argument must be a string" unless key.is_a?(String)
201
+
201
202
  key
202
203
  end
203
204
 
204
205
  def self.check_api_key!(key)
205
206
  raise TypeError, "api_key must be a string" unless key.is_a?(String)
207
+
206
208
  key
207
209
  end
208
210
 
@@ -245,14 +247,14 @@ module Stripe
245
247
  #
246
248
 
247
249
  COLOR_CODES = {
248
- black: 0, light_black: 60,
249
- red: 1, light_red: 61,
250
- green: 2, light_green: 62,
251
- yellow: 3, light_yellow: 63,
252
- blue: 4, light_blue: 64,
250
+ black: 0, light_black: 60,
251
+ red: 1, light_red: 61,
252
+ green: 2, light_green: 62,
253
+ yellow: 3, light_yellow: 63,
254
+ blue: 4, light_blue: 64,
253
255
  magenta: 5, light_magenta: 65,
254
- cyan: 6, light_cyan: 66,
255
- white: 7, light_white: 67,
256
+ cyan: 6, light_cyan: 66,
257
+ white: 7, light_white: 67,
256
258
  default: 9,
257
259
  }.freeze
258
260
  private_constant :COLOR_CODES
@@ -281,10 +283,7 @@ module Stripe
281
283
  end
282
284
  private_class_method :level_name
283
285
 
284
- # TODO: Make these named required arguments when we drop support for Ruby
285
- # 2.0.
286
- def self.log_internal(message, data = {}, color: nil, level: nil,
287
- logger: nil, out: nil)
286
+ def self.log_internal(message, data = {}, color:, level:, logger:, out:)
288
287
  data_str = data.reject { |_k, v| v.nil? }
289
288
  .map do |(k, v)|
290
289
  format("%<key>s=%<value>s",
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Stripe
4
- VERSION = "4.24.0".freeze
4
+ VERSION = "5.0.0"
5
5
  end
@@ -22,7 +22,7 @@ module Stripe
22
22
  end
23
23
 
24
24
  module Signature
25
- EXPECTED_SCHEME = "v1".freeze
25
+ EXPECTED_SCHEME = "v1"
26
26
 
27
27
  def self.compute_signature(payload, secret)
28
28
  OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha256"), secret, payload)
@@ -7,7 +7,7 @@ require "stripe/version"
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "stripe"
9
9
  s.version = Stripe::VERSION
10
- s.required_ruby_version = ">= 2.1.0"
10
+ s.required_ruby_version = ">= 2.3.0"
11
11
  s.summary = "Ruby bindings for the Stripe API"
12
12
  s.description = "Stripe is the easiest way to accept payments online. " \
13
13
  "See https://stripe.com for details."
@@ -17,18 +17,15 @@ Gem::Specification.new do |s|
17
17
  s.license = "MIT"
18
18
 
19
19
  s.metadata = {
20
- "bug_tracker_uri" => "https://github.com/stripe/stripe-ruby/issues",
21
- "changelog_uri" =>
20
+ "bug_tracker_uri" => "https://github.com/stripe/stripe-ruby/issues",
21
+ "changelog_uri" =>
22
22
  "https://github.com/stripe/stripe-ruby/blob/master/CHANGELOG.md",
23
23
  "documentation_uri" => "https://stripe.com/docs/api/ruby",
24
- "github_repo" => "ssh://github.com/stripe/stripe-ruby",
25
- "homepage_uri" => "https://stripe.com/docs/api/ruby",
26
- "source_code_uri" => "https://github.com/stripe/stripe-ruby",
24
+ "github_repo" => "ssh://github.com/stripe/stripe-ruby",
25
+ "homepage_uri" => "https://stripe.com/docs/api/ruby",
26
+ "source_code_uri" => "https://github.com/stripe/stripe-ruby",
27
27
  }
28
28
 
29
- s.add_dependency("faraday", "~> 0.13")
30
- s.add_dependency("net-http-persistent", "~> 3.0")
31
-
32
29
  s.files = `git ls-files`.split("\n")
33
30
  s.test_files = `git ls-files -- test/*`.split("\n")
34
31
  s.executables = `git ls-files -- bin/*`.split("\n")
@@ -82,22 +82,6 @@ module Stripe
82
82
  assert persons.data[0].is_a?(Stripe::Person)
83
83
  end
84
84
 
85
- context "#bank_account=" do
86
- should "warn that #bank_account= is deprecated" do
87
- old_stderr = $stderr
88
- $stderr = StringIO.new
89
- begin
90
- account = Stripe::Account.retrieve("acct_123")
91
- account.bank_account = "tok_123"
92
- message = "NOTE: Stripe::Account#bank_account= is " \
93
- "deprecated; use #external_account= instead"
94
- assert_match Regexp.new(message), $stderr.string
95
- ensure
96
- $stderr = old_stderr
97
- end
98
- end
99
- end
100
-
101
85
  context "#deauthorize" do
102
86
  should "deauthorize an account" do
103
87
  account = Stripe::Account.retrieve("acct_123")
@@ -7,7 +7,7 @@ module Stripe
7
7
  class UpdateableResource < APIResource
8
8
  include Stripe::APIOperations::Save
9
9
 
10
- OBJECT_NAME = "updateableresource".freeze
10
+ OBJECT_NAME = "updateableresource"
11
11
 
12
12
  def self.protected_fields
13
13
  [:protected]
@@ -34,7 +34,7 @@ module Stripe
34
34
  context ".nested_resource_class_methods" do
35
35
  class MainResource < APIResource
36
36
  extend Stripe::APIOperations::NestedResource
37
- OBJECT_NAME = "mainresource".freeze
37
+ OBJECT_NAME = "mainresource"
38
38
  nested_resource_class_methods :nested,
39
39
  operations: %i[create retrieve update delete list]
40
40
  end
@@ -5,7 +5,7 @@ require ::File.expand_path("../test_helper", __dir__)
5
5
  module Stripe
6
6
  class ApiResourceTest < Test::Unit::TestCase
7
7
  class CustomMethodAPIResource < APIResource
8
- OBJECT_NAME = "custom_method".freeze
8
+ OBJECT_NAME = "custom_method"
9
9
  custom_method :my_method, http_verb: :post
10
10
  end
11
11
 
@@ -271,14 +271,6 @@ module Stripe
271
271
  assert_equal c.created, 12_345
272
272
  end
273
273
 
274
- should "accessing a property other than id or parent on an unfetched object should fetch it" do
275
- stub_request(:get, "#{Stripe.api_base}/v1/charges")
276
- .with(query: { customer: "cus_123" })
277
- .to_return(body: JSON.generate(customer_fixture))
278
- c = Stripe::Customer.new("cus_123")
279
- c.charges
280
- end
281
-
282
274
  should "updating an object should issue a POST request with only the changed properties" do
283
275
  stub_request(:post, "#{Stripe.api_base}/v1/customers/cus_123")
284
276
  .with(body: { "description" => "another_mn" })
@@ -513,7 +505,7 @@ module Stripe
513
505
 
514
506
  context "#request_stripe_object" do
515
507
  class HelloTestAPIResource < APIResource
516
- OBJECT_NAME = "hello".freeze
508
+ OBJECT_NAME = "hello"
517
509
  def say_hello(params = {}, opts = {})
518
510
  request_stripe_object(
519
511
  method: :post,
@@ -60,21 +60,5 @@ module Stripe
60
60
  assert charge.is_a?(Stripe::Charge)
61
61
  end
62
62
  end
63
-
64
- context "#mark_as_fraudulent" do
65
- should "charges should be able to be marked as fraudulent" do
66
- charge = Stripe::Charge.retrieve("ch_123")
67
- charge = charge.mark_as_fraudulent
68
- assert charge.is_a?(Stripe::Charge)
69
- end
70
- end
71
-
72
- context "#mark_as_safe" do
73
- should "charges should be able to be marked as safe" do
74
- charge = Stripe::Charge.retrieve("ch_123")
75
- charge = charge.mark_as_safe
76
- assert charge.is_a?(Stripe::Charge)
77
- end
78
- end
79
63
  end
80
64
  end
@@ -0,0 +1,138 @@
1
+ # frozen_string_literal: true
2
+
3
+ require ::File.expand_path("../test_helper", __dir__)
4
+
5
+ module Stripe
6
+ class ConnectionManagerTest < Test::Unit::TestCase
7
+ setup do
8
+ @manager = Stripe::ConnectionManager.new
9
+ end
10
+
11
+ context "#clear" do
12
+ should "clear any active connections" do
13
+ stub_request(:post, "#{Stripe.api_base}/path")
14
+ .to_return(body: JSON.generate(object: "account"))
15
+
16
+ # Making a request lets us know that at least one connection is open.
17
+ @manager.execute_request(:post, "#{Stripe.api_base}/path")
18
+
19
+ # Now clear the manager.
20
+ @manager.clear
21
+
22
+ # This check isn't great, but it's otherwise difficult to tell that
23
+ # anything happened with just the public-facing API.
24
+ assert_equal({}, @manager.instance_variable_get(:@active_connections))
25
+ end
26
+ end
27
+
28
+ context "#connection_for" do
29
+ should "correctly initialize a connection" do
30
+ old_proxy = Stripe.proxy
31
+
32
+ old_open_timeout = Stripe.open_timeout
33
+ old_read_timeout = Stripe.read_timeout
34
+
35
+ begin
36
+ # Make sure any global initialization here is undone in the `ensure`
37
+ # block below.
38
+ Stripe.proxy = "http://user:pass@localhost:8080"
39
+
40
+ Stripe.open_timeout = 123
41
+ Stripe.read_timeout = 456
42
+
43
+ conn = @manager.connection_for("https://stripe.com")
44
+
45
+ # Host/port
46
+ assert_equal "stripe.com", conn.address
47
+ assert_equal 443, conn.port
48
+
49
+ # Proxy
50
+ assert_equal "localhost", conn.proxy_address
51
+ assert_equal 8080, conn.proxy_port
52
+ assert_equal "user", conn.proxy_user
53
+ assert_equal "pass", conn.proxy_pass
54
+
55
+ # Timeouts
56
+ assert_equal 123, conn.open_timeout
57
+ assert_equal 456, conn.read_timeout
58
+
59
+ assert_equal true, conn.use_ssl?
60
+ assert_equal OpenSSL::SSL::VERIFY_PEER, conn.verify_mode
61
+ assert_equal Stripe.ca_store, conn.cert_store
62
+ ensure
63
+ Stripe.proxy = old_proxy
64
+
65
+ Stripe.open_timeout = old_open_timeout
66
+ Stripe.read_timeout = old_read_timeout
67
+ end
68
+ end
69
+
70
+ should "produce the same connection multiple times" do
71
+ conn1 = @manager.connection_for("https://stripe.com")
72
+ conn2 = @manager.connection_for("https://stripe.com")
73
+
74
+ assert_equal conn1, conn2
75
+ end
76
+
77
+ should "produce different connections for different hosts" do
78
+ conn1 = @manager.connection_for("https://example.com")
79
+ conn2 = @manager.connection_for("https://stripe.com")
80
+
81
+ refute_equal conn1, conn2
82
+ end
83
+
84
+ should "produce different connections for different ports" do
85
+ conn1 = @manager.connection_for("https://stripe.com:80")
86
+ conn2 = @manager.connection_for("https://stripe.com:443")
87
+
88
+ refute_equal conn1, conn2
89
+ end
90
+ end
91
+
92
+ context "#execute_request" do
93
+ should "make a request" do
94
+ stub_request(:post, "#{Stripe.api_base}/path?query=bar")
95
+ .with(
96
+ body: "body=foo",
97
+ headers: { "Stripe-Account" => "bar" }
98
+ )
99
+ .to_return(body: JSON.generate(object: "account"))
100
+
101
+ @manager.execute_request(:post, "#{Stripe.api_base}/path",
102
+ body: "body=foo",
103
+ headers: { "Stripe-Account" => "bar" },
104
+ query: "query=bar")
105
+ end
106
+
107
+ should "perform basic argument validation" do
108
+ e = assert_raises ArgumentError do
109
+ @manager.execute_request("POST", "#{Stripe.api_base}/path")
110
+ end
111
+ assert_equal e.message, "method should be a symbol"
112
+
113
+ e = assert_raises ArgumentError do
114
+ @manager.execute_request(:post, :uri)
115
+ end
116
+ assert_equal e.message, "uri should be a string"
117
+
118
+ e = assert_raises ArgumentError do
119
+ @manager.execute_request(:post, "#{Stripe.api_base}/path",
120
+ body: {})
121
+ end
122
+ assert_equal e.message, "body should be a string"
123
+
124
+ e = assert_raises ArgumentError do
125
+ @manager.execute_request(:post, "#{Stripe.api_base}/path",
126
+ headers: "foo")
127
+ end
128
+ assert_equal e.message, "headers should be a hash"
129
+
130
+ e = assert_raises ArgumentError do
131
+ @manager.execute_request(:post, "#{Stripe.api_base}/path",
132
+ query: {})
133
+ end
134
+ assert_equal e.message, "query should be a string"
135
+ end
136
+ end
137
+ end
138
+ end