webmock 1.24.6 → 2.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.travis.yml +0 -9
- data/CHANGELOG.md +37 -8
- data/Gemfile +1 -5
- data/README.md +22 -51
- data/Rakefile +0 -23
- data/lib/webmock.rb +0 -12
- data/lib/webmock/cucumber.rb +2 -0
- data/lib/webmock/http_lib_adapters/curb_adapter.rb +9 -3
- data/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +220 -9
- data/lib/webmock/http_lib_adapters/excon_adapter.rb +2 -0
- data/lib/webmock/http_lib_adapters/http_rb/response.rb +1 -1
- data/lib/webmock/http_lib_adapters/httpclient_adapter.rb +0 -38
- data/lib/webmock/http_lib_adapters/manticore_adapter.rb +6 -2
- data/lib/webmock/http_lib_adapters/net_http.rb +2 -10
- data/lib/webmock/http_lib_adapters/patron_adapter.rb +7 -3
- data/lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb +6 -2
- data/lib/webmock/minitest.rb +2 -0
- data/lib/webmock/request_pattern.rb +16 -1
- data/lib/webmock/response.rb +0 -7
- data/lib/webmock/rspec.rb +2 -0
- data/lib/webmock/test_unit.rb +2 -0
- data/lib/webmock/util/headers.rb +4 -0
- data/lib/webmock/util/query_mapper.rb +1 -2
- data/lib/webmock/version.rb +1 -1
- data/lib/webmock/webmock.rb +0 -2
- data/spec/acceptance/curb/curb_spec_helper.rb +6 -3
- data/spec/acceptance/em_http_request/em_http_request_spec_helper.rb +4 -1
- data/spec/acceptance/excon/excon_spec_helper.rb +9 -3
- data/spec/acceptance/http_rb/http_rb_spec_helper.rb +7 -1
- data/spec/acceptance/httpclient/httpclient_spec_helper.rb +5 -2
- data/spec/acceptance/manticore/manticore_spec_helper.rb +5 -1
- data/spec/acceptance/net_http/net_http_spec.rb +2 -2
- data/spec/acceptance/net_http/net_http_spec_helper.rb +4 -1
- data/spec/acceptance/patron/patron_spec_helper.rb +6 -3
- data/spec/acceptance/shared/allowing_and_disabling_net_connect.rb +2 -2
- data/spec/acceptance/shared/request_expectations.rb +64 -7
- data/spec/acceptance/shared/stubbing_requests.rb +51 -1
- data/spec/acceptance/typhoeus/typhoeus_hydra_spec_helper.rb +11 -8
- data/spec/spec_helper.rb +0 -4
- data/spec/unit/request_pattern_spec.rb +1 -1
- data/spec/unit/util/query_mapper_spec.rb +0 -16
- data/webmock.gemspec +5 -7
- metadata +187 -236
- data/Appraisals +0 -3
- data/gemfiles/ruby_1_8.gemfile +0 -21
- data/lib/webmock/http_lib_adapters/em_http_request/em_http_request_0_x.rb +0 -147
- data/lib/webmock/http_lib_adapters/em_http_request/em_http_request_1_x.rb +0 -228
@@ -102,6 +102,8 @@ if defined?(Excon)
|
|
102
102
|
|
103
103
|
def self.build_request(params)
|
104
104
|
params = params.dup
|
105
|
+
params.delete(:user)
|
106
|
+
params.delete(:password)
|
105
107
|
method = (params.delete(:method) || :get).to_s.downcase.to_sym
|
106
108
|
params[:query] = to_query(params[:query]) if params[:query].is_a?(Hash)
|
107
109
|
uri = Addressable::URI.new(params).to_s
|
@@ -170,7 +170,6 @@ if defined?(::HTTPClient)
|
|
170
170
|
uri = WebMock::Util::URI.heuristic_parse(req.header.request_uri.to_s)
|
171
171
|
uri.query = WebMock::Util::QueryMapper.values_to_query(req.header.request_query, :notation => WebMock::Config.instance.query_values_notation) if req.header.request_query
|
172
172
|
uri.port = req.header.request_uri.port
|
173
|
-
uri = uri.omit(:userinfo)
|
174
173
|
|
175
174
|
@request_filter.each do |filter|
|
176
175
|
filter.filter_request(req)
|
@@ -183,11 +182,6 @@ if defined?(::HTTPClient)
|
|
183
182
|
end
|
184
183
|
headers = headers_from_session(uri).merge(headers)
|
185
184
|
|
186
|
-
if auth_cred = auth_cred_from_www_auth(req) || auth_cred_from_headers(headers)
|
187
|
-
remove_authorization_header headers
|
188
|
-
uri.userinfo = userinfo_from_auth_cred auth_cred
|
189
|
-
end
|
190
|
-
|
191
185
|
signature = WebMock::RequestSignature.new(
|
192
186
|
req.header.request_method.downcase.to_sym,
|
193
187
|
uri.to_s,
|
@@ -203,38 +197,6 @@ if defined?(::HTTPClient)
|
|
203
197
|
signature
|
204
198
|
end
|
205
199
|
|
206
|
-
def userinfo_from_auth_cred auth_cred
|
207
|
-
userinfo = WebMock::Util::Headers.decode_userinfo_from_header(auth_cred)
|
208
|
-
WebMock::Util::URI.encode_unsafe_chars_in_userinfo(userinfo)
|
209
|
-
end
|
210
|
-
|
211
|
-
def remove_authorization_header headers
|
212
|
-
headers.reject! do |name, value|
|
213
|
-
next unless name =~ /[Aa]uthorization/
|
214
|
-
if value.is_a? Array
|
215
|
-
value.reject! { |v| v =~ /^Basic / }
|
216
|
-
value.length == 0
|
217
|
-
elsif value.is_a? String
|
218
|
-
value =~ /^Basic /
|
219
|
-
end
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
def auth_cred_from_www_auth(req)
|
224
|
-
auth = www_auth.basic_auth
|
225
|
-
auth.challenge(req.header.request_uri, nil)
|
226
|
-
auth.get(req) if auth.scheme == 'Basic'
|
227
|
-
end
|
228
|
-
|
229
|
-
def auth_cred_from_headers(headers)
|
230
|
-
headers.each do |k,v|
|
231
|
-
next unless k =~ /[Aa]uthorization/
|
232
|
-
return v if v.is_a?(String) && v =~ /^Basic /
|
233
|
-
v.each { |v| return v if v =~ /^Basic / } if v.is_a? Array
|
234
|
-
end
|
235
|
-
nil
|
236
|
-
end
|
237
|
-
|
238
200
|
def webmock_responses
|
239
201
|
@webmock_responses ||= Hash.new do |hash, request_signature|
|
240
202
|
hash[request_signature] = WebMock::StubRegistry.instance.response_for_request(request_signature)
|
@@ -45,7 +45,7 @@ if defined?(Manticore)
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def response_object_for(request, context, &block)
|
48
|
-
request_signature = generate_webmock_request_signature(request)
|
48
|
+
request_signature = generate_webmock_request_signature(request, context)
|
49
49
|
WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)
|
50
50
|
|
51
51
|
if webmock_response = registered_response_for(request_signature)
|
@@ -74,12 +74,16 @@ if defined?(Manticore)
|
|
74
74
|
WebMock.net_connect_allowed?(uri)
|
75
75
|
end
|
76
76
|
|
77
|
-
def generate_webmock_request_signature(request)
|
77
|
+
def generate_webmock_request_signature(request, context)
|
78
78
|
method = request.method.downcase
|
79
79
|
uri = request.uri.to_s
|
80
80
|
body = read_body(request)
|
81
81
|
headers = split_array_values(request.headers)
|
82
82
|
|
83
|
+
if context.get_credentials_provider && credentials = context.get_credentials_provider.get_credentials(AuthScope::ANY)
|
84
|
+
headers['Authorization'] = WebMock::Util::Headers.basic_auth_header(credentials.get_user_name,credentials.get_password)
|
85
|
+
end
|
86
|
+
|
83
87
|
WebMock::RequestSignature.new(method, uri, {:body => body, :headers => headers})
|
84
88
|
end
|
85
89
|
|
@@ -275,19 +275,11 @@ module WebMock
|
|
275
275
|
|
276
276
|
path = WebMock::Util::URI.heuristic_parse(path).request_uri if path =~ /^http/
|
277
277
|
|
278
|
-
|
279
|
-
userinfo = WebMock::Util::Headers.decode_userinfo_from_header(request["authorization"])
|
280
|
-
userinfo = WebMock::Util::URI.encode_unsafe_chars_in_userinfo(userinfo) + "@"
|
281
|
-
else
|
282
|
-
userinfo = ""
|
283
|
-
end
|
284
|
-
|
285
|
-
uri = "#{protocol}://#{userinfo}#{net_http.address}:#{net_http.port}#{path}"
|
278
|
+
uri = "#{protocol}://#{net_http.address}:#{net_http.port}#{path}"
|
286
279
|
method = request.method.downcase.to_sym
|
287
280
|
|
288
281
|
headers = Hash[*request.to_hash.map {|k,v| [k, v]}.inject([]) {|r,x| r + x}]
|
289
282
|
validate_headers(headers)
|
290
|
-
headers.reject! {|k,v| k =~ /[Aa]uthorization/ && v.first =~ /^Basic / } #we added it to url userinfo
|
291
283
|
|
292
284
|
if request.body_stream
|
293
285
|
body = request.body_stream.read
|
@@ -314,7 +306,7 @@ module WebMock
|
|
314
306
|
#
|
315
307
|
# So before this point, WebMock raises an ArgumentError if any of the headers are symbols
|
316
308
|
# instead of the cryptic NoMethodError "undefined method `split' ...` from Net::HTTP
|
317
|
-
if Gem::Version.new(RUBY_VERSION
|
309
|
+
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.3.0')
|
318
310
|
header_as_symbol = headers.keys.find {|header| header.is_a? Symbol}
|
319
311
|
if header_as_symbol
|
320
312
|
raise ArgumentError.new("Net:HTTP does not accept headers as symbols")
|
@@ -68,8 +68,6 @@ if defined?(::Patron)
|
|
68
68
|
def self.build_request_signature(req)
|
69
69
|
uri = WebMock::Util::URI.heuristic_parse(req.url)
|
70
70
|
uri.path = uri.normalized_path.gsub("[^:]//","/")
|
71
|
-
uri.user = req.username
|
72
|
-
uri.password = req.password
|
73
71
|
|
74
72
|
if [:put, :post].include?(req.action)
|
75
73
|
if req.file_name
|
@@ -84,11 +82,17 @@ if defined?(::Patron)
|
|
84
82
|
end
|
85
83
|
end
|
86
84
|
|
85
|
+
headers = req.headers
|
86
|
+
|
87
|
+
if req.credentials
|
88
|
+
headers['Authorization'] = WebMock::Util::Headers.basic_auth_header(req.credentials)
|
89
|
+
end
|
90
|
+
|
87
91
|
request_signature = WebMock::RequestSignature.new(
|
88
92
|
req.action,
|
89
93
|
uri.to_s,
|
90
94
|
:body => request_body,
|
91
|
-
:headers =>
|
95
|
+
:headers => headers
|
92
96
|
)
|
93
97
|
request_signature
|
94
98
|
end
|
@@ -53,8 +53,11 @@ if defined?(Typhoeus)
|
|
53
53
|
def self.build_request_signature(req)
|
54
54
|
uri = WebMock::Util::URI.heuristic_parse(req.url)
|
55
55
|
uri.path = uri.normalized_path.gsub("[^:]//","/")
|
56
|
+
|
57
|
+
headers = req.options[:headers]
|
58
|
+
|
56
59
|
if req.options[:userpwd]
|
57
|
-
|
60
|
+
headers['Authorization'] = WebMock::Util::Headers.basic_auth_header(req.options[:userpwd])
|
58
61
|
end
|
59
62
|
|
60
63
|
body = req.options[:body]
|
@@ -67,7 +70,7 @@ if defined?(Typhoeus)
|
|
67
70
|
req.options[:method] || :get,
|
68
71
|
uri.to_s,
|
69
72
|
:body => body,
|
70
|
-
:headers =>
|
73
|
+
:headers => headers
|
71
74
|
)
|
72
75
|
|
73
76
|
req.instance_variable_set(:@__webmock_request_signature, request_signature)
|
@@ -75,6 +78,7 @@ if defined?(Typhoeus)
|
|
75
78
|
request_signature
|
76
79
|
end
|
77
80
|
|
81
|
+
|
78
82
|
def self.build_webmock_response(typhoeus_response)
|
79
83
|
webmock_response = WebMock::Response.new
|
80
84
|
webmock_response.status = [typhoeus_response.code, typhoeus_response.status_message]
|
data/lib/webmock/minitest.rb
CHANGED
@@ -50,12 +50,27 @@ module WebMock
|
|
50
50
|
|
51
51
|
def assign_options(options)
|
52
52
|
options = WebMock::Util::HashKeysStringifier.stringify_keys!(options, :deep => true)
|
53
|
-
HashValidator.new(options).validate_keys('body', 'headers', 'query')
|
53
|
+
HashValidator.new(options).validate_keys('body', 'headers', 'query', 'basic_auth')
|
54
|
+
set_basic_auth_as_headers!(options)
|
54
55
|
@body_pattern = BodyPattern.new(options['body']) if options.has_key?('body')
|
55
56
|
@headers_pattern = HeadersPattern.new(options['headers']) if options.has_key?('headers')
|
56
57
|
@uri_pattern.add_query_params(options['query']) if options.has_key?('query')
|
57
58
|
end
|
58
59
|
|
60
|
+
def set_basic_auth_as_headers!(options)
|
61
|
+
if basic_auth = options.delete('basic_auth')
|
62
|
+
validate_basic_auth!(basic_auth)
|
63
|
+
options['headers'] ||= {}
|
64
|
+
options['headers']['Authorization'] = WebMock::Util::Headers.basic_auth_header(basic_auth[0],basic_auth[1])
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def validate_basic_auth!(basic_auth)
|
69
|
+
if !basic_auth.is_a?(Array) || basic_auth.map{|e| e.is_a?(String)}.uniq != [true]
|
70
|
+
raise "The basic_auth option value should be an array which contains 2 strings: username and password"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
59
74
|
def create_uri_pattern(uri)
|
60
75
|
if uri.is_a?(Regexp)
|
61
76
|
URIRegexpPattern.new(uri)
|
data/lib/webmock/response.rb
CHANGED
data/lib/webmock/rspec.rb
CHANGED
data/lib/webmock/test_unit.rb
CHANGED
data/lib/webmock/util/headers.rb
CHANGED
@@ -146,7 +146,6 @@ module WebMock::Util
|
|
146
146
|
last_container = current_node.select { |n| n.is_a?(Hash) }.last
|
147
147
|
if last_container && !last_container.has_key?(last_key)
|
148
148
|
if array_value
|
149
|
-
last_container[last_key] ||= []
|
150
149
|
last_container[last_key] << value
|
151
150
|
else
|
152
151
|
last_container[last_key] = value
|
@@ -160,7 +159,7 @@ module WebMock::Util
|
|
160
159
|
end
|
161
160
|
else
|
162
161
|
if array_value
|
163
|
-
current_node[last_key]
|
162
|
+
current_node[last_key] = [] unless current_node[last_key]
|
164
163
|
current_node[last_key] << value
|
165
164
|
else
|
166
165
|
current_node[last_key] = value
|
data/lib/webmock/version.rb
CHANGED
data/lib/webmock/webmock.rb
CHANGED
@@ -30,9 +30,12 @@ module CurbSpecHelper
|
|
30
30
|
|
31
31
|
def setup_request(uri, curl, options={})
|
32
32
|
curl ||= Curl::Easy.new
|
33
|
-
curl.url = uri.
|
34
|
-
|
35
|
-
|
33
|
+
curl.url = uri.to_s
|
34
|
+
if options[:basic_auth]
|
35
|
+
curl.http_auth_types = :basic
|
36
|
+
curl.username = options[:basic_auth][0]
|
37
|
+
curl.password = options[:basic_auth][1]
|
38
|
+
end
|
36
39
|
curl.timeout = 30
|
37
40
|
curl.connect_timeout = 30
|
38
41
|
|
@@ -8,6 +8,9 @@ module EMHttpRequestSpecHelper
|
|
8
8
|
def http_request(method, uri, options = {}, &block)
|
9
9
|
@http = nil
|
10
10
|
head = options[:headers] || {}
|
11
|
+
if options[:basic_auth]
|
12
|
+
head.merge!('authorization' => options[:basic_auth])
|
13
|
+
end
|
11
14
|
response = nil
|
12
15
|
error = nil
|
13
16
|
error_set = false
|
@@ -19,7 +22,7 @@ module EMHttpRequestSpecHelper
|
|
19
22
|
:body => options[:body],
|
20
23
|
:file => options[:file],
|
21
24
|
:query => options[:query],
|
22
|
-
:head => head
|
25
|
+
:head => head
|
23
26
|
}, &block)
|
24
27
|
http.errback {
|
25
28
|
error_set = true
|
@@ -5,14 +5,20 @@ module ExconSpecHelper
|
|
5
5
|
def http_request(method, uri, options = {}, &block)
|
6
6
|
Excon.defaults[:ssl_verify_peer] = false
|
7
7
|
uri = Addressable::URI.heuristic_parse(uri)
|
8
|
-
uri = uri.
|
8
|
+
uri = uri.to_s.gsub(' ', '%20')
|
9
|
+
|
10
|
+
excon_options = {}
|
11
|
+
|
12
|
+
if basic_auth = options.delete(:basic_auth)
|
13
|
+
excon_options = {user: basic_auth[0], password: basic_auth[1]}
|
14
|
+
end
|
9
15
|
|
10
16
|
if Gem::Version.new(Excon::VERSION) < Gem::Version.new("0.29.0")
|
11
17
|
options = options.merge(:method => method, :nonblock => false) # Dup and merge
|
12
|
-
response = Excon.new(uri).request(options, &block)
|
18
|
+
response = Excon.new(uri, excon_options).request(options, &block)
|
13
19
|
else
|
14
20
|
options = options.merge(:method => method) # Dup and merge
|
15
|
-
response = Excon.new(uri, :
|
21
|
+
response = Excon.new(uri, excon_options.merge(nonblock: false)).request(options, &block)
|
16
22
|
end
|
17
23
|
|
18
24
|
headers = WebMock::Util::Headers.normalize_headers(response.headers)
|
@@ -2,7 +2,13 @@ require "ostruct"
|
|
2
2
|
|
3
3
|
module HttpRbSpecHelper
|
4
4
|
def http_request(method, uri, options = {})
|
5
|
-
|
5
|
+
chain = HTTP
|
6
|
+
|
7
|
+
if basic_auth = options.delete(:basic_auth)
|
8
|
+
chain = chain.basic_auth(user: basic_auth[0], pass: basic_auth[1])
|
9
|
+
end
|
10
|
+
|
11
|
+
response = chain.request(method, normalize_uri(uri), options)
|
6
12
|
|
7
13
|
OpenStruct.new({
|
8
14
|
:body => response.body.to_s,
|
@@ -7,8 +7,11 @@ module HTTPClientSpecHelper
|
|
7
7
|
uri = Addressable::URI.heuristic_parse(uri)
|
8
8
|
c = options.fetch(:client) { HTTPClient.new }
|
9
9
|
c.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
10
|
-
|
11
|
-
|
10
|
+
if options[:basic_auth]
|
11
|
+
c.force_basic_auth = true
|
12
|
+
c.set_basic_auth(nil, options[:basic_auth][0], options[:basic_auth][1])
|
13
|
+
end
|
14
|
+
params = [method, uri.normalize.to_s,
|
12
15
|
WebMock::Util::QueryMapper.query_to_values(uri.query, :notation => WebMock::Config.instance.query_values_notation), options[:body], options[:headers] || {}]
|
13
16
|
if HTTPClientSpecHelper.async_mode
|
14
17
|
connection = c.request_async(*params)
|
@@ -1,8 +1,12 @@
|
|
1
1
|
module ManticoreSpecHelper
|
2
2
|
def http_request(method, uri, options = {})
|
3
3
|
client = Manticore::Client.new
|
4
|
-
response = client.http(method, uri, options)
|
5
4
|
|
5
|
+
if basic_auth = options[:basic_auth]
|
6
|
+
options = options.merge(auth: {user: basic_auth[0], pass: basic_auth[1]})
|
7
|
+
end
|
8
|
+
|
9
|
+
response = client.http(method, uri, options)
|
6
10
|
OpenStruct.new({
|
7
11
|
:body => response.body || '',
|
8
12
|
:headers => WebMock::Util::Headers.normalize_headers(join_array_values(response.headers)),
|
@@ -7,7 +7,7 @@ require 'acceptance/net_http/net_http_shared'
|
|
7
7
|
include NetHTTPSpecHelper
|
8
8
|
|
9
9
|
describe "Net:HTTP" do
|
10
|
-
include_examples "with WebMock"
|
10
|
+
include_examples "with WebMock", :no_url_auth
|
11
11
|
|
12
12
|
let(:port) { WebMockServer.instance.port }
|
13
13
|
|
@@ -132,7 +132,7 @@ describe "Net:HTTP" do
|
|
132
132
|
end
|
133
133
|
end
|
134
134
|
|
135
|
-
if Gem::Version.new(RUBY_VERSION
|
135
|
+
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.3.0')
|
136
136
|
expect do
|
137
137
|
http.request(request)
|
138
138
|
end.to raise_error ArgumentError, "Net:HTTP does not accept headers as symbols"
|
@@ -18,7 +18,10 @@ module NetHTTPSpecHelper
|
|
18
18
|
end
|
19
19
|
end if options[:headers]
|
20
20
|
|
21
|
-
|
21
|
+
if options[:basic_auth]
|
22
|
+
req.basic_auth(options[:basic_auth][0], options[:basic_auth][1])
|
23
|
+
end
|
24
|
+
|
22
25
|
http = Net::HTTP.new(uri.host, uri.port)
|
23
26
|
if uri.scheme == "https"
|
24
27
|
http.use_ssl = true
|