webmock 3.16.1 → 3.17.1

Sign up to get free protection for your applications and to get access to all the features.
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: []