Reputation: 4164
I am trying to test my cancancan abilities using rspec
but as opposed to testing for what a particular user can do, I am trying to test for what a user should not be able to do.
Now, I have a block of context like so:
context "for a manager" do
before do
@manager = FactoryGirl.build(:user, :manager)
@ability = Ability.new(@manager)
end
it "should not be able to create Questions" do
expect(@ability).not_to be_able_to(:create, Question.new)
end
it "should not be able to read Questions" do
expect(@ability).not_to be_able_to(:read, Question.new)
end
it "should not be able to update Questions" do
expect(@ability).not_to be_able_to(:update, Question.new)
end
it "should not be able to delete Questions" do
expect(@ability).not_to be_able_to(:destroy, Question.new)
end
end
This clearly shows that a user of type manager
should not have any form of access to the Question
model.
Is there a direct way to write this whole block in a single it
block, with only one expect
?
I have thought about writing it as follow:
context "for a manager" do
before do
@manager = FactoryGirl.build(:user, :manager)
@ability = Ability.new(@manager)
end
it "should not be able to manage Questions" do
expect(@ability).not_to be_able_to(:manage, Question.new)
end
end
But I'm thinking that this may not necessarily do what I'm intending it to do, as this test will pass is as much as one of the ability for that resource is not granted.
So, in short, is there a direct way to test such scenarios? Thanks to all.
Upvotes: 1
Views: 3740
Reputation: 1250
First of all, I advise you to use an explicit subject
for @ability
so you can use the one-liner syntax like in the example below.
describe Role do
subject(:ability){ Ability.new(user) }
let(:user){ FactoryGirl.build(:user, roles: [role]) }
context "when is a manager" do
let(:role){ FactoryGirl.build(:manager_role) }
it{ is_expected.not_to be_able_to(:create, Question.new) }
it{ is_expected.not_to be_able_to(:read, Question.new) }
it{ is_expected.not_to be_able_to(:update, Question.new) }
it{ is_expected.not_to be_able_to(:destroy, Question.new) }
end
end
Updated after your comment
But you can also summarize all this 4 expectations to simply
%i[create read update destroy].each do |role|
it{ is_expected.not_to be_able_to(role, Question.new) }
end
Upvotes: 7