scenario "viewing all the posts" do
user = create(:user)
allow(user).to receive(:has_permission?)
.with(:view_posts)
.and_return(true)
sign_in(user)
#=> User sees a landing page
visit posts_path
expect(page).to have_text "Here are your posts"
expect(page).not_to have_text "You're not allowed to view posts."
end
We’d expect this to work but there is a problem.
During the test we ask current_user.has_permission?(:view_posts) but the response is false 🤔
What’s going on?
During the test, we’re looking up the User based on a user_id in the session1.
The User that we find is not the same instance of the user we created in our test setup 🤦♂️.
A quick fix would be to allow any instance of a User to have the :view_posts permission.
scenario "viewing all the posts" do
user = create(:user)
- allow(user).to receive(:has_permission?)
- .with(:view_posts)
- .and_return(true)
+ allow_any_instance_of(User).to receive(:has_permission?)
+ .with(:view_posts)
+ .and_return(true)
sign_in(user)
#=> User sees a landing page
visit posts_path
expect(page).to have_text "Here are your posts"
expect(page).not_to have_text "You're not allowed to view posts."
end
Is this what we want? We would prefer to only permit the one User.
Failing
Solution
scenario "viewing all the posts" do
user = create(:user)
- allow(user).to receive(:has_permission?)
- .with(:view_posts)
- .and_return(true)
+ allow_any_instance_of(User).to receive(:has_permission?) do |instance, permission_key|
+ instance.id == user.id && permission_key == :view_posts
+ end
sign_in(user)
#=> User sees a landing page
visit posts_path
expect(page).to have_text "Here are your posts"
expect(page).not_to have_text "You're not allowed to view posts."
end
This solution checks that the instance User is the same as the one created by comparing their id attributes.
-
We’re using devise where I’m sure it’s much more complicated than this but for now it’ll do. ↩