Testing my rails authentication controller


#1

I have a simple controller:

class AccessController < ApplicationController

def login

if request.post?

  employee = Employee.authenticate(params[:name], params[:password])

  if employee

    session[:employee_id] = employee.id

    redirect_to(:controller => "timesheets", :action => "index")

  else

    flash.now[:notice] = "Invalid username/password combination"

  end

end

end

end

I have tried a number of ways to create a spec to test the login
function,
but am not having any luck.

My current code looks something like this, but I don’t really understand
what is going on here.

controller.should_receive(:login).with(no_args())

post :login, params

session[:employee_id].should_not be_nil

I am setting a simple expectation in the first line and then doing a
post
with params

I then check to see if the variable is in the session.

What is the best way to make something like this work…

Wayne L. Andersen


#2

On Fri, Jun 5, 2009 at 3:10 PM, Wayne A. removed_email_address@domain.invalid
wrote:

    flash.now[:notice] = "Invalid username/password combination"

controller.should_receive(:login).with(no_args())

This line overrides the login action with a message expectation, so
the login action in the controller is never executed. What you want is
to stub the decision points and then set expectations about what
happens. For example:

it “assigns the employee id to the session if the employee is found” do
Employee.stub(:authenticate).and_return(mock_model(Employee, :id =>
37))
post :login, params
session[:employee_id].should == 37
end

Let me know if that is not self-explanatory and I’ll explain.

Cheers,
David

post :login, params
session[:employee_id].should_not be_nil

I am setting a simple expectation in the first line and then doing a post
with params. I then check to see if the variable is in the session.

What is the best way to make something like this work…

Wayne L. Andersen

Hi Wayne,

In the firs tlin


#3

David thank you, that worked great. I am doing this and am very happy
with
the result.

  Employee.stub(:authenticate).with(params[:username],

params[:password]).and_return(nil)
post :login, params
session[:employee_id].should be_nil
response.should redirect_to(:controller => “access”, :action =>
“login”)

The question I have now is how do I test the other controllers. Since
all of
my other pages are going to require authentication.

How do I mock the login functionality in a way that allows me to test my
protected pages as if I were logged in without using an actual post to
the
login controller, and still get the :employee_id in the session?

I tried adding this in a before each do

@params = {:username => 'MyString', :password => 'MyString'}
Employee.stub(:authenticate).with(params[:username],

params[:password]).and_return(mock_model(Employee, :id => 1))
session[:employee_id] = 1

Which successfully sets the session variable, but my test fails.

describe “GET index” do
it “assigns all details as @details” do
Detail.stub!(:find).with(:all).and_return([mock_detail])
get :index
session[:employee_id].should == 1
<+++++++++
This passes
assigns[:details].should == [mock_detail]
<+++++++++
This fails
end
end

I get

expected: [#<Detail:0x23246b2 @name=“Detail_1001”>],
got: nil (using ==)


View this message in context:
http://www.nabble.com/Testing-my-rails-authentication-controller-tp23895779p24116711.html
Sent from the rspec-users mailing list archive at Nabble.com.