Allow specifying the HTTP status code in assert_redirected_to

Previously, the method always asserts the status is `:redirect` which
allows for any kind of 3XX response. However, sometimes it is worthwhile
to precise the status code of the redirect. For example, a Rails
application may want to verify the redirect is a 301 (Moved Permanently)
and not the default 302 (Found). The new method argument makes this
convenient to do in one assertion.
This commit is contained in:
Jon Dufresne 2022-09-17 07:05:53 -07:00
parent 83f32f62fe
commit 021113927a
3 changed files with 39 additions and 4 deletions

View File

@ -1,3 +1,9 @@
* Added the `:status` option to `assert_redirected_to` to specify the precise
HTTP status of the redirect. Defaults to `:redirect` for backwards
compatibility.
*Jon Dufresne*
* Rescue `JSON::ParserError` in Cookies JSON deserializer to discards marshal dumps:
Without this change, if `action_dispatch.cookies_serializer` is set to `:json` and

View File

@ -50,12 +50,19 @@ module ActionDispatch
#
# # Asserts that the redirection matches the regular expression
# assert_redirected_to %r(\Ahttp://example.org)
def assert_redirected_to(options = {}, message = nil)
assert_response(:redirect, message)
return true if options === @response.location
#
# # Asserts that the redirection has the HTTP status code 301 (Moved
# # Permanently).
# assert_redirected_to "/some/path", status: :moved_permanently
def assert_redirected_to(url_options = {}, options = {}, message = nil)
options, message = message, nil if message.is_a?(Hash) && options.empty?
status = options[:status] || :redirect
assert_response(status, message)
return true if url_options === @response.location
redirect_is = normalize_argument_to_redirection(@response.location)
redirect_expected = normalize_argument_to_redirection(options)
redirect_expected = normalize_argument_to_redirection(url_options)
message ||= "Expected response to be a redirect to <#{redirect_expected}> but was a redirect to <#{redirect_is}>"
assert_operator redirect_expected, :===, redirect_is, message

View File

@ -36,6 +36,8 @@ class ActionPackAssertionsController < ActionController::Base
def redirect_external_protocol_relative() redirect_to "//www.rubyonrails.org"; end
def redirect_permanently() redirect_to "/some/path", status: :moved_permanently end
def response404() head "404 AWOL" end
def response500() head "500 Sorry" end
@ -440,6 +442,26 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase
}
end
def test_assert_redirection_with_status
process :redirect_to_path
assert_redirected_to "http://test.host/some/path", status: :found
assert_raise ActiveSupport::TestCase::Assertion do
assert_redirected_to "http://test.host/some/path", status: :moved_permanently
end
assert_raise ActiveSupport::TestCase::Assertion, "Custom message" do
assert_redirected_to "http://test.host/some/path", { status: :moved_permanently }, "Custom message"
end
process :redirect_permanently
assert_redirected_to "http://test.host/some/path", status: :moved_permanently
assert_raise ActiveSupport::TestCase::Assertion do
assert_redirected_to "http://test.host/some/path", status: :found
end
assert_raise ActiveSupport::TestCase::Assertion, "Custom message" do
assert_redirected_to "http://test.host/some/path", { status: :found }, "Custom message"
end
end
def test_redirected_to_with_nested_controller
@controller = Admin::InnerModuleController.new
get :redirect_to_absolute_controller