1 // Copyright (c) 2012 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 "chrome/browser/ui/webui/options/preferences_browsertest.h"
10 #include "base/callback.h"
11 #include "base/json/json_reader.h"
12 #include "base/json/json_writer.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/prefs/pref_service.h"
15 #include "base/values.h"
16 #include "chrome/browser/chrome_notification_types.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/ui/browser.h"
19 #include "chrome/browser/ui/tabs/tab_strip_model.h"
20 #include "chrome/common/pref_names.h"
21 #include "chrome/common/url_constants.h"
22 #include "chrome/test/base/ui_test_utils.h"
23 #include "components/policy/core/browser/browser_policy_connector.h"
24 #include "components/policy/core/common/external_data_fetcher.h"
25 #include "components/policy/core/common/policy_map.h"
26 #include "components/policy/core/common/policy_types.h"
27 #include "content/public/browser/notification_details.h"
28 #include "content/public/browser/notification_source.h"
29 #include "content/public/browser/render_view_host.h"
30 #include "content/public/browser/web_contents.h"
31 #include "content/public/test/browser_test_utils.h"
32 #include "policy/policy_constants.h"
33 #include "testing/gtest/include/gtest/gtest.h"
36 #if defined(OS_CHROMEOS)
37 #include "base/strings/stringprintf.h"
38 #include "chrome/browser/browser_process.h"
39 #include "chrome/browser/chromeos/net/proxy_config_handler.h"
40 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
41 #include "chrome/browser/chromeos/policy/stub_enterprise_install_attributes.h"
42 #include "chrome/browser/chromeos/proxy_cros_settings_parser.h"
43 #include "chrome/browser/chromeos/settings/cros_settings.h"
44 #include "chromeos/dbus/dbus_thread_manager.h"
45 #include "chromeos/dbus/shill_profile_client.h"
46 #include "chromeos/dbus/shill_service_client.h"
47 #include "chromeos/network/network_state.h"
48 #include "chromeos/network/network_state_handler.h"
49 #include "chromeos/settings/cros_settings_names.h"
50 #include "components/proxy_config/proxy_config_dictionary.h"
51 #include "content/public/test/test_utils.h"
52 #include "third_party/cros_system_api/dbus/service_constants.h"
57 using testing::Property
;
58 using testing::Return
;
63 // Helper for using EXPECT_EQ() with base::Value.
64 bool operator==(const base::Value
& first
, const base::Value
& second
) {
65 return first
.Equals(&second
);
68 // Helper for pretty-printing the contents of base::Value in case of failures.
69 void PrintTo(const base::Value
& value
, std::ostream
* stream
) {
71 JSONWriter::Write(value
, &json
);
77 // Googlemock matcher for base::Value.
78 MATCHER_P(EqualsValue
, expected
, "") {
79 return arg
&& arg
->Equals(expected
);
82 PreferencesBrowserTest::PreferencesBrowserTest() {
85 PreferencesBrowserTest::~PreferencesBrowserTest() {
88 // Navigates to the settings page, causing the JavaScript pref handling code to
89 // load and injects JavaScript testing code.
90 void PreferencesBrowserTest::SetUpOnMainThread() {
91 ui_test_utils::NavigateToURL(browser(),
92 GURL(chrome::kChromeUISettingsFrameURL
));
96 void PreferencesBrowserTest::SetUpPrefs() {
97 content::WebContents
* web_contents
=
98 browser()->tab_strip_model()->GetActiveWebContents();
99 ASSERT_TRUE(web_contents
);
100 render_view_host_
= web_contents
->GetRenderViewHost();
101 ASSERT_TRUE(render_view_host_
);
102 pref_service_
= browser()->profile()->GetPrefs();
103 pref_change_registrar_
.Init(pref_service_
);
104 ASSERT_TRUE(content::ExecuteScript(render_view_host_
,
105 "function TestEnv() {"
106 " this.sentinelName_ = 'download.prompt_for_download';"
108 " TestEnv.instance_ = this;"
111 "TestEnv.handleEvent = function(event) {"
112 " var env = TestEnv.instance_;"
113 " var name = event.type;"
114 " env.removePrefListener_(name);"
115 " if (name == TestEnv.sentinelName_)"
116 " env.sentinelValue_ = event.value.value;"
118 " env.reply_[name] = event.value;"
119 " if (env.fetching_ && !--env.fetching_ ||"
120 " !env.fetching_ && name == env.sentinelName_) {"
121 " env.removePrefListeners_();"
122 " window.domAutomationController.send(JSON.stringify(env.reply_));"
123 " delete env.reply_;"
127 "TestEnv.prototype = {"
128 " addPrefListener_: function(name) {"
129 " Preferences.getInstance().addEventListener(name,"
130 " TestEnv.handleEvent);"
133 " addPrefListeners_: function() {"
134 " for (var i in this.prefs_)"
135 " this.addPrefListener_(this.prefs_[i]);"
138 " removePrefListener_: function(name) {"
139 " Preferences.getInstance().removeEventListener(name,"
140 " TestEnv.handleEvent);"
143 " removePrefListeners_: function() {"
144 " for (var i in this.prefs_)"
145 " this.removePrefListener_(this.prefs_[i]);"
149 " addPref: function(name) {"
150 " this.prefs_.push(name);"
153 " setupAndReply: function() {"
155 " Preferences.instance_ = new Preferences();"
156 " this.addPref(this.sentinelName_);"
157 " this.fetching_ = this.prefs_.length;"
158 " this.addPrefListeners_();"
159 " Preferences.getInstance().initialize();"
162 " runAndReply: function(test) {"
164 " this.addPrefListeners_();"
166 " this.sentinelValue_ = !this.sentinelValue_;"
167 " Preferences.setBooleanPref(this.sentinelName_, this.sentinelValue_,"
171 " startObserving: function() {"
173 " this.addPrefListeners_();"
176 " finishObservingAndReply: function() {"
177 " this.sentinelValue_ = !this.sentinelValue_;"
178 " Preferences.setBooleanPref(this.sentinelName_, this.sentinelValue_,"
184 // Forwards notifications received when pref values change in the backend.
185 void PreferencesBrowserTest::OnPreferenceChanged(const std::string
& pref_name
) {
186 OnCommit(pref_service_
->FindPreference(pref_name
.c_str()));
189 void PreferencesBrowserTest::SetUpInProcessBrowserTestFixture() {
190 // Sets up a mock policy provider for user and device policies.
191 EXPECT_CALL(policy_provider_
, IsInitializationComplete(_
))
192 .WillRepeatedly(Return(true));
193 policy::BrowserPolicyConnector::SetPolicyProviderForTesting(
197 void PreferencesBrowserTest::SetUserPolicies(
198 const std::vector
<std::string
>& names
,
199 const std::vector
<base::Value
*>& values
,
200 policy::PolicyLevel level
) {
201 policy::PolicyMap map
;
202 for (size_t i
= 0; i
< names
.size(); ++i
) {
203 map
.Set(names
[i
], level
, policy::POLICY_SCOPE_USER
,
204 values
[i
]->DeepCopy(), NULL
);
206 policy_provider_
.UpdateChromePolicy(map
);
209 void PreferencesBrowserTest::ClearUserPolicies() {
210 policy::PolicyMap empty_policy_map
;
211 policy_provider_
.UpdateChromePolicy(empty_policy_map
);
214 void PreferencesBrowserTest::SetUserValues(
215 const std::vector
<std::string
>& names
,
216 const std::vector
<base::Value
*>& values
) {
217 for (size_t i
= 0; i
< names
.size(); ++i
) {
218 pref_service_
->Set(names
[i
].c_str(), *values
[i
]);
222 void PreferencesBrowserTest::VerifyKeyValue(const base::DictionaryValue
& dict
,
223 const std::string
& key
,
224 const base::Value
& expected
) {
225 const base::Value
* actual
= NULL
;
226 EXPECT_TRUE(dict
.Get(key
, &actual
)) << "Was checking key: " << key
;
228 EXPECT_EQ(expected
, *actual
) << "Was checking key: " << key
;
231 void PreferencesBrowserTest::VerifyPref(const base::DictionaryValue
* prefs
,
232 const std::string
& name
,
233 const base::Value
* value
,
234 const std::string
& controlledBy
,
237 const base::Value
* pref
= NULL
;
238 const base::DictionaryValue
* dict
= NULL
;
239 ASSERT_TRUE(prefs
->GetWithoutPathExpansion(name
, &pref
));
240 ASSERT_TRUE(pref
->GetAsDictionary(&dict
));
241 VerifyKeyValue(*dict
, "value", *value
);
242 if (!controlledBy
.empty())
243 VerifyKeyValue(*dict
, "controlledBy", base::StringValue(controlledBy
));
245 EXPECT_FALSE(dict
->HasKey("controlledBy"));
248 VerifyKeyValue(*dict
, "disabled", base::FundamentalValue(true));
249 else if (dict
->HasKey("disabled"))
250 VerifyKeyValue(*dict
, "disabled", base::FundamentalValue(false));
253 VerifyKeyValue(*dict
, "uncommitted", base::FundamentalValue(true));
254 else if (dict
->HasKey("uncommitted"))
255 VerifyKeyValue(*dict
, "uncommitted", base::FundamentalValue(false));
258 void PreferencesBrowserTest::VerifyObservedPref(const std::string
& json
,
259 const std::string
& name
,
260 const base::Value
* value
,
261 const std::string
& controlledBy
,
264 scoped_ptr
<base::Value
> observed_value_ptr
= base::JSONReader::Read(json
);
265 const base::DictionaryValue
* observed_dict
;
266 ASSERT_TRUE(observed_value_ptr
.get());
267 ASSERT_TRUE(observed_value_ptr
->GetAsDictionary(&observed_dict
));
268 VerifyPref(observed_dict
, name
, value
, controlledBy
, disabled
, uncommitted
);
271 void PreferencesBrowserTest::VerifyObservedPrefs(
272 const std::string
& json
,
273 const std::vector
<std::string
>& names
,
274 const std::vector
<base::Value
*>& values
,
275 const std::string
& controlledBy
,
278 scoped_ptr
<base::Value
> observed_value_ptr
= base::JSONReader::Read(json
);
279 const base::DictionaryValue
* observed_dict
;
280 ASSERT_TRUE(observed_value_ptr
.get());
281 ASSERT_TRUE(observed_value_ptr
->GetAsDictionary(&observed_dict
));
282 for (size_t i
= 0; i
< names
.size(); ++i
) {
283 VerifyPref(observed_dict
, names
[i
], values
[i
], controlledBy
, disabled
,
288 void PreferencesBrowserTest::ExpectNoCommit(const std::string
& name
) {
289 pref_change_registrar_
.Add(
291 base::Bind(&PreferencesBrowserTest::OnPreferenceChanged
,
292 base::Unretained(this)));
293 EXPECT_CALL(*this, OnCommit(Property(&PrefService::Preference::name
, name
)))
297 void PreferencesBrowserTest::ExpectSetCommit(const std::string
& name
,
298 const base::Value
* value
) {
299 pref_change_registrar_
.Add(
301 base::Bind(&PreferencesBrowserTest::OnPreferenceChanged
,
302 base::Unretained(this)));
303 EXPECT_CALL(*this, OnCommit(AllOf(
304 Property(&PrefService::Preference::name
, name
),
305 Property(&PrefService::Preference::IsUserControlled
, true),
306 Property(&PrefService::Preference::GetValue
, EqualsValue(value
)))));
309 void PreferencesBrowserTest::ExpectClearCommit(const std::string
& name
) {
310 pref_change_registrar_
.Add(
312 base::Bind(&PreferencesBrowserTest::OnPreferenceChanged
,
313 base::Unretained(this)));
314 EXPECT_CALL(*this, OnCommit(AllOf(
315 Property(&PrefService::Preference::name
, name
),
316 Property(&PrefService::Preference::IsUserControlled
, false))));
319 void PreferencesBrowserTest::VerifyAndClearExpectations() {
320 Mock::VerifyAndClearExpectations(this);
321 pref_change_registrar_
.RemoveAll();
324 void PreferencesBrowserTest::SetupJavaScriptTestEnvironment(
325 const std::vector
<std::string
>& pref_names
,
326 std::string
* observed_json
) const {
327 std::stringstream javascript
;
328 javascript
<< "var testEnv = new TestEnv();";
329 for (std::vector
<std::string
>::const_iterator name
= pref_names
.begin();
330 name
!= pref_names
.end(); ++name
) {
331 javascript
<< "testEnv.addPref('" << name
->c_str() << "');";
333 javascript
<< "testEnv.setupAndReply();";
334 std::string temp_observed_json
;
336 observed_json
= &temp_observed_json
;
337 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
338 render_view_host_
, javascript
.str(), observed_json
));
341 void PreferencesBrowserTest::SetPref(const std::string
& name
,
342 const std::string
& type
,
343 const base::Value
* value
,
345 std::string
* observed_json
) {
346 scoped_ptr
<base::Value
> commit_ptr(new base::FundamentalValue(commit
));
347 std::stringstream javascript
;
348 javascript
<< "testEnv.runAndReply(function() {"
349 << " Preferences.set" << type
<< "Pref("
350 << " '" << name
<< "',"
351 << " " << *value
<< ","
352 << " " << *commit_ptr
<< ");"
354 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
355 render_view_host_
, javascript
.str(), observed_json
));
358 void PreferencesBrowserTest::VerifySetPref(const std::string
& name
,
359 const std::string
& type
,
360 const base::Value
* value
,
363 ExpectSetCommit(name
, value
);
365 ExpectNoCommit(name
);
366 std::string observed_json
;
367 SetPref(name
, type
, value
, commit
, &observed_json
);
368 VerifyObservedPref(observed_json
, name
, value
, std::string(), false, !commit
);
369 VerifyAndClearExpectations();
372 void PreferencesBrowserTest::VerifyClearPref(const std::string
& name
,
373 const base::Value
* value
,
376 ExpectClearCommit(name
);
378 ExpectNoCommit(name
);
379 std::string commit_json
;
380 base::JSONWriter::Write(base::FundamentalValue(commit
), &commit_json
);
381 std::stringstream javascript
;
382 javascript
<< "testEnv.runAndReply(function() {"
383 << " Preferences.clearPref("
384 << " '" << name
.c_str() << "',"
385 << " " << commit_json
.c_str() << ");});";
386 std::string observed_json
;
387 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
388 render_view_host_
, javascript
.str(), &observed_json
));
389 VerifyObservedPref(observed_json
, name
, value
, "recommended", false, !commit
);
390 VerifyAndClearExpectations();
393 void PreferencesBrowserTest::VerifyCommit(const std::string
& name
,
394 const base::Value
* value
,
395 const std::string
& controlledBy
) {
396 std::stringstream javascript
;
397 javascript
<< "testEnv.runAndReply(function() {"
398 << " Preferences.getInstance().commitPref("
399 << " '" << name
.c_str() << "');});";
400 std::string observed_json
;
401 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
402 render_view_host_
, javascript
.str(), &observed_json
));
403 VerifyObservedPref(observed_json
, name
, value
, controlledBy
, false, false);
406 void PreferencesBrowserTest::VerifySetCommit(const std::string
& name
,
407 const base::Value
* value
) {
408 ExpectSetCommit(name
, value
);
409 VerifyCommit(name
, value
, std::string());
410 VerifyAndClearExpectations();
413 void PreferencesBrowserTest::VerifyClearCommit(const std::string
& name
,
414 const base::Value
* value
) {
415 ExpectClearCommit(name
);
416 VerifyCommit(name
, value
, "recommended");
417 VerifyAndClearExpectations();
420 void PreferencesBrowserTest::VerifyRollback(const std::string
& name
,
421 const base::Value
* value
,
422 const std::string
& controlledBy
) {
423 ExpectNoCommit(name
);
424 std::stringstream javascript
;
425 javascript
<< "testEnv.runAndReply(function() {"
426 << " Preferences.getInstance().rollbackPref("
427 << " '" << name
.c_str() << "');});";
428 std::string observed_json
;
429 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
430 render_view_host_
, javascript
.str(), &observed_json
));
431 VerifyObservedPref(observed_json
, name
, value
, controlledBy
, false, true);
432 VerifyAndClearExpectations();
435 void PreferencesBrowserTest::StartObserving() {
436 ASSERT_TRUE(content::ExecuteScript(
437 render_view_host_
, "testEnv.startObserving();"));
440 void PreferencesBrowserTest::FinishObserving(std::string
* observed_json
) {
441 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
443 "testEnv.finishObservingAndReply();",
447 void PreferencesBrowserTest::UseDefaultTestPrefs(bool includeListPref
) {
449 types_
.push_back("Boolean");
450 pref_names_
.push_back(prefs::kAlternateErrorPagesEnabled
);
451 policy_names_
.push_back(policy::key::kAlternateErrorPagesEnabled
);
452 non_default_values_
.push_back(new base::FundamentalValue(false));
455 types_
.push_back("Integer");
456 pref_names_
.push_back(prefs::kRestoreOnStartup
);
457 policy_names_
.push_back(policy::key::kRestoreOnStartup
);
458 non_default_values_
.push_back(new base::FundamentalValue(4));
461 if (includeListPref
) {
462 types_
.push_back("List");
463 pref_names_
.push_back(prefs::kURLsToRestoreOnStartup
);
464 policy_names_
.push_back(policy::key::kRestoreOnStartupURLs
);
465 base::ListValue
* list
= new base::ListValue
;
466 list
->Append(new base::StringValue("http://www.example.com"));
467 list
->Append(new base::StringValue("http://example.com"));
468 non_default_values_
.push_back(list
);
471 // Retrieve default values.
472 for (std::vector
<std::string
>::const_iterator name
= pref_names_
.begin();
473 name
!= pref_names_
.end(); ++name
) {
474 default_values_
.push_back(
475 pref_service_
->GetDefaultPrefValue(name
->c_str())->DeepCopy());
479 // Verifies that initializing the JavaScript Preferences class fires the correct
480 // notifications in JavaScript.
481 IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest
, FetchPrefs
) {
482 UseDefaultTestPrefs(true);
483 std::string observed_json
;
485 // Verify notifications when default values are in effect.
486 SetupJavaScriptTestEnvironment(pref_names_
, &observed_json
);
488 observed_json
, pref_names_
, default_values_
.get(),
489 std::string(), false, false);
491 // Verify notifications when recommended values are in effect.
492 SetUserPolicies(policy_names_
, non_default_values_
.get(),
493 policy::POLICY_LEVEL_RECOMMENDED
);
494 SetupJavaScriptTestEnvironment(pref_names_
, &observed_json
);
495 VerifyObservedPrefs(observed_json
, pref_names_
, non_default_values_
.get(),
496 "recommended", false, false);
498 // Verify notifications when mandatory values are in effect.
499 SetUserPolicies(policy_names_
, non_default_values_
.get(),
500 policy::POLICY_LEVEL_MANDATORY
);
501 SetupJavaScriptTestEnvironment(pref_names_
, &observed_json
);
502 VerifyObservedPrefs(observed_json
, pref_names_
, non_default_values_
.get(),
503 "policy", true, false);
505 // Verify notifications when user-modified values are in effect.
507 SetUserValues(pref_names_
, non_default_values_
.get());
508 SetupJavaScriptTestEnvironment(pref_names_
, &observed_json
);
509 VerifyObservedPrefs(observed_json
,
511 non_default_values_
.get(),
517 // Verifies that setting a user-modified pref value through the JavaScript
518 // Preferences class fires the correct notification in JavaScript and causes the
519 // change to be committed to the C++ backend.
520 IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest
, SetPrefs
) {
521 UseDefaultTestPrefs(false);
523 ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_
, NULL
));
524 for (size_t i
= 0; i
< pref_names_
.size(); ++i
) {
525 VerifySetPref(pref_names_
[i
], types_
[i
], non_default_values_
[i
], true);
529 // Verifies that clearing a user-modified pref value through the JavaScript
530 // Preferences class fires the correct notification in JavaScript and causes the
531 // change to be committed to the C++ backend.
532 IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest
, ClearPrefs
) {
533 UseDefaultTestPrefs(false);
535 SetUserPolicies(policy_names_
, default_values_
.get(),
536 policy::POLICY_LEVEL_RECOMMENDED
);
537 SetUserValues(pref_names_
, non_default_values_
.get());
538 ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_
, NULL
));
539 for (size_t i
= 0; i
< pref_names_
.size(); ++i
) {
540 VerifyClearPref(pref_names_
[i
], default_values_
[i
], true);
544 // Verifies that when the user-modified value of a dialog pref is set and the
545 // change then committed through the JavaScript Preferences class, the correct
546 // notifications fire and a commit to the C++ backend occurs in the latter step
548 IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest
, DialogPrefsSetCommit
) {
549 UseDefaultTestPrefs(false);
551 ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_
, NULL
));
552 for (size_t i
= 0; i
< pref_names_
.size(); ++i
) {
553 VerifySetPref(pref_names_
[i
], types_
[i
], non_default_values_
[i
], false);
554 VerifySetCommit(pref_names_
[i
], non_default_values_
[i
]);
558 // Verifies that when the user-modified value of a dialog pref is set and the
559 // change then rolled back through the JavaScript Preferences class, the correct
560 // notifications fire and no commit to the C++ backend occurs.
561 IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest
, DialogPrefsSetRollback
) {
562 UseDefaultTestPrefs(false);
564 // Verify behavior when default values are in effect.
565 ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_
, NULL
));
566 for (size_t i
= 0; i
< pref_names_
.size(); ++i
) {
567 VerifySetPref(pref_names_
[i
], types_
[i
], non_default_values_
[i
], false);
568 VerifyRollback(pref_names_
[i
], default_values_
[i
], std::string());
571 // Verify behavior when recommended values are in effect.
572 SetUserPolicies(policy_names_
, default_values_
.get(),
573 policy::POLICY_LEVEL_RECOMMENDED
);
574 ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_
, NULL
));
575 for (size_t i
= 0; i
< pref_names_
.size(); ++i
) {
576 VerifySetPref(pref_names_
[i
], types_
[i
], non_default_values_
[i
], false);
577 VerifyRollback(pref_names_
[i
], default_values_
[i
], "recommended");
581 // Verifies that when the user-modified value of a dialog pref is cleared and
582 // the change then committed through the JavaScript Preferences class, the
583 // correct notifications fire and a commit to the C++ backend occurs in the
585 IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest
, DialogPrefsClearCommit
) {
586 UseDefaultTestPrefs(false);
588 SetUserPolicies(policy_names_
, default_values_
.get(),
589 policy::POLICY_LEVEL_RECOMMENDED
);
590 SetUserValues(pref_names_
, non_default_values_
.get());
591 ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_
, NULL
));
592 for (size_t i
= 0; i
< pref_names_
.size(); ++i
) {
593 VerifyClearPref(pref_names_
[i
], default_values_
[i
], false);
594 VerifyClearCommit(pref_names_
[i
], default_values_
[i
]);
598 // Verifies that when the user-modified value of a dialog pref is cleared and
599 // the change then rolled back through the JavaScript Preferences class, the
600 // correct notifications fire and no commit to the C++ backend occurs.
601 IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest
, DialogPrefsClearRollback
) {
602 UseDefaultTestPrefs(false);
604 SetUserPolicies(policy_names_
, default_values_
.get(),
605 policy::POLICY_LEVEL_RECOMMENDED
);
606 SetUserValues(pref_names_
, non_default_values_
.get());
607 ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_
, NULL
));
608 for (size_t i
= 0; i
< pref_names_
.size(); ++i
) {
609 VerifyClearPref(pref_names_
[i
], default_values_
[i
], false);
610 VerifyRollback(pref_names_
[i
], non_default_values_
[i
], std::string());
614 // Verifies that when preference values change in the C++ backend, the correct
615 // notifications fire in JavaScript.
616 IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest
, NotificationsOnBackendChanges
) {
617 UseDefaultTestPrefs(false);
618 std::string observed_json
;
620 ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_
, NULL
));
622 // Verify notifications when recommended values come into effect.
624 SetUserPolicies(policy_names_
, non_default_values_
.get(),
625 policy::POLICY_LEVEL_RECOMMENDED
);
626 FinishObserving(&observed_json
);
627 VerifyObservedPrefs(observed_json
, pref_names_
, non_default_values_
.get(),
628 "recommended", false, false);
630 // Verify notifications when mandatory values come into effect.
632 SetUserPolicies(policy_names_
, non_default_values_
.get(),
633 policy::POLICY_LEVEL_MANDATORY
);
634 FinishObserving(&observed_json
);
635 VerifyObservedPrefs(observed_json
, pref_names_
, non_default_values_
.get(),
636 "policy", true, false);
638 // Verify notifications when default values come into effect.
641 FinishObserving(&observed_json
);
643 observed_json
, pref_names_
, default_values_
.get(),
644 std::string(), false, false);
646 // Verify notifications when user-modified values come into effect.
648 SetUserValues(pref_names_
, non_default_values_
.get());
649 FinishObserving(&observed_json
);
650 VerifyObservedPrefs(observed_json
,
652 non_default_values_
.get(),
658 #if defined(OS_CHROMEOS)
660 // Verifies that initializing the JavaScript Preferences class fires the correct
661 // notifications in JavaScript for pref values handled by the
662 // CoreChromeOSOptionsHandler class.
663 IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest
, ChromeOSDeviceFetchPrefs
) {
664 std::string observed_json
;
667 pref_names_
.push_back(chromeos::kAccountsPrefAllowGuest
);
668 default_values_
.push_back(new base::FundamentalValue(true));
671 pref_names_
.push_back(chromeos::kReleaseChannel
);
672 default_values_
.push_back(new base::StringValue(""));
675 pref_names_
.push_back(chromeos::kAccountsPrefUsers
);
676 default_values_
.push_back(new base::ListValue
);
678 // Verify notifications when default values are in effect.
679 SetupJavaScriptTestEnvironment(pref_names_
, &observed_json
);
680 VerifyObservedPrefs(observed_json
, pref_names_
, default_values_
.get(),
681 "owner", true, false);
684 // Verifies that initializing the JavaScript Preferences class fires the correct
685 // notifications in JavaScript for non-privileged pref values handled by the
686 // CoreChromeOSOptionsHandler class.
687 IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest
,
688 ChromeOSDeviceFetchNonPrivilegedPrefs
) {
689 ScopedVector
<base::Value
> decorated_non_default_values
;
690 std::string observed_json
;
692 // Non-privileged string pref.
693 pref_names_
.push_back(chromeos::kSystemTimezone
);
694 default_values_
.push_back(new base::StringValue("America/Los_Angeles"));
695 non_default_values_
.push_back(new base::StringValue("America/New_York"));
696 decorated_non_default_values
.push_back(
697 non_default_values_
.back()->DeepCopy());
699 // Verify notifications when default values are in effect.
700 SetupJavaScriptTestEnvironment(pref_names_
, &observed_json
);
701 VerifyObservedPrefs(observed_json
, pref_names_
, default_values_
.get(),
702 std::string(), false, false);
704 chromeos::CrosSettings
* cros_settings
= chromeos::CrosSettings::Get();
705 cros_settings
->Set(pref_names_
[0], *non_default_values_
[0]);
707 // Verify notifications when non-default values are in effect.
708 SetupJavaScriptTestEnvironment(pref_names_
, &observed_json
);
709 VerifyObservedPrefs(observed_json
, pref_names_
,
710 decorated_non_default_values
.get(),
711 std::string(), false, false);
714 class ManagedPreferencesBrowserTest
: public PreferencesBrowserTest
{
716 // PreferencesBrowserTest implementation:
717 void SetUpInProcessBrowserTestFixture() override
{
718 // Set up fake install attributes.
719 scoped_ptr
<policy::StubEnterpriseInstallAttributes
> attributes(
720 new policy::StubEnterpriseInstallAttributes());
721 attributes
->SetDomain("example.com");
722 attributes
->SetRegistrationUser("user@example.com");
723 policy::BrowserPolicyConnectorChromeOS::SetInstallAttributesForTesting(
724 attributes
.release());
726 PreferencesBrowserTest::SetUpInProcessBrowserTestFixture();
730 // Verifies that initializing the JavaScript Preferences class fires the correct
731 // notifications in JavaScript for pref values handled by the
732 // CoreChromeOSOptionsHandler class for a managed device.
733 IN_PROC_BROWSER_TEST_F(ManagedPreferencesBrowserTest
,
734 ChromeOSDeviceFetchPrefs
) {
735 ScopedVector
<base::Value
> decorated_non_default_values
;
736 std::string observed_json
;
739 pref_names_
.push_back(chromeos::kAccountsPrefAllowGuest
);
740 non_default_values_
.push_back(new base::FundamentalValue(false));
741 decorated_non_default_values
.push_back(
742 non_default_values_
.back()->DeepCopy());
745 pref_names_
.push_back(chromeos::kReleaseChannel
);
746 non_default_values_
.push_back(new base::StringValue("stable-channel"));
747 decorated_non_default_values
.push_back(
748 non_default_values_
.back()->DeepCopy());
751 pref_names_
.push_back(chromeos::kAccountsPrefUsers
);
752 base::ListValue
* list
= new base::ListValue
;
753 list
->Append(new base::StringValue("me@google.com"));
754 list
->Append(new base::StringValue("you@google.com"));
755 non_default_values_
.push_back(list
);
756 list
= new base::ListValue
;
757 base::DictionaryValue
* dict
= new base::DictionaryValue
;
758 dict
->SetString("username", "me@google.com");
759 dict
->SetString("name", "me@google.com");
760 dict
->SetString("email", "");
761 dict
->SetBoolean("owner", false);
763 dict
= new base::DictionaryValue
;
764 dict
->SetString("username", "you@google.com");
765 dict
->SetString("name", "you@google.com");
766 dict
->SetString("email", "");
767 dict
->SetBoolean("owner", false);
769 decorated_non_default_values
.push_back(list
);
771 chromeos::CrosSettings
* cros_settings
= chromeos::CrosSettings::Get();
772 for (size_t i
= 0; i
< pref_names_
.size(); ++i
) {
773 cros_settings
->Set(pref_names_
[i
], *non_default_values_
[i
]);
776 // Verify notifications when mandatory values are in effect.
777 SetupJavaScriptTestEnvironment(pref_names_
, &observed_json
);
778 VerifyObservedPrefs(observed_json
, pref_names_
,
779 decorated_non_default_values
.get(),
780 "policy", true, false);
783 // Verifies that initializing the JavaScript Preferences class fires the correct
784 // notifications in JavaScript for non-privileged pref values handled by the
785 // CoreChromeOSOptionsHandler class for a managed device.
786 IN_PROC_BROWSER_TEST_F(ManagedPreferencesBrowserTest
,
787 ChromeOSDeviceFetchNonPrivilegedPrefs
) {
788 ScopedVector
<base::Value
> decorated_non_default_values
;
789 std::string observed_json
;
791 // Non-privileged string pref.
792 pref_names_
.push_back(chromeos::kSystemTimezone
);
793 non_default_values_
.push_back(new base::StringValue("America/New_York"));
794 decorated_non_default_values
.push_back(
795 non_default_values_
.back()->DeepCopy());
797 // Verify notifications when mandatory values are in effect.
798 chromeos::CrosSettings
* cros_settings
= chromeos::CrosSettings::Get();
799 cros_settings
->Set(pref_names_
[0], *non_default_values_
[0]);
801 SetupJavaScriptTestEnvironment(pref_names_
, &observed_json
);
802 VerifyObservedPrefs(observed_json
, pref_names_
,
803 decorated_non_default_values
.get(),
804 std::string(), false, false);
809 const char* kUserProfilePath
= "user_profile";
813 class ProxyPreferencesBrowserTest
: public PreferencesBrowserTest
{
815 void SetUpOnMainThread() override
{
816 SetupNetworkEnvironment();
817 content::RunAllPendingInMessageLoop();
819 scoped_ptr
<base::DictionaryValue
> proxy_config_dict(
820 ProxyConfigDictionary::CreateFixedServers("127.0.0.1:8080",
821 "*.google.com, 1.2.3.4:22"));
823 ProxyConfigDictionary
proxy_config(proxy_config_dict
.get());
825 const chromeos::NetworkState
* network
= GetDefaultNetwork();
826 ASSERT_TRUE(network
);
827 chromeos::proxy_config::SetProxyConfigForNetwork(proxy_config
, *network
);
829 std::string url
= base::StringPrintf("%s?network=%s",
830 chrome::kChromeUIProxySettingsURL
,
831 network
->guid().c_str());
833 ui_test_utils::NavigateToURL(browser(), GURL(url
));
838 void SetupNetworkEnvironment() {
839 chromeos::ShillProfileClient::TestInterface
* profile_test
=
840 chromeos::DBusThreadManager::Get()->GetShillProfileClient()
841 ->GetTestInterface();
842 chromeos::ShillServiceClient::TestInterface
* service_test
=
843 chromeos::DBusThreadManager::Get()->GetShillServiceClient()
844 ->GetTestInterface();
846 profile_test
->AddProfile(kUserProfilePath
, "user");
848 service_test
->ClearServices();
849 service_test
->AddService("stub_ethernet",
850 "stub_ethernet_guid",
852 shill::kTypeEthernet
,
854 true /* add_to_visible */ );
855 service_test
->SetServiceProperty("stub_ethernet",
856 shill::kProfileProperty
,
857 base::StringValue(kUserProfilePath
));
858 profile_test
->AddService(kUserProfilePath
, "stub_wifi2");
861 void SetONCPolicy(const char* policy_name
, policy::PolicyScope scope
) {
862 std::string onc_policy
=
863 "{ \"NetworkConfigurations\": ["
864 " { \"GUID\": \"stub_ethernet_guid\","
865 " \"Type\": \"Ethernet\","
866 " \"Name\": \"My Ethernet\","
868 " \"Authentication\": \"None\" },"
869 " \"ProxySettings\": {"
870 " \"PAC\": \"http://domain.com/x\","
871 " \"Type\": \"PAC\" }"
874 " \"Type\": \"UnencryptedConfiguration\""
877 policy::PolicyMap map
;
879 policy::POLICY_LEVEL_MANDATORY
,
881 new base::StringValue(onc_policy
),
883 policy_provider_
.UpdateChromePolicy(map
);
885 content::RunAllPendingInMessageLoop();
888 const chromeos::NetworkState
* GetDefaultNetwork() {
889 chromeos::NetworkStateHandler
* handler
=
890 chromeos::NetworkHandler::Get()->network_state_handler();
891 return handler
->DefaultNetwork();
894 void SetProxyPref(const std::string
& name
, const base::Value
& value
) {
896 switch (value
.GetType()) {
897 case base::Value::TYPE_BOOLEAN
:
900 case base::Value::TYPE_INTEGER
:
903 case base::Value::TYPE_STRING
:
910 std::string observed_json
;
911 SetPref(name
, type
, &value
, true, &observed_json
);
914 void VerifyCurrentProxyServer(const std::string
& expected_server
,
915 onc::ONCSource expected_source
) {
916 const chromeos::NetworkState
* network
= GetDefaultNetwork();
917 ASSERT_TRUE(network
);
918 onc::ONCSource actual_source
;
919 scoped_ptr
<ProxyConfigDictionary
> proxy_dict
=
920 chromeos::proxy_config::GetProxyConfigForNetwork(
922 g_browser_process
->local_state(),
925 ASSERT_TRUE(proxy_dict
);
926 std::string actual_proxy_server
;
927 EXPECT_TRUE(proxy_dict
->GetProxyServer(&actual_proxy_server
));
928 EXPECT_EQ(expected_server
, actual_proxy_server
);
929 EXPECT_EQ(expected_source
, actual_source
);
933 // Verifies that proxy settings are correctly pushed to JavaScript during
934 // initialization of the proxy settings page.
935 IN_PROC_BROWSER_TEST_F(ProxyPreferencesBrowserTest
, ChromeOSInitializeProxy
) {
937 pref_names_
.push_back(chromeos::kProxySingle
);
938 non_default_values_
.push_back(new base::FundamentalValue(true));
941 pref_names_
.push_back(chromeos::kProxySingleHttpPort
);
942 non_default_values_
.push_back(new base::FundamentalValue(8080));
945 pref_names_
.push_back(chromeos::kProxySingleHttp
);
946 non_default_values_
.push_back(new base::StringValue("127.0.0.1"));
949 pref_names_
.push_back(chromeos::kProxyIgnoreList
);
950 base::ListValue
* list
= new base::ListValue();
951 list
->Append(new base::StringValue("*.google.com"));
952 list
->Append(new base::StringValue("1.2.3.4:22"));
953 non_default_values_
.push_back(list
);
955 // Verify that no policy is presented to the UI. This must be verified on the
956 // kProxyType and the kUseSharedProxies prefs.
957 pref_names_
.push_back(chromeos::kProxyType
);
958 non_default_values_
.push_back(new base::FundamentalValue(2));
960 pref_names_
.push_back(prefs::kUseSharedProxies
);
961 non_default_values_
.push_back(new base::FundamentalValue(false));
963 std::string observed_json
;
964 SetupJavaScriptTestEnvironment(pref_names_
, &observed_json
);
966 observed_json
, pref_names_
, non_default_values_
.get(), "", false, false);
969 IN_PROC_BROWSER_TEST_F(ProxyPreferencesBrowserTest
, ONCPolicy
) {
970 SetONCPolicy(policy::key::kOpenNetworkConfiguration
,
971 policy::POLICY_SCOPE_USER
);
973 // Verify that per-network policy is presented to the UI. This must be
974 // verified on the kProxyType.
975 pref_names_
.push_back(chromeos::kProxyType
);
976 non_default_values_
.push_back(new base::FundamentalValue(3));
978 std::string observed_json
;
979 SetupJavaScriptTestEnvironment(pref_names_
, &observed_json
);
981 observed_json
, pref_names_
, non_default_values_
.get(),
982 "policy", true, false);
984 // Verify that 'use-shared-proxies' is not affected by per-network policy.
986 non_default_values_
.clear();
987 pref_names_
.push_back(prefs::kUseSharedProxies
);
988 non_default_values_
.push_back(new base::FundamentalValue(false));
990 SetupJavaScriptTestEnvironment(pref_names_
, &observed_json
);
992 observed_json
, pref_names_
, non_default_values_
.get(), "", false, false);
995 IN_PROC_BROWSER_TEST_F(ProxyPreferencesBrowserTest
, DeviceONCPolicy
) {
996 SetONCPolicy(policy::key::kDeviceOpenNetworkConfiguration
,
997 policy::POLICY_SCOPE_MACHINE
);
999 // Verify that the policy is presented to the UI. This verification must be
1000 // done on the kProxyType pref.
1001 pref_names_
.push_back(chromeos::kProxyType
);
1002 non_default_values_
.push_back(new base::FundamentalValue(3));
1004 std::string observed_json
;
1005 SetupJavaScriptTestEnvironment(pref_names_
, &observed_json
);
1006 VerifyObservedPrefs(
1007 observed_json
, pref_names_
, non_default_values_
.get(),
1008 "policy", true, false);
1010 // Verify that 'use-shared-proxies' is not affected by per-network policy.
1011 pref_names_
.clear();
1012 non_default_values_
.clear();
1013 pref_names_
.push_back(prefs::kUseSharedProxies
);
1014 non_default_values_
.push_back(new base::FundamentalValue(false));
1016 SetupJavaScriptTestEnvironment(pref_names_
, &observed_json
);
1017 VerifyObservedPrefs(
1018 observed_json
, pref_names_
, non_default_values_
.get(), "", false, false);
1021 IN_PROC_BROWSER_TEST_F(ProxyPreferencesBrowserTest
, UserProxyPolicy
) {
1022 policy_names_
.push_back(policy::key::kProxyMode
);
1023 default_values_
.push_back(
1024 new base::StringValue(ProxyPrefs::kAutoDetectProxyModeName
));
1026 policy_names_
, default_values_
.get(), policy::POLICY_LEVEL_MANDATORY
);
1027 content::RunAllPendingInMessageLoop();
1029 // Verify that the policy is presented to the UI. This verification must be
1030 // done on the kProxyType pref.
1031 pref_names_
.push_back(chromeos::kProxyType
);
1032 non_default_values_
.push_back(new base::FundamentalValue(3));
1034 // Verify that 'use-shared-proxies' is controlled by the policy.
1035 pref_names_
.push_back(prefs::kUseSharedProxies
);
1036 non_default_values_
.push_back(new base::FundamentalValue(false));
1038 std::string observed_json
;
1039 SetupJavaScriptTestEnvironment(pref_names_
, &observed_json
);
1040 VerifyObservedPrefs(
1041 observed_json
, pref_names_
, non_default_values_
.get(),
1042 "policy", true, false);
1045 // Verifies that modifications to the proxy settings are correctly pushed from
1046 // JavaScript to the ProxyConfig property stored in the network configuration.
1047 IN_PROC_BROWSER_TEST_F(ProxyPreferencesBrowserTest
, ChromeOSSetProxy
) {
1048 ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_
, NULL
));
1050 SetProxyPref(chromeos::kProxySingleHttpPort
, base::FundamentalValue(123));
1051 SetProxyPref(chromeos::kProxySingleHttp
, base::StringValue("www.adomain.xy"));
1053 VerifyCurrentProxyServer("www.adomain.xy:123",
1054 onc::ONC_SOURCE_NONE
);
1057 // Verify that default proxy ports are used and that ports can be updated
1058 // without affecting the previously set hosts.
1059 IN_PROC_BROWSER_TEST_F(ProxyPreferencesBrowserTest
, ChromeOSProxyDefaultPorts
) {
1060 ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_
, NULL
));
1062 // Set to manual, per scheme proxy.
1063 SetProxyPref(chromeos::kProxySingle
, base::FundamentalValue(false));
1065 // Set hosts but no ports.
1066 SetProxyPref(chromeos::kProxyHttpUrl
, base::StringValue("a.com"));
1067 SetProxyPref(chromeos::kProxyHttpsUrl
, base::StringValue("4.3.2.1"));
1068 SetProxyPref(chromeos::kProxyFtpUrl
, base::StringValue("c.com"));
1069 SetProxyPref(chromeos::kProxySocks
, base::StringValue("d.com"));
1071 // Verify default ports.
1072 VerifyCurrentProxyServer(
1073 "http=a.com:80;https=4.3.2.1:80;ftp=c.com:80;socks=socks4://d.com:1080",
1074 onc::ONC_SOURCE_NONE
);
1076 // Set and verify the ports.
1077 SetProxyPref(chromeos::kProxyHttpPort
, base::FundamentalValue(1));
1078 SetProxyPref(chromeos::kProxyHttpsPort
, base::FundamentalValue(2));
1079 SetProxyPref(chromeos::kProxyFtpPort
, base::FundamentalValue(3));
1080 SetProxyPref(chromeos::kProxySocksPort
, base::FundamentalValue(4));
1082 VerifyCurrentProxyServer(
1083 "http=a.com:1;https=4.3.2.1:2;ftp=c.com:3;socks=socks4://d.com:4",
1084 onc::ONC_SOURCE_NONE
);