2011-02-15 89 views
2

我一直在努力通過邁克爾哈特的Rails tutorial(這是令人難以置信的令人敬畏的方式)。通過教程工作時,Cookie相關的rspec測試問題

無論如何,一切都一直很好,我已經接近第10章的末尾。問題是我的rspec測試已經開始產生一些失敗,我無法弄清楚什麼是錯的。

第一次失敗發生在我通過the section on destroying users進行工作時。測試

before :each do 
    @user = Factory :user 
end 

describe "as a non-signed-in user" do 
    it "should deny access" do 
    delete :destroy, :id => @user 
    response.should redirect_to(signin_path) 
    end 
end 

給出了錯誤:

UsersController DELETE 'destroy' as a non-signed-in user should deny access 
Failure/Error: delete :destroy, :id => @user 
NoMethodError: 
    undefined method `admin?' for nil:NilClass 
# ./app/controllers/users_controller.rb:76:in `admin_user' 
# ./spec/controllers/users_controller_spec.rb:308:in `block (4 levels) in <top (required)>' 

下面的代碼在users_controller消息引用:

def admin_user 
    # the error tels me that current_user = NilClass 
    redirect_to(root_path) unless current_user.admin? 
end 

所以我想這將表明CURRENT_USER不能正常工作和正被設置爲零。現在,current_user涉及SessionsHelper的很多方法,它們(afaik)處理在安全Cookie中設置用戶ID並在Cookie移動時引用Cookie。所以這表明cookie有問題。

我已經檢查了瀏覽器和cookie的設置,我也瀏覽了代碼的每一部分,並且它完全按照我所知道的複製了教程。

有什麼我應該看?

附錄

這裏是SessionsHelper模塊的內容:

module SessionsHelper 

    def sign_in user 
     # rails represents cookies as a hash and deals with the conversion for us 
     # making the cookie "signed" makes it impervious to attack 
     cookies.permanent.signed[:remember_token] = [user.id, user.salt] 
     # this line calls the assignment operator below 
     self.current_user = user 
     end 

     def current_user=(user) 
     @current_user = user 
     end 

     # this is a getter method 
     def current_user 
     # this sets @current_user = to the user corresponding to the remember token 
     # but only if @current user is undefined. ie it only works once 
     @current_user ||= user_from_remember_token 
     end 

    def signed_in? 
     # return true if current_user is not nil 
     !current_user.nil? 
     end 

     def sign_out 
     cookies.delete(:remember_token) 
     self.current_user = nil 
     end 

     def current_user? user 
     # returns true if the user object == the current_user object 
     user == current_user 
     end 

     def authenticate 
     deny_access unless signed_in? 
     end 

    def deny_access 
     store_location 
     # this is a shortcut for flash notices: flash[:notice] = "Please sign in to access this page." 
     redirect_to signin_path, :notice => "Please sign in to access this page." 
     end 

     def redirect_back_or(default) 
     redirect_to(session[:return_to] || default) 
     clear_return_to 
     end 

    private 

    def user_from_remember_token 
     # the * allows us to give a 2 element array to a method expecting 2 seperate arguments 
     User.authenticate_with_salt(*remember_token) 
    end 

    def remember_token 
     # return [nil, nil] if the :remember_token cookie is nil 
     cookies.signed[:remember_token] || [nil, nil] 
    end 

    def store_location 
     # stores the url the browser was requesting 
     session[:return_to] = request.fullpath 
    end 

    def clear_return_to 
     session[:return_to] = nil 
    end 
    end 

回答

6

在你規範YPU試圖刪除用戶,而你還沒有登錄,所以CURRENT_USER是零。您應該阻止訪問此用戶非主頁的操作。

class UsersController < ApplicationController 
    before_filter :authenticate, :only => [:index, :edit, :update, :destroy] 
    .... 

正如在例子中描述的那樣。

+1

你先生,是男性的傳奇人物。 – 2011-02-15 09:21:20

0

我做了同樣的遺漏,這個修復工作。謝謝。我同意ducky,Michael Hartl的Rails教程非常棒。將它稱爲「Rails教程」幾乎是一種恥辱。儘管本教程似乎確實指向了良好的Rails開發習慣,但文章簡潔地包含了更多內容。做得太好了。