blob: 68e267cc6c887a4ae897d99cc73ff68bf6bb4821 [file] [log] [blame]
// Copyright 2013 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 <string>
#include "base/message_loop/message_loop.h"
#include "base/values.h"
#include "chrome/browser/chromeos/login/existing_user_controller.h"
#include "chrome/browser/chromeos/login/mock_login_display.h"
#include "chrome/browser/chromeos/login/mock_login_display_host.h"
#include "chrome/browser/chromeos/login/mock_login_utils.h"
#include "chrome/browser/chromeos/login/mock_user_manager.h"
#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/chromeos/policy/device_local_account.h"
#include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/chromeos/settings/cros_settings_names.h"
#include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
#include "chrome/test/base/scoped_testing_local_state.h"
#include "chrome/test/base/testing_browser_process.h"
#include "content/public/test/test_browser_thread.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using testing::AnyNumber;
using testing::Return;
using testing::ReturnNull;
using testing::_;
namespace chromeos {
namespace {
const char kAutoLoginAccountId[] = "public_session_user@localhost";
// These values are only used to test the configuration. They don't
// delay the test.
const int kAutoLoginNoDelay = 0;
const int kAutoLoginDelay1 = 60000;
const int kAutoLoginDelay2 = 180000;
} // namespace
class ExistingUserControllerAutoLoginTest : public ::testing::Test {
protected:
ExistingUserControllerAutoLoginTest()
: auto_login_user_id_(policy::GenerateDeviceLocalAccountUserId(
kAutoLoginAccountId,
policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION)),
message_loop_(base::MessageLoop::TYPE_UI),
ui_thread_(content::BrowserThread::UI, &message_loop_),
local_state_(TestingBrowserProcess::GetGlobal()),
mock_user_manager_(new MockUserManager()),
scoped_user_manager_(mock_user_manager_) {
}
virtual void SetUp() {
mock_login_display_host_.reset(new MockLoginDisplayHost);
mock_login_display_ = new MockLoginDisplay();
mock_login_utils_ = new MockLoginUtils();
LoginUtils::Set(mock_login_utils_);
EXPECT_CALL(*mock_login_display_host_.get(), CreateLoginDisplay(_))
.Times(1)
.WillOnce(Return(mock_login_display_));
EXPECT_CALL(*mock_login_utils_, DelegateDeleted(_)).Times(AnyNumber());
EXPECT_CALL(*mock_user_manager_, Shutdown()).Times(AnyNumber());
EXPECT_CALL(*mock_user_manager_, FindUser(_))
.WillRepeatedly(ReturnNull());
EXPECT_CALL(*mock_user_manager_, FindUser(auto_login_user_id_))
.WillRepeatedly(Return(
mock_user_manager_->CreatePublicAccountUser(auto_login_user_id_)));
existing_user_controller_.reset(
new ExistingUserController(mock_login_display_host_.get()));
scoped_ptr<base::DictionaryValue> account(new base::DictionaryValue);
account->SetStringWithoutPathExpansion(
kAccountsPrefDeviceLocalAccountsKeyId,
kAutoLoginAccountId);
account->SetIntegerWithoutPathExpansion(
kAccountsPrefDeviceLocalAccountsKeyType,
policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION);
base::ListValue accounts;
accounts.Append(account.release());
CrosSettings::Get()->Set(kAccountsPrefDeviceLocalAccounts, accounts);
// Prevent settings changes from auto-starting the timer.
existing_user_controller_->
local_account_auto_login_id_subscription_.reset();
existing_user_controller_->
local_account_auto_login_delay_subscription_.reset();
}
const ExistingUserController* existing_user_controller() const {
return ExistingUserController::current_controller();
}
ExistingUserController* existing_user_controller() {
return ExistingUserController::current_controller();
}
void SetAutoLoginSettings(const std::string& account_id, int delay) {
CrosSettings::Get()->SetString(
kAccountsPrefDeviceLocalAccountAutoLoginId,
account_id);
CrosSettings::Get()->SetInteger(
kAccountsPrefDeviceLocalAccountAutoLoginDelay,
delay);
}
// ExistingUserController private member accessors.
base::OneShotTimer<ExistingUserController>* auto_login_timer() {
return existing_user_controller()->auto_login_timer_.get();
}
const std::string& auto_login_username() const {
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() const {
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() const {
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;
}
void ConfigureAutoLogin() {
existing_user_controller()->ConfigurePublicSessionAutoLogin();
}
const std::string auto_login_user_id_;
private:
// Owned by LoginUtilsWrapper.
MockLoginUtils* mock_login_utils_;
// |mock_login_display_| is owned by the ExistingUserController, which calls
// CreateLoginDisplay() on the |mock_login_display_host_| to get it.
MockLoginDisplay* mock_login_display_;
scoped_ptr<MockLoginDisplayHost> mock_login_display_host_;
base::MessageLoop message_loop_;
content::TestBrowserThread ui_thread_;
ScopedTestingLocalState local_state_;
// Required by ExistingUserController:
ScopedDeviceSettingsTestHelper device_settings_test_helper_;
ScopedTestCrosSettings test_cros_settings_;
MockUserManager* mock_user_manager_;
ScopedUserManagerEnabler scoped_user_manager_;
// |existing_user_controller_| must be destroyed before
// |device_settings_test_helper_|.
scoped_ptr<ExistingUserController> existing_user_controller_;
};
TEST_F(ExistingUserControllerAutoLoginTest, StartAutoLoginTimer) {
// Timer shouldn't start until signin screen is ready.
set_auto_login_username(auto_login_user_id_);
set_auto_login_delay(kAutoLoginDelay2);
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(auto_login_user_id_);
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(),
kAutoLoginDelay2);
}
TEST_F(ExistingUserControllerAutoLoginTest, StopAutoLoginTimer) {
existing_user_controller()->OnSigninScreenReady();
set_auto_login_username(auto_login_user_id_);
set_auto_login_delay(kAutoLoginDelay2);
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());
}
TEST_F(ExistingUserControllerAutoLoginTest, ResetAutoLoginTimer) {
existing_user_controller()->OnSigninScreenReady();
set_auto_login_username(auto_login_user_id_);
// 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(kAutoLoginDelay2);
existing_user_controller()->StartPublicSessionAutoLoginTimer();
ASSERT_TRUE(auto_login_timer());
EXPECT_TRUE(auto_login_timer()->IsRunning());
EXPECT_EQ(auto_login_timer()->GetCurrentDelay().InMilliseconds(),
kAutoLoginDelay2);
// User activity should restart the timer, so check to see that the
// timer delay was modified.
set_auto_login_delay(kAutoLoginDelay1);
existing_user_controller()->ResetPublicSessionAutoLoginTimer();
ASSERT_TRUE(auto_login_timer());
EXPECT_TRUE(auto_login_timer()->IsRunning());
EXPECT_EQ(auto_login_timer()->GetCurrentDelay().InMilliseconds(),
kAutoLoginDelay1);
}
TEST_F(ExistingUserControllerAutoLoginTest, ConfigureAutoLogin) {
existing_user_controller()->OnSigninScreenReady();
// Timer shouldn't start when the policy is disabled.
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.
SetAutoLoginSettings("", kAutoLoginDelay1);
ConfigureAutoLogin();
EXPECT_FALSE(auto_login_timer());
EXPECT_EQ(auto_login_delay(), kAutoLoginDelay1);
EXPECT_EQ(auto_login_username(), "");
// Timer should start when the account ID is set.
SetAutoLoginSettings(kAutoLoginAccountId, kAutoLoginDelay1);
ConfigureAutoLogin();
ASSERT_TRUE(auto_login_timer());
EXPECT_TRUE(auto_login_timer()->IsRunning());
EXPECT_EQ(auto_login_timer()->GetCurrentDelay().InMilliseconds(),
kAutoLoginDelay1);
EXPECT_EQ(auto_login_delay(), kAutoLoginDelay1);
EXPECT_EQ(auto_login_username(), auto_login_user_id_);
// Timer should restart when the delay is changed.
SetAutoLoginSettings(kAutoLoginAccountId, kAutoLoginDelay2);
ConfigureAutoLogin();
ASSERT_TRUE(auto_login_timer());
EXPECT_TRUE(auto_login_timer()->IsRunning());
EXPECT_EQ(auto_login_timer()->GetCurrentDelay().InMilliseconds(),
kAutoLoginDelay2);
EXPECT_EQ(auto_login_delay(), kAutoLoginDelay2);
EXPECT_EQ(auto_login_username(), auto_login_user_id_);
// Timer should stop when the account ID is unset.
SetAutoLoginSettings("", kAutoLoginDelay2);
ConfigureAutoLogin();
ASSERT_TRUE(auto_login_timer());
EXPECT_FALSE(auto_login_timer()->IsRunning());
EXPECT_EQ(auto_login_timer()->GetCurrentDelay().InMilliseconds(),
kAutoLoginDelay2);
EXPECT_EQ(auto_login_username(), "");
EXPECT_EQ(auto_login_delay(), kAutoLoginDelay2);
}
} // namespace chromeos