webmock 3.9.1 → 3.18.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/.github/workflows/CI.yml +38 -0
- data/CHANGELOG.md +180 -6
- data/Gemfile +1 -1
- data/README.md +63 -30
- data/Rakefile +12 -2
- data/lib/webmock/http_lib_adapters/async_http_client_adapter.rb +11 -4
- data/lib/webmock/http_lib_adapters/curb_adapter.rb +2 -2
- data/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +6 -3
- data/lib/webmock/http_lib_adapters/http_rb/client.rb +2 -1
- data/lib/webmock/http_lib_adapters/http_rb/response.rb +17 -3
- data/lib/webmock/http_lib_adapters/http_rb/streamer.rb +4 -2
- data/lib/webmock/http_lib_adapters/http_rb/webmock.rb +6 -2
- data/lib/webmock/http_lib_adapters/httpclient_adapter.rb +23 -6
- data/lib/webmock/http_lib_adapters/manticore_adapter.rb +8 -1
- data/lib/webmock/http_lib_adapters/net_http.rb +29 -115
- data/lib/webmock/request_pattern.rb +30 -8
- data/lib/webmock/request_signature.rb +2 -2
- data/lib/webmock/request_stub.rb +15 -0
- data/lib/webmock/response.rb +19 -13
- data/lib/webmock/stub_registry.rb +24 -9
- data/lib/webmock/test_unit.rb +1 -3
- data/lib/webmock/version.rb +1 -1
- data/lib/webmock/webmock.rb +12 -2
- data/minitest/webmock_spec.rb +1 -1
- data/spec/acceptance/async_http_client/async_http_client_spec.rb +27 -5
- data/spec/acceptance/curb/curb_spec.rb +11 -0
- data/spec/acceptance/em_http_request/em_http_request_spec.rb +57 -1
- data/spec/acceptance/em_http_request/em_http_request_spec_helper.rb +1 -1
- data/spec/acceptance/excon/excon_spec.rb +2 -2
- data/spec/acceptance/manticore/manticore_spec.rb +32 -0
- data/spec/acceptance/net_http/net_http_shared.rb +46 -9
- data/spec/acceptance/net_http/net_http_spec.rb +75 -23
- data/spec/acceptance/net_http/real_net_http_spec.rb +1 -1
- data/spec/acceptance/patron/patron_spec.rb +19 -21
- data/spec/acceptance/patron/patron_spec_helper.rb +2 -2
- data/spec/acceptance/shared/allowing_and_disabling_net_connect.rb +14 -14
- data/spec/acceptance/shared/callbacks.rb +2 -2
- data/spec/acceptance/shared/complex_cross_concern_behaviors.rb +1 -1
- data/spec/acceptance/shared/stubbing_requests.rb +17 -0
- data/spec/unit/request_pattern_spec.rb +82 -46
- data/spec/unit/request_signature_spec.rb +21 -1
- data/spec/unit/request_stub_spec.rb +35 -0
- data/spec/unit/response_spec.rb +51 -19
- data/spec/unit/webmock_spec.rb +54 -0
- data/test/test_webmock.rb +6 -0
- data/webmock.gemspec +6 -5
- metadata +49 -35
- data/.travis.yml +0 -24
@@ -135,6 +135,28 @@ unless RUBY_PLATFORM =~ /java/
|
|
135
135
|
expect { make_request(:get, 'http://www.example.com') }.to raise_error Async::TimeoutError
|
136
136
|
end
|
137
137
|
|
138
|
+
it 'does not invoke "after real request" callbacks for stubbed requests' do
|
139
|
+
WebMock.allow_net_connect!
|
140
|
+
stub_request(:get, 'http://www.example.com').to_return(body: 'abc')
|
141
|
+
|
142
|
+
callback_invoked = false
|
143
|
+
WebMock.after_request(real_requests_only: true) { |_| callback_invoked = true }
|
144
|
+
|
145
|
+
make_request(:get, 'http://www.example.com')
|
146
|
+
expect(callback_invoked).to eq(false)
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'does invoke "after request" callbacks for stubbed requests' do
|
150
|
+
WebMock.allow_net_connect!
|
151
|
+
stub_request(:get, 'http://www.example.com').to_return(body: 'abc')
|
152
|
+
|
153
|
+
callback_invoked = false
|
154
|
+
WebMock.after_request(real_requests_only: false) { |_| callback_invoked = true }
|
155
|
+
|
156
|
+
make_request(:get, 'http://www.example.com')
|
157
|
+
expect(callback_invoked).to eq(true)
|
158
|
+
end
|
159
|
+
|
138
160
|
context 'scheme and protocol' do
|
139
161
|
let(:default_response_headers) { {} }
|
140
162
|
|
@@ -226,7 +248,7 @@ unless RUBY_PLATFORM =~ /java/
|
|
226
248
|
end
|
227
249
|
|
228
250
|
context 'multiple requests' do
|
229
|
-
let(:endpoint) { Async::HTTP::Endpoint.parse('http://www.example.com') }
|
251
|
+
let!(:endpoint) { Async::HTTP::Endpoint.parse('http://www.example.com') }
|
230
252
|
let(:requests_count) { 3 }
|
231
253
|
|
232
254
|
shared_examples :common do
|
@@ -278,13 +300,13 @@ unless RUBY_PLATFORM =~ /java/
|
|
278
300
|
end
|
279
301
|
|
280
302
|
context 'HTTP1 protocol' do
|
281
|
-
let(:protocol) { Async::HTTP::Protocol::HTTP1 }
|
303
|
+
let!(:protocol) { Async::HTTP::Protocol::HTTP1 }
|
282
304
|
|
283
305
|
include_examples :common
|
284
306
|
end
|
285
307
|
|
286
308
|
context 'HTTP2 protocol' do
|
287
|
-
let(:protocol) { Async::HTTP::Protocol::HTTP2 }
|
309
|
+
let!(:protocol) { Async::HTTP::Protocol::HTTP2 }
|
288
310
|
|
289
311
|
include_examples :common
|
290
312
|
end
|
@@ -309,13 +331,13 @@ unless RUBY_PLATFORM =~ /java/
|
|
309
331
|
end
|
310
332
|
|
311
333
|
context 'HTTP1 protocol' do
|
312
|
-
let(:protocol) { Async::HTTP::Protocol::HTTP1 }
|
334
|
+
let!(:protocol) { Async::HTTP::Protocol::HTTP1 }
|
313
335
|
|
314
336
|
include_examples :common
|
315
337
|
end
|
316
338
|
|
317
339
|
context 'HTTP2 protocol' do
|
318
|
-
let(:protocol) { Async::HTTP::Protocol::HTTP2 }
|
340
|
+
let!(:protocol) { Async::HTTP::Protocol::HTTP2 }
|
319
341
|
|
320
342
|
include_examples :common
|
321
343
|
end
|
@@ -383,6 +383,17 @@ unless RUBY_PLATFORM =~ /java/
|
|
383
383
|
expect(c.body).to eq("abc")
|
384
384
|
end
|
385
385
|
|
386
|
+
it "supports headers containing the ':' character" do
|
387
|
+
stub_request(:get, "www.example.com").with(headers: {'Referer'=>'http://www.example.com'}).to_return(body: "abc")
|
388
|
+
|
389
|
+
c = Curl::Easy.new
|
390
|
+
c.url = "http://www.example.com"
|
391
|
+
c.headers = ["Referer: http://www.example.com"]
|
392
|
+
c.http(:GET)
|
393
|
+
expect(c.body).to eq("abc")
|
394
|
+
expect(c.headers).to eq(["Referer: http://www.example.com"])
|
395
|
+
end
|
396
|
+
|
386
397
|
describe 'match request body' do
|
387
398
|
it 'for post' do
|
388
399
|
stub_request(:post, "www.example.com").with(body: 'foo=nhe').to_return(body: "abc")
|
@@ -22,7 +22,7 @@ unless RUBY_PLATFORM =~ /java/
|
|
22
22
|
|
23
23
|
def make_request
|
24
24
|
EM.run do
|
25
|
-
request = EM::HttpRequest.new(http_url).get(redirects: 1)
|
25
|
+
request = EM::HttpRequest.new(http_url, ssl: {verify_peer: true}).get(redirects: 1)
|
26
26
|
request.callback { EM.stop }
|
27
27
|
end
|
28
28
|
end
|
@@ -71,6 +71,35 @@ unless RUBY_PLATFORM =~ /java/
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
+
it "only calls request middleware once" do
|
75
|
+
stub_request(:get, "www.example.com")
|
76
|
+
|
77
|
+
middleware = Class.new do
|
78
|
+
def self.called!
|
79
|
+
@called = called + 1
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.called
|
83
|
+
@called || 0
|
84
|
+
end
|
85
|
+
|
86
|
+
def request(client, head, body)
|
87
|
+
self.class.called!
|
88
|
+
[head, body]
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
EM.run do
|
93
|
+
conn = EventMachine::HttpRequest.new('http://www.example.com/')
|
94
|
+
conn.use middleware
|
95
|
+
http = conn.get
|
96
|
+
http.callback do
|
97
|
+
expect(middleware.called).to eq(1)
|
98
|
+
EM.stop
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
74
103
|
let(:response_middleware) do
|
75
104
|
Class.new do
|
76
105
|
def response(resp)
|
@@ -119,6 +148,33 @@ unless RUBY_PLATFORM =~ /java/
|
|
119
148
|
context 'making a real request', net_connect: true do
|
120
149
|
before { WebMock.allow_net_connect! }
|
121
150
|
include_examples "em-http-request middleware/after_request hook integration"
|
151
|
+
|
152
|
+
it "only calls request middleware once" do
|
153
|
+
middleware = Class.new do
|
154
|
+
def self.called!
|
155
|
+
@called = called + 1
|
156
|
+
end
|
157
|
+
|
158
|
+
def self.called
|
159
|
+
@called || 0
|
160
|
+
end
|
161
|
+
|
162
|
+
def request(client, head, body)
|
163
|
+
self.class.called!
|
164
|
+
[head, body]
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
EM.run do
|
169
|
+
conn = EventMachine::HttpRequest.new(webmock_server_url)
|
170
|
+
conn.use middleware
|
171
|
+
http = conn.get
|
172
|
+
http.callback do
|
173
|
+
expect(middleware.called).to eq(1)
|
174
|
+
EM.stop
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
122
178
|
end
|
123
179
|
|
124
180
|
context 'when the request is stubbed' do
|
@@ -16,7 +16,7 @@ module EMHttpRequestSpecHelper
|
|
16
16
|
error_set = false
|
17
17
|
uri = Addressable::URI.heuristic_parse(uri)
|
18
18
|
EventMachine.run {
|
19
|
-
request = EventMachine::HttpRequest.new("#{uri.normalize.to_s}")
|
19
|
+
request = EventMachine::HttpRequest.new("#{uri.normalize.to_s}", ssl: {verify_peer: true})
|
20
20
|
http = request.send(method, {
|
21
21
|
timeout: 30,
|
22
22
|
body: options[:body],
|
@@ -20,7 +20,7 @@ describe "Excon" do
|
|
20
20
|
it "should support excon response_block for real requests", net_connect: true do
|
21
21
|
a = []
|
22
22
|
WebMock.allow_net_connect!
|
23
|
-
r = Excon.new('
|
23
|
+
r = Excon.new('https://httpstat.us/200', headers: { "Accept" => "*" }).
|
24
24
|
get(response_block: lambda {|e, remaining, total| a << e}, chunk_size: 1)
|
25
25
|
expect(a).to eq(["2", "0", "0", " ", "O", "K"])
|
26
26
|
expect(r.body).to eq("")
|
@@ -41,7 +41,7 @@ describe "Excon" do
|
|
41
41
|
WebMock.after_request { |_, res|
|
42
42
|
response = res
|
43
43
|
}
|
44
|
-
r = Excon.new('
|
44
|
+
r = Excon.new('https://httpstat.us/200', headers: { "Accept" => "*" }).
|
45
45
|
get(response_block: lambda {|e, remaining, total| a << e}, chunk_size: 1)
|
46
46
|
expect(response.body).to eq("200 OK")
|
47
47
|
expect(a).to eq(["2", "0", "0", " ", "O", "K"])
|
@@ -70,6 +70,38 @@ if RUBY_PLATFORM =~ /java/
|
|
70
70
|
expect(failure_handler).to have_received(:call)
|
71
71
|
end
|
72
72
|
end
|
73
|
+
|
74
|
+
context 'when used in a streaming mode' do
|
75
|
+
let(:webmock_server_url) {"http://#{WebMockServer.instance.host_with_port}/"}
|
76
|
+
let(:result_chunks) { [] }
|
77
|
+
|
78
|
+
def manticore_streaming_get
|
79
|
+
Manticore.get(webmock_server_url).tap do |req|
|
80
|
+
req.on_success do |response|
|
81
|
+
response.body do |chunk|
|
82
|
+
result_chunks << chunk
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'when connections are allowed' do
|
89
|
+
it 'works' do
|
90
|
+
WebMock.allow_net_connect!
|
91
|
+
expect { manticore_streaming_get.call }.to_not raise_error
|
92
|
+
expect(result_chunks).to_not be_empty
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'when stubbed' do
|
97
|
+
it 'works' do
|
98
|
+
stub_body = 'hello!'
|
99
|
+
stub_request(:get, webmock_server_url).to_return(body: stub_body)
|
100
|
+
expect { manticore_streaming_get.call }.to_not raise_error
|
101
|
+
expect(result_chunks).to eq [stub_body]
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
73
105
|
end
|
74
106
|
end
|
75
107
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
1
3
|
shared_examples_for "Net::HTTP" do
|
2
4
|
describe "when making real requests", net_connect: true do
|
3
5
|
let(:port){ WebMockServer.instance.port }
|
@@ -26,21 +28,56 @@ shared_examples_for "Net::HTTP" do
|
|
26
28
|
|
27
29
|
it "should connect only once when connected on start", net_connect: true do
|
28
30
|
@http = Net::HTTP.new('localhost', port)
|
29
|
-
|
31
|
+
socket_before_request = socket_after_request = nil
|
30
32
|
@http.start {|conn|
|
31
|
-
|
33
|
+
socket_before_request = conn.instance_variable_get(:@socket)
|
32
34
|
conn.request(Net::HTTP::Get.new("/"))
|
33
|
-
|
35
|
+
socket_after_request = conn.instance_variable_get(:@socket)
|
34
36
|
}
|
35
37
|
|
36
|
-
if !defined?(WebMock::
|
37
|
-
expect(
|
38
|
-
expect(
|
39
|
-
expect(
|
38
|
+
if !defined?(WebMock::NetHTTPUtility) || WebMock::Config.instance.net_http_connect_on_start
|
39
|
+
expect(socket_before_request).to be_a(Net::BufferedIO)
|
40
|
+
expect(socket_after_request).to be_a(Net::BufferedIO)
|
41
|
+
expect(socket_after_request).to be(socket_before_request)
|
42
|
+
else
|
43
|
+
expect(socket_before_request).to be_a(StubSocket)
|
44
|
+
expect(socket_after_request).to be_a(Net::BufferedIO)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should allow sending multiple requests when persisted", net_connect: true do
|
49
|
+
@http = Net::HTTP.new('example.org')
|
50
|
+
@http.start
|
51
|
+
expect(@http.get("/")).to be_a(Net::HTTPSuccess)
|
52
|
+
expect(@http.get("/")).to be_a(Net::HTTPSuccess)
|
53
|
+
expect(@http.get("/")).to be_a(Net::HTTPSuccess)
|
54
|
+
@http.finish
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should not leak file descriptors", net_connect: true do
|
58
|
+
sockets = Set.new
|
59
|
+
|
60
|
+
@http = Net::HTTP.new('example.org')
|
61
|
+
@http.start
|
62
|
+
sockets << @http.instance_variable_get(:@socket)
|
63
|
+
@http.get("/")
|
64
|
+
sockets << @http.instance_variable_get(:@socket)
|
65
|
+
@http.get("/")
|
66
|
+
sockets << @http.instance_variable_get(:@socket)
|
67
|
+
@http.get("/")
|
68
|
+
sockets << @http.instance_variable_get(:@socket)
|
69
|
+
@http.finish
|
70
|
+
|
71
|
+
if !defined?(WebMock::NetHTTPUtility) || WebMock.net_http_connect_on_start?(Addressable::URI.parse("http://example.com/"))
|
72
|
+
expect(sockets.length).to eq(1)
|
73
|
+
expect(sockets.to_a[0]).to be_a(Net::BufferedIO)
|
40
74
|
else
|
41
|
-
expect(
|
42
|
-
expect(
|
75
|
+
expect(sockets.length).to eq(2)
|
76
|
+
expect(sockets.to_a[0]).to be_a(StubSocket)
|
77
|
+
expect(sockets.to_a[1]).to be_a(Net::BufferedIO)
|
43
78
|
end
|
79
|
+
|
80
|
+
expect(sockets.all?(&:closed?)).to be(true)
|
44
81
|
end
|
45
82
|
|
46
83
|
it "should pass the read_timeout value on", net_connect: true do
|
@@ -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)
|
@@ -254,6 +253,21 @@ describe "Net:HTTP" do
|
|
254
253
|
}
|
255
254
|
end
|
256
255
|
|
256
|
+
it "should connect to the server on start when allowlisted", net_connect: true do
|
257
|
+
WebMock.disable_net_connect!(allow: "www.google.com", net_http_connect_on_start: "www.google.com")
|
258
|
+
@http.start {|conn|
|
259
|
+
cert = OpenSSL::X509::Certificate.new conn.peer_cert
|
260
|
+
expect(cert).to be_a(OpenSSL::X509::Certificate)
|
261
|
+
}
|
262
|
+
end
|
263
|
+
|
264
|
+
it "should not connect to the server on start when not allowlisted", net_connect: true do
|
265
|
+
WebMock.disable_net_connect!(allow: "www.google.com", net_http_connect_on_start: "www.yahoo.com")
|
266
|
+
@http.start {|conn|
|
267
|
+
expect(conn.peer_cert).to be_nil
|
268
|
+
}
|
269
|
+
end
|
270
|
+
|
257
271
|
it "should connect to the server if the URI matches an regex", net_connect: true do
|
258
272
|
WebMock.disable_net_connect!(allow: /google.com/)
|
259
273
|
Net::HTTP.get('www.google.com','/')
|
@@ -282,6 +296,13 @@ describe "Net:HTTP" do
|
|
282
296
|
it_should_behave_like "Net::HTTP"
|
283
297
|
end
|
284
298
|
|
299
|
+
describe "when net_http_connect_on_start is a specific host" do
|
300
|
+
before(:each) do
|
301
|
+
WebMock.allow_net_connect!(net_http_connect_on_start: "localhost")
|
302
|
+
end
|
303
|
+
it_should_behave_like "Net::HTTP"
|
304
|
+
end
|
305
|
+
|
285
306
|
describe 'after_request callback support', net_connect: true do
|
286
307
|
let(:expected_body_regex) { /hello world/ }
|
287
308
|
|
@@ -340,4 +361,35 @@ describe "Net:HTTP" do
|
|
340
361
|
http.request(req, '')
|
341
362
|
end
|
342
363
|
end
|
364
|
+
|
365
|
+
describe "hostname handling" do
|
366
|
+
it "should set brackets around the hostname if it is an IPv6 address" do
|
367
|
+
net_http = Net::HTTP.new('b2dc:5bdf:4f0d::3014:e0ca', 80)
|
368
|
+
path = '/example.jpg'
|
369
|
+
expect(WebMock::NetHTTPUtility.get_uri(net_http, path)).to eq('http://[b2dc:5bdf:4f0d::3014:e0ca]:80/example.jpg')
|
370
|
+
end
|
371
|
+
|
372
|
+
it "should not set brackets around the hostname if it is already wrapped by brackets" do
|
373
|
+
net_http = Net::HTTP.new('[b2dc:5bdf:4f0d::3014:e0ca]', 80)
|
374
|
+
path = '/example.jpg'
|
375
|
+
expect(WebMock::NetHTTPUtility.get_uri(net_http, path)).to eq('http://[b2dc:5bdf:4f0d::3014:e0ca]:80/example.jpg')
|
376
|
+
end
|
377
|
+
|
378
|
+
it "should not set brackets around the hostname if it is an IPv4 address" do
|
379
|
+
net_http = Net::HTTP.new('181.152.137.168', 80)
|
380
|
+
path = '/example.jpg'
|
381
|
+
expect(WebMock::NetHTTPUtility.get_uri(net_http, path)).to eq('http://181.152.137.168:80/example.jpg')
|
382
|
+
end
|
383
|
+
|
384
|
+
it "should not set brackets around the hostname if it is a domain" do
|
385
|
+
net_http = Net::HTTP.new('www.example.com', 80)
|
386
|
+
path = '/example.jpg'
|
387
|
+
expect(WebMock::NetHTTPUtility.get_uri(net_http, path)).to eq('http://www.example.com:80/example.jpg')
|
388
|
+
end
|
389
|
+
|
390
|
+
it "does not require a path" do
|
391
|
+
net_http = Net::HTTP.new('www.example.com', 80)
|
392
|
+
expect(WebMock::NetHTTPUtility.get_uri(net_http)).to eq('http://www.example.com:80')
|
393
|
+
end
|
394
|
+
end
|
343
395
|
end
|
@@ -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
|
@@ -28,8 +28,8 @@ module PatronSpecHelper
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
status_line_pattern = %r(\AHTTP/(\d
|
32
|
-
message = response.status_line.match(status_line_pattern)[
|
31
|
+
status_line_pattern = %r(\AHTTP/(\d+(\.\d+)?)\s+(\d\d\d)\s*([^\r\n]+)?)
|
32
|
+
message = response.status_line.match(status_line_pattern)[4] || ""
|
33
33
|
|
34
34
|
OpenStruct.new({
|
35
35
|
body: response.body,
|
@@ -91,7 +91,7 @@ shared_context "allowing and disabling net connect" do |*adapter_info|
|
|
91
91
|
describe "is not allowed, with exceptions" do
|
92
92
|
describe "allowing by host string" do
|
93
93
|
before :each do
|
94
|
-
WebMock.disable_net_connect!(allow: 'httpstat.us')
|
94
|
+
WebMock.disable_net_connect!(allow: 'https://httpstat.us')
|
95
95
|
end
|
96
96
|
|
97
97
|
context "when the host is not allowed" do
|
@@ -109,13 +109,13 @@ shared_context "allowing and disabling net connect" do |*adapter_info|
|
|
109
109
|
|
110
110
|
context "when the host is allowed" do
|
111
111
|
it "should return stubbed response if request was stubbed" do
|
112
|
-
stub_request(:get, 'httpstat.us/200').to_return(body: "abc")
|
113
|
-
expect(http_request(:get, "
|
112
|
+
stub_request(:get, 'https://httpstat.us/200').to_return(body: "abc")
|
113
|
+
expect(http_request(:get, "https://httpstat.us/200").body).to eq("abc")
|
114
114
|
end
|
115
115
|
|
116
116
|
# WARNING: this makes a real HTTP request!
|
117
117
|
it "should make a real request to allowed host", net_connect: true do
|
118
|
-
expect(http_request(:get, "
|
118
|
+
expect(http_request(:get, "https://httpstat.us/200").status).to eq('200')
|
119
119
|
end
|
120
120
|
end
|
121
121
|
end
|
@@ -229,13 +229,13 @@ shared_context "allowing and disabling net connect" do |*adapter_info|
|
|
229
229
|
|
230
230
|
context "when the host is allowed" do
|
231
231
|
it "should return stubbed response if request was stubbed" do
|
232
|
-
stub_request(:get, 'httpstat.us/200').to_return(body: "abc")
|
233
|
-
expect(http_request(:get, "
|
232
|
+
stub_request(:get, 'https://httpstat.us/200').to_return(body: "abc")
|
233
|
+
expect(http_request(:get, "https://httpstat.us/200").body).to eq("abc")
|
234
234
|
end
|
235
235
|
|
236
236
|
# WARNING: this makes a real HTTP request!
|
237
237
|
it "should make a real request to allowed host", net_connect: true do
|
238
|
-
expect(http_request(:get, "
|
238
|
+
expect(http_request(:get, "https://httpstat.us/200").status).to eq('200')
|
239
239
|
end
|
240
240
|
|
241
241
|
it "should make a real request if request is allowed by path regexp and url contains default port", net_connect: true do
|
@@ -266,20 +266,20 @@ shared_context "allowing and disabling net connect" do |*adapter_info|
|
|
266
266
|
|
267
267
|
context "when the host is allowed" do
|
268
268
|
it "should return stubbed response if request was stubbed" do
|
269
|
-
stub_request(:get, 'httpstat.us/200').to_return(body: "abc")
|
270
|
-
expect(http_request(:get, "
|
269
|
+
stub_request(:get, 'https://httpstat.us/200').to_return(body: "abc")
|
270
|
+
expect(http_request(:get, "https://httpstat.us/200").body).to eq("abc")
|
271
271
|
end
|
272
272
|
|
273
273
|
# WARNING: this makes a real HTTP request!
|
274
274
|
it "should make a real request to allowed host", net_connect: true do
|
275
|
-
expect(http_request(:get, "
|
275
|
+
expect(http_request(:get, "https://httpstat.us/200").status).to eq('200')
|
276
276
|
end
|
277
277
|
end
|
278
278
|
end
|
279
279
|
|
280
280
|
describe "allowing by a list of the above" do
|
281
281
|
before :each do
|
282
|
-
WebMock.disable_net_connect!(allow: [lambda{|_| false }, %r{foobar}, 'httpstat.us'])
|
282
|
+
WebMock.disable_net_connect!(allow: [lambda{|_| false }, %r{foobar}, 'https://httpstat.us'])
|
283
283
|
end
|
284
284
|
|
285
285
|
context "when the host is not allowed" do
|
@@ -297,13 +297,13 @@ shared_context "allowing and disabling net connect" do |*adapter_info|
|
|
297
297
|
|
298
298
|
context "when the host is allowed" do
|
299
299
|
it "should return stubbed response if request was stubbed" do
|
300
|
-
stub_request(:get, 'httpstat.us/200').to_return(body: "abc")
|
301
|
-
expect(http_request(:get, "
|
300
|
+
stub_request(:get, 'https://httpstat.us/200').to_return(body: "abc")
|
301
|
+
expect(http_request(:get, "https://httpstat.us/200").body).to eq("abc")
|
302
302
|
end
|
303
303
|
|
304
304
|
# WARNING: this makes a real HTTP request!
|
305
305
|
it "should make a real request to allowed host", net_connect: true do
|
306
|
-
expect(http_request(:get, "
|
306
|
+
expect(http_request(:get, "https://httpstat.us/200").status).to eq('200')
|
307
307
|
end
|
308
308
|
end
|
309
309
|
end
|
@@ -102,7 +102,7 @@ shared_context "callbacks" do |*adapter_info|
|
|
102
102
|
WebMock.after_request(except: [:other_lib]) do |_, response|
|
103
103
|
@response = response
|
104
104
|
end
|
105
|
-
http_request(:get, "
|
105
|
+
http_request(:get, "https://httpstat.us/201", headers: { "Accept" => "*" })
|
106
106
|
end
|
107
107
|
|
108
108
|
it "should pass real response to callback with status and message" do
|
@@ -111,7 +111,7 @@ shared_context "callbacks" do |*adapter_info|
|
|
111
111
|
end
|
112
112
|
|
113
113
|
it "should pass real response to callback with headers" do
|
114
|
-
expect(@response.headers["
|
114
|
+
expect(@response.headers["Server"]).to eq( "Kestrel")
|
115
115
|
expect(@response.headers["Content-Length"]).to eq("11") unless adapter_info.include?(:no_content_length_header)
|
116
116
|
end
|
117
117
|
|
@@ -18,7 +18,7 @@ shared_context "complex cross-concern behaviors" do |*adapter_info|
|
|
18
18
|
expect(played_back_response).to eq(real_response)
|
19
19
|
end
|
20
20
|
|
21
|
-
let(:no_content_url) { '
|
21
|
+
let(:no_content_url) { 'https://httpstat.us/204' }
|
22
22
|
[nil, ''].each do |stub_val|
|
23
23
|
it "returns the same value (nil or "") for a request stubbed as #{stub_val.inspect} that a real empty response has", net_connect: true do
|
24
24
|
unless http_library == :curb
|
@@ -593,6 +593,23 @@ shared_examples_for "stubbing requests" do |*adapter_info|
|
|
593
593
|
end
|
594
594
|
end
|
595
595
|
end
|
596
|
+
|
597
|
+
context "when global stub should be invoked last" do
|
598
|
+
before do
|
599
|
+
WebMock.globally_stub_request(:after_local_stubs) do
|
600
|
+
{ body: "global stub body" }
|
601
|
+
end
|
602
|
+
end
|
603
|
+
|
604
|
+
it "uses global stub when non-global stub is not defined" do
|
605
|
+
expect(http_request(:get, "http://www.example.com/").body).to eq("global stub body")
|
606
|
+
end
|
607
|
+
|
608
|
+
it "uses non-global stub first" do
|
609
|
+
stub_request(:get, "www.example.com").to_return(body: 'non-global stub body')
|
610
|
+
expect(http_request(:get, "http://www.example.com/").body).to eq("non-global stub body")
|
611
|
+
end
|
612
|
+
end
|
596
613
|
end
|
597
614
|
|
598
615
|
describe "when stubbing request with a block evaluated on request" do
|