If you're doing functional testing with rails, you'll undoubtedly use follow_redirect - it allows you to follow the redirection for further tests.
def test_something
However, the above code doesn't work when redirecting to a RESTful resource path. You'll get an error:
get :index
assert_response :redirect
follow_redirect
assert_response :success
end
Exception: can't convert Symbol to String
This is because the URL helpers for restful resources return a string, where
follow_redirect expects a hash.The following code in your
test_helper.rb file resolves this. It checks the type first to see if the normal follow_redirect should be called.If not, it parses the path and calls the appropriate action thus following the redirection.
alias_method_chain :follow_redirect, :restful_routes
def follow_redirect_with_restful_routes
#use the normal one unless its a string
return follow_redirect_without_restful_routes unless @response.redirected_to.is_a?(String)
#okay we need to follow the redirect, but first parse the path
url = URI.parse(@response.redirected_to)
path = url.path
extras = CGI.parse(url.query)
#parse puts values into array so flatten
extras.each do |key, value|
extras[key] = value[0] if value.is_a?(Array) && value.length == 1
end
# Assume given controller
request = ActionController::TestRequest.new({}, {}, nil)
request.env["REQUEST_METHOD"] = "GET"
equest.path = path
redirected_controller = ActionController::Routing::Routes.recognize(request)
if @controller.is_a?(redirected_controller)
#then we can redirect, otherwise we can't'
get request.path_parameters[:action], extras.symbolize_keys!
else
raise "Can't follow redirects outside of current controller (from #{@controller.controller_name} to #{redirected_controller})"
end
end
