webmock 1.24.6 → 2.0.0.beta1

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.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +0 -9
  3. data/CHANGELOG.md +37 -8
  4. data/Gemfile +1 -5
  5. data/README.md +22 -51
  6. data/Rakefile +0 -23
  7. data/lib/webmock.rb +0 -12
  8. data/lib/webmock/cucumber.rb +2 -0
  9. data/lib/webmock/http_lib_adapters/curb_adapter.rb +9 -3
  10. data/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +220 -9
  11. data/lib/webmock/http_lib_adapters/excon_adapter.rb +2 -0
  12. data/lib/webmock/http_lib_adapters/http_rb/response.rb +1 -1
  13. data/lib/webmock/http_lib_adapters/httpclient_adapter.rb +0 -38
  14. data/lib/webmock/http_lib_adapters/manticore_adapter.rb +6 -2
  15. data/lib/webmock/http_lib_adapters/net_http.rb +2 -10
  16. data/lib/webmock/http_lib_adapters/patron_adapter.rb +7 -3
  17. data/lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb +6 -2
  18. data/lib/webmock/minitest.rb +2 -0
  19. data/lib/webmock/request_pattern.rb +16 -1
  20. data/lib/webmock/response.rb +0 -7
  21. data/lib/webmock/rspec.rb +2 -0
  22. data/lib/webmock/test_unit.rb +2 -0
  23. data/lib/webmock/util/headers.rb +4 -0
  24. data/lib/webmock/util/query_mapper.rb +1 -2
  25. data/lib/webmock/version.rb +1 -1
  26. data/lib/webmock/webmock.rb +0 -2
  27. data/spec/acceptance/curb/curb_spec_helper.rb +6 -3
  28. data/spec/acceptance/em_http_request/em_http_request_spec_helper.rb +4 -1
  29. data/spec/acceptance/excon/excon_spec_helper.rb +9 -3
  30. data/spec/acceptance/http_rb/http_rb_spec_helper.rb +7 -1
  31. data/spec/acceptance/httpclient/httpclient_spec_helper.rb +5 -2
  32. data/spec/acceptance/manticore/manticore_spec_helper.rb +5 -1
  33. data/spec/acceptance/net_http/net_http_spec.rb +2 -2
  34. data/spec/acceptance/net_http/net_http_spec_helper.rb +4 -1
  35. data/spec/acceptance/patron/patron_spec_helper.rb +6 -3
  36. data/spec/acceptance/shared/allowing_and_disabling_net_connect.rb +2 -2
  37. data/spec/acceptance/shared/request_expectations.rb +64 -7
  38. data/spec/acceptance/shared/stubbing_requests.rb +51 -1
  39. data/spec/acceptance/typhoeus/typhoeus_hydra_spec_helper.rb +11 -8
  40. data/spec/spec_helper.rb +0 -4
  41. data/spec/unit/request_pattern_spec.rb +1 -1
  42. data/spec/unit/util/query_mapper_spec.rb +0 -16
  43. data/webmock.gemspec +5 -7
  44. metadata +187 -236
  45. data/Appraisals +0 -3
  46. data/gemfiles/ruby_1_8.gemfile +0 -21
  47. data/lib/webmock/http_lib_adapters/em_http_request/em_http_request_0_x.rb +0 -147
  48. 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
@@ -33,7 +33,7 @@ module HTTP
33
33
  def normalize_uri(uri)
34
34
  return unless uri
35
35
 
36
- uri = Addressable::URI.parse uri
36
+ uri = URI.parse uri
37
37
  uri.port = nil if uri.default_port && uri.port == uri.default_port
38
38
 
39
39
  uri
@@ -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
- if request["authorization"] =~ /^Basic /
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.dup) < Gem::Version.new('2.3.0')
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 => req.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
- uri.user, uri.password = req.options[:userpwd].split(':')
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 => req.options[: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]
@@ -10,6 +10,8 @@ end
10
10
 
11
11
  require 'webmock'
12
12
 
13
+ WebMock.enable!
14
+
13
15
  test_class.class_eval do
14
16
  include WebMock::API
15
17
 
@@ -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)
@@ -1,12 +1,5 @@
1
1
  require "pathname"
2
2
 
3
- #compatibility with Ruby 1.9.2 preview1 to allow reading raw responses
4
- if RUBY_VERSION <= "1.9.2"
5
- class StringIO
6
- alias_method :read_nonblock, :sysread
7
- end
8
- end
9
-
10
3
  module WebMock
11
4
 
12
5
  class ResponseFactory
@@ -20,6 +20,8 @@ end
20
20
 
21
21
  require 'webmock/rspec/matchers'
22
22
 
23
+ WebMock.enable!
24
+
23
25
  RSPEC_CONFIGURER.configure { |config|
24
26
 
25
27
  config.include WebMock::API
@@ -1,6 +1,8 @@
1
1
  require 'test/unit'
2
2
  require 'webmock'
3
3
 
4
+ WebMock.enable!
5
+
4
6
  module Test
5
7
  module Unit
6
8
  class TestCase
@@ -36,6 +36,10 @@ module WebMock
36
36
  header.sub(/^Basic /, "").unpack("m").first
37
37
  end
38
38
 
39
+ def self.basic_auth_header(*credentials)
40
+ "Basic #{Base64.encode64(credentials.join(':')).chomp}"
41
+ end
42
+
39
43
  end
40
44
 
41
45
  end
@@ -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
@@ -1,3 +1,3 @@
1
1
  module WebMock
2
- VERSION = '1.24.6' unless defined?(::WebMock::VERSION)
2
+ VERSION = '2.0.0.beta1' unless defined?(::WebMock::VERSION)
3
3
  end
@@ -153,6 +153,4 @@ module WebMock
153
153
  end
154
154
  ))
155
155
  end
156
-
157
- self.enable!
158
156
  end
@@ -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.omit(:userinfo).to_s
34
- curl.username = uri.user
35
- curl.password = uri.password
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.merge('authorization' => [uri.user, uri.password])
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.omit(:userinfo).to_s.gsub(' ', '%20')
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, :nonblock => false).request(options, &block)
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
- response = HTTP.request(method, normalize_uri(uri), options)
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
- c.set_basic_auth(nil, uri.user, uri.password) if uri.user
11
- params = [method, "#{uri.omit(:userinfo, :query).normalize.to_s}",
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.dup) < Gem::Version.new('2.3.0')
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
- req.basic_auth uri.user, uri.password if uri.user
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