1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <string>
6
7#include "base/message_loop/message_loop.h"
8#include "base/values.h"
9#include "chrome/browser/chromeos/login/existing_user_controller.h"
10#include "chrome/browser/chromeos/login/mock_login_display.h"
11#include "chrome/browser/chromeos/login/mock_login_display_host.h"
12#include "chrome/browser/chromeos/login/mock_login_utils.h"
13#include "chrome/browser/chromeos/login/mock_user_manager.h"
14#include "chrome/browser/chromeos/login/user_manager.h"
15#include "chrome/browser/chromeos/policy/device_local_account.h"
16#include "chrome/browser/chromeos/settings/cros_settings.h"
17#include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
18#include "chrome/test/base/scoped_testing_local_state.h"
19#include "chrome/test/base/testing_browser_process.h"
20#include "chromeos/settings/cros_settings_names.h"
21#include "content/public/test/test_browser_thread.h"
22#include "testing/gmock/include/gmock/gmock.h"
23#include "testing/gtest/include/gtest/gtest.h"
24
25using testing::AnyNumber;
26using testing::Return;
27using testing::ReturnNull;
28using testing::_;
29
30namespace chromeos {
31
32namespace {
33
34const char kAutoLoginAccountId[] = "public_session_user@localhost";
35// These values are only used to test the configuration.  They don't
36// delay the test.
37const int kAutoLoginDelay1 = 60000;
38const int kAutoLoginDelay2 = 180000;
39
40}  // namespace
41
42class ExistingUserControllerAutoLoginTest : public ::testing::Test {
43 protected:
44  ExistingUserControllerAutoLoginTest()
45      : auto_login_user_id_(policy::GenerateDeviceLocalAccountUserId(
46            kAutoLoginAccountId,
47            policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION)),
48        message_loop_(base::MessageLoop::TYPE_UI),
49        ui_thread_(content::BrowserThread::UI, &message_loop_),
50        local_state_(TestingBrowserProcess::GetGlobal()),
51        mock_user_manager_(new MockUserManager()),
52        scoped_user_manager_(mock_user_manager_) {
53  }
54
55  virtual void SetUp() {
56    mock_login_display_host_.reset(new MockLoginDisplayHost);
57    mock_login_display_ = new MockLoginDisplay();
58    mock_login_utils_ = new MockLoginUtils();
59    LoginUtils::Set(mock_login_utils_);
60
61    EXPECT_CALL(*mock_login_display_host_.get(), CreateLoginDisplay(_))
62        .Times(1)
63        .WillOnce(Return(mock_login_display_));
64
65    EXPECT_CALL(*mock_login_utils_, DelegateDeleted(_)).Times(AnyNumber());
66
67    EXPECT_CALL(*mock_user_manager_, Shutdown()).Times(AnyNumber());
68    EXPECT_CALL(*mock_user_manager_, FindUser(_))
69        .WillRepeatedly(ReturnNull());
70    EXPECT_CALL(*mock_user_manager_, FindUser(auto_login_user_id_))
71        .WillRepeatedly(Return(
72            mock_user_manager_->CreatePublicAccountUser(auto_login_user_id_)));
73
74    existing_user_controller_.reset(
75        new ExistingUserController(mock_login_display_host_.get()));
76
77    scoped_ptr<base::DictionaryValue> account(new base::DictionaryValue);
78    account->SetStringWithoutPathExpansion(
79        kAccountsPrefDeviceLocalAccountsKeyId,
80        kAutoLoginAccountId);
81    account->SetIntegerWithoutPathExpansion(
82        kAccountsPrefDeviceLocalAccountsKeyType,
83        policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION);
84    base::ListValue accounts;
85    accounts.Append(account.release());
86    CrosSettings::Get()->Set(kAccountsPrefDeviceLocalAccounts, accounts);
87
88    // Prevent settings changes from auto-starting the timer.
89    existing_user_controller_->
90        local_account_auto_login_id_subscription_.reset();
91    existing_user_controller_->
92        local_account_auto_login_delay_subscription_.reset();
93  }
94
95  const ExistingUserController* existing_user_controller() const {
96    return ExistingUserController::current_controller();
97  }
98
99  ExistingUserController* existing_user_controller() {
100    return ExistingUserController::current_controller();
101  }
102
103  void SetAutoLoginSettings(const std::string& account_id, int delay) {
104    CrosSettings::Get()->SetString(
105        kAccountsPrefDeviceLocalAccountAutoLoginId,
106        account_id);
107    CrosSettings::Get()->SetInteger(
108        kAccountsPrefDeviceLocalAccountAutoLoginDelay,
109        delay);
110  }
111
112  // ExistingUserController private member accessors.
113  base::OneShotTimer<ExistingUserController>* auto_login_timer() {
114    return existing_user_controller()->auto_login_timer_.get();
115  }
116
117  const std::string& auto_login_username() const {
118    return existing_user_controller()->public_session_auto_login_username_;
119  }
120  void set_auto_login_username(const std::string& username) {
121    existing_user_controller()->public_session_auto_login_username_ = username;
122  }
123
124  int auto_login_delay() const {
125    return existing_user_controller()->public_session_auto_login_delay_;
126  }
127  void set_auto_login_delay(int delay) {
128    existing_user_controller()->public_session_auto_login_delay_ = delay;
129  }
130
131  bool is_login_in_progress() const {
132    return existing_user_controller()->is_login_in_progress_;
133  }
134  void set_is_login_in_progress(bool is_login_in_progress) {
135    existing_user_controller()->is_login_in_progress_ = is_login_in_progress;
136  }
137
138  void ConfigureAutoLogin() {
139    existing_user_controller()->ConfigurePublicSessionAutoLogin();
140  }
141
142  const std::string auto_login_user_id_;
143
144 private:
145  // Owned by LoginUtilsWrapper.
146  MockLoginUtils* mock_login_utils_;
147
148  // |mock_login_display_| is owned by the ExistingUserController, which calls
149  // CreateLoginDisplay() on the |mock_login_display_host_| to get it.
150  MockLoginDisplay* mock_login_display_;
151
152  scoped_ptr<MockLoginDisplayHost> mock_login_display_host_;
153  base::MessageLoop message_loop_;
154  content::TestBrowserThread ui_thread_;
155  ScopedTestingLocalState local_state_;
156
157  // Required by ExistingUserController:
158  ScopedDeviceSettingsTestHelper device_settings_test_helper_;
159  ScopedTestCrosSettings test_cros_settings_;
160  MockUserManager* mock_user_manager_;
161  ScopedUserManagerEnabler scoped_user_manager_;
162
163  // |existing_user_controller_| must be destroyed before
164  // |device_settings_test_helper_|.
165  scoped_ptr<ExistingUserController> existing_user_controller_;
166};
167
168TEST_F(ExistingUserControllerAutoLoginTest, StartAutoLoginTimer) {
169  // Timer shouldn't start until signin screen is ready.
170  set_auto_login_username(auto_login_user_id_);
171  set_auto_login_delay(kAutoLoginDelay2);
172  existing_user_controller()->StartPublicSessionAutoLoginTimer();
173  EXPECT_FALSE(auto_login_timer());
174
175  // Timer shouldn't start if the policy isn't set.
176  set_auto_login_username("");
177  existing_user_controller()->OnSigninScreenReady();
178  existing_user_controller()->StartPublicSessionAutoLoginTimer();
179  EXPECT_FALSE(auto_login_timer());
180
181  // Timer shouldn't fire in the middle of a login attempt.
182  set_auto_login_username(auto_login_user_id_);
183  set_is_login_in_progress(true);
184  existing_user_controller()->StartPublicSessionAutoLoginTimer();
185  EXPECT_FALSE(auto_login_timer());
186
187  // Otherwise start.
188  set_is_login_in_progress(false);
189  existing_user_controller()->StartPublicSessionAutoLoginTimer();
190  ASSERT_TRUE(auto_login_timer());
191  EXPECT_TRUE(auto_login_timer()->IsRunning());
192  EXPECT_EQ(auto_login_timer()->GetCurrentDelay().InMilliseconds(),
193            kAutoLoginDelay2);
194}
195
196TEST_F(ExistingUserControllerAutoLoginTest, StopAutoLoginTimer) {
197  existing_user_controller()->OnSigninScreenReady();
198  set_auto_login_username(auto_login_user_id_);
199  set_auto_login_delay(kAutoLoginDelay2);
200
201  existing_user_controller()->StartPublicSessionAutoLoginTimer();
202  ASSERT_TRUE(auto_login_timer());
203  EXPECT_TRUE(auto_login_timer()->IsRunning());
204
205  existing_user_controller()->StopPublicSessionAutoLoginTimer();
206  ASSERT_TRUE(auto_login_timer());
207  EXPECT_FALSE(auto_login_timer()->IsRunning());
208}
209
210TEST_F(ExistingUserControllerAutoLoginTest, ResetAutoLoginTimer) {
211  existing_user_controller()->OnSigninScreenReady();
212  set_auto_login_username(auto_login_user_id_);
213
214  // Timer starts off not running.
215  EXPECT_FALSE(auto_login_timer());
216
217  // When the timer isn't running, nothing should happen.
218  existing_user_controller()->ResetPublicSessionAutoLoginTimer();
219  EXPECT_FALSE(auto_login_timer());
220
221  // Start the timer.
222  set_auto_login_delay(kAutoLoginDelay2);
223  existing_user_controller()->StartPublicSessionAutoLoginTimer();
224  ASSERT_TRUE(auto_login_timer());
225  EXPECT_TRUE(auto_login_timer()->IsRunning());
226  EXPECT_EQ(auto_login_timer()->GetCurrentDelay().InMilliseconds(),
227            kAutoLoginDelay2);
228
229  // User activity should restart the timer, so check to see that the
230  // timer delay was modified.
231  set_auto_login_delay(kAutoLoginDelay1);
232  existing_user_controller()->ResetPublicSessionAutoLoginTimer();
233  ASSERT_TRUE(auto_login_timer());
234  EXPECT_TRUE(auto_login_timer()->IsRunning());
235  EXPECT_EQ(auto_login_timer()->GetCurrentDelay().InMilliseconds(),
236            kAutoLoginDelay1);
237}
238
239TEST_F(ExistingUserControllerAutoLoginTest, ConfigureAutoLogin) {
240  existing_user_controller()->OnSigninScreenReady();
241
242  // Timer shouldn't start when the policy is disabled.
243  ConfigureAutoLogin();
244  EXPECT_FALSE(auto_login_timer());
245  EXPECT_EQ(auto_login_delay(), 0);
246  EXPECT_EQ(auto_login_username(), "");
247
248  // Timer shouldn't start when the delay alone is set.
249  SetAutoLoginSettings("", kAutoLoginDelay1);
250  ConfigureAutoLogin();
251  EXPECT_FALSE(auto_login_timer());
252  EXPECT_EQ(auto_login_delay(), kAutoLoginDelay1);
253  EXPECT_EQ(auto_login_username(), "");
254
255  // Timer should start when the account ID is set.
256  SetAutoLoginSettings(kAutoLoginAccountId, kAutoLoginDelay1);
257  ConfigureAutoLogin();
258  ASSERT_TRUE(auto_login_timer());
259  EXPECT_TRUE(auto_login_timer()->IsRunning());
260  EXPECT_EQ(auto_login_timer()->GetCurrentDelay().InMilliseconds(),
261            kAutoLoginDelay1);
262  EXPECT_EQ(auto_login_delay(), kAutoLoginDelay1);
263  EXPECT_EQ(auto_login_username(), auto_login_user_id_);
264
265  // Timer should restart when the delay is changed.
266  SetAutoLoginSettings(kAutoLoginAccountId, kAutoLoginDelay2);
267  ConfigureAutoLogin();
268  ASSERT_TRUE(auto_login_timer());
269  EXPECT_TRUE(auto_login_timer()->IsRunning());
270  EXPECT_EQ(auto_login_timer()->GetCurrentDelay().InMilliseconds(),
271            kAutoLoginDelay2);
272  EXPECT_EQ(auto_login_delay(), kAutoLoginDelay2);
273  EXPECT_EQ(auto_login_username(), auto_login_user_id_);
274
275  // Timer should stop when the account ID is unset.
276  SetAutoLoginSettings("", kAutoLoginDelay2);
277  ConfigureAutoLogin();
278  ASSERT_TRUE(auto_login_timer());
279  EXPECT_FALSE(auto_login_timer()->IsRunning());
280  EXPECT_EQ(auto_login_timer()->GetCurrentDelay().InMilliseconds(),
281            kAutoLoginDelay2);
282  EXPECT_EQ(auto_login_username(), "");
283  EXPECT_EQ(auto_login_delay(), kAutoLoginDelay2);
284}
285
286}  // namespace chromeos
287