Index: chrome/browser/chromeos/login/existing_user_controller_browsertest.cc |
diff --git a/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc b/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc |
index 9ffb78128b7cd3c39779e2330b910dfe9dfa2c76..bf4a3be5ccb5cc4784845787403378b3ff48ae60 100644 |
--- a/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc |
+++ b/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc |
@@ -3,9 +3,12 @@ |
// found in the LICENSE file. |
#include "base/bind.h" |
+#include "base/bind_helpers.h" |
#include "base/command_line.h" |
#include "base/compiler_specific.h" |
#include "base/memory/scoped_ptr.h" |
+#include "base/path_service.h" |
+#include "base/stl_util.h" |
#include "chrome/browser/chromeos/cros/cros_in_process_browser_test.h" |
#include "chrome/browser/chromeos/cros/cros_mock.h" |
#include "chrome/browser/chromeos/cros/mock_network_library.h" |
@@ -21,12 +24,25 @@ |
#include "chrome/browser/chromeos/login/mock_url_fetchers.h" |
#include "chrome/browser/chromeos/login/mock_user_manager.h" |
#include "chrome/browser/chromeos/login/wizard_controller.h" |
+#include "chrome/browser/chromeos/settings/cros_settings.h" |
+#include "chrome/browser/policy/browser_policy_connector.h" |
+#include "chrome/browser/policy/cloud_policy_constants.h" |
+#include "chrome/browser/policy/cloud_policy_store.h" |
+#include "chrome/browser/policy/device_local_account_policy_service.h" |
+#include "chrome/browser/policy/policy_builder.h" |
+#include "chrome/browser/policy/proto/chrome_device_policy.pb.h" |
+#include "chrome/common/chrome_notification_types.h" |
+#include "chrome/common/chrome_paths.h" |
#include "chrome/common/chrome_switches.h" |
+#include "chrome/test/base/testing_browser_process.h" |
#include "chrome/test/base/testing_profile.h" |
#include "chrome/test/base/ui_test_utils.h" |
+#include "chromeos/dbus/fake_session_manager_client.h" |
#include "chromeos/dbus/mock_dbus_thread_manager.h" |
#include "chromeos/dbus/mock_session_manager_client.h" |
#include "chromeos/dbus/mock_shill_manager_client.h" |
+#include "content/public/browser/notification_watcher.h" |
+#include "content/public/test/mock_notification_observer.h" |
#include "google_apis/gaia/mock_url_fetcher_factory.h" |
#include "grit/generated_resources.h" |
#include "testing/gmock/include/gmock/gmock.h" |
@@ -39,10 +55,13 @@ using ::testing::AnyOf; |
using ::testing::Invoke; |
using ::testing::InvokeWithoutArgs; |
using ::testing::Return; |
+using ::testing::ReturnRef; |
using ::testing::ReturnNull; |
using ::testing::Sequence; |
using ::testing::WithArg; |
+namespace em = enterprise_management; |
+ |
namespace chromeos { |
namespace { |
@@ -51,6 +70,11 @@ const char kUsername[] = "test_user@gmail.com"; |
const char kNewUsername[] = "test_new_user@gmail.com"; |
const char kPassword[] = "test_password"; |
+const char kAutoLoginUsername[] = "public_session_user@localhost"; |
+const int kAutoLoginNoDelay = 0; |
+const int kAutoLoginShortDelay = 100; |
+const int kAutoLoginLongDelay = 10000; |
+ |
class MockLoginDisplay : public LoginDisplay { |
public: |
MockLoginDisplay() |
@@ -102,6 +126,18 @@ class MockLoginDisplayHost : public LoginDisplayHost { |
DISALLOW_COPY_AND_ASSIGN(MockLoginDisplayHost); |
}; |
+class MockCloudPolicyStoreObserver : public policy::CloudPolicyStore::Observer { |
Mattias Nissler (ping if slow)
2013/03/01 10:37:21
There's a copy of this in mock_cloud_policy_store_
dconnelly
2013/03/06 10:02:59
Done.
|
+ public: |
+ MockCloudPolicyStoreObserver() { |
+ } |
+ |
+ MOCK_METHOD1(OnStoreLoaded, void(policy::CloudPolicyStore*)); |
+ MOCK_METHOD1(OnStoreError, void(policy::CloudPolicyStore*)); |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(MockCloudPolicyStoreObserver); |
+}; |
+ |
scoped_refptr<Authenticator> CreateAuthenticator( |
LoginStatusConsumer* consumer) { |
return new MockAuthenticator(consumer, kUsername, kPassword); |
@@ -112,6 +148,11 @@ scoped_refptr<Authenticator> CreateAuthenticatorNewUser( |
return new MockAuthenticator(consumer, kNewUsername, kPassword); |
} |
+scoped_refptr<Authenticator> CreateAuthenticatorPublicSession( |
Mattias Nissler (ping if slow)
2013/03/01 10:37:21
nit: Maybe rather CreateAuthenticatorForPublicSess
dconnelly
2013/03/06 10:02:59
Done.
|
+ LoginStatusConsumer* consumer) { |
+ return new MockAuthenticator(consumer, kAutoLoginUsername, ""); |
+} |
+ |
} // namespace |
class ExistingUserControllerTest : public CrosInProcessBrowserTest { |
@@ -144,6 +185,9 @@ class ExistingUserControllerTest : public CrosInProcessBrowserTest { |
EXPECT_CALL(*mock_dbus_thread_manager->mock_shill_manager_client(), |
RemovePropertyChangedObserver(_)) |
.Times(AnyNumber()); |
+ |
+ SetUpSessionManager(mock_dbus_thread_manager); |
+ |
DBusThreadManager::InitializeForTesting(mock_dbus_thread_manager); |
CrosInProcessBrowserTest::SetUpInProcessBrowserTestFixture(); |
cros_mock_->InitStatusAreaMocks(); |
@@ -155,13 +199,6 @@ class ExistingUserControllerTest : public CrosInProcessBrowserTest { |
EXPECT_CALL(*mock_network_library_, LoadOncNetworks(_, _, _, _)) |
.WillRepeatedly(Return(true)); |
- MockSessionManagerClient* mock_session_manager_client = |
- mock_dbus_thread_manager->mock_session_manager_client(); |
- EXPECT_CALL(*mock_session_manager_client, EmitLoginPromptReady()) |
- .Times(1); |
- EXPECT_CALL(*mock_session_manager_client, RetrieveDevicePolicy(_)) |
- .Times(AnyNumber()); |
- |
mock_login_utils_ = new MockLoginUtils(); |
LoginUtils::Set(mock_login_utils_); |
EXPECT_CALL(*mock_login_utils_, PrewarmAuthentication()) |
@@ -172,32 +209,52 @@ class ExistingUserControllerTest : public CrosInProcessBrowserTest { |
.Times(1); |
mock_login_display_host_.reset(new MockLoginDisplayHost()); |
+ mock_login_display_ = new MockLoginDisplay(); |
+ SetUpLoginDisplay(); |
+ } |
- EXPECT_CALL(*mock_user_manager_.user_manager(), IsKnownUser(kUsername)) |
+ virtual void SetUpSessionManager( |
+ MockDBusThreadManager* mock_dbus_thread_manager) { |
+ mock_user_manager_.reset(new ScopedMockUserManagerEnabler); |
+ EXPECT_CALL(*mock_user_manager_->user_manager(), IsKnownUser(kUsername)) |
.Times(AnyNumber()) |
.WillRepeatedly(Return(true)); |
- EXPECT_CALL(*mock_user_manager_.user_manager(), IsKnownUser(kNewUsername)) |
+ EXPECT_CALL(*mock_user_manager_->user_manager(), IsKnownUser(kNewUsername)) |
+ .Times(AnyNumber()) |
+ .WillRepeatedly(Return(false)); |
+ EXPECT_CALL(*mock_user_manager_->user_manager(), IsUserLoggedIn()) |
.Times(AnyNumber()) |
.WillRepeatedly(Return(false)); |
- EXPECT_CALL(*mock_user_manager_.user_manager(), IsUserLoggedIn()) |
+ EXPECT_CALL(*mock_user_manager_->user_manager(), IsLoggedInAsGuest()) |
.Times(AnyNumber()) |
.WillRepeatedly(Return(false)); |
- EXPECT_CALL(*mock_user_manager_.user_manager(), IsLoggedInAsGuest()) |
+ EXPECT_CALL(*mock_user_manager_->user_manager(), IsLoggedInAsDemoUser()) |
.Times(AnyNumber()) |
.WillRepeatedly(Return(false)); |
- EXPECT_CALL(*mock_user_manager_.user_manager(), IsLoggedInAsDemoUser()) |
+ EXPECT_CALL(*mock_user_manager_->user_manager(), |
+ IsLoggedInAsPublicAccount()) |
.Times(AnyNumber()) |
.WillRepeatedly(Return(false)); |
- EXPECT_CALL(*mock_user_manager_.user_manager(), IsLoggedInAsPublicAccount()) |
+ EXPECT_CALL(*mock_user_manager_->user_manager(), IsSessionStarted()) |
.Times(AnyNumber()) |
.WillRepeatedly(Return(false)); |
- EXPECT_CALL(*mock_user_manager_.user_manager(), IsSessionStarted()) |
+ EXPECT_CALL(*mock_user_manager_->user_manager(), IsCurrentUserNew()) |
.Times(AnyNumber()) |
.WillRepeatedly(Return(false)); |
+ EXPECT_CALL(*mock_user_manager_->user_manager(), Shutdown()) |
+ .Times(1); |
+ MockSessionManagerClient* mock_session_manager_client = |
+ mock_dbus_thread_manager->mock_session_manager_client(); |
+ EXPECT_CALL(*mock_session_manager_client, EmitLoginPromptReady()) |
+ .Times(1); |
+ EXPECT_CALL(*mock_session_manager_client, RetrieveDevicePolicy(_)) |
+ .Times(AnyNumber()); |
+ } |
+ |
+ virtual void SetUpLoginDisplay() { |
// |mock_login_display_| is owned by the ExistingUserController, which calls |
// CreateLoginDisplay() on the |mock_login_display_host_| to get it. |
- mock_login_display_ = new MockLoginDisplay(); |
EXPECT_CALL(*mock_login_display_host_.get(), CreateLoginDisplay(_)) |
.Times(1) |
.WillOnce(Return(mock_login_display_)); |
@@ -227,6 +284,12 @@ class ExistingUserControllerTest : public CrosInProcessBrowserTest { |
} |
virtual void CleanUpOnMainThread() OVERRIDE { |
+ // ExistingUserController must be deleted before the thread is cleaned up: |
+ // If there is an outstanding login attempt when ExistingUserController is |
+ // deleted, its LoginPerformer instance will be deleted, which in turn |
+ // deletes its OnlineAttemptHost instance. However, OnlineAttemptHost must |
+ // be deleted on the UI thread. |
+ existing_user_controller_.reset(); |
CrosInProcessBrowserTest::CleanUpOnMainThread(); |
testing_profile_.reset(NULL); |
} |
@@ -236,6 +299,32 @@ class ExistingUserControllerTest : public CrosInProcessBrowserTest { |
DBusThreadManager::Shutdown(); |
} |
+ // ExistingUserController private member accessors. |
+ base::OneShotTimer<ExistingUserController>* auto_login_timer() { |
+ return existing_user_controller()->auto_login_timer_.get(); |
+ } |
+ |
+ std::string auto_login_username() { |
+ return existing_user_controller()->public_session_auto_login_username_; |
+ } |
+ void set_auto_login_username(const std::string& username) { |
+ existing_user_controller()->public_session_auto_login_username_ = username; |
+ } |
+ |
+ int auto_login_delay() { |
+ return existing_user_controller()->public_session_auto_login_delay_; |
+ } |
+ void set_auto_login_delay(int delay) { |
+ existing_user_controller()->public_session_auto_login_delay_ = delay; |
+ } |
+ |
+ bool is_login_in_progress() { |
+ return existing_user_controller()->is_login_in_progress_; |
+ } |
+ void set_is_login_in_progress(bool is_login_in_progress) { |
+ existing_user_controller()->is_login_in_progress_ = is_login_in_progress; |
+ } |
+ |
scoped_ptr<ExistingUserController> existing_user_controller_; |
// These mocks are owned by CrosLibrary class. |
@@ -244,7 +333,7 @@ class ExistingUserControllerTest : public CrosInProcessBrowserTest { |
MockLoginDisplay* mock_login_display_; |
scoped_ptr<MockLoginDisplayHost> mock_login_display_host_; |
- ScopedMockUserManagerEnabler mock_user_manager_; |
+ scoped_ptr<ScopedMockUserManagerEnabler> mock_user_manager_; |
// Owned by LoginUtilsWrapper. |
MockLoginUtils* mock_login_utils_; |
@@ -286,7 +375,7 @@ IN_PROC_BROWSER_TEST_F(ExistingUserControllerTest, ExistingUserLogin) { |
EXPECT_CALL(*mock_login_display_host_, |
StartWizard(WizardController::kTermsOfServiceScreenName, NULL)) |
.Times(0); |
- EXPECT_CALL(*mock_user_manager_.user_manager(), IsCurrentUserNew()) |
+ EXPECT_CALL(*mock_user_manager_->user_manager(), IsCurrentUserNew()) |
.Times(AnyNumber()) |
.WillRepeatedly(Return(false)); |
existing_user_controller()->Login(kUsername, kPassword); |
@@ -301,7 +390,7 @@ IN_PROC_BROWSER_TEST_F(ExistingUserControllerTest, AutoEnrollAfterSignIn) { |
.Times(1); |
EXPECT_CALL(*mock_login_display_host_.get(), OnCompleteLogin()) |
.Times(1); |
- EXPECT_CALL(*mock_user_manager_.user_manager(), IsCurrentUserNew()) |
+ EXPECT_CALL(*mock_user_manager_->user_manager(), IsCurrentUserNew()) |
.Times(AnyNumber()) |
.WillRepeatedly(Return(false)); |
// The order of these expected calls matters: the UI if first disabled |
@@ -346,7 +435,7 @@ IN_PROC_BROWSER_TEST_F(ExistingUserControllerTest, |
.Times(1); |
EXPECT_CALL(*mock_login_display_host_.get(), OnCompleteLogin()) |
.Times(1); |
- EXPECT_CALL(*mock_user_manager_.user_manager(), IsCurrentUserNew()) |
+ EXPECT_CALL(*mock_user_manager_->user_manager(), IsCurrentUserNew()) |
.Times(AnyNumber()) |
.WillRepeatedly(Return(true)); |
@@ -366,4 +455,528 @@ IN_PROC_BROWSER_TEST_F(ExistingUserControllerTest, |
content::RunAllPendingInMessageLoop(); |
} |
+MATCHER_P(HasDetails, expected, "") { |
+ return expected == *content::Details<const std::string>(arg).ptr(); |
+} |
+ |
+class ExistingUserControllerPublicSessionTest |
+ : public ExistingUserControllerTest { |
Mattias Nissler (ping if slow)
2013/03/01 10:37:21
nit: 4 space indentation
dconnelly
2013/03/06 10:02:59
Done.
|
+ protected: |
+ ExistingUserControllerPublicSessionTest() { |
+ } |
+ |
+ virtual void SetUpOnMainThread() OVERRIDE { |
+ ExistingUserControllerTest::SetUpOnMainThread(); |
+ |
+ // Wait for the public session user to be created. |
+ if (!chromeos::UserManager::Get()->IsKnownUser(kAutoLoginUsername)) { |
+ content::NotificationWatcher( |
+ chrome::NOTIFICATION_USER_LIST_CHANGED, |
+ base::Bind(&chromeos::UserManager::IsKnownUser, |
+ base::Unretained(chromeos::UserManager::Get()), |
+ kAutoLoginUsername)).Run(); |
+ } |
+ |
+ // Wait for the device local account policy to be installed. |
+ MockCloudPolicyStoreObserver observer; |
+ content::MessageLoopRunner* runner = new content::MessageLoopRunner; |
+ policy::CloudPolicyStore* store = TestingBrowserProcess::GetGlobal()-> |
+ browser_policy_connector()->GetDeviceLocalAccountPolicyService()-> |
+ GetBrokerForAccount(kAutoLoginUsername)->core()->store(); |
+ store->AddObserver(&observer); |
+ EXPECT_CALL(observer, OnStoreLoaded(store)) |
+ .Times(1) |
+ .WillOnce(InvokeWithoutArgs(runner, &content::MessageLoopRunner::Quit)); |
+ runner->Run(); |
+ store->RemoveObserver(&observer); |
+ } |
+ |
+ virtual void SetUpSessionManager( |
+ MockDBusThreadManager* mock_dbus_thread_manager) OVERRIDE { |
+ EXPECT_CALL(*mock_dbus_thread_manager, GetSessionManagerClient()) |
+ .WillRepeatedly(Return(&session_manager_client_)); |
+ |
+ // Install the owner key. |
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
+ base::FilePath owner_key_file = temp_dir_.path().AppendASCII("owner.key"); |
+ std::vector<uint8> owner_key_bits; |
+ ASSERT_TRUE(device_policy_.signing_key()->ExportPublicKey(&owner_key_bits)); |
+ ASSERT_EQ( |
+ file_util::WriteFile( |
+ owner_key_file, |
+ reinterpret_cast<const char*>(vector_as_array(&owner_key_bits)), |
+ owner_key_bits.size()), |
+ static_cast<int>(owner_key_bits.size())); |
+ ASSERT_TRUE(PathService::Override(chrome::FILE_OWNER_KEY, owner_key_file)); |
+ |
+ // Setup the device policy. |
+ em::ChromeDeviceSettingsProto& proto(device_policy_.payload()); |
+ proto.mutable_device_local_accounts()->add_account()->set_id( |
+ kAutoLoginUsername); |
+ RefreshDevicePolicy(); |
+ |
+ // Setup the device local account policy. |
+ policy::UserPolicyBuilder device_local_account_policy; |
+ device_local_account_policy.policy_data().set_username(kAutoLoginUsername); |
+ device_local_account_policy.policy_data().set_policy_type( |
+ policy::dm_protocol::kChromePublicAccountPolicyType); |
+ device_local_account_policy.policy_data().set_settings_entity_id( |
+ kAutoLoginUsername); |
+ device_local_account_policy.Build(); |
+ session_manager_client_.set_device_local_account_policy( |
+ kAutoLoginUsername, |
+ device_local_account_policy.GetBlob()); |
+ } |
+ |
+ virtual void SetUpLoginDisplay() { |
+ EXPECT_CALL(*mock_login_display_host_.get(), CreateLoginDisplay(_)) |
+ .Times(1) |
+ .WillOnce(Return(mock_login_display_)); |
+ EXPECT_CALL(*mock_login_display_host_.get(), GetNativeWindow()) |
+ .Times(AnyNumber()) |
+ .WillRepeatedly(ReturnNull()); |
+ EXPECT_CALL(*mock_login_display_host_.get(), OnPreferencesChanged()) |
+ .Times(AnyNumber()); |
+ EXPECT_CALL(*mock_login_display_, Init(_, _, _, _)) |
+ .Times(AnyNumber()); |
+ } |
+ |
+ void DisableAutoLoginPolicyNotifications() { |
Mattias Nissler (ping if slow)
2013/03/01 10:37:21
Yikes, why is this necessary?
dconnelly
2013/03/06 10:02:59
So that the auto-login timer delay and username ca
|
+ CrosSettings::Get()->RemoveSettingsObserver( |
+ kAccountsPrefDeviceLocalAccountAutoLoginId, |
+ existing_user_controller()); |
+ CrosSettings::Get()->RemoveSettingsObserver( |
+ kAccountsPrefDeviceLocalAccountAutoLoginDelay, |
+ existing_user_controller()); |
+ } |
+ |
+ void ExpectSuccessfulLogin(const std::string& username, |
+ const std::string& password, |
+ scoped_refptr<Authenticator> create_authenticator( |
+ LoginStatusConsumer* consumer)) { |
+ EXPECT_CALL(*mock_login_display_, SetUIEnabled(false)) |
+ .Times(AnyNumber()); |
+ EXPECT_CALL(*mock_login_utils_, CreateAuthenticator(_)) |
+ .Times(1) |
+ .WillOnce(WithArg<0>(Invoke(create_authenticator))); |
+ EXPECT_CALL(*mock_login_utils_, |
+ PrepareProfile(username, _, password, _, _, _)) |
+ .Times(1) |
+ .WillOnce(InvokeWithoutArgs(&profile_prepared_cb_, |
+ &base::Callback<void(void)>::Run)); |
+ EXPECT_CALL(*mock_login_utils_, |
+ DoBrowserLaunch(testing_profile_.get(), |
+ mock_login_display_host_.get())) |
+ .Times(1); |
+ EXPECT_CALL(*mock_login_display_, OnLoginSuccess(username)) |
+ .Times(1); |
+ EXPECT_CALL(*mock_login_display_, SetUIEnabled(true)) |
+ .Times(1); |
+ EXPECT_CALL(*mock_login_display_, OnFadeOut()) |
+ .Times(1); |
+ EXPECT_CALL(*mock_login_display_host_, |
+ StartWizard(WizardController::kTermsOfServiceScreenName, NULL)) |
+ .Times(0); |
+ } |
+ |
+ content::MessageLoopRunner* CreateSettingsObserverRunLoop( |
+ content::MockNotificationObserver& observer, const char* setting) { |
+ content::MessageLoopRunner* runner = new content::MessageLoopRunner; |
+ EXPECT_CALL(observer, Observe(chrome::NOTIFICATION_SYSTEM_SETTING_CHANGED, |
+ _, HasDetails(setting))) |
+ .Times(1) |
+ .WillOnce(InvokeWithoutArgs(runner, &content::MessageLoopRunner::Quit)); |
+ CrosSettings::Get()->AddSettingsObserver(setting, &observer); |
+ return runner; |
+ } |
+ |
+ void RefreshDevicePolicy() { |
+ // Reset the key to its original state. |
+ device_policy_.set_signing_key( |
+ policy::PolicyBuilder::CreateTestSigningKey()); |
+ device_policy_.Build(); |
+ // Clear the key so the device can't write owner settings. |
Mattias Nissler (ping if slow)
2013/03/01 10:37:21
Can you elaborate? Personally, I know what's going
Nikita (slow)
2013/03/06 17:07:16
nit: This comment was not addressed.
dconnelly
2013/03/07 08:38:00
Thank you. Done.
|
+ device_policy_.set_signing_key( |
+ make_scoped_ptr<crypto::RSAPrivateKey>(NULL)); |
+ device_policy_.set_new_signing_key( |
+ make_scoped_ptr<crypto::RSAPrivateKey>(NULL)); |
+ session_manager_client_.set_device_policy(device_policy_.GetBlob()); |
+ } |
+ |
+ void SetAutoLoginPolicy(const std::string& username, int delay) { |
+ // Wait until ExistingUserController has finished auto-login |
+ // configuration by observing the same settings that trigger |
+ // ConfigurePublicSessionAutoLogin. |
+ content::MockNotificationObserver observer; |
+ |
+ em::ChromeDeviceSettingsProto& proto(device_policy_.payload()); |
+ |
+ // If both settings have changed we need to wait for both to |
+ // propagate, so check the new values against the old ones. |
+ content::MessageLoopRunner* runner1 = NULL; |
+ if (!proto.has_device_local_accounts() || |
+ !proto.device_local_accounts().has_auto_login_id() || |
+ proto.device_local_accounts().auto_login_id() != username) { |
+ runner1 = CreateSettingsObserverRunLoop( |
+ observer, kAccountsPrefDeviceLocalAccountAutoLoginId); |
+ } |
+ content::MessageLoopRunner* runner2 = NULL; |
+ if (!proto.has_device_local_accounts() || |
+ !proto.device_local_accounts().has_auto_login_delay() || |
+ proto.device_local_accounts().auto_login_delay() != delay) { |
+ runner2 = CreateSettingsObserverRunLoop( |
+ observer, kAccountsPrefDeviceLocalAccountAutoLoginDelay); |
+ } |
+ |
+ // Update the policy. |
+ proto.mutable_device_local_accounts()->set_auto_login_id(username); |
+ proto.mutable_device_local_accounts()->set_auto_login_delay(delay); |
+ RefreshDevicePolicy(); |
Mattias Nissler (ping if slow)
2013/03/01 10:37:21
How does this ensure that ExistingUserController a
dconnelly
2013/03/06 10:02:59
That's the next line few lines (Run()). I've clar
|
+ |
+ // Wait for ExistingUserController. |
+ if (runner1) |
+ runner1->Run(); |
+ if (runner2) |
+ runner2->Run(); |
+ |
+ // Clean up. |
+ CrosSettings::Get()->RemoveSettingsObserver( |
+ kAccountsPrefDeviceLocalAccountAutoLoginId, |
+ &observer); |
+ CrosSettings::Get()->RemoveSettingsObserver( |
+ kAccountsPrefDeviceLocalAccountAutoLoginDelay, |
+ &observer); |
+ } |
+ |
+ void ConfigureAutoLogin() { |
+ existing_user_controller()->ConfigurePublicSessionAutoLogin(); |
+ } |
+ |
+ void FireAutoLogin() { |
+ existing_user_controller()->OnPublicSessionAutoLoginTimerFire(); |
+ } |
+ |
+ // Enables public sessions in tests. |
Mattias Nissler (ping if slow)
2013/03/01 10:37:21
Not entirely accurate. Actually it mocks out sessi
dconnelly
2013/03/06 10:02:59
Done.
|
+ FakeSessionManagerClient session_manager_client_; |
+ |
+ // Stores the device owner key. |
+ base::ScopedTempDir temp_dir_; |
+ |
+ // Carries Chrome OS device policies for tests. |
+ policy::DevicePolicyBuilder device_policy_; |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(ExistingUserControllerPublicSessionTest); |
+}; |
+ |
+IN_PROC_BROWSER_TEST_F(ExistingUserControllerPublicSessionTest, |
+ StartAutoLoginTimer) { |
+ DisableAutoLoginPolicyNotifications(); |
+ |
+ // Timer shouldn't start until signin screen is ready. |
+ set_auto_login_username(kAutoLoginUsername); |
+ set_auto_login_delay(kAutoLoginLongDelay); |
+ existing_user_controller()->StartPublicSessionAutoLoginTimer(); |
+ EXPECT_FALSE(auto_login_timer()); |
+ |
+ // Timer shouldn't start if the policy isn't set. |
+ set_auto_login_username(""); |
+ existing_user_controller()->OnSigninScreenReady(); |
+ existing_user_controller()->StartPublicSessionAutoLoginTimer(); |
+ EXPECT_FALSE(auto_login_timer()); |
+ |
+ // Timer shouldn't fire in the middle of a login attempt. |
+ set_auto_login_username(kAutoLoginUsername); |
+ set_is_login_in_progress(true); |
+ existing_user_controller()->StartPublicSessionAutoLoginTimer(); |
+ EXPECT_FALSE(auto_login_timer()); |
+ |
+ // Otherwise start. |
+ set_is_login_in_progress(false); |
+ existing_user_controller()->StartPublicSessionAutoLoginTimer(); |
+ ASSERT_TRUE(auto_login_timer()); |
+ EXPECT_TRUE(auto_login_timer()->IsRunning()); |
+ EXPECT_EQ(auto_login_timer()->GetCurrentDelay().InMilliseconds(), |
+ kAutoLoginLongDelay); |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(ExistingUserControllerPublicSessionTest, |
+ StopAutoLoginTimer) { |
+ existing_user_controller()->OnSigninScreenReady(); |
+ set_auto_login_username(kAutoLoginUsername); |
+ set_auto_login_delay(kAutoLoginLongDelay); |
+ |
+ existing_user_controller()->StartPublicSessionAutoLoginTimer(); |
+ ASSERT_TRUE(auto_login_timer()); |
+ EXPECT_TRUE(auto_login_timer()->IsRunning()); |
+ |
+ existing_user_controller()->StopPublicSessionAutoLoginTimer(); |
+ ASSERT_TRUE(auto_login_timer()); |
+ EXPECT_FALSE(auto_login_timer()->IsRunning()); |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(ExistingUserControllerPublicSessionTest, |
+ ResetAutoLoginTimer) { |
+ existing_user_controller()->OnSigninScreenReady(); |
+ set_auto_login_username(kAutoLoginUsername); |
+ |
+ // Timer starts off not running. |
+ EXPECT_FALSE(auto_login_timer()); |
+ |
+ // When the timer isn't running, nothing should happen. |
+ existing_user_controller()->ResetPublicSessionAutoLoginTimer(); |
+ EXPECT_FALSE(auto_login_timer()); |
+ |
+ // Start the timer. |
+ set_auto_login_delay(kAutoLoginLongDelay); |
+ existing_user_controller()->StartPublicSessionAutoLoginTimer(); |
+ ASSERT_TRUE(auto_login_timer()); |
+ EXPECT_TRUE(auto_login_timer()->IsRunning()); |
+ EXPECT_EQ(auto_login_timer()->GetCurrentDelay().InMilliseconds(), |
+ kAutoLoginLongDelay); |
+ |
+ // User activity should restart the timer, so check to see that the |
+ // timer delay was modified. |
+ set_auto_login_delay(kAutoLoginShortDelay); |
+ existing_user_controller()->ResetPublicSessionAutoLoginTimer(); |
+ ASSERT_TRUE(auto_login_timer()); |
+ EXPECT_TRUE(auto_login_timer()->IsRunning()); |
+ EXPECT_EQ(auto_login_timer()->GetCurrentDelay().InMilliseconds(), |
+ kAutoLoginShortDelay); |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(ExistingUserControllerPublicSessionTest, |
+ ConfigureAutoLogin) { |
+ existing_user_controller()->OnSigninScreenReady(); |
+ |
+ // Turn off settings notifications to ExistingUserController. |
+ DisableAutoLoginPolicyNotifications(); |
+ |
+ // Timer shouldn't start when the policy is disabled. |
+ SetAutoLoginPolicy("", 0); |
+ ConfigureAutoLogin(); |
+ EXPECT_FALSE(auto_login_timer()); |
+ EXPECT_EQ(auto_login_delay(), 0); |
+ EXPECT_EQ(auto_login_username(), ""); |
+ |
+ // Timer shouldn't start when the delay alone is set. |
+ SetAutoLoginPolicy("", kAutoLoginShortDelay); |
+ ConfigureAutoLogin(); |
+ EXPECT_FALSE(auto_login_timer()); |
+ EXPECT_EQ(auto_login_delay(), kAutoLoginShortDelay); |
+ EXPECT_EQ(auto_login_username(), ""); |
+ |
+ // Timer should start when the username is set. |
+ SetAutoLoginPolicy(kAutoLoginUsername, kAutoLoginShortDelay); |
+ ConfigureAutoLogin(); |
+ ASSERT_TRUE(auto_login_timer()); |
+ EXPECT_TRUE(auto_login_timer()->IsRunning()); |
+ EXPECT_EQ(auto_login_timer()->GetCurrentDelay().InMilliseconds(), |
+ kAutoLoginShortDelay); |
+ EXPECT_EQ(auto_login_delay(), kAutoLoginShortDelay); |
+ EXPECT_EQ(auto_login_username(), kAutoLoginUsername); |
+ |
+ // Timer should restart when the delay is changed. |
+ SetAutoLoginPolicy(kAutoLoginUsername, kAutoLoginLongDelay); |
+ ConfigureAutoLogin(); |
+ ASSERT_TRUE(auto_login_timer()); |
+ EXPECT_TRUE(auto_login_timer()->IsRunning()); |
+ EXPECT_EQ(auto_login_timer()->GetCurrentDelay().InMilliseconds(), |
+ kAutoLoginLongDelay); |
+ EXPECT_EQ(auto_login_delay(), kAutoLoginLongDelay); |
+ EXPECT_EQ(auto_login_username(), kAutoLoginUsername); |
+ |
+ // Timer should stop when the username is unset. |
+ SetAutoLoginPolicy("", kAutoLoginLongDelay); |
+ ConfigureAutoLogin(); |
+ ASSERT_TRUE(auto_login_timer()); |
+ EXPECT_FALSE(auto_login_timer()->IsRunning()); |
+ EXPECT_EQ(auto_login_timer()->GetCurrentDelay().InMilliseconds(), |
+ kAutoLoginLongDelay); |
+ EXPECT_EQ(auto_login_username(), ""); |
+ EXPECT_EQ(auto_login_delay(), kAutoLoginLongDelay); |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(ExistingUserControllerPublicSessionTest, |
+ ConfigureAutoLoginUsingPolicy) { |
+ existing_user_controller()->OnSigninScreenReady(); |
+ EXPECT_EQ("", auto_login_username()); |
+ EXPECT_EQ(0, auto_login_delay()); |
+ EXPECT_FALSE(auto_login_timer()); |
+ |
+ // Set the policy. |
+ SetAutoLoginPolicy(kAutoLoginUsername, kAutoLoginLongDelay); |
+ EXPECT_EQ(kAutoLoginUsername, auto_login_username()); |
+ EXPECT_EQ(kAutoLoginLongDelay, auto_login_delay()); |
+ ASSERT_TRUE(auto_login_timer()); |
+ EXPECT_TRUE(auto_login_timer()->IsRunning()); |
+ |
+ // Unset the policy. |
+ SetAutoLoginPolicy("", 0); |
+ EXPECT_EQ("", auto_login_username()); |
+ EXPECT_EQ(0, auto_login_delay()); |
+ ASSERT_TRUE(auto_login_timer()); |
+ EXPECT_FALSE(auto_login_timer()->IsRunning()); |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(ExistingUserControllerPublicSessionTest, |
+ OnAutoLoginFire) { |
+ // Set up mocks to check login success. |
+ ExpectSuccessfulLogin(kAutoLoginUsername, "", |
+ CreateAuthenticatorPublicSession); |
+ existing_user_controller()->OnSigninScreenReady(); |
+ |
+ // Directly set auto-login parameters to avoid starting the timer. |
+ set_auto_login_username(kAutoLoginUsername); |
+ set_auto_login_delay(kAutoLoginLongDelay); |
+ |
+ // Manually fire auto-login and wait for the login tasks to complete. |
+ FireAutoLogin(); |
+ content::RunAllPendingInMessageLoop(); |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(ExistingUserControllerPublicSessionTest, |
+ AutoLoginNoDelay) { |
+ // Set up mocks to check login success. |
+ ExpectSuccessfulLogin(kAutoLoginUsername, "", |
+ CreateAuthenticatorPublicSession); |
+ existing_user_controller()->OnSigninScreenReady(); |
+ |
+ // Start auto-login and wait for login tasks to complete. |
+ SetAutoLoginPolicy(kAutoLoginUsername, kAutoLoginNoDelay); |
+ content::RunAllPendingInMessageLoop(); |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(ExistingUserControllerPublicSessionTest, |
+ AutoLoginShortDelay) { |
+ // Set up mocks to check login success. |
+ ExpectSuccessfulLogin(kAutoLoginUsername, "", |
+ CreateAuthenticatorPublicSession); |
+ existing_user_controller()->OnSigninScreenReady(); |
+ SetAutoLoginPolicy(kAutoLoginUsername, kAutoLoginShortDelay); |
+ ASSERT_TRUE(auto_login_timer()); |
+ ASSERT_TRUE(auto_login_timer()->IsRunning()); |
+ |
+ // Wait for the timer to fire. |
Mattias Nissler (ping if slow)
2013/03/01 10:37:21
It looks like you're actually waiting. That'll jus
Nikita (slow)
2013/03/04 15:52:08
Take a look at this issue
https://code.google.com/
dconnelly
2013/03/06 10:02:59
Okay, so I've dug into how I can avoid waiting. T
|
+ content::MessageLoopRunner* runner = new content::MessageLoopRunner; |
+ base::OneShotTimer<content::MessageLoopRunner> timer; |
+ timer.Start(FROM_HERE, |
+ base::TimeDelta::FromMilliseconds(2 * kAutoLoginShortDelay), |
+ base::Bind(&content::MessageLoopRunner::Quit, |
+ base::Unretained(runner))); |
+ runner->Run(); |
+ |
+ // Wait for login tasks to complete. |
+ content::RunAllPendingInMessageLoop(); |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(ExistingUserControllerPublicSessionTest, |
+ LoginStopsAutoLogin) { |
+ // Set up mocks to check login success. |
+ ExpectSuccessfulLogin(kUsername, kPassword, CreateAuthenticator); |
+ |
+ existing_user_controller()->OnSigninScreenReady(); |
+ set_auto_login_username(kAutoLoginUsername); |
+ set_auto_login_delay(kAutoLoginLongDelay); |
+ existing_user_controller()->StartPublicSessionAutoLoginTimer(); |
+ ASSERT_TRUE(auto_login_timer()); |
+ EXPECT_TRUE(auto_login_timer()->IsRunning()); |
+ |
+ // Login and check that it stopped the timer. |
+ existing_user_controller()->Login(kUsername, kPassword); |
+ EXPECT_TRUE(is_login_in_progress()); |
+ ASSERT_TRUE(auto_login_timer()); |
+ EXPECT_FALSE(auto_login_timer()->IsRunning()); |
+ |
+ // Wait for login tasks to complete. |
+ content::RunAllPendingInMessageLoop(); |
+ |
+ // Timer should still be stopped after login completes. |
+ ASSERT_TRUE(auto_login_timer()); |
+ EXPECT_FALSE(auto_login_timer()->IsRunning()); |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(ExistingUserControllerPublicSessionTest, |
+ GuestModeLoginStopsAutoLogin) { |
+ EXPECT_CALL(*mock_login_display_, SetUIEnabled(false)) |
+ .Times(1); |
+ EXPECT_CALL(*mock_login_utils_, CreateAuthenticator(_)) |
+ .Times(1) |
+ .WillOnce(WithArg<0>(Invoke(CreateAuthenticator))); |
+ ScopedMockUserManagerEnabler mock_user_manager; |
+ EXPECT_CALL(*mock_login_utils_, CompleteOffTheRecordLogin(_)) |
+ .Times(1); |
+ |
+ existing_user_controller()->OnSigninScreenReady(); |
+ set_auto_login_username(kAutoLoginUsername); |
+ set_auto_login_delay(kAutoLoginLongDelay); |
+ existing_user_controller()->StartPublicSessionAutoLoginTimer(); |
+ ASSERT_TRUE(auto_login_timer()); |
+ EXPECT_TRUE(auto_login_timer()->IsRunning()); |
+ |
+ // Login and check that it stopped the timer. |
+ existing_user_controller()->LoginAsGuest(); |
+ EXPECT_TRUE(is_login_in_progress()); |
+ ASSERT_TRUE(auto_login_timer()); |
+ EXPECT_FALSE(auto_login_timer()->IsRunning()); |
+ |
+ // Wait for login tasks to complete. |
+ content::RunAllPendingInMessageLoop(); |
+ |
+ // Timer should still be stopped after login completes. |
+ ASSERT_TRUE(auto_login_timer()); |
+ EXPECT_FALSE(auto_login_timer()->IsRunning()); |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(ExistingUserControllerPublicSessionTest, |
+ CompleteLoginStopsAutoLogin) { |
+ // Set up mocks to check login success. |
+ ExpectSuccessfulLogin(kUsername, kPassword, CreateAuthenticator); |
+ EXPECT_CALL(*mock_login_display_host_, OnCompleteLogin()) |
+ .Times(1); |
+ |
+ existing_user_controller()->OnSigninScreenReady(); |
+ set_auto_login_username(kAutoLoginUsername); |
+ set_auto_login_delay(kAutoLoginLongDelay); |
+ existing_user_controller()->StartPublicSessionAutoLoginTimer(); |
+ ASSERT_TRUE(auto_login_timer()); |
+ EXPECT_TRUE(auto_login_timer()->IsRunning()); |
+ |
+ // Check that login completes and stops the timer. |
+ existing_user_controller()->CompleteLogin(kUsername, kPassword); |
+ ASSERT_TRUE(auto_login_timer()); |
+ EXPECT_FALSE(auto_login_timer()->IsRunning()); |
+ |
+ // Wait for login tasks to complete. |
+ content::RunAllPendingInMessageLoop(); |
+ |
+ // Timer should still be stopped after login completes. |
+ ASSERT_TRUE(auto_login_timer()); |
+ EXPECT_FALSE(auto_login_timer()->IsRunning()); |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(ExistingUserControllerPublicSessionTest, |
+ PublicSessionLoginStopsAutoLogin) { |
+ // Set up mocks to check login success. |
+ ExpectSuccessfulLogin(kAutoLoginUsername, "", |
+ CreateAuthenticatorPublicSession); |
+ existing_user_controller()->OnSigninScreenReady(); |
+ SetAutoLoginPolicy(kAutoLoginUsername, kAutoLoginShortDelay); |
+ ASSERT_TRUE(auto_login_timer()); |
+ EXPECT_TRUE(auto_login_timer()->IsRunning()); |
+ |
+ // Login and check that it stopped the timer. |
+ existing_user_controller()->LoginAsPublicAccount(kAutoLoginUsername); |
+ EXPECT_TRUE(is_login_in_progress()); |
+ ASSERT_TRUE(auto_login_timer()); |
+ EXPECT_FALSE(auto_login_timer()->IsRunning()); |
+ |
+ // Wait for login tasks to complete. |
+ content::RunAllPendingInMessageLoop(); |
+ |
+ // Timer should still be stopped after login completes. |
+ ASSERT_TRUE(auto_login_timer()); |
+ EXPECT_FALSE(auto_login_timer()->IsRunning()); |
+} |
+ |
} // namespace chromeos |