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.
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