Been chugging along learning Rspec, Capybara, and FactoryGirl as per Ryan Bates' "How I Test" railscast and hit a snag. My app uses Devise for authentication and CanCan for authorization. I'd like to test to make sure that an user can delete their own posts, but not the posts of other users, but I can't seem to make the deletion happen. I've read about how I should use "controller tests" for this, but googling hasn't shed much light on what the difference is between that and my integration tests and how I might go that route.
Here's my code and, below it, the result:
Factories:
2 FactoryGirl.define do
3 factory :role do
4 factory :admin_role do
5 name 'admin'
6 end
7
8 factory :author_role do
9 name 'author'
10 end
...
17 sequence(:name) { |n| "Joe User #{n}"}
18 sequence(:email) { |n| "joeuser+user#{n}@example.com"}
19
20 factory :user do
21 name
22 email
23 password 'secret'
24
25 factory :admin, :class => User do
26 name
27 email
28 after_create { |user| user.roles << FactoryGirl.create(:admin_role) }
29 end
30
31 factory :author , :class => User do
32 name
33 email
34 after_create { |user| user.roles << FactoryGirl.create(:author_role) }
35 end
36 end
37
38 sequence(:title) { |n| "Post Title #{n}"}
39 sequence(:body) { |n| "The inner post body #{n}"}
40
41 factory :post do
42 title
43 body
44 end
45
46 end
posts_spec.rb:
1 require 'spec_helper'
2
3 def login(user)
4 visit new_user_session_path
5 fill_in "Email", :with => user.email
6 fill_in "Password", :with => user.password
7 click_button "Sign in"
8 page.should have_content("Signed in successfully")
9 end
10
11 describe "Posts" do
12 let(:author) {FactoryGirl.create(:author)}
13 let(:author2) {FactoryGirl.create(:author)}
14 let(:user) {FactoryGirl.create(:user)}
15 let(:admin) {FactoryGirl.create(:admin)}
16 let(:post) { FactoryGirl.create(:post, user: author) }
...
99 describe "destroy /post/:id" do
100 it "should allow the author to destroy post" do
101 login(author)
102
103 visit post_path(post, :method => :delete)
104 lambda {
105 visit post_path(post)
106 }.should raise_exception(ActiveRecord::RecordNotFound)
107 end
108 end
109 end
Results from guard:
Running: spec/requests/posts_spec.rb
........F
Failures:
1) Posts destroy /post/:id should allow the author to destroy post
Failure/Error: lambda {
expected ActiveRecord::RecordNotFound but nothing was raised
# ./spec/requests/posts_spec.rb:104:in `block (3 levels) in <top (required)>'
When I actually save_and_open_page (using launchy) I see that the post hasn't been deleted. Any thoughts on how I should best do this? Thanks much!