Index: chrome/browser/chromeos/login/quick_unlock/fingerprint_unlock_unittest.cc |
diff --git a/chrome/browser/chromeos/login/quick_unlock/fingerprint_unlock_unittest.cc b/chrome/browser/chromeos/login/quick_unlock/fingerprint_unlock_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..58fc12727f6f33b260b36c7bda06db5fd8ad8818 |
--- /dev/null |
+++ b/chrome/browser/chromeos/login/quick_unlock/fingerprint_unlock_unittest.cc |
@@ -0,0 +1,202 @@ |
+// Copyright 2017 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/browser/chromeos/login/quick_unlock/fingerprint_unlock.h" |
+#include "chrome/browser/chromeos/login/quick_unlock/fingerprint_unlock_factory.h" |
+#include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.h" |
+#include "chrome/common/pref_names.h" |
+#include "chrome/test/base/testing_profile.h" |
+#include "components/prefs/pref_service.h" |
+#include "content/public/test/test_browser_thread_bundle.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace chromeos { |
+namespace { |
+ |
+void SetConfirmationFrequency( |
+ PrefService* pref_service, |
+ quick_unlock::PasswordConfirmationFrequency frequency) { |
+ pref_service->SetInteger(prefs::kQuickUnlockTimeout, |
+ static_cast<int>(frequency)); |
+} |
+ |
+class FingerprintUnlockUnitTest : public testing::Test { |
+ protected: |
+ FingerprintUnlockUnitTest() : profile_(new TestingProfile()) {} |
+ ~FingerprintUnlockUnitTest() override {} |
+ |
+ // testing::Test: |
+ void SetUp() override { quick_unlock::EnableForTesting(); } |
+ |
+ content::TestBrowserThreadBundle thread_bundle_; |
+ std::unique_ptr<TestingProfile> profile_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(FingerprintUnlockUnitTest); |
+}; |
+ |
+} // namespace |
+ |
+// Provides test-only FingerprintUnlock APIs. |
+class FingerprintUnlockTestApi { |
+ public: |
+ // Does *not* take ownership over |fingerprint_unlock|. |
+ explicit FingerprintUnlockTestApi( |
+ quick_unlock::FingerprintUnlock* fingerprint_unlock) |
+ : fingerprint_unlock_(fingerprint_unlock) {} |
+ |
+ // Reduces the amount of strong auth time available by |time_delta|. |
+ void ReduceRemainingStrongAuthTimeBy(const base::TimeDelta& time_delta) { |
+ fingerprint_unlock_->last_strong_auth_ -= time_delta; |
+ } |
+ |
+ bool HasStrongAuthInfo() { |
+ return !fingerprint_unlock_->last_strong_auth_.is_null(); |
+ } |
+ |
+ void SetEnrollments(bool has_enrollments) { |
+ fingerprint_unlock_->has_enrollments_ = has_enrollments; |
+ } |
+ |
+ private: |
+ quick_unlock::FingerprintUnlock* fingerprint_unlock_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(FingerprintUnlockTestApi); |
+}; |
+ |
+// Verifies that: |
+// 1. Initial unlock attempt count is zero. |
+// 2. Attempting unlock attempts correctly increases unlock attempt count. |
+// 3. Resetting unlock attempt count correctly sets attempt count to 0. |
+TEST_F(FingerprintUnlockUnitTest, UnlockAttemptCount) { |
+ quick_unlock::FingerprintUnlock* fingerprint_unlock = |
+ quick_unlock::FingerprintUnlockFactory::GetForProfile(profile_.get()); |
+ |
+ EXPECT_EQ(0, fingerprint_unlock->unlock_attempt_count()); |
+ |
+ fingerprint_unlock->AddUnlockAttempt(); |
+ fingerprint_unlock->AddUnlockAttempt(); |
+ fingerprint_unlock->AddUnlockAttempt(); |
+ EXPECT_EQ(3, fingerprint_unlock->unlock_attempt_count()); |
+ |
+ fingerprint_unlock->ResetUnlockAttemptCount(); |
+ EXPECT_EQ(0, fingerprint_unlock->unlock_attempt_count()); |
+} |
+ |
+// Verifies that marking the strong auth makes TimeSinceLastStrongAuth a > zero |
+// value. |
+TEST_F(FingerprintUnlockUnitTest, TimeSinceLastStrongAuthReturnsPositiveValue) { |
+ quick_unlock::FingerprintUnlock* fingerprint_unlock = |
+ quick_unlock::FingerprintUnlockFactory::GetForProfile(profile_.get()); |
+ FingerprintUnlockTestApi test_api(fingerprint_unlock); |
+ |
+ EXPECT_FALSE(test_api.HasStrongAuthInfo()); |
+ |
+ fingerprint_unlock->MarkStrongAuth(); |
+ |
+ EXPECT_TRUE(test_api.HasStrongAuthInfo()); |
+ test_api.ReduceRemainingStrongAuthTimeBy(base::TimeDelta::FromSeconds(60)); |
+ |
+ EXPECT_TRUE(fingerprint_unlock->TimeSinceLastStrongAuth() >= |
+ base::TimeDelta::FromSeconds(30)); |
stevenjb
2017/02/27 17:25:34
It isn't clear whether 60 and 30 are arbitrary or
xiaoyinh(OOO Sep 11-29)
2017/02/27 21:36:42
Done.
|
+} |
+ |
+// Verifies that by altering the password confirmation preference, the |
+// fingerprint unlock will request password reconfirmation as expected. |
+TEST_F(FingerprintUnlockUnitTest, |
+ QuickUnlockPasswordConfirmationFrequencyPreference) { |
+ quick_unlock::FingerprintUnlock* fingerprint_unlock = |
+ quick_unlock::FingerprintUnlockFactory::GetForProfile(profile_.get()); |
+ PrefService* pref_service = profile_->GetPrefs(); |
+ FingerprintUnlockTestApi test_api(fingerprint_unlock); |
+ |
+ // The default is one day, so verify moving the last strong auth time back 13 |
+ // hours should not request strong auth. |
+ fingerprint_unlock->MarkStrongAuth(); |
+ test_api.ReduceRemainingStrongAuthTimeBy(base::TimeDelta::FromHours(13)); |
stevenjb
2017/02/27 17:25:34
Again, use named constants throughout.
xiaoyinh(OOO Sep 11-29)
2017/02/27 21:36:42
Done.
|
+ EXPECT_TRUE(fingerprint_unlock->HasStrongAuth()); |
+ |
+ // Verify moving the last strong auth time back another 13 hours should |
+ // request strong auth. |
+ test_api.ReduceRemainingStrongAuthTimeBy(base::TimeDelta::FromHours(13)); |
+ EXPECT_FALSE(fingerprint_unlock->HasStrongAuth()); |
+ |
+ // Verify that by changing the frequency of required password confirmation to |
+ // six hours, moving the last strong auth interval back by 4 hours will not |
+ // trigger a request for strong auth, but moving it by an additional 4 hours |
+ // will. |
+ fingerprint_unlock->MarkStrongAuth(); |
+ SetConfirmationFrequency( |
+ pref_service, quick_unlock::PasswordConfirmationFrequency::SIX_HOURS); |
+ test_api.ReduceRemainingStrongAuthTimeBy(base::TimeDelta::FromHours(4)); |
+ EXPECT_TRUE(fingerprint_unlock->HasStrongAuth()); |
+ test_api.ReduceRemainingStrongAuthTimeBy(base::TimeDelta::FromHours(4)); |
+ EXPECT_FALSE(fingerprint_unlock->HasStrongAuth()); |
+ |
+ // A valid strong auth becomes invalid if the confirmation frequency is |
+ // shortened to less than the expiration time. |
+ fingerprint_unlock->MarkStrongAuth(); |
+ SetConfirmationFrequency( |
+ pref_service, quick_unlock::PasswordConfirmationFrequency::TWELVE_HOURS); |
+ EXPECT_TRUE(fingerprint_unlock->HasStrongAuth()); |
+ test_api.ReduceRemainingStrongAuthTimeBy(base::TimeDelta::FromHours(8)); |
+ EXPECT_TRUE(fingerprint_unlock->HasStrongAuth()); |
+ SetConfirmationFrequency( |
+ pref_service, quick_unlock::PasswordConfirmationFrequency::SIX_HOURS); |
+ EXPECT_FALSE(fingerprint_unlock->HasStrongAuth()); |
+ |
+ // An expired strong auth becomes usable if the confirmation frequency gets |
+ // extended past the expiration time. |
+ fingerprint_unlock->MarkStrongAuth(); |
+ SetConfirmationFrequency( |
+ pref_service, quick_unlock::PasswordConfirmationFrequency::SIX_HOURS); |
+ EXPECT_TRUE(fingerprint_unlock->HasStrongAuth()); |
+ test_api.ReduceRemainingStrongAuthTimeBy(base::TimeDelta::FromHours(8)); |
+ EXPECT_FALSE(fingerprint_unlock->HasStrongAuth()); |
+ SetConfirmationFrequency( |
+ pref_service, quick_unlock::PasswordConfirmationFrequency::TWELVE_HOURS); |
+ EXPECT_TRUE(fingerprint_unlock->HasStrongAuth()); |
+} |
+ |
+// Verifies that authentication is not available when |
+// 1. No enrollments registered |
+// 2. Too many authentication attempts |
+// 3. No valid strong auth |
+TEST_F(FingerprintUnlockUnitTest, AuthenticationUnAvailable) { |
+ quick_unlock::FingerprintUnlock* fingerprint_unlock = |
+ quick_unlock::FingerprintUnlockFactory::GetForProfile(profile_.get()); |
+ FingerprintUnlockTestApi test_api(fingerprint_unlock); |
+ |
+ EXPECT_FALSE(test_api.HasStrongAuthInfo()); |
+ fingerprint_unlock->MarkStrongAuth(); |
+ EXPECT_TRUE(test_api.HasStrongAuthInfo()); |
+ |
+ EXPECT_FALSE(fingerprint_unlock->HasEnrollment()); |
+ test_api.SetEnrollments(true); |
+ EXPECT_TRUE(fingerprint_unlock->HasEnrollment()); |
+ EXPECT_EQ(0, fingerprint_unlock->unlock_attempt_count()); |
+ EXPECT_TRUE(fingerprint_unlock->IsFingerprintAuthenticationAvailable()); |
+ |
+ // No enrollment registered makes fingerprint authentication unavailable. |
+ test_api.SetEnrollments(false); |
+ EXPECT_FALSE(fingerprint_unlock->IsFingerprintAuthenticationAvailable()); |
+ test_api.SetEnrollments(true); |
+ EXPECT_TRUE(fingerprint_unlock->IsFingerprintAuthenticationAvailable()); |
+ |
+ // Too many authentication attempts make fingerprint authentication |
+ // unavailable. |
+ for (int i = 0; i < quick_unlock::FingerprintUnlock::kMaximumUnlockAttempts; |
+ ++i) |
+ fingerprint_unlock->AddUnlockAttempt(); |
stevenjb
2017/02/27 17:25:34
{}
xiaoyinh(OOO Sep 11-29)
2017/02/27 21:36:43
Done.
|
+ EXPECT_FALSE(fingerprint_unlock->IsFingerprintAuthenticationAvailable()); |
+ fingerprint_unlock->ResetUnlockAttemptCount(); |
+ EXPECT_TRUE(fingerprint_unlock->IsFingerprintAuthenticationAvailable()); |
+ |
+ // Strong auth becomes invalid after 1 day, and invalid strong auth makes |
+ // fingerprint authentication unavailable. |
+ test_api.ReduceRemainingStrongAuthTimeBy(base::TimeDelta::FromHours(24)); |
+ EXPECT_FALSE(fingerprint_unlock->HasStrongAuth()); |
+ EXPECT_FALSE(fingerprint_unlock->IsFingerprintAuthenticationAvailable()); |
+} |
+ |
+} // namespace chromeos |