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 Small

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

Colin Law 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 Small

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?

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.

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.

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.

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.

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