Or, to put it another way, how can I prevent my my tests from redirecting to the login page if I have '' before_filter :login_required'' in application.rb? I know this has been covered before on this list, and the solution has been to put some variation of @request.session["user"] = User.authenticate("user", "user_pass") in the controller_test. I have tried doing this in my controller test in both setup() and in the first test_* method that fails (which is test_create, fyi) and it''s made no difference. Here''s the error message: 1) Failure: test_create(DatasetsControllerTest) [/usr/lib/ruby/gems/1.8/gems/actionpack-1.9.1/lib/action_controller/assertions.rb:88 :in `assert_redirected_to'' ./test/functional/datasets_controller_test.rb:58:in `test_create'']: response is not a redirection to all of the options supplied (redirection is <{:controll er=>"/user", :action=>"login"}>) Where is the best place to create and store the user so that the functional tests are tricked into thinking someone is logged in? thanks, jh -- James Hughes Web application developer Centre for Health Services and Policy Research Vancouver, BC
On Oct 24, 2005, at 3:49 PM, James Hughes wrote:> > @request.session["user"] = User.authenticate("user", "user_pass")I don''t try to authenticate. I just instantiate the user and assign it to the session. @request.session["user"] = User.find_by_name("user") ----- Doug Alcorn - http://lathi.net/RubyOnRailsDeveloper doug-jGAhs73c5XxeoWH0uzbU5w@public.gmane.org
On 10/24/05, Doug Alcorn <doug-jGAhs73c5XxeoWH0uzbU5w@public.gmane.org> wrote:> > On Oct 24, 2005, at 3:49 PM, James Hughes wrote: > > > > > @request.session["user"] = User.authenticate("user", "user_pass") > > I don''t try to authenticate. I just instantiate the user and assign > it to the session.I understand. You''ll note that my wording was ''some variation of'' putting a user in the session. My question was more where would I put the following line of code:> > @request.session["user"] = User.find_by_name("user")because, no matter *how* I create the user and put it in the session (and I''ve tried both methods shown here, and a few others), my tests still get redirected to the login page. Again, I have tried manipulating the session in this way in both the setup method for the controller and in the failing test itself. Is there another place where this code should go? Thanks, jh -- James Hughes Web application developer Centre for Health Services and Policy Research Vancouver, BC
On Oct 24, 2005, at 6:31 PM, James Hughes wrote:> On 10/24/05, Doug Alcorn <doug-jGAhs73c5XxeoWH0uzbU5w@public.gmane.org> wrote: > > I understand. You''ll note that my wording was ''some variation of'' > putting a user in the session. My question was more where would I put > the following line of code: > >> >> @request.session["user"] = User.find_by_name("user") >> > > because, no matter *how* I create the user and put it in the session > (and I''ve tried both methods shown here, and a few others), my tests > still get redirected to the login page. Again, I have tried > manipulating the session in this way in both the setup method for the > controller and in the failing test itself. Is there another place > where this code should go? >I put mine in either the setup or the individual test as appropriate. Some of my tests are testing how different users interact with the models, so... What I think the net-net is that your test are failing because your authentication isn''t doing what you think it is. Of course, I could be wrong. How does your authentication work on the actual site through the browser? Maybe it''s just a fixture setup problem? It''s kludgy way to debug, but I''ve been known to pepper my controller and helpers with logger.debug ("I''m here") type stuff. Then when you run the tests you can look in log/test.log to see what''s what and where. To summarize, I''d check one of three things: 1. Are you using session["user"] when you should be using session [:user]? I don''t think they are the same. 2. Check your authentication before_filters to see where the authentication is failing and why 3. See if your fixtures for the User aren''t setup properly. ----- Doug Alcorn - http://lathi.net/RubyOnRailsDeveloper doug-jGAhs73c5XxeoWH0uzbU5w@public.gmane.org
James, A different approach is to add a method like this to the test_helper.rb: def login_as_admin(name=''developer'', password=''developer'') post :login, :user => {:username => name, :password => password} assert_redirected_to :action => "index" assert_not_nil(session[:user_id]) end and then change your setup() in your test class to do this: def setup # make sure we are authenticated @controller = LoginController.new @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new login_as_admin @controller = OtherController.new end So basically you change your test context to the controller that does the login, then call the function, then change context back to what you want to test. If you don''t like this, I''ve found that in order to access the session in my tests, I''ve had to do something like this: @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new @controller = LoginController.new @session = ActionController::TestSession.new @request.session = @session otherwise it simply didn''t work for me.. YMMV HTH, Dan
post takes 3 args: :action, params hash, session hash. So, just set your session to whatever it would be like if someone was posting who was already logged in. -- -- Tom Mornini On Oct 25, 2005, at 3:11 AM, Dan Sketcher wrote:> James, > > A different approach is to add a method like this to the > test_helper.rb: > > def login_as_admin(name=''developer'', password=''developer'') > post :login, :user => {:username => name, :password => password} > assert_redirected_to :action => "index" > assert_not_nil(session[:user_id]) > end > > and then change your setup() in your test class to do this: > > def setup > # make sure we are authenticated > @controller = LoginController.new > @request = ActionController::TestRequest.new > @response = ActionController::TestResponse.new > > login_as_admin > > @controller = OtherController.new > end > > So basically you change your test context to the controller that does > the login, then call the function, then change context back to what > you want to test. > > If you don''t like this, I''ve found that in order to access the session > in my tests, I''ve had to do something like this: > > @request = ActionController::TestRequest.new > @response = ActionController::TestResponse.new > @controller = LoginController.new > > @session = ActionController::TestSession.new > @request.session = @session > > otherwise it simply didn''t work for me.. YMMV > > HTH, > Dan > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
Dan and Doug, thanks for your input on this. I definitely need to look deeper into the flow of control through all the redirects and such, as adding the login generator makes the default set of tests generated by scaffolding not particularly relevant, and that is more at the root of my problem here I think. thanks, jh On 10/25/05, Dan Sketcher <dansketcher-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> James, > > A different approach is to add a method like this to the test_helper.rb: > > def login_as_admin(name=''developer'', password=''developer'') > post :login, :user => {:username => name, :password => password} > assert_redirected_to :action => "index" > assert_not_nil(session[:user_id]) > end > > and then change your setup() in your test class to do this: > > def setup > # make sure we are authenticated > @controller = LoginController.new > @request = ActionController::TestRequest.new > @response = ActionController::TestResponse.new > > login_as_admin > > @controller = OtherController.new > end > > So basically you change your test context to the controller that does > the login, then call the function, then change context back to what > you want to test. > > If you don''t like this, I''ve found that in order to access the session > in my tests, I''ve had to do something like this: > > @request = ActionController::TestRequest.new > @response = ActionController::TestResponse.new > @controller = LoginController.new > > @session = ActionController::TestSession.new > @request.session = @session > > otherwise it simply didn''t work for me.. YMMV > > HTH, > Dan > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- James Hughes Web application developer Centre for Health Services and Policy Research Vancouver, BC
On 10/25/05, Tom Mornini <tmornini-W/9V78bTXriB+jHODAdFcQ@public.gmane.org> wrote:> post takes 3 args: > > :action, params hash, session hash. > > So, just set your session to whatever it would be like if someone > was posting who was already logged in.hmm, good to know, thanks. This thread has provided lots of great ideas on how to trick tests into thinking a user is logged in, and I think I''ve cracked that nut. What I''m trying to figure out now is how to modify the generated tests so that they take into account the fact that, with ''before_filter :login_required'' protecting the app, actions will always make a pit stop in the login method of the user_controller, before potentially carrying on to carry out an action, and then redirecting again to a final location. To take the example of test_create (for a model named Dataset), the generated test looks like this: post :create, :dataset => {} assert_response :redirect assert_redirected_to :action => ''list'' Obviously that last assertion fails. I''ve tried using follow_redirect [1], but that has the limitation of not being able to follow redirects across controllers. (i.e. users -> datasets) So, with the before_filter in place, how can I test the assertion that we redirect to the list action? Should I just not bother, and simply test that the entity was created successfully? I''m pretty confused by this, any thoughts on the matter are appreciated jh [1] http://dev.rubyonrails.com/changeset/585 -- James Hughes Web application developer Centre for Health Services and Policy Research Vancouver, BC
On 10/26/05, James Hughes <hughes.james-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> so that they take into account the fact that, with ''before_filter > :login_required'' protecting the app, actions will always make a pit > stop in the login method of the user_controller,ok, now I''m *really* confused. Some further experimentation with just randomly clicking on actions in my app, with a breakpoint in the user/login method, demonstrates that control flow in fact doesn''t make the aforementioned pit-stop; except in the tests, it does. jh -- James Hughes Web application developer Centre for Health Services and Policy Research Vancouver, BC