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. ↩