У меня есть модель User
и модель Authentications
, которая является базовой настройкой omniauth.По сути, пользователи могут зарегистрироваться через oauth без установки пароля.
У меня есть метод Authentication.is_destroyable?
, который возвращает true, если у пользователя есть пароль или несколько аутентификаций.По сути, это предотвращает удаление пользователями их единственного и единственного способа аутентификации.
def is_destroyable?
if user.encrypted_password.present? || user.authentications.count > 1
true
else
errors.add :base, 'not allowed'
false
end
end
При тестировании этого в разработке он работает, как и ожидалось, при любых условиях.Однако мои юнит-тесты провалились:
describe "Authentication#is_destroyable?" do
before(:each) do
# This creates a user with no password and a single authentication
@user = FactoryGirl.create(:user_with_oauth)
@auth = @user.authentications.first
end
# This spec passes :)
it "should return false when is users only authentication method" do
@auth.is_destroyable?.should be_false
end
# This FAILS - I have no idea why :(
it "should return true when user has multiple authentications" do
@user.authentications.create FactoryGirl.attributes_for(:authentication, :provider => 'twitter')
@auth.is_destroyable?.should be_true
end
# This FAILS - I have no idea why :(
it "should return true when user has a password" do
@user.update_attributes :password => 'password'
@auth.is_destroyable?.should be_true
end
end
Я потратил лучшую часть из трех часов, стуча головой о стену.Я не могу понять, почему это работает, когда я вручную тестирую функциональность (и истории о Cucumber проходят также тестирование функциональности), но в rspec модульные тесты не проходят.Есть ли что-то очевидное, что я упускаю?
Редактировать
В соответствии с просьбой, здесь есть некоторые дополнительные детали.
Обе ошибочные спецификации завершаются с:
Failure/Error: @auth.is_destroyable?.should be_true
expected false to be true
Фабрики:
FactoryGirl.define do
factory :user do
username { FactoryGirl.generate(:username) }
name 'Test User'
email { FactoryGirl.generate(:email) }
password 'password'
end
factory :user_with_oauth, :parent => :user do
password nil
authentications [ FactoryGirl.build(:authentication) ]
end
factory :authentication do
provider 'facebook'
uid SecureRandom.hex(16)
end
end
Также, возможно, актуально, я использую DatabaseCleaner со стратегией усечения .