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.
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
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 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.
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.
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.
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.