2012-06-06 2 views
3

난 railstutorial.org에 대한 최신 레일 튜토리얼을 진행하고 있는데 특정 운동 (# 8 http://ruby.railstutorial.org/chapters/updating-showing-and-deleting-users#sec:updating_deleting_exercises)에 붙어 있습니다. 관리자가 자신을 삭제할 수 없도록 rspec/capybara 테스트를 작성해야합니다. 구현이 작동하지만 테스트가 제대로 작동하지 않습니다. 여기 내 코드가있다. 비슷한 질문을 여기에서 발견했습니다 : Ruby on Rails syntaxhttps://getsatisfaction.com/railstutorial/topics/how_to_prevent_admin_user_from_deleting_themselves. 그러나 나는 그것이 이전의 튜토리얼이고 같은 질문이 아니라고 생각합니다. 여기 삭제 링크가없는 경우 파괴를위한 Rspec 테스트

은 사양/요청/user_pages_spec.rb의 관련 코드입니다 :

가 여기에 오류 메시지가 사용자 수는 완성도 1.

감소지고 있다고

describe "User pages" do 
    subject { page } 
    describe "delete links" do 
     describe "as an admin user" do 
     let(:admin) { FactoryGirl.create(:admin) } 
     before do 
      sign_in admin 
      visit users_path 
     end 
     it "should not be able to delete themself" do 
      expect { admin.delete }.should_not change(User, :count) 
     end 
     end 
    end 
    end 
end 

내 (작동) 구현 :

class UsersController < ApplicationController 
    before_filter :current_admin,  only: :destroy 
    def current_admin 
    @user = User.find(params[:id]) 
    redirect_to users_path, notice: "Cannot delete current admin" if current_user?(@user) 
    end 
end 

나는 잘못 가고있다. (몇 가지 방법을 생략했지만 잘하면 내가 뭘 하려는지 알기에 충분하다.)

편집 : Ruby v1.9.3, Rails v3.2.3을 사용한다. 기본적으로 관리자에게는 삭제 링크가 없습니다.

Edit2가이 :

사양/컨트롤러/users_controller_spec.rb

require 'spec_helper' 

describe UsersController do 
    describe "admins" do 
    let(:admin) { FactoryGirl.create(:admin) } 

    it "should not be able to delete themself" do 
     sign_in admin 
     expect { delete :destroy, :id => admin.id }.should_not change(User, :count) 
    end 
    end 
end 

users_controller.rb

def destroy 
    @user = User.find(params[:id]) 

    if current_user?(@user) 
    flash[:error] = "Cannot delete current admin" 
    else 
    @user.destroy 
    flash[:success] = "User destroyed." 
    end 
    redirect_to users_path 
end 

답변

7

당신의 before_filter의 구문이 올바르지 않습니다 : 여기가 작동 얻었다 것입니다. 전화는 다음과 같아야합니다.

before_filter :current_admin, :only => [:destroy] 

또한이 논리를 파괴 작업에 사용하는 것이 좋습니다. 해당 작업에만 적용되므로 별도의 메서드/필터로 옮길 이유는 없습니다. 당신이 지적 다른 질문은 튜토리얼의 이전 버전에서 사실이지만, 논리 그럼에도 불구하고 동일합니다 : 당신이 대신 파괴 활동의 삭제 방법을 호출하기 때문에 테스트에 관해서는

class UsersController < ApplicationController 
    def destroy 
    @user = User.find(params[:id]) 

    if current_user?(@user) 
     flash[:error] = "Cannot delete current admin" 
    else 
     user.destroy 
     flash[:notice] = "User was successfully deleted" 
    end 

    redirect_to users_path 
    end 
end 

, 그것은 실패한 것 귀하의 컨트롤러에. ActiveRecord::Relation

에서 액티브 레코드 객체 인스턴스화되지 않으므로 객체의 콜백 은 어떤을 포함하여 실행되지 않습니다 의존 연결 옵션이나 관찰자 방법.

rspec/capybara를 사용하도록 요청 했으므로 click_link 메소드를 사용하여 삭제 작업을 트리거 할 수 있습니다. 여러 개의 목록이있는 색인 페이지를 사용하고 있으므로 올바른 버튼을 확실하게 선택하려면 Capybara::Node::Finders을 조사해야합니다.

편집 : 당신이 컨트롤러가 아닌 뷰를 테스트하기 위해 찾고 있기 때문에, 당신은 함께 테스트 할 수 있습니다 :이 꽤 많이 railstutorial.org 책 보인다 무엇입니까 user_pages_spec 테스트 할 수

describe "admins" do 
    let(:admin) { FactoryGirl.create(:admin) } 

    it "should not be able to delete themself" do 
    sign_in admin 
    expect { delete :destroy, :id => admin.id }.should_not change(User, :count) 
    end 
end 
+0

답장을 보내 주셔서 감사합니다. 나는 당신의 대답으로 놀고 그것이 효과가 있는지 볼 것입니다. 그러나 기본적으로 관리자를위한 destroy 작업에 대한 링크는 없습니다. 그래서 click_link 메서드를 사용할 수 있다고 생각하지 않습니다. 또한 컨트롤러에 대한 삭제 링크를 추가하면 내 컨트롤러를 테스트하기 위해 이전의 before_filter가 작동하고있었습니다. 그러나, 그것을하는 것이 최선의 방법이 아닐 수도 있습니다. 내가 페이지를 테스트하지 않고 컨트롤러를 테스트하기 때문에 내 주제가 정확하지 않을 수도 있습니다. –

+0

"delete : destroy"를 사용하여 파괴 행동을 직접 호출 할 수 있습니다. 대답에 예제를 추가했습니다. – rpedroso

+0

current_user 메서드가 테스트를 위해 존재하지 않습니다. 아마 나는 하나를 써야한다. admin 객체를 사용하는 또 다른 방법이 있습니까? 추가 된 테스트를 spec/controllers/users_controller_spec.rb와 같은 다른 파일로 옮겨야합니까? –

7

네가하기를 바란다. (Ruby on Rails 튜토리얼 9 장, 연습 9).그게 좋은 생각인지, 나는 더 큰 마음으로 떠난다. user_pages_spec.rb에서

테스트 코드는 다음과 같습니다

describe "I should not be able to delete admins" do 
     before { delete user_path(admin.id) } 

     it { should_not have_selector('div.alert.alert-error', text: 'Admins cannot delete themselves') } 
    end 

삭제 user_path (admin.id)의 '삭제'를 클릭 모방 RSpec에 - 카피 바라 작동합니다. 위의 코드는 위의 컨트롤러 코드와 함께 전달되며 오류 메시지가 내 것과 일치하도록 변경하거나 그 반대의 경우도 마찬가지입니다.

또한, 항목 만있는 경우 UsersController의 before_filter 구문이 []와 함께 사용되거나 사용되지 않는 것으로 보입니다.

+2

오류 메시지의 존재 여부를 테스트하는 것은 어색한 것 같습니다. 문자열을 변경하고 테스트를 업데이트하는 것을 잊어 버렸다고 암시하는 것처럼, 이는 거짓 긍정으로 이어질 것입니다. 나에게 더 이해가되는 것은'expect {delete user_path (admin.id)} .should_not change (User, : count)'와 같은 것이 될 것이다. –