1 require 'rexml/document'
2 require 'html/document'
4 module ActionController
6 # A small suite of assertions that test responses from Rails applications.
7 module ResponseAssertions
8 # Asserts that the response is one of the following types:
10 # * <tt>:success</tt> - Status code was 200
11 # * <tt>:redirect</tt> - Status code was in the 300-399 range
12 # * <tt>:missing</tt> - Status code was 404
13 # * <tt>:error</tt> - Status code was in the 500-599 range
15 # You can also pass an explicit status number like assert_response(501)
16 # or its symbolic equivalent assert_response(:not_implemented).
17 # See ActionController::StatusCodes for a full list.
21 # # assert that the response was a redirection
22 # assert_response :redirect
24 # # assert that the response code was status code 401 (unauthorized)
27 def assert_response(type
, message
= nil)
29 if [ :success, :missing, :redirect, :error ].include?(type
) && @response.send("#{type}?")
30 assert_block("") { true } # to count the assertion
31 elsif type
.is_a
?(Fixnum
) && @response.response_code
== type
32 assert_block("") { true } # to count the assertion
33 elsif type
.is_a
?(Symbol
) && @response.response_code
== ActionController
::StatusCodes::SYMBOL_TO_STATUS_CODE[type
]
34 assert_block("") { true } # to count the assertion
37 exception
= @response.template
.instance_variable_get(:@exception)
38 exception_message
= exception
&& exception
.message
39 assert_block(build_message(message
, "Expected response to be a <?>, but was <?>\n<?>", type
, @response.response_code
, exception_message
.to_s
)) { false }
41 assert_block(build_message(message
, "Expected response to be a <?>, but was <?>", type
, @response.response_code
)) { false }
47 # Assert that the redirection options passed in match those of the redirect called in the latest action.
48 # This match can be partial, such that assert_redirected_to(:controller => "weblog") will also
49 # match the redirection of redirect_to(:controller => "weblog", :action => "show") and so on.
53 # # assert that the redirection was to the "index" action on the WeblogController
54 # assert_redirected_to :controller => "weblog", :action => "index"
56 # # assert that the redirection was to the named route login_url
57 # assert_redirected_to login_url
59 # # assert that the redirection was to the url for @customer
60 # assert_redirected_to @customer
62 def assert_redirected_to(options
= {}, message
=nil)
64 assert_response(:redirect, message
)
65 return true if options
== @response.redirected_to
67 # Support partial arguments for hash redirections
68 if options
.is_a
?(Hash
) && @response.redirected_to
.is_a
?(Hash
)
69 return true if options
.all
? {|(key
, value
)| @response.redirected_to
[key
] == value
}
72 redirected_to_after_normalisation
= normalize_argument_to_redirection(@response.redirected_to
)
73 options_after_normalisation
= normalize_argument_to_redirection(options
)
75 if redirected_to_after_normalisation
!= options_after_normalisation
76 flunk
"Expected response to be a redirect to <#{options_after_normalisation}> but was a redirect to <#{redirected_to_after_normalisation}>"
81 # Asserts that the request was rendered with the appropriate template file.
85 # # assert that the "new" view template was rendered
86 # assert_template "new"
88 def assert_template(expected
= nil, message
=nil)
90 rendered
= @response.rendered_template
.to_s
91 msg
= build_message(message
, "expecting <?> but rendering with <?>", expected
, rendered
)
94 @response.rendered_template
.blank
?
96 rendered
.to_s
.match(expected
)
104 # Proxy to to_param if the object will respond to it.
105 def parameterize(value
)
106 value
.respond_to
?(:to_param) ? value
.to_param
: value
109 def normalize_argument_to_redirection(fragment
)
110 after_routing
= @controller.url_for(fragment
)
111 if after_routing
=~
%r
{^\w
+://.*}
114 # FIXME - this should probably get removed.
115 if after_routing
.first
!= '/'
116 after_routing
= '/' + after_routing
118 @request.protocol
+ @request.host_with_port
+ after_routing