2016-06-14 25 views
0

我在Rails 3.1項目中使用devise,當我單獨爲用戶運行rspec測試時,它們沒有問題。在運行所有測試時設計encrypted_pa​​ssword requried錯誤

rspec spec/model/user_spec.rb 

但是,如果我運行使用rake我所有的測試,那麼它失敗在這四個用戶相關的測試

describe "validation" do 
    context "when user is from google" do 
     before do 
     @user = User.new(email: "[email protected]") 
     @user.authentications.build(provider: "google", uid: "1234") 
     end 

     it "should be valid" do 
     @user.valid?.should be_true 
     end 

     it "should save" do 
     @user.save.should be_true 
     end 
    end 

    context "when user is from twitter" do 
     before do 
     @user = User.new(email: nil) 
     @user.authentications.build(provider: "twitter", uid: "1234") 
     end 

     it "should be valid" do 
     @user.valid?.should be_true 
     end 

     it "should save" do 
     @user.save.should be_true 
     end 
    end 
    end 

這些測試的重點當用戶註冊使用無論是谷歌或Twitter上。

如果我把一個調試器在測試中我可以手動鍵入

(rdb:1) @user.errors 
#<ActiveModel::Errors:0x0000000ca98e98 @base=#<User id: nil, email: "[email protected]", encrypted_password: "", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: nil, updated_at: nil, admin: nil, given_names: nil, surname: nil, dob: nil, address: nil, suburb: nil, state: nil, country: nil, phone: nil, interests: nil, venue_manager: nil, nickname: nil, data_entry: nil>, @messages={}> 
(rdb:1) @user.valid? 
false 
(rdb:1) @user.errors 
#<ActiveModel::Errors:0x0000000ca98e98 @base=#<User id: nil, email: "[email protected]", encrypted_password: "", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: nil, updated_at: nil, admin: nil, given_names: nil, surname: nil, dob: nil, address: nil, suburb: nil, state: nil, country: nil, phone: nil, interests: nil, venue_manager: nil, nickname: nil, data_entry: nil>, @messages={:encrypted_password=>["can't be blank"]}> 
(rdb:1) 

出於某種原因,我被提示我輸入密碼。我的用戶模型中有以下方法。

def password_required? 
    authentications.empty? && (!persisted? || password.present? || password_confirmation.present?) 
    end 

如果我把調試器放在那裏,那麼我可以證明這將返回false,但我仍然得到錯誤。

UPDATE

增加了以下測試谷歌簽署了用戶

it "should not require a password" do 
    @user.send(:password_required?).should be_false 
    end 

這些用戶不需要密碼。當我運行user_spec時,以及當我使用rake一起運行它時,此測試通過。其他測試在使用rake運行時仍然失敗,因爲它們仍未通過驗證。

UPDATE

這裏是我的用戶模型的頂部

class User < ActiveRecord::Base 
    has_many :authentications  
    has_many :created_venues, foreign_key: :created_by_id, class_name: "Venue" 
    has_many :manages 
    has_many :venues, :through => :manages  
    has_many :events 

    devise :database_authenticatable, :registerable, 
     :recoverable, :rememberable, :trackable, :validatable 

    default_scope :order => "given_names" 

    # Setup accessible (or protected) attributes for your model 
    attr_protected :admin 
    attr_reader :venue_tokens 
    <snip> 

UPDATE:在屬性encrypted_password上的用戶望着驗證

> p User._validate_callbacks.map(&:raw_filter) 
[:validate_associated_records_for_authentications, :validate_associated_records_for_created_venues, :validate_associated_records_for_manages, :validate_associated_records_for_venues, :validate_associated_records_for_events, #<ActiveModel::Validations::PresenceValidator:0x000000087a54b0 @attributes=[:email], @options={:if=>:email_required?}>, #<ActiveRecord::Validations::UniquenessValidator:0x000000089a5260 @attributes=[:email], @options={:case_sensitive=>true, :allow_blank=>true, :if=>:email_changed?}, @klass=User(id: integer, email: string, encrypted_password: string, reset_password_token: string, reset_password_sent_at: datetime, remember_created_at: datetime, sign_in_count: integer, current_sign_in_at: datetime, last_sign_in_at: datetime, current_sign_in_ip: string, last_sign_in_ip: string, created_at: datetime, updated_at: datetime, admin: boolean, given_names: string, surname: string, dob: date, address: string, suburb: string, state: string, country: string, phone: string, interests: text, venue_manager: boolean, nickname: string, data_entry: boolean)>, #<ActiveModel::Validations::FormatValidator:0x000000089fe518 @attributes=[:email], @options={:with=>/\A[^@][email protected]([^@\.]+\.)+[^@\.]+\z/, :allow_blank=>true, :if=>:email_changed?}>, #<ActiveModel::Validations::PresenceValidator:0x00000008a874f8 @attributes=[:password], @options={:if=>:password_required?}>, #<ActiveModel::Validations::ConfirmationValidator:0x00000008abb5c8 @attributes=[:password], @options={:if=>:password_required?}>, #<ActiveModel::Validations::LengthValidator:0x00000008ae66d8 @attributes=[:password], @options={:allow_blank=>true, :minimum=>6, :maximum=>128}>] 
+0

設計只直接驗證'password'和'password_confirmation',而不''encrypted_pa​​ssword'。你可以添加一個測試'user.send(:password_required?)。should be_true'。如果此測試通過,則必須有其他驗證。 – scorix

+0

對於在用戶中登錄的Google和Twitter,password_required應該爲false。我已經在我的問題中更新了這個測試。所以看起來我一直在尋找錯誤的地方。由於某些原因,它們在一起運行所有測試時仍然失敗。 – map7

+0

您需要展示更多的用戶模型,比如scorix說,Devise的'encrypted_pa​​ssword'上沒有默認的在線驗證器。東西加了一個(無論你還是另一個寶石)。 –

回答

0

必須有一個PresenceValidator

運行此控制檯列出User模型的所有驗證回調:

# active_record 4 
p User.send(:get_callbacks, :validate).instance_variable_get(:@chain).map(&:filter) 

# active_record 3 
p User._validate_callbacks.map(&:raw_filter) 

查找驗證並刪除它。

相關問題