webmock 3.5.0 → 3.25.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 +4 -4
- data/CHANGELOG.md +476 -2
- data/README.md +166 -42
- data/lib/webmock/api.rb +2 -0
- data/lib/webmock/assertion_failure.rb +2 -0
- data/lib/webmock/callback_registry.rb +2 -0
- data/lib/webmock/config.rb +2 -0
- data/lib/webmock/cucumber.rb +2 -0
- data/lib/webmock/deprecation.rb +2 -0
- data/lib/webmock/errors.rb +2 -0
- data/lib/webmock/http_lib_adapters/async_http_client_adapter.rb +228 -0
- data/lib/webmock/http_lib_adapters/curb_adapter.rb +14 -3
- data/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +22 -9
- data/lib/webmock/http_lib_adapters/excon_adapter.rb +5 -0
- data/lib/webmock/http_lib_adapters/http_lib_adapter.rb +2 -0
- data/lib/webmock/http_lib_adapters/http_lib_adapter_registry.rb +2 -0
- data/lib/webmock/http_lib_adapters/http_rb/client.rb +4 -1
- data/lib/webmock/http_lib_adapters/http_rb/request.rb +17 -5
- data/lib/webmock/http_lib_adapters/http_rb/response.rb +49 -5
- data/lib/webmock/http_lib_adapters/http_rb/streamer.rb +11 -3
- data/lib/webmock/http_lib_adapters/http_rb/webmock.rb +8 -2
- data/lib/webmock/http_lib_adapters/http_rb_adapter.rb +7 -5
- data/lib/webmock/http_lib_adapters/httpclient_adapter.rb +25 -7
- data/lib/webmock/http_lib_adapters/manticore_adapter.rb +35 -15
- data/lib/webmock/http_lib_adapters/net_http.rb +59 -112
- data/lib/webmock/http_lib_adapters/net_http_response.rb +3 -1
- data/lib/webmock/http_lib_adapters/patron_adapter.rb +4 -2
- data/lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb +18 -2
- data/lib/webmock/matchers/any_arg_matcher.rb +2 -0
- data/lib/webmock/matchers/hash_argument_matcher.rb +2 -0
- data/lib/webmock/matchers/hash_excluding_matcher.rb +2 -0
- data/lib/webmock/matchers/hash_including_matcher.rb +2 -0
- data/lib/webmock/minitest.rb +2 -0
- data/lib/webmock/rack_response.rb +5 -1
- data/lib/webmock/request_body_diff.rb +3 -1
- data/lib/webmock/request_execution_verifier.rb +2 -0
- data/lib/webmock/request_pattern.rb +118 -61
- data/lib/webmock/request_registry.rb +2 -0
- data/lib/webmock/request_signature.rb +4 -2
- data/lib/webmock/request_signature_snippet.rb +2 -0
- data/lib/webmock/request_stub.rb +34 -0
- data/lib/webmock/response.rb +22 -14
- data/lib/webmock/responses_sequence.rb +2 -0
- data/lib/webmock/rspec/matchers/request_pattern_matcher.rb +2 -0
- data/lib/webmock/rspec/matchers/webmock_matcher.rb +2 -0
- data/lib/webmock/rspec/matchers.rb +2 -0
- data/lib/webmock/rspec.rb +4 -1
- data/lib/webmock/stub_registry.rb +28 -11
- data/lib/webmock/stub_request_snippet.rb +2 -0
- data/lib/webmock/test_unit.rb +3 -3
- data/lib/webmock/util/hash_counter.rb +12 -6
- data/lib/webmock/util/hash_keys_stringifier.rb +2 -0
- data/lib/webmock/util/hash_validator.rb +2 -0
- data/lib/webmock/util/headers.rb +23 -10
- data/lib/webmock/util/parsers/json.rb +72 -0
- data/lib/webmock/util/parsers/parse_error.rb +7 -0
- data/lib/webmock/util/parsers/xml.rb +16 -0
- data/lib/webmock/util/query_mapper.rb +6 -2
- data/lib/webmock/util/uri.rb +11 -9
- data/lib/webmock/util/values_stringifier.rb +2 -0
- data/lib/webmock/util/version_checker.rb +7 -5
- data/lib/webmock/version.rb +3 -1
- data/lib/webmock/webmock.rb +22 -3
- data/lib/webmock.rb +5 -2
- metadata +99 -175
- data/.gemtest +0 -0
- data/.gitignore +0 -34
- data/.rspec-tm +0 -2
- data/.travis.yml +0 -21
- data/Gemfile +0 -9
- data/Rakefile +0 -30
- data/lib/webmock/util/json.rb +0 -67
- data/minitest/test_helper.rb +0 -34
- data/minitest/test_webmock.rb +0 -9
- data/minitest/webmock_spec.rb +0 -60
- data/spec/acceptance/curb/curb_spec.rb +0 -481
- data/spec/acceptance/curb/curb_spec_helper.rb +0 -147
- data/spec/acceptance/em_http_request/em_http_request_spec.rb +0 -406
- data/spec/acceptance/em_http_request/em_http_request_spec_helper.rb +0 -77
- data/spec/acceptance/excon/excon_spec.rb +0 -77
- data/spec/acceptance/excon/excon_spec_helper.rb +0 -50
- data/spec/acceptance/http_rb/http_rb_spec.rb +0 -82
- data/spec/acceptance/http_rb/http_rb_spec_helper.rb +0 -54
- data/spec/acceptance/httpclient/httpclient_spec.rb +0 -217
- data/spec/acceptance/httpclient/httpclient_spec_helper.rb +0 -57
- data/spec/acceptance/manticore/manticore_spec.rb +0 -56
- data/spec/acceptance/manticore/manticore_spec_helper.rb +0 -35
- data/spec/acceptance/net_http/net_http_shared.rb +0 -153
- data/spec/acceptance/net_http/net_http_spec.rb +0 -331
- data/spec/acceptance/net_http/net_http_spec_helper.rb +0 -64
- data/spec/acceptance/net_http/real_net_http_spec.rb +0 -20
- data/spec/acceptance/patron/patron_spec.rb +0 -125
- data/spec/acceptance/patron/patron_spec_helper.rb +0 -54
- data/spec/acceptance/shared/allowing_and_disabling_net_connect.rb +0 -313
- data/spec/acceptance/shared/callbacks.rb +0 -147
- data/spec/acceptance/shared/complex_cross_concern_behaviors.rb +0 -36
- data/spec/acceptance/shared/enabling_and_disabling_webmock.rb +0 -95
- data/spec/acceptance/shared/precedence_of_stubs.rb +0 -15
- data/spec/acceptance/shared/request_expectations.rb +0 -923
- data/spec/acceptance/shared/returning_declared_responses.rb +0 -388
- data/spec/acceptance/shared/stubbing_requests.rb +0 -638
- data/spec/acceptance/typhoeus/typhoeus_hydra_spec.rb +0 -135
- data/spec/acceptance/typhoeus/typhoeus_hydra_spec_helper.rb +0 -60
- data/spec/acceptance/webmock_shared.rb +0 -41
- data/spec/fixtures/test.txt +0 -1
- data/spec/quality_spec.rb +0 -84
- data/spec/spec_helper.rb +0 -48
- data/spec/support/example_curl_output.txt +0 -22
- data/spec/support/failures.rb +0 -9
- data/spec/support/my_rack_app.rb +0 -53
- data/spec/support/network_connection.rb +0 -19
- data/spec/support/webmock_server.rb +0 -69
- data/spec/unit/api_spec.rb +0 -175
- data/spec/unit/errors_spec.rb +0 -129
- data/spec/unit/http_lib_adapters/http_lib_adapter_registry_spec.rb +0 -17
- data/spec/unit/http_lib_adapters/http_lib_adapter_spec.rb +0 -12
- data/spec/unit/matchers/hash_excluding_matcher_spec.rb +0 -61
- data/spec/unit/matchers/hash_including_matcher_spec.rb +0 -87
- data/spec/unit/rack_response_spec.rb +0 -112
- data/spec/unit/request_body_diff_spec.rb +0 -90
- data/spec/unit/request_execution_verifier_spec.rb +0 -208
- data/spec/unit/request_pattern_spec.rb +0 -596
- data/spec/unit/request_registry_spec.rb +0 -95
- data/spec/unit/request_signature_snippet_spec.rb +0 -89
- data/spec/unit/request_signature_spec.rb +0 -155
- data/spec/unit/request_stub_spec.rb +0 -199
- data/spec/unit/response_spec.rb +0 -282
- data/spec/unit/stub_registry_spec.rb +0 -103
- data/spec/unit/stub_request_snippet_spec.rb +0 -115
- data/spec/unit/util/hash_counter_spec.rb +0 -39
- data/spec/unit/util/hash_keys_stringifier_spec.rb +0 -27
- data/spec/unit/util/headers_spec.rb +0 -28
- data/spec/unit/util/json_spec.rb +0 -33
- data/spec/unit/util/query_mapper_spec.rb +0 -150
- data/spec/unit/util/uri_spec.rb +0 -299
- data/spec/unit/util/version_checker_spec.rb +0 -65
- data/spec/unit/webmock_spec.rb +0 -11
- data/test/http_request.rb +0 -24
- data/test/shared_test.rb +0 -108
- data/test/test_helper.rb +0 -23
- data/test/test_webmock.rb +0 -6
- data/webmock.gemspec +0 -46
@@ -1,3 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
return if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.4.0')
|
4
|
+
|
1
5
|
begin
|
2
6
|
require 'em-http-request'
|
3
7
|
rescue LoadError
|
@@ -99,6 +103,11 @@ if defined?(EventMachine::HttpClient)
|
|
99
103
|
end
|
100
104
|
end
|
101
105
|
|
106
|
+
def connection_completed
|
107
|
+
@state = :response_header
|
108
|
+
send_request(*headers_and_body_processed_by_middleware)
|
109
|
+
end
|
110
|
+
|
102
111
|
def send_request(head, body)
|
103
112
|
WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)
|
104
113
|
|
@@ -107,7 +116,7 @@ if defined?(EventMachine::HttpClient)
|
|
107
116
|
@uri ||= nil
|
108
117
|
EM.next_tick {
|
109
118
|
setup(make_raw_response(stubbed_webmock_response), @uri,
|
110
|
-
stubbed_webmock_response.should_timeout ?
|
119
|
+
stubbed_webmock_response.should_timeout ? Errno::ETIMEDOUT : nil)
|
111
120
|
}
|
112
121
|
self
|
113
122
|
elsif WebMock.net_connect_allowed?(request_signature.uri)
|
@@ -149,7 +158,7 @@ if defined?(EventMachine::HttpClient)
|
|
149
158
|
raw_cookie = response_header.cookie
|
150
159
|
raw_cookie = [raw_cookie] if raw_cookie.is_a? String
|
151
160
|
|
152
|
-
cookie = raw_cookie.
|
161
|
+
cookie = raw_cookie.detect { |c| c.start_with? name }
|
153
162
|
cookie and cookie.split('=', 2)[1]
|
154
163
|
end
|
155
164
|
|
@@ -163,12 +172,18 @@ if defined?(EventMachine::HttpClient)
|
|
163
172
|
webmock_response
|
164
173
|
end
|
165
174
|
|
166
|
-
def
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
175
|
+
def headers_and_body_processed_by_middleware
|
176
|
+
@headers_and_body_processed_by_middleware ||= begin
|
177
|
+
head, body = build_request, @req.body
|
178
|
+
@conn.middleware.each do |m|
|
179
|
+
head, body = m.request(self, head, body) if m.respond_to?(:request)
|
180
|
+
end
|
181
|
+
[head, body]
|
171
182
|
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def build_request_signature
|
186
|
+
headers, body = headers_and_body_processed_by_middleware
|
172
187
|
|
173
188
|
method = @req.method
|
174
189
|
uri = @req.uri.clone
|
@@ -178,8 +193,6 @@ if defined?(EventMachine::HttpClient)
|
|
178
193
|
|
179
194
|
body = form_encode_body(body) if body.is_a?(Hash)
|
180
195
|
|
181
|
-
headers = @req.headers
|
182
|
-
|
183
196
|
if headers['authorization'] && headers['authorization'].is_a?(Array)
|
184
197
|
headers['Authorization'] = WebMock::Util::Headers.basic_auth_header(headers.delete('authorization'))
|
185
198
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
begin
|
2
4
|
require 'excon'
|
3
5
|
rescue LoadError
|
@@ -159,4 +161,7 @@ if defined?(Excon)
|
|
159
161
|
end
|
160
162
|
end
|
161
163
|
end
|
164
|
+
|
165
|
+
# Suppresses Excon connection argument validation warning
|
166
|
+
Excon::VALID_CONNECTION_KEYS << :__construction_args
|
162
167
|
end
|
@@ -1,10 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module HTTP
|
2
4
|
class Client
|
3
5
|
alias_method :__perform__, :perform
|
4
6
|
|
5
7
|
def perform(request, options)
|
6
8
|
return __perform__(request, options) unless webmock_enabled?
|
7
|
-
|
9
|
+
|
10
|
+
WebMockPerform.new(request, options) { __perform__(request, options) }.exec
|
8
11
|
end
|
9
12
|
|
10
13
|
def webmock_enabled?
|
@@ -1,11 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module HTTP
|
2
4
|
class Request
|
3
5
|
def webmock_signature
|
4
|
-
request_body =
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
request_body = nil
|
7
|
+
|
8
|
+
if defined?(HTTP::Request::Body)
|
9
|
+
request_body = String.new
|
10
|
+
first_chunk_encoding = nil
|
11
|
+
body.each do |part|
|
12
|
+
request_body << part
|
13
|
+
first_chunk_encoding ||= part.encoding
|
14
|
+
end
|
15
|
+
|
16
|
+
request_body.force_encoding(first_chunk_encoding) if first_chunk_encoding
|
17
|
+
request_body
|
18
|
+
else
|
19
|
+
request_body = body
|
20
|
+
end
|
9
21
|
|
10
22
|
::WebMock::RequestSignature.new(verb, uri.to_s, {
|
11
23
|
headers: headers.to_h,
|
@@ -1,34 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module HTTP
|
2
4
|
class Response
|
3
5
|
def to_webmock
|
4
6
|
webmock_response = ::WebMock::Response.new
|
5
7
|
|
6
8
|
webmock_response.status = [status.to_i, reason]
|
9
|
+
|
7
10
|
webmock_response.body = body.to_s
|
8
|
-
|
11
|
+
# This call is used to reset the body of the response to enable it to be streamed if necessary.
|
12
|
+
# The `body.to_s` call above reads the body, which allows WebMock to trigger any registered callbacks.
|
13
|
+
# However, once the body is read to_s, it cannot be streamed again and attempting to do so
|
14
|
+
# will raise a "HTTP::StateError: body has already been consumed" error.
|
15
|
+
# To avoid this error, we replace the original body with a new one.
|
16
|
+
# The new body has its @stream attribute set to new Streamer, instead of the original Connection.
|
17
|
+
# Unfortunately, it's not possible to reset the original body to its initial streaming state.
|
18
|
+
# Therefore, this replacement is the best workaround currently available.
|
19
|
+
reset_body_to_allow_it_to_be_streamed!(webmock_response)
|
9
20
|
|
21
|
+
webmock_response.headers = headers.to_h
|
10
22
|
webmock_response
|
11
23
|
end
|
12
24
|
|
13
25
|
class << self
|
14
|
-
def from_webmock(webmock_response, request_signature = nil)
|
26
|
+
def from_webmock(request, webmock_response, request_signature = nil)
|
15
27
|
status = Status.new(webmock_response.status.first)
|
16
28
|
headers = webmock_response.headers || {}
|
17
|
-
body = Body.new Streamer.new webmock_response.body
|
18
29
|
uri = normalize_uri(request_signature && request_signature.uri)
|
19
30
|
|
31
|
+
# HTTP.rb 3.0+ uses a keyword argument to pass the encoding, but 1.x
|
32
|
+
# and 2.x use a positional argument, and 0.x don't support supplying
|
33
|
+
# the encoding.
|
34
|
+
body = build_http_rb_response_body_from_webmock_response(webmock_response)
|
35
|
+
|
20
36
|
return new(status, "1.1", headers, body, uri) if HTTP::VERSION < "1.0.0"
|
21
37
|
|
38
|
+
# 5.0.0 had a breaking change to require request instead of uri.
|
39
|
+
if HTTP::VERSION < '5.0.0'
|
40
|
+
return new({
|
41
|
+
status: status,
|
42
|
+
version: "1.1",
|
43
|
+
headers: headers,
|
44
|
+
body: body,
|
45
|
+
uri: uri
|
46
|
+
})
|
47
|
+
end
|
48
|
+
|
22
49
|
new({
|
23
50
|
status: status,
|
24
51
|
version: "1.1",
|
25
52
|
headers: headers,
|
26
53
|
body: body,
|
27
|
-
|
54
|
+
request: request,
|
28
55
|
})
|
29
56
|
end
|
30
57
|
|
31
|
-
|
58
|
+
def build_http_rb_response_body_from_webmock_response(webmock_response)
|
59
|
+
if HTTP::VERSION < "1.0.0"
|
60
|
+
Body.new(Streamer.new(webmock_response.body))
|
61
|
+
elsif HTTP::VERSION < "3.0.0"
|
62
|
+
Body.new(Streamer.new(webmock_response.body), webmock_response.body.encoding)
|
63
|
+
else
|
64
|
+
Body.new(
|
65
|
+
Streamer.new(webmock_response.body, encoding: webmock_response.body.encoding),
|
66
|
+
encoding: webmock_response.body.encoding
|
67
|
+
)
|
68
|
+
end
|
69
|
+
end
|
32
70
|
|
33
71
|
def normalize_uri(uri)
|
34
72
|
return unless uri
|
@@ -39,5 +77,11 @@ module HTTP
|
|
39
77
|
uri
|
40
78
|
end
|
41
79
|
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def reset_body_to_allow_it_to_be_streamed!(webmock_response)
|
84
|
+
@body = self.class.build_http_rb_response_body_from_webmock_response(webmock_response)
|
85
|
+
end
|
42
86
|
end
|
43
87
|
end
|
@@ -1,11 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module HTTP
|
2
4
|
class Response
|
3
5
|
class Streamer
|
4
|
-
def initialize(str)
|
6
|
+
def initialize(str, encoding: Encoding::BINARY)
|
5
7
|
@io = StringIO.new str
|
8
|
+
@encoding = encoding
|
6
9
|
end
|
7
10
|
|
8
|
-
def readpartial(size = nil)
|
11
|
+
def readpartial(size = nil, outbuf = nil)
|
9
12
|
unless size
|
10
13
|
if defined?(HTTP::Client::BUFFER_SIZE)
|
11
14
|
size = HTTP::Client::BUFFER_SIZE
|
@@ -14,13 +17,18 @@ module HTTP
|
|
14
17
|
end
|
15
18
|
end
|
16
19
|
|
17
|
-
@io.read size
|
20
|
+
chunk = @io.read size, outbuf
|
21
|
+
chunk.force_encoding(@encoding) if chunk
|
18
22
|
end
|
19
23
|
|
20
24
|
def close
|
21
25
|
@io.close
|
22
26
|
end
|
23
27
|
|
28
|
+
def finished_request?
|
29
|
+
@io.eof?
|
30
|
+
end
|
31
|
+
|
24
32
|
def sequence_id
|
25
33
|
-1
|
26
34
|
end
|
@@ -1,7 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module HTTP
|
2
4
|
class WebMockPerform
|
3
|
-
def initialize(request, &perform)
|
5
|
+
def initialize(request, options, &perform)
|
4
6
|
@request = request
|
7
|
+
@options = options
|
5
8
|
@perform = perform
|
6
9
|
@request_signature = nil
|
7
10
|
end
|
@@ -38,7 +41,10 @@ module HTTP
|
|
38
41
|
webmock_response.raise_error_if_any
|
39
42
|
|
40
43
|
invoke_callbacks(webmock_response, real_request: false)
|
41
|
-
::HTTP::Response.from_webmock webmock_response, request_signature
|
44
|
+
response = ::HTTP::Response.from_webmock @request, webmock_response, request_signature
|
45
|
+
|
46
|
+
@options.features.each { |_name, feature| response = feature.wrap_response(response) }
|
47
|
+
response
|
42
48
|
end
|
43
49
|
|
44
50
|
def raise_timeout_error
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
begin
|
2
4
|
require "http"
|
3
5
|
rescue LoadError
|
@@ -29,9 +31,9 @@ if defined?(HTTP) && defined?(HTTP::VERSION)
|
|
29
31
|
end
|
30
32
|
end
|
31
33
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
require_relative "http_rb/client"
|
35
|
+
require_relative "http_rb/request"
|
36
|
+
require_relative "http_rb/response"
|
37
|
+
require_relative "http_rb/streamer"
|
38
|
+
require_relative "http_rb/webmock"
|
37
39
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
begin
|
2
4
|
require 'httpclient'
|
3
5
|
require 'jsonclient' # defined in 'httpclient' gem as well
|
@@ -43,6 +45,11 @@ if defined?(::HTTPClient)
|
|
43
45
|
end
|
44
46
|
|
45
47
|
module WebMockHTTPClients
|
48
|
+
WEBMOCK_HTTPCLIENT_RESPONSES = :webmock_httpclient_responses
|
49
|
+
WEBMOCK_HTTPCLIENT_REQUEST_SIGNATURES = :webmock_httpclient_request_signatures
|
50
|
+
|
51
|
+
REQUEST_RESPONSE_LOCK = Mutex.new
|
52
|
+
|
46
53
|
def do_get_block(req, proxy, conn, &block)
|
47
54
|
do_get(req, proxy, conn, false, &block)
|
48
55
|
end
|
@@ -52,6 +59,8 @@ if defined?(::HTTPClient)
|
|
52
59
|
end
|
53
60
|
|
54
61
|
def do_get(req, proxy, conn, stream = false, &block)
|
62
|
+
clear_thread_variables unless conn.async_thread
|
63
|
+
|
55
64
|
request_signature = build_request_signature(req, :reuse_existing)
|
56
65
|
|
57
66
|
WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)
|
@@ -98,12 +107,16 @@ if defined?(::HTTPClient)
|
|
98
107
|
end
|
99
108
|
|
100
109
|
def do_request_async(method, uri, query, body, extheader)
|
110
|
+
clear_thread_variables
|
101
111
|
req = create_request(method, uri, query, body, extheader)
|
102
112
|
request_signature = build_request_signature(req)
|
103
113
|
webmock_request_signatures << request_signature
|
104
114
|
|
105
115
|
if webmock_responses[request_signature] || WebMock.net_connect_allowed?(request_signature.uri)
|
106
|
-
super
|
116
|
+
conn = super
|
117
|
+
conn.async_thread[WEBMOCK_HTTPCLIENT_REQUEST_SIGNATURES] = Thread.current[WEBMOCK_HTTPCLIENT_REQUEST_SIGNATURES]
|
118
|
+
conn.async_thread[WEBMOCK_HTTPCLIENT_RESPONSES] = Thread.current[WEBMOCK_HTTPCLIENT_RESPONSES]
|
119
|
+
conn
|
107
120
|
else
|
108
121
|
raise WebMock::NetConnectNotAllowedError.new(request_signature)
|
109
122
|
end
|
@@ -152,14 +165,14 @@ if defined?(::HTTPClient)
|
|
152
165
|
end
|
153
166
|
|
154
167
|
def build_request_signature(req, reuse_existing = false)
|
155
|
-
uri = WebMock::Util::URI.heuristic_parse(req.header.request_uri.to_s)
|
156
|
-
uri.query = WebMock::Util::QueryMapper.values_to_query(req.header.request_query, notation: WebMock::Config.instance.query_values_notation) if req.header.request_query
|
157
|
-
uri.port = req.header.request_uri.port
|
158
|
-
|
159
168
|
@request_filter.each do |filter|
|
160
169
|
filter.filter_request(req)
|
161
170
|
end
|
162
171
|
|
172
|
+
uri = WebMock::Util::URI.heuristic_parse(req.header.request_uri.to_s)
|
173
|
+
uri.query = WebMock::Util::QueryMapper.values_to_query(req.header.request_query, notation: WebMock::Config.instance.query_values_notation) if req.header.request_query
|
174
|
+
uri.port = req.header.request_uri.port
|
175
|
+
|
163
176
|
headers = req.header.all.inject({}) do |hdrs, header|
|
164
177
|
hdrs[header[0]] ||= []
|
165
178
|
hdrs[header[0]] << header[1]
|
@@ -183,13 +196,13 @@ if defined?(::HTTPClient)
|
|
183
196
|
end
|
184
197
|
|
185
198
|
def webmock_responses
|
186
|
-
|
199
|
+
Thread.current[WEBMOCK_HTTPCLIENT_RESPONSES] ||= Hash.new do |hash, request_signature|
|
187
200
|
hash[request_signature] = WebMock::StubRegistry.instance.response_for_request(request_signature)
|
188
201
|
end
|
189
202
|
end
|
190
203
|
|
191
204
|
def webmock_request_signatures
|
192
|
-
|
205
|
+
Thread.current[WEBMOCK_HTTPCLIENT_REQUEST_SIGNATURES] ||= []
|
193
206
|
end
|
194
207
|
|
195
208
|
def previous_signature_for(signature)
|
@@ -209,6 +222,11 @@ if defined?(::HTTPClient)
|
|
209
222
|
hdrs
|
210
223
|
end
|
211
224
|
end
|
225
|
+
|
226
|
+
def clear_thread_variables
|
227
|
+
Thread.current[WEBMOCK_HTTPCLIENT_REQUEST_SIGNATURES] = nil
|
228
|
+
Thread.current[WEBMOCK_HTTPCLIENT_RESPONSES] = nil
|
229
|
+
end
|
212
230
|
end
|
213
231
|
|
214
232
|
class WebMockHTTPClient < HTTPClient
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
begin
|
2
4
|
require 'manticore'
|
3
5
|
rescue LoadError
|
@@ -24,6 +26,12 @@ if defined?(Manticore)
|
|
24
26
|
Manticore.instance_variable_set(:@manticore_facade, OriginalManticoreClient.new)
|
25
27
|
end
|
26
28
|
|
29
|
+
class StubbedTimeoutResponse < Manticore::StubbedResponse
|
30
|
+
def call
|
31
|
+
@handlers[:failure].call(Manticore::ConnectTimeout.new("Too slow (mocked timeout)"))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
27
35
|
class WebMockManticoreClient < Manticore::Client
|
28
36
|
def request(klass, url, options={}, &block)
|
29
37
|
super(klass, WebMock::Util::URI.normalize_uri(url).to_s, format_options(options))
|
@@ -50,19 +58,22 @@ if defined?(Manticore)
|
|
50
58
|
|
51
59
|
if webmock_response = registered_response_for(request_signature)
|
52
60
|
webmock_response.raise_error_if_any
|
53
|
-
manticore_response = generate_manticore_response(webmock_response)
|
54
|
-
|
61
|
+
manticore_response = generate_manticore_response(webmock_response)
|
62
|
+
manticore_response.on_success do
|
63
|
+
WebMock::CallbackRegistry.invoke_callbacks({lib: :manticore, real_request: false}, request_signature, webmock_response)
|
64
|
+
end
|
55
65
|
|
56
66
|
elsif real_request_allowed?(request_signature.uri)
|
57
|
-
manticore_response = Manticore::Response.new(self, request, context, &block)
|
58
|
-
|
59
|
-
|
67
|
+
manticore_response = Manticore::Response.new(self, request, context, &block)
|
68
|
+
manticore_response.on_complete do |completed_response|
|
69
|
+
webmock_response = generate_webmock_response(completed_response)
|
70
|
+
WebMock::CallbackRegistry.invoke_callbacks({lib: :manticore, real_request: true}, request_signature, webmock_response)
|
71
|
+
end
|
60
72
|
|
61
73
|
else
|
62
74
|
raise WebMock::NetConnectNotAllowedError.new(request_signature)
|
63
75
|
end
|
64
76
|
|
65
|
-
WebMock::CallbackRegistry.invoke_callbacks({lib: :manticore, real_request: real_request}, request_signature, webmock_response)
|
66
77
|
manticore_response
|
67
78
|
end
|
68
79
|
|
@@ -103,21 +114,30 @@ if defined?(Manticore)
|
|
103
114
|
end
|
104
115
|
|
105
116
|
def generate_manticore_response(webmock_response)
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
117
|
+
if webmock_response.should_timeout
|
118
|
+
StubbedTimeoutResponse.new
|
119
|
+
else
|
120
|
+
Manticore::StubbedResponse.stub(
|
121
|
+
code: webmock_response.status[0],
|
122
|
+
body: webmock_response.body,
|
123
|
+
headers: webmock_response.headers,
|
124
|
+
cookies: {}
|
125
|
+
)
|
126
|
+
end
|
114
127
|
end
|
115
128
|
|
116
129
|
def generate_webmock_response(manticore_response)
|
117
130
|
webmock_response = WebMock::Response.new
|
118
131
|
webmock_response.status = [manticore_response.code, manticore_response.message]
|
119
|
-
webmock_response.body = manticore_response.body
|
120
132
|
webmock_response.headers = manticore_response.headers
|
133
|
+
|
134
|
+
# The attempt to read the body could fail if manticore is used in a streaming mode
|
135
|
+
webmock_response.body = begin
|
136
|
+
manticore_response.body
|
137
|
+
rescue ::Manticore::StreamClosedException
|
138
|
+
nil
|
139
|
+
end
|
140
|
+
|
121
141
|
webmock_response
|
122
142
|
end
|
123
143
|
end
|