I'm upgrading my Rails 5 app now, and currently overcoming the following deprecation:
DEPRECATION WARNING: `redirect_to :back` is deprecated and will be removed from Rails 5.1. Please use `redirect_back(fallback_location: fallback_location)` where `fallback_location` represents the location to use if the request has no HTTP referer information. (called from block (3 levels) in <top (required)> at /path/to/some/controller_spec.rb:74)
No worries. Just switched the controller to the new format:
redirect_back(fallback_location: home_path, message: "Some error")
However, the warning doesn't disappear, because the test still looks at :back
, like this:
expect(response).to redirect_to(:back)
I don't see any preferred way to overcome this deprecation. Is there another way to test this without manually specifying a HTTP_REFERER
in my test?
Well, I looked into the rails
/ rspec-rails
source a bit, and it looks pretty bleak. Here's the new redirect code:
def redirect_back(fallback_location:, **args)
if referer = request.headers["Referer"]
redirect_to referer, **args
else
redirect_to fallback_location, **args
end
end
And rspec-rails specifically tests the redirect location, like this:
@scope.assert_redirected_to(@expected)
That would imply that if we don't know the redirect location (or at least the fallback location), we're pretty much out of luck. The rspec matcher itself is just testing whether the response object responds to redirect?
with true, but since Rails redirects don't currently track whether they originated from redirect_to
or redirect_back
, there's no distinguishing case.
It seems that currently, given the following redirect:
redirect_back(fallback_location: "/foo/bar")
The best controller test we can manage is testing for:
expect(response).to redirect_to("/foo/bar")
Which will fail if we manage to provide a Referer
header at some point.
More updates! I asked around rspec-rails
, and they're not interested in supporting an update on this. It's a reasonable stance, given I'm really just looking for a clean syntax to do the assertion. Instead, I've changed over to this:
let(:back) { 'http://google.com' }
before { request.env['HTTP_REFERER'] = back }
And now I can retain the nice format of:
expect(response).to redirect_to(back)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With