Hello, One of the actions in one of my controllers requires a login and I''m trying to write a test for that action. I don''t want to actually go through the login process. I just want to initialize a session variable and be done with it :) So, the way the authentication works is pretty simple. In my application controller I defined this method: def authenticate if session[:user].nil? session[:initial_uri] = request.request_uri redirect_to :controller => ''user'', :action => ''login'' end end In the controller, I have :before_filter = "authenticate" Now, my test so far is: def test_show_valid_request # Assign the user session variable the user with id = 1 @request.session[:user] = User.find(1) # Santity test -- this does say that the value is an ActiveRecord object. puts @request.session[:user] # Try to call the action, which triggers a call to authenticate get :show, { :id => ''1'' }, { :customer_id => ''16'' } # This should fail because no redirection should take place assert_redirect_to(:controller => ''user'', :action => ''login'') end What happens is that the "if session[:user]" in "authenticate" returns nil. tail -f on logs/test.log has "Session ID: ", which would mean that no session exists? Anybody know what I''m missing? --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On 7/1/07, surge <gerases-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > > Hello, > > One of the actions in one of my controllers requires a login and I''m > trying to write a test for that action. I don''t want to actually go > through the login process. I just want to initialize a session > variable and be done with it :) > > So, the way the authentication works is pretty simple. In my > application controller I defined this method: > > def authenticate > if session[:user].nil? > session[:initial_uri] = request.request_uri > redirect_to :controller => ''user'', :action => ''login'' > end > end > > In the controller, I have :before_filter = "authenticate" > > Now, my test so far is: > > def test_show_valid_request > # Assign the user session variable the user with id = 1 > @request.session[:user] = User.find(1) > > # Santity test -- this does say that the value is an ActiveRecord > object. > puts @request.session[:user] > > # Try to call the action, which triggers a call to authenticate > get :show, { :id => ''1'' }, { :customer_id => ''16'' } > > # This should fail because no redirection should take place > assert_redirect_to(:controller => ''user'', :action => ''login'') > end > > What happens is that the "if session[:user]" in "authenticate" returns > nil. > > tail -f on logs/test.log has "Session ID: ", which would mean that no > session exists? > > Anybody know what I''m missing?Because your using a before filter, and the session variable is set there is not actually anything being evaluated for the method. Hence the last evaluated expression for the method is nil. If at the end you returned the session[:user] it should work. def authenticate if session[:user].nil? session[:initial_uri] = request.request_uri redirect_to :controller => ''user'', :action => ''login'' end session[:user] end There are dangers associated with storing your user object in the session. Stale objects and more. There is plenty of discussion about it on the list and elsewhere. It is common practice to just store the ID of the user object in the session and then do a lazy lookup of the user when you need it. It only results in one lookup per request for the user object. eg something like def current_user @current_user ||= User.find_by_id( session[:user_id] ) if session[:user_id] end HTH Daniel --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
> Because your using a before filter, and the session variable is set there is > not actually anything being evaluated for the method. Hence the last > evaluated expression for the method is nil.Hmm, I don''t think that''s it because I''m not relying on the return of value of "authenticate". It just redirects or doesn''t. And it does redirect, which means that session[:user] is nil by the time authenticate is called. But if I do this: get :show, { :id => ''1'' }, { :user => User.find(1) } it does work. So, for some reason if the session variable is set as part of the get call, it works.> There are dangers associated with storing your user object in the session. Stale objects and more.Thanks for the tip. I''ll rework my process to take that into account. Never thought about it! Thanks for the post, Daniel. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On 7/1/07, surge <gerases-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > > > Because your using a before filter, and the session variable is set > there is > > not actually anything being evaluated for the method. Hence the last > > evaluated expression for the method is nil. > > Hmm, I don''t think that''s it because I''m not relying on the return of > value of "authenticate". It just redirects or doesn''t. And it does > redirect, which means that session[:user] is nil by the time > authenticate is called. But if I do this: > > get :show, { :id => ''1'' }, { :user => User.find(1) } > > it does work. So, for some reason if the session variable is set as > part of the get call, it works. > > > There are dangers associated with storing your user object in the > session. Stale objects and more. > > Thanks for the tip. I''ll rework my process to take that into account. > Never thought about it! > > Thanks for the post, Daniel.In IRB ?> def test>> if @test.nil? >> "Blah" >> end >> end=> nil>> test=> "Blah" # => When @test is not set the method returns a value>> @test = "I''m Set"=> "I''m Set">> test=> nil #=> When @test is set the method returns nil>>Can you see that in your situation, when your session variable is set the method will return nil? From the docs you can see. http://api.rubyonrails.org/classes/ActionController/Filters/ClassMethods.html before_filter<http://api.rubyonrails.org/classes/ActionController/Filters/ClassMethods.html#M000180>and around_filter<http://api.rubyonrails.org/classes/ActionController/Filters/ClassMethods.html#M000186>may halt the request before controller action is run. This is useful, for example, to deny access to unauthenticated users or to redirect from http to https. Simply return false from the filter or call render or redirect. So if the result of a method evaluates to false ( either false or nil ) then the action of the controller will not be run. Since your redirect_to is inside an if statement whose body is never executed it does not re-direct either. So even though you aren''t explicitly relying on the return value of authenticate, rails is as part of the before_filter behavior. I''ve never actually tried this. What is returned in this situation? Daniel --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
> Can you see that in your situation, when your session variable is set the method will return nil?If I do @request.session[:user_id] = 1, the "if session[:user].nil?" returns true and the redirect does happen. If I do get :show, { :id => ''1'' }, { :customer_id => ''16'' }, the method does return nil, but the action of the controller is not stopped. That''s interesting about halting the action of a controller. It''s strange though. Say I do return false from a before filter, what would the user see? I''m not a big expert on all this -- just reporting the results. Sergei --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
There is a better way (IMO). Move as much authentication as possible into your model, then create a logged_in? helper function in your application.rb. For your tests, use Mocha (http:// mocha.rubyforge.org/) and stub the logged_in? function to return true for tests where the user is meant to be logged in and false for ones where you might have a bogus user. E.g., # your controller def test_user_is_logged_in controller.stubs(:logged_in?).returns(true) # ... end Just a thought... On Jul 1, 2007, at 9:19 AM, surge wrote:> >> Can you see that in your situation, when your session variable is >> set the method will return nil? > > If I do @request.session[:user_id] = 1, the "if session[:user].nil?" > returns true and the redirect does happen. > If I do get :show, { :id => ''1'' }, { :customer_id => ''16'' }, the > method does return nil, but the action of the controller is not > stopped. > > That''s interesting about halting the action of a controller. It''s > strange though. Say I do return false from a before filter, what would > the user see? > > I''m not a big expert on all this -- just reporting the results. > > Sergei > > > > > >Steve Ross sross-ju+vs0qJmyeQKKlA4PA9hA@public.gmane.org http://www.calicowebdev.com --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Steve, thanks for the idea. Right now though I want to stick to the framework so I can keep the amount of new information to a minimum :) On Jul 1, 2:04 pm, "s.ross" <cwdi...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> There is a better way (IMO). Move as much authentication as possible > into your model, then create a logged_in? helper function in your > application.rb. For your tests, use Mocha (http:// > mocha.rubyforge.org/) and stub the logged_in? function to return true > for tests where the user is meant to be logged in and false for ones > where you might have a bogus user. > > E.g., > > # your controller > def test_user_is_logged_in > controller.stubs(:logged_in?).returns(true) > # ... > end > > Just a thought... > > On Jul 1, 2007, at 9:19 AM, surge wrote: > > > > > > >> Can you see that in your situation, when your session variable is > >> set the method will return nil? > > > If I do @request.session[:user_id] = 1, the "if session[:user].nil?" > > returns true and the redirect does happen. > > If I do get :show, { :id => ''1'' }, { :customer_id => ''16'' }, the > > method does return nil, but the action of the controller is not > > stopped. > > > That''s interesting about halting the action of a controller. It''s > > strange though. Say I do return false from a before filter, what would > > the user see? > > > I''m not a big expert on all this -- just reporting the results. > > > Sergei > > Steve Ross > s...-ju+vs0qJmyeQKKlA4PA9hBHnuRYL88vP@public.gmane.org://www.calicowebdev.com--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Here is some code from one of my older projects: # in controller def test_admin get_logged_in get :admin assert_response :success end # in test_helper.rb def get_logged_in request.session[:user] = users(:users_004).id # theoretically, there is more involved in getting logged in... i.e., login time end Hope this helps. On Jul 1, 2007, at 11:51 AM, surge wrote:> > Steve, thanks for the idea. Right now though I want to stick to the > framework so I can keep the amount of new information to a minimum :) > > On Jul 1, 2:04 pm, "s.ross" <cwdi...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: >> There is a better way (IMO). Move as much authentication as possible >> into your model, then create a logged_in? helper function in your >> application.rb. For your tests, use Mocha (http:// >> mocha.rubyforge.org/) and stub the logged_in? function to return true >> for tests where the user is meant to be logged in and false for ones >> where you might have a bogus user. >> >> E.g., >> >> # your controller >> def test_user_is_logged_in >> controller.stubs(:logged_in?).returns(true) >> # ... >> end >> >> Just a thought... >> >> On Jul 1, 2007, at 9:19 AM, surge wrote: >> >> >> >> >> >>>> Can you see that in your situation, when your session variable is >>>> set the method will return nil? >> >>> If I do @request.session[:user_id] = 1, the "if session[:user].nil?" >>> returns true and the redirect does happen. >>> If I do get :show, { :id => ''1'' }, { :customer_id => ''16'' }, the >>> method does return nil, but the action of the controller is not >>> stopped. >> >>> That''s interesting about halting the action of a controller. It''s >>> strange though. Say I do return false from a before filter, what >>> would >>> the user see? >> >>> I''m not a big expert on all this -- just reporting the results. >> >>> Sergei >> >> Steve Ross >> s...-ju+vs0qJmyeQKKlA4PA9hBHnuRYL88vP@public.gmane.org://www.calicowebdev.com > > > >Steve Ross sross-ju+vs0qJmyeQKKlA4PA9hA@public.gmane.org http://www.calicowebdev.com --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Yes, that''s what I was doing too -- except are you sure it''s "request.session[:user] = users(:users_004).id" and not "@request.session[:user] = users(:users_004).id"? Because otherwise I get "an unknown local variable". Anyways, this general approach is not working for me for some reason. But I''m OK with passing the session variables along with the call to "get" Thanks! Sergei On Jul 1, 3:10 pm, "s.ross" <cwdi...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Here is some code from one of my older projects: > > # in controller > def test_admin > get_logged_in > get :admin > assert_response :success > end > > # in test_helper.rb > def get_logged_in > request.session[:user] = users(:users_004).id > # theoretically, there is more involved in getting logged in... > i.e., login time > end > > Hope this helps. > > On Jul 1, 2007, at 11:51 AM, surge wrote: > > > > > > > Steve, thanks for the idea. Right now though I want to stick to the > > framework so I can keep the amount of new information to a minimum :) > > > On Jul 1, 2:04 pm, "s.ross" <cwdi...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > >> There is a better way (IMO). Move as much authentication as possible > >> into your model, then create a logged_in? helper function in your > >> application.rb. For your tests, use Mocha (http:// > >> mocha.rubyforge.org/) and stub the logged_in? function to return true > >> for tests where the user is meant to be logged in and false for ones > >> where you might have a bogus user. > > >> E.g., > > >> # your controller > >> def test_user_is_logged_in > >> controller.stubs(:logged_in?).returns(true) > >> # ... > >> end > > >> Just a thought... > > >> On Jul 1, 2007, at 9:19 AM, surge wrote: > > >>>> Can you see that in your situation, when your session variable is > >>>> set the method will return nil? > > >>> If I do @request.session[:user_id] = 1, the "if session[:user].nil?" > >>> returns true and the redirect does happen. > >>> If I do get :show, { :id => ''1'' }, { :customer_id => ''16'' }, the > >>> method does return nil, but the action of the controller is not > >>> stopped. > > >>> That''s interesting about halting the action of a controller. It''s > >>> strange though. Say I do return false from a before filter, what > >>> would > >>> the user see? > > >>> I''m not a big expert on all this -- just reporting the results. > > >>> Sergei > > >> Steve Ross > >> s...-ju+vs0qJmyeQKKlA4PA9hBHnuRYL88vP@public.gmane.org://www.calicowebdev.com > > Steve Ross > s...-ju+vs0qJmyeQKKlA4PA9hBHnuRYL88vP@public.gmane.org://www.calicowebdev.com--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---