stripe 4.24.0 → 5.0.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 (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