2007-02-10 00:12:31 +01:00
module ActionController
module Assertions
2007-12-21 08:48:59 +01:00
# A small suite of assertions that test responses from Rails applications.
2007-02-10 00:12:31 +01:00
module ResponseAssertions
# Asserts that the response is one of the following types:
#
2007-12-21 08:48:59 +01:00
# * <tt>:success</tt> - Status code was 200
# * <tt>:redirect</tt> - Status code was in the 300-399 range
# * <tt>:missing</tt> - Status code was 404
# * <tt>:error</tt> - Status code was in the 500-599 range
2007-02-10 00:12:31 +01:00
#
# You can also pass an explicit status number like assert_response(501)
# or its symbolic equivalent assert_response(:not_implemented).
# See ActionController::StatusCodes for a full list.
2007-12-21 08:48:59 +01:00
#
# ==== Examples
#
# # assert that the response was a redirection
2009-02-04 21:26:08 +01:00
# assert_response :redirect
2007-12-21 08:48:59 +01:00
#
# # assert that the response code was status code 401 (unauthorized)
# assert_response 401
#
2007-02-10 00:12:31 +01:00
def assert_response ( type , message = nil )
clean_backtrace do
if [ :success , :missing , :redirect , :error ] . include? ( type ) && @response . send ( " #{ type } ? " )
assert_block ( " " ) { true } # to count the assertion
elsif type . is_a? ( Fixnum ) && @response . response_code == type
assert_block ( " " ) { true } # to count the assertion
elsif type . is_a? ( Symbol ) && @response . response_code == ActionController :: StatusCodes :: SYMBOL_TO_STATUS_CODE [ type ]
assert_block ( " " ) { true } # to count the assertion
else
2008-05-18 06:22:34 +02:00
if @response . error?
exception = @response . template . instance_variable_get ( :@exception )
exception_message = exception && exception . message
assert_block ( build_message ( message , " Expected response to be a <?>, but was <?> \n <?> " , type , @response . response_code , exception_message . to_s ) ) { false }
else
assert_block ( build_message ( message , " Expected response to be a <?>, but was <?> " , type , @response . response_code ) ) { false }
end
2007-02-10 00:12:31 +01:00
end
end
end
2009-02-04 21:26:08 +01:00
# Assert that the redirection options passed in match those of the redirect called in the latest action.
2007-12-21 08:48:59 +01:00
# This match can be partial, such that assert_redirected_to(:controller => "weblog") will also
# match the redirection of redirect_to(:controller => "weblog", :action => "show") and so on.
#
# ==== Examples
#
# # assert that the redirection was to the "index" action on the WeblogController
# assert_redirected_to :controller => "weblog", :action => "index"
#
# # assert that the redirection was to the named route login_url
# assert_redirected_to login_url
#
2008-10-27 07:47:01 +01:00
# # assert that the redirection was to the url for @customer
# assert_redirected_to @customer
#
2007-02-10 00:12:31 +01:00
def assert_redirected_to ( options = { } , message = nil )
clean_backtrace do
assert_response ( :redirect , message )
return true if options == @response . redirected_to
2009-02-04 21:26:08 +01:00
2008-10-27 07:47:01 +01:00
# Support partial arguments for hash redirections
if options . is_a? ( Hash ) && @response . redirected_to . is_a? ( Hash )
2009-08-04 17:16:03 +02:00
if options . all? { | ( key , value ) | @response . redirected_to [ key ] == value }
:: ActiveSupport :: Deprecation . warn ( " Using assert_redirected_to with partial hash arguments is deprecated. Specify the full set arguments instead " , caller )
return true
end
2008-10-27 07:47:01 +01:00
end
2009-02-04 21:26:08 +01:00
2008-10-27 07:47:01 +01:00
redirected_to_after_normalisation = normalize_argument_to_redirection ( @response . redirected_to )
options_after_normalisation = normalize_argument_to_redirection ( options )
2007-02-10 00:12:31 +01:00
2008-10-27 07:47:01 +01:00
if redirected_to_after_normalisation != options_after_normalisation
flunk " Expected response to be a redirect to < #{ options_after_normalisation } > but was a redirect to < #{ redirected_to_after_normalisation } > "
2007-02-10 00:12:31 +01:00
end
end
end
2009-02-04 21:26:08 +01:00
# Asserts that the request was rendered with the appropriate template file or partials
2007-12-21 08:48:59 +01:00
#
# ==== Examples
#
# # assert that the "new" view template was rendered
# assert_template "new"
#
2009-08-04 17:16:03 +02:00
# # assert that the "new" view template was rendered with Symbol
# assert_template :new
#
2009-02-04 21:26:08 +01:00
# # assert that the "_customer" partial was rendered twice
# assert_template :partial => '_customer', :count => 2
#
# # assert that no partials were rendered
# assert_template :partial => false
#
def assert_template ( options = { } , message = nil )
2007-02-10 00:12:31 +01:00
clean_backtrace do
2009-02-04 21:26:08 +01:00
case options
2009-08-04 17:16:03 +02:00
when NilClass , String , Symbol
2009-02-04 21:26:08 +01:00
rendered = @response . rendered [ :template ] . to_s
msg = build_message ( message ,
" expecting <?> but rendering with <?> " ,
options , rendered )
assert_block ( msg ) do
if options . nil?
@response . rendered [ :template ] . blank?
else
2009-08-04 17:16:03 +02:00
rendered . to_s . match ( options . to_s )
2009-02-04 21:26:08 +01:00
end
end
when Hash
if expected_partial = options [ :partial ]
partials = @response . rendered [ :partials ]
if expected_count = options [ :count ]
found = partials . detect { | p , _ | p . to_s . match ( expected_partial ) }
actual_count = found . nil? ? 0 : found . second
msg = build_message ( message ,
" expecting ? to be rendered ? time(s) but rendered ? time(s) " ,
expected_partial , expected_count , actual_count )
assert ( actual_count == expected_count . to_i , msg )
else
msg = build_message ( message ,
" expecting partial <?> but action rendered <?> " ,
options [ :partial ] , partials . keys )
assert ( partials . keys . any? { | p | p . to_s . match ( expected_partial ) } , msg )
end
2007-02-10 00:12:31 +01:00
else
2009-02-04 21:26:08 +01:00
assert @response . rendered [ :partials ] . empty? ,
" Expected no partials to be rendered "
2007-02-10 00:12:31 +01:00
end
2009-08-04 17:16:03 +02:00
else
raise ArgumentError
2007-02-10 00:12:31 +01:00
end
end
end
private
2007-10-15 19:16:54 +02:00
# Proxy to to_param if the object will respond to it.
2007-02-10 00:12:31 +01:00
def parameterize ( value )
value . respond_to? ( :to_param ) ? value . to_param : value
end
2008-10-27 07:47:01 +01:00
def normalize_argument_to_redirection ( fragment )
after_routing = @controller . url_for ( fragment )
if after_routing =~ %r{ ^ \ w+://.* }
after_routing
else
# FIXME - this should probably get removed.
if after_routing . first != '/'
after_routing = '/' + after_routing
end
@request . protocol + @request . host_with_port + after_routing
end
end
2007-02-10 00:12:31 +01:00
end
end
end