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