1 module ActionController
3 # A small suite of assertions that test responses from Rails applications.
4 module ResponseAssertions
5 # Asserts that the response is one of the following types:
7 # * <tt>:success</tt> - Status code was 200
8 # * <tt>:redirect</tt> - Status code was in the 300-399 range
9 # * <tt>:missing</tt> - Status code was 404
10 # * <tt>:error</tt> - Status code was in the 500-599 range
12 # You can also pass an explicit status number like assert_response(501)
13 # or its symbolic equivalent assert_response(:not_implemented).
14 # See ActionController::StatusCodes for a full list.
18 # # assert that the response was a redirection
19 # assert_response :redirect
21 # # assert that the response code was status code 401 (unauthorized)
24 def assert_response(type
, message
= nil)
26 if [ :success, :missing, :redirect, :error ].include?(type
) && @response.send("#{type}?")
27 assert_block("") { true } # to count the assertion
28 elsif type
.is_a
?(Fixnum
) && @response.response_code
== type
29 assert_block("") { true } # to count the assertion
30 elsif type
.is_a
?(Symbol
) && @response.response_code
== ActionController
::StatusCodes::SYMBOL_TO_STATUS_CODE[type
]
31 assert_block("") { true } # to count the assertion
34 exception
= @response.template
.instance_variable_get(:@exception)
35 exception_message
= exception
&& exception
.message
36 assert_block(build_message(message
, "Expected response to be a <?>, but was <?>\n<?>", type
, @response.response_code
, exception_message
.to_s
)) { false }
38 assert_block(build_message(message
, "Expected response to be a <?>, but was <?>", type
, @response.response_code
)) { false }
44 # Assert that the redirection options passed in match those of the redirect called in the latest action.
45 # This match can be partial, such that assert_redirected_to(:controller => "weblog") will also
46 # match the redirection of redirect_to(:controller => "weblog", :action => "show") and so on.
50 # # assert that the redirection was to the "index" action on the WeblogController
51 # assert_redirected_to :controller => "weblog", :action => "index"
53 # # assert that the redirection was to the named route login_url
54 # assert_redirected_to login_url
56 # # assert that the redirection was to the url for @customer
57 # assert_redirected_to @customer
59 def assert_redirected_to(options
= {}, message
=nil)
61 assert_response(:redirect, message
)
62 return true if options
== @response.redirected_to
64 # Support partial arguments for hash redirections
65 if options
.is_a
?(Hash
) && @response.redirected_to
.is_a
?(Hash
)
66 return true if options
.all
? {|(key
, value
)| @response.redirected_to
[key
] == value
}
69 redirected_to_after_normalisation
= normalize_argument_to_redirection(@response.redirected_to
)
70 options_after_normalisation
= normalize_argument_to_redirection(options
)
72 if redirected_to_after_normalisation
!= options_after_normalisation
73 flunk
"Expected response to be a redirect to <#{options_after_normalisation}> but was a redirect to <#{redirected_to_after_normalisation}>"
78 # Asserts that the request was rendered with the appropriate template file or partials
82 # # assert that the "new" view template was rendered
83 # assert_template "new"
85 # # assert that the "_customer" partial was rendered twice
86 # assert_template :partial => '_customer', :count => 2
88 # # assert that no partials were rendered
89 # assert_template :partial => false
91 def assert_template(options
= {}, message
= nil)
95 rendered
= @response.rendered
[:template].to_s
96 msg
= build_message(message
,
97 "expecting <?> but rendering with <?>",
101 @response.rendered
[:template].blank
?
103 rendered
.to_s
.match(options
)
107 if expected_partial
= options
[:partial]
108 partials
= @response.rendered
[:partials]
109 if expected_count
= options
[:count]
110 found
= partials
.detect
{ |p
, _
| p
.to_s
.match(expected_partial
) }
111 actual_count
= found
.nil? ? 0 : found
.second
112 msg
= build_message(message
,
113 "expecting ? to be rendered ? time(s) but rendered ? time(s)",
114 expected_partial
, expected_count
, actual_count
)
115 assert(actual_count
== expected_count
.to_i
, msg
)
117 msg
= build_message(message
,
118 "expecting partial <?> but action rendered <?>",
119 options
[:partial], partials
.keys
)
120 assert(partials
.keys
.any
? { |p
| p
.to_s
.match(expected_partial
) }, msg
)
123 assert
@response.rendered
[:partials].empty
?,
124 "Expected no partials to be rendered"
131 # Proxy to to_param if the object will respond to it.
132 def parameterize(value
)
133 value
.respond_to
?(:to_param) ? value
.to_param
: value
136 def normalize_argument_to_redirection(fragment
)
137 after_routing
= @controller.url_for(fragment
)
138 if after_routing
=~
%r
{^\w
+://.*}
141 # FIXME - this should probably get removed.
142 if after_routing
.first
!= '/'
143 after_routing
= '/' + after_routing
145 @request.protocol
+ @request.host_with_port
+ after_routing