1

これは簡単な質問だと思いますが、答えを見つけるのに苦労しました。Railsプロジェクトで認証用のデバイスを設定しましたが、うまく機能しています。パスワードの検証とログイン要件もカスタマイズしました。具体的には、ユーザー名または電子メールのいずれかでログインできる必要があり、電子メールでは大文字と小文字が区別されないようにする必要があります。

モデル仕様でこれをテストするにはどうすればよいですか?具体的にはテスト:

  1. 電子メール(すべて下位)でログインし、パスワードは有効です
  2. メール(すべて上)でログインし、パスワードは有効です
  3. ユーザー名とパスワードでのログインは有効です
  4. ユーザー名(ごちゃ混ぜの場合)でログインし、パスワードが無効です

基本的に、ログインの詳細を取り込んで、deviseがそれを認証するかどうかを教えてくれる関数が1つ必要です。しかし、私はそのような関数をデバイスのドキュメントでそのような関数を構築するための例や方法で見つけることができません。

私はそれが実際に機能していると確信しており、私のリクエスト仕様でテストできますが、モデルで定義されているので、モデルテストでもあるはずだと感じています。

私が定期的に見つけた唯一の工夫テストはコントローラーであり、ログインの詳細を必要とせずにユーザーに自動的にサインインするだけなので役に立ちません。

4

1 に答える 1

3

ここには、2つの異なるコンポーネントがあります。

1)ユーザーの検索
2)ユーザーのパスワードの検証

ユーザーの検索はfind_for_database_authenticationユーザー名と電子メールを「ログイン」で処理するための情報)によって処理されます。

パスワードの検証は、valid_password?メソッド(info)によって処理されます。

したがって、このテストを次のように分割する必要があります。

context "finding a user" do
  let(:user) { FactoryGirl.create(:user) }

  it "can find by lower email" do
    User.find_for_database_authentication( {login: user.email.downcase} ).should eq(user)
  end

  it "can find by upper email" do
    User.find_for_database_authentication( {login: user.email.upcase} ).should eq(user)
  end

  it "can find by jumbled username" do
    scrambled_username = user.username.downcase.chars.map{|c| rand() > 0.5 ? c.capitalize : c}.join
    User.find_for_database_authentication( {login: username} ).should eq(user)
  end
end

context "authenticating a user" do
  let(:user) { FactoryGirl.create(:user, password: "password123", password_confirmation: "password123") }

  it "will validate a correct password" do
    user.valid_password?("password123").should be_true
  end
  it "will not validate an incorrect password" do
    user.valid_password?("bad-password").should be_false
  end
end
于 2012-10-10T23:55:07.440 に答える