webmock 3.11.1 → 3.12.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/CI.yml +37 -0
- data/CHANGELOG.md +28 -0
- data/Gemfile +1 -1
- data/README.md +18 -12
- data/Rakefile +12 -2
- data/lib/webmock/http_lib_adapters/async_http_client_adapter.rb +3 -1
- data/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +6 -3
- data/lib/webmock/http_lib_adapters/manticore_adapter.rb +8 -1
- data/lib/webmock/http_lib_adapters/net_http.rb +10 -3
- data/lib/webmock/request_pattern.rb +7 -1
- data/lib/webmock/version.rb +1 -1
- data/spec/acceptance/async_http_client/async_http_client_spec.rb +22 -0
- data/spec/acceptance/em_http_request/em_http_request_spec.rb +56 -0
- data/spec/acceptance/manticore/manticore_spec.rb +32 -0
- data/spec/acceptance/net_http/net_http_spec.rb +26 -0
- data/spec/acceptance/patron/patron_spec_helper.rb +2 -2
- data/spec/unit/request_pattern_spec.rb +70 -46
- data/webmock.gemspec +1 -0
- metadata +20 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6cf9216e779a2041d66197b6842541c77cb4bbcccc93c5d1b1260283b1003264
|
4
|
+
data.tar.gz: '04926e981765e34e6c39919a14dc7f41ce7b7a272484762269adae18004902d0'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d0998bb9620479a4c3036ea2872ba8de5f0748b5cb4b62e454239324cdecede5007d7dd63e65ebc676f9798574ebf680255737623088a01293dbca7eaa95a1b2
|
7
|
+
data.tar.gz: 7afd145d161fe7460ad0ef10f4eb1ec29e67b58cd0462de7bfc5fac39fc210f9bd27f7d56b508ab8552be1152ec807245044ebe009cdca15b944fe58bdc9d679
|
@@ -0,0 +1,37 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- master
|
7
|
+
pull_request:
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
build:
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
strategy:
|
13
|
+
fail-fast: false
|
14
|
+
matrix:
|
15
|
+
ruby:
|
16
|
+
- head
|
17
|
+
- '3.0'
|
18
|
+
- '2.7'
|
19
|
+
- '2.6'
|
20
|
+
- '2.5'
|
21
|
+
- jruby
|
22
|
+
continue-on-error: ${{ matrix.ruby == 'head' }}
|
23
|
+
name: Ruby ${{ matrix.ruby }}
|
24
|
+
env:
|
25
|
+
JRUBY_OPTS: "--debug"
|
26
|
+
steps:
|
27
|
+
- uses: actions/checkout@v2
|
28
|
+
- name: Install Apt Packages
|
29
|
+
run: |
|
30
|
+
sudo apt-get install libcurl4-openssl-dev -y
|
31
|
+
- uses: ruby/setup-ruby@v1
|
32
|
+
continue-on-error: true
|
33
|
+
with:
|
34
|
+
ruby-version: ${{ matrix.ruby }}
|
35
|
+
bundler-cache: true
|
36
|
+
- run: |
|
37
|
+
bundle exec rake
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,33 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
# 3.12.2
|
4
|
+
|
5
|
+
* Fixed em-http-request adapter to avoid calling middleware twice.
|
6
|
+
|
7
|
+
Thanks to [Alex Vondrak](https://github.com/ajvondrak)
|
8
|
+
|
9
|
+
# 3.12.1
|
10
|
+
|
11
|
+
* Fixed handling of URIs with IPv6 addresses with square brackets when in Net::HTTP adapter.
|
12
|
+
|
13
|
+
Thanks to [Johanna Hartmann](https://github.com/JohannaHartmann)
|
14
|
+
|
15
|
+
# 3.12.0
|
16
|
+
|
17
|
+
* Added support for handling custom JSON and XML content types e.g. 'application/vnd.api+json'
|
18
|
+
|
19
|
+
# 3.11.3
|
20
|
+
|
21
|
+
* Fixed async-http adapter to only considered requests as real if they are real.
|
22
|
+
|
23
|
+
Thanks to Thanks to [Tony Schneider](https://github.com/tonywok) and [Samuel Williams](https://github.com/ioquatix)
|
24
|
+
|
25
|
+
# 3.11.2
|
26
|
+
|
27
|
+
* Fix for Manticore streaming mode
|
28
|
+
|
29
|
+
Thanks to [Oleksiy Kovyrin](https://github.com/kovyrin)
|
30
|
+
|
3
31
|
# 3.11.1
|
4
32
|
|
5
33
|
* Compatibility with async-http 0.54+
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -24,19 +24,19 @@ Features
|
|
24
24
|
Supported HTTP libraries
|
25
25
|
------------------------
|
26
26
|
|
27
|
-
* Async::HTTP::Client
|
28
|
-
* Curb (currently only Curb::Easy)
|
29
|
-
* EM-HTTP-Request
|
30
|
-
* Excon
|
31
|
-
* HTTPClient
|
27
|
+
* [Async::HTTP::Client](https://github.com/socketry/async-http)
|
28
|
+
* [Curb](https://github.com/taf2/curb) (currently only Curb::Easy)
|
29
|
+
* [EM-HTTP-Request](https://github.com/igrigorik/em-http-request)
|
30
|
+
* [Excon](https://github.com/excon/excon)
|
31
|
+
* [HTTPClient](https://github.com/nahi/httpclient)
|
32
32
|
* [HTTP Gem (also known as http.rb)](https://github.com/httprb/http)
|
33
|
-
*
|
34
|
-
*
|
35
|
-
|
36
|
-
*
|
37
|
-
*
|
38
|
-
* Patron
|
39
|
-
* Typhoeus (currently only Typhoeus::Hydra)
|
33
|
+
* [httpx](https://honeyryderchuck.gitlab.io/httpx/wiki/Webmock-Adapter)
|
34
|
+
* [Manticore](https://github.com/cheald/manticore)
|
35
|
+
* [Net::HTTP](https://ruby-doc.org/stdlib-2.7.0/libdoc/net/http/rdoc/Net/HTTP.html) and other libraries based on Net::HTTP, e.g.:
|
36
|
+
* [HTTParty](https://github.com/jnunemaker/httparty)
|
37
|
+
* [REST Client](https://github.com/rest-client/rest-client)
|
38
|
+
* [Patron](https://github.com/toland/patron)
|
39
|
+
* [Typhoeus](https://github.com/typhoeus/typhoeus) (currently only Typhoeus::Hydra)
|
40
40
|
|
41
41
|
Supported Ruby Interpreters
|
42
42
|
---------------------------
|
@@ -1153,6 +1153,12 @@ People who submitted patches and new features or suggested improvements. Many th
|
|
1153
1153
|
* Marek Kasztelnik
|
1154
1154
|
* ce07c3
|
1155
1155
|
* Jun Jiang
|
1156
|
+
* Oleksiy Kovyrin
|
1157
|
+
* Matt Larraz
|
1158
|
+
* Tony Schneider
|
1159
|
+
* Niklas Hösl
|
1160
|
+
* Johanna Hartmann
|
1161
|
+
* Alex Vondrak
|
1156
1162
|
|
1157
1163
|
For a full list of contributors you can visit the
|
1158
1164
|
[contributors](https://github.com/bblimke/webmock/contributors) page.
|
data/Rakefile
CHANGED
@@ -3,24 +3,34 @@ Bundler::GemHelper.install_tasks
|
|
3
3
|
|
4
4
|
require "rspec/core/rake_task"
|
5
5
|
RSpec::Core::RakeTask.new(:spec) do |t|
|
6
|
-
t.rspec_opts = [
|
6
|
+
t.rspec_opts = %w[
|
7
|
+
--force-color
|
8
|
+
--format progress
|
9
|
+
--require ./spec/spec_helper.rb
|
10
|
+
]
|
7
11
|
t.pattern = 'spec/**/*_spec.rb'
|
8
12
|
end
|
9
13
|
|
10
14
|
RSpec::Core::RakeTask.new(:spec_http_without_webmock) do |t|
|
11
|
-
t.rspec_opts = [
|
15
|
+
t.rspec_opts = %w[
|
16
|
+
--force-color
|
17
|
+
--format progress
|
18
|
+
--require ./spec/acceptance/net_http/real_net_http_spec.rb
|
19
|
+
]
|
12
20
|
t.pattern = 'spec/acceptance/net_http/real_net_http_spec.rb'
|
13
21
|
end
|
14
22
|
|
15
23
|
require 'rake/testtask'
|
16
24
|
Rake::TestTask.new(:test) do |test|
|
17
25
|
test.test_files = FileList["test/**/*.rb"].exclude("test/test_helper.rb")
|
26
|
+
test.options = "--use-color"
|
18
27
|
test.verbose = false
|
19
28
|
test.warning = false
|
20
29
|
end
|
21
30
|
|
22
31
|
Rake::TestTask.new(:minitest) do |test|
|
23
32
|
test.test_files = FileList["minitest/**/*.rb"].exclude("test/test_helper.rb")
|
33
|
+
test.options = "--pride"
|
24
34
|
test.verbose = false
|
25
35
|
test.warning = false
|
26
36
|
end
|
@@ -55,6 +55,7 @@ if defined?(Async::HTTP)
|
|
55
55
|
WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)
|
56
56
|
webmock_response = WebMock::StubRegistry.instance.response_for_request(request_signature)
|
57
57
|
net_connect_allowed = WebMock.net_connect_allowed?(request_signature.uri)
|
58
|
+
real_request = false
|
58
59
|
|
59
60
|
if webmock_response
|
60
61
|
webmock_response.raise_error_if_any
|
@@ -63,6 +64,7 @@ if defined?(Async::HTTP)
|
|
63
64
|
response = @webmock_client.call(request)
|
64
65
|
elsif net_connect_allowed
|
65
66
|
response = @network_client.call(request)
|
67
|
+
real_request = true
|
66
68
|
else
|
67
69
|
raise WebMock::NetConnectNotAllowedError.new(request_signature) unless webmock_response
|
68
70
|
end
|
@@ -72,7 +74,7 @@ if defined?(Async::HTTP)
|
|
72
74
|
WebMock::CallbackRegistry.invoke_callbacks(
|
73
75
|
{
|
74
76
|
lib: :async_http_client,
|
75
|
-
real_request:
|
77
|
+
real_request: real_request
|
76
78
|
},
|
77
79
|
request_signature,
|
78
80
|
webmock_response
|
@@ -99,6 +99,11 @@ if defined?(EventMachine::HttpClient)
|
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
102
|
+
def connection_completed
|
103
|
+
@state = :response_header
|
104
|
+
send_request(request_signature.headers, request_signature.body)
|
105
|
+
end
|
106
|
+
|
102
107
|
def send_request(head, body)
|
103
108
|
WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)
|
104
109
|
|
@@ -164,7 +169,7 @@ if defined?(EventMachine::HttpClient)
|
|
164
169
|
end
|
165
170
|
|
166
171
|
def build_request_signature
|
167
|
-
headers, body =
|
172
|
+
headers, body = build_request, @req.body
|
168
173
|
|
169
174
|
@conn.middleware.select {|m| m.respond_to?(:request) }.each do |m|
|
170
175
|
headers, body = m.request(self, headers, body)
|
@@ -178,8 +183,6 @@ if defined?(EventMachine::HttpClient)
|
|
178
183
|
|
179
184
|
body = form_encode_body(body) if body.is_a?(Hash)
|
180
185
|
|
181
|
-
headers = @req.headers
|
182
|
-
|
183
186
|
if headers['authorization'] && headers['authorization'].is_a?(Array)
|
184
187
|
headers['Authorization'] = WebMock::Util::Headers.basic_auth_header(headers.delete('authorization'))
|
185
188
|
end
|
@@ -127,8 +127,15 @@ if defined?(Manticore)
|
|
127
127
|
def generate_webmock_response(manticore_response)
|
128
128
|
webmock_response = WebMock::Response.new
|
129
129
|
webmock_response.status = [manticore_response.code, manticore_response.message]
|
130
|
-
webmock_response.body = manticore_response.body
|
131
130
|
webmock_response.headers = manticore_response.headers
|
131
|
+
|
132
|
+
# The attempt to read the body could fail if manticore is used in a streaming mode
|
133
|
+
webmock_response.body = begin
|
134
|
+
manticore_response.body
|
135
|
+
rescue ::Manticore::StreamClosedException
|
136
|
+
nil
|
137
|
+
end
|
138
|
+
|
132
139
|
webmock_response
|
133
140
|
end
|
134
141
|
end
|
@@ -313,8 +313,6 @@ module WebMock
|
|
313
313
|
module NetHTTPUtility
|
314
314
|
|
315
315
|
def self.request_signature_from_request(net_http, request, body = nil)
|
316
|
-
protocol = net_http.use_ssl? ? "https" : "http"
|
317
|
-
|
318
316
|
path = request.path
|
319
317
|
|
320
318
|
if path.respond_to?(:request_uri) #https://github.com/bblimke/webmock/issues/288
|
@@ -323,7 +321,7 @@ module WebMock
|
|
323
321
|
|
324
322
|
path = WebMock::Util::URI.heuristic_parse(path).request_uri if path =~ /^http/
|
325
323
|
|
326
|
-
uri =
|
324
|
+
uri = get_uri(net_http, path)
|
327
325
|
method = request.method.downcase.to_sym
|
328
326
|
|
329
327
|
headers = Hash[*request.to_hash.map {|k,v| [k, v]}.inject([]) {|r,x| r + x}]
|
@@ -343,6 +341,15 @@ module WebMock
|
|
343
341
|
WebMock::RequestSignature.new(method, uri, body: request.body, headers: headers)
|
344
342
|
end
|
345
343
|
|
344
|
+
def self.get_uri(net_http, path)
|
345
|
+
protocol = net_http.use_ssl? ? "https" : "http"
|
346
|
+
|
347
|
+
hostname = net_http.address
|
348
|
+
hostname = "[#{hostname}]" if /\A\[.*\]\z/ !~ hostname && /:/ =~ hostname
|
349
|
+
|
350
|
+
"#{protocol}://#{hostname}:#{net_http.port}#{path}"
|
351
|
+
end
|
352
|
+
|
346
353
|
def self.validate_headers(headers)
|
347
354
|
# For Ruby versions < 2.3.0, if you make a request with headers that are symbols
|
348
355
|
# Net::HTTP raises a NoMethodError
|
@@ -295,8 +295,9 @@ module WebMock
|
|
295
295
|
end
|
296
296
|
|
297
297
|
private
|
298
|
+
|
298
299
|
def body_as_hash(body, content_type)
|
299
|
-
case
|
300
|
+
case body_format(content_type)
|
300
301
|
when :json then
|
301
302
|
WebMock::Util::JSON.parse(body)
|
302
303
|
when :xml then
|
@@ -306,6 +307,11 @@ module WebMock
|
|
306
307
|
end
|
307
308
|
end
|
308
309
|
|
310
|
+
def body_format(content_type)
|
311
|
+
normalized_content_type = content_type.sub(/\A(application\/)[a-zA-Z0-9.-]+\+(json|xml)\Z/,'\1\2')
|
312
|
+
BODY_FORMATS[normalized_content_type]
|
313
|
+
end
|
314
|
+
|
309
315
|
def assert_non_multipart_body(content_type)
|
310
316
|
if content_type =~ %r{^multipart/form-data}
|
311
317
|
raise ArgumentError.new("WebMock does not support matching body for multipart/form-data requests yet :(")
|
data/lib/webmock/version.rb
CHANGED
@@ -135,6 +135,28 @@ unless RUBY_PLATFORM =~ /java/
|
|
135
135
|
expect { make_request(:get, 'http://www.example.com') }.to raise_error Async::TimeoutError
|
136
136
|
end
|
137
137
|
|
138
|
+
it 'does not invoke "after real request" callbacks for stubbed requests' do
|
139
|
+
WebMock.allow_net_connect!
|
140
|
+
stub_request(:get, 'http://www.example.com').to_return(body: 'abc')
|
141
|
+
|
142
|
+
callback_invoked = false
|
143
|
+
WebMock.after_request(real_requests_only: true) { |_| callback_invoked = true }
|
144
|
+
|
145
|
+
make_request(:get, 'http://www.example.com')
|
146
|
+
expect(callback_invoked).to eq(false)
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'does invoke "after request" callbacks for stubbed requests' do
|
150
|
+
WebMock.allow_net_connect!
|
151
|
+
stub_request(:get, 'http://www.example.com').to_return(body: 'abc')
|
152
|
+
|
153
|
+
callback_invoked = false
|
154
|
+
WebMock.after_request(real_requests_only: false) { |_| callback_invoked = true }
|
155
|
+
|
156
|
+
make_request(:get, 'http://www.example.com')
|
157
|
+
expect(callback_invoked).to eq(true)
|
158
|
+
end
|
159
|
+
|
138
160
|
context 'scheme and protocol' do
|
139
161
|
let(:default_response_headers) { {} }
|
140
162
|
|
@@ -71,6 +71,35 @@ unless RUBY_PLATFORM =~ /java/
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
+
it "only calls request middleware once" do
|
75
|
+
stub_request(:get, "www.example.com")
|
76
|
+
|
77
|
+
middleware = Class.new do
|
78
|
+
def self.called!
|
79
|
+
@called = called + 1
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.called
|
83
|
+
@called || 0
|
84
|
+
end
|
85
|
+
|
86
|
+
def request(client, head, body)
|
87
|
+
self.class.called!
|
88
|
+
[head, body]
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
EM.run do
|
93
|
+
conn = EventMachine::HttpRequest.new('http://www.example.com/')
|
94
|
+
conn.use middleware
|
95
|
+
http = conn.get
|
96
|
+
http.callback do
|
97
|
+
expect(middleware.called).to eq(1)
|
98
|
+
EM.stop
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
74
103
|
let(:response_middleware) do
|
75
104
|
Class.new do
|
76
105
|
def response(resp)
|
@@ -119,6 +148,33 @@ unless RUBY_PLATFORM =~ /java/
|
|
119
148
|
context 'making a real request', net_connect: true do
|
120
149
|
before { WebMock.allow_net_connect! }
|
121
150
|
include_examples "em-http-request middleware/after_request hook integration"
|
151
|
+
|
152
|
+
it "only calls request middleware once" do
|
153
|
+
middleware = Class.new do
|
154
|
+
def self.called!
|
155
|
+
@called = called + 1
|
156
|
+
end
|
157
|
+
|
158
|
+
def self.called
|
159
|
+
@called || 0
|
160
|
+
end
|
161
|
+
|
162
|
+
def request(client, head, body)
|
163
|
+
self.class.called!
|
164
|
+
[head, body]
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
EM.run do
|
169
|
+
conn = EventMachine::HttpRequest.new(webmock_server_url)
|
170
|
+
conn.use middleware
|
171
|
+
http = conn.get
|
172
|
+
http.callback do
|
173
|
+
expect(middleware.called).to eq(1)
|
174
|
+
EM.stop
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
122
178
|
end
|
123
179
|
|
124
180
|
context 'when the request is stubbed' do
|
@@ -70,6 +70,38 @@ if RUBY_PLATFORM =~ /java/
|
|
70
70
|
expect(failure_handler).to have_received(:call)
|
71
71
|
end
|
72
72
|
end
|
73
|
+
|
74
|
+
context 'when used in a streaming mode' do
|
75
|
+
let(:webmock_server_url) {"http://#{WebMockServer.instance.host_with_port}/"}
|
76
|
+
let(:result_chunks) { [] }
|
77
|
+
|
78
|
+
def manticore_streaming_get
|
79
|
+
Manticore.get(webmock_server_url).tap do |req|
|
80
|
+
req.on_success do |response|
|
81
|
+
response.body do |chunk|
|
82
|
+
result_chunks << chunk
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'when connections are allowed' do
|
89
|
+
it 'works' do
|
90
|
+
WebMock.allow_net_connect!
|
91
|
+
expect { manticore_streaming_get.call }.to_not raise_error
|
92
|
+
expect(result_chunks).to_not be_empty
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'when stubbed' do
|
97
|
+
it 'works' do
|
98
|
+
stub_body = 'hello!'
|
99
|
+
stub_request(:get, webmock_server_url).to_return(body: stub_body)
|
100
|
+
expect { manticore_streaming_get.call }.to_not raise_error
|
101
|
+
expect(result_chunks).to eq [stub_body]
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
73
105
|
end
|
74
106
|
end
|
75
107
|
end
|
@@ -340,4 +340,30 @@ describe "Net:HTTP" do
|
|
340
340
|
http.request(req, '')
|
341
341
|
end
|
342
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')
|
367
|
+
end
|
368
|
+
end
|
343
369
|
end
|
@@ -28,8 +28,8 @@ module PatronSpecHelper
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
status_line_pattern = %r(\AHTTP/(\d
|
32
|
-
message = response.status_line.match(status_line_pattern)[
|
31
|
+
status_line_pattern = %r(\AHTTP/(\d+(\.\d+)?)\s+(\d\d\d)\s*([^\r\n]+)?)
|
32
|
+
message = response.status_line.match(status_line_pattern)[4] || ""
|
33
33
|
|
34
34
|
OpenStruct.new({
|
35
35
|
body: response.body,
|
@@ -534,69 +534,93 @@ describe WebMock::RequestPattern do
|
|
534
534
|
end
|
535
535
|
|
536
536
|
describe "for request with json body and content type is set to json" do
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
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
|
542
543
|
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
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
|
548
549
|
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
550
|
+
it "should not match when body is not json" do
|
551
|
+
expect(WebMock::RequestPattern.new(:post, 'www.example.com', body: body_hash)).
|
552
|
+
not_to match(WebMock::RequestSignature.new(:post, "www.example.com",
|
553
|
+
headers: {content_type: content_type}, body: "foo bar"))
|
554
|
+
end
|
555
|
+
|
556
|
+
it "should not match if request body is different" do
|
557
|
+
expect(WebMock::RequestPattern.new(:post, 'www.example.com', body: {a: 1, b: 2})).
|
558
|
+
not_to match(WebMock::RequestSignature.new(:post, "www.example.com",
|
559
|
+
headers: {content_type: content_type}, body: "{\"a\":1,\"c\":null}"))
|
560
|
+
end
|
554
561
|
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
562
|
+
it "should not match if request body is has less params than pattern" do
|
563
|
+
expect(WebMock::RequestPattern.new(:post, 'www.example.com', body: {a: 1, b: 2})).
|
564
|
+
not_to match(WebMock::RequestSignature.new(:post, "www.example.com",
|
565
|
+
headers: {content_type: content_type}, body: "{\"a\":1}"))
|
566
|
+
end
|
567
|
+
|
568
|
+
it "should not match if request body is has more params than pattern" do
|
569
|
+
expect(WebMock::RequestPattern.new(:post, 'www.example.com', body: {a: 1})).
|
570
|
+
not_to match(WebMock::RequestSignature.new(:post, "www.example.com",
|
571
|
+
headers: {content_type: content_type}, body: "{\"a\":1,\"c\":1}"))
|
572
|
+
end
|
559
573
|
end
|
560
574
|
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
headers: {content_type: 'application/json'}, body: "{\"a\":1}"))
|
575
|
+
context "standard application/json" do
|
576
|
+
let(:content_type) { 'application/json' }
|
577
|
+
it_behaves_like "a json body"
|
565
578
|
end
|
566
579
|
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
headers: {content_type: 'application/json'}, body: "{\"a\":1,\"c\":1}"))
|
580
|
+
context "custom json content type" do
|
581
|
+
let(:content_type) { 'application/vnd.api+json' }
|
582
|
+
it_behaves_like "a json body"
|
571
583
|
end
|
572
584
|
end
|
573
585
|
|
574
586
|
describe "for request with xml body and content type is set to xml" do
|
575
587
|
let(:body_hash) { {"opt" => {:a => '1', :b => 'five', 'c' => {'d' => ['e', 'f']}}} }
|
576
588
|
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
589
|
+
shared_examples "a xml body" do
|
590
|
+
it "should match when hash matches body" do
|
591
|
+
expect(WebMock::RequestPattern.new(:post, 'www.example.com', body: body_hash)).
|
592
|
+
to match(WebMock::RequestSignature.new(:post, "www.example.com", headers: {content_type: content_type},
|
593
|
+
body: "<opt a=\"1\" b=\"five\">\n <c>\n <d>e</d>\n <d>f</d>\n </c>\n</opt>\n"))
|
594
|
+
end
|
582
595
|
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
596
|
+
it "should match if hash matches body in different form" do
|
597
|
+
expect(WebMock::RequestPattern.new(:post, 'www.example.com', body: body_hash)).
|
598
|
+
to match(WebMock::RequestSignature.new(:post, "www.example.com", headers: {content_type: content_type},
|
599
|
+
body: "<opt b=\"five\" a=\"1\">\n <c>\n <d>e</d>\n <d>f</d>\n </c>\n</opt>\n"))
|
600
|
+
end
|
588
601
|
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
602
|
+
it "should not match when body is not xml" do
|
603
|
+
expect(WebMock::RequestPattern.new(:post, 'www.example.com', body: body_hash)).
|
604
|
+
not_to match(WebMock::RequestSignature.new(:post, "www.example.com",
|
605
|
+
headers: {content_type: content_type}, body: "foo bar"))
|
606
|
+
end
|
594
607
|
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
608
|
+
it "matches when the content type include a charset" 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};charset=UTF-8"},
|
611
|
+
body: "<opt a=\"1\" b=\"five\">\n <c>\n <d>e</d>\n <d>f</d>\n </c>\n</opt>\n"))
|
612
|
+
|
613
|
+
end
|
614
|
+
end
|
615
|
+
|
616
|
+
context "standard application/xml" do
|
617
|
+
let(:content_type) { 'application/xml' }
|
618
|
+
it_behaves_like "a xml body"
|
619
|
+
end
|
599
620
|
|
621
|
+
context "custom xml content type" do
|
622
|
+
let(:content_type) { 'application/atom+xml' }
|
623
|
+
it_behaves_like "a xml body"
|
600
624
|
end
|
601
625
|
end
|
602
626
|
end
|
data/webmock.gemspec
CHANGED
@@ -45,6 +45,7 @@ Gem::Specification.new do |s|
|
|
45
45
|
s.add_development_dependency 'minitest', '>= 5.0.0'
|
46
46
|
s.add_development_dependency 'test-unit', '>= 3.0.0'
|
47
47
|
s.add_development_dependency 'rdoc', '> 3.5.0'
|
48
|
+
s.add_development_dependency 'webrick'
|
48
49
|
|
49
50
|
s.files = `git ls-files`.split("\n")
|
50
51
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: webmock
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.12.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bartosz Blimke
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-03-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|
@@ -254,6 +254,20 @@ dependencies:
|
|
254
254
|
- - ">"
|
255
255
|
- !ruby/object:Gem::Version
|
256
256
|
version: 3.5.0
|
257
|
+
- !ruby/object:Gem::Dependency
|
258
|
+
name: webrick
|
259
|
+
requirement: !ruby/object:Gem::Requirement
|
260
|
+
requirements:
|
261
|
+
- - ">="
|
262
|
+
- !ruby/object:Gem::Version
|
263
|
+
version: '0'
|
264
|
+
type: :development
|
265
|
+
prerelease: false
|
266
|
+
version_requirements: !ruby/object:Gem::Requirement
|
267
|
+
requirements:
|
268
|
+
- - ">="
|
269
|
+
- !ruby/object:Gem::Version
|
270
|
+
version: '0'
|
257
271
|
description: WebMock allows stubbing HTTP requests and setting expectations on HTTP
|
258
272
|
requests.
|
259
273
|
email:
|
@@ -263,6 +277,7 @@ extensions: []
|
|
263
277
|
extra_rdoc_files: []
|
264
278
|
files:
|
265
279
|
- ".gemtest"
|
280
|
+
- ".github/workflows/CI.yml"
|
266
281
|
- ".gitignore"
|
267
282
|
- ".rspec-tm"
|
268
283
|
- ".travis.yml"
|
@@ -407,9 +422,9 @@ licenses:
|
|
407
422
|
- MIT
|
408
423
|
metadata:
|
409
424
|
bug_tracker_uri: https://github.com/bblimke/webmock/issues
|
410
|
-
changelog_uri: https://github.com/bblimke/webmock/blob/v3.
|
411
|
-
documentation_uri: https://www.rubydoc.info/gems/webmock/3.
|
412
|
-
source_code_uri: https://github.com/bblimke/webmock/tree/v3.
|
425
|
+
changelog_uri: https://github.com/bblimke/webmock/blob/v3.12.2/CHANGELOG.md
|
426
|
+
documentation_uri: https://www.rubydoc.info/gems/webmock/3.12.2
|
427
|
+
source_code_uri: https://github.com/bblimke/webmock/tree/v3.12.2
|
413
428
|
wiki_uri: https://github.com/bblimke/webmock/wiki
|
414
429
|
post_install_message:
|
415
430
|
rdoc_options: []
|