3
votes

I'm new to rpsec w Rails 3.... I just added CanCan for permissions in my Rails 3 app. I want to add test cases w rspec but I'm not 100% sure where they should live.

If I want to write tests to check the permissions. Should these be in the controller? The model? Some where else?

Something like:

@user1 = belongs to @group
@user2 does not


@user1.should be_able_to(:destroy, @group.new(:user => user))
@user2. should_not be_able_to(:destroy, @group.new(:user => user))

Thanks

2

2 Answers

3
votes

Nice question, I think they should live in the model specs folder or even added as a describe block for the model you're testing. Something like

# in user_spec.rb
describe "user abilities" do
  let(:group) { Factory(:group) }
  let(:user) { Factory(:user, :group => group) }

  it "should be able to destroy his group" do
    user.should be_able_to(:destroy, group)
  end

  it "should not be able to destroy other groups" do
    Factory(:user).should_not be_able_to(:destroy, group)
  end

  # if be_able_to macro define its error message
  # you could also do this kind of specs with
  # automatic failure message and spec descriptions
  subject { Factory(:user) }

  it { should be_able_to(:destroy, subject.group) }

end

Since you're spec'ing user abilities I think user_spec.rb is the best place where to store them.

3
votes

I don't think such tests should belong on the model because I don't want model objects to need to be aware of user sessions. I would rather handle that logic in the controllers.

Additionally while you can create an ability_spec to test your cancan configuration that doesn't prove that the authorization rules you define are actually used. You can easily configure cancan to disallow an action, never check for authorization before performing that operation, and end up ignoring your own rules. As a result I favor testing the behaviors of controllers in both authorized and unauthorized situations rather than testing the implementation of my authorization rules.