Adding instrumentation to locate the source of jankiness
[chromium-blink-merge.git] / chrome / browser / ui / webui / options / preferences_browsertest.cc
blob6587ad9586a0427766db9d61ba4face352f56d71
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"
7 #include <iostream>
8 #include <sstream>
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"
34 #include "url/gurl.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 "chrome/browser/prefs/proxy_config_dictionary.h"
45 #include "chromeos/dbus/dbus_thread_manager.h"
46 #include "chromeos/dbus/shill_profile_client.h"
47 #include "chromeos/dbus/shill_service_client.h"
48 #include "chromeos/network/network_state.h"
49 #include "chromeos/network/network_state_handler.h"
50 #include "chromeos/settings/cros_settings_names.h"
51 #include "content/public/test/test_utils.h"
52 #include "third_party/cros_system_api/dbus/service_constants.h"
53 #endif
55 using testing::AllOf;
56 using testing::Mock;
57 using testing::Property;
58 using testing::Return;
59 using testing::_;
61 namespace base {
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) {
70 std::string json;
71 JSONWriter::Write(&value, &json);
72 *stream << json;
75 } // namespace base
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));
93 SetUpPrefs();
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';"
107 " this.prefs_ = [];"
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;"
117 " else"
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_;"
124 " }"
125 "};"
127 "TestEnv.prototype = {"
128 " addPrefListener_: function(name) {"
129 " Preferences.getInstance().addEventListener(name,"
130 " TestEnv.handleEvent);"
131 " },"
133 " addPrefListeners_: function() {"
134 " for (var i in this.prefs_)"
135 " this.addPrefListener_(this.prefs_[i]);"
136 " },"
138 " removePrefListener_: function(name) {"
139 " Preferences.getInstance().removeEventListener(name,"
140 " TestEnv.handleEvent);"
141 " },"
143 " removePrefListeners_: function() {"
144 " for (var i in this.prefs_)"
145 " this.removePrefListener_(this.prefs_[i]);"
146 " },"
149 " addPref: function(name) {"
150 " this.prefs_.push(name);"
151 " },"
153 " setupAndReply: function() {"
154 " this.reply_ = {};"
155 " Preferences.instance_ = new Preferences();"
156 " this.addPref(this.sentinelName_);"
157 " this.fetching_ = this.prefs_.length;"
158 " this.addPrefListeners_();"
159 " Preferences.getInstance().initialize();"
160 " },"
162 " runAndReply: function(test) {"
163 " this.reply_ = {};"
164 " this.addPrefListeners_();"
165 " test();"
166 " this.sentinelValue_ = !this.sentinelValue_;"
167 " Preferences.setBooleanPref(this.sentinelName_, this.sentinelValue_,"
168 " true);"
169 " },"
171 " startObserving: function() {"
172 " this.reply_ = {};"
173 " this.addPrefListeners_();"
174 " },"
176 " finishObservingAndReply: function() {"
177 " this.sentinelValue_ = !this.sentinelValue_;"
178 " Preferences.setBooleanPref(this.sentinelName_, this.sentinelValue_,"
179 " true);"
180 " }"
181 "};"));
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(
194 &policy_provider_);
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;
227 if (actual)
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,
235 bool disabled,
236 bool uncommitted) {
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));
244 else
245 EXPECT_FALSE(dict->HasKey("controlledBy"));
247 if (disabled)
248 VerifyKeyValue(*dict, "disabled", base::FundamentalValue(true));
249 else if (dict->HasKey("disabled"))
250 VerifyKeyValue(*dict, "disabled", base::FundamentalValue(false));
252 if (uncommitted)
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,
262 bool disabled,
263 bool uncommitted) {
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,
276 bool disabled,
277 bool uncommitted) {
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,
284 uncommitted);
288 void PreferencesBrowserTest::ExpectNoCommit(const std::string& name) {
289 pref_change_registrar_.Add(
290 name.c_str(),
291 base::Bind(&PreferencesBrowserTest::OnPreferenceChanged,
292 base::Unretained(this)));
293 EXPECT_CALL(*this, OnCommit(Property(&PrefService::Preference::name, name)))
294 .Times(0);
297 void PreferencesBrowserTest::ExpectSetCommit(const std::string& name,
298 const base::Value* value) {
299 pref_change_registrar_.Add(
300 name.c_str(),
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(
311 name.c_str(),
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;
335 if (!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,
344 bool commit,
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 << ");"
353 << "});";
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,
361 bool commit) {
362 if (commit)
363 ExpectSetCommit(name, value);
364 else
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,
374 bool commit) {
375 if (commit)
376 ExpectClearCommit(name);
377 else
378 ExpectNoCommit(name);
379 scoped_ptr<base::Value> commit_ptr(new base::FundamentalValue(commit));
380 std::string commit_json;
381 base::JSONWriter::Write(commit_ptr.get(), &commit_json);
382 std::stringstream javascript;
383 javascript << "testEnv.runAndReply(function() {"
384 << " Preferences.clearPref("
385 << " '" << name.c_str() << "',"
386 << " " << commit_json.c_str() << ");});";
387 std::string observed_json;
388 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
389 render_view_host_, javascript.str(), &observed_json));
390 VerifyObservedPref(observed_json, name, value, "recommended", false, !commit);
391 VerifyAndClearExpectations();
394 void PreferencesBrowserTest::VerifyCommit(const std::string& name,
395 const base::Value* value,
396 const std::string& controlledBy) {
397 std::stringstream javascript;
398 javascript << "testEnv.runAndReply(function() {"
399 << " Preferences.getInstance().commitPref("
400 << " '" << name.c_str() << "');});";
401 std::string observed_json;
402 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
403 render_view_host_, javascript.str(), &observed_json));
404 VerifyObservedPref(observed_json, name, value, controlledBy, false, false);
407 void PreferencesBrowserTest::VerifySetCommit(const std::string& name,
408 const base::Value* value) {
409 ExpectSetCommit(name, value);
410 VerifyCommit(name, value, std::string());
411 VerifyAndClearExpectations();
414 void PreferencesBrowserTest::VerifyClearCommit(const std::string& name,
415 const base::Value* value) {
416 ExpectClearCommit(name);
417 VerifyCommit(name, value, "recommended");
418 VerifyAndClearExpectations();
421 void PreferencesBrowserTest::VerifyRollback(const std::string& name,
422 const base::Value* value,
423 const std::string& controlledBy) {
424 ExpectNoCommit(name);
425 std::stringstream javascript;
426 javascript << "testEnv.runAndReply(function() {"
427 << " Preferences.getInstance().rollbackPref("
428 << " '" << name.c_str() << "');});";
429 std::string observed_json;
430 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
431 render_view_host_, javascript.str(), &observed_json));
432 VerifyObservedPref(observed_json, name, value, controlledBy, false, true);
433 VerifyAndClearExpectations();
436 void PreferencesBrowserTest::StartObserving() {
437 ASSERT_TRUE(content::ExecuteScript(
438 render_view_host_, "testEnv.startObserving();"));
441 void PreferencesBrowserTest::FinishObserving(std::string* observed_json) {
442 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
443 render_view_host_,
444 "testEnv.finishObservingAndReply();",
445 observed_json));
448 void PreferencesBrowserTest::UseDefaultTestPrefs(bool includeListPref) {
449 // Boolean pref.
450 types_.push_back("Boolean");
451 pref_names_.push_back(prefs::kAlternateErrorPagesEnabled);
452 policy_names_.push_back(policy::key::kAlternateErrorPagesEnabled);
453 non_default_values_.push_back(new base::FundamentalValue(false));
455 // Integer pref.
456 types_.push_back("Integer");
457 pref_names_.push_back(prefs::kRestoreOnStartup);
458 policy_names_.push_back(policy::key::kRestoreOnStartup);
459 non_default_values_.push_back(new base::FundamentalValue(4));
461 // List pref.
462 if (includeListPref) {
463 types_.push_back("List");
464 pref_names_.push_back(prefs::kURLsToRestoreOnStartup);
465 policy_names_.push_back(policy::key::kRestoreOnStartupURLs);
466 base::ListValue* list = new base::ListValue;
467 list->Append(new base::StringValue("http://www.example.com"));
468 list->Append(new base::StringValue("http://example.com"));
469 non_default_values_.push_back(list);
472 // Retrieve default values.
473 for (std::vector<std::string>::const_iterator name = pref_names_.begin();
474 name != pref_names_.end(); ++name) {
475 default_values_.push_back(
476 pref_service_->GetDefaultPrefValue(name->c_str())->DeepCopy());
480 // Verifies that initializing the JavaScript Preferences class fires the correct
481 // notifications in JavaScript.
482 IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, FetchPrefs) {
483 UseDefaultTestPrefs(true);
484 std::string observed_json;
486 // Verify notifications when default values are in effect.
487 SetupJavaScriptTestEnvironment(pref_names_, &observed_json);
488 VerifyObservedPrefs(
489 observed_json, pref_names_, default_values_.get(),
490 std::string(), false, false);
492 // Verify notifications when recommended values are in effect.
493 SetUserPolicies(policy_names_, non_default_values_.get(),
494 policy::POLICY_LEVEL_RECOMMENDED);
495 SetupJavaScriptTestEnvironment(pref_names_, &observed_json);
496 VerifyObservedPrefs(observed_json, pref_names_, non_default_values_.get(),
497 "recommended", false, false);
499 // Verify notifications when mandatory values are in effect.
500 SetUserPolicies(policy_names_, non_default_values_.get(),
501 policy::POLICY_LEVEL_MANDATORY);
502 SetupJavaScriptTestEnvironment(pref_names_, &observed_json);
503 VerifyObservedPrefs(observed_json, pref_names_, non_default_values_.get(),
504 "policy", true, false);
506 // Verify notifications when user-modified values are in effect.
507 ClearUserPolicies();
508 SetUserValues(pref_names_, non_default_values_.get());
509 SetupJavaScriptTestEnvironment(pref_names_, &observed_json);
510 VerifyObservedPrefs(observed_json,
511 pref_names_,
512 non_default_values_.get(),
513 std::string(),
514 false,
515 false);
518 // Verifies that setting a user-modified pref value through the JavaScript
519 // Preferences class fires the correct notification in JavaScript and causes the
520 // change to be committed to the C++ backend.
521 IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, SetPrefs) {
522 UseDefaultTestPrefs(false);
524 ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_, NULL));
525 for (size_t i = 0; i < pref_names_.size(); ++i) {
526 VerifySetPref(pref_names_[i], types_[i], non_default_values_[i], true);
530 // Verifies that clearing a user-modified pref value through the JavaScript
531 // Preferences class fires the correct notification in JavaScript and causes the
532 // change to be committed to the C++ backend.
533 IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, ClearPrefs) {
534 UseDefaultTestPrefs(false);
536 SetUserPolicies(policy_names_, default_values_.get(),
537 policy::POLICY_LEVEL_RECOMMENDED);
538 SetUserValues(pref_names_, non_default_values_.get());
539 ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_, NULL));
540 for (size_t i = 0; i < pref_names_.size(); ++i) {
541 VerifyClearPref(pref_names_[i], default_values_[i], true);
545 // Verifies that when the user-modified value of a dialog pref is set and the
546 // change then committed through the JavaScript Preferences class, the correct
547 // notifications fire and a commit to the C++ backend occurs in the latter step
548 // only.
549 IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, DialogPrefsSetCommit) {
550 UseDefaultTestPrefs(false);
552 ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_, NULL));
553 for (size_t i = 0; i < pref_names_.size(); ++i) {
554 VerifySetPref(pref_names_[i], types_[i], non_default_values_[i], false);
555 VerifySetCommit(pref_names_[i], non_default_values_[i]);
559 // Verifies that when the user-modified value of a dialog pref is set and the
560 // change then rolled back through the JavaScript Preferences class, the correct
561 // notifications fire and no commit to the C++ backend occurs.
562 IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, DialogPrefsSetRollback) {
563 UseDefaultTestPrefs(false);
565 // Verify behavior when default values are in effect.
566 ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_, NULL));
567 for (size_t i = 0; i < pref_names_.size(); ++i) {
568 VerifySetPref(pref_names_[i], types_[i], non_default_values_[i], false);
569 VerifyRollback(pref_names_[i], default_values_[i], std::string());
572 // Verify behavior when recommended values are in effect.
573 SetUserPolicies(policy_names_, default_values_.get(),
574 policy::POLICY_LEVEL_RECOMMENDED);
575 ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_, NULL));
576 for (size_t i = 0; i < pref_names_.size(); ++i) {
577 VerifySetPref(pref_names_[i], types_[i], non_default_values_[i], false);
578 VerifyRollback(pref_names_[i], default_values_[i], "recommended");
582 // Verifies that when the user-modified value of a dialog pref is cleared and
583 // the change then committed through the JavaScript Preferences class, the
584 // correct notifications fire and a commit to the C++ backend occurs in the
585 // latter step only.
586 IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, DialogPrefsClearCommit) {
587 UseDefaultTestPrefs(false);
589 SetUserPolicies(policy_names_, default_values_.get(),
590 policy::POLICY_LEVEL_RECOMMENDED);
591 SetUserValues(pref_names_, non_default_values_.get());
592 ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_, NULL));
593 for (size_t i = 0; i < pref_names_.size(); ++i) {
594 VerifyClearPref(pref_names_[i], default_values_[i], false);
595 VerifyClearCommit(pref_names_[i], default_values_[i]);
599 // Verifies that when the user-modified value of a dialog pref is cleared and
600 // the change then rolled back through the JavaScript Preferences class, the
601 // correct notifications fire and no commit to the C++ backend occurs.
602 IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, DialogPrefsClearRollback) {
603 UseDefaultTestPrefs(false);
605 SetUserPolicies(policy_names_, default_values_.get(),
606 policy::POLICY_LEVEL_RECOMMENDED);
607 SetUserValues(pref_names_, non_default_values_.get());
608 ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_, NULL));
609 for (size_t i = 0; i < pref_names_.size(); ++i) {
610 VerifyClearPref(pref_names_[i], default_values_[i], false);
611 VerifyRollback(pref_names_[i], non_default_values_[i], std::string());
615 // Verifies that when preference values change in the C++ backend, the correct
616 // notifications fire in JavaScript.
617 IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, NotificationsOnBackendChanges) {
618 UseDefaultTestPrefs(false);
619 std::string observed_json;
621 ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_, NULL));
623 // Verify notifications when recommended values come into effect.
624 StartObserving();
625 SetUserPolicies(policy_names_, non_default_values_.get(),
626 policy::POLICY_LEVEL_RECOMMENDED);
627 FinishObserving(&observed_json);
628 VerifyObservedPrefs(observed_json, pref_names_, non_default_values_.get(),
629 "recommended", false, false);
631 // Verify notifications when mandatory values come into effect.
632 StartObserving();
633 SetUserPolicies(policy_names_, non_default_values_.get(),
634 policy::POLICY_LEVEL_MANDATORY);
635 FinishObserving(&observed_json);
636 VerifyObservedPrefs(observed_json, pref_names_, non_default_values_.get(),
637 "policy", true, false);
639 // Verify notifications when default values come into effect.
640 StartObserving();
641 ClearUserPolicies();
642 FinishObserving(&observed_json);
643 VerifyObservedPrefs(
644 observed_json, pref_names_, default_values_.get(),
645 std::string(), false, false);
647 // Verify notifications when user-modified values come into effect.
648 StartObserving();
649 SetUserValues(pref_names_, non_default_values_.get());
650 FinishObserving(&observed_json);
651 VerifyObservedPrefs(observed_json,
652 pref_names_,
653 non_default_values_.get(),
654 std::string(),
655 false,
656 false);
659 #if defined(OS_CHROMEOS)
661 // Verifies that initializing the JavaScript Preferences class fires the correct
662 // notifications in JavaScript for pref values handled by the
663 // CoreChromeOSOptionsHandler class.
664 IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, ChromeOSDeviceFetchPrefs) {
665 std::string observed_json;
667 // Boolean pref.
668 pref_names_.push_back(chromeos::kAccountsPrefAllowGuest);
669 default_values_.push_back(new base::FundamentalValue(true));
671 // String pref.
672 pref_names_.push_back(chromeos::kReleaseChannel);
673 default_values_.push_back(new base::StringValue(""));
675 // List pref.
676 pref_names_.push_back(chromeos::kAccountsPrefUsers);
677 default_values_.push_back(new base::ListValue);
679 // Verify notifications when default values are in effect.
680 SetupJavaScriptTestEnvironment(pref_names_, &observed_json);
681 VerifyObservedPrefs(observed_json, pref_names_, default_values_.get(),
682 "owner", true, false);
685 // Verifies that initializing the JavaScript Preferences class fires the correct
686 // notifications in JavaScript for non-privileged pref values handled by the
687 // CoreChromeOSOptionsHandler class.
688 IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest,
689 ChromeOSDeviceFetchNonPrivilegedPrefs) {
690 ScopedVector<base::Value> decorated_non_default_values;
691 std::string observed_json;
693 // Non-privileged string pref.
694 pref_names_.push_back(chromeos::kSystemTimezone);
695 default_values_.push_back(new base::StringValue("America/Los_Angeles"));
696 non_default_values_.push_back(new base::StringValue("America/New_York"));
697 decorated_non_default_values.push_back(
698 non_default_values_.back()->DeepCopy());
700 // Verify notifications when default values are in effect.
701 SetupJavaScriptTestEnvironment(pref_names_, &observed_json);
702 VerifyObservedPrefs(observed_json, pref_names_, default_values_.get(),
703 std::string(), false, false);
705 chromeos::CrosSettings* cros_settings = chromeos::CrosSettings::Get();
706 cros_settings->Set(pref_names_[0], *non_default_values_[0]);
708 // Verify notifications when non-default values are in effect.
709 SetupJavaScriptTestEnvironment(pref_names_, &observed_json);
710 VerifyObservedPrefs(observed_json, pref_names_,
711 decorated_non_default_values.get(),
712 std::string(), false, false);
715 class ManagedPreferencesBrowserTest : public PreferencesBrowserTest {
716 protected:
717 // PreferencesBrowserTest implementation:
718 virtual void SetUpInProcessBrowserTestFixture() override {
719 // Set up fake install attributes.
720 scoped_ptr<policy::StubEnterpriseInstallAttributes> attributes(
721 new policy::StubEnterpriseInstallAttributes());
722 attributes->SetDomain("example.com");
723 attributes->SetRegistrationUser("user@example.com");
724 policy::BrowserPolicyConnectorChromeOS::SetInstallAttributesForTesting(
725 attributes.release());
727 PreferencesBrowserTest::SetUpInProcessBrowserTestFixture();
731 // Verifies that initializing the JavaScript Preferences class fires the correct
732 // notifications in JavaScript for pref values handled by the
733 // CoreChromeOSOptionsHandler class for a managed device.
734 IN_PROC_BROWSER_TEST_F(ManagedPreferencesBrowserTest,
735 ChromeOSDeviceFetchPrefs) {
736 ScopedVector<base::Value> decorated_non_default_values;
737 std::string observed_json;
739 // Boolean pref.
740 pref_names_.push_back(chromeos::kAccountsPrefAllowGuest);
741 non_default_values_.push_back(new base::FundamentalValue(false));
742 decorated_non_default_values.push_back(
743 non_default_values_.back()->DeepCopy());
745 // String pref.
746 pref_names_.push_back(chromeos::kReleaseChannel);
747 non_default_values_.push_back(new base::StringValue("stable-channel"));
748 decorated_non_default_values.push_back(
749 non_default_values_.back()->DeepCopy());
751 // List pref.
752 pref_names_.push_back(chromeos::kAccountsPrefUsers);
753 base::ListValue* list = new base::ListValue;
754 list->Append(new base::StringValue("me@google.com"));
755 list->Append(new base::StringValue("you@google.com"));
756 non_default_values_.push_back(list);
757 list = new base::ListValue;
758 base::DictionaryValue* dict = new base::DictionaryValue;
759 dict->SetString("username", "me@google.com");
760 dict->SetString("name", "me@google.com");
761 dict->SetString("email", "");
762 dict->SetBoolean("owner", false);
763 list->Append(dict);
764 dict = new base::DictionaryValue;
765 dict->SetString("username", "you@google.com");
766 dict->SetString("name", "you@google.com");
767 dict->SetString("email", "");
768 dict->SetBoolean("owner", false);
769 list->Append(dict);
770 decorated_non_default_values.push_back(list);
772 chromeos::CrosSettings* cros_settings = chromeos::CrosSettings::Get();
773 for (size_t i = 0; i < pref_names_.size(); ++i) {
774 cros_settings->Set(pref_names_[i], *non_default_values_[i]);
777 // Verify notifications when mandatory values are in effect.
778 SetupJavaScriptTestEnvironment(pref_names_, &observed_json);
779 VerifyObservedPrefs(observed_json, pref_names_,
780 decorated_non_default_values.get(),
781 "policy", true, false);
784 // Verifies that initializing the JavaScript Preferences class fires the correct
785 // notifications in JavaScript for non-privileged pref values handled by the
786 // CoreChromeOSOptionsHandler class for a managed device.
787 IN_PROC_BROWSER_TEST_F(ManagedPreferencesBrowserTest,
788 ChromeOSDeviceFetchNonPrivilegedPrefs) {
789 ScopedVector<base::Value> decorated_non_default_values;
790 std::string observed_json;
792 // Non-privileged string pref.
793 pref_names_.push_back(chromeos::kSystemTimezone);
794 non_default_values_.push_back(new base::StringValue("America/New_York"));
795 decorated_non_default_values.push_back(
796 non_default_values_.back()->DeepCopy());
798 // Verify notifications when mandatory values are in effect.
799 chromeos::CrosSettings* cros_settings = chromeos::CrosSettings::Get();
800 cros_settings->Set(pref_names_[0], *non_default_values_[0]);
802 SetupJavaScriptTestEnvironment(pref_names_, &observed_json);
803 VerifyObservedPrefs(observed_json, pref_names_,
804 decorated_non_default_values.get(),
805 std::string(), false, false);
808 namespace {
810 const char* kUserProfilePath = "user_profile";
812 } // namespace
814 class ProxyPreferencesBrowserTest : public PreferencesBrowserTest {
815 public:
816 virtual void SetUpOnMainThread() override {
817 SetupNetworkEnvironment();
818 content::RunAllPendingInMessageLoop();
820 scoped_ptr<base::DictionaryValue> proxy_config_dict(
821 ProxyConfigDictionary::CreateFixedServers("127.0.0.1:8080",
822 "*.google.com, 1.2.3.4:22"));
824 ProxyConfigDictionary proxy_config(proxy_config_dict.get());
826 const chromeos::NetworkState* network = GetDefaultNetwork();
827 ASSERT_TRUE(network);
828 chromeos::proxy_config::SetProxyConfigForNetwork(proxy_config, *network);
830 std::string url = base::StringPrintf("%s?network=%s",
831 chrome::kChromeUIProxySettingsURL,
832 network->path().c_str());
834 ui_test_utils::NavigateToURL(browser(), GURL(url));
835 SetUpPrefs();
838 protected:
839 void SetupNetworkEnvironment() {
840 chromeos::ShillProfileClient::TestInterface* profile_test =
841 chromeos::DBusThreadManager::Get()->GetShillProfileClient()
842 ->GetTestInterface();
843 chromeos::ShillServiceClient::TestInterface* service_test =
844 chromeos::DBusThreadManager::Get()->GetShillServiceClient()
845 ->GetTestInterface();
847 profile_test->AddProfile(kUserProfilePath, "user");
849 service_test->ClearServices();
850 service_test->AddService("stub_ethernet",
851 "stub_ethernet_guid",
852 "eth0",
853 shill::kTypeEthernet,
854 shill::kStateOnline,
855 true /* add_to_visible */ );
856 service_test->SetServiceProperty("stub_ethernet",
857 shill::kProfileProperty,
858 base::StringValue(kUserProfilePath));
859 profile_test->AddService(kUserProfilePath, "stub_wifi2");
862 void SetONCPolicy(const char* policy_name, policy::PolicyScope scope) {
863 std::string onc_policy =
864 "{ \"NetworkConfigurations\": ["
865 " { \"GUID\": \"stub_ethernet_guid\","
866 " \"Type\": \"Ethernet\","
867 " \"Name\": \"My Ethernet\","
868 " \"Ethernet\": {"
869 " \"Authentication\": \"None\" },"
870 " \"ProxySettings\": {"
871 " \"PAC\": \"http://domain.com/x\","
872 " \"Type\": \"PAC\" }"
873 " }"
874 " ],"
875 " \"Type\": \"UnencryptedConfiguration\""
876 "}";
878 policy::PolicyMap map;
879 map.Set(policy_name,
880 policy::POLICY_LEVEL_MANDATORY,
881 scope,
882 new base::StringValue(onc_policy),
883 NULL);
884 policy_provider_.UpdateChromePolicy(map);
886 content::RunAllPendingInMessageLoop();
889 const chromeos::NetworkState* GetDefaultNetwork() {
890 chromeos::NetworkStateHandler* handler =
891 chromeos::NetworkHandler::Get()->network_state_handler();
892 return handler->DefaultNetwork();
895 void SetProxyPref(const std::string& name, const base::Value& value) {
896 std::string type;
897 switch (value.GetType()) {
898 case base::Value::TYPE_BOOLEAN:
899 type = "Boolean";
900 break;
901 case base::Value::TYPE_INTEGER:
902 type = "Integer";
903 break;
904 case base::Value::TYPE_STRING:
905 type = "String";
906 break;
907 default:
908 ASSERT_TRUE(false);
911 std::string observed_json;
912 SetPref(name, type, &value, true, &observed_json);
915 void VerifyCurrentProxyServer(const std::string& expected_server,
916 onc::ONCSource expected_source) {
917 const chromeos::NetworkState* network = GetDefaultNetwork();
918 ASSERT_TRUE(network);
919 onc::ONCSource actual_source;
920 scoped_ptr<ProxyConfigDictionary> proxy_dict =
921 chromeos::proxy_config::GetProxyConfigForNetwork(
922 pref_service_,
923 g_browser_process->local_state(),
924 *network,
925 &actual_source);
926 ASSERT_TRUE(proxy_dict);
927 std::string actual_proxy_server;
928 EXPECT_TRUE(proxy_dict->GetProxyServer(&actual_proxy_server));
929 EXPECT_EQ(expected_server, actual_proxy_server);
930 EXPECT_EQ(expected_source, actual_source);
934 // Verifies that proxy settings are correctly pushed to JavaScript during
935 // initialization of the proxy settings page.
936 IN_PROC_BROWSER_TEST_F(ProxyPreferencesBrowserTest, ChromeOSInitializeProxy) {
937 // Boolean pref.
938 pref_names_.push_back(chromeos::kProxySingle);
939 non_default_values_.push_back(new base::FundamentalValue(true));
941 // Integer prefs.
942 pref_names_.push_back(chromeos::kProxySingleHttpPort);
943 non_default_values_.push_back(new base::FundamentalValue(8080));
945 // String pref.
946 pref_names_.push_back(chromeos::kProxySingleHttp);
947 non_default_values_.push_back(new base::StringValue("127.0.0.1"));
949 // List pref.
950 pref_names_.push_back(chromeos::kProxyIgnoreList);
951 base::ListValue* list = new base::ListValue();
952 list->Append(new base::StringValue("*.google.com"));
953 list->Append(new base::StringValue("1.2.3.4:22"));
954 non_default_values_.push_back(list);
956 // Verify that no policy is presented to the UI. This must be verified on the
957 // kProxyType and the kUseSharedProxies prefs.
958 pref_names_.push_back(chromeos::kProxyType);
959 non_default_values_.push_back(new base::FundamentalValue(2));
961 pref_names_.push_back(prefs::kUseSharedProxies);
962 non_default_values_.push_back(new base::FundamentalValue(false));
964 std::string observed_json;
965 SetupJavaScriptTestEnvironment(pref_names_, &observed_json);
966 VerifyObservedPrefs(
967 observed_json, pref_names_, non_default_values_.get(), "", false, false);
970 IN_PROC_BROWSER_TEST_F(ProxyPreferencesBrowserTest, ONCPolicy) {
971 SetONCPolicy(policy::key::kOpenNetworkConfiguration,
972 policy::POLICY_SCOPE_USER);
974 // Verify that per-network policy is presented to the UI. This must be
975 // verified on the kProxyType.
976 pref_names_.push_back(chromeos::kProxyType);
977 non_default_values_.push_back(new base::FundamentalValue(3));
979 std::string observed_json;
980 SetupJavaScriptTestEnvironment(pref_names_, &observed_json);
981 VerifyObservedPrefs(
982 observed_json, pref_names_, non_default_values_.get(),
983 "policy", true, false);
985 // Verify that 'use-shared-proxies' is not affected by per-network policy.
986 pref_names_.clear();
987 non_default_values_.clear();
988 pref_names_.push_back(prefs::kUseSharedProxies);
989 non_default_values_.push_back(new base::FundamentalValue(false));
991 SetupJavaScriptTestEnvironment(pref_names_, &observed_json);
992 VerifyObservedPrefs(
993 observed_json, pref_names_, non_default_values_.get(), "", false, false);
996 IN_PROC_BROWSER_TEST_F(ProxyPreferencesBrowserTest, DeviceONCPolicy) {
997 SetONCPolicy(policy::key::kDeviceOpenNetworkConfiguration,
998 policy::POLICY_SCOPE_MACHINE);
1000 // Verify that the policy is presented to the UI. This verification must be
1001 // done on the kProxyType pref.
1002 pref_names_.push_back(chromeos::kProxyType);
1003 non_default_values_.push_back(new base::FundamentalValue(3));
1005 std::string observed_json;
1006 SetupJavaScriptTestEnvironment(pref_names_, &observed_json);
1007 VerifyObservedPrefs(
1008 observed_json, pref_names_, non_default_values_.get(),
1009 "policy", true, false);
1011 // Verify that 'use-shared-proxies' is not affected by per-network policy.
1012 pref_names_.clear();
1013 non_default_values_.clear();
1014 pref_names_.push_back(prefs::kUseSharedProxies);
1015 non_default_values_.push_back(new base::FundamentalValue(false));
1017 SetupJavaScriptTestEnvironment(pref_names_, &observed_json);
1018 VerifyObservedPrefs(
1019 observed_json, pref_names_, non_default_values_.get(), "", false, false);
1022 IN_PROC_BROWSER_TEST_F(ProxyPreferencesBrowserTest, UserProxyPolicy) {
1023 policy_names_.push_back(policy::key::kProxyMode);
1024 default_values_.push_back(
1025 new base::StringValue(ProxyPrefs::kAutoDetectProxyModeName));
1026 SetUserPolicies(
1027 policy_names_, default_values_.get(), policy::POLICY_LEVEL_MANDATORY);
1028 content::RunAllPendingInMessageLoop();
1030 // Verify that the policy is presented to the UI. This verification must be
1031 // done on the kProxyType pref.
1032 pref_names_.push_back(chromeos::kProxyType);
1033 non_default_values_.push_back(new base::FundamentalValue(3));
1035 // Verify that 'use-shared-proxies' is controlled by the policy.
1036 pref_names_.push_back(prefs::kUseSharedProxies);
1037 non_default_values_.push_back(new base::FundamentalValue(false));
1039 std::string observed_json;
1040 SetupJavaScriptTestEnvironment(pref_names_, &observed_json);
1041 VerifyObservedPrefs(
1042 observed_json, pref_names_, non_default_values_.get(),
1043 "policy", true, false);
1046 // Verifies that modifications to the proxy settings are correctly pushed from
1047 // JavaScript to the ProxyConfig property stored in the network configuration.
1048 IN_PROC_BROWSER_TEST_F(ProxyPreferencesBrowserTest, ChromeOSSetProxy) {
1049 ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_, NULL));
1051 SetProxyPref(chromeos::kProxySingleHttpPort, base::FundamentalValue(123));
1052 SetProxyPref(chromeos::kProxySingleHttp, base::StringValue("www.adomain.xy"));
1054 VerifyCurrentProxyServer("www.adomain.xy:123",
1055 onc::ONC_SOURCE_NONE);
1058 // Verify that default proxy ports are used and that ports can be updated
1059 // without affecting the previously set hosts.
1060 IN_PROC_BROWSER_TEST_F(ProxyPreferencesBrowserTest, ChromeOSProxyDefaultPorts) {
1061 ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_, NULL));
1063 // Set to manual, per scheme proxy.
1064 SetProxyPref(chromeos::kProxySingle, base::FundamentalValue(false));
1066 // Set hosts but no ports.
1067 SetProxyPref(chromeos::kProxyHttpUrl, base::StringValue("a.com"));
1068 SetProxyPref(chromeos::kProxyHttpsUrl, base::StringValue("4.3.2.1"));
1069 SetProxyPref(chromeos::kProxyFtpUrl, base::StringValue("c.com"));
1070 SetProxyPref(chromeos::kProxySocks, base::StringValue("d.com"));
1072 // Verify default ports.
1073 VerifyCurrentProxyServer(
1074 "http=a.com:80;https=4.3.2.1:80;ftp=c.com:80;socks=socks4://d.com:1080",
1075 onc::ONC_SOURCE_NONE);
1077 // Set and verify the ports.
1078 SetProxyPref(chromeos::kProxyHttpPort, base::FundamentalValue(1));
1079 SetProxyPref(chromeos::kProxyHttpsPort, base::FundamentalValue(2));
1080 SetProxyPref(chromeos::kProxyFtpPort, base::FundamentalValue(3));
1081 SetProxyPref(chromeos::kProxySocksPort, base::FundamentalValue(4));
1083 VerifyCurrentProxyServer(
1084 "http=a.com:1;https=4.3.2.1:2;ftp=c.com:3;socks=socks4://d.com:4",
1085 onc::ONC_SOURCE_NONE);
1088 #endif