Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / webui / options / chromeos / shared_options_browsertest.cc
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.
4
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"
25
26 namespace chromeos {
27
28 namespace {
29
30 const char* kTestOwner = "test-owner@example.com";
31 const char* kTestNonOwner = "test-user1@example.com";
32
33 const char* kKnownSettings[] = {
34   kDeviceOwner,
35   kAccountsPrefAllowGuest,
36   kAccountsPrefAllowNewUser,
37   kAccountsPrefDeviceLocalAccounts,
38   kAccountsPrefShowUserNamesOnSignIn,
39   kAccountsPrefSupervisedUsersEnabled,
40 };
41
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 {
46  public:
47   StubAccountSettingsProvider() {
48   }
49
50   virtual ~StubAccountSettingsProvider() {
51   }
52
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;
57   }
58 };
59
60 struct PrefTest {
61   const char* pref_name;
62   bool owner_only;
63   bool indicator;
64 };
65
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 },
77 #endif
78 };
79
80 }  // namespace
81
82 class SharedOptionsTest : public LoginManagerTest {
83  public:
84   SharedOptionsTest()
85     : LoginManagerTest(false),
86       device_settings_provider_(NULL) {
87     stub_settings_provider_.Set(kDeviceOwner, base::StringValue(kTestOwner));
88   }
89
90   virtual ~SharedOptionsTest() {
91   }
92
93   virtual void SetUpOnMainThread() OVERRIDE {
94     LoginManagerTest::SetUpOnMainThread();
95
96     CrosSettings* settings = CrosSettings::Get();
97
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_);
104   }
105
106   virtual void TearDownOnMainThread() OVERRIDE {
107     CrosSettings* settings = CrosSettings::Get();
108     settings->RemoveSettingsProvider(&stub_settings_provider_);
109     LoginManagerTest::TearDownOnMainThread();
110   }
111
112  protected:
113   void CheckOptionsUI(const user_manager::User* user,
114                       bool is_owner,
115                       bool is_primary) {
116     Browser* browser = CreateBrowserForUser(user);
117     content::WebContents* contents =
118         browser->tab_strip_model()->GetActiveWebContents();
119
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" :
125                                                              std::string());
126     }
127     CheckBanner(contents, is_primary);
128     CheckSharedSections(contents, is_primary);
129     CheckAccountsOverlay(contents, is_owner);
130   }
131
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,
136                                    user->email());
137
138     ui_test_utils::BrowserAddedObserver observer;
139     Browser* browser = CreateBrowser(profile);
140     observer.WaitForSingleNewBrowser();
141
142     ui_test_utils::NavigateToURL(browser,
143                                  GURL("chrome://settings-frame"));
144     return browser;
145   }
146
147   // Verifies a preference's disabled state and controlled-by indicator.
148   void CheckPreference(content::WebContents* contents,
149                        std::string pref_name,
150                        bool disabled,
151                        std::string controlled_by) {
152     bool success;
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;"
159         "if (input) {"
160         "  success = input.disabled == %d;"
161         "  var indicator = document.querySelector(input.tagName +"
162         "      prefSelector + ' + span span.controlled-setting-indicator');"
163         "  if (controlledBy) {"
164         "    success = success && indicator &&"
165         "              indicator.getAttribute('controlled-by') == controlledBy;"
166         "  } else {"
167         "    success = success && (!indicator ||"
168         "              !indicator.hasAttribute('controlled-by') ||"
169         "              indicator.getAttribute('controlled-by') == '')"
170         "  }"
171         "}"
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);
177   }
178
179   // Verifies a checkbox's disabled state, controlled-by indicator and value.
180   void CheckBooleanPreference(content::WebContents* contents,
181                               std::string pref_name,
182                               bool disabled,
183                               std::string controlled_by,
184                               bool expected_value) {
185     CheckPreference(contents, pref_name, disabled, controlled_by);
186     bool actual_value;
187     std::string js_expression = base::StringPrintf(
188         "window.domAutomationController.send(document.querySelector('"
189         "    input[type=\"checkbox\"][pref=\"%s\"]').checked);",
190         pref_name.c_str());
191     ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
192         contents, js_expression, &actual_value));
193     EXPECT_EQ(expected_value, actual_value);
194   }
195
196   // Verifies that the shared settings banner is visible only for
197   // secondary users.
198   void CheckBanner(content::WebContents* contents,
199                    bool is_primary) {
200     bool banner_visible;
201     ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
202         contents,
203         "var e = $('secondary-user-banner');"
204         "window.domAutomationController.send(e && !e.hidden);",
205         &banner_visible));
206     EXPECT_EQ(!is_primary, banner_visible);
207   }
208
209   // Verifies that sections of shared settings have the appropriate indicator.
210   void CheckSharedSections(content::WebContents* contents,
211                            bool is_primary) {
212     // This only applies to the Internet options section.
213     std::string controlled_by;
214     ASSERT_TRUE(content::ExecuteScriptAndExtractString(
215         contents,
216         "var e = document.querySelector("
217         "    '#network-section-header span.controlled-setting-indicator');"
218         "if (!e || !e.getAttribute('controlled-by')) {"
219         "  window.domAutomationController.send('');"
220         "} else {"
221         "  window.domAutomationController.send("
222         "      e.getAttribute('controlled-by'));"
223         "}",
224         &controlled_by));
225     EXPECT_EQ(!is_primary ? "shared" : std::string(), controlled_by);
226   }
227
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));
234
235     bool success;
236     std::string js_expression = base::StringPrintf(
237         "var controlled = %d;"
238         "var warning = $('ownerOnlyWarning');"
239         "var userList = $('userList');"
240         "var input = $('userNameEdit');"
241         "var success;"
242         "if (controlled)"
243         "  success = warning && !warning.hidden && userList.disabled &&"
244         "            input.disabled;"
245         "else"
246         "  success = (!warning || warning.hidden) && !userList.disabled &&"
247         "            !input.disabled;"
248         "window.domAutomationController.send(!!success);",
249         !is_owner);
250     ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
251         contents, js_expression, &success));
252     EXPECT_TRUE(success) << "Accounts overlay incorrect for " <<
253         (is_owner ? "owner." : "non-owner.");
254   }
255
256   StubAccountSettingsProvider stub_settings_provider_;
257   CrosSettingsProvider* device_settings_provider_;
258
259  private:
260   DISALLOW_COPY_AND_ASSIGN(SharedOptionsTest);
261 };
262
263 IN_PROC_BROWSER_TEST_F(SharedOptionsTest, PRE_SharedOptions) {
264   RegisterUser(kTestOwner);
265   RegisterUser(kTestNonOwner);
266   StartupUtils::MarkOobeCompleted();
267 }
268
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);
275
276   user_manager::UserManager* manager = user_manager::UserManager::Get();
277   ASSERT_EQ(2u, manager->GetLoggedInUsers().size());
278   {
279     SCOPED_TRACE("Checking settings for owner, primary user.");
280     CheckOptionsUI(manager->FindUser(manager->GetOwnerEmail()), true, true);
281   }
282   {
283     SCOPED_TRACE("Checking settings for non-owner, secondary user.");
284     CheckOptionsUI(manager->FindUser(kTestNonOwner), false, false);
285   }
286   // TODO(michaelpg): Add tests for non-primary owner and primary non-owner
287   // when the owner-only multiprofile restriction is removed, probably M38.
288 }
289
290 IN_PROC_BROWSER_TEST_F(SharedOptionsTest, PRE_ScreenLockPreferencePrimary) {
291   RegisterUser(kTestOwner);
292   RegisterUser(kTestNonOwner);
293   StartupUtils::MarkOobeCompleted();
294 }
295
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);
306
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);
310
311   PrefService* prefs1 =
312       ProfileHelper::Get()->GetProfileByUserUnsafe(user1)->GetPrefs();
313   PrefService* prefs2 =
314       ProfileHelper::Get()->GetProfileByUserUnsafe(user2)->GetPrefs();
315
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);
321
322   Browser* browser = CreateBrowserForUser(user1);
323   content::WebContents* contents =
324       browser->tab_strip_model()->GetActiveWebContents();
325
326   bool disabled = false;
327   bool expected_value;
328   std::string empty_controlled;
329   std::string shared_controlled("shared");
330
331   {
332     SCOPED_TRACE("Screen lock false for both users");
333     expected_value = false;
334     CheckBooleanPreference(contents, prefs::kEnableAutoScreenLock, disabled,
335                            empty_controlled, expected_value);
336   }
337
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);
343   {
344     SCOPED_TRACE("Screen lock false for primary user");
345     expected_value = false;
346     CheckBooleanPreference(contents, prefs::kEnableAutoScreenLock, disabled,
347                            shared_controlled, expected_value);
348   }
349
350   // Set the preference to true for the primary user and check that the
351   // indicator disappears.
352   prefs1->SetBoolean(prefs::kEnableAutoScreenLock, true);
353   {
354     SCOPED_TRACE("Screen lock true for both users");
355     expected_value = true;
356     CheckBooleanPreference(contents, prefs::kEnableAutoScreenLock, disabled,
357                            empty_controlled, expected_value);
358   }
359 }
360
361 IN_PROC_BROWSER_TEST_F(SharedOptionsTest, PRE_ScreenLockPreferenceSecondary) {
362   RegisterUser(kTestOwner);
363   RegisterUser(kTestNonOwner);
364   StartupUtils::MarkOobeCompleted();
365 }
366
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);
377
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);
381
382   PrefService* prefs1 =
383       ProfileHelper::Get()->GetProfileByUserUnsafe(user1)->GetPrefs();
384   PrefService* prefs2 =
385       ProfileHelper::Get()->GetProfileByUserUnsafe(user2)->GetPrefs();
386
387   // Set both users' preference to true, then change the secondary user's to
388   // false.
389   prefs1->SetBoolean(prefs::kEnableAutoScreenLock, true);
390   prefs2->SetBoolean(prefs::kEnableAutoScreenLock, true);
391
392   Browser* browser = CreateBrowserForUser(user2);
393   content::WebContents* contents =
394       browser->tab_strip_model()->GetActiveWebContents();
395
396   bool disabled = false;
397   bool expected_value;
398   std::string empty_controlled;
399   std::string shared_controlled("shared");
400
401   {
402     SCOPED_TRACE("Screen lock true for both users");
403     expected_value = true;
404     CheckBooleanPreference(contents, prefs::kEnableAutoScreenLock, disabled,
405                            empty_controlled, expected_value);
406   }
407
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);
411   {
412     SCOPED_TRACE("Screen lock false for secondary user");
413     expected_value = false;
414     CheckBooleanPreference(contents, prefs::kEnableAutoScreenLock, disabled,
415                            shared_controlled, expected_value);
416   }
417
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);
423   {
424     SCOPED_TRACE("Screen lock false for both users");
425     expected_value = false;
426     CheckBooleanPreference(contents, prefs::kEnableAutoScreenLock, disabled,
427                            empty_controlled, expected_value);
428   }
429 }
430
431 }  // namespace chromeos