rspec + capybara + rails Capybara :: ElementNotFound无法找到链接

时间:2014-08-14 22:59:02

标签: ruby-on-rails rspec capybara

我试图用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

0 个答案:

没有答案