webmock 3.16.1 → 3.17.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 263012f9e44fcac8ea946df8447eab008528eb83677b83a63ba4558c9f66fbf7
4
- data.tar.gz: d5dbeaaba04501fbeeac6a10a95d8d5c9eca1824fec719d26b2ea769630bbce7
3
+ metadata.gz: e4cbe1f0f2f191bea7fda094073e265aeff44e1669d1222da5cb724e5124eb55
4
+ data.tar.gz: e631266b6f082b93800e815a9dc0aa071a60a89c1f803bf3eee739e6b97820a2
5
5
  SHA512:
6
- metadata.gz: bbaa6dfb6563bf64a3ddf902977345cac5e909503db5eda9cd4f39a799a81f8f23d740bb113d860596752ad27ac8cd0ee2f1d3a9f91d535d611e7bba1c192547
7
- data.tar.gz: 7732c64762933e689c2f5cbe147cc430580be9bfe5cc6b1480ccefdcf683a3849438090070e02f4f9ea5b4bfaa59e8c68028092e305c01147567b04357585211
6
+ metadata.gz: 4911f51bd82520812df827796996ab8cf9975f1bee625a158f4644f8c121bbf34172266cd3097ef0609750d51d0c987ea7a645df077f936924f2ea0915f1c0a1
7
+ data.tar.gz: bc053c6d94f668d75c1e97629dd9ba38f018ffb2355f5cd97e1f5e54015f6adf02c6f9cac2abf6b5c13d7d4fcd69d1bae77b45cffa2b2b8488fa4d0a1c53e1b3
data/CHANGELOG.md CHANGED
@@ -1,9 +1,35 @@
1
1
  # Changelog
2
2
 
3
- # 3.16.1
3
+ # 3.17.1
4
+
5
+ * Fixed Syntax Error
6
+
7
+ Thanks to [Mark Spangler](https://github.com/mspangler)
8
+
9
+ # 3.17.0
4
10
 
5
11
  * Minimum required Ruby version is 2.3
6
12
 
13
+ Thanks to [Go Sueyoshi](https://github.com/sue445)
14
+
15
+ * When using Net::HTTP, stubbed socket StubSocket#close and StubSocket#closed? behave more like the real sockets.
16
+
17
+ Thanks to [Ray Zane](https://github.com/rzane)
18
+
19
+ * Added `peeraddr`, `ssl_version` and `cipher` methods to stubbed sockets used by Net::HTTP.
20
+
21
+ Thanks to [Ray Zane](https://github.com/rzane)
22
+
23
+ * Added support for matching top-level array in JSON request body.
24
+
25
+ E.g.
26
+
27
+ ````
28
+ stub_request(:post, 'www.example.com').with(body: [{a: 1}])
29
+ ````
30
+
31
+ Thanks to [Cedric Sohrauer](https://github.com/cedrics)
32
+
7
33
  # 3.16.0
8
34
 
9
35
  * Fix leaky file descriptors and reuse socket for persistent connections.
data/README.md CHANGED
@@ -1166,6 +1166,10 @@ People who submitted patches and new features or suggested improvements. Many th
1166
1166
  * Timmitry
1167
1167
  * Michael Fairley
1168
1168
  * Ray Zane
1169
+ * Go Sueyoshi
1170
+ * Cedric Sohrauer
1171
+ * Akira Matsuda
1172
+ * Mark Spangler
1169
1173
 
1170
1174
  For a full list of contributors you can visit the
1171
1175
  [contributors](https://github.com/bblimke/webmock/contributors) page.
@@ -128,7 +128,11 @@ module WebMock
128
128
 
129
129
 
130
130
  def ensure_actual_connection
131
- do_start if @socket.is_a?(StubSocket)
131
+ if @socket.is_a?(StubSocket)
132
+ @socket&.close
133
+ @socket = nil
134
+ do_start
135
+ end
132
136
  end
133
137
 
134
138
  alias_method :start_with_connect, :start
@@ -161,7 +165,7 @@ module WebMock
161
165
  response.extend Net::WebMockHTTPResponse
162
166
 
163
167
  if webmock_response.should_timeout
164
- raise timeout_exception, "execution expired"
168
+ raise Net::OpenTimeout, "execution expired"
165
169
  end
166
170
 
167
171
  webmock_response.raise_error_if_any
@@ -171,16 +175,6 @@ module WebMock
171
175
  response
172
176
  end
173
177
 
174
- def timeout_exception
175
- if defined?(Net::OpenTimeout)
176
- # Ruby 2.x
177
- Net::OpenTimeout
178
- else
179
- # Fallback, if things change
180
- Timeout::Error
181
- end
182
- end
183
-
184
178
  def build_webmock_response(net_http_response)
185
179
  webmock_response = WebMock::Response.new
186
180
  webmock_response.status = [
@@ -232,13 +226,16 @@ class StubSocket #:nodoc:
232
226
  attr_accessor :read_timeout, :continue_timeout, :write_timeout
233
227
 
234
228
  def initialize(*args)
229
+ @closed = false
235
230
  end
236
231
 
237
232
  def closed?
238
- @closed ||= true
233
+ @closed
239
234
  end
240
235
 
241
236
  def close
237
+ @closed = true
238
+ nil
242
239
  end
243
240
 
244
241
  def readuntil(*args)
@@ -251,6 +248,9 @@ class StubSocket #:nodoc:
251
248
  class StubIO
252
249
  def setsockopt(*args); end
253
250
  def peer_cert; end
251
+ def peeraddr; ["AF_INET", 443, "127.0.0.1", "127.0.0.1"] end
252
+ def ssl_version; "TLSv1.3" end
253
+ def cipher; ["TLS_AES_128_GCM_SHA256", "TLSv1.3", 128, 128] end
254
254
  end
255
255
  end
256
256
 
@@ -318,7 +318,6 @@ module WebMock
318
318
  method = request.method.downcase.to_sym
319
319
 
320
320
  headers = Hash[*request.to_hash.map {|k,v| [k, v]}.inject([]) {|r,x| r + x}]
321
- validate_headers(headers)
322
321
 
323
322
  if request.body_stream
324
323
  body = request.body_stream.read
@@ -343,25 +342,6 @@ module WebMock
343
342
  "#{protocol}://#{hostname}:#{net_http.port}#{path}"
344
343
  end
345
344
 
346
- def self.validate_headers(headers)
347
- # For Ruby versions < 2.3.0, if you make a request with headers that are symbols
348
- # Net::HTTP raises a NoMethodError
349
- #
350
- # WebMock normalizes headers when creating a RequestSignature,
351
- # and will update all headers from symbols to strings.
352
- #
353
- # This could create a false positive in a test suite with WebMock.
354
- #
355
- # So before this point, WebMock raises an ArgumentError if any of the headers are symbols
356
- # instead of the cryptic NoMethodError "undefined method `split' ...` from Net::HTTP
357
- if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.3.0')
358
- header_as_symbol = headers.keys.find {|header| header.is_a? Symbol}
359
- if header_as_symbol
360
- raise ArgumentError.new("Net:HTTP does not accept headers as symbols")
361
- end
362
- end
363
- end
364
-
365
345
  def self.check_right_http_connection
366
346
  @was_right_http_connection_loaded = defined?(RightHttpConnection)
367
347
  end
@@ -281,6 +281,8 @@ module WebMock
281
281
  if (@pattern).is_a?(Hash)
282
282
  return true if @pattern.empty?
283
283
  matching_body_hashes?(body_as_hash(body, content_type), @pattern, content_type)
284
+ elsif (@pattern).is_a?(Array)
285
+ matching_body_array?(body_as_hash(body, content_type), @pattern, content_type)
284
286
  elsif (@pattern).is_a?(WebMock::Matchers::HashIncludingMatcher)
285
287
  @pattern == body_as_hash(body, content_type)
286
288
  else
@@ -344,19 +346,33 @@ module WebMock
344
346
  def matching_body_hashes?(query_parameters, pattern, content_type)
345
347
  return false unless query_parameters.is_a?(Hash)
346
348
  return false unless query_parameters.keys.sort == pattern.keys.sort
347
- query_parameters.each do |key, actual|
349
+
350
+ query_parameters.all? do |key, actual|
348
351
  expected = pattern[key]
352
+ matching_values(actual, expected, content_type)
353
+ end
354
+ end
349
355
 
350
- if actual.is_a?(Hash) && expected.is_a?(Hash)
351
- return false unless matching_body_hashes?(actual, expected, content_type)
352
- else
353
- expected = WebMock::Util::ValuesStringifier.stringify_values(expected) if url_encoded_body?(content_type)
354
- return false unless expected === actual
355
- end
356
+ def matching_body_array?(query_parameters, pattern, content_type)
357
+ return false unless query_parameters.is_a?(Array)
358
+ return false unless query_parameters.length == pattern.length
359
+
360
+ query_parameters.each_with_index do |actual, index|
361
+ expected = pattern[index]
362
+ return false unless matching_values(actual, expected, content_type)
356
363
  end
364
+
357
365
  true
358
366
  end
359
367
 
368
+ def matching_values(actual, expected, content_type)
369
+ return matching_body_hashes?(actual, expected, content_type) if actual.is_a?(Hash) && expected.is_a?(Hash)
370
+ return matching_body_array?(actual, expected, content_type) if actual.is_a?(Array) && expected.is_a?(Array)
371
+
372
+ expected = WebMock::Util::ValuesStringifier.stringify_values(expected) if url_encoded_body?(content_type)
373
+ expected === actual
374
+ end
375
+
360
376
  def empty_string?(string)
361
377
  string.nil? || string == ""
362
378
  end
@@ -1,3 +1,3 @@
1
1
  module WebMock
2
- VERSION = '3.16.1' unless defined?(::WebMock::VERSION)
2
+ VERSION = '3.17.1' unless defined?(::WebMock::VERSION)
3
3
  end
@@ -115,33 +115,16 @@ describe "Net:HTTP" do
115
115
  expect(Net::HTTP.start("www.example.com") { |http| http.request(req)}.body).to eq("abc")
116
116
  end
117
117
 
118
- it "raises an ArgumentError if passed headers as symbols if RUBY_VERSION < 2.3.0" do
118
+ it "raises an ArgumentError if passed headers as symbols" do
119
119
  uri = URI.parse("http://google.com/")
120
120
  http = Net::HTTP.new(uri.host, uri.port)
121
121
  request = Net::HTTP::Get.new(uri.request_uri)
122
+ request[:InvalidHeaderSinceItsASymbol] = "this will not be valid"
122
123
 
123
- # Net::HTTP calls downcase on header keys assigned with []=
124
- # In Ruby 1.8.7 symbols do not respond to downcase
125
- #
126
- # Meaning you can not assign header keys as symbols in ruby 1.8.7 using []=
127
- if :symbol.respond_to?(:downcase)
128
- request[:InvalidHeaderSinceItsASymbol] = "this will not be valid"
129
- else
130
- request.instance_eval do
131
- @header = request.to_hash.merge({InvalidHeaderSinceItsASymbol: "this will not be valid"})
132
- end
133
- end
134
-
135
- if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.3.0')
136
- expect do
137
- http.request(request)
138
- end.to raise_error ArgumentError, "Net:HTTP does not accept headers as symbols"
139
- else
140
- stub_http_request(:get, "google.com").with(headers: { InvalidHeaderSinceItsASymbol: "this will not be valid" })
141
- expect do
142
- http.request(request)
143
- end.not_to raise_error
144
- end
124
+ stub_http_request(:get, "google.com").with(headers: { InvalidHeaderSinceItsASymbol: "this will not be valid" })
125
+ expect do
126
+ http.request(request)
127
+ end.not_to raise_error
145
128
  end
146
129
 
147
130
  it "should handle multiple values for the same response header" do
@@ -213,6 +196,22 @@ describe "Net:HTTP" do
213
196
  end
214
197
  end
215
198
 
199
+ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7.0')
200
+ it "uses the StubSocket to provide IP address" do
201
+ Net::HTTP.start("http://example.com") do |http|
202
+ expect(http.ipaddr).to eq("127.0.0.1")
203
+ end
204
+ end
205
+ end
206
+
207
+ it "defines common socket methods" do
208
+ Net::HTTP.start("http://example.com") do |http|
209
+ socket = http.instance_variable_get(:@socket)
210
+ expect(socket.io.ssl_version).to eq("TLSv1.3")
211
+ expect(socket.io.cipher).to eq(["TLS_AES_128_GCM_SHA256", "TLSv1.3", 128, 128])
212
+ end
213
+ end
214
+
216
215
  describe "connecting on Net::HTTP.start" do
217
216
  before(:each) do
218
217
  @http = Net::HTTP.new('www.google.com', 443)
@@ -93,31 +93,29 @@ unless RUBY_PLATFORM =~ /java/
93
93
  @sess.copy("/abc", "/def")
94
94
  end
95
95
 
96
- if /^1\.9/ === RUBY_VERSION
97
- describe "handling encoding same way as patron" do
98
- around(:each) do |example|
99
- @encoding = Encoding.default_internal
100
- Encoding.default_internal = "UTF-8"
101
- example.run
102
- Encoding.default_internal = @encoding
103
- end
96
+ describe "handling encoding same way as patron" do
97
+ around(:each) do |example|
98
+ @encoding = Encoding.default_internal
99
+ Encoding.default_internal = "UTF-8"
100
+ example.run
101
+ Encoding.default_internal = @encoding
102
+ end
104
103
 
105
- it "should not encode body with default encoding" do
106
- stub_request(:get, "www.example.com").
107
- to_return(body: "Øl")
104
+ it "should not encode body with default encoding" do
105
+ stub_request(:get, "www.example.com").
106
+ to_return(body: "Øl")
108
107
 
109
- expect(@sess.get("").body.encoding).to eq(Encoding::ASCII_8BIT)
110
- expect(@sess.get("").inspectable_body.encoding).to eq(Encoding::UTF_8)
111
- end
108
+ expect(@sess.get("").body.encoding).to eq(Encoding::ASCII_8BIT)
109
+ expect(@sess.get("").inspectable_body.encoding).to eq(Encoding::UTF_8)
110
+ end
112
111
 
113
- it "should not encode body to default internal" do
114
- stub_request(:get, "www.example.com").
115
- to_return(headers: {'Content-Type' => 'text/html; charset=iso-8859-1'},
116
- body: "Øl".encode("iso-8859-1"))
112
+ it "should not encode body to default internal" do
113
+ stub_request(:get, "www.example.com").
114
+ to_return(headers: {'Content-Type' => 'text/html; charset=iso-8859-1'},
115
+ body: "Øl".encode("iso-8859-1"))
117
116
 
118
- expect(@sess.get("").body.encoding).to eq(Encoding::ASCII_8BIT)
119
- expect(@sess.get("").decoded_body.encoding).to eq(Encoding.default_internal)
120
- end
117
+ expect(@sess.get("").body.encoding).to eq(Encoding::ASCII_8BIT)
118
+ expect(@sess.get("").decoded_body.encoding).to eq(Encoding.default_internal)
121
119
  end
122
120
  end
123
121
  end
@@ -547,6 +547,18 @@ describe WebMock::RequestPattern do
547
547
  body: "{\"a\":\"1\",\"b\":\"five\",\"c\":{\"d\":[\"e\",\"f\"]}}"))
548
548
  end
549
549
 
550
+ it "should match if the request body has a top level array" do
551
+ expect(WebMock::RequestPattern.new(:post, 'www.example.com', body: [{a: 1}])).
552
+ to match(WebMock::RequestSignature.new(:post, "www.example.com",
553
+ headers: {content_type: content_type}, body: "[{\"a\":1}]"))
554
+ end
555
+
556
+ it "should not match if the request body has a different top level array" do
557
+ expect(WebMock::RequestPattern.new(:post, 'www.example.com', body: ["a", "b"])).
558
+ not_to match(WebMock::RequestSignature.new(:post, "www.example.com",
559
+ headers: {content_type: content_type}, body: "[\"a\", \"c\"]"))
560
+ end
561
+
550
562
  it "should not match when body is not json" do
551
563
  expect(WebMock::RequestPattern.new(:post, 'www.example.com', body: body_hash)).
552
564
  not_to match(WebMock::RequestSignature.new(:post, "www.example.com",
data/webmock.gemspec CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |s|
8
8
  s.platform = Gem::Platform::RUBY
9
9
  s.authors = ['Bartosz Blimke']
10
10
  s.email = ['bartosz.blimke@gmail.com']
11
- s.homepage = 'http://github.com/bblimke/webmock'
11
+ s.homepage = 'https://github.com/bblimke/webmock'
12
12
  s.summary = %q{Library for stubbing HTTP requests in Ruby.}
13
13
  s.description = %q{WebMock allows stubbing HTTP requests and setting expectations on HTTP requests.}
14
14
  s.license = "MIT"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webmock
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.16.1
4
+ version: 3.17.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bartosz Blimke
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-08-10 00:00:00.000000000 Z
11
+ date: 2022-08-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -416,14 +416,14 @@ files:
416
416
  - test/test_helper.rb
417
417
  - test/test_webmock.rb
418
418
  - webmock.gemspec
419
- homepage: http://github.com/bblimke/webmock
419
+ homepage: https://github.com/bblimke/webmock
420
420
  licenses:
421
421
  - MIT
422
422
  metadata:
423
423
  bug_tracker_uri: https://github.com/bblimke/webmock/issues
424
- changelog_uri: https://github.com/bblimke/webmock/blob/v3.16.1/CHANGELOG.md
425
- documentation_uri: https://www.rubydoc.info/gems/webmock/3.16.1
426
- source_code_uri: https://github.com/bblimke/webmock/tree/v3.16.1
424
+ changelog_uri: https://github.com/bblimke/webmock/blob/v3.17.1/CHANGELOG.md
425
+ documentation_uri: https://www.rubydoc.info/gems/webmock/3.17.1
426
+ source_code_uri: https://github.com/bblimke/webmock/tree/v3.17.1
427
427
  wiki_uri: https://github.com/bblimke/webmock/wiki
428
428
  post_install_message:
429
429
  rdoc_options: []