On Mon, Jan 17, 2011 at 1:43 PM, David Chelimsky <dchelim...@gmail.com>wrote:
> On Jan 17, 2011, at 10:16 AM, David Kahn wrote: > > On Mon, Jan 17, 2011 at 9:48 AM, Ants Pants <antsmailingl...@gmail.com>wrote: > >> Hello all, >> >> From what I've seen, this type of question doesn't really seem to get an >> answer on this list as most of the replies relate to failures of RSpec. If >> this is the case, where is the best place to go to get advice about best >> practices etc? >> >> I have a question about best practice. In some of my controllers only an >> admin user can perform edit, update, show etc. So I have a before filter in >> those controllers; ApplicationController#authorise_is_admin >> >> The ApplicationController#authorise_is_admin throws an AccessDenied >> exception and that is caught in ApplicationController#access_denied >> >> My question is, in the spec for the calling controller, let's say >> ProductGroups, what should I spec? >> >> I have a context "user is admin" and that's easy to spec, but the context >> "user is not admin" is where I'm stuck as no actions are performed in that >> controller but I would just like to cover that failure somehow. >> >> Interesting question. I had the same dilemma and decided that it took too > much effort and test code to test this at the controller level. What I do > (and this may or may not work for you depending on your apps security > needs), is to have an authorize method in the User model. It returns success > or failure based on the controller and action passed. The model looks > something like this: > > def authorize(controller_name, action_name) > if self.role > current_role = self.role.name > else > # guest user is empty user > current_role = 'guest' > end > > > case controller_name > when 'activations' > if current_role != 'guest' > return set_autorize_failure_value("You are already logged in to the > system. If you are activating a new user please log out first and try > again.") > end > return authorize_success_message > > when 'feedback_supports' > if current_role == 'guest' || current_role == 'sysadmin' > return set_autorize_failure_value(LOGIN_NOTICE) > end > return authorize_success_message > ... > > end > > Then in the spec it is real easy: > > describe "user authorization - guest role" do > it "is authorized to access certain pages only" do > user = User.new > user.authorize('activations', 'create')[:success].should == true > user.authorize('home', 'index')[:success].should == false > > .... > > end > end > > This might not be everyone's cup of tea and I am sure I can refactor and > make this less verbose, but what I like is having the 'dna' of all my access > rights app wide in one place. > > > Definitely agree with the idea of keeping decisions in one place. I don't > really like the idea of 'controllers' living inside a model, but change > 'controller_name' to 'resource_collection_name' and that solves that > problem. > > I would still want to specify that the controller asks the user for > authorization. WDYT? > If I am following the thread right, I should clarify that I call 'authorize' from the application controller -- should have included this in my first response. It is from there that the User model is invoked: class ApplicationController < ActionController::Base private def authorize if current_user return_value = current_user.authorize(controller_name, action_name) else return_value = User.new.authorize(controller_name, action_name) end if !return_value[:success] flash[:notice] = return_value[:failure_message] if current_user redirect_to home_path else redirect_to login_path end end end end I would not venture to say what I have is the best but just what came up from refactoring in search of simplifying my code and tests. I also do not like the idea of anything dependent like a session or params or something else from a controller getting coupled to a model, but in this case it feels to me that the model is just a switchboard in decision-making, which for me I would consider business logic. > > _______________________________________________ > rspec-users mailing list > rspec-users@rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
_______________________________________________ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users