Functional testing with restful_authentication

I don’t need to do functional testing of restful_authentication, but I
do need to do functional testing of controllers that require
authentication.

Restful_authentication sets up a session and a current_user but sessions
aren’t available in functional testing. So my integration tests run just
fine but my functional tests freak out. I have two issues that I need
advice on.

I can’t login and follow the redirect because follow_redirect has been
taken out of Rails 2.2.2 on the assumption that it belongs in
integration testing.

  1. I’m accessing @current_user in my views, to test for some property of
    the user and display certain things on the page iff the user has that
    property

  2. I’m also using role_requirement, and when I have require_role set in
    my controllers, nothing works because there’s no session, and hence no
    current_user to check the role of.

How should I set things up in this case?

Ta

John S.

In functional tests get, put etc take a third parameter which allows
session
data to be setup. Thus one can say:
def test_show
get :show, {:id => @first_id}, { :user_id =>
users(:user_name_from_fixture).id }

This sets the user_id in the session and allows restful_authentication
to
login and setup current_user

2009/1/20 John S. [email protected]

Colin L. wrote:

In functional tests get, put etc take a third parameter which allows
session
data to be setup. Thus one can say:
def test_show
get :show, {:id => @first_id}, { :user_id =>
users(:user_name_from_fixture).id }

This sets the user_id in the session and allows restful_authentication
to
login and setup current_user

This would be great except that it doesn’t work for me.

Where is the documentation on the params get, put etc take, or is it
something you have to “just know”?

I’ve checked the http://rails.rubyonrails.com/
actioncontroller::TestCase docs and there’s no mention of any of these
methods. None of the ‘get’ methods mentioned in the list of methods
doesn’t seem to match the context of functional testing they’re being
used in so how they work is just magic. What incantations are required?

I’m using Rails 2.2.2

John S.

I must admit I am having difficulty finding documentaion on this. I got
it
from section 13.3 (Functional Testing) of Agile Development With Rails
(Pragmatic Bookshelf) and it certainly works.
When you say it doesn’t work was there an error or did the login
simulation
not work?

2009/1/20 John S. [email protected]

If necessary debug into the logged_in? method in authenticated_system.rb
to
check what is happening. That should call current_user then
login_from_session should pick up the user_id and log you in.

2009/1/20 John S. [email protected]

Colin L. wrote:

I must admit I am having difficulty finding documentaion on this. I got
it
from section 13.3 (Functional Testing) of Agile Development With Rails
(Pragmatic Bookshelf) and it certainly works.
When you say it doesn’t work was there an error or did the login
simulation
not work?

2009/1/20 John S. [email protected]

OK, I see the reference. That’s probably the only place it’s ever
written down, you either know it or you don’t. It doesn’t seem to be in
the online docs.

I’ll fiddle with it to see if I can get it to work. You say you can so
it must be possible. I’m not sure where the error is, I just see that I
don’t have a variable @current_user available in my views unless I go
via login in integration.

I’ll be a while. I’m out till Thursday. Thanks all the same.

John S.

Whichever method you use note that you cannot change the logged in user
within one test by changing the id in the session, though probably you
should not be doing this anyway. Changing the id in the session has no
effect as the user is already logged in.

2009/1/20 Brian H. [email protected]

You could skip passing it and do it directly.

In your functional test, declare a setup method that gets run before
everything else. Load fixutres and use Quentin (first fixture) and add
his ID to the session directly.

fixtures :all
def setup
@request.session[:current_user] = users(:quentin).id
end

This saves lots of time testing the controllers because you’re not
passing sessions. For cases where you want to test that redirection to
the login page works, just set it to nil.

def test_should_go_to_the_login_page_when_not_logged_in
@request.session[:current_user] = nil
get :index
assert_redirected_to new_session_path
end

Look at Shoulda, a nice library to help you with your testing. It lets
you define “contexts” for your tests so you can set the session up
before just a subset of your tests rather than all or nothing.

2009/1/20 Brian H. [email protected]

Colin:

Double-check your understanding of functional tests. Each test is run
in a vaccuum. Sessions do not persist between tests which is why the
get,put,post,delete methods accept session info as a third parameter.

As long as you change the session before you do the call to get, post,
put, delete, it works just fine. Don’t believe me? Try it out.

Brian:
I was refering to multiple gets (or whatever) within one test, not
across
tests. Changing the user_id in the session between gets within one test
will
not change the user. I also suggested this is not something that one
should
do, generally I would expect this to be multiple tests.
Colin

Colin:

Double-check your understanding of functional tests. Each test is run
in a vaccuum. Sessions do not persist between tests which is why the
get,put,post,delete methods accept session info as a third parameter.

As long as you change the session before you do the call to get, post,
put, delete, it works just fine. Don’t believe me? Try it out.