rack-test 1.0.0 → 2.0.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 +4 -4
- data/History.md +100 -0
- data/MIT-LICENSE.txt +1 -0
- data/README.md +53 -62
- data/lib/rack/mock_session.rb +2 -63
- data/lib/rack/test/cookie_jar.rb +101 -49
- data/lib/rack/test/methods.rb +57 -45
- data/lib/rack/test/mock_digest_request.rb +11 -1
- data/lib/rack/test/uploaded_file.rb +35 -11
- data/lib/rack/test/utils.rb +78 -61
- data/lib/rack/test/version.rb +1 -1
- data/lib/rack/test.rb +231 -144
- metadata +27 -96
data/lib/rack/test.rb
CHANGED
|
@@ -1,23 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'uri'
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
require
|
|
6
|
-
|
|
7
|
-
require
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
|
|
5
|
+
# :nocov:
|
|
6
|
+
begin
|
|
7
|
+
require "rack/version"
|
|
8
|
+
rescue LoadError
|
|
9
|
+
require "rack"
|
|
10
|
+
else
|
|
11
|
+
if Rack.release >= '2.3'
|
|
12
|
+
require "rack/request"
|
|
13
|
+
require "rack/mock"
|
|
14
|
+
require "rack/utils"
|
|
15
|
+
else
|
|
16
|
+
require "rack"
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
# :nocov:
|
|
20
|
+
|
|
21
|
+
require 'forwardable'
|
|
22
|
+
|
|
23
|
+
require_relative 'test/cookie_jar'
|
|
24
|
+
require_relative 'test/utils'
|
|
25
|
+
require_relative 'test/methods'
|
|
26
|
+
require_relative 'test/uploaded_file'
|
|
27
|
+
require_relative 'test/version'
|
|
10
28
|
|
|
11
29
|
module Rack
|
|
12
30
|
module Test
|
|
31
|
+
# The default host to use for requests, when a full URI is not
|
|
32
|
+
# provided.
|
|
13
33
|
DEFAULT_HOST = 'example.org'.freeze
|
|
34
|
+
|
|
35
|
+
# The default multipart boundary to use for multipart request bodies
|
|
14
36
|
MULTIPART_BOUNDARY = '----------XnJLe9ZIbbGUYtzPQJ16u1'.freeze
|
|
15
37
|
|
|
38
|
+
# The starting boundary in multipart requests
|
|
39
|
+
START_BOUNDARY = "--#{MULTIPART_BOUNDARY}\r\n".freeze
|
|
40
|
+
|
|
41
|
+
# The ending boundary in multipart requests
|
|
42
|
+
END_BOUNDARY = "--#{MULTIPART_BOUNDARY}--\r\n".freeze
|
|
43
|
+
|
|
16
44
|
# The common base class for exceptions raised by Rack::Test
|
|
17
45
|
class Error < StandardError; end
|
|
18
46
|
|
|
19
|
-
#
|
|
20
|
-
#
|
|
47
|
+
# Rack::Test::Session handles a series of requests issued to a Rack app.
|
|
48
|
+
# It keeps track of the cookies for the session, and allows for setting headers
|
|
49
|
+
# and a default rack environment that is used for future requests.
|
|
21
50
|
#
|
|
22
51
|
# Rack::Test::Session's methods are most often called through Rack::Test::Methods,
|
|
23
52
|
# which will automatically build a session when it's first used.
|
|
@@ -25,93 +54,100 @@ module Rack
|
|
|
25
54
|
extend Forwardable
|
|
26
55
|
include Rack::Test::Utils
|
|
27
56
|
|
|
28
|
-
|
|
57
|
+
def self.new(app, default_host = DEFAULT_HOST) # :nodoc:
|
|
58
|
+
if app.is_a?(self)
|
|
59
|
+
# Backwards compatibility for initializing with Rack::MockSession
|
|
60
|
+
app
|
|
61
|
+
else
|
|
62
|
+
super
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# The Rack::Test::CookieJar for the cookies for the current session.
|
|
67
|
+
attr_accessor :cookie_jar
|
|
68
|
+
|
|
69
|
+
# The default host used for the session for when using paths for URIs.
|
|
70
|
+
attr_reader :default_host
|
|
29
71
|
|
|
30
|
-
# Creates a Rack::Test::Session for a given Rack app or Rack::
|
|
72
|
+
# Creates a Rack::Test::Session for a given Rack app or Rack::Test::BasicSession.
|
|
31
73
|
#
|
|
32
74
|
# Note: Generally, you won't need to initialize a Rack::Test::Session directly.
|
|
33
75
|
# Instead, you should include Rack::Test::Methods into your testing context.
|
|
34
76
|
# (See README.rdoc for an example)
|
|
35
|
-
|
|
36
|
-
|
|
77
|
+
#
|
|
78
|
+
# The following methods are defined via metaprogramming: get, post, put, patch,
|
|
79
|
+
# delete, options, and head. Each method submits a request with the given request
|
|
80
|
+
# method, with the given URI and optional parameters and rack environment.
|
|
81
|
+
# Examples:
|
|
82
|
+
#
|
|
83
|
+
# # URI only:
|
|
84
|
+
# get("/") # GET /
|
|
85
|
+
# get("/?foo=bar") # GET /?foo=bar
|
|
86
|
+
#
|
|
87
|
+
# # URI and parameters
|
|
88
|
+
# get("/foo", 'bar'=>'baz') # GET /foo?bar=baz
|
|
89
|
+
# post("/foo", 'bar'=>'baz') # POST /foo (bar=baz in request body)
|
|
90
|
+
#
|
|
91
|
+
# # URI, parameters, and rack environment
|
|
92
|
+
# get("/bar", {}, 'CONTENT_TYPE'=>'foo')
|
|
93
|
+
# get("/bar", {'foo'=>'baz'}, 'HTTP_ACCEPT'=>'*')
|
|
94
|
+
#
|
|
95
|
+
# The above methods as well as #request and #custom_request store the Rack::Request
|
|
96
|
+
# submitted in #last_request. The methods store a Rack::MockResponse based on the
|
|
97
|
+
# response in #last_response. #last_response is also returned by the methods.
|
|
98
|
+
# If a block is given, #last_response is also yielded to the block.
|
|
99
|
+
def initialize(app, default_host = DEFAULT_HOST)
|
|
37
100
|
@env = {}
|
|
38
101
|
@digest_username = nil
|
|
39
102
|
@digest_password = nil
|
|
40
|
-
|
|
41
|
-
@
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
@default_host = @rack_mock_session.default_host
|
|
103
|
+
@app = app
|
|
104
|
+
@after_request = []
|
|
105
|
+
@default_host = default_host
|
|
106
|
+
@last_request = nil
|
|
107
|
+
@last_response = nil
|
|
108
|
+
clear_cookies
|
|
48
109
|
end
|
|
49
110
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
# get "/"
|
|
57
|
-
def get(uri, params = {}, env = {}, &block)
|
|
58
|
-
custom_request('GET', uri, params, env, &block)
|
|
111
|
+
%w[get post put patch delete options head].each do |method_name|
|
|
112
|
+
class_eval(<<-END, __FILE__, __LINE__+1)
|
|
113
|
+
def #{method_name}(uri, params = {}, env = {}, &block)
|
|
114
|
+
custom_request('#{method_name.upcase}', uri, params, env, &block)
|
|
115
|
+
end
|
|
116
|
+
END
|
|
59
117
|
end
|
|
60
118
|
|
|
61
|
-
#
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
# post "/signup", "name" => "Bryan"
|
|
65
|
-
def post(uri, params = {}, env = {}, &block)
|
|
66
|
-
custom_request('POST', uri, params, env, &block)
|
|
119
|
+
# Run a block after the each request completes.
|
|
120
|
+
def after_request(&block)
|
|
121
|
+
@after_request << block
|
|
67
122
|
end
|
|
68
123
|
|
|
69
|
-
#
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
# put "/"
|
|
73
|
-
def put(uri, params = {}, env = {}, &block)
|
|
74
|
-
custom_request('PUT', uri, params, env, &block)
|
|
124
|
+
# Replace the current cookie jar with an empty cookie jar.
|
|
125
|
+
def clear_cookies
|
|
126
|
+
@cookie_jar = CookieJar.new([], @default_host)
|
|
75
127
|
end
|
|
76
128
|
|
|
77
|
-
#
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
# patch "/"
|
|
81
|
-
def patch(uri, params = {}, env = {}, &block)
|
|
82
|
-
custom_request('PATCH', uri, params, env, &block)
|
|
129
|
+
# Set a cookie in the current cookie jar.
|
|
130
|
+
def set_cookie(cookie, uri = nil)
|
|
131
|
+
cookie_jar.merge(cookie, uri)
|
|
83
132
|
end
|
|
84
133
|
|
|
85
|
-
#
|
|
86
|
-
#
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
custom_request('DELETE', uri, params, env, &block)
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
# Issue an OPTIONS request for the given URI. See #get
|
|
94
|
-
#
|
|
95
|
-
# Example:
|
|
96
|
-
# options "/"
|
|
97
|
-
def options(uri, params = {}, env = {}, &block)
|
|
98
|
-
custom_request('OPTIONS', uri, params, env, &block)
|
|
134
|
+
# Return the last request issued in the session. Raises an error if no
|
|
135
|
+
# requests have been sent yet.
|
|
136
|
+
def last_request
|
|
137
|
+
raise Error, 'No request yet. Request a page first.' unless @last_request
|
|
138
|
+
@last_request
|
|
99
139
|
end
|
|
100
140
|
|
|
101
|
-
#
|
|
102
|
-
#
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
custom_request('HEAD', uri, params, env, &block)
|
|
141
|
+
# Return the last response received in the session. Raises an error if
|
|
142
|
+
# no requests have been sent yet.
|
|
143
|
+
def last_response
|
|
144
|
+
raise Error, 'No response yet. Request a page first.' unless @last_response
|
|
145
|
+
@last_response
|
|
107
146
|
end
|
|
108
147
|
|
|
109
148
|
# Issue a request to the Rack app for the given URI and optional Rack
|
|
110
|
-
# environment.
|
|
111
|
-
# the app's response in #last_response. Yield #last_response to a block
|
|
112
|
-
# if given.
|
|
149
|
+
# environment. Example:
|
|
113
150
|
#
|
|
114
|
-
# Example:
|
|
115
151
|
# request "/"
|
|
116
152
|
def request(uri, env = {}, &block)
|
|
117
153
|
uri = parse_uri(uri, env)
|
|
@@ -119,9 +155,9 @@ module Rack
|
|
|
119
155
|
process_request(uri, env, &block)
|
|
120
156
|
end
|
|
121
157
|
|
|
122
|
-
# Issue a request using the given verb for the given URI
|
|
158
|
+
# Issue a request using the given HTTP verb for the given URI, with optional
|
|
159
|
+
# params and rack environment. Example:
|
|
123
160
|
#
|
|
124
|
-
# Example:
|
|
125
161
|
# custom_request "LINK", "/"
|
|
126
162
|
def custom_request(verb, uri, params = {}, env = {}, &block)
|
|
127
163
|
uri = parse_uri(uri, env)
|
|
@@ -133,22 +169,20 @@ module Rack
|
|
|
133
169
|
# session. Use a value of nil to remove a previously configured header.
|
|
134
170
|
#
|
|
135
171
|
# In accordance with the Rack spec, headers will be included in the Rack
|
|
136
|
-
# environment hash in HTTP_USER_AGENT form.
|
|
172
|
+
# environment hash in HTTP_USER_AGENT form. Example:
|
|
137
173
|
#
|
|
138
|
-
#
|
|
139
|
-
# header "User-Agent", "Firefox"
|
|
174
|
+
# header "user-agent", "Firefox"
|
|
140
175
|
def header(name, value)
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
end
|
|
176
|
+
name = name.upcase
|
|
177
|
+
name.tr!('-', '_')
|
|
178
|
+
name = "HTTP_#{name}" unless name == 'CONTENT_TYPE' || name == 'CONTENT_LENGTH'
|
|
179
|
+
env(name, value)
|
|
146
180
|
end
|
|
147
181
|
|
|
148
|
-
# Set an
|
|
149
|
-
# session. Use a value of nil to remove a previously
|
|
182
|
+
# Set an entry in the rack environment to be included on all subsequent
|
|
183
|
+
# requests through the session. Use a value of nil to remove a previously
|
|
184
|
+
# value. Example:
|
|
150
185
|
#
|
|
151
|
-
# Example:
|
|
152
186
|
# env "rack.session", {:csrf => 'token'}
|
|
153
187
|
def env(name, value)
|
|
154
188
|
if value.nil?
|
|
@@ -172,10 +206,15 @@ module Rack
|
|
|
172
206
|
|
|
173
207
|
# Set the username and password for HTTP Digest authorization, to be
|
|
174
208
|
# included in subsequent requests in the HTTP_AUTHORIZATION header.
|
|
209
|
+
# This method is deprecated and will be removed in rack-test 2.1
|
|
175
210
|
#
|
|
176
211
|
# Example:
|
|
177
212
|
# digest_authorize "bryan", "secret"
|
|
178
213
|
def digest_authorize(username, password)
|
|
214
|
+
warn 'digest authentication support will be removed in rack-test 2.1', uplevel: 1
|
|
215
|
+
_digest_authorize(username, password)
|
|
216
|
+
end
|
|
217
|
+
def _digest_authorize(username, password) # :nodoc:
|
|
179
218
|
@digest_username = username
|
|
180
219
|
@digest_password = password
|
|
181
220
|
end
|
|
@@ -188,81 +227,147 @@ module Rack
|
|
|
188
227
|
unless last_response.redirect?
|
|
189
228
|
raise Error, 'Last response was not a redirect. Cannot follow_redirect!'
|
|
190
229
|
end
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
230
|
+
|
|
231
|
+
if last_response.status == 307
|
|
232
|
+
request_method = last_request.request_method
|
|
233
|
+
params = last_request.params
|
|
234
|
+
else
|
|
235
|
+
request_method = 'GET'
|
|
236
|
+
params = {}
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
# Compute the next location by appending the location header with the
|
|
240
|
+
# last request, as per https://tools.ietf.org/html/rfc7231#section-7.1.2
|
|
241
|
+
# Adding two absolute locations returns the right-hand location
|
|
242
|
+
next_location = URI.parse(last_request.url) + URI.parse(last_response['Location'])
|
|
243
|
+
|
|
244
|
+
custom_request(
|
|
245
|
+
request_method,
|
|
246
|
+
next_location.to_s,
|
|
247
|
+
params,
|
|
199
248
|
'HTTP_REFERER' => last_request.url,
|
|
200
|
-
'rack.session' => last_request.session
|
|
249
|
+
'rack.session' => last_request.session,
|
|
250
|
+
'rack.session.options' => last_request.session_options
|
|
201
251
|
)
|
|
202
252
|
end
|
|
203
253
|
|
|
204
254
|
private
|
|
205
255
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
256
|
+
# :nocov:
|
|
257
|
+
if !defined?(Rack::RELEASE) || Gem::Version.new(Rack::RELEASE) < Gem::Version.new('2.2.2')
|
|
258
|
+
def close_body(body)
|
|
259
|
+
body.close if body.respond_to?(:close)
|
|
260
|
+
end
|
|
261
|
+
# :nocov:
|
|
262
|
+
else
|
|
263
|
+
# close() gets called automatically in newer Rack versions.
|
|
264
|
+
def close_body(body)
|
|
211
265
|
end
|
|
212
266
|
end
|
|
213
267
|
|
|
268
|
+
# Normalize URI based on given URI/path and environment.
|
|
269
|
+
def parse_uri(path, env)
|
|
270
|
+
uri = URI.parse(path)
|
|
271
|
+
uri.path = "/#{uri.path}" unless uri.path.start_with?('/')
|
|
272
|
+
uri.host ||= @default_host
|
|
273
|
+
uri.scheme ||= 'https' if env['HTTPS'] == 'on'
|
|
274
|
+
uri
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
DEFAULT_ENV = {
|
|
278
|
+
'rack.test' => true,
|
|
279
|
+
'REMOTE_ADDR' => '127.0.0.1',
|
|
280
|
+
'SERVER_PROTOCOL' => 'HTTP/1.0',
|
|
281
|
+
}
|
|
282
|
+
# :nocov:
|
|
283
|
+
unless Rack.release >= '2.3'
|
|
284
|
+
DEFAULT_ENV['HTTP_VERSION'] = DEFAULT_ENV['SERVER_PROTOCOL']
|
|
285
|
+
end
|
|
286
|
+
# :nocov:
|
|
287
|
+
DEFAULT_ENV.freeze
|
|
288
|
+
private_constant :DEFAULT_ENV
|
|
289
|
+
|
|
290
|
+
# Update environment to use based on given URI.
|
|
214
291
|
def env_for(uri, env)
|
|
215
|
-
env =
|
|
292
|
+
env = DEFAULT_ENV.merge(@env).merge!(env)
|
|
216
293
|
|
|
217
294
|
env['HTTP_HOST'] ||= [uri.host, (uri.port if uri.port != uri.default_port)].compact.join(':')
|
|
218
|
-
|
|
219
|
-
env.update('HTTPS' => 'on') if URI::HTTPS === uri
|
|
295
|
+
env['HTTPS'] = 'on' if URI::HTTPS === uri
|
|
220
296
|
env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest' if env[:xhr]
|
|
221
|
-
|
|
222
|
-
# TODO: Remove this after Rack 1.1 has been released.
|
|
223
|
-
# Stringifying and upcasing methods has be commit upstream
|
|
224
297
|
env['REQUEST_METHOD'] ||= env[:method] ? env[:method].to_s.upcase : 'GET'
|
|
225
298
|
|
|
226
|
-
params = env.delete(:params)
|
|
299
|
+
params = env.delete(:params)
|
|
300
|
+
query_array = [uri.query]
|
|
227
301
|
|
|
228
302
|
if env['REQUEST_METHOD'] == 'GET'
|
|
229
|
-
#
|
|
303
|
+
# Treat params as query params
|
|
230
304
|
if params
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
uri.query = [uri.query, build_nested_query(params)].compact.reject { |v| v == '' }.join('&')
|
|
305
|
+
append_query_params(query_array, params)
|
|
234
306
|
end
|
|
235
307
|
elsif !env.key?(:input)
|
|
236
308
|
env['CONTENT_TYPE'] ||= 'application/x-www-form-urlencoded'
|
|
309
|
+
params ||= {}
|
|
310
|
+
multipart = env.has_key?(:multipart) ? env.delete(:multipart) : env['CONTENT_TYPE'].start_with?('multipart/')
|
|
237
311
|
|
|
238
312
|
if params.is_a?(Hash)
|
|
239
|
-
if data = build_multipart(params)
|
|
313
|
+
if data = build_multipart(params, false, multipart)
|
|
240
314
|
env[:input] = data
|
|
241
315
|
env['CONTENT_LENGTH'] ||= data.length.to_s
|
|
242
|
-
env['CONTENT_TYPE'] = "
|
|
316
|
+
env['CONTENT_TYPE'] = "#{multipart_content_type(env)}; boundary=#{MULTIPART_BOUNDARY}"
|
|
243
317
|
else
|
|
244
|
-
|
|
245
|
-
# Rack::ContentLength will determine it automatically.
|
|
246
|
-
env[:input] = params_to_string(params)
|
|
318
|
+
env[:input] = build_nested_query(params)
|
|
247
319
|
end
|
|
248
320
|
else
|
|
249
321
|
env[:input] = params
|
|
250
322
|
end
|
|
251
323
|
end
|
|
252
324
|
|
|
325
|
+
if query_params = env.delete(:query_params)
|
|
326
|
+
append_query_params(query_array, query_params)
|
|
327
|
+
end
|
|
328
|
+
query_array.compact!
|
|
329
|
+
query_array.reject!(&:empty?)
|
|
330
|
+
uri.query = query_array.join('&')
|
|
331
|
+
|
|
253
332
|
set_cookie(env.delete(:cookie), uri) if env.key?(:cookie)
|
|
254
333
|
|
|
255
334
|
Rack::MockRequest.env_for(uri.to_s, env)
|
|
256
335
|
end
|
|
257
336
|
|
|
337
|
+
# Append a string version of the query params to the array of query params.
|
|
338
|
+
def append_query_params(query_array, query_params)
|
|
339
|
+
query_params = parse_nested_query(query_params) if query_params.is_a?(String)
|
|
340
|
+
query_array << build_nested_query(query_params)
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
# Return the multipart content type to use based on the environment.
|
|
344
|
+
def multipart_content_type(env)
|
|
345
|
+
requested_content_type = env['CONTENT_TYPE']
|
|
346
|
+
if requested_content_type.start_with?('multipart/')
|
|
347
|
+
requested_content_type
|
|
348
|
+
else
|
|
349
|
+
'multipart/form-data'
|
|
350
|
+
end
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
# Submit the request with the given URI and rack environment to
|
|
354
|
+
# the mock session. Returns and potentially yields the last response.
|
|
258
355
|
def process_request(uri, env)
|
|
259
|
-
|
|
356
|
+
env['HTTP_COOKIE'] ||= cookie_jar.for(uri)
|
|
357
|
+
@last_request = Rack::Request.new(env)
|
|
358
|
+
status, headers, body = @app.call(env).to_a
|
|
359
|
+
|
|
360
|
+
@last_response = MockResponse.new(status, headers, body, env['rack.errors'].flush)
|
|
361
|
+
close_body(body)
|
|
362
|
+
cookie_jar.merge(last_response.headers['set-cookie'], uri)
|
|
363
|
+
@after_request.each(&:call)
|
|
364
|
+
@last_response.finish
|
|
260
365
|
|
|
261
366
|
if retry_with_digest_auth?(env)
|
|
262
367
|
auth_env = env.merge('HTTP_AUTHORIZATION' => digest_auth_header,
|
|
263
368
|
'rack-test.digest_auth_retry' => true)
|
|
264
369
|
auth_env.delete('rack.request')
|
|
265
|
-
process_request(uri
|
|
370
|
+
process_request(uri, auth_env)
|
|
266
371
|
else
|
|
267
372
|
yield last_response if block_given?
|
|
268
373
|
|
|
@@ -271,6 +376,8 @@ module Rack
|
|
|
271
376
|
end
|
|
272
377
|
|
|
273
378
|
def digest_auth_header
|
|
379
|
+
require_relative 'test/mock_digest_request'
|
|
380
|
+
|
|
274
381
|
challenge = last_response['WWW-Authenticate'].split(' ', 2).last
|
|
275
382
|
params = Rack::Auth::Digest::Params.parse(challenge)
|
|
276
383
|
|
|
@@ -280,7 +387,7 @@ module Rack
|
|
|
280
387
|
'uri' => last_request.fullpath,
|
|
281
388
|
'method' => last_request.env['REQUEST_METHOD'])
|
|
282
389
|
|
|
283
|
-
params['response'] =
|
|
390
|
+
params['response'] = MockDigestRequest_.new(params).response(@digest_password)
|
|
284
391
|
|
|
285
392
|
"Digest #{params}"
|
|
286
393
|
end
|
|
@@ -294,34 +401,14 @@ module Rack
|
|
|
294
401
|
def digest_auth_configured?
|
|
295
402
|
@digest_username
|
|
296
403
|
end
|
|
297
|
-
|
|
298
|
-
def default_env
|
|
299
|
-
{ 'rack.test' => true, 'REMOTE_ADDR' => '127.0.0.1' }.merge(@env).merge(headers_for_env)
|
|
300
|
-
end
|
|
301
|
-
|
|
302
|
-
def headers_for_env
|
|
303
|
-
converted_headers = {}
|
|
304
|
-
|
|
305
|
-
@headers.each do |name, value|
|
|
306
|
-
env_key = name.upcase.tr('-', '_')
|
|
307
|
-
env_key = 'HTTP_' + env_key unless env_key == 'CONTENT_TYPE'
|
|
308
|
-
converted_headers[env_key] = value
|
|
309
|
-
end
|
|
310
|
-
|
|
311
|
-
converted_headers
|
|
312
|
-
end
|
|
313
|
-
|
|
314
|
-
def params_to_string(params)
|
|
315
|
-
case params
|
|
316
|
-
when Hash then build_nested_query(params)
|
|
317
|
-
when nil then ''
|
|
318
|
-
else params
|
|
319
|
-
end
|
|
320
|
-
end
|
|
321
404
|
end
|
|
322
405
|
|
|
406
|
+
# Whether the version of rack in use handles encodings.
|
|
323
407
|
def self.encoding_aware_strings?
|
|
324
|
-
|
|
408
|
+
Rack.release >= '1.6'
|
|
325
409
|
end
|
|
326
410
|
end
|
|
411
|
+
|
|
412
|
+
# For backwards compatibility with 1.1.0 and below
|
|
413
|
+
MockSession = Test::Session
|
|
327
414
|
end
|