webmock 3.14.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 +213 -3
- data/README.md +66 -20
- 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 +16 -4
- data/lib/webmock/http_lib_adapters/curb_adapter.rb +4 -2
- data/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +17 -7
- data/lib/webmock/http_lib_adapters/excon_adapter.rb +2 -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 +3 -3
- data/lib/webmock/http_lib_adapters/http_rb/request.rb +17 -5
- data/lib/webmock/http_lib_adapters/http_rb/response.rb +32 -9
- data/lib/webmock/http_lib_adapters/http_rb/streamer.rb +10 -2
- 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 +26 -25
- data/lib/webmock/http_lib_adapters/manticore_adapter.rb +2 -0
- data/lib/webmock/http_lib_adapters/net_http.rb +46 -121
- data/lib/webmock/http_lib_adapters/net_http_response.rb +2 -0
- data/lib/webmock/http_lib_adapters/patron_adapter.rb +3 -1
- 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 +2 -0
- data/lib/webmock/request_execution_verifier.rb +2 -0
- data/lib/webmock/request_pattern.rb +35 -12
- 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 +15 -13
- 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 +2 -0
- data/lib/webmock/stub_registry.rb +2 -0
- data/lib/webmock/stub_request_snippet.rb +2 -0
- data/lib/webmock/test_unit.rb +2 -0
- 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 +2 -0
- data/lib/webmock/util/uri.rb +3 -1
- 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 +12 -0
- data/lib/webmock.rb +4 -2
- metadata +66 -185
- data/.gemtest +0 -0
- data/.github/workflows/CI.yml +0 -37
- data/.gitignore +0 -34
- data/.rspec-tm +0 -2
- data/Gemfile +0 -9
- data/Rakefile +0 -38
- 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/async_http_client/async_http_client_spec.rb +0 -375
- data/spec/acceptance/async_http_client/async_http_client_spec_helper.rb +0 -73
- data/spec/acceptance/curb/curb_spec.rb +0 -499
- data/spec/acceptance/curb/curb_spec_helper.rb +0 -147
- data/spec/acceptance/em_http_request/em_http_request_spec.rb +0 -462
- 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 -52
- data/spec/acceptance/http_rb/http_rb_spec.rb +0 -93
- 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 -107
- 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 -369
- 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 -148
- 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 -930
- data/spec/acceptance/shared/returning_declared_responses.rb +0 -409
- data/spec/acceptance/shared/stubbing_requests.rb +0 -678
- 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 -70
- 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 -736
- 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 -286
- 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 -157
- data/spec/unit/util/uri_spec.rb +0 -371
- data/spec/unit/util/version_checker_spec.rb +0 -65
- data/spec/unit/webmock_spec.rb +0 -60
- 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 -12
- data/webmock.gemspec +0 -54
@@ -1,462 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
require 'spec_helper'
|
3
|
-
require 'acceptance/webmock_shared'
|
4
|
-
require 'ostruct'
|
5
|
-
|
6
|
-
unless RUBY_PLATFORM =~ /java/
|
7
|
-
require 'acceptance/em_http_request/em_http_request_spec_helper'
|
8
|
-
|
9
|
-
describe "EM::HttpRequest" do
|
10
|
-
include EMHttpRequestSpecHelper
|
11
|
-
|
12
|
-
include_context "with WebMock", :no_status_message
|
13
|
-
|
14
|
-
#functionality only supported for em-http-request 1.x
|
15
|
-
if defined?(EventMachine::HttpConnection)
|
16
|
-
context 'when a real request is made and redirects are followed', net_connect: true do
|
17
|
-
before { WebMock.allow_net_connect! }
|
18
|
-
|
19
|
-
# This url redirects to the https URL.
|
20
|
-
let(:http_url) { "http://raw.github.com:80/gist/fb555cb593f3349d53af/6921dd638337d3f6a51b0e02e7f30e3c414f70d6/vcr_gist" }
|
21
|
-
let(:https_url) { http_url.gsub('http', 'https').gsub('80', '443') }
|
22
|
-
|
23
|
-
def make_request
|
24
|
-
EM.run do
|
25
|
-
request = EM::HttpRequest.new(http_url).get(redirects: 1)
|
26
|
-
request.callback { EM.stop }
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
it "invokes the globally_stub_request hook with both requests" do
|
31
|
-
urls = []
|
32
|
-
WebMock.globally_stub_request { |r| urls << r.uri.to_s; nil }
|
33
|
-
|
34
|
-
make_request
|
35
|
-
|
36
|
-
expect(urls).to eq([http_url, https_url])
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'invokes the after_request hook with both requests' do
|
40
|
-
urls = []
|
41
|
-
WebMock.after_request { |req, res| urls << req.uri.to_s }
|
42
|
-
|
43
|
-
make_request
|
44
|
-
|
45
|
-
expect(urls).to eq([http_url, https_url])
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
describe "with middleware" do
|
50
|
-
|
51
|
-
it "should work with request middleware" do
|
52
|
-
stub_request(:get, "www.example.com").with(body: 'bar')
|
53
|
-
|
54
|
-
middleware = Class.new do
|
55
|
-
def request(client, head, body)
|
56
|
-
[{}, 'bar']
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
EM.run do
|
61
|
-
conn = EventMachine::HttpRequest.new('http://www.example.com/')
|
62
|
-
|
63
|
-
conn.use middleware
|
64
|
-
|
65
|
-
http = conn.get(body: 'foo')
|
66
|
-
|
67
|
-
http.callback do
|
68
|
-
expect(WebMock).to have_requested(:get, "www.example.com").with(body: 'bar')
|
69
|
-
EM.stop
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
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
|
-
|
103
|
-
let(:response_middleware) do
|
104
|
-
Class.new do
|
105
|
-
def response(resp)
|
106
|
-
resp.response = 'bar'
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
it "should work with response middleware" do
|
112
|
-
stub_request(:get, "www.example.com").to_return(body: 'foo')
|
113
|
-
|
114
|
-
EM.run do
|
115
|
-
conn = EventMachine::HttpRequest.new('http://www.example.com/')
|
116
|
-
|
117
|
-
conn.use response_middleware
|
118
|
-
|
119
|
-
http = conn.get
|
120
|
-
|
121
|
-
http.callback do
|
122
|
-
expect(http.response).to eq('bar')
|
123
|
-
EM.stop
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
let(:webmock_server_url) { "http://#{WebMockServer.instance.host_with_port}/" }
|
129
|
-
|
130
|
-
shared_examples_for "em-http-request middleware/after_request hook integration" do
|
131
|
-
it 'yields the original raw body to the after_request hook even if a response middleware modifies the body' do
|
132
|
-
yielded_response_body = nil
|
133
|
-
::WebMock.after_request do |request, response|
|
134
|
-
yielded_response_body = response.body
|
135
|
-
end
|
136
|
-
|
137
|
-
EM::HttpRequest.use response_middleware
|
138
|
-
|
139
|
-
EM.run do
|
140
|
-
http = EventMachine::HttpRequest.new(webmock_server_url).get
|
141
|
-
http.callback { EM.stop }
|
142
|
-
end
|
143
|
-
|
144
|
-
expect(yielded_response_body).to eq("hello world")
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
context 'making a real request', net_connect: true do
|
149
|
-
before { WebMock.allow_net_connect! }
|
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
|
178
|
-
end
|
179
|
-
|
180
|
-
context 'when the request is stubbed' do
|
181
|
-
before { stub_request(:get, webmock_server_url).to_return(body: 'hello world') }
|
182
|
-
include_examples "em-http-request middleware/after_request hook integration"
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
it 'should trigger error callbacks asynchronously' do
|
187
|
-
stub_request(:get, 'www.example.com').to_timeout
|
188
|
-
called = false
|
189
|
-
|
190
|
-
EM.run do
|
191
|
-
conn = EventMachine::HttpRequest.new('http://www.example.com/')
|
192
|
-
http = conn.get
|
193
|
-
http.errback do
|
194
|
-
called = true
|
195
|
-
EM.stop
|
196
|
-
end
|
197
|
-
expect(called).to eq(false)
|
198
|
-
end
|
199
|
-
|
200
|
-
expect(called).to eq(true)
|
201
|
-
end
|
202
|
-
|
203
|
-
# not pretty, but it works
|
204
|
-
if defined?(EventMachine::Synchrony)
|
205
|
-
describe "with synchrony" do
|
206
|
-
let(:webmock_em_http) { File.expand_path(File.join(File.dirname(__FILE__), "../lib/webmock/http_lib_adapters/em_http_request/em_http_request_1_x.rb")) }
|
207
|
-
|
208
|
-
before(:each) do
|
209
|
-
# need to reload the webmock em-http adapter after we require synchrony
|
210
|
-
WebMock::HttpLibAdapters::EmHttpRequestAdapter.disable!
|
211
|
-
$".delete webmock_em_http
|
212
|
-
$".delete File.expand_path(File.join(File.dirname(__FILE__), "../../../lib/webmock/http_lib_adapters/em_http_request_adapter.rb"))
|
213
|
-
require 'em-synchrony'
|
214
|
-
require 'em-synchrony/em-http'
|
215
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "../../../lib/webmock/http_lib_adapters/em_http_request_adapter.rb"))
|
216
|
-
end
|
217
|
-
|
218
|
-
it "should work" do
|
219
|
-
stub_request(:post, /.*.testserver.com*/).to_return(status: 200, body: 'ok')
|
220
|
-
expect {
|
221
|
-
EM.run do
|
222
|
-
fiber = Fiber.new do
|
223
|
-
EM::HttpRequest.new("http://www.testserver.com").post body: "foo=bar&baz=bang", timeout: 60
|
224
|
-
EM.stop
|
225
|
-
end
|
226
|
-
fiber.resume
|
227
|
-
end
|
228
|
-
}.not_to raise_error
|
229
|
-
end
|
230
|
-
|
231
|
-
after(:each) do
|
232
|
-
EM.send(:remove_const, :Synchrony)
|
233
|
-
EM.send(:remove_const, :HTTPMethods)
|
234
|
-
WebMock::HttpLibAdapters::EmHttpRequestAdapter.disable!
|
235
|
-
$".reject! {|path| path.include? "em-http-request"}
|
236
|
-
$".delete webmock_em_http
|
237
|
-
$".delete File.expand_path(File.join(File.dirname(__FILE__), "../../../lib/webmock/http_lib_adapters/em_http_request_adapter.rb"))
|
238
|
-
require 'em-http-request'
|
239
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "../../../lib/webmock/http_lib_adapters/em_http_request_adapter.rb"))
|
240
|
-
end
|
241
|
-
end
|
242
|
-
end
|
243
|
-
end
|
244
|
-
|
245
|
-
it "should work with streaming" do
|
246
|
-
stub_request(:get, "www.example.com").to_return(body: "abc")
|
247
|
-
response = ""
|
248
|
-
EM.run {
|
249
|
-
http = EventMachine::HttpRequest.new('http://www.example.com/').get
|
250
|
-
http.stream { |chunk| response = chunk; EM.stop }
|
251
|
-
}
|
252
|
-
expect(response).to eq("abc")
|
253
|
-
end
|
254
|
-
|
255
|
-
it "should work with responses that use chunked transfer encoding" do
|
256
|
-
stub_request(:get, "www.example.com").to_return(body: "abc", headers: { 'Transfer-Encoding' => 'chunked' })
|
257
|
-
expect(http_request(:get, "http://www.example.com").body).to eq("abc")
|
258
|
-
end
|
259
|
-
|
260
|
-
it "should work with optional query params" do
|
261
|
-
stub_request(:get, "www.example.com/?x=3&a[]=b&a[]=c").to_return(body: "abc")
|
262
|
-
expect(http_request(:get, "http://www.example.com/?x=3", query: {"a" => ["b", "c"]}).body).to eq("abc")
|
263
|
-
end
|
264
|
-
|
265
|
-
it "should work with optional query params declared as string" do
|
266
|
-
stub_request(:get, "www.example.com/?x=3&a[]=b&a[]=c").to_return(body: "abc")
|
267
|
-
expect(http_request(:get, "http://www.example.com/?x=3", query: "a[]=b&a[]=c").body).to eq("abc")
|
268
|
-
end
|
269
|
-
|
270
|
-
it "should work when the body is passed as a Hash" do
|
271
|
-
stub_request(:post, "www.example.com").with(body: {a: "1", b: "2"}).to_return(body: "ok")
|
272
|
-
expect(http_request(:post, "http://www.example.com", body: {a: "1", b: "2"}).body).to eq("ok")
|
273
|
-
end
|
274
|
-
|
275
|
-
if defined?(EventMachine::HttpConnection)
|
276
|
-
it "should work when a file is passed as body" do
|
277
|
-
stub_request(:post, "www.example.com").with(body: File.read(__FILE__)).to_return(body: "ok")
|
278
|
-
expect(http_request(:post, "http://www.example.com", file: __FILE__).body).to eq("ok")
|
279
|
-
end
|
280
|
-
end
|
281
|
-
|
282
|
-
it "should work with UTF-8 strings" do
|
283
|
-
body = "Привет, Мир!"
|
284
|
-
stub_request(:post, "www.example.com").to_return(body: body)
|
285
|
-
expect(http_request(:post, "http://www.example.com").body.bytesize).to eq(body.bytesize)
|
286
|
-
end
|
287
|
-
|
288
|
-
it "should work with multiple requests to the same connection" do
|
289
|
-
stub_request(:get, "www.example.com/foo").to_return(body: "bar")
|
290
|
-
stub_request(:get, "www.example.com/baz").to_return(body: "wombat")
|
291
|
-
err1 = nil
|
292
|
-
err2 = nil
|
293
|
-
body1 = nil
|
294
|
-
body2 = nil
|
295
|
-
i = 0
|
296
|
-
|
297
|
-
EM.run do
|
298
|
-
conn = EM::HttpRequest.new("http://www.example.com")
|
299
|
-
conn.get(path: "/foo").callback do |resp|
|
300
|
-
body1 = resp.response
|
301
|
-
i += 1; EM.stop if i == 2
|
302
|
-
end.errback do |resp|
|
303
|
-
err1 = resp.error
|
304
|
-
i += 1; EM.stop if i == 2
|
305
|
-
end
|
306
|
-
|
307
|
-
conn.get(path: "/baz").callback do |resp|
|
308
|
-
body2 = resp.response
|
309
|
-
i += 1; EM.stop if i == 2
|
310
|
-
end.errback do |resp|
|
311
|
-
err2 = resp.error
|
312
|
-
i += 1; EM.stop if i == 2
|
313
|
-
end
|
314
|
-
end
|
315
|
-
|
316
|
-
expect(err1).to be(nil)
|
317
|
-
expect(err2).to be(nil)
|
318
|
-
expect(body1).to eq("bar")
|
319
|
-
expect(body2).to eq("wombat")
|
320
|
-
end
|
321
|
-
|
322
|
-
it "should work with multiple requests to the same connection when the first request times out" do
|
323
|
-
stub_request(:get, "www.example.com/foo").to_timeout.then.to_return(status: 200, body: "wombat")
|
324
|
-
err = nil
|
325
|
-
body = nil
|
326
|
-
|
327
|
-
EM.run do
|
328
|
-
conn = EM::HttpRequest.new("http://www.example.com")
|
329
|
-
conn.get(path: "/foo").callback do |resp|
|
330
|
-
err = :success_from_timeout
|
331
|
-
EM.stop
|
332
|
-
end.errback do |resp|
|
333
|
-
conn.get(path: "/foo").callback do |retry_resp|
|
334
|
-
expect(retry_resp.response_header.status).to eq(200)
|
335
|
-
body = retry_resp.response
|
336
|
-
EM.stop
|
337
|
-
end.errback do |retry_resp|
|
338
|
-
err = retry_resp.error
|
339
|
-
EM.stop
|
340
|
-
end
|
341
|
-
end
|
342
|
-
end
|
343
|
-
|
344
|
-
expect(err).to be(nil)
|
345
|
-
expect(body).to eq("wombat")
|
346
|
-
end
|
347
|
-
|
348
|
-
describe "mocking EM::HttpClient API" do
|
349
|
-
let(:uri) { "http://www.example.com/" }
|
350
|
-
|
351
|
-
before do
|
352
|
-
stub_request(:get, uri)
|
353
|
-
WebMock::HttpLibAdapters::EmHttpRequestAdapter.enable!
|
354
|
-
end
|
355
|
-
|
356
|
-
def client(uri, options = {})
|
357
|
-
client = nil
|
358
|
-
EM.run do
|
359
|
-
client = EventMachine::HttpRequest.new(uri).get(options)
|
360
|
-
client.callback { EM.stop }
|
361
|
-
client.errback { failed }
|
362
|
-
end
|
363
|
-
client
|
364
|
-
end
|
365
|
-
|
366
|
-
subject { client(uri) }
|
367
|
-
|
368
|
-
it 'should support #uri' do
|
369
|
-
expect(subject.uri).to eq(Addressable::URI.parse(uri))
|
370
|
-
end
|
371
|
-
|
372
|
-
it 'should support #last_effective_url' do
|
373
|
-
expect(subject.last_effective_url).to eq(Addressable::URI.parse(uri))
|
374
|
-
end
|
375
|
-
|
376
|
-
context "with a query" do
|
377
|
-
let(:uri) { "http://www.example.com/?a=1&b=2" }
|
378
|
-
subject { client("http://www.example.com/?a=1", query: { 'b' => 2 }) }
|
379
|
-
|
380
|
-
it "#request_signature doesn't mutate the original uri" do
|
381
|
-
expect(subject.uri).to eq(Addressable::URI.parse("http://www.example.com/?a=1"))
|
382
|
-
signature = WebMock::RequestRegistry.instance.requested_signatures.hash.keys.first
|
383
|
-
expect(signature.uri).to eq(Addressable::URI.parse(uri))
|
384
|
-
end
|
385
|
-
end
|
386
|
-
|
387
|
-
describe 'get_response_cookie' do
|
388
|
-
|
389
|
-
before(:each) do
|
390
|
-
stub_request(:get, "http://example.org/").
|
391
|
-
to_return(
|
392
|
-
status: 200,
|
393
|
-
body: "",
|
394
|
-
headers: { 'Set-Cookie' => cookie_string }
|
395
|
-
)
|
396
|
-
end
|
397
|
-
|
398
|
-
describe 'success' do
|
399
|
-
|
400
|
-
context 'with only one cookie' do
|
401
|
-
|
402
|
-
let(:cookie_name) { 'name_of_the_cookie' }
|
403
|
-
let(:cookie_value) { 'value_of_the_cookie' }
|
404
|
-
let(:cookie_string) { "#{cookie_name}=#{cookie_value}" }
|
405
|
-
|
406
|
-
it 'successfully gets the cookie' do
|
407
|
-
EM.run {
|
408
|
-
http = EventMachine::HttpRequest.new('http://example.org').get
|
409
|
-
|
410
|
-
http.errback { fail(http.error) }
|
411
|
-
http.callback {
|
412
|
-
expect(http.get_response_cookie(cookie_name)).to eq(cookie_value)
|
413
|
-
EM.stop
|
414
|
-
}
|
415
|
-
}
|
416
|
-
end
|
417
|
-
end
|
418
|
-
|
419
|
-
context 'with several cookies' do
|
420
|
-
|
421
|
-
let(:cookie_name) { 'name_of_the_cookie' }
|
422
|
-
let(:cookie_value) { 'value_of_the_cookie' }
|
423
|
-
let(:cookie_2_name) { 'name_of_the_2nd_cookie' }
|
424
|
-
let(:cookie_2_value) { 'value_of_the_2nd_cookie' }
|
425
|
-
let(:cookie_string) { %W(#{cookie_name}=#{cookie_value} #{cookie_2_name}=#{cookie_2_value}) }
|
426
|
-
|
427
|
-
it 'successfully gets both cookies' do
|
428
|
-
EM.run {
|
429
|
-
http = EventMachine::HttpRequest.new('http://example.org').get
|
430
|
-
|
431
|
-
http.errback { fail(http.error) }
|
432
|
-
http.callback {
|
433
|
-
expect(http.get_response_cookie(cookie_name)).to eq(cookie_value)
|
434
|
-
expect(http.get_response_cookie(cookie_2_name)).to eq(cookie_2_value)
|
435
|
-
EM.stop
|
436
|
-
}
|
437
|
-
}
|
438
|
-
end
|
439
|
-
end
|
440
|
-
end
|
441
|
-
|
442
|
-
describe 'failure' do
|
443
|
-
|
444
|
-
let(:cookie_string) { 'a=b' }
|
445
|
-
|
446
|
-
it 'returns nil when no cookie is found' do
|
447
|
-
EM.run {
|
448
|
-
http = EventMachine::HttpRequest.new('http://example.org').get
|
449
|
-
|
450
|
-
http.errback { fail(http.error) }
|
451
|
-
http.callback {
|
452
|
-
expect(http.get_response_cookie('not_found_cookie')).to eq(nil)
|
453
|
-
EM.stop
|
454
|
-
}
|
455
|
-
}
|
456
|
-
end
|
457
|
-
end
|
458
|
-
end
|
459
|
-
end
|
460
|
-
|
461
|
-
end
|
462
|
-
end
|
@@ -1,77 +0,0 @@
|
|
1
|
-
module EMHttpRequestSpecHelper
|
2
|
-
|
3
|
-
def failed
|
4
|
-
EventMachine.stop
|
5
|
-
fail
|
6
|
-
end
|
7
|
-
|
8
|
-
def http_request(method, uri, options = {}, &block)
|
9
|
-
@http = nil
|
10
|
-
head = options[:headers] || {}
|
11
|
-
if options[:basic_auth]
|
12
|
-
head.merge!('authorization' => options[:basic_auth])
|
13
|
-
end
|
14
|
-
response = nil
|
15
|
-
error = nil
|
16
|
-
error_set = false
|
17
|
-
uri = Addressable::URI.heuristic_parse(uri)
|
18
|
-
EventMachine.run {
|
19
|
-
request = EventMachine::HttpRequest.new("#{uri.normalize.to_s}")
|
20
|
-
http = request.send(method, {
|
21
|
-
timeout: 30,
|
22
|
-
body: options[:body],
|
23
|
-
file: options[:file],
|
24
|
-
query: options[:query],
|
25
|
-
head: head,
|
26
|
-
compressed: false
|
27
|
-
}, &block)
|
28
|
-
http.errback {
|
29
|
-
error_set = true
|
30
|
-
error = if http.respond_to?(:errors)
|
31
|
-
http.errors
|
32
|
-
else
|
33
|
-
http.error
|
34
|
-
end
|
35
|
-
failed
|
36
|
-
}
|
37
|
-
http.callback {
|
38
|
-
response = OpenStruct.new({
|
39
|
-
body: http.response,
|
40
|
-
headers: WebMock::Util::Headers.normalize_headers(extract_response_headers(http)),
|
41
|
-
message: http.response_header.http_reason,
|
42
|
-
status: http.response_header.status.to_s
|
43
|
-
})
|
44
|
-
EventMachine.stop
|
45
|
-
}
|
46
|
-
@http = http
|
47
|
-
}
|
48
|
-
raise error.to_s if error_set
|
49
|
-
response
|
50
|
-
end
|
51
|
-
|
52
|
-
def client_timeout_exception_class
|
53
|
-
'Errno::ETIMEDOUT'
|
54
|
-
end
|
55
|
-
|
56
|
-
def connection_refused_exception_class
|
57
|
-
RuntimeError
|
58
|
-
end
|
59
|
-
|
60
|
-
def http_library
|
61
|
-
:em_http_request
|
62
|
-
end
|
63
|
-
|
64
|
-
private
|
65
|
-
|
66
|
-
def extract_response_headers(http)
|
67
|
-
headers = {}
|
68
|
-
if http.response_header
|
69
|
-
http.response_header.each do |k,v|
|
70
|
-
v = v.join(", ") if v.is_a?(Array)
|
71
|
-
headers[k] = v
|
72
|
-
end
|
73
|
-
end
|
74
|
-
headers
|
75
|
-
end
|
76
|
-
|
77
|
-
end
|
@@ -1,77 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'acceptance/webmock_shared'
|
3
|
-
require 'acceptance/excon/excon_spec_helper'
|
4
|
-
|
5
|
-
describe "Excon" do
|
6
|
-
include ExconSpecHelper
|
7
|
-
include_context "with WebMock", :no_url_auth
|
8
|
-
|
9
|
-
it 'should allow Excon requests to use query hash paramters' do
|
10
|
-
stub_request(:get, "http://example.com/resource/?a=1&b=2").to_return(body: "abc")
|
11
|
-
expect(Excon.new('http://example.com').get(path: "resource/", query: {a: 1, b: 2}).body).to eq("abc")
|
12
|
-
end
|
13
|
-
|
14
|
-
it 'should support Excon :expects options' do
|
15
|
-
stub_request(:get, "http://example.com/").to_return(body: 'a')
|
16
|
-
expect { Excon.new('http://example.com').get(expects: 204) }.to raise_error(Excon::Errors::OK)
|
17
|
-
end
|
18
|
-
|
19
|
-
context "with response_block" do
|
20
|
-
it "should support excon response_block for real requests", net_connect: true do
|
21
|
-
a = []
|
22
|
-
WebMock.allow_net_connect!
|
23
|
-
r = Excon.new('http://httpstat.us/200', headers: { "Accept" => "*" }).
|
24
|
-
get(response_block: lambda {|e, remaining, total| a << e}, chunk_size: 1)
|
25
|
-
expect(a).to eq(["2", "0", "0", " ", "O", "K"])
|
26
|
-
expect(r.body).to eq("")
|
27
|
-
end
|
28
|
-
|
29
|
-
it "should support excon response_block" do
|
30
|
-
a = []
|
31
|
-
stub_request(:get, "http://example.com/").to_return(body: "abc")
|
32
|
-
r = Excon.new('http://example.com').get(response_block: lambda {|e, remaining, total| a << e}, chunk_size: 1)
|
33
|
-
expect(a).to eq(['a', 'b', 'c'])
|
34
|
-
expect(r.body).to eq("")
|
35
|
-
end
|
36
|
-
|
37
|
-
it "should invoke callbacks with response body even if a real request is made", net_connect: true do
|
38
|
-
a = []
|
39
|
-
WebMock.allow_net_connect!
|
40
|
-
response = nil
|
41
|
-
WebMock.after_request { |_, res|
|
42
|
-
response = res
|
43
|
-
}
|
44
|
-
r = Excon.new('http://httpstat.us/200', headers: { "Accept" => "*" }).
|
45
|
-
get(response_block: lambda {|e, remaining, total| a << e}, chunk_size: 1)
|
46
|
-
expect(response.body).to eq("200 OK")
|
47
|
-
expect(a).to eq(["2", "0", "0", " ", "O", "K"])
|
48
|
-
expect(r.body).to eq("")
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
let(:file) { File.new(__FILE__) }
|
53
|
-
let(:file_contents) { File.read(__FILE__) }
|
54
|
-
|
55
|
-
it 'handles file uploads correctly' do
|
56
|
-
stub_request(:put, "http://example.com/upload").with(body: file_contents)
|
57
|
-
|
58
|
-
yielded_request_body = nil
|
59
|
-
WebMock.after_request do |req, res|
|
60
|
-
yielded_request_body = req.body
|
61
|
-
end
|
62
|
-
|
63
|
-
Excon.new("http://example.com").put(path: "upload", body: file)
|
64
|
-
|
65
|
-
expect(yielded_request_body).to eq(file_contents)
|
66
|
-
end
|
67
|
-
|
68
|
-
describe '.request_params_from' do
|
69
|
-
|
70
|
-
it 'rejects invalid request keys' do
|
71
|
-
request_params = WebMock::HttpLibAdapters::ExconAdapter.request_params_from(body: :keep, fake: :reject)
|
72
|
-
expect(request_params).to eq(body: :keep)
|
73
|
-
end
|
74
|
-
|
75
|
-
end
|
76
|
-
|
77
|
-
end
|
@@ -1,52 +0,0 @@
|
|
1
|
-
require 'ostruct'
|
2
|
-
|
3
|
-
module ExconSpecHelper
|
4
|
-
|
5
|
-
def http_request(method, uri, options = {}, &block)
|
6
|
-
Excon.defaults[:ssl_verify_peer] = false
|
7
|
-
Excon.defaults[:ciphers] = 'DEFAULT'
|
8
|
-
uri = Addressable::URI.heuristic_parse(uri)
|
9
|
-
uri = uri.to_s.gsub(' ', '%20')
|
10
|
-
|
11
|
-
excon_options = {}
|
12
|
-
|
13
|
-
if basic_auth = options.delete(:basic_auth)
|
14
|
-
excon_options = {user: basic_auth[0], password: basic_auth[1]}
|
15
|
-
end
|
16
|
-
|
17
|
-
if Gem::Version.new(Excon::VERSION) < Gem::Version.new("0.29.0")
|
18
|
-
options = options.merge(method: method, nonblock: false) # Dup and merge
|
19
|
-
response = Excon.new(uri, excon_options).request(options, &block)
|
20
|
-
else
|
21
|
-
options = options.merge(method: method) # Dup and merge
|
22
|
-
response = Excon.new(uri, excon_options.merge(nonblock: false)).request(options, &block)
|
23
|
-
end
|
24
|
-
|
25
|
-
headers = WebMock::Util::Headers.normalize_headers(response.headers)
|
26
|
-
headers = headers.inject({}) do |res, (name, value)|
|
27
|
-
res[name] = value.is_a?(Array) ? value.flatten.join(', ') : value
|
28
|
-
res
|
29
|
-
end
|
30
|
-
|
31
|
-
Excon.set_raise_on_warnings!(true)
|
32
|
-
|
33
|
-
OpenStruct.new \
|
34
|
-
body: response.body,
|
35
|
-
headers: headers,
|
36
|
-
status: response.status.to_s,
|
37
|
-
message: response.reason_phrase
|
38
|
-
end
|
39
|
-
|
40
|
-
def client_timeout_exception_class
|
41
|
-
Excon::Errors::Timeout
|
42
|
-
end
|
43
|
-
|
44
|
-
def connection_refused_exception_class
|
45
|
-
Excon::Errors::SocketError
|
46
|
-
end
|
47
|
-
|
48
|
-
def http_library
|
49
|
-
:excon
|
50
|
-
end
|
51
|
-
|
52
|
-
end
|