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.

  1. We’re using devise where I’m sure it’s much more complicated than this but for now it’ll do.