Testing Actions Requiring A Login

Hello,

I would be grateful if somebody could let me know how to test actions
on a controller which are intercepted by a before_filter requiring a
login. The catch is that the before_filter is on my application
controller and I am trying to test my users controller.

I have functional tests for the login and logout actions on their own
controller. Now I just want to be able to post a valid username and
password into that controller, from my users controller, so I can
just get on with testing my users controller’s actions.

Any help would be much appreciated.

Thanks and regards,
Andy S.

In a functional test you can simply populate the session… the
functional
test really should only test the method itself, not the login. It’s
common
practice to put the user’s id in the session… so in a functional test
we
can just populate the session… In this example, I am assuming that
session[:user_id] will be 1 (the id of my logged in user).

def test_edit_user
# passing the session should get me there
get :edit, {:id=>1}, {:user_id => 1}
assert_response :success
end

def test_edit_user_without_login
# no session? should get denied
get :edit, {:id=>1}
assert_response :redirect
assert flash[:notice] = “Please log in.”
end
Testhing the integration of logins with other actions can be done using
Integration tests

def test_edit_user
get “/user/edit/1” #gets the edit page
assert_response :redirect # should be redirected to the login page
follow_redirect #follow that redirect
post “/main/login” , {:username=>“homer”, :password=>“simpson”} #
post
username and password
assert_response :redirect # login should redirect you back to the
url
they wanted to go to originally
follow_redirect # follow that redirect
assert_response :success # Was it successful?
assert_template “edit” # was it the edit page??
end

My feeling is that functional tests are meant to act as unit tests for a
controller. You don’t want any dependencies, you just want to test their
behavior. Integration tests should test the dependencies.

Does that help?

Andrew S. wrote:

I would be grateful if somebody could let me know how to test actions
on a controller which are intercepted by a before_filter requiring a
login. The catch is that the before_filter is on my application
controller and I am trying to test my users controller.

Thanks and regards,
Andy S.

Hi Andy,

Jamis B. has a great article on Integration Tests here:

http://weblog.jamisbuck.org/2006/3/9/integration-testing-in-rails-1-1

HTH,

Alan

On 7 Dec 2006, at 16:35, Alan F. wrote:

Hi Andy,

Jamis B. has a great article on Integration Tests here:

http://weblog.jamisbuck.org/2006/3/9/integration-testing-in-rails-1-1

Alan, thanks for the great link. That will be very helpful.

Regards,
Andy

On 7 Dec 2006, at 15:30, Brian H. wrote:

the functional test really should only test the method itself, not
the login.

Good – that’s what I would like to do.

It’s common practice to put the user’s id in the session… so in a
functional test we can just populate the session… In this
example, I am assuming that session[:user_id] will be 1 (the id of
my logged in user).

That works well for me. Stuffing the user_id into the session
successfully passes my login filter.

def test_edit_user
# passing the session should get me there
get :edit, {:id=>1}, {:user_id => 1}
assert_response :success
end

Aha! I didn’t know that passing a second hash set up the session;
that’s good to learn. (I can’t find it in the API docs though?)

Testhing the integration of logins with other actions can be done
using Integration tests

Oh, okay. So a functional test can only test one controller and
integration tests are for spanning multiple controllers.

My feeling is that functional tests are meant to act as unit tests
for a controller. You don’t want any dependencies, you just want to
test their behavior. Integration tests should test the dependencies.

That confirms what I thought. I just wasn’t quite sure how to bypass
the dependencies for the functional tests.

Does that help?

Yes it does, Brian, thank you. You’ve taught me a new way to pass
session parameters and confirmed the way to proceed.

Thanks again,
Andy

On 12/7/06, Brian H. [email protected] wrote:

Ahh, It seems to wordy for me having to specify it in every request.
I use following technique:

  1. Have login test helper with login_as and logout methods. Those
    methods
    set appropriate @request.session values.
  2. When I just need to run functional tests assuming that user is logged
    in,
    I do login_as :some_user in my test’s setup method:

class FooControllerTest < Test::Unit::TestCase
fixtures :user, :roles, :rights, :rights_roles, :roles_users

def setup
@request = …
@response = …
@controller = …

login_as :admin_user

end


end

  1. You can also add some sugar:

class Test::Unit::TestCase
def self.include_user_fixtures
fixtures :user, :roles, :rights, :rights_roles, :roles_users
end
end

and then write

class FooControllerTest < Test::Unit::TestCase
include_user_fixtures
end

or you can add some parent class for all controller test (assuming that
in
every controller you should deal with user permissions):

class ControllerTest < Test::Unit::TestCase
include_user_fixtures
end

class FooControllerTest < ControllerTest
end

Hope that helps.

On 7 Dec 2006, at 23:32, Maxim K. wrote:

  1. Have login test helper with login_as and logout methods. Those
    methods set appropriate @ request.session values.
  2. When I just need to run functional tests assuming that user is
    logged in, I do login_as :some_user in my test’s setup method:
    [snip]
  3. You can also add some sugar:
    [snip]

That’s all good stuff – thank you. I’ll make use of it.

Regards,
Andy S.