- Read Tutorial
- Watch Guide Video
In this guide we are going to continue building out our application's permission structure. Specifically we're going to work on ensuring that users are only able to see the posts that they created. This is a common permission structure requirement.
Our tests in post_spec.rb
check to see if the posts
index
page can be reached successfully and if it is displaying a list of posts. However, we have to be more explicit on the types of posts it renders.
If you start the rails server and open the browser, you can see a list that includes all the posts - even those that were not created by a regular user.
Since this is sensitive payroll information, we don't want one user to see the overtime requested by employees. We have to ensure that the post we created is not visible to other users.
For that, open post_spec.rb
, and let's add the following code to the index
action specs:
# spec/features/post_spec.rb it 'has a scope so that only post creators can see their posts' do post1 = Post.create(date: Date.today, rationale: "asdf", user_id: @user.id) post2 = Post.create(date: Date.today, rationale: "asdf", user_id: @user.id) other_user = User.create(first_name: 'Non', last_name: 'Authorized', email: "nonauth@example.com", password: "asdfasdf", password_confirmation: "asdfasdf") post_from_other_user = Post.create(date: Date.today, rationale: "This post shouldn't be seen", user_id: other_user.id) visit posts_path expect(page).to_not have_content(/This post shouldn't be seen/) end
We have a specific flow for this test:
- It's creating multiple
posts
and associating them with the logged in user - Then it creates another user and a new post that it associates with the
other_user
- Next it visits the
index
page - Lastly it expects the page to not display the posts associated with the
other_user
since that user is not the one accessing the page
If you run rspec
it will fail, and that's what we want. Let's implement the code needed for getting this to work.
Go to posts_controller.rb
, and implement this code:
# app/controllers/posts_controller.rb def index @posts = current_user.posts end
If you run rspec
, it throws another error. However this is causing an error with a different test. This is a different error and it's caused by FactoryGirl
not associating a post with the current user. When we start to polish the code we can clean this up and implement a custom method to fix this, but for now we're simply setting the user id of post to the current user id using an update
call. You can update it as follows.
# spec/features/post_spec.rb describe 'delete' do it 'can be deleted' do @post = FactoryGirl.create(:post) @post.update(user_id: @user.id) visit posts_path click_link("delete_post_#{@post.id}_from_index") expect(page.status_code).to eq(200) end end
If you run the tests now they will all be passing.