While building a Rest API call for our product, we needed the server to respond to a post with a “303 see other” response.  Unfortunately, in Rails when you do a redirect_to, it always uses the 302 response code, even when you set the status explicitly:

  1. redirect_to chunky_bacon_url(@bacon), :status => :see other
  2. redirect_to chunky_bacon_url(@bacon), :status => :303

These don’t fail, but they dont do what you would expect. In my test I asserted that the response code was 303, and the test failed.  After some digging I found that I could use the ‘head’ method to force rails to respond correctly:

  1. head :see_other, :location=>chunky_bacon_url(@bacon)

My response assertion passed. Yay. But it was short lived, because this assertion failed after I made the change:

  1. assert_redirected_to chunky_bacon_url(@bacon)

with an error deep inside response_assertions.rb.  Inside the ‘assert_redirected_to’ method, the following line failed because @response.redirected_to returns nil, and then explodes when it tries to call dup.

  1. original = { :expected => options, :actual => @response.redirected_to.is_a?(Symbol) ? @response.redirected_to : @response.redirected_to.dup }

I did some digging, and it turns out that when I used ‘head’ instead of ‘redirect_to’, the @response.redirected_to was never set.  I fixed the test by asserting string equality directly in the response headers:

  1. assert_equal chunky_bacon_url(@bacon), @response.headers["Location"]