Module: Merb::Test::RequestHelper

Included in:
ControllerHelper, RouteHelper
Defined in:
lib/merb-core/test/helpers/request_helper.rb,
lib/merb-core/test/helpers/mock_request_helper.rb

Defined Under Namespace

Classes: CookieJar, FakeRequest

Instance Method Summary collapse

Instance Method Details

#build_request(params = {}, env = {}) ⇒ Object

Deprecated.

Prepares and returns a request suitable for dispatching with dispatch_request. If you don’t need to modify the request object before dispatching (e.g. to add cookies), you probably want to use dispatch_to instead.

Parameters

params<Hash>

An optional hash that will end up as params in the controller instance.

env<Hash>

An optional hash that is passed to the fake request. Any request options should go here (see fake_request), including :req or :post_body for setting the request body itself.

Example

req = build_request(:id => 1)
req.cookies['app_cookie'] = "testing"
dispatch_request(req, MyController, :edit)

Notes

Does not use routes.



212
213
214
215
216
217
218
219
220
# File 'lib/merb-core/test/helpers/mock_request_helper.rb', line 212

def build_request(params = {}, env = {})
  params             = Merb::Request.params_to_query_string(params)

  query_string = env[:query_string] || env['QUERY_STRING']
  env[:query_string] = query_string ? "#{query_string}&#{params}" : params
  
  post_body = env[:post_body] || env['POST_BODY']
  fake_request(env, { :post_body => post_body, :req => env[:req] })
end

#check_request_for_route(request) ⇒ Object

Deprecated.

Checks to see that a request is routable.

Parameters

request<Merb::Test::RequestHelper::FakeRequest, Merb::Request>

The request object to inspect.

Raises

Merb::ControllerExceptions::BadRequest

No matching route was found.

Returns

Hash

The parameters built based on the matching route.



390
391
392
393
394
395
396
397
# File 'lib/merb-core/test/helpers/mock_request_helper.rb', line 390

def check_request_for_route(request)
  match =  ::Merb::Router.match(request)
  if match[0].nil? && match[1].empty?
    raise ::Merb::ControllerExceptions::BadRequest, "No routes match the request. Request uri: #{request.uri}"
  else
    match[1]
  end
end

#delete(path, params = {}, env = {}, &block) ⇒ Object

Deprecated.

An HTTP DELETE request that operates through the router

Parameters

path<String>

The path that should go to the router as the request uri.

params<Hash>

An optional hash that will end up as params in the controller instance.

env<Hash>

An optional hash that is passed to the fake request. Any request options should go here (see fake_request).

&blk

The controller is yielded to the block provided for actions prior to the action being dispatched.



296
297
298
299
# File 'lib/merb-core/test/helpers/mock_request_helper.rb', line 296

def delete(path, params = {}, env = {}, &block)
  env[:request_method] = "DELETE"
  mock_request(path, params, env, &block)
end

#describe_input(input) ⇒ Object



11
12
13
14
15
16
17
18
19
# File 'lib/merb-core/test/helpers/request_helper.rb', line 11

def describe_input(input)
  if input.respond_to?(:controller_name)
    "#{input.controller_name}##{input.action_name}"
  elsif input.respond_to?(:original_env)
    describe_request(input)
  else
    input
  end
end

#describe_request(rack) ⇒ Object



7
8
9
# File 'lib/merb-core/test/helpers/request_helper.rb', line 7

def describe_request(rack)
  "a #{rack.original_env[:method] || rack.original_env["REQUEST_METHOD"] || "GET"} to '#{rack.url}'"
end

#dispatch_request(request, controller_klass, action) {|controller| ... } ⇒ Object

Deprecated.

The workhorse for the dispatch*to helpers.

Parameters

request<Merb::Test::RequestHelper::FakeRequest, Merb::Request>

A request object that has been setup for testing.

controller_klass<Merb::Controller>

The class object off the controller to dispatch the action to.

action<Symbol>

The action to dispatch the request to.

&blk

The controller is yielded to the block provided for actions prior to the action being dispatched.

Returns

An instance of controller_klass based on the parameters.

Notes

Does not use routes.

Yields:

  • (controller)


364
365
366
367
368
369
370
371
372
373
# File 'lib/merb-core/test/helpers/mock_request_helper.rb', line 364

def dispatch_request(request, controller_klass, action, &blk)
  controller = controller_klass.new(request)
  yield controller if block_given?
  controller._dispatch(action)

  Merb.logger.info controller._benchmarks.inspect
  Merb.logger.flush

  controller
end

#dispatch_to(controller_klass, action, params = {}, env = {}, &blk) ⇒ Object

Deprecated.

Dispatches an action to the given class. This bypasses the router and is suitable for unit testing of controllers.

Parameters

controller_klass<Controller>

The controller class object that the action should be dispatched to.

action<Symbol>

The action name, as a symbol.

params<Hash>

An optional hash that will end up as params in the controller instance.

env<Hash>

An optional hash that is passed to the fake request. Any request options should go here (see fake_request), including :req or :post_body for setting the request body itself.

&blk

The controller is yielded to the block provided for actions prior to the action being dispatched.

Example

dispatch_to(MyController, :create, :name => 'Homer' ) do |controller|
  controller.stub!(:current_user).and_return(@user)
end

Notes

Does not use routes.



116
117
118
119
# File 'lib/merb-core/test/helpers/mock_request_helper.rb', line 116

def dispatch_to(controller_klass, action, params = {}, env = {}, &blk)
  params = merge_controller_and_action(controller_klass, action, params)
  dispatch_request(build_request(params, env), controller_klass, action.to_s, &blk)
end

#dispatch_with_basic_authentication_to(controller_klass, action, username, password, params = {}, env = {}, &blk) ⇒ Object

Deprecated.

Dispatches an action to the given class and using HTTP Basic Authentication This bypasses the router and is suitable for unit testing of controllers.

Parameters

controller_klass<Controller>

The controller class object that the action should be dispatched to.

action<Symbol>

The action name, as a symbol.

username<String>

The username.

password<String>

The password.

params<Hash>

An optional hash that will end up as params in the controller instance.

env<Hash>

An optional hash that is passed to the fake request. Any request options should go here (see fake_request), including :req or :post_body for setting the request body itself.

&blk

The controller is yielded to the block provided for actions prior to the action being dispatched.

Example

dispatch_with_basic_authentication_to(MyController, :create, 'Fred', 'secret', :name => 'Homer' ) do |controller|
  controller.stub!(:current_user).and_return(@user)
end

Notes

Does not use routes.



174
175
176
177
178
179
# File 'lib/merb-core/test/helpers/mock_request_helper.rb', line 174

def dispatch_with_basic_authentication_to(controller_klass, action, username, password, params = {}, env = {}, &blk)
  env["X_HTTP_AUTHORIZATION"] = "Basic #{Base64.encode64("#{username}:#{password}")}"
  
  params = merge_controller_and_action(controller_klass, action, params)        
  dispatch_request(build_request(params, env), controller_klass, action.to_s, &blk)
end

#fake_request(env = {}, opt = {}) ⇒ Object

Deprecated.

Parameters

env<Hash>

A hash of environment keys to be merged into the default list.

opt<Hash>

A hash of options (see below).

Options (opt)

:post_body<String>

The post body for the request.

:req<String>

The request string. This will only be used if :post_body is left out.

Returns

FakeRequest

A Request object that is built based on the parameters.

Notes

If you pass a post body, the content-type will be set to URL-encoded.



79
80
81
82
83
84
85
86
87
# File 'lib/merb-core/test/helpers/mock_request_helper.rb', line 79

def fake_request(env = {}, opt = {})
  if opt[:post_body]
    req = opt[:post_body]
    env[:content_type] ||= "application/x-www-form-urlencoded"
  else
    req = opt[:req]
  end
  FakeRequest.new(env, StringIO.new(req || ''))
end

#get(path, params = {}, env = {}, &block) ⇒ Object

Deprecated.

An HTTP GET request that operates through the router.

Parameters

path<String>

The path that should go to the router as the request uri.

params<Hash>

An optional hash that will end up as params in the controller instance.

env<Hash>

An optional hash that is passed to the fake request. Any request options should go here (see fake_request).

&blk

The controller is yielded to the block provided for actions prior to the action being dispatched.



237
238
239
240
# File 'lib/merb-core/test/helpers/mock_request_helper.rb', line 237

def get(path, params = {}, env = {}, &block)
  env[:request_method] = "GET"
  mock_request(path, params, env, &block)
end

#merge_controller_and_action(controller_klass, action, params) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



182
183
184
185
186
187
# File 'lib/merb-core/test/helpers/mock_request_helper.rb', line 182

def merge_controller_and_action(controller_klass, action, params)
  params[:controller] = controller_klass.name.to_const_path
  params[:action]     = action.to_s
  
  params
end

#mock_request(path, params = {}, env = {}, &block) ⇒ Object

Deprecated.

A generic request that checks the router for the controller and action. This request goes through the Merb::Router and finishes at the controller.

Parameters

path<String>

The path that should go to the router as the request uri.

params<Hash>

An optional hash that will end up as params in the controller instance.

env<Hash>

An optional hash that is passed to the fake request. Any request options should go here (see fake_request).

&blk

The controller is yielded to the block provided for actions prior to the action being dispatched.

Example

request(path, { :name => 'Homer' }, { :request_method => "PUT" }) do |controller|
  controller.stub!(:current_user).and_return(@user)
end

Notes

Uses Routes.



325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
# File 'lib/merb-core/test/helpers/mock_request_helper.rb', line 325

def mock_request(path, params = {}, env= {}, &block)
  env[:request_method] ||= "GET"
  env[:request_uri], env[:query_string] = path.split('?')
  
  multipart = env.delete(:test_with_multipart)

  request = build_request(params, env)

  opts = check_request_for_route(request) # Check that the request will be routed correctly
  controller_name = (opts[:namespace] ? opts.delete(:namespace) + '/' : '') + opts.delete(:controller)
  klass = Object.full_const_get(controller_name.snake_case.to_const_string)
  
  action = opts.delete(:action).to_s
  params.merge!(opts)

  multipart.nil? ? dispatch_to(klass, action, params, env, &block) : dispatch_multipart_to(klass, action, params, env, &block)
end

#post(path, params = {}, env = {}, &block) ⇒ Object

Deprecated.

An HTTP POST request that operates through the router.

Parameters

path<String>

The path that should go to the router as the request uri.

params<Hash>

An optional hash that will end up as params in the controller instance.

env<Hash>

An optional hash that is passed to the fake request. Any request options should go here (see fake_request).

&blk

The controller is yielded to the block provided for actions prior to the action being dispatched.



257
258
259
260
# File 'lib/merb-core/test/helpers/mock_request_helper.rb', line 257

def post(path, params = {}, env = {}, &block)
  env[:request_method] = "POST"
  mock_request(path, params, env, &block)
end

#put(path, params = {}, env = {}, &block) ⇒ Object

An HTTP PUT request that operates through the router.

Parameters

path<String>

The path that should go to the router as the request uri.

params<Hash>

An optional hash that will end up as params in the controller instance.

env<Hash>

An optional hash that is passed to the fake request. Any request options should go here (see fake_request).

&blk

The controller is yielded to the block provided for actions prior to the action being dispatched.



276
277
278
279
# File 'lib/merb-core/test/helpers/mock_request_helper.rb', line 276

def put(path, params = {}, env = {}, &block)
  env[:request_method] = "PUT"
  mock_request(path, params, env, &block)
end

#request(uri, env = {}) ⇒ Object Also known as: requesting, response_for



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/merb-core/test/helpers/request_helper.rb', line 25

def request(uri, env = {})
  uri = url(uri) if uri.is_a?(Symbol)    

  if (env[:method] == "POST" || env["REQUEST_METHOD"] == "POST")
    params = env.delete(:body_params) if env.key?(:body_params)
    params = env.delete(:params) if env.key?(:params) && !env.key?(:input)
    
    unless env.key?(:input)
      env[:input] = Merb::Request.params_to_query_string(params)
      env["CONTENT_TYPE"] = "application/x-www-form-urlencoded"
    end
  end

  if env[:params]
    uri << "?#{Merb::Request.params_to_query_string(env.delete(:params))}"
  end

  if @__cookie__
    env["HTTP_COOKIE"] = @__cookie__
  end

  app = Merb::Rack::Application.new
  rack = app.call(::Rack::MockRequest.env_for(uri, env))

  rack = Struct.new(:status, :headers, :body, :url, :original_env).
    new(rack[0], rack[1], rack[2], uri, env)

  @__cookie__ = rack.headers["Set-Cookie"] && rack.headers["Set-Cookie"].join

  rack
end

#status_code(input) ⇒ Object



21
22
23
# File 'lib/merb-core/test/helpers/request_helper.rb', line 21

def status_code(input)
  input.respond_to?(:status) ? input.status : input
end

#with_cookies(*controller_classes, &blk) ⇒ Object

Deprecated.

Keep track of cookie values in CookieJar within the context of the block; you need to set this up for secific controllers.

Parameters

*controller_classes

Controller classes to operate on in the context of the block.

&blk

The context to operate on; optionally accepts the cookie jar as an argument.



130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/merb-core/test/helpers/mock_request_helper.rb', line 130

def with_cookies(*controller_classes, &blk)
  cookie_jar = CookieJar.new
  before_cb = lambda { |c| c.cookies.update(cookie_jar) }
  after_cb  = lambda { |c| cookie_jar.update_from_request(c.request) }
  controller_classes.each do |klass|
    klass._before_dispatch_callbacks << before_cb
    klass._after_dispatch_callbacks  << after_cb
  end
  blk.arity == 1 ? blk.call(cookie_jar) : blk.call
  controller_classes.each do |klass|
    klass._before_dispatch_callbacks.delete before_cb
    klass._after_dispatch_callbacks.delete after_cb
  end
end