Home | History | Annotate | Download | only in options
      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.
      4 
      5 #include "chrome/browser/ui/webui/options/preferences_browsertest.h"
      6 
      7 #include <iostream>
      8 #include <sstream>
      9 
     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"
     35 
     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
     54 
     55 using testing::AllOf;
     56 using testing::Mock;
     57 using testing::Property;
     58 using testing::Return;
     59 using testing::_;
     60 
     61 namespace base {
     62 
     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);
     66 }
     67 
     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;
     73 }
     74 
     75 }  // namespace base
     76 
     77 // Googlemock matcher for base::Value.
     78 MATCHER_P(EqualsValue, expected, "") {
     79   return arg && arg->Equals(expected);
     80 }
     81 
     82 PreferencesBrowserTest::PreferencesBrowserTest() {
     83 }
     84 
     85 PreferencesBrowserTest::~PreferencesBrowserTest() {
     86 }
     87 
     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();
     94 }
     95 
     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;"
    109       "}"
    110       ""
    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       "};"
    126       ""
    127       "TestEnv.prototype = {"
    128       "  addPrefListener_: function(name) {"
    129       "    Preferences.getInstance().addEventListener(name,"
    130       "                                               TestEnv.handleEvent);"
    131       "  },"
    132       ""
    133       "  addPrefListeners_: function() {"
    134       "    for (var i in this.prefs_)"
    135       "      this.addPrefListener_(this.prefs_[i]);"
    136       "  },"
    137       ""
    138       "  removePrefListener_: function(name) {"
    139       "    Preferences.getInstance().removeEventListener(name,"
    140       "                                                  TestEnv.handleEvent);"
    141       "  },"
    142       ""
    143       "  removePrefListeners_: function() {"
    144       "    for (var i in this.prefs_)"
    145       "      this.removePrefListener_(this.prefs_[i]);"
    146       "  },"
    147       ""
    148       ""
    149       "  addPref: function(name) {"
    150       "    this.prefs_.push(name);"
    151       "  },"
    152       ""
    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       "  },"
    161       ""
    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       "  },"
    170       ""
    171       "  startObserving: function() {"
    172       "    this.reply_ = {};"
    173       "    this.addPrefListeners_();"
    174       "  },"
    175       ""
    176       "  finishObservingAndReply: function() {"
    177       "    this.sentinelValue_ = !this.sentinelValue_;"
    178       "    Preferences.setBooleanPref(this.sentinelName_, this.sentinelValue_,"
    179       "                               true);"
    180       "  }"
    181       "};"));
    182 }
    183 
    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()));
    187 }
    188 
    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_);
    195 };
    196 
    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);
    205   }
    206   policy_provider_.UpdateChromePolicy(map);
    207 }
    208 
    209 void PreferencesBrowserTest::ClearUserPolicies() {
    210   policy::PolicyMap empty_policy_map;
    211   policy_provider_.UpdateChromePolicy(empty_policy_map);
    212 }
    213 
    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]);
    219   }
    220 }
    221 
    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;
    229 }
    230 
    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"));
    246 
    247   if (disabled)
    248     VerifyKeyValue(*dict, "disabled", base::FundamentalValue(true));
    249   else if (dict->HasKey("disabled"))
    250     VerifyKeyValue(*dict, "disabled", base::FundamentalValue(false));
    251 
    252   if (uncommitted)
    253     VerifyKeyValue(*dict, "uncommitted", base::FundamentalValue(true));
    254   else if (dict->HasKey("uncommitted"))
    255     VerifyKeyValue(*dict, "uncommitted", base::FundamentalValue(false));
    256 }
    257 
    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);
    269 }
    270 
    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);
    285   }
    286 }
    287 
    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);
    295 }
    296 
    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)))));
    307 }
    308 
    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))));
    317 }
    318 
    319 void PreferencesBrowserTest::VerifyAndClearExpectations() {
    320   Mock::VerifyAndClearExpectations(this);
    321   pref_change_registrar_.RemoveAll();
    322 }
    323 
    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() << "');";
    332   }
    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));
    339 }
    340 
    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));
    356 }
    357 
    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();
    370 }
    371 
    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();
    392 }
    393 
    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);
    405 }
    406 
    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();
    412 }
    413 
    414 void PreferencesBrowserTest::VerifyClearCommit(const std::string& name,
    415                                                const base::Value* value) {
    416   ExpectClearCommit(name);
    417   VerifyCommit(name, value, "recommended");
    418   VerifyAndClearExpectations();
    419 }
    420 
    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();
    434 }
    435 
    436 void PreferencesBrowserTest::StartObserving() {
    437   ASSERT_TRUE(content::ExecuteScript(
    438       render_view_host_, "testEnv.startObserving();"));
    439 }
    440 
    441 void PreferencesBrowserTest::FinishObserving(std::string* observed_json) {
    442   ASSERT_TRUE(content::ExecuteScriptAndExtractString(
    443       render_view_host_,
    444       "testEnv.finishObservingAndReply();",
    445       observed_json));
    446 }
    447 
    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));
    454 
    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));
    460 
    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);
    470   }
    471 
    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());
    477   }
    478 }
    479 
    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;
    485 
    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);
    491 
    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);
    498 
    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);
    505 
    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);
    516 }
    517 
    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);
    523 
    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);
    527   }
    528 }
    529 
    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);
    535 
    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);
    542   }
    543 }
    544 
    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);
    551 
    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]);
    556   }
    557 }
    558 
    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);
    564 
    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());
    570   }
    571 
    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");
    579   }
    580 }
    581 
    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);
    588 
    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]);
    596   }
    597 }
    598 
    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);
    604 
    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());
    612   }
    613 }
    614 
    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;
    620 
    621   ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_, NULL));
    622 
    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);
    630 
    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);
    638 
    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);
    646 
    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);
    657 }
    658 
    659 #if defined(OS_CHROMEOS)
    660 
    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;
    666 
    667   // Boolean pref.
    668   pref_names_.push_back(chromeos::kAccountsPrefAllowGuest);
    669   default_values_.push_back(new base::FundamentalValue(true));
    670 
    671   // String pref.
    672   pref_names_.push_back(chromeos::kReleaseChannel);
    673   default_values_.push_back(new base::StringValue(""));
    674 
    675   // List pref.
    676   pref_names_.push_back(chromeos::kAccountsPrefUsers);
    677   default_values_.push_back(new base::ListValue);
    678 
    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);
    683 }
    684 
    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;
    692 
    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());
    699 
    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);
    704 
    705   chromeos::CrosSettings* cros_settings = chromeos::CrosSettings::Get();
    706   cros_settings->Set(pref_names_[0], *non_default_values_[0]);
    707 
    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);
    713 }
    714 
    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 (at) example.com");
    724     policy::BrowserPolicyConnectorChromeOS::SetInstallAttributesForTesting(
    725         attributes.release());
    726 
    727     PreferencesBrowserTest::SetUpInProcessBrowserTestFixture();
    728   }
    729 };
    730 
    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;
    738 
    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());
    744 
    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());
    750 
    751   // List pref.
    752   pref_names_.push_back(chromeos::kAccountsPrefUsers);
    753   base::ListValue* list = new base::ListValue;
    754   list->Append(new base::StringValue("me (at) google.com"));
    755   list->Append(new base::StringValue("you (at) 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 (at) google.com");
    760   dict->SetString("name", "me (at) 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 (at) google.com");
    766   dict->SetString("name", "you (at) google.com");
    767   dict->SetString("email", "");
    768   dict->SetBoolean("owner", false);
    769   list->Append(dict);
    770   decorated_non_default_values.push_back(list);
    771 
    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]);
    775   }
    776 
    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);
    782 }
    783 
    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;
    791 
    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());
    797 
    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]);
    801 
    802   SetupJavaScriptTestEnvironment(pref_names_, &observed_json);
    803   VerifyObservedPrefs(observed_json, pref_names_,
    804                       decorated_non_default_values.get(),
    805                       std::string(), false, false);
    806 }
    807 
    808 namespace {
    809 
    810 const char* kUserProfilePath = "user_profile";
    811 
    812 }  // namespace
    813 
    814 class ProxyPreferencesBrowserTest : public PreferencesBrowserTest {
    815  public:
    816   virtual void SetUpOnMainThread() OVERRIDE {
    817     SetupNetworkEnvironment();
    818     content::RunAllPendingInMessageLoop();
    819 
    820     scoped_ptr<base::DictionaryValue> proxy_config_dict(
    821         ProxyConfigDictionary::CreateFixedServers("127.0.0.1:8080",
    822                                                   "*.google.com, 1.2.3.4:22"));
    823 
    824     ProxyConfigDictionary proxy_config(proxy_config_dict.get());
    825 
    826     const chromeos::NetworkState* network = GetDefaultNetwork();
    827     ASSERT_TRUE(network);
    828     chromeos::proxy_config::SetProxyConfigForNetwork(proxy_config, *network);
    829 
    830     std::string url = base::StringPrintf("%s?network=%s",
    831                                          chrome::kChromeUIProxySettingsURL,
    832                                          network->path().c_str());
    833 
    834     ui_test_utils::NavigateToURL(browser(), GURL(url));
    835     SetUpPrefs();
    836   }
    837 
    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();
    846 
    847     profile_test->AddProfile(kUserProfilePath, "user");
    848 
    849     service_test->ClearServices();
    850     service_test->AddService("stub_ethernet",
    851                              "eth0",
    852                              shill::kTypeEthernet,
    853                              shill::kStateOnline,
    854                              true /* add_to_visible */ );
    855     service_test->SetServiceProperty("stub_ethernet",
    856                                      shill::kGuidProperty,
    857                                      base::StringValue("stub_ethernet"));
    858     service_test->SetServiceProperty("stub_ethernet",
    859                                      shill::kProfileProperty,
    860                                      base::StringValue(kUserProfilePath));
    861     profile_test->AddService(kUserProfilePath, "stub_wifi2");
    862   }
    863 
    864   void SetONCPolicy(const char* policy_name, policy::PolicyScope scope) {
    865     std::string onc_policy =
    866         "{ \"NetworkConfigurations\": ["
    867         "    { \"GUID\": \"stub_ethernet\","
    868         "      \"Type\": \"Ethernet\","
    869         "      \"Name\": \"My Ethernet\","
    870         "      \"Ethernet\": {"
    871         "        \"Authentication\": \"None\" },"
    872         "      \"ProxySettings\": {"
    873         "        \"PAC\": \"http://domain.com/x\","
    874         "        \"Type\": \"PAC\" }"
    875         "    }"
    876         "  ],"
    877         "  \"Type\": \"UnencryptedConfiguration\""
    878         "}";
    879 
    880     policy::PolicyMap map;
    881     map.Set(policy_name,
    882             policy::POLICY_LEVEL_MANDATORY,
    883             scope,
    884             new base::StringValue(onc_policy),
    885             NULL);
    886     policy_provider_.UpdateChromePolicy(map);
    887 
    888     content::RunAllPendingInMessageLoop();
    889   }
    890 
    891   const chromeos::NetworkState* GetDefaultNetwork() {
    892     chromeos::NetworkStateHandler* handler =
    893         chromeos::NetworkHandler::Get()->network_state_handler();
    894     return handler->DefaultNetwork();
    895   }
    896 
    897   void SetProxyPref(const std::string& name, const base::Value& value) {
    898     std::string type;
    899     switch (value.GetType()) {
    900       case base::Value::TYPE_BOOLEAN:
    901         type = "Boolean";
    902         break;
    903       case base::Value::TYPE_INTEGER:
    904         type = "Integer";
    905         break;
    906       case base::Value::TYPE_STRING:
    907         type = "String";
    908         break;
    909       default:
    910         ASSERT_TRUE(false);
    911     }
    912 
    913     std::string observed_json;
    914     SetPref(name, type, &value, true, &observed_json);
    915   }
    916 
    917   void VerifyCurrentProxyServer(const std::string& expected_server,
    918                                 onc::ONCSource expected_source) {
    919     const chromeos::NetworkState* network = GetDefaultNetwork();
    920     ASSERT_TRUE(network);
    921     onc::ONCSource actual_source;
    922     scoped_ptr<ProxyConfigDictionary> proxy_dict =
    923         chromeos::proxy_config::GetProxyConfigForNetwork(
    924             pref_service_,
    925             g_browser_process->local_state(),
    926             *network,
    927             &actual_source);
    928     ASSERT_TRUE(proxy_dict);
    929     std::string actual_proxy_server;
    930     EXPECT_TRUE(proxy_dict->GetProxyServer(&actual_proxy_server));
    931     EXPECT_EQ(expected_server, actual_proxy_server);
    932     EXPECT_EQ(expected_source, actual_source);
    933   }
    934 };
    935 
    936 // Verifies that proxy settings are correctly pushed to JavaScript during
    937 // initialization of the proxy settings page.
    938 IN_PROC_BROWSER_TEST_F(ProxyPreferencesBrowserTest, ChromeOSInitializeProxy) {
    939   // Boolean pref.
    940   pref_names_.push_back(chromeos::kProxySingle);
    941   non_default_values_.push_back(new base::FundamentalValue(true));
    942 
    943   // Integer prefs.
    944   pref_names_.push_back(chromeos::kProxySingleHttpPort);
    945   non_default_values_.push_back(new base::FundamentalValue(8080));
    946 
    947   // String pref.
    948   pref_names_.push_back(chromeos::kProxySingleHttp);
    949   non_default_values_.push_back(new base::StringValue("127.0.0.1"));
    950 
    951   // List pref.
    952   pref_names_.push_back(chromeos::kProxyIgnoreList);
    953   base::ListValue* list = new base::ListValue();
    954   list->Append(new base::StringValue("*.google.com"));
    955   list->Append(new base::StringValue("1.2.3.4:22"));
    956   non_default_values_.push_back(list);
    957 
    958   // Verify that no policy is presented to the UI. This must be verified on the
    959   // kProxyType and the kUseSharedProxies prefs.
    960   pref_names_.push_back(chromeos::kProxyType);
    961   non_default_values_.push_back(new base::FundamentalValue(2));
    962 
    963   pref_names_.push_back(prefs::kUseSharedProxies);
    964   non_default_values_.push_back(new base::FundamentalValue(false));
    965 
    966   std::string observed_json;
    967   SetupJavaScriptTestEnvironment(pref_names_, &observed_json);
    968   VerifyObservedPrefs(
    969       observed_json, pref_names_, non_default_values_.get(), "", false, false);
    970 }
    971 
    972 IN_PROC_BROWSER_TEST_F(ProxyPreferencesBrowserTest, ONCPolicy) {
    973   SetONCPolicy(policy::key::kOpenNetworkConfiguration,
    974                policy::POLICY_SCOPE_USER);
    975 
    976   // Verify that per-network policy is presented to the UI. This must be
    977   // verified on the kProxyType.
    978   pref_names_.push_back(chromeos::kProxyType);
    979   non_default_values_.push_back(new base::FundamentalValue(3));
    980 
    981   std::string observed_json;
    982   SetupJavaScriptTestEnvironment(pref_names_, &observed_json);
    983   VerifyObservedPrefs(
    984       observed_json, pref_names_, non_default_values_.get(),
    985       "policy", true, false);
    986 
    987   // Verify that 'use-shared-proxies' is not affected by per-network policy.
    988   pref_names_.clear();
    989   non_default_values_.clear();
    990   pref_names_.push_back(prefs::kUseSharedProxies);
    991   non_default_values_.push_back(new base::FundamentalValue(false));
    992 
    993   SetupJavaScriptTestEnvironment(pref_names_, &observed_json);
    994   VerifyObservedPrefs(
    995       observed_json, pref_names_, non_default_values_.get(), "", false, false);
    996 }
    997 
    998 IN_PROC_BROWSER_TEST_F(ProxyPreferencesBrowserTest, DeviceONCPolicy) {
    999   SetONCPolicy(policy::key::kDeviceOpenNetworkConfiguration,
   1000                policy::POLICY_SCOPE_MACHINE);
   1001 
   1002   // Verify that the policy is presented to the UI. This verification must be
   1003   // done on the kProxyType pref.
   1004   pref_names_.push_back(chromeos::kProxyType);
   1005   non_default_values_.push_back(new base::FundamentalValue(3));
   1006 
   1007   std::string observed_json;
   1008   SetupJavaScriptTestEnvironment(pref_names_, &observed_json);
   1009   VerifyObservedPrefs(
   1010       observed_json, pref_names_, non_default_values_.get(),
   1011       "policy", true, false);
   1012 
   1013   // Verify that 'use-shared-proxies' is not affected by per-network policy.
   1014   pref_names_.clear();
   1015   non_default_values_.clear();
   1016   pref_names_.push_back(prefs::kUseSharedProxies);
   1017   non_default_values_.push_back(new base::FundamentalValue(false));
   1018 
   1019   SetupJavaScriptTestEnvironment(pref_names_, &observed_json);
   1020   VerifyObservedPrefs(
   1021       observed_json, pref_names_, non_default_values_.get(), "", false, false);
   1022 }
   1023 
   1024 IN_PROC_BROWSER_TEST_F(ProxyPreferencesBrowserTest, UserProxyPolicy) {
   1025   policy_names_.push_back(policy::key::kProxyMode);
   1026   default_values_.push_back(
   1027       new base::StringValue(ProxyPrefs::kAutoDetectProxyModeName));
   1028   SetUserPolicies(
   1029       policy_names_, default_values_.get(), policy::POLICY_LEVEL_MANDATORY);
   1030   content::RunAllPendingInMessageLoop();
   1031 
   1032   // Verify that the policy is presented to the UI. This verification must be
   1033   // done on the kProxyType pref.
   1034   pref_names_.push_back(chromeos::kProxyType);
   1035   non_default_values_.push_back(new base::FundamentalValue(3));
   1036 
   1037   // Verify that 'use-shared-proxies' is controlled by the policy.
   1038   pref_names_.push_back(prefs::kUseSharedProxies);
   1039   non_default_values_.push_back(new base::FundamentalValue(false));
   1040 
   1041   std::string observed_json;
   1042   SetupJavaScriptTestEnvironment(pref_names_, &observed_json);
   1043   VerifyObservedPrefs(
   1044       observed_json, pref_names_, non_default_values_.get(),
   1045       "policy", true, false);
   1046 }
   1047 
   1048 // Verifies that modifications to the proxy settings are correctly pushed from
   1049 // JavaScript to the ProxyConfig property stored in the network configuration.
   1050 IN_PROC_BROWSER_TEST_F(ProxyPreferencesBrowserTest, ChromeOSSetProxy) {
   1051   ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_, NULL));
   1052 
   1053   SetProxyPref(chromeos::kProxySingleHttpPort, base::FundamentalValue(123));
   1054   SetProxyPref(chromeos::kProxySingleHttp, base::StringValue("www.adomain.xy"));
   1055 
   1056   VerifyCurrentProxyServer("www.adomain.xy:123",
   1057                            onc::ONC_SOURCE_NONE);
   1058 }
   1059 
   1060 // Verify that default proxy ports are used and that ports can be updated
   1061 // without affecting the previously set hosts.
   1062 IN_PROC_BROWSER_TEST_F(ProxyPreferencesBrowserTest, ChromeOSProxyDefaultPorts) {
   1063   ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_, NULL));
   1064 
   1065   // Set to manual, per scheme proxy.
   1066   SetProxyPref(chromeos::kProxySingle, base::FundamentalValue(false));
   1067 
   1068   // Set hosts but no ports.
   1069   SetProxyPref(chromeos::kProxyHttpUrl, base::StringValue("a.com"));
   1070   SetProxyPref(chromeos::kProxyHttpsUrl, base::StringValue("4.3.2.1"));
   1071   SetProxyPref(chromeos::kProxyFtpUrl, base::StringValue("c.com"));
   1072   SetProxyPref(chromeos::kProxySocks, base::StringValue("d.com"));
   1073 
   1074   // Verify default ports.
   1075   VerifyCurrentProxyServer(
   1076       "http=a.com:80;https=4.3.2.1:80;ftp=c.com:80;socks=socks4://d.com:1080",
   1077       onc::ONC_SOURCE_NONE);
   1078 
   1079   // Set and verify the ports.
   1080   SetProxyPref(chromeos::kProxyHttpPort, base::FundamentalValue(1));
   1081   SetProxyPref(chromeos::kProxyHttpsPort, base::FundamentalValue(2));
   1082   SetProxyPref(chromeos::kProxyFtpPort, base::FundamentalValue(3));
   1083   SetProxyPref(chromeos::kProxySocksPort, base::FundamentalValue(4));
   1084 
   1085   VerifyCurrentProxyServer(
   1086       "http=a.com:1;https=4.3.2.1:2;ftp=c.com:3;socks=socks4://d.com:4",
   1087       onc::ONC_SOURCE_NONE);
   1088 }
   1089 
   1090 #endif
   1091