webmock 1.8.6 → 3.14.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.
- checksums.yaml +7 -0
- data/.github/workflows/CI.yml +37 -0
- data/.gitignore +6 -0
- data/CHANGELOG.md +1198 -0
- data/Gemfile +3 -15
- data/README.md +761 -305
- data/Rakefile +13 -40
- data/lib/webmock/api.rb +63 -17
- data/lib/webmock/callback_registry.rb +1 -1
- data/lib/webmock/config.rb +8 -0
- data/lib/webmock/cucumber.rb +2 -0
- data/lib/webmock/errors.rb +8 -24
- data/lib/webmock/http_lib_adapters/async_http_client_adapter.rb +216 -0
- data/lib/webmock/http_lib_adapters/curb_adapter.rb +148 -84
- data/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +224 -4
- data/lib/webmock/http_lib_adapters/excon_adapter.rb +104 -34
- data/lib/webmock/http_lib_adapters/http_rb/client.rb +17 -0
- data/lib/webmock/http_lib_adapters/http_rb/request.rb +16 -0
- data/lib/webmock/http_lib_adapters/http_rb/response.rb +64 -0
- data/lib/webmock/http_lib_adapters/http_rb/streamer.rb +29 -0
- data/lib/webmock/http_lib_adapters/http_rb/webmock.rb +68 -0
- data/lib/webmock/http_lib_adapters/http_rb_adapter.rb +37 -0
- data/lib/webmock/http_lib_adapters/httpclient_adapter.rb +152 -86
- data/lib/webmock/http_lib_adapters/manticore_adapter.rb +145 -0
- data/lib/webmock/http_lib_adapters/net_http.rb +155 -46
- data/lib/webmock/http_lib_adapters/net_http_response.rb +1 -1
- data/lib/webmock/http_lib_adapters/patron_adapter.rb +16 -15
- data/lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb +76 -82
- data/lib/webmock/matchers/any_arg_matcher.rb +13 -0
- data/lib/webmock/matchers/hash_argument_matcher.rb +21 -0
- data/lib/webmock/matchers/hash_excluding_matcher.rb +15 -0
- data/lib/webmock/matchers/hash_including_matcher.rb +4 -12
- data/lib/webmock/minitest.rb +29 -3
- data/lib/webmock/rack_response.rb +14 -7
- data/lib/webmock/request_body_diff.rb +64 -0
- data/lib/webmock/request_execution_verifier.rb +38 -17
- data/lib/webmock/request_pattern.rb +158 -38
- data/lib/webmock/request_registry.rb +3 -3
- data/lib/webmock/request_signature.rb +7 -3
- data/lib/webmock/request_signature_snippet.rb +61 -0
- data/lib/webmock/request_stub.rb +9 -6
- data/lib/webmock/response.rb +30 -15
- data/lib/webmock/rspec/matchers/request_pattern_matcher.rb +38 -2
- data/lib/webmock/rspec/matchers/webmock_matcher.rb +23 -2
- data/lib/webmock/rspec/matchers.rb +0 -1
- data/lib/webmock/rspec.rb +11 -2
- data/lib/webmock/stub_registry.rb +31 -10
- data/lib/webmock/stub_request_snippet.rb +14 -6
- data/lib/webmock/test_unit.rb +4 -4
- data/lib/webmock/util/hash_counter.rb +20 -6
- data/lib/webmock/util/hash_keys_stringifier.rb +5 -3
- data/lib/webmock/util/hash_validator.rb +17 -0
- data/lib/webmock/util/headers.rb +23 -2
- data/lib/webmock/util/json.rb +20 -7
- data/lib/webmock/util/query_mapper.rb +281 -0
- data/lib/webmock/util/uri.rb +29 -19
- data/lib/webmock/util/values_stringifier.rb +20 -0
- data/lib/webmock/util/version_checker.rb +40 -2
- data/lib/webmock/version.rb +1 -1
- data/lib/webmock/webmock.rb +56 -17
- data/lib/webmock.rb +56 -46
- data/minitest/test_helper.rb +8 -3
- data/minitest/test_webmock.rb +4 -1
- data/minitest/webmock_spec.rb +16 -6
- data/spec/acceptance/async_http_client/async_http_client_spec.rb +375 -0
- data/spec/acceptance/async_http_client/async_http_client_spec_helper.rb +73 -0
- data/spec/acceptance/curb/curb_spec.rb +227 -68
- data/spec/acceptance/curb/curb_spec_helper.rb +11 -8
- data/spec/acceptance/em_http_request/em_http_request_spec.rb +322 -28
- data/spec/acceptance/em_http_request/em_http_request_spec_helper.rb +15 -10
- data/spec/acceptance/excon/excon_spec.rb +66 -4
- data/spec/acceptance/excon/excon_spec_helper.rb +21 -7
- data/spec/acceptance/http_rb/http_rb_spec.rb +93 -0
- data/spec/acceptance/http_rb/http_rb_spec_helper.rb +54 -0
- data/spec/acceptance/httpclient/httpclient_spec.rb +152 -11
- data/spec/acceptance/httpclient/httpclient_spec_helper.rb +25 -16
- data/spec/acceptance/manticore/manticore_spec.rb +107 -0
- data/spec/acceptance/manticore/manticore_spec_helper.rb +35 -0
- data/spec/acceptance/net_http/net_http_shared.rb +52 -24
- data/spec/acceptance/net_http/net_http_spec.rb +164 -50
- data/spec/acceptance/net_http/net_http_spec_helper.rb +19 -10
- data/spec/acceptance/net_http/real_net_http_spec.rb +1 -1
- data/spec/acceptance/patron/patron_spec.rb +29 -40
- data/spec/acceptance/patron/patron_spec_helper.rb +15 -11
- data/spec/acceptance/shared/allowing_and_disabling_net_connect.rb +229 -58
- data/spec/acceptance/shared/callbacks.rb +32 -30
- data/spec/acceptance/shared/complex_cross_concern_behaviors.rb +20 -5
- data/spec/acceptance/shared/enabling_and_disabling_webmock.rb +14 -14
- data/spec/acceptance/shared/precedence_of_stubs.rb +6 -6
- data/spec/acceptance/shared/request_expectations.rb +560 -296
- data/spec/acceptance/shared/returning_declared_responses.rb +180 -138
- data/spec/acceptance/shared/stubbing_requests.rb +385 -154
- data/spec/acceptance/typhoeus/typhoeus_hydra_spec.rb +78 -17
- data/spec/acceptance/typhoeus/typhoeus_hydra_spec_helper.rb +19 -15
- data/spec/acceptance/webmock_shared.rb +2 -2
- data/spec/fixtures/test.txt +1 -0
- data/spec/quality_spec.rb +27 -3
- data/spec/spec_helper.rb +11 -20
- data/spec/support/failures.rb +9 -0
- data/spec/support/my_rack_app.rb +8 -3
- data/spec/support/network_connection.rb +7 -13
- data/spec/support/webmock_server.rb +8 -3
- data/spec/unit/api_spec.rb +175 -0
- data/spec/unit/errors_spec.rb +116 -19
- data/spec/unit/http_lib_adapters/http_lib_adapter_registry_spec.rb +1 -1
- data/spec/unit/http_lib_adapters/http_lib_adapter_spec.rb +2 -2
- data/spec/unit/matchers/hash_excluding_matcher_spec.rb +61 -0
- data/spec/unit/matchers/hash_including_matcher_spec.rb +87 -0
- data/spec/unit/rack_response_spec.rb +54 -16
- data/spec/unit/request_body_diff_spec.rb +90 -0
- data/spec/unit/request_execution_verifier_spec.rb +147 -39
- data/spec/unit/request_pattern_spec.rb +462 -198
- data/spec/unit/request_registry_spec.rb +29 -9
- data/spec/unit/request_signature_snippet_spec.rb +89 -0
- data/spec/unit/request_signature_spec.rb +91 -49
- data/spec/unit/request_stub_spec.rb +71 -70
- data/spec/unit/response_spec.rb +100 -81
- data/spec/unit/stub_registry_spec.rb +37 -20
- data/spec/unit/stub_request_snippet_spec.rb +51 -31
- data/spec/unit/util/hash_counter_spec.rb +6 -6
- data/spec/unit/util/hash_keys_stringifier_spec.rb +4 -4
- data/spec/unit/util/headers_spec.rb +4 -4
- data/spec/unit/util/json_spec.rb +29 -3
- data/spec/unit/util/query_mapper_spec.rb +157 -0
- data/spec/unit/util/uri_spec.rb +150 -36
- data/spec/unit/util/version_checker_spec.rb +15 -9
- data/spec/unit/webmock_spec.rb +57 -4
- data/test/http_request.rb +3 -3
- data/test/shared_test.rb +45 -13
- data/test/test_helper.rb +1 -1
- data/test/test_webmock.rb +6 -0
- data/webmock.gemspec +30 -11
- metadata +308 -199
- data/.rvmrc +0 -1
- data/.travis.yml +0 -11
- data/Guardfile +0 -24
- data/lib/webmock/http_lib_adapters/em_http_request/em_http_request_0_x.rb +0 -151
- data/lib/webmock/http_lib_adapters/em_http_request/em_http_request_1_x.rb +0 -210
@@ -1,18 +1,18 @@
|
|
1
1
|
shared_examples_for "Net::HTTP" do
|
2
|
-
describe "when making real requests", :
|
2
|
+
describe "when making real requests", net_connect: true do
|
3
3
|
let(:port){ WebMockServer.instance.port }
|
4
4
|
|
5
5
|
before(:each) do
|
6
6
|
@http = Net::HTTP.new("localhost", port)
|
7
7
|
end
|
8
8
|
|
9
|
-
it "should return a Net::ReadAdapter from response.body when a real request is made with a block and #read_body", :
|
9
|
+
it "should return a Net::ReadAdapter from response.body when a real request is made with a block and #read_body", net_connect: true do
|
10
10
|
response = Net::HTTP.new("localhost", port).request_get('/') { |r| r.read_body { } }
|
11
|
-
response.body.
|
11
|
+
expect(response.body).to be_a(Net::ReadAdapter)
|
12
12
|
end
|
13
13
|
|
14
|
-
it "should handle requests with block passed to read_body", :
|
15
|
-
body = ""
|
14
|
+
it "should handle requests with block passed to read_body", net_connect: true do
|
15
|
+
body = "".dup
|
16
16
|
req = Net::HTTP::Get.new("/")
|
17
17
|
Net::HTTP.start("localhost", port) do |http|
|
18
18
|
http.request(req) do |res|
|
@@ -21,10 +21,10 @@ shared_examples_for "Net::HTTP" do
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
24
|
-
body.
|
24
|
+
expect(body).to match(/hello world/)
|
25
25
|
end
|
26
26
|
|
27
|
-
it "should connect only once when connected on start", :
|
27
|
+
it "should connect only once when connected on start", net_connect: true do
|
28
28
|
@http = Net::HTTP.new('localhost', port)
|
29
29
|
socket_id_before_request = socket_id_after_request = nil
|
30
30
|
@http.start {|conn|
|
@@ -32,20 +32,38 @@ shared_examples_for "Net::HTTP" do
|
|
32
32
|
conn.request(Net::HTTP::Get.new("/"))
|
33
33
|
socket_id_after_request = conn.instance_variable_get(:@socket).object_id
|
34
34
|
}
|
35
|
-
|
36
|
-
|
35
|
+
|
36
|
+
if !defined?(WebMock::Config) || WebMock::Config.instance.net_http_connect_on_start
|
37
|
+
expect(socket_id_before_request).not_to eq(nil.object_id)
|
38
|
+
expect(socket_id_after_request).not_to eq(nil.object_id)
|
39
|
+
expect(socket_id_after_request).to eq(socket_id_before_request)
|
40
|
+
else
|
41
|
+
expect(socket_id_before_request).to eq(nil.object_id)
|
42
|
+
expect(socket_id_after_request).not_to eq(nil.object_id)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should pass the read_timeout value on", net_connect: true do
|
47
|
+
@http = Net::HTTP.new('localhost', port)
|
48
|
+
read_timeout = @http.read_timeout + 1
|
49
|
+
@http.read_timeout = read_timeout
|
50
|
+
@http.start {|conn|
|
51
|
+
conn.request(Net::HTTP::Get.new("/"))
|
52
|
+
socket = conn.instance_variable_get(:@socket)
|
53
|
+
expect(socket.read_timeout).to eq(read_timeout)
|
54
|
+
}
|
37
55
|
end
|
38
56
|
|
39
57
|
describe "without start" do
|
40
58
|
it "should close connection after a real request" do
|
41
59
|
@http.get('/') { }
|
42
|
-
@http.
|
60
|
+
expect(@http).not_to be_started
|
43
61
|
end
|
44
62
|
|
45
63
|
it "should execute block exactly once" do
|
46
64
|
times = 0
|
47
65
|
@http.get('/') { times += 1 }
|
48
|
-
times.
|
66
|
+
expect(times).to eq(1)
|
49
67
|
end
|
50
68
|
|
51
69
|
it "should have socket open during a real request" do
|
@@ -53,7 +71,7 @@ shared_examples_for "Net::HTTP" do
|
|
53
71
|
@http.get('/') {
|
54
72
|
socket_id = @http.instance_variable_get(:@socket).object_id
|
55
73
|
}
|
56
|
-
socket_id.
|
74
|
+
expect(socket_id).not_to be_nil
|
57
75
|
end
|
58
76
|
|
59
77
|
it "should be started during a real request" do
|
@@ -61,21 +79,21 @@ shared_examples_for "Net::HTTP" do
|
|
61
79
|
@http.get('/') {
|
62
80
|
started = @http.started?
|
63
81
|
}
|
64
|
-
started.
|
65
|
-
@http.started
|
82
|
+
expect(started).to eq(true)
|
83
|
+
expect(@http.started?).to eq(false)
|
66
84
|
end
|
67
85
|
end
|
68
86
|
|
69
87
|
describe "with start" do
|
70
88
|
it "should close connection after a real request" do
|
71
89
|
@http.start {|conn| conn.get('/') { } }
|
72
|
-
@http.
|
90
|
+
expect(@http).not_to be_started
|
73
91
|
end
|
74
92
|
|
75
93
|
it "should execute block exactly once" do
|
76
94
|
times = 0
|
77
95
|
@http.start {|conn| conn.get('/') { times += 1 }}
|
78
|
-
times.
|
96
|
+
expect(times).to eq(1)
|
79
97
|
end
|
80
98
|
|
81
99
|
it "should have socket open during a real request" do
|
@@ -84,7 +102,7 @@ shared_examples_for "Net::HTTP" do
|
|
84
102
|
socket_id = conn.instance_variable_get(:@socket).object_id
|
85
103
|
}
|
86
104
|
}
|
87
|
-
socket_id.
|
105
|
+
expect(socket_id).not_to be_nil
|
88
106
|
end
|
89
107
|
|
90
108
|
it "should be started during a real request" do
|
@@ -93,15 +111,15 @@ shared_examples_for "Net::HTTP" do
|
|
93
111
|
started = conn.started?
|
94
112
|
}
|
95
113
|
}
|
96
|
-
started.
|
97
|
-
@http.started
|
114
|
+
expect(started).to eq(true)
|
115
|
+
expect(@http.started?).to eq(false)
|
98
116
|
end
|
99
117
|
end
|
100
118
|
|
101
119
|
describe "with start without request block" do
|
102
120
|
it "should close connection after a real request" do
|
103
121
|
@http.start {|conn| conn.get('/') }
|
104
|
-
@http.
|
122
|
+
expect(@http).not_to be_started
|
105
123
|
end
|
106
124
|
|
107
125
|
it "should have socket open during a real request" do
|
@@ -109,7 +127,7 @@ shared_examples_for "Net::HTTP" do
|
|
109
127
|
@http.start {|conn|
|
110
128
|
socket_id = conn.instance_variable_get(:@socket).object_id
|
111
129
|
}
|
112
|
-
socket_id.
|
130
|
+
expect(socket_id).not_to be_nil
|
113
131
|
end
|
114
132
|
|
115
133
|
it "should be started during a real request" do
|
@@ -117,9 +135,19 @@ shared_examples_for "Net::HTTP" do
|
|
117
135
|
@http.start {|conn|
|
118
136
|
started = conn.started?
|
119
137
|
}
|
120
|
-
started.
|
121
|
-
@http.started
|
138
|
+
expect(started).to eq(true)
|
139
|
+
expect(@http.started?).to eq(false)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe "with start without a block and finish" do
|
144
|
+
it "should gracefully start and close connection" do
|
145
|
+
@http.start
|
146
|
+
@http.get("/")
|
147
|
+
expect(@http).to be_started
|
148
|
+
@http.finish
|
149
|
+
expect(@http).not_to be_started
|
122
150
|
end
|
123
151
|
end
|
124
152
|
end
|
125
|
-
end
|
153
|
+
end
|
@@ -7,9 +7,9 @@ require 'acceptance/net_http/net_http_shared'
|
|
7
7
|
include NetHTTPSpecHelper
|
8
8
|
|
9
9
|
describe "Net:HTTP" do
|
10
|
-
include_examples "with WebMock"
|
10
|
+
include_examples "with WebMock", :no_url_auth
|
11
11
|
|
12
|
-
let(:port){ WebMockServer.instance.port }
|
12
|
+
let(:port) { WebMockServer.instance.port }
|
13
13
|
|
14
14
|
describe "marshalling" do
|
15
15
|
class TestMarshalingInWebMockNetHTTP
|
@@ -58,91 +58,159 @@ describe "Net:HTTP" do
|
|
58
58
|
|
59
59
|
describe "constants" do
|
60
60
|
it "should still have const Get defined on replaced Net::HTTP" do
|
61
|
-
Object.const_get("Net").const_get("HTTP").const_defined?("Get").
|
61
|
+
expect(Object.const_get("Net").const_get("HTTP").const_defined?("Get")).to be_truthy
|
62
62
|
end
|
63
63
|
|
64
64
|
it "should still have const Get within constants on replaced Net::HTTP" do
|
65
|
-
Object.const_get("Net").const_get("HTTP").constants.map(&:to_s).
|
65
|
+
expect(Object.const_get("Net").const_get("HTTP").constants.map(&:to_s)).to include("Get")
|
66
66
|
end
|
67
67
|
|
68
68
|
it "should still have const Get within constants on replaced Net::HTTP" do
|
69
|
-
Object.const_get("Net").const_get("HTTP").const_get("Get").
|
69
|
+
expect(Object.const_get("Net").const_get("HTTP").const_get("Get")).not_to be_nil
|
70
70
|
end
|
71
71
|
|
72
72
|
if Module.method(:const_defined?).arity != 1
|
73
73
|
it "should still have const Get defined (and not inherited) on replaced Net::HTTP" do
|
74
|
-
Object.const_get("Net").const_get("HTTP").const_defined?("Get", false).
|
74
|
+
expect(Object.const_get("Net").const_get("HTTP").const_defined?("Get", false)).to be_truthy
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
78
78
|
if Module.method(:const_get).arity != 1
|
79
79
|
it "should still be able to get non inherited constant Get on replaced Net::HTTP" do
|
80
|
-
Object.const_get("Net").const_get("HTTP").const_get("Get", false).
|
80
|
+
expect(Object.const_get("Net").const_get("HTTP").const_get("Get", false)).not_to be_nil
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
84
|
if Module.method(:constants).arity != 0
|
85
85
|
it "should still Get within non inherited constants on replaced Net::HTTP" do
|
86
|
-
Object.const_get("Net").const_get("HTTP").constants(false).map(&:to_s).
|
86
|
+
expect(Object.const_get("Net").const_get("HTTP").constants(false).map(&:to_s)).to include("Get")
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "after WebMock is disabled" do
|
91
|
+
after(:each) do
|
92
|
+
WebMock.enable!
|
93
|
+
end
|
94
|
+
it "Net::HTTP should have the same constants" do
|
95
|
+
orig_consts_number = WebMock::HttpLibAdapters::NetHttpAdapter::OriginalNetHTTP.constants.size
|
96
|
+
Net::HTTP.send(:const_set, "TEST_CONST", 10)
|
97
|
+
expect(Net::HTTP.constants.size).to eq(orig_consts_number + 1)
|
98
|
+
WebMock.disable!
|
99
|
+
expect(Net::HTTP.constants.size).to eq(orig_consts_number + 1)
|
87
100
|
end
|
88
101
|
end
|
89
102
|
end
|
90
103
|
|
91
104
|
it "should work with block provided" do
|
92
|
-
stub_http_request(:get, "www.example.com").to_return(:
|
93
|
-
Net::HTTP.start("www.example.com") { |query| query.get("/") }.body.
|
105
|
+
stub_http_request(:get, "www.example.com").to_return(body: "abc"*100000)
|
106
|
+
expect(Net::HTTP.start("www.example.com") { |query| query.get("/") }.body).to eq("abc"*100000)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should handle requests with raw binary data" do
|
110
|
+
body = "\x14\x00\x00\x00\x70\x69\x6e\x67\x00\x00"
|
111
|
+
stub_http_request(:post, "www.example.com").with(body: body).to_return(body: "abc")
|
112
|
+
req = Net::HTTP::Post.new("/")
|
113
|
+
req.body = body
|
114
|
+
req.content_type = "application/octet-stream"
|
115
|
+
expect(Net::HTTP.start("www.example.com") { |http| http.request(req)}.body).to eq("abc")
|
116
|
+
end
|
117
|
+
|
118
|
+
it "raises an ArgumentError if passed headers as symbols if RUBY_VERSION < 2.3.0" do
|
119
|
+
uri = URI.parse("http://google.com/")
|
120
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
121
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
122
|
+
|
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
|
94
145
|
end
|
95
146
|
|
96
147
|
it "should handle multiple values for the same response header" do
|
97
|
-
stub_http_request(:get, "www.example.com").to_return(:
|
148
|
+
stub_http_request(:get, "www.example.com").to_return(headers: { 'Set-Cookie' => ['foo=bar', 'bar=bazz'] })
|
98
149
|
response = Net::HTTP.get_response(URI.parse("http://www.example.com/"))
|
99
|
-
response.get_fields('Set-Cookie').
|
150
|
+
expect(response.get_fields('Set-Cookie')).to eq(['bar=bazz', 'foo=bar'])
|
100
151
|
end
|
101
152
|
|
102
153
|
it "should yield block on response" do
|
103
|
-
stub_http_request(:get, "www.example.com").to_return(:
|
154
|
+
stub_http_request(:get, "www.example.com").to_return(body: "abc")
|
104
155
|
response_body = ""
|
105
156
|
http_request(:get, "http://www.example.com/") do |response|
|
106
157
|
response_body = response.body
|
107
158
|
end
|
108
|
-
response_body.
|
159
|
+
expect(response_body).to eq("abc")
|
109
160
|
end
|
110
161
|
|
111
162
|
it "should handle Net::HTTP::Post#body" do
|
112
|
-
stub_http_request(:post, "www.example.com").with(:
|
163
|
+
stub_http_request(:post, "www.example.com").with(body: "my_params").to_return(body: "abc")
|
113
164
|
req = Net::HTTP::Post.new("/")
|
114
165
|
req.body = "my_params"
|
115
|
-
Net::HTTP.start("www.example.com") { |http| http.request(req)}.body.
|
166
|
+
expect(Net::HTTP.start("www.example.com") { |http| http.request(req)}.body).to eq("abc")
|
116
167
|
end
|
117
168
|
|
118
169
|
it "should handle Net::HTTP::Post#body_stream" do
|
119
|
-
stub_http_request(:post, "www.example.com").with(:
|
170
|
+
stub_http_request(:post, "www.example.com").with(body: "my_params").to_return(body: "abc")
|
120
171
|
req = Net::HTTP::Post.new("/")
|
121
172
|
req.body_stream = StringIO.new("my_params")
|
122
|
-
Net::HTTP.start("www.example.com") { |http| http.request(req)}.body.
|
173
|
+
expect(Net::HTTP.start("www.example.com") { |http| http.request(req)}.body).to eq("abc")
|
123
174
|
end
|
124
175
|
|
125
176
|
it "should behave like Net::HTTP and raise error if both request body and body argument are set" do
|
126
|
-
stub_http_request(:post, "www.example.com").with(:
|
177
|
+
stub_http_request(:post, "www.example.com").with(body: "my_params").to_return(body: "abc")
|
127
178
|
req = Net::HTTP::Post.new("/")
|
128
179
|
req.body = "my_params"
|
129
|
-
|
180
|
+
expect {
|
130
181
|
Net::HTTP.start("www.example.com") { |http| http.request(req, "my_params")}
|
131
|
-
}.
|
182
|
+
}.to raise_error("both of body argument and HTTPRequest#body set")
|
132
183
|
end
|
133
184
|
|
134
185
|
it "should return a Net::ReadAdapter from response.body when a stubbed request is made with a block and #read_body" do
|
135
|
-
WebMock.stub_request(:get, 'http://example.com/').to_return(:
|
186
|
+
WebMock.stub_request(:get, 'http://example.com/').to_return(body: "the body")
|
136
187
|
response = Net::HTTP.new('example.com', 80).request_get('/') { |r| r.read_body { } }
|
137
|
-
response.body.
|
188
|
+
expect(response.body).to be_a(Net::ReadAdapter)
|
138
189
|
end
|
139
190
|
|
140
|
-
it "should have request 1 time executed in registry after 1 real request", :
|
191
|
+
it "should have request 1 time executed in registry after 1 real request", net_connect: true do
|
141
192
|
WebMock.allow_net_connect!
|
142
193
|
http = Net::HTTP.new('localhost', port)
|
143
194
|
http.get('/') {}
|
144
|
-
WebMock::RequestRegistry.instance.requested_signatures.hash.size.
|
145
|
-
WebMock::RequestRegistry.instance.requested_signatures.hash.values.first.
|
195
|
+
expect(WebMock::RequestRegistry.instance.requested_signatures.hash.size).to eq(1)
|
196
|
+
expect(WebMock::RequestRegistry.instance.requested_signatures.hash.values.first).to eq(1)
|
197
|
+
end
|
198
|
+
|
199
|
+
it "should work with Addressable::URI passed to Net::HTTP.get_response" do
|
200
|
+
stub_request(:get, 'http://www.example.com/hello?a=1').to_return(body: "abc")
|
201
|
+
expect(Net::HTTP.get_response(Addressable::URI.parse('http://www.example.com/hello?a=1')).body).to eq("abc")
|
202
|
+
end
|
203
|
+
|
204
|
+
it "should support method calls on stubbed socket" do
|
205
|
+
WebMock.allow_net_connect!
|
206
|
+
stub_request(:get, 'www.google.com')#.with(headers: {"My-Header" => 99})
|
207
|
+
req = Net::HTTP::Get.new('/')
|
208
|
+
Net::HTTP.start('www.google.com') do |http|
|
209
|
+
http.request(req, '')
|
210
|
+
socket = http.instance_variable_get(:@socket)
|
211
|
+
expect(socket).to be_a(StubSocket)
|
212
|
+
expect { socket.io.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) }.to_not raise_error
|
213
|
+
end
|
146
214
|
end
|
147
215
|
|
148
216
|
describe "connecting on Net::HTTP.start" do
|
@@ -151,43 +219,49 @@ describe "Net:HTTP" do
|
|
151
219
|
@http.use_ssl = true
|
152
220
|
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
153
221
|
end
|
222
|
+
|
154
223
|
describe "when net http is allowed" do
|
155
|
-
it "should not connect to the server until the request", :
|
224
|
+
it "should not connect to the server until the request", net_connect: true do
|
156
225
|
WebMock.allow_net_connect!
|
157
226
|
@http.start {|conn|
|
158
|
-
conn.peer_cert.
|
227
|
+
expect(conn.peer_cert).to be_nil
|
159
228
|
}
|
160
229
|
end
|
161
230
|
|
162
|
-
it "should connect to the server on start", :
|
163
|
-
WebMock.allow_net_connect!(:
|
231
|
+
it "should connect to the server on start", net_connect: true do
|
232
|
+
WebMock.allow_net_connect!(net_http_connect_on_start: true)
|
164
233
|
@http.start {|conn|
|
165
234
|
cert = OpenSSL::X509::Certificate.new conn.peer_cert
|
166
|
-
cert.
|
235
|
+
expect(cert).to be_a(OpenSSL::X509::Certificate)
|
167
236
|
}
|
168
237
|
end
|
169
238
|
|
170
239
|
end
|
171
240
|
|
172
241
|
describe "when net http is disabled and allowed only for some hosts" do
|
173
|
-
it "should not connect to the server until the request", :
|
174
|
-
WebMock.disable_net_connect!(:
|
242
|
+
it "should not connect to the server until the request", net_connect: true do
|
243
|
+
WebMock.disable_net_connect!(allow: "www.google.com")
|
175
244
|
@http.start {|conn|
|
176
|
-
conn.peer_cert.
|
245
|
+
expect(conn.peer_cert).to be_nil
|
177
246
|
}
|
178
247
|
end
|
179
248
|
|
180
|
-
it "should connect to the server on start", :
|
181
|
-
WebMock.disable_net_connect!(:
|
249
|
+
it "should connect to the server on start", net_connect: true do
|
250
|
+
WebMock.disable_net_connect!(allow: "www.google.com", net_http_connect_on_start: true)
|
182
251
|
@http.start {|conn|
|
183
252
|
cert = OpenSSL::X509::Certificate.new conn.peer_cert
|
184
|
-
cert.
|
253
|
+
expect(cert).to be_a(OpenSSL::X509::Certificate)
|
185
254
|
}
|
186
255
|
end
|
187
256
|
|
188
|
-
it "should connect to the server if the URI matches an regex", :
|
189
|
-
WebMock.disable_net_connect!(:
|
190
|
-
|
257
|
+
it "should connect to the server if the URI matches an regex", net_connect: true do
|
258
|
+
WebMock.disable_net_connect!(allow: /google.com/)
|
259
|
+
Net::HTTP.get('www.google.com','/')
|
260
|
+
end
|
261
|
+
|
262
|
+
it "should connect to the server if the URI matches any regex the array", net_connect: true do
|
263
|
+
WebMock.disable_net_connect!(allow: [/google.com/, /yahoo.com/])
|
264
|
+
Net::HTTP.get('www.google.com','/')
|
191
265
|
end
|
192
266
|
|
193
267
|
end
|
@@ -196,19 +270,19 @@ describe "Net:HTTP" do
|
|
196
270
|
|
197
271
|
describe "when net_http_connect_on_start is true" do
|
198
272
|
before(:each) do
|
199
|
-
WebMock.allow_net_connect!(:
|
273
|
+
WebMock.allow_net_connect!(net_http_connect_on_start: true)
|
200
274
|
end
|
201
275
|
it_should_behave_like "Net::HTTP"
|
202
276
|
end
|
203
277
|
|
204
278
|
describe "when net_http_connect_on_start is false" do
|
205
279
|
before(:each) do
|
206
|
-
WebMock.allow_net_connect!(:
|
280
|
+
WebMock.allow_net_connect!(net_http_connect_on_start: false)
|
207
281
|
end
|
208
282
|
it_should_behave_like "Net::HTTP"
|
209
283
|
end
|
210
284
|
|
211
|
-
describe 'after_request callback support', :
|
285
|
+
describe 'after_request callback support', net_connect: true do
|
212
286
|
let(:expected_body_regex) { /hello world/ }
|
213
287
|
|
214
288
|
before(:each) do
|
@@ -231,25 +305,65 @@ describe "Net:HTTP" do
|
|
231
305
|
end
|
232
306
|
|
233
307
|
it "should support the after_request callback on an request with block and read_body" do
|
234
|
-
response_body = ''
|
308
|
+
response_body = ''.dup
|
235
309
|
http_request(:get, "http://localhost:#{port}/") do |response|
|
236
310
|
response.read_body { |fragment| response_body << fragment }
|
237
311
|
end
|
238
|
-
response_body.
|
312
|
+
expect(response_body).to match(expected_body_regex)
|
239
313
|
|
240
|
-
@callback_response.body.
|
314
|
+
expect(@callback_response.body).to eq(response_body)
|
241
315
|
end
|
242
316
|
|
243
317
|
it "should support the after_request callback on a request with a returning block" do
|
244
318
|
response_body = perform_get_with_returning_block
|
245
|
-
response_body.
|
246
|
-
@callback_response.
|
247
|
-
@callback_response.body.
|
319
|
+
expect(response_body).to match(expected_body_regex)
|
320
|
+
expect(@callback_response).to be_instance_of(WebMock::Response)
|
321
|
+
expect(@callback_response.body).to eq(response_body)
|
248
322
|
end
|
249
323
|
|
250
324
|
it "should only invoke the after_request callback once, even for a recursive post request" do
|
251
325
|
Net::HTTP.new('localhost', port).post('/', nil)
|
252
|
-
@callback_invocation_count.
|
326
|
+
expect(@callback_invocation_count).to eq(1)
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
it "should match http headers, even if their values have been set in a request as numbers" do
|
331
|
+
WebMock.disable_net_connect!
|
332
|
+
|
333
|
+
stub_request(:post, "www.example.com").with(headers: {"My-Header" => 99})
|
334
|
+
|
335
|
+
uri = URI.parse('http://www.example.com/')
|
336
|
+
req = Net::HTTP::Post.new(uri.path)
|
337
|
+
req['My-Header'] = 99
|
338
|
+
|
339
|
+
res = Net::HTTP.start(uri.host, uri.port) do |http|
|
340
|
+
http.request(req, '')
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
describe "hostname handling" do
|
345
|
+
it "should set brackets around the hostname if it is an IPv6 address" do
|
346
|
+
net_http = Net::HTTP.new('b2dc:5bdf:4f0d::3014:e0ca', 80)
|
347
|
+
path = '/example.jpg'
|
348
|
+
expect(WebMock::NetHTTPUtility.get_uri(net_http, path)).to eq('http://[b2dc:5bdf:4f0d::3014:e0ca]:80/example.jpg')
|
349
|
+
end
|
350
|
+
|
351
|
+
it "should not set brackets around the hostname if it is already wrapped by brackets" do
|
352
|
+
net_http = Net::HTTP.new('[b2dc:5bdf:4f0d::3014:e0ca]', 80)
|
353
|
+
path = '/example.jpg'
|
354
|
+
expect(WebMock::NetHTTPUtility.get_uri(net_http, path)).to eq('http://[b2dc:5bdf:4f0d::3014:e0ca]:80/example.jpg')
|
355
|
+
end
|
356
|
+
|
357
|
+
it "should not set brackets around the hostname if it is an IPv4 address" do
|
358
|
+
net_http = Net::HTTP.new('181.152.137.168', 80)
|
359
|
+
path = '/example.jpg'
|
360
|
+
expect(WebMock::NetHTTPUtility.get_uri(net_http, path)).to eq('http://181.152.137.168:80/example.jpg')
|
361
|
+
end
|
362
|
+
|
363
|
+
it "should not set brackets around the hostname if it is a domain" do
|
364
|
+
net_http = Net::HTTP.new('www.example.com', 80)
|
365
|
+
path = '/example.jpg'
|
366
|
+
expect(WebMock::NetHTTPUtility.get_uri(net_http, path)).to eq('http://www.example.com:80/example.jpg')
|
253
367
|
end
|
254
368
|
end
|
255
369
|
end
|
@@ -10,15 +10,18 @@ module NetHTTPSpecHelper
|
|
10
10
|
req = clazz.new("#{uri.path}#{uri.query ? '?' : ''}#{uri.query}", nil)
|
11
11
|
options[:headers].each do |k,v|
|
12
12
|
if v.is_a?(Array)
|
13
|
-
v.each_with_index do |
|
14
|
-
i == 0 ? (req[k] =
|
13
|
+
v.each_with_index do |e,i|
|
14
|
+
i == 0 ? (req[k] = e) : req.add_field(k, e)
|
15
15
|
end
|
16
16
|
else
|
17
17
|
req[k] = v
|
18
18
|
end
|
19
19
|
end if options[:headers]
|
20
20
|
|
21
|
-
|
21
|
+
if options[:basic_auth]
|
22
|
+
req.basic_auth(options[:basic_auth][0], options[:basic_auth][1])
|
23
|
+
end
|
24
|
+
|
22
25
|
http = Net::HTTP.new(uri.host, uri.port)
|
23
26
|
if uri.scheme == "https"
|
24
27
|
http.use_ssl = true
|
@@ -28,21 +31,27 @@ module NetHTTPSpecHelper
|
|
28
31
|
http.read_timeout = 60
|
29
32
|
end
|
30
33
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
31
|
-
response = http.start {|
|
32
|
-
|
34
|
+
response = http.start {|open_http|
|
35
|
+
open_http.request(req, options[:body], &block)
|
33
36
|
}
|
34
37
|
headers = {}
|
35
38
|
response.each_header {|name, value| headers[name] = value}
|
36
39
|
OpenStruct.new({
|
37
|
-
:
|
38
|
-
:
|
39
|
-
:
|
40
|
-
:
|
40
|
+
body: response.body,
|
41
|
+
headers: WebMock::Util::Headers.normalize_headers(headers),
|
42
|
+
status: response.code,
|
43
|
+
message: response.message
|
41
44
|
})
|
42
45
|
end
|
43
46
|
|
44
47
|
def client_timeout_exception_class
|
45
|
-
|
48
|
+
if defined?(Net::OpenTimeout)
|
49
|
+
Net::OpenTimeout
|
50
|
+
elsif defined?(Net::HTTP::OpenTimeout)
|
51
|
+
Net::HTTP::OpenTimeout
|
52
|
+
else
|
53
|
+
Timeout::Error
|
54
|
+
end
|
46
55
|
end
|
47
56
|
|
48
57
|
def connection_refused_exception_class
|
@@ -6,7 +6,7 @@ require 'stringio'
|
|
6
6
|
require 'acceptance/net_http/net_http_shared'
|
7
7
|
require 'support/webmock_server'
|
8
8
|
|
9
|
-
describe "Real Net:HTTP without webmock", :
|
9
|
+
describe "Real Net:HTTP without webmock", without_webmock: true do
|
10
10
|
before(:all) do
|
11
11
|
raise "WebMock has no access here!!!" if defined?(WebMock::NetHTTPUtility)
|
12
12
|
WebMockServer.instance.start
|