views:

156

answers:

1

--preface: ignore if you want.
I'm new to rails, and working on a project that will require user authentication. I found this tutorial and have been trying to go through it and understand what's happening. Of course, it's not exactly what I need as-is, so I've been modifying as I go along. The tutorial is also out of date in some areas, so of course I've had to update my code. So part of my problem is that I'm not sure if the bug is in my modifications, or some function that's been deprecated, or what.

--the question
This is the (simplest) test that fails. (" expected to not be nil" on the first assert statement.)

def test_authentication
  #check we can log in
  post :login, :user => { :username => "bob", :password => "test" }
  assert_not_nil session[:user_id]
  assert_equal users(:bob).id, session[:user_id]
  assert_response :redirect
  assert_redirected_to :action => 'welcome'
end

It calls the user_controller action login:

def login
  if request.post?
    if session[:user_id] = User.authenticate(params[:user][:username], params[:user][:password])
    flash[:message] = "Login succeeded!"
    redirect_to_stored
    else
      flash[:warning] = "Login failed."
    end
  end
end

which calls the User method authenticate. I know that authenticate works properly, however, because I have a single test that does pass:

def test_registration
  #check that we can register and are logged in automatically
  post :register, :user => { :username => "newuser", :password => "pass", :password_confirmation => "pass", :email => "[email protected]" }
  assert_response :redirect
  assert_not_nil session[:user_id]
  assert_redirected_to :action => 'welcome'
end

which calls the user_controller action register

def register
  @user = User.new(params[:user])
  if request.post?
    if @user.save
      session[:user_id] = User.authenticate(@user.username, @user.password)
      flash[:message] = "Registration succeeded"
      redirect_to :action => 'welcome'
    end
  else
    flash[:warning] = "Registration failed"
  end
end

which successfully calls authenticate.

the users fixture has one relevant record:

bob:
  username: bob
  email: [email protected] 
  hashed_password: 77a0d943cdbace52716a9ef9fae12e45e2788d39 # test
  salt: 1000

I've tested the hashed password and salt - "test" is the correct password.

So by my analysis, the bug has got to be in one of 3 places:
how I'm sending my post request,
how I'm accessing the parameters in the login action,
or some aspect of the fixture loading.

(originally I was using the tutorial's code to load the fixture explicitly (self.use_instantiated_fixtures = true; fixtures :users), but I read that all fixtures are automatically loaded before testing, so I took it out. That didn't change a thing.)

Of course, since I can't seem to find the problem in those areas, it could just as well be anywhere else.

A: 

Is it possible that there's a filter that is preventing your action getting called? If there's a general :before_filter => 'login_required' then you might not be reaching your login functionality at all. (Though admittedly the register action would have to be excluded for that test to pass)

In cases like this it's useful to stick some logging in (or run through a debugger) to see whether you even get to the part of the method that you think is failing. If it were me I'd stick a logger.debug("...") as the first line of the login method and then another after the check for request.post? and then another after the authentication check.

Shadwell
I can't believe I missed that, but it was in fact the filter. I had originally named the function log_in, and then for aesthetic reasons renamed it to login -- but my filter exceptions never got updated.Thank you!
dorr