Class: Rack::Test::Session

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Utils
Defined in:
lib/rack/test.rb

Overview

Rack::Test::Session handles a series of requests issued to a Rack app. It keeps track of the cookies for the session, and allows for setting headers and a default rack environment that is used for future requests.

Rack::Test::Session’s methods are most often called through Rack::Test::Methods, which will automatically build a session when it’s first used.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Utils

#build_multipart, #build_nested_query

Constructor Details

#initialize(app, default_host = DEFAULT_HOST) ⇒ Session

Creates a Rack::Test::Session for a given Rack app or Rack::Test::BasicSession.

Note: Generally, you won’t need to initialize a Rack::Test::Session directly. Instead, you should include Rack::Test::Methods into your testing context. (See README.rdoc for an example)

The following methods are defined via metaprogramming: get, post, put, patch, delete, options, and head. Each method submits a request with the given request method, with the given URI and optional parameters and rack environment. Examples:

# URI only:
get("/")                   # GET /
get("/?foo=bar")           # GET /?foo=bar

# URI and parameters
get("/foo", 'bar'=>'baz')  # GET /foo?bar=baz
post("/foo", 'bar'=>'baz') # POST /foo (bar=baz in request body)

# URI, parameters, and rack environment
get("/bar", {}, 'CONTENT_TYPE'=>'foo')
get("/bar", {'foo'=>'baz'}, 'HTTP_ACCEPT'=>'*')

The above methods as well as #request and #custom_request store the Rack::Request submitted in #last_request. The methods store a Rack::MockResponse based on the response in #last_response. #last_response is also returned by the methods. If a block is given, #last_response is also yielded to the block.



99
100
101
102
103
104
105
106
107
# File 'lib/rack/test.rb', line 99

def initialize(app, default_host = DEFAULT_HOST)
  @env = {}
  @app = app
  @after_request = []
  @default_host = default_host
  @last_request = nil
  @last_response = nil
  clear_cookies
end

Instance Attribute Details

The Rack::Test::CookieJar for the cookies for the current session.



67
68
69
# File 'lib/rack/test.rb', line 67

def cookie_jar
  @cookie_jar
end

#default_hostObject (readonly)

The default host used for the session for when using paths for URIs.



70
71
72
# File 'lib/rack/test.rb', line 70

def default_host
  @default_host
end

Class Method Details

.new(app, default_host = DEFAULT_HOST) ⇒ Object

:nodoc:



57
58
59
60
61
62
63
64
# File 'lib/rack/test.rb', line 57

def self.new(app, default_host = DEFAULT_HOST) # :nodoc:
  if app.is_a?(self)
    # Backwards compatibility for initializing with Rack::MockSession
    app
  else
    super
  end
end

Instance Method Details

#after_request(&block) ⇒ Object

Run a block after the each request completes.



118
119
120
# File 'lib/rack/test.rb', line 118

def after_request(&block)
  @after_request << block
end

#basic_authorize(username, password) ⇒ Object Also known as: authorize

Set the username and password for HTTP Basic authorization, to be included in subsequent requests in the HTTP_AUTHORIZATION header.

Example:

basic_authorize "bryan", "secret"


198
199
200
201
# File 'lib/rack/test.rb', line 198

def basic_authorize(username, password)
   = ["#{username}:#{password}"].pack('m0')
  header('Authorization', "Basic #{}")
end

#clear_cookiesObject

Replace the current cookie jar with an empty cookie jar.



123
124
125
# File 'lib/rack/test.rb', line 123

def clear_cookies
  @cookie_jar = CookieJar.new([], @default_host)
end

#custom_request(verb, uri, params = {}, env = {}, &block) ⇒ Object

Issue a request using the given HTTP verb for the given URI, with optional params and rack environment. Example:

custom_request "LINK", "/"


160
161
162
163
164
# File 'lib/rack/test.rb', line 160

def custom_request(verb, uri, params = {}, env = {}, &block)
  uri = parse_uri(uri, env)
  env = env_for(uri, env.merge(method: verb.to_s.upcase, params: params))
  process_request(uri, env, &block)
end

#env(name, value) ⇒ Object

Set an entry in the rack environment to be included on all subsequent requests through the session. Use a value of nil to remove a previously value. Example:

env "rack.session", {:csrf => 'token'}


185
186
187
188
189
190
191
# File 'lib/rack/test.rb', line 185

def env(name, value)
  if value.nil?
    @env.delete(name)
  else
    @env[name] = value
  end
end

#follow_redirect!Object

Rack::Test will not follow any redirects automatically. This method will follow the redirect returned (including setting the Referer header on the new request) in the last response. If the last response was not a redirect, an error will be raised.



209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/rack/test.rb', line 209

def follow_redirect!
  unless last_response.redirect?
    raise Error, 'Last response was not a redirect. Cannot follow_redirect!'
  end

  if last_response.status == 307
    request_method = last_request.request_method
    params = last_request.params
  else
    request_method = 'GET'
    params = {}
  end

  # Compute the next location by appending the location header with the
  # last request, as per https://tools.ietf.org/html/rfc7231#section-7.1.2
  # Adding two absolute locations returns the right-hand location
  next_location = URI.parse(last_request.url) + URI.parse(last_response['Location'])

  custom_request(
    request_method,
    next_location.to_s,
    params,
    'HTTP_REFERER' => last_request.url,
    'rack.session' => last_request.session,
    'rack.session.options' => last_request.session_options
  )
end

#header(name, value) ⇒ Object

Set a header to be included on all subsequent requests through the session. Use a value of nil to remove a previously configured header.

In accordance with the Rack spec, headers will be included in the Rack environment hash in HTTP_USER_AGENT form. Example:

header "user-agent", "Firefox"


173
174
175
176
177
178
# File 'lib/rack/test.rb', line 173

def header(name, value)
  name = name.upcase
  name.tr!('-', '_')
  name = "HTTP_#{name}" unless name == 'CONTENT_TYPE' || name == 'CONTENT_LENGTH'
  env(name, value)
end

#last_requestObject

Return the last request issued in the session. Raises an error if no requests have been sent yet.

Raises:



134
135
136
137
# File 'lib/rack/test.rb', line 134

def last_request
  raise Error, 'No request yet. Request a page first.' unless @last_request
  @last_request
end

#last_responseObject

Return the last response received in the session. Raises an error if no requests have been sent yet.

Raises:



141
142
143
144
# File 'lib/rack/test.rb', line 141

def last_response
  raise Error, 'No response yet. Request a page first.' unless @last_response
  @last_response
end

#request(uri, env = {}, &block) ⇒ Object

Issue a request to the Rack app for the given URI and optional Rack environment. Example:

request "/"


150
151
152
153
154
# File 'lib/rack/test.rb', line 150

def request(uri, env = {}, &block)
  uri = parse_uri(uri, env)
  env = env_for(uri, env)
  process_request(uri, env, &block)
end

#restore_stateObject

Yield to the block, and restore the last request, last response, and cookie jar to the state they were prior to block execution upon exiting the block.



240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/rack/test.rb', line 240

def restore_state
  request = @last_request
  response = @last_response
  cookie_jar = @cookie_jar.dup
  after_request = @after_request.dup

  begin
    yield
  ensure
    @last_request = request
    @last_response = response
    @cookie_jar = cookie_jar
    @after_request = after_request
  end
end

Set a cookie in the current cookie jar.



128
129
130
# File 'lib/rack/test.rb', line 128

def set_cookie(cookie, uri = nil)
  cookie_jar.merge(cookie, uri)
end