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 +4 -4
- data/CHANGELOG.md +27 -1
- data/README.md +4 -0
- data/lib/webmock/http_lib_adapters/net_http.rb +13 -33
- data/lib/webmock/request_pattern.rb +23 -7
- data/lib/webmock/version.rb +1 -1
- data/spec/acceptance/net_http/net_http_spec.rb +22 -23
- data/spec/acceptance/patron/patron_spec.rb +19 -21
- data/spec/unit/request_pattern_spec.rb +12 -0
- data/webmock.gemspec +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e4cbe1f0f2f191bea7fda094073e265aeff44e1669d1222da5cb724e5124eb55
|
4
|
+
data.tar.gz: e631266b6f082b93800e815a9dc0aa071a60a89c1f803bf3eee739e6b97820a2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4911f51bd82520812df827796996ab8cf9975f1bee625a158f4644f8c121bbf34172266cd3097ef0609750d51d0c987ea7a645df077f936924f2ea0915f1c0a1
|
7
|
+
data.tar.gz: bc053c6d94f668d75c1e97629dd9ba38f018ffb2355f5cd97e1f5e54015f6adf02c6f9cac2abf6b5c13d7d4fcd69d1bae77b45cffa2b2b8488fa4d0a1c53e1b3
|
data/CHANGELOG.md
CHANGED
@@ -1,9 +1,35 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
-
# 3.
|
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
|
-
|
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
|
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
|
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
|
-
|
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
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
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
|
data/lib/webmock/version.rb
CHANGED
@@ -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
|
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
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
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
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
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
|
-
|
106
|
-
|
107
|
-
|
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
|
-
|
110
|
-
|
111
|
-
|
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
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
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
|
-
|
119
|
-
|
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 = '
|
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.
|
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-
|
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:
|
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.
|
425
|
-
documentation_uri: https://www.rubydoc.info/gems/webmock/3.
|
426
|
-
source_code_uri: https://github.com/bblimke/webmock/tree/v3.
|
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: []
|