I have a rails app with the following routes
root :to => "pages#home"
scope "/:locale" do
root :to => "pages#home"
...
match "/sign_in" => "sessions#new"
resources :sessions, :only => [:new, :create]
end
My ApplicationController contains a default_url_options() that automatically sets the locale option
My SessionsController contains the following
class SessionsController < ApplicationController
def new
end
def create
redirect_to root_path
end
end
So there there is not yet any logic, just a redirect. When I run the application in a browser, go to the sign in page, submit the form (which posts to /en/sessions), then it works as expected: I am redirected to /en
The integration test however fails to recognize the redirect
describe "sign-in" do
before(:each) do
visit "/en/sign_in"
@user = Factory.create(:user)
end
context "with valid attributes" do
before(:each) do
fill_in "email", :with => @user.email
fill_in "password", :with => @user.password
end
it "should redirect to root" do
click_button "Sign in"
response.should be_redirect
response.should redirect_to "/en"
end
end
end
The test fails with the message
5) Authentication sign-in with valid attributes should redirect to root
Failure/Error: response.should be_redirect
expected redirect? to return true, got false
So even though the application redirects correctly, RSpec does not see the response as a redirect.
If I, just for the fun of it, change the implementation of create to
def create
redirect_to new_user_path
end
Then I get the error message
6) SessionsController POST 'create' with valid user should redirect to root
Failure/Error: response.should redirect_to root_path
Expected response to be a redirect to <http://test.host/en> but was a redirect to <http://test.host/en/users/new>
Which is of course the expected error message as the function is now redirecting to the wrong url. But why is it that new_user_path results in a redirect that RSpec sees as a redirect, but root_path results in a redirect that RSpec does not recognize as a redirect?
Based on comments, I modified the test to verify the status code
it "should redirect to root" do
click_button "Sign in"
response.status.should == 302
response.should be_redirect
response.should redirect_to "/en"
end
It leads to the error
5) Authentication sign-in with valid attributes should redirect to root
Failure/Error: response.status.should == 302
expected: 302
got: 200 (using ==)
I think I solved the problem. Changing the verification code to
it "should redirect to root" do
current_url.should == root_url("en")
end
works.
I assume that the cause of my problem is because webrat actually follows the redirect, so in my original test, I was testing the response code of the second response after the redirect.