我试图用rspec + capybara测试我的编辑和删除帖子的链接是否正确。它们只能由管理员用户查看。我在控制器中有一个回调,并且在部分中有一个有条件的链接。这是我运行rspec spec /:
的错误(我用简单的版本编写)Capybara::ElementNotFound Unable to find link "edit"
Capybara::ElementNotFound Unable to find link "delete"
我认为问题是Capybara + rspecs没有看到我的部分/收藏 - 使用save_and_open_page它们不会出现。我需要做些什么来使它们出现在rspecs中?或者您认为真正的问题是什么?
这就是我所拥有的:
/specs/requests/post_pages/specs.rb
require 'spec_helper'
describe "PostPages" do
subject { page }
describe "post destruction" do
let(:user) { FactoryGirl.create(:user) }
before { FactoryGirl.create(:post, user: user) }
describe "as an admin user" do
let(:admin) { FactoryGirl.create(:admin) }
before {sign_in admin}
describe "user is admin" do
subject { admin }
it { should be_admin }
end
describe "from home" do
before { visit root_path }
it "should delete a post" do
save_and_open_page
expect { click_link "delete", match: :first}.to change(Post, :count).by(-1)
end
end
end
end
describe "post editing" do
let(:user) { FactoryGirl.create(:user) }
before { FactoryGirl.create(:post, user: user) }
describe "as an admin user" do
let(:admin) { FactoryGirl.create(:admin) }
let(:post) { FactoryGirl.create(:post) }
before do
sign_in admin
visit edit_post_path(post)
end
describe "from home" do
before { visit root_path }
it "should edit a post" do
save_and_open_page
expect { click_link "edit", match: :first}.not_to change(Post, :count)
end
end
end
end
end
/app/views/static_pages/home.html.erb
<li>
<span class="posttitle"><%= feed_item.title %></span>
<span class="content"><%= feed_item.content %></span>
<span class="timestamp">
Posted <%= time_ago_in_words(feed_item.created_at) %> ago by <%= feed_item.user.name %>.
</span>
<% if admin?(current_user) %>
<%= link_to "edit", edit_post_path(feed_item),
data: { confirm: "You sure?" },
title: feed_item.content %>
<%= link_to "delete", post_path(feed_item), method: :delete,
data: { confirm: "You sure?" },
title: feed_item.content %>
<% end %>
</li>
/app/views/shared/_feed.html.ern
<% if @feed_items.any? %>
<ol class="userposts">
<%= render partial: 'shared/feed_item', collection: @feed_items %>
</ol>
<%= will_paginate @feed_items %>
<% end %>
/app/views/shared/_feed_item.html.erb
<li>
<span class="posttitle"><%= feed_item.title %></span>
<span class="content"><%= feed_item.content %></span>
<span class="timestamp">
Posted <%= time_ago_in_words(feed_item.created_at) %> ago by <%= feed_item.user.name %>.
</span>
<% if admin?(current_user) %>
<%= link_to "edit", edit_post_path(feed_item),
data: { confirm: "You sure?" },
title: feed_item.content %>
<%= link_to "delete", post_path(feed_item), method: :delete,
data: { confirm: "You sure?" },
title: feed_item.content %>
<% end %>
</li>
/app/helpers/sessions_helper.rb
module SessionsHelper
def sign_in(user)
remember_token = User.new_remember_token
cookies.permanent[:remember_token] = remember_token
user.update_attribute(:remember_token, User.digest(remember_token))
self.current_user = user
end
def signed_in?
!current_user.nil?
end
def current_user=(user)
@current_user = user
end
def current_user
remember_token = User.digest(cookies[:remember_token])
@current_user ||= User.find_by(remember_token: remember_token)
end
def current_user?(user)
user == current_user
end
def signed_in_user
#redirect_to signin_url, notice: "Please sign in." unless signed_in?
unless signed_in?
store_location
redirect_to signin_url, notice: "Please sign in."
end
end
def sign_out
current_user.update_attribute(:remember_token,
User.digest(User.new_remember_token))
cookies.delete(:remember_token)
self.current_user = nil
end
def redirect_back_or(default)
redirect_to(session[:return_to] || default)
session.delete(:return_to)
end
def store_location
session[:return_to] = request.url if request.get?
end
def admin_user
if current_user.admin?
true
else
redirect_to(root_url)
end
end
end
/app/controllers/posts_controller.rb
class PostsController < ApplicationController
before_action :signed_in_user, only: [:create, :destroy,:edit, :update]
before_action :admin_user, only: [:destroy,:edit, :update]
def index
@posts = Post.paginate(page: params[:page])
end
def create
@post = current_user.posts.build(post_params)
if @post.save
flash[:success] = "Post created!"
redirect_to root_url
else
@feed_items = []
render 'static_pages/home'
end
end
def destroy
Post.find(params[:id]).destroy
redirect_to root_url
end
def edit
@post = Post.find(params[:id])
end
def update
@post = Post.find(params[:id])
if @post.update(post_params)
flash[:success] = "Post updated"
redirect_to root_url
else
render 'edit'
end
end
private
def post_params
params.require(:post).permit(:title,:content)
end
def correct_user
@post = current_user.posts.find_by(id: params[:id])
redirect_to root_url if @post.nil?
end
end
编辑:
/app/spec/factories.rb
FactoryGirl.define do
factory :user do
sequence(:name) { |n| "Person #{n}" }
sequence(:email) { |n| "person_#{n}@example.com"}
password "foobar"
password_confirmation "foobar"
factory :admin do
admin true
end
factory :coadmin do
coadmin true
end
end
factory :post do
title "Prueba"
content "Lorem ipsum"
user
end
end