1 // Copyright 2014 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.
5 #include "base/basictypes.h"
6 #include "base/compiler_specific.h"
7 #include "base/prefs/pref_service.h"
8 #include "base/strings/stringprintf.h"
9 #include "chrome/browser/chromeos/login/login_manager_test.h"
10 #include "chrome/browser/chromeos/login/startup_utils.h"
11 #include "chrome/browser/chromeos/login/ui/user_adding_screen.h"
12 #include "chrome/browser/chromeos/profiles/profile_helper.h"
13 #include "chrome/browser/chromeos/settings/cros_settings.h"
14 #include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/browser/ui/browser_commands.h"
17 #include "chrome/browser/ui/tabs/tab_strip_model.h"
18 #include "chrome/common/pref_names.h"
19 #include "chrome/test/base/ui_test_utils.h"
20 #include "chromeos/settings/cros_settings_names.h"
21 #include "components/user_manager/user_manager.h"
22 #include "content/public/browser/web_contents.h"
23 #include "content/public/test/browser_test_utils.h"
24 #include "content/public/test/test_utils.h"
30 const char* kTestOwner = "test-owner@example.com";
31 const char* kTestNonOwner = "test-user1@example.com";
33 const char* kKnownSettings[] = {
35 kAccountsPrefAllowGuest,
36 kAccountsPrefAllowNewUser,
37 kAccountsPrefDeviceLocalAccounts,
38 kAccountsPrefShowUserNamesOnSignIn,
39 kAccountsPrefSupervisedUsersEnabled,
42 // Stub settings provider that only handles the settings we need to control.
43 // StubCrosSettingsProvider handles more settings but leaves many of them unset
44 // which the Settings page doesn't expect.
45 class StubAccountSettingsProvider : public StubCrosSettingsProvider {
47 StubAccountSettingsProvider() {
50 virtual ~StubAccountSettingsProvider() {
53 // StubCrosSettingsProvider implementation.
54 virtual bool HandlesSetting(const std::string& path) const OVERRIDE {
55 const char** end = kKnownSettings + arraysize(kKnownSettings);
56 return std::find(kKnownSettings, end, path) != end;
61 const char* pref_name;
66 const PrefTest kPrefTests[] = {
67 { kSystemTimezone, false, false },
68 { prefs::kUse24HourClock, false, false },
69 { kAttestationForContentProtectionEnabled, true, true },
70 { kAccountsPrefAllowGuest, true, false },
71 { kAccountsPrefAllowNewUser, true, false },
72 { kAccountsPrefShowUserNamesOnSignIn, true, false },
73 { kAccountsPrefSupervisedUsersEnabled, true, false },
74 #if defined(GOOGLE_CHROME_BUILD)
75 { kStatsReportingPref, true, true },
76 { prefs::kSpellCheckUseSpellingService, false, false },
82 class SharedOptionsTest : public LoginManagerTest {
85 : LoginManagerTest(false),
86 device_settings_provider_(NULL) {
87 stub_settings_provider_.Set(kDeviceOwner, base::StringValue(kTestOwner));
90 virtual ~SharedOptionsTest() {
93 virtual void SetUpOnMainThread() OVERRIDE {
94 LoginManagerTest::SetUpOnMainThread();
96 CrosSettings* settings = CrosSettings::Get();
98 // Add the stub settings provider, moving the device settings provider
99 // behind it so our stub takes precedence.
100 device_settings_provider_ = settings->GetProvider(kDeviceOwner);
101 settings->RemoveSettingsProvider(device_settings_provider_);
102 settings->AddSettingsProvider(&stub_settings_provider_);
103 settings->AddSettingsProvider(device_settings_provider_);
106 virtual void TearDownOnMainThread() OVERRIDE {
107 CrosSettings* settings = CrosSettings::Get();
108 settings->RemoveSettingsProvider(&stub_settings_provider_);
109 LoginManagerTest::TearDownOnMainThread();
113 void CheckOptionsUI(const user_manager::User* user,
116 Browser* browser = CreateBrowserForUser(user);
117 content::WebContents* contents =
118 browser->tab_strip_model()->GetActiveWebContents();
120 for (size_t i = 0; i < sizeof(kPrefTests) / sizeof(kPrefTests[0]); i++) {
121 CheckPreference(contents,
122 kPrefTests[i].pref_name,
123 !is_owner && kPrefTests[i].owner_only,
124 !is_owner && kPrefTests[i].indicator ? "owner" :
127 CheckBanner(contents, is_primary);
128 CheckSharedSections(contents, is_primary);
129 CheckAccountsOverlay(contents, is_owner);
132 // Creates a browser and navigates to the Settings page.
133 Browser* CreateBrowserForUser(const user_manager::User* user) {
134 Profile* profile = ProfileHelper::Get()->GetProfileByUserUnsafe(user);
135 profile->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
138 ui_test_utils::BrowserAddedObserver observer;
139 Browser* browser = CreateBrowser(profile);
140 observer.WaitForSingleNewBrowser();
142 ui_test_utils::NavigateToURL(browser,
143 GURL("chrome://settings-frame"));
147 // Verifies a preference's disabled state and controlled-by indicator.
148 void CheckPreference(content::WebContents* contents,
149 std::string pref_name,
151 std::string controlled_by) {
153 std::string js_expression = base::StringPrintf(
154 "var prefSelector = '[pref=\"%s\"]';"
155 "var controlledBy = '%s';"
156 "var input = document.querySelector("
157 " 'input' + prefSelector + ', select' + prefSelector);"
158 "var success = false;"
160 " success = input.disabled == %d;"
161 " var indicator = input.parentNode.parentNode.querySelector("
162 " '.controlled-setting-indicator');"
163 " if (controlledBy) {"
164 " success = success && indicator &&"
165 " indicator.getAttribute('controlled-by') == controlledBy;"
167 " success = success && (!indicator ||"
168 " !indicator.hasAttribute('controlled-by') ||"
169 " indicator.getAttribute('controlled-by') == '')"
172 "window.domAutomationController.send(!!success);",
173 pref_name.c_str(), controlled_by.c_str(), disabled);
174 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
175 contents, js_expression, &success));
176 EXPECT_TRUE(success);
179 // Verifies a checkbox's disabled state, controlled-by indicator and value.
180 void CheckBooleanPreference(content::WebContents* contents,
181 std::string pref_name,
183 std::string controlled_by,
184 bool expected_value) {
185 CheckPreference(contents, pref_name, disabled, controlled_by);
187 std::string js_expression = base::StringPrintf(
188 "window.domAutomationController.send(document.querySelector('"
189 " input[type=\"checkbox\"][pref=\"%s\"]').checked);",
191 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
192 contents, js_expression, &actual_value));
193 EXPECT_EQ(expected_value, actual_value);
196 // Verifies that the shared settings banner is visible only for
198 void CheckBanner(content::WebContents* contents,
201 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
203 "var e = $('secondary-user-banner');"
204 "window.domAutomationController.send(e && !e.hidden);",
206 EXPECT_EQ(!is_primary, banner_visible);
209 // Verifies that sections of shared settings have the appropriate indicator.
210 void CheckSharedSections(content::WebContents* contents,
212 // This only applies to the Internet options section.
213 std::string controlled_by;
214 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
216 "var e = document.querySelector("
217 " '#network-section-header span.controlled-setting-indicator');"
218 "if (!e || !e.getAttribute('controlled-by')) {"
219 " window.domAutomationController.send('');"
221 " window.domAutomationController.send("
222 " e.getAttribute('controlled-by'));"
225 EXPECT_EQ(!is_primary ? "shared" : std::string(), controlled_by);
228 // Checks the Accounts header and non-checkbox inputs.
229 void CheckAccountsOverlay(content::WebContents* contents, bool is_owner) {
230 // Set cros.accounts.allowGuest to false so we can test the accounts list.
231 // This has to be done after the PRE_* test or we can't add the owner.
232 stub_settings_provider_.Set(
233 kAccountsPrefAllowNewUser, base::FundamentalValue(false));
236 std::string js_expression = base::StringPrintf(
237 "var controlled = %d;"
238 "var warning = $('ownerOnlyWarning');"
239 "var userList = $('userList');"
240 "var input = $('userNameEdit');"
243 " success = warning && !warning.hidden && userList.disabled &&"
246 " success = (!warning || warning.hidden) && !userList.disabled &&"
248 "window.domAutomationController.send(!!success);",
250 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
251 contents, js_expression, &success));
252 EXPECT_TRUE(success) << "Accounts overlay incorrect for " <<
253 (is_owner ? "owner." : "non-owner.");
256 StubAccountSettingsProvider stub_settings_provider_;
257 CrosSettingsProvider* device_settings_provider_;
260 DISALLOW_COPY_AND_ASSIGN(SharedOptionsTest);
263 IN_PROC_BROWSER_TEST_F(SharedOptionsTest, PRE_SharedOptions) {
264 RegisterUser(kTestOwner);
265 RegisterUser(kTestNonOwner);
266 StartupUtils::MarkOobeCompleted();
269 IN_PROC_BROWSER_TEST_F(SharedOptionsTest, SharedOptions) {
270 // Log in the owner first, then add a secondary user.
271 LoginUser(kTestOwner);
272 UserAddingScreen::Get()->Start();
273 content::RunAllPendingInMessageLoop();
274 AddUser(kTestNonOwner);
276 user_manager::UserManager* manager = user_manager::UserManager::Get();
277 ASSERT_EQ(2u, manager->GetLoggedInUsers().size());
279 SCOPED_TRACE("Checking settings for owner, primary user.");
280 CheckOptionsUI(manager->FindUser(manager->GetOwnerEmail()), true, true);
283 SCOPED_TRACE("Checking settings for non-owner, secondary user.");
284 CheckOptionsUI(manager->FindUser(kTestNonOwner), false, false);
286 // TODO(michaelpg): Add tests for non-primary owner and primary non-owner
287 // when the owner-only multiprofile restriction is removed, probably M38.
290 IN_PROC_BROWSER_TEST_F(SharedOptionsTest, PRE_ScreenLockPreferencePrimary) {
291 RegisterUser(kTestOwner);
292 RegisterUser(kTestNonOwner);
293 StartupUtils::MarkOobeCompleted();
296 // Tests the shared setting indicator for the primary user's auto-lock setting
297 // when the secondary user has enabled or disabled their preference.
298 // (The checkbox is unset if the current user's preference is false, but if any
299 // other signed-in user has enabled this preference, the shared setting
300 // indicator explains this.)
301 IN_PROC_BROWSER_TEST_F(SharedOptionsTest, ScreenLockPreferencePrimary) {
302 LoginUser(kTestOwner);
303 UserAddingScreen::Get()->Start();
304 content::RunAllPendingInMessageLoop();
305 AddUser(kTestNonOwner);
307 user_manager::UserManager* manager = user_manager::UserManager::Get();
308 const user_manager::User* user1 = manager->FindUser(kTestOwner);
309 const user_manager::User* user2 = manager->FindUser(kTestNonOwner);
311 PrefService* prefs1 =
312 ProfileHelper::Get()->GetProfileByUserUnsafe(user1)->GetPrefs();
313 PrefService* prefs2 =
314 ProfileHelper::Get()->GetProfileByUserUnsafe(user2)->GetPrefs();
316 // Set both users' preference to false, then change the secondary user's to
317 // true. We'll do the opposite in the next test. Doesn't provide 100% coverage
318 // but reloading the settings page is super slow on debug builds.
319 prefs1->SetBoolean(prefs::kEnableAutoScreenLock, false);
320 prefs2->SetBoolean(prefs::kEnableAutoScreenLock, false);
322 Browser* browser = CreateBrowserForUser(user1);
323 content::WebContents* contents =
324 browser->tab_strip_model()->GetActiveWebContents();
326 bool disabled = false;
328 std::string empty_controlled;
329 std::string shared_controlled("shared");
332 SCOPED_TRACE("Screen lock false for both users");
333 expected_value = false;
334 CheckBooleanPreference(contents, prefs::kEnableAutoScreenLock, disabled,
335 empty_controlled, expected_value);
338 // Set the secondary user's preference to true, and reload the primary user's
339 // browser to see the updated controlled-by indicator.
340 prefs2->SetBoolean(prefs::kEnableAutoScreenLock, true);
341 chrome::Reload(browser, CURRENT_TAB);
342 content::WaitForLoadStop(contents);
344 SCOPED_TRACE("Screen lock false for primary user");
345 expected_value = false;
346 CheckBooleanPreference(contents, prefs::kEnableAutoScreenLock, disabled,
347 shared_controlled, expected_value);
350 // Set the preference to true for the primary user and check that the
351 // indicator disappears.
352 prefs1->SetBoolean(prefs::kEnableAutoScreenLock, true);
354 SCOPED_TRACE("Screen lock true for both users");
355 expected_value = true;
356 CheckBooleanPreference(contents, prefs::kEnableAutoScreenLock, disabled,
357 empty_controlled, expected_value);
361 IN_PROC_BROWSER_TEST_F(SharedOptionsTest, PRE_ScreenLockPreferenceSecondary) {
362 RegisterUser(kTestOwner);
363 RegisterUser(kTestNonOwner);
364 StartupUtils::MarkOobeCompleted();
367 // Tests the shared setting indicator for the secondary user's auto-lock setting
368 // when the primary user has enabled or disabled their preference.
369 // (The checkbox is unset if the current user's preference is false, but if any
370 // other signed-in user has enabled this preference, the shared setting
371 // indicator explains this.)
372 IN_PROC_BROWSER_TEST_F(SharedOptionsTest, ScreenLockPreferenceSecondary) {
373 LoginUser(kTestOwner);
374 UserAddingScreen::Get()->Start();
375 content::RunAllPendingInMessageLoop();
376 AddUser(kTestNonOwner);
378 user_manager::UserManager* manager = user_manager::UserManager::Get();
379 const user_manager::User* user1 = manager->FindUser(kTestOwner);
380 const user_manager::User* user2 = manager->FindUser(kTestNonOwner);
382 PrefService* prefs1 =
383 ProfileHelper::Get()->GetProfileByUserUnsafe(user1)->GetPrefs();
384 PrefService* prefs2 =
385 ProfileHelper::Get()->GetProfileByUserUnsafe(user2)->GetPrefs();
387 // Set both users' preference to true, then change the secondary user's to
389 prefs1->SetBoolean(prefs::kEnableAutoScreenLock, true);
390 prefs2->SetBoolean(prefs::kEnableAutoScreenLock, true);
392 Browser* browser = CreateBrowserForUser(user2);
393 content::WebContents* contents =
394 browser->tab_strip_model()->GetActiveWebContents();
396 bool disabled = false;
398 std::string empty_controlled;
399 std::string shared_controlled("shared");
402 SCOPED_TRACE("Screen lock true for both users");
403 expected_value = true;
404 CheckBooleanPreference(contents, prefs::kEnableAutoScreenLock, disabled,
405 empty_controlled, expected_value);
408 // Set the secondary user's preference to false and check that the
409 // controlled-by indicator is shown.
410 prefs2->SetBoolean(prefs::kEnableAutoScreenLock, false);
412 SCOPED_TRACE("Screen lock false for secondary user");
413 expected_value = false;
414 CheckBooleanPreference(contents, prefs::kEnableAutoScreenLock, disabled,
415 shared_controlled, expected_value);
418 // Set the preference to false for the primary user and check that the
419 // indicator disappears.
420 prefs1->SetBoolean(prefs::kEnableAutoScreenLock, false);
421 chrome::Reload(browser, CURRENT_TAB);
422 content::WaitForLoadStop(contents);
424 SCOPED_TRACE("Screen lock false for both users");
425 expected_value = false;
426 CheckBooleanPreference(contents, prefs::kEnableAutoScreenLock, disabled,
427 empty_controlled, expected_value);
431 } // namespace chromeos