Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing redirect_back with Rspec in Rails 5

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?

like image 327
Joe Mastey Avatar asked Jul 02 '16 17:07

Joe Mastey


1 Answers

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)
like image 106
Joe Mastey Avatar answered Oct 26 '22 00:10

Joe Mastey