Topic: Session Not Showing Up in Test

I've been integrating Aiden Finn's Basic User Authentication in Rails, and am trying to do some testing. My model tests pass just fine, but my first stab at a functional test is not going so well.

Here is my users_controller_test.rb
[code ruby]
require File.dirname(__FILE__) + '/../test_helper'
require 'users_controller'

# Re-raise errors caught by the controller.
class UsersController; def rescue_action(e) raise e end; end

class UsersControllerTest < Test::Unit::TestCase
  self.use_instantiated_fixtures  = true
  fixtures :users

  def setup
    @controller   = UsersController.new
    @request      = ActionController::TestRequest.new
    @response     = ActionController::TestResponse.new
    @request.host = "localhost"
  end
 
  def test_auth_bob
    #check that we can login
    post :login, :user=> { :login => "bob", :password => "test" }
    assert(@response.has_session_object?(@user))
    assert_equal @bob, session[:user]
    assert_response :redirect
    assert_redirected_to :action => :index
  end
end[/code]

Here is my fixture:

bob:
  id: 10001
  type: Administrator
  rsid: AZAA
  rank_id: 2
  first_name: Bob
  last_name: Jones
  mi: L
  login: bob
  hashed_password: 77a0d943cdbace52716a9ef9fae12e45e2788d39 # test
  salt: 1000
  email: bob@dood.com
  location_id: 1
  office_number: 5555555555
  cell_number: 5555555555
  fax_number: 5555555555
  report_to: 1
  region: 1

Here's the relevant sections from the controller and model:
[code ruby]
# From users_controller.rb
def login
    if request.post?
      if session[:user] = User.authenticate(params[:user][:login],
                                            params[:user][:password])
        flash[:notice] = 'Login Successful'
        redirect_to_stored
      else
        flash[:notice] = 'Login Unsuccessful'
      end
    end
  end

# From users.rb
def self.authenticate(login, pass)
    u = find(:first, :conditions => ["login = ?", login])
    return nil if u.nil?
    return u if User.encrypt(pass, u.salt) == u.hashed_password
    nil
end

protected

def self.encrypt(pass, salt)
    Digest::SHA1.hexdigest(pass+salt)
end[/code]

When I run the test I get:

1) Failure:
test_auth_bob(UsersControllerTest) [test/functional/users_controller_test.rb:21]
<false> is not true

Now, I understand the error. It's saying that the test is returning false when I was expecting true. Line 21 is assert(@response.has_session_object?(@user)) so I know that the response does not have a session object. My test.log confirms this:
Processing UsersController#login (for 0.0.0.0 at 2007-06-22 11:00:43) [POST]
  Session ID:
  Parameters: {"user"=> "login"=>"bob", "password"=>"test"}, "action"=>"login", "controller"=>"users"}
User Load (0.000000) SELECT * FROM users WHERE (login = 'bob') LIMIT 1
Administrator Columns (0.010000) SHOW FIELDS FROM users
Redirected to http://localhost/users
Completed in 0.01000 (100 reqs/sec) | DB: 0.01000 (100%) | 302 Found [http://localhost/users/login?user=passwordtestloginbob]

So, this tells me that I'm not getting a session. But, it doesn't tell me why.

The code functions. In real life, it logs in correctly, and redirects work great if a user is not logged in. So why is the test failing?

As usual, I'm sorry for my long windedness.

Re: Session Not Showing Up in Test

You are using @user in the test, but I don't see where that variable is getting set in the test. Try setting it first.

Railscasts - Free Ruby on Rails Screencasts

Re: Session Not Showing Up in Test

bah!

That line should be:
[code ruby]
assert(@response.has_session_object?(:user))[/code]

It works now. Thanks for making me review my code, Ryan. Sometimes it's the small things.

Last edited by mikeyv (2007-06-22 15:29:36)