2014-06-18 80 views
1

一直在遵循RoR教程,而不是堅持在9.2.2節。 GET請求和修補程序要求的測試與以下錯誤消息失敗,我不明白爲什麼:Hartl Ruby on Rails教程9.2.2驗證失敗:名稱已被採用

1) Authentication authorization as wrong user submitting a GET request to the Users#edit action 
Failure/Error: let(:wrong_user) { FactoryGirl.create(:user, email: "[email protected]") } 
ActiveRecord::RecordInvalid: 
    Validation failed: Name has already been taken 
# ./spec/requests/authentication_pages_spec.rb:62:in `block (4 levels) in <top (required)>' 
# ./spec/requests/authentication_pages_spec.rb:66:in `block (5 levels) in <top (required)>' 

    2) Authentication authorization as wrong user submitting a GET request to the Users#edit action 
Failure/Error: let(:wrong_user) { FactoryGirl.create(:user, email: "[email protected]") } 
ActiveRecord::RecordInvalid: 
    Validation failed: Name has already been taken 
# ./spec/requests/authentication_pages_spec.rb:62:in `block (4 levels) in <top (required)>' 
# ./spec/requests/authentication_pages_spec.rb:66:in `block (5 levels) in <top (required)>' 

    3) Authentication authorization as wrong user submitting a PATCH request to the Users#update action 
Failure/Error: let(:wrong_user) { FactoryGirl.create(:user, email: "[email protected]") } 
ActiveRecord::RecordInvalid: 
    Validation failed: Name has already been taken 
# ./spec/requests/authentication_pages_spec.rb:62:in `block (4 levels) in <top (required)>' 
# ./spec/requests/authentication_pages_spec.rb:72:in `block (5 levels) in <top (required)>' 

Failed examples: 

rspec ./spec/requests/authentication_pages_spec.rb:67 # Authentication authorization as wrong user submitting a GET request to the Users#edit action 
rspec ./spec/requests/authentication_pages_spec.rb:68 # Authentication authorization as wrong user submitting a GET request to the Users#edit action 
rspec ./spec/requests/authentication_pages_spec.rb:73 # Authentication authorization as wrong user submitting a PATCH request to the Users#update action 

我曾嘗試:

rake db:reset rake test:prepare

,但並沒有區別

以下是我的authentication_pages_spec.rb

require 'spec_helper' 

describe "Authentication" do 

    subject { page } 

    describe "signin page" do 
    before { visit signin_path } 

    it { should have_content('Sign in') } 
    it { should have_title('Sign in') } 
    end 

describe "signin" do 
    before { visit signin_path } 

describe "with invalid information" do 
    before { click_button "Sign in" } 

     it { should have_title('Sign in') } 
     it { should have_selector('div.alert.alert-error') } 

    describe "after visiting another page" do 
     before { click_link "Home" } 
     it { should_not have_selector('div.alert.alert-error') } 
     end 
    end 

    describe "with valid information" do 
     let(:user) { FactoryGirl.create(:user) } 
     before {sign_in user} 

     it { should have_title(user.name) } 
     it { should have_link('Profile',  href: user_path(user)) } 
     it { should have_link('Settings', href: edit_user_path(user)) } 
     it { should have_link('Sign out', href: signout_path) } 
     it { should_not have_link('Sign in', href: signin_path) } 
    end 
    end 

    describe "authorization" do 

    describe "for non-signed-in users" do 
     let(:user) { FactoryGirl.create(:user) } 

     describe "in the Users controller" do 

     describe "visiting the edit page" do 
      before { visit edit_user_path(user) } 
      it { should have_title('Sign in') } 
     end 

     describe "submitting to the update action" do 
      before { patch user_path(user) } 
      specify { expect(response).to redirect_to(signin_path) } 
     end 
     end 
    end 

    describe "as wrong user" do 
     let(:user) { FactoryGirl.create(:user) } 
     let(:wrong_user) { FactoryGirl.create(:user, email: "[email protected]") } 
     before { sign_in user, no_capybara: true } 

    describe "submitting a GET request to the Users#edit action" do 
     before { get edit_user_path(wrong_user) } 
     specify { expect(response.body).not_to match(full_title('Edit user')) } 
     specify { expect(response).to redirect_to(root_url) } 
     end 

     describe "submitting a PATCH request to the Users#update action" do 
     before { patch user_path(wrong_user) } 
     specify { expect(response).to redirect_to(root_url) } 
     end 
    end 
    end 
end 

users_controller.rb

class UsersController < ApplicationController 

before_action :signed_in_user, only: [:edit, :update] 
before_action :correct_user, only: [:edit, :update] 


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

    def new 
    @user = User.new 
    end 

    def create 
    @user = User.new(user_params) 
    if @user.save 
     sign_in @user 
     flash[:success] = "Welcome to the Sample App!" 
     redirect_to @user 
    else 
     render 'new' 
    end 
    end 

    def edit 
    end 

def update 
    if @user.update_attributes(user_params) 
     flash[:success] = "Profile updated" 
     redirect_to @user 
    else 
     render 'edit' 
    end 
    end 

    private 
    def user_params 
     params.require(:user).permit(:name, :email, :password, 
           :password_confirmation) 
    end 

    # Before filters 

    def signed_in_user 
     redirect_to signin_url, notice: "Please sign in." unless signed_in? 
    end 

    def correct_user 
     @user = User.find(params[:id]) 
     redirect_to(root_url) unless current_user?(@user) 
    end 
    end 

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 sign_out 
    current_user.update_attribute(:remember_token, User.digest(User.new_remember_token)) 
    cookies.delete(:remember_token) 
    self.current_user = nil 
    end 
end 

規格/支持/ utilities.rb

def full_title(page_title) 
    base_title = "Ruby on Rails Tutorial Sample App" 
    if page_title.empty? 
    base_title 
    else 
    "#{base_title} | #{page_title}" 
    end 
end 

def sign_in(user, options={}) 
    if options[:no_capybara] 
    # Sign in when not using Capybara. 
    remember_token = User.new_remember_token 
    cookies[:remember_token] = remember_token 
    user.update_attribute(:remember_token, User.digest(remember_token)) 
    else 
    visit signin_path 
    fill_in "Email", with: user.email 
    fill_in "Password", with: user.password 
    click_button "Sign in" 
    end 
end 

規格/ factories.rb

FactoryGirl.define do 
    factory :user do 
    name  "Michael Hartl" 
    email "[email protected]" 
    password "foobar" 
    password_confirmation "foobar" 
    end 
end 

任何援助將不勝感激。

+0

能否請您發佈'規格/工廠/ users.rb'? – max

+0

謝謝@papirtiger。我已經包含了我的utilities.rb和factories.rb。你的回答是有道理的。我注意到,在第9章中會進一步提及工廠代碼中類似於你的更改。不知道它是否只是教程中的一個疏忽? – TimJ

+0

可能只是一個疏忽,你可以隨時通過電子郵件向作者詢問或[在github上啓動一個問題](https://github.com/railstutorial/sample_app/issues)。如果它解決了你的問題,也請接受答案:) – max

回答

1

問題是userwrong_user具有相同的名稱。

let(:wrong_user) do 
    FactoryGirl.create(:user, name: 'The Wrong Dude', email: "[email protected]") 
end 

或改變your factory to use a sequence:你可以通過一個唯一的名稱在規範中解決這個

FactoryGirl.define do 
    factory :user do 
    sequence(:name) {|n| "J. Random User #{n}" } 
    end 
end 
相關問題