webmock 3.0.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 +5 -5
- data/.github/workflows/CI.yml +38 -0
- data/CHANGELOG.md +496 -2
- data/Gemfile +1 -1
- data/README.md +169 -34
- data/Rakefile +12 -4
- data/lib/webmock/api.rb +12 -0
- data/lib/webmock/http_lib_adapters/async_http_client_adapter.rb +221 -0
- data/lib/webmock/http_lib_adapters/curb_adapter.rb +19 -5
- data/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +7 -4
- data/lib/webmock/http_lib_adapters/excon_adapter.rb +5 -2
- data/lib/webmock/http_lib_adapters/http_rb/client.rb +2 -1
- data/lib/webmock/http_lib_adapters/http_rb/request.rb +7 -1
- data/lib/webmock/http_lib_adapters/http_rb/response.rb +27 -3
- data/lib/webmock/http_lib_adapters/http_rb/streamer.rb +9 -3
- data/lib/webmock/http_lib_adapters/http_rb/webmock.rb +7 -3
- data/lib/webmock/http_lib_adapters/httpclient_adapter.rb +28 -9
- data/lib/webmock/http_lib_adapters/manticore_adapter.rb +33 -15
- data/lib/webmock/http_lib_adapters/net_http.rb +36 -89
- data/lib/webmock/http_lib_adapters/net_http_response.rb +1 -1
- data/lib/webmock/http_lib_adapters/patron_adapter.rb +4 -4
- 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 -23
- data/lib/webmock/rack_response.rb +1 -1
- data/lib/webmock/request_body_diff.rb +1 -1
- data/lib/webmock/request_execution_verifier.rb +2 -3
- data/lib/webmock/request_pattern.rb +129 -51
- data/lib/webmock/request_registry.rb +1 -1
- data/lib/webmock/request_signature.rb +3 -3
- data/lib/webmock/request_signature_snippet.rb +4 -4
- data/lib/webmock/request_stub.rb +15 -0
- data/lib/webmock/response.rb +19 -13
- data/lib/webmock/rspec.rb +10 -3
- data/lib/webmock/stub_registry.rb +26 -11
- data/lib/webmock/stub_request_snippet.rb +10 -6
- data/lib/webmock/test_unit.rb +1 -3
- data/lib/webmock/util/hash_counter.rb +3 -3
- data/lib/webmock/util/headers.rb +17 -2
- data/lib/webmock/util/json.rb +1 -2
- data/lib/webmock/util/query_mapper.rb +9 -7
- data/lib/webmock/util/uri.rb +10 -10
- data/lib/webmock/util/values_stringifier.rb +20 -0
- data/lib/webmock/version.rb +1 -1
- data/lib/webmock/webmock.rb +20 -3
- data/lib/webmock.rb +53 -48
- data/minitest/webmock_spec.rb +3 -3
- 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 +44 -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 +2 -2
- data/spec/acceptance/excon/excon_spec.rb +4 -2
- data/spec/acceptance/excon/excon_spec_helper.rb +2 -0
- data/spec/acceptance/http_rb/http_rb_spec.rb +20 -0
- data/spec/acceptance/http_rb/http_rb_spec_helper.rb +5 -2
- data/spec/acceptance/httpclient/httpclient_spec.rb +8 -1
- data/spec/acceptance/manticore/manticore_spec.rb +51 -0
- data/spec/acceptance/net_http/net_http_shared.rb +47 -10
- data/spec/acceptance/net_http/net_http_spec.rb +102 -24
- data/spec/acceptance/net_http/real_net_http_spec.rb +1 -1
- data/spec/acceptance/patron/patron_spec.rb +26 -21
- data/spec/acceptance/patron/patron_spec_helper.rb +3 -3
- data/spec/acceptance/shared/allowing_and_disabling_net_connect.rb +14 -14
- data/spec/acceptance/shared/callbacks.rb +3 -2
- data/spec/acceptance/shared/complex_cross_concern_behaviors.rb +1 -1
- data/spec/acceptance/shared/request_expectations.rb +14 -0
- data/spec/acceptance/shared/returning_declared_responses.rb +36 -15
- data/spec/acceptance/shared/stubbing_requests.rb +95 -0
- data/spec/acceptance/typhoeus/typhoeus_hydra_spec.rb +1 -1
- data/spec/acceptance/typhoeus/typhoeus_hydra_spec_helper.rb +1 -1
- data/spec/support/webmock_server.rb +1 -0
- data/spec/unit/api_spec.rb +103 -3
- data/spec/unit/matchers/hash_excluding_matcher_spec.rb +61 -0
- data/spec/unit/request_execution_verifier_spec.rb +12 -12
- data/spec/unit/request_pattern_spec.rb +207 -49
- data/spec/unit/request_signature_snippet_spec.rb +2 -2
- 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/stub_request_snippet_spec.rb +30 -10
- data/spec/unit/util/query_mapper_spec.rb +13 -0
- data/spec/unit/util/uri_spec.rb +74 -2
- data/spec/unit/webmock_spec.rb +108 -5
- data/test/shared_test.rb +15 -2
- data/test/test_webmock.rb +6 -0
- data/webmock.gemspec +15 -7
- metadata +86 -37
- data/.travis.yml +0 -20
|
@@ -58,7 +58,7 @@ describe WebMock::RequestPattern do
|
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
it "should raise an error if neither options or block is provided" do
|
|
61
|
-
expect { @request_pattern.with() }.to raise_error('#with method invoked with no arguments. Either options hash or block must be specified.')
|
|
61
|
+
expect { @request_pattern.with() }.to raise_error('#with method invoked with no arguments. Either options hash or block must be specified. Created a block with do..end? Try creating it with curly braces {} instead.')
|
|
62
62
|
end
|
|
63
63
|
end
|
|
64
64
|
|
|
@@ -111,6 +111,21 @@ describe WebMock::RequestPattern do
|
|
|
111
111
|
to match(WebMock::RequestSignature.new(:get, "www.example.com"))
|
|
112
112
|
end
|
|
113
113
|
|
|
114
|
+
it "should match if uri matches requesst uri as URI object" do
|
|
115
|
+
expect(WebMock::RequestPattern.new(:get, URI.parse("www.example.com"))).
|
|
116
|
+
to match(WebMock::RequestSignature.new(:get, "www.example.com"))
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it "should match if uri proc pattern returning true" do
|
|
120
|
+
expect(WebMock::RequestPattern.new(:get, ->(uri) { true })).
|
|
121
|
+
to match(WebMock::RequestSignature.new(:get, "www.example.com"))
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it "should not match if uri proc pattern returns false" do
|
|
125
|
+
expect(WebMock::RequestPattern.new(:get, ->(uri) { false })).
|
|
126
|
+
not_to match(WebMock::RequestSignature.new(:get, "www.example.com"))
|
|
127
|
+
end
|
|
128
|
+
|
|
114
129
|
it "should match if uri Addressable::Template pattern matches unescaped form of request uri" do
|
|
115
130
|
expect(WebMock::RequestPattern.new(:get, Addressable::Template.new("www.example.com/{any_path}"))).
|
|
116
131
|
to match(WebMock::RequestSignature.new(:get, "www.example.com/my%20path"))
|
|
@@ -121,6 +136,41 @@ describe WebMock::RequestPattern do
|
|
|
121
136
|
to match(WebMock::RequestSignature.new(:get, "www.example.com"))
|
|
122
137
|
end
|
|
123
138
|
|
|
139
|
+
it "should match if uri Addressable::Template pattern matches request uri without TLD" do
|
|
140
|
+
expect(WebMock::RequestPattern.new(:get, Addressable::Template.new("localhost"))).
|
|
141
|
+
to match(WebMock::RequestSignature.new(:get, "localhost"))
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it "should match if Addressable::Template pattern that has ip address host matches request uri" do
|
|
145
|
+
signature = WebMock::RequestSignature.new(:get, "127.0.0.1:3000/1234")
|
|
146
|
+
uri = Addressable::Template.new("127.0.0.1:3000/{id}")
|
|
147
|
+
expect(WebMock::RequestPattern.new(:get, uri)).to match(signature)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
it "should match if Addressable::Template pattern that has ip address host without port matches request uri" do
|
|
151
|
+
signature = WebMock::RequestSignature.new(:get, "127.0.0.1/1234")
|
|
152
|
+
uri = Addressable::Template.new("127.0.0.1/{id}")
|
|
153
|
+
expect(WebMock::RequestPattern.new(:get, uri)).to match(signature)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
it "should match if Addressable::Template pattern host matches request uri" do
|
|
157
|
+
signature = WebMock::RequestSignature.new(:get, "www.example.com")
|
|
158
|
+
uri = Addressable::Template.new("{subdomain}.example.com")
|
|
159
|
+
expect(WebMock::RequestPattern.new(:get, uri)).to match(signature)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
it "should not match if Addressable::Template pattern host does not match request uri" do
|
|
163
|
+
signature = WebMock::RequestSignature.new(:get, "www.bad-example.com")
|
|
164
|
+
uri = Addressable::Template.new("{subdomain}.example.com")
|
|
165
|
+
expect(WebMock::RequestPattern.new(:get, uri)).not_to match(signature)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
it "should match if uri Addressable::Template pattern matches request uri without a schema and a path " do
|
|
169
|
+
signature = WebMock::RequestSignature.new(:get, "127.0.0.1:3000")
|
|
170
|
+
uri = Addressable::Template.new("127.0.0.1:3000")
|
|
171
|
+
expect(WebMock::RequestPattern.new(:get, uri)).to match(signature)
|
|
172
|
+
end
|
|
173
|
+
|
|
124
174
|
it "should match for uris with same parameters as pattern" do
|
|
125
175
|
expect(WebMock::RequestPattern.new(:get, "www.example.com?a=1&b=2")).
|
|
126
176
|
to match(WebMock::RequestSignature.new(:get, "www.example.com?a=1&b=2"))
|
|
@@ -188,7 +238,7 @@ describe WebMock::RequestPattern do
|
|
|
188
238
|
to match(WebMock::RequestSignature.new(:get, "www.example.com?a[]=b&a[]=c"))
|
|
189
239
|
end
|
|
190
240
|
|
|
191
|
-
it "should match request query params if params don't match" do
|
|
241
|
+
it "should not match request query params if params don't match" do
|
|
192
242
|
expect(WebMock::RequestPattern.new(:get, /.*example.*/, query: {"x" => ["b", "c"]})).
|
|
193
243
|
not_to match(WebMock::RequestSignature.new(:get, "www.example.com?a[]=b&a[]=c"))
|
|
194
244
|
end
|
|
@@ -218,13 +268,85 @@ describe WebMock::RequestPattern do
|
|
|
218
268
|
end
|
|
219
269
|
end
|
|
220
270
|
|
|
271
|
+
describe "when uri is described as URI" do
|
|
272
|
+
it "should match request query params" do
|
|
273
|
+
expect(WebMock::RequestPattern.new(:get, URI.parse("www.example.com"), query: {"a" => ["b", "c"]})).
|
|
274
|
+
to match(WebMock::RequestSignature.new(:get, "www.example.com?a[]=b&a[]=c"))
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
it "should not match request query params if params don't match" do
|
|
278
|
+
expect(WebMock::RequestPattern.new(:get, URI.parse("www.example.com"), query: {"x" => ["b", "c"]})).
|
|
279
|
+
not_to match(WebMock::RequestSignature.new(:get, "www.example.com?a[]=b&a[]=c"))
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
it "should match when query params are declared as HashIncluding matcher matching params" do
|
|
283
|
+
expect(WebMock::RequestPattern.new(:get, URI.parse("www.example.com"),
|
|
284
|
+
query: WebMock::Matchers::HashIncludingMatcher.new({"a" => ["b", "c"]}))).
|
|
285
|
+
to match(WebMock::RequestSignature.new(:get, "www.example.com?a[]=b&a[]=c&b=1"))
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
it "should not match when query params are declared as HashIncluding matcher not matching params" do
|
|
289
|
+
expect(WebMock::RequestPattern.new(:get, URI.parse("www.example.com"),
|
|
290
|
+
query: WebMock::Matchers::HashIncludingMatcher.new({"x" => ["b", "c"]}))).
|
|
291
|
+
not_to match(WebMock::RequestSignature.new(:get, "www.example.com?a[]=b&a[]=c&b=1"))
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
it "should match when query params are declared as RSpec HashIncluding matcher matching params" do
|
|
295
|
+
expect(WebMock::RequestPattern.new(:get, URI.parse("www.example.com"),
|
|
296
|
+
query: RSpec::Mocks::ArgumentMatchers::HashIncludingMatcher.new({"a" => ["b", "c"]}))).
|
|
297
|
+
to match(WebMock::RequestSignature.new(:get, "www.example.com?a[]=b&a[]=c&b=1"))
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
it "should not match when query params are declared as RSpec HashIncluding matcher not matching params" do
|
|
301
|
+
expect(WebMock::RequestPattern.new(:get, URI.parse("www.example.com"),
|
|
302
|
+
query: RSpec::Mocks::ArgumentMatchers::HashIncludingMatcher.new({"a" => ["b", "d"]}))).
|
|
303
|
+
not_to match(WebMock::RequestSignature.new(:get, "www.example.com?a[]=b&a[]=c&b=1"))
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
describe "when uri is described as a proc" do
|
|
308
|
+
it "should match request query params" do
|
|
309
|
+
expect(WebMock::RequestPattern.new(:get, ->(uri) { true }, query: {"a" => ["b", "c"]})).
|
|
310
|
+
to match(WebMock::RequestSignature.new(:get, "www.example.com?a[]=b&a[]=c"))
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
it "should not match request query params if params don't match" do
|
|
314
|
+
expect(WebMock::RequestPattern.new(:get, ->(uri) { true }, query: {"x" => ["b", "c"]})).
|
|
315
|
+
not_to match(WebMock::RequestSignature.new(:get, "www.example.com?a[]=b&a[]=c"))
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
it "should match when query params are declared as HashIncluding matcher matching params" do
|
|
319
|
+
expect(WebMock::RequestPattern.new(:get, ->(uri) { true },
|
|
320
|
+
query: WebMock::Matchers::HashIncludingMatcher.new({"a" => ["b", "c"]}))).
|
|
321
|
+
to match(WebMock::RequestSignature.new(:get, "www.example.com?a[]=b&a[]=c&b=1"))
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
it "should not match when query params are declared as HashIncluding matcher not matching params" do
|
|
325
|
+
expect(WebMock::RequestPattern.new(:get, ->(uri) { true },
|
|
326
|
+
query: WebMock::Matchers::HashIncludingMatcher.new({"x" => ["b", "c"]}))).
|
|
327
|
+
not_to match(WebMock::RequestSignature.new(:get, "www.example.com?a[]=b&a[]=c&b=1"))
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
it "should match when query params are declared as RSpec HashIncluding matcher matching params" do
|
|
331
|
+
expect(WebMock::RequestPattern.new(:get, ->(uri) { true },
|
|
332
|
+
query: RSpec::Mocks::ArgumentMatchers::HashIncludingMatcher.new({"a" => ["b", "c"]}))).
|
|
333
|
+
to match(WebMock::RequestSignature.new(:get, "www.example.com?a[]=b&a[]=c&b=1"))
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
it "should not match when query params are declared as RSpec HashIncluding matcher not matching params" do
|
|
337
|
+
expect(WebMock::RequestPattern.new(:get, ->(uri) { true },
|
|
338
|
+
query: RSpec::Mocks::ArgumentMatchers::HashIncludingMatcher.new({"a" => ["b", "d"]}))).
|
|
339
|
+
not_to match(WebMock::RequestSignature.new(:get, "www.example.com?a[]=b&a[]=c&b=1"))
|
|
340
|
+
end
|
|
341
|
+
end
|
|
342
|
+
|
|
221
343
|
describe "when uri is described as Addressable::Template" do
|
|
222
344
|
it "should raise error if query params are specified" do
|
|
223
345
|
expect(WebMock::RequestPattern.new(:get, Addressable::Template.new("www.example.com"), query: {"a" => ["b", "c"]})).
|
|
224
346
|
to match(WebMock::RequestSignature.new(:get, "www.example.com?a[]=b&a[]=c"))
|
|
225
347
|
end
|
|
226
348
|
|
|
227
|
-
it "should match request query params if params don't match" do
|
|
349
|
+
it "should not match request query params if params don't match" do
|
|
228
350
|
expect(WebMock::RequestPattern.new(:get, Addressable::Template.new("www.example.com"), query: {"x" => ["b", "c"]})).
|
|
229
351
|
not_to match(WebMock::RequestSignature.new(:get, "www.example.com?a[]=b&a[]=c"))
|
|
230
352
|
end
|
|
@@ -412,69 +534,105 @@ describe WebMock::RequestPattern do
|
|
|
412
534
|
end
|
|
413
535
|
|
|
414
536
|
describe "for request with json body and content type is set to json" do
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
537
|
+
shared_examples "a json body" do
|
|
538
|
+
it "should match when hash matches body" do
|
|
539
|
+
expect(WebMock::RequestPattern.new(:post, 'www.example.com', body: body_hash)).
|
|
540
|
+
to match(WebMock::RequestSignature.new(:post, "www.example.com", headers: {content_type: content_type},
|
|
541
|
+
body: "{\"a\":\"1\",\"c\":{\"d\":[\"e\",\"f\"]},\"b\":\"five\"}"))
|
|
542
|
+
end
|
|
420
543
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
544
|
+
it "should match if hash matches body in different form" do
|
|
545
|
+
expect(WebMock::RequestPattern.new(:post, 'www.example.com', body: body_hash)).
|
|
546
|
+
to match(WebMock::RequestSignature.new(:post, "www.example.com", headers: {content_type: content_type},
|
|
547
|
+
body: "{\"a\":\"1\",\"b\":\"five\",\"c\":{\"d\":[\"e\",\"f\"]}}"))
|
|
548
|
+
end
|
|
549
|
+
|
|
550
|
+
it "should match if the request body has a top level array" do
|
|
551
|
+
expect(WebMock::RequestPattern.new(:post, 'www.example.com', body: [{a: 1}])).
|
|
552
|
+
to match(WebMock::RequestSignature.new(:post, "www.example.com",
|
|
553
|
+
headers: {content_type: content_type}, body: "[{\"a\":1}]"))
|
|
554
|
+
end
|
|
426
555
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
556
|
+
it "should not match if the request body has a different top level array" do
|
|
557
|
+
expect(WebMock::RequestPattern.new(:post, 'www.example.com', body: ["a", "b"])).
|
|
558
|
+
not_to match(WebMock::RequestSignature.new(:post, "www.example.com",
|
|
559
|
+
headers: {content_type: content_type}, body: "[\"a\", \"c\"]"))
|
|
560
|
+
end
|
|
561
|
+
|
|
562
|
+
it "should not match when body is not json" do
|
|
563
|
+
expect(WebMock::RequestPattern.new(:post, 'www.example.com', body: body_hash)).
|
|
564
|
+
not_to match(WebMock::RequestSignature.new(:post, "www.example.com",
|
|
565
|
+
headers: {content_type: content_type}, body: "foo bar"))
|
|
566
|
+
end
|
|
432
567
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
568
|
+
it "should not match if request body is different" do
|
|
569
|
+
expect(WebMock::RequestPattern.new(:post, 'www.example.com', body: {a: 1, b: 2})).
|
|
570
|
+
not_to match(WebMock::RequestSignature.new(:post, "www.example.com",
|
|
571
|
+
headers: {content_type: content_type}, body: "{\"a\":1,\"c\":null}"))
|
|
572
|
+
end
|
|
573
|
+
|
|
574
|
+
it "should not match if request body is has less params than pattern" do
|
|
575
|
+
expect(WebMock::RequestPattern.new(:post, 'www.example.com', body: {a: 1, b: 2})).
|
|
576
|
+
not_to match(WebMock::RequestSignature.new(:post, "www.example.com",
|
|
577
|
+
headers: {content_type: content_type}, body: "{\"a\":1}"))
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
it "should not match if request body is has more params than pattern" do
|
|
581
|
+
expect(WebMock::RequestPattern.new(:post, 'www.example.com', body: {a: 1})).
|
|
582
|
+
not_to match(WebMock::RequestSignature.new(:post, "www.example.com",
|
|
583
|
+
headers: {content_type: content_type}, body: "{\"a\":1,\"c\":1}"))
|
|
584
|
+
end
|
|
437
585
|
end
|
|
438
586
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
headers: {content_type: 'application/json'}, body: "{\"a\":1}"))
|
|
587
|
+
context "standard application/json" do
|
|
588
|
+
let(:content_type) { 'application/json' }
|
|
589
|
+
it_behaves_like "a json body"
|
|
443
590
|
end
|
|
444
591
|
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
headers: {content_type: 'application/json'}, body: "{\"a\":1,\"c\":1}"))
|
|
592
|
+
context "custom json content type" do
|
|
593
|
+
let(:content_type) { 'application/vnd.api+json' }
|
|
594
|
+
it_behaves_like "a json body"
|
|
449
595
|
end
|
|
450
596
|
end
|
|
451
597
|
|
|
452
598
|
describe "for request with xml body and content type is set to xml" do
|
|
453
599
|
let(:body_hash) { {"opt" => {:a => '1', :b => 'five', 'c' => {'d' => ['e', 'f']}}} }
|
|
454
600
|
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
601
|
+
shared_examples "a xml body" do
|
|
602
|
+
it "should match when hash matches body" do
|
|
603
|
+
expect(WebMock::RequestPattern.new(:post, 'www.example.com', body: body_hash)).
|
|
604
|
+
to match(WebMock::RequestSignature.new(:post, "www.example.com", headers: {content_type: content_type},
|
|
605
|
+
body: "<opt a=\"1\" b=\"five\">\n <c>\n <d>e</d>\n <d>f</d>\n </c>\n</opt>\n"))
|
|
606
|
+
end
|
|
460
607
|
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
608
|
+
it "should match if hash matches body in different form" do
|
|
609
|
+
expect(WebMock::RequestPattern.new(:post, 'www.example.com', body: body_hash)).
|
|
610
|
+
to match(WebMock::RequestSignature.new(:post, "www.example.com", headers: {content_type: content_type},
|
|
611
|
+
body: "<opt b=\"five\" a=\"1\">\n <c>\n <d>e</d>\n <d>f</d>\n </c>\n</opt>\n"))
|
|
612
|
+
end
|
|
466
613
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
614
|
+
it "should not match when body is not xml" do
|
|
615
|
+
expect(WebMock::RequestPattern.new(:post, 'www.example.com', body: body_hash)).
|
|
616
|
+
not_to match(WebMock::RequestSignature.new(:post, "www.example.com",
|
|
617
|
+
headers: {content_type: content_type}, body: "foo bar"))
|
|
618
|
+
end
|
|
472
619
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
620
|
+
it "matches when the content type include a charset" do
|
|
621
|
+
expect(WebMock::RequestPattern.new(:post, 'www.example.com', body: body_hash)).
|
|
622
|
+
to match(WebMock::RequestSignature.new(:post, "www.example.com", headers: {content_type: "#{content_type};charset=UTF-8"},
|
|
623
|
+
body: "<opt a=\"1\" b=\"five\">\n <c>\n <d>e</d>\n <d>f</d>\n </c>\n</opt>\n"))
|
|
624
|
+
|
|
625
|
+
end
|
|
626
|
+
end
|
|
627
|
+
|
|
628
|
+
context "standard application/xml" do
|
|
629
|
+
let(:content_type) { 'application/xml' }
|
|
630
|
+
it_behaves_like "a xml body"
|
|
631
|
+
end
|
|
477
632
|
|
|
633
|
+
context "custom xml content type" do
|
|
634
|
+
let(:content_type) { 'application/atom+xml' }
|
|
635
|
+
it_behaves_like "a xml body"
|
|
478
636
|
end
|
|
479
637
|
end
|
|
480
638
|
end
|
|
@@ -60,7 +60,7 @@ RSpec.describe WebMock::RequestSignatureSnippet do
|
|
|
60
60
|
result = subject.request_stubs
|
|
61
61
|
result.sub!("registered request stubs:\n\n", "")
|
|
62
62
|
expect(result).to eq(
|
|
63
|
-
"stub_request(:get, \"https://www.example.com/\").\n with(body: {\"a\"=>\"b\"})"
|
|
63
|
+
"stub_request(:get, \"https://www.example.com/\").\n with(\n body: {\"a\"=>\"b\"})"
|
|
64
64
|
)
|
|
65
65
|
end
|
|
66
66
|
|
|
@@ -74,7 +74,7 @@ RSpec.describe WebMock::RequestSignatureSnippet do
|
|
|
74
74
|
result = subject.request_stubs
|
|
75
75
|
result.sub!("registered request stubs:\n\n", "")
|
|
76
76
|
expect(result).to eq(
|
|
77
|
-
"stub_request(:get, \"https://www.example.com/\").\n with(body: {\"a\"=>\"b\"})\n\nBody diff:\n [[\"-\", \"key\", \"different value\"], [\"+\", \"a\", \"b\"]]\n"
|
|
77
|
+
"stub_request(:get, \"https://www.example.com/\").\n with(\n body: {\"a\"=>\"b\"})\n\nBody diff:\n [[\"-\", \"key\", \"different value\"], [\"+\", \"a\", \"b\"]]\n"
|
|
78
78
|
)
|
|
79
79
|
end
|
|
80
80
|
end
|
|
@@ -18,7 +18,7 @@ describe WebMock::RequestSignature do
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
it "assigns normalized headers" do
|
|
21
|
-
|
|
21
|
+
allow(WebMock::Util::Headers).to receive(:normalize_headers).with({'A' => 'a'}.freeze).and_return('B' => 'b')
|
|
22
22
|
expect(
|
|
23
23
|
WebMock::RequestSignature.new(:get, "www.example.com", headers: {'A' => 'a'}).headers
|
|
24
24
|
).to eq({'B' => 'b'})
|
|
@@ -125,11 +125,21 @@ describe WebMock::RequestSignature do
|
|
|
125
125
|
expect(subject.url_encoded?).to be true
|
|
126
126
|
end
|
|
127
127
|
|
|
128
|
+
it "returns true if the headers are urlencoded with a specified charset" do
|
|
129
|
+
subject.headers = { "Content-Type" => "application/x-www-form-urlencoded; charset=UTF-8" }
|
|
130
|
+
expect(subject.url_encoded?).to be true
|
|
131
|
+
end
|
|
132
|
+
|
|
128
133
|
it "returns false if the headers are NOT urlencoded" do
|
|
129
134
|
subject.headers = { "Content-Type" => "application/made-up-format" }
|
|
130
135
|
expect(subject.url_encoded?).to be false
|
|
131
136
|
end
|
|
132
137
|
|
|
138
|
+
it "returns false when no content type header is present" do
|
|
139
|
+
subject.headers = { "Some-Header" => "some-value" }
|
|
140
|
+
expect(subject.url_encoded?).to be false
|
|
141
|
+
end
|
|
142
|
+
|
|
133
143
|
it "returns false when no headers are set" do
|
|
134
144
|
subject.headers = nil
|
|
135
145
|
expect(subject.url_encoded?).to be false
|
|
@@ -142,11 +152,21 @@ describe WebMock::RequestSignature do
|
|
|
142
152
|
expect(subject.json_headers?).to be true
|
|
143
153
|
end
|
|
144
154
|
|
|
155
|
+
it "returns true if the headers are json with a specified charset" do
|
|
156
|
+
subject.headers = { "Content-Type" => "application/json; charset=UTF-8" }
|
|
157
|
+
expect(subject.json_headers?).to be true
|
|
158
|
+
end
|
|
159
|
+
|
|
145
160
|
it "returns false if the headers are NOT json" do
|
|
146
161
|
subject.headers = { "Content-Type" => "application/made-up-format" }
|
|
147
162
|
expect(subject.json_headers?).to be false
|
|
148
163
|
end
|
|
149
164
|
|
|
165
|
+
it "returns false when no content type header is present" do
|
|
166
|
+
subject.headers = { "Some-Header" => "some-value" }
|
|
167
|
+
expect(subject.json_headers?).to be false
|
|
168
|
+
end
|
|
169
|
+
|
|
150
170
|
it "returns false when no headers are set" do
|
|
151
171
|
subject.headers = nil
|
|
152
172
|
expect(subject.json_headers?).to be false
|
|
@@ -50,6 +50,41 @@ describe WebMock::RequestStub do
|
|
|
50
50
|
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
+
describe "to_return_json" do
|
|
54
|
+
|
|
55
|
+
it "should raise if a block is given" do
|
|
56
|
+
expect {
|
|
57
|
+
@request_stub.to_return_json(body: "abc", status: 500) { puts "don't call me" }
|
|
58
|
+
}.to raise_error(ArgumentError, '#to_return_json does not support passing a block')
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "should assign responses normally" do
|
|
62
|
+
@request_stub.to_return_json([{body: "abc"}, {body: "def"}])
|
|
63
|
+
expect([@request_stub.response.body, @request_stub.response.body]).to eq(["abc", "def"])
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it "should json-ify a Hash body" do
|
|
67
|
+
@request_stub.to_return_json(body: {abc: "def"}, status: 500)
|
|
68
|
+
expect(@request_stub.response.body).to eq({abc: "def"}.to_json)
|
|
69
|
+
expect(@request_stub.response.status).to eq([500, ""])
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it "should apply the content_type header" do
|
|
73
|
+
@request_stub.to_return_json(body: {abc: "def"}, status: 500)
|
|
74
|
+
expect(@request_stub.response.headers).to eq({"Content-Type"=>"application/json"})
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it "should preserve existing headers" do
|
|
78
|
+
@request_stub.to_return_json(headers: {"A" => "a"}, body: "")
|
|
79
|
+
expect(@request_stub.response.headers).to eq({"A"=>"a", "Content-Type"=>"application/json"})
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "should allow callsites to override content_type header" do
|
|
83
|
+
@request_stub.to_return_json(headers: {content_type: 'application/super-special-json'})
|
|
84
|
+
expect(@request_stub.response.headers).to eq({"Content-Type"=>"application/super-special-json"})
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
53
88
|
describe "then" do
|
|
54
89
|
it "should return stub without any modifications, acting as syntactic sugar" do
|
|
55
90
|
expect(@request_stub.then).to eq(@request_stub)
|
data/spec/unit/response_spec.rb
CHANGED
|
@@ -31,7 +31,7 @@ describe WebMock::Response do
|
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
it "should report normalized headers" do
|
|
34
|
-
|
|
34
|
+
allow(WebMock::Util::Headers).to receive(:normalize_headers).with({'A' => 'a'}.freeze).and_return('B' => 'b')
|
|
35
35
|
@response = WebMock::Response.new(headers: {'A' => 'a'})
|
|
36
36
|
expect(@response.headers).to eq({'B' => 'b'})
|
|
37
37
|
end
|
|
@@ -130,14 +130,46 @@ describe WebMock::Response do
|
|
|
130
130
|
# Users of webmock commonly make the mistake of stubbing the response
|
|
131
131
|
# body to return a hash, to prevent this:
|
|
132
132
|
#
|
|
133
|
-
it "should error if
|
|
133
|
+
it "should error if given a non-allowed type: a hash" do
|
|
134
134
|
expect { WebMock::Response.new(body: Hash.new) }.to \
|
|
135
135
|
raise_error(WebMock::Response::InvalidBody)
|
|
136
136
|
end
|
|
137
137
|
|
|
138
|
+
it "should error if given a non-allowed type: something that is not a hash" do
|
|
139
|
+
expect { WebMock::Response.new(body: 123) }.to \
|
|
140
|
+
raise_error(WebMock::Response::InvalidBody)
|
|
141
|
+
end
|
|
138
142
|
end
|
|
139
143
|
|
|
140
144
|
describe "from raw response" do
|
|
145
|
+
describe "when input is a StringIO" do
|
|
146
|
+
before(:each) do
|
|
147
|
+
@io = StringIO.new(File.read(CURL_EXAMPLE_OUTPUT_PATH))
|
|
148
|
+
@response = WebMock::Response.new(@io)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
it "should read status" do
|
|
152
|
+
expect(@response.status).to eq([202, "OK"])
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
it "should read headers" do
|
|
156
|
+
expect(@response.headers).to eq(
|
|
157
|
+
"Date"=>"Sat, 23 Jan 2010 01:01:05 GMT",
|
|
158
|
+
"Content-Type"=>"text/html; charset=UTF-8",
|
|
159
|
+
"Content-Length"=>"419",
|
|
160
|
+
"Connection"=>"Keep-Alive",
|
|
161
|
+
"Accept"=>"image/jpeg, image/png"
|
|
162
|
+
)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
it "should read body" do
|
|
166
|
+
expect(@response.body.size).to eq(419)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
it "should close IO" do
|
|
170
|
+
expect(@io).to be_closed
|
|
171
|
+
end
|
|
172
|
+
end
|
|
141
173
|
|
|
142
174
|
describe "when input is IO" do
|
|
143
175
|
before(:each) do
|
|
@@ -152,12 +184,12 @@ describe WebMock::Response do
|
|
|
152
184
|
|
|
153
185
|
it "should read headers" do
|
|
154
186
|
expect(@response.headers).to eq({
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
187
|
+
"Date"=>"Sat, 23 Jan 2010 01:01:05 GMT",
|
|
188
|
+
"Content-Type"=>"text/html; charset=UTF-8",
|
|
189
|
+
"Content-Length"=>"419",
|
|
190
|
+
"Connection"=>"Keep-Alive",
|
|
191
|
+
"Accept"=>"image/jpeg, image/png"
|
|
192
|
+
})
|
|
161
193
|
end
|
|
162
194
|
|
|
163
195
|
it "should read body" do
|
|
@@ -182,12 +214,12 @@ describe WebMock::Response do
|
|
|
182
214
|
|
|
183
215
|
it "should read headers" do
|
|
184
216
|
expect(@response.headers).to eq({
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
217
|
+
"Date"=>"Sat, 23 Jan 2010 01:01:05 GMT",
|
|
218
|
+
"Content-Type"=>"text/html; charset=UTF-8",
|
|
219
|
+
"Content-Length"=>"419",
|
|
220
|
+
"Connection"=>"Keep-Alive",
|
|
221
|
+
"Accept"=>"image/jpeg, image/png"
|
|
222
|
+
})
|
|
191
223
|
end
|
|
192
224
|
|
|
193
225
|
it "should read body" do
|
|
@@ -234,11 +266,11 @@ describe WebMock::Response do
|
|
|
234
266
|
it "should evaluate new response with evaluated options" do
|
|
235
267
|
request_signature = WebMock::RequestSignature.new(:post, "www.example.com", body: "abc", headers: {'A' => 'a'})
|
|
236
268
|
response = WebMock::DynamicResponse.new(lambda {|request|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
269
|
+
{
|
|
270
|
+
body: request.body,
|
|
271
|
+
headers: request.headers,
|
|
272
|
+
status: 302
|
|
273
|
+
}
|
|
242
274
|
})
|
|
243
275
|
evaluated_response = response.evaluate(request_signature)
|
|
244
276
|
expect(evaluated_response.body).to eq("abc")
|
|
@@ -16,7 +16,7 @@ describe WebMock::StubRequestSnippet do
|
|
|
16
16
|
it "should print stub request snippet with body if available" do
|
|
17
17
|
@request_signature.body = "abcdef"
|
|
18
18
|
expected = %Q(stub_request(:get, "http://www.example.com/?a=b&c=d").)+
|
|
19
|
-
"\n with(body: \"abcdef\")." +
|
|
19
|
+
"\n with(\n body: \"abcdef\")." +
|
|
20
20
|
"\n to_return(status: 200, body: \"\", headers: {})"
|
|
21
21
|
@request_stub = WebMock::RequestStub.from_request_signature(@request_signature)
|
|
22
22
|
expect(WebMock::StubRequestSnippet.new(@request_stub).to_s).to eq(expected)
|
|
@@ -25,7 +25,7 @@ describe WebMock::StubRequestSnippet do
|
|
|
25
25
|
it "should print stub request snippet with multiline body" do
|
|
26
26
|
@request_signature.body = "abc\ndef"
|
|
27
27
|
expected = %Q(stub_request(:get, "http://www.example.com/?a=b&c=d").)+
|
|
28
|
-
"\n with(body: \"abc\\ndef\")." +
|
|
28
|
+
"\n with(\n body: \"abc\\ndef\")." +
|
|
29
29
|
"\n to_return(status: 200, body: \"\", headers: {})"
|
|
30
30
|
@request_stub = WebMock::RequestStub.from_request_signature(@request_signature)
|
|
31
31
|
expect(WebMock::StubRequestSnippet.new(@request_stub).to_s).to eq(expected)
|
|
@@ -34,7 +34,7 @@ describe WebMock::StubRequestSnippet do
|
|
|
34
34
|
it "should print stub request snippet with headers if any" do
|
|
35
35
|
@request_signature.headers = {'B' => 'b', 'A' => 'a'}
|
|
36
36
|
expected = 'stub_request(:get, "http://www.example.com/?a=b&c=d").'+
|
|
37
|
-
"\n with(headers: {\'A\'=>\'a\'
|
|
37
|
+
"\n with(\n headers: {\n\t\ 'A\'=>\'a\',\n\t \'B\'=>\'b\'\n })." +
|
|
38
38
|
"\n to_return(status: 200, body: \"\", headers: {})"
|
|
39
39
|
@request_stub = WebMock::RequestStub.from_request_signature(@request_signature)
|
|
40
40
|
expect(WebMock::StubRequestSnippet.new(@request_stub).to_s).to eq(expected)
|
|
@@ -44,7 +44,7 @@ describe WebMock::StubRequestSnippet do
|
|
|
44
44
|
@request_signature.body = "abcdef"
|
|
45
45
|
@request_signature.headers = {'B' => 'b', 'A' => 'a'}
|
|
46
46
|
expected = 'stub_request(:get, "http://www.example.com/?a=b&c=d").'+
|
|
47
|
-
"\n with(body: \"abcdef\",\n
|
|
47
|
+
"\n with(\n body: \"abcdef\",\n headers: {\n\t \'A\'=>\'a\',\n\t \'B\'=>\'b\'\n })." +
|
|
48
48
|
"\n to_return(status: 200, body: \"\", headers: {})"
|
|
49
49
|
@request_stub = WebMock::RequestStub.from_request_signature(@request_signature)
|
|
50
50
|
expect(WebMock::StubRequestSnippet.new(@request_stub).to_s).to eq(expected)
|
|
@@ -52,7 +52,7 @@ describe WebMock::StubRequestSnippet do
|
|
|
52
52
|
|
|
53
53
|
it "should not print to_return part if not wanted" do
|
|
54
54
|
expected = 'stub_request(:get, "http://www.example.com/").'+
|
|
55
|
-
"\n with(body: \"abcdef\")"
|
|
55
|
+
"\n with(\n body: \"abcdef\")"
|
|
56
56
|
stub = WebMock::RequestStub.new(:get, "www.example.com").with(body: "abcdef").to_return(body: "hello")
|
|
57
57
|
expect(WebMock::StubRequestSnippet.new(stub).to_s(false)).to eq(expected)
|
|
58
58
|
end
|
|
@@ -68,8 +68,11 @@ describe WebMock::StubRequestSnippet do
|
|
|
68
68
|
@request_stub = WebMock::RequestStub.from_request_signature(@request_signature)
|
|
69
69
|
expected = <<-STUB
|
|
70
70
|
stub_request(:post, "http://www.example.com/").
|
|
71
|
-
with(
|
|
72
|
-
|
|
71
|
+
with(
|
|
72
|
+
body: {"user"=>{"first_name"=>"Bartosz"}},
|
|
73
|
+
headers: {
|
|
74
|
+
\t 'Content-Type'=>'application/x-www-form-urlencoded'
|
|
75
|
+
}).
|
|
73
76
|
to_return(status: 200, body: \"\", headers: {})
|
|
74
77
|
STUB
|
|
75
78
|
expect(WebMock::StubRequestSnippet.new(@request_stub).to_s).to eq(expected.strip)
|
|
@@ -82,14 +85,31 @@ stub_request(:post, "http://www.example.com/").
|
|
|
82
85
|
@request_stub = WebMock::RequestStub.from_request_signature(@request_signature)
|
|
83
86
|
expected = <<-STUB
|
|
84
87
|
stub_request(:post, "http://www.example.com/").
|
|
85
|
-
with(
|
|
86
|
-
|
|
88
|
+
with(
|
|
89
|
+
body: "#{multipart_form_body}",
|
|
90
|
+
headers: {
|
|
91
|
+
\t 'Content-Type'=>'multipart/form-data; boundary=ABC123'
|
|
92
|
+
}).
|
|
87
93
|
to_return(status: 200, body: \"\", headers: {})
|
|
88
94
|
STUB
|
|
89
95
|
expect(WebMock::StubRequestSnippet.new(@request_stub).to_s).to eq(expected.strip)
|
|
90
96
|
end
|
|
91
|
-
end
|
|
92
97
|
|
|
98
|
+
it "should print stub request snippet with valid JSON body when request header contains 'Accept'=>'application/json' " do
|
|
99
|
+
@request_signature = WebMock::RequestSignature.new(:post, "www.example.com",
|
|
100
|
+
headers: {'Accept' => 'application/json'})
|
|
101
|
+
@request_stub = WebMock::RequestStub.from_request_signature(@request_signature)
|
|
102
|
+
expected = <<-STUB
|
|
103
|
+
stub_request(:post, "http://www.example.com/").
|
|
104
|
+
with(
|
|
105
|
+
headers: {
|
|
106
|
+
\t 'Accept'=>'application/json'
|
|
107
|
+
}).
|
|
108
|
+
to_return(status: 200, body: \"{}\", headers: {})
|
|
109
|
+
STUB
|
|
110
|
+
expect(WebMock::StubRequestSnippet.new(@request_stub).to_s).to eq(expected.strip)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
93
113
|
|
|
94
114
|
end
|
|
95
115
|
end
|