Giuseppe Bertini
2008-Apr-08 14:03 UTC
[rspec-users] how to mock/stub restful_authenticated and acl2-ized actions
Dear all, I am wondering how to properly mock/stub out the preliminary steps to actions protected by restful_authentication and acl_system2 (role-based authorization to execute actions). Here''s my setup: class User < ActiveRecord::Base has_and_belongs_to_many :roles has_many :tasks [snip] end class Task < ActiveRecord::Base belongs_to :user end I also have a Role class that habtm :users Now, for the controller that I need to spec: class TasksController < ApplicationController before_filter :login_required access_control :DEFAULT => ''operator'' def index @tasks = current_user.tasks end end Two interesting things happen here. First, access to the index action is only granted after checking that the user is logged-in *and* that she is an ''operator''. Second, the tasks method is called on current_user, which is available to all controllers that include AuthenticatedSystem. I can easily write a few specs for this controller if I use a fixture_scenario and login_as (see below). On the other hand, I am trying to learn to abide to the "hey, dont touch that!" database thing. As a novice, the task of setting up examples in which authentication & authorization are satisfied, and where current_user still responds properly appears daunting. But then again, I *am* a novice! Thank you all in advance, Giuseppe ############### # my current specs ############### include AuthenticatedTestHelper describe TasksController, "with a logged-in user having ''operator'' privileges" do scenario :users_and_roles before(:each) do login_as :giuseppe # based on the fixtures, giuseppe is now a logged-in operator end describe "getting the index" do before(:each) do @tasks = mock_model(Task) Task.stub!(:find).and_return([@tasks]) end it "should render index" do get :index response.should render_template(''index'') end it "should assign to the @tasks instance variable" do get :index assigns[:tasks].should ==[@tasks] end end end -- Posted via http://www.ruby-forum.com/.
Glenn Ford
2008-Apr-08 16:13 UTC
[rspec-users] how to mock/stub restful_authenticated and acl2-ized actions
While my approach might not be the best, since I don''t stub :login_required, it still serves me well. I would do something like this: user = mock_model(User, :operator => true) controller.stub!(:current_user).and_return(user) login_required will find the ''current_user'' and be happy. I don''t know if the :operator => true thing will cut it for your other check, but that should get you on the right track. I hope that helps! Glenn On Apr 8, 2008, at 10:03 AM, Giuseppe Bertini wrote:> Dear all, > > I am wondering how to properly mock/stub out the preliminary steps to > actions protected by restful_authentication and acl_system2 (role- > based > authorization to execute actions). Here''s my setup: > > class User < ActiveRecord::Base > has_and_belongs_to_many :roles > has_many :tasks > [snip] > end > > class Task < ActiveRecord::Base > belongs_to :user > end > > I also have a Role class that habtm :users > > Now, for the controller that I need to spec: > > class TasksController < ApplicationController > before_filter :login_required > access_control :DEFAULT => ''operator'' > > def index > @tasks = current_user.tasks > end > end > > Two interesting things happen here. First, access to the index > action is > only granted after checking that the user is logged-in *and* that > she is > an ''operator''. Second, the tasks method is called on current_user, > which > is available to all controllers that include AuthenticatedSystem. > > I can easily write a few specs for this controller if I use a > fixture_scenario and login_as (see below). On the other hand, I am > trying to learn to abide to the "hey, dont touch that!" database > thing. > As a novice, the task of setting up examples in which authentication & > authorization are satisfied, and where current_user still responds > properly appears daunting. But then again, I *am* a novice! > > Thank you all in advance, > Giuseppe > > > ############### > # my current specs > ############### > include AuthenticatedTestHelper > describe TasksController, "with a logged-in user having ''operator'' > privileges" do > scenario :users_and_roles > before(:each) do > login_as :giuseppe # based on the fixtures, giuseppe is now a > logged-in operator > end > > describe "getting the index" do > > before(:each) do > @tasks = mock_model(Task) > Task.stub!(:find).and_return([@tasks]) > end > > it "should render index" do > get :index > response.should render_template(''index'') > end > > it "should assign to the @tasks instance variable" do > get :index > assigns[:tasks].should ==[@tasks] > end > end > end > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users
Giuseppe Bertini
2008-Apr-08 20:17 UTC
[rspec-users] how to mock/stub restful_authenticated and acl2-ized act
Hi Glenn, thanks for the response.> I would do something like this: > > user = mock_model(User, :operator => true) > controller.stub!(:current_user).and_return(user)OK, so, :operator is not a User attribute. Rather, a user is an operator, so to speak, if a habtm relationship exists between the user and the role titled ''operator''. If I modify your code like this: role = mock_model(Role, :title => ''operator'') user = mock_model(User, :roles => [role]) controller.stub!(:current_user).and_return(user) things appear to be working well. Thank you again for your help! Giuseppe -- Posted via http://www.ruby-forum.com/.
Jarkko Laine
2008-Apr-08 20:40 UTC
[rspec-users] how to mock/stub restful_authenticated and acl2-ized act
On 8.4.2008, at 23.17, Giuseppe Bertini wrote:> Hi Glenn, thanks for the response. > >> I would do something like this: >> >> user = mock_model(User, :operator => true) >> controller.stub!(:current_user).and_return(user) > > OK, so, :operator is not a User attribute. Rather, a user is an > operator, so to speak, if a habtm relationship exists between the user > and the role titled ''operator''. If I modify your code like this: > > role = mock_model(Role, :title => ''operator'') > user = mock_model(User, :roles => [role]) > controller.stub!(:current_user).and_return(user) > > things appear to be working well. > Thank you again for your help!You might want to take that one step further and create a method such as has_role?(:operator) for the user class. That way you don''t have to stub arrays like roles in your specs, you just stub that method to return true or false and you''re done. That way you make your code more easily "speccable": def has_role?(role) roles.map(&:title).include?(role.to_s) end //jarkko> > > Giuseppe > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users-- Jarkko Laine http://jlaine.net http://dotherightthing.com http://www.railsecommerce.com http://odesign.fi -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2417 bytes Desc: not available Url : http://rubyforge.org/pipermail/rspec-users/attachments/20080408/a432b19c/attachment.bin
Giuseppe Bertini
2008-Apr-08 21:42 UTC
[rspec-users] how to mock/stub restful_authenticated and acl2-ized act
Hi Jarkko, I see your point. However, checking the user''s roles in order to authorize access to the action is done behind the scenes by the acl_system2 plugin, which would not know what to do with has_role?, unless I am missing something. Thanks! Giuseppe> You might want to take that one step further and create a method such > as has_role?(:operator) for the user class. That way you don''t have to > stub arrays like roles in your specs, you just stub that method to > return true or false and you''re done. That way you make your code more > easily "speccable": > > def has_role?(role) > roles.map(&:title).include?(role.to_s) > end > > //jarkko-- Posted via http://www.ruby-forum.com/.
Chris Flipse
2008-Apr-09 02:03 UTC
[rspec-users] how to mock/stub restful_authenticated and acl2-ized actions
On Tue, Apr 8, 2008 at 10:03 AM, Giuseppe Bertini <lists at ruby-forum.com> wrote:> Dear all, > > I am wondering how to properly mock/stub out the preliminary steps to > actions protected by restful_authentication and acl_system2 (role-based > authorization to execute actions). Here''s my setup: >I use a different authorization plugin, so you might have to adapt, but I''ve got the following in my spec_helper: def as_role(roles = []) returning User.new do |user| # This will become stub_model whenever 1.1.4 comes out ... user.id = 2000 user.stub!(:new_record?).and_return false user.stub!(:valid?).and_return true if @controller @controller.stub!(:login_required).and_return true @controller.stub!(:current_user).and_return true @controller.stub!(:logged_in?).and_return true end user.stub!(:has_role?).and_return false # because has_role? hits the DB [*roles].map(&:to_s).each do |role| user.stub!("is_#{role}?").and_return true user.stub!(:has_role?).with(role).and_return true end end end alias :logged_in :as_role This returns a User, and can be used in either the controller or in model specs, to deal with various aspects of a roled user. You can call it with an array of roles, or a single role; it deals with it either way. The last alias is because logged_in looks better than as_role without any arguments. -- // anything worth taking seriously is worth making fun of // http://blog.devcaffeine.com/ -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20080408/386d7bbd/attachment-0001.html