Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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/options2/preferences_browsertest.h" | |
| 6 | |
| 7 #include <iostream> | |
| 8 #include <sstream> | |
| 9 | |
| 10 #include "base/json/json_reader.h" | |
| 11 #include "base/json/json_writer.h" | |
| 12 #include "base/values.h" | |
| 13 #include "chrome/browser/policy/browser_policy_connector.h" | |
| 14 #include "chrome/browser/policy/policy_map.h" | |
| 15 #include "chrome/browser/profiles/profile.h" | |
| 16 #include "chrome/browser/ui/browser.h" | |
| 17 #include "chrome/browser/ui/browser_tabstrip.h" | |
| 18 #include "chrome/common/pref_names.h" | |
| 19 #include "chrome/common/url_constants.h" | |
| 20 #include "chrome/test/base/ui_test_utils.h" | |
| 21 #include "content/public/browser/render_view_host.h" | |
| 22 #include "content/public/browser/web_contents.h" | |
| 23 #include "content/public/common/content_client.h" | |
| 24 #include "content/public/test/browser_test_utils.h" | |
| 25 #include "googleurl/src/gurl.h" | |
| 26 #include "policy/policy_constants.h" | |
| 27 #include "testing/gmock/include/gmock/gmock.h" | |
| 28 #include "testing/gtest/include/gtest/gtest.h" | |
| 29 | |
| 30 #if defined(OS_CHROMEOS) | |
| 31 #include "chrome/browser/chromeos/settings/cros_settings_names.h" | |
| 32 #include "chrome/browser/chromeos/settings/cros_settings.h" | |
| 33 #include "chrome/browser/chromeos/proxy_cros_settings_parser.h" | |
| 34 #endif | |
| 35 | |
| 36 using testing::Return; | |
| 37 | |
| 38 namespace base { | |
| 39 | |
| 40 // Helper for using EXPECT_EQ() with base::Value. | |
| 41 bool operator==(const base::Value& first, const base::Value& second) { | |
| 42 return first.Equals(&second); | |
| 43 } | |
| 44 | |
| 45 // Helper for pretty-printing the contents of base::Value in case of failures. | |
| 46 void PrintTo(const Value& value, std::ostream* stream) { | |
| 47 std::string json; | |
| 48 JSONWriter::Write(&value, &json); | |
| 49 *stream << json; | |
| 50 } | |
| 51 | |
| 52 } // namespace base | |
| 53 | |
| 54 PreferencesBrowserTest::PreferencesBrowserTest() { | |
| 55 } | |
| 56 | |
| 57 // Sets up a mock policy provider. | |
| 58 void PreferencesBrowserTest::SetUpInProcessBrowserTestFixture() { | |
| 59 EXPECT_CALL(policy_provider_, IsInitializationComplete()) | |
| 60 .WillRepeatedly(Return(true)); | |
| 61 policy::BrowserPolicyConnector::SetPolicyProviderForTesting( | |
| 62 &policy_provider_); | |
| 63 }; | |
| 64 | |
| 65 // Navigates to the settings page, causing the JS preference handling classes to | |
| 66 // be loaded and initialized. | |
| 67 void PreferencesBrowserTest::SetUpOnMainThread() { | |
| 68 ui_test_utils::NavigateToURL(browser(), | |
| 69 GURL(chrome::kChromeUISettingsFrameURL)); | |
| 70 content::WebContents* web_contents = chrome::GetActiveWebContents(browser()); | |
| 71 ASSERT_TRUE(web_contents); | |
| 72 render_view_host_ = web_contents->GetRenderViewHost(); | |
| 73 ASSERT_TRUE(render_view_host_); | |
| 74 } | |
| 75 | |
| 76 // Verifies that a dictionary contains a (key, value) pair. | |
| 77 void PreferencesBrowserTest::VerifyValue(const base::DictionaryValue* dict, | |
| 78 const std::string& key, | |
| 79 base::Value* expected) { | |
|
James Hawkins
2012/08/07 17:59:05
nit: Document that this method takes ownership of
bartfab (slow)
2012/08/07 18:27:05
Done.
| |
| 80 ASSERT_TRUE(dict); | |
|
James Hawkins
2012/08/07 17:59:05
These are internal methods so you shouldn't be ass
bartfab (slow)
2012/08/07 18:27:05
Done.
| |
| 81 ASSERT_TRUE(expected); | |
| 82 const base::Value* actual; | |
| 83 ASSERT_TRUE(dict->Get(key, &actual)) << "Was checking key: " << key; | |
|
James Hawkins
2012/08/07 17:59:05
These two should be EXPECT_TRUE instead of ASSERT_
bartfab (slow)
2012/08/07 18:27:05
Done.
| |
| 84 ASSERT_EQ(*expected, *actual) << "Was checking key: " << key; | |
| 85 delete expected; | |
| 86 } | |
| 87 | |
| 88 // Verifies that a pref value has been decorated correctly. | |
| 89 void PreferencesBrowserTest::VerifyDict(const base::DictionaryValue* dict, | |
| 90 const base::Value* value, | |
| 91 const std::string& controlledBy, | |
| 92 bool disabled) { | |
| 93 ASSERT_TRUE(dict); | |
| 94 VerifyValue(dict, "value", value->DeepCopy()); | |
| 95 if (!controlledBy.empty()) { | |
| 96 VerifyValue(dict, "controlledBy", | |
| 97 base::Value::CreateStringValue(controlledBy)); | |
| 98 } else { | |
| 99 EXPECT_FALSE(dict->HasKey("controlledBy")); | |
| 100 } | |
| 101 | |
| 102 if (disabled) | |
| 103 VerifyValue(dict, "disabled", base::Value::CreateBooleanValue(true)); | |
| 104 else if (dict->HasKey("disabled")) | |
| 105 VerifyValue(dict, "disabled", base::Value::CreateBooleanValue(false)); | |
| 106 } | |
| 107 | |
| 108 // Verifies that a dictionary contains a given pref and that its value has been | |
| 109 // decorated correctly. | |
| 110 void PreferencesBrowserTest::VerifyPref(const base::DictionaryValue* prefs, | |
| 111 const std::string& name, | |
| 112 const base::Value* value, | |
| 113 const std::string& controlledBy, | |
| 114 bool disabled) { | |
| 115 ASSERT_TRUE(prefs); | |
| 116 ASSERT_TRUE(value); | |
| 117 const base::Value* pref; | |
| 118 const base::DictionaryValue* dict; | |
| 119 ASSERT_TRUE(prefs->Get(name, &pref)); | |
| 120 ASSERT_TRUE(pref->GetAsDictionary(&dict)); | |
| 121 VerifyDict(dict, value, controlledBy, disabled); | |
| 122 } | |
| 123 | |
| 124 // Verifies that a dictionary contains a given list of prefs and that their | |
| 125 // values have been decorated correctly. | |
| 126 void PreferencesBrowserTest::VerifyPrefs( | |
| 127 const base::DictionaryValue* prefs, | |
| 128 const std::vector<std::string>& names, | |
| 129 const std::vector<base::Value*>& values, | |
| 130 const std::string& controlledBy, | |
| 131 bool disabled) { | |
| 132 ASSERT_TRUE(prefs); | |
| 133 ASSERT_EQ(names.size(), values.size()); | |
| 134 for (size_t i = 0; i < names.size(); ++i) | |
| 135 VerifyPref(prefs, names[i], values[i], controlledBy, disabled); | |
| 136 } | |
| 137 | |
| 138 // Sets a pref value from JavaScript, waits for an observer callback to fire and | |
| 139 // returns the decorated value received. | |
| 140 void PreferencesBrowserTest::VerifySetPref(const std::string& name, | |
| 141 const std::string& type, | |
| 142 base::Value* set_value, | |
| 143 base::Value* expected_value) { | |
| 144 std::string set_value_json; | |
| 145 base::JSONWriter::Write(set_value, &set_value_json); | |
| 146 std::wstringstream javascript; | |
| 147 javascript << "pref_changed_callback = function(notification) {" | |
| 148 << " if (notification[0] == '" << name.c_str() << "') {" | |
| 149 << " pref_changed_callback = function() {};" | |
| 150 << " window.domAutomationController.send(" | |
| 151 << " JSON.stringify(notification[1]));" | |
| 152 << " }" | |
| 153 << "};" | |
| 154 << "chrome.send('observePrefs', ['pref_changed_callback'," | |
| 155 << " '" << name.c_str() << "']);" | |
| 156 << "Preferences.set" << type.c_str() << "Pref(" | |
| 157 << " '" << name.c_str() << "'," | |
| 158 << " " << set_value_json.c_str() << ");"; | |
| 159 std::string actual_json; | |
| 160 ASSERT_TRUE(content::ExecuteJavaScriptAndExtractString( | |
| 161 render_view_host_, L"", javascript.str(), &actual_json)); | |
| 162 | |
| 163 base::Value* actual_value = base::JSONReader::Read(actual_json); | |
| 164 const base::DictionaryValue* actual_dict; | |
| 165 ASSERT_TRUE(actual_value); | |
| 166 ASSERT_TRUE(actual_value->GetAsDictionary(&actual_dict)); | |
| 167 VerifyDict(actual_dict, expected_value ? expected_value : set_value, | |
| 168 "", false); | |
| 169 delete set_value; | |
| 170 delete expected_value; | |
| 171 } | |
| 172 | |
| 173 // Requests a list of pref values from JavaScript, waits for a callback to fire | |
| 174 // and returns the decorated values received. | |
| 175 void PreferencesBrowserTest::FetchPrefs(const std::vector<std::string>& names, | |
| 176 base::DictionaryValue** prefs) { | |
| 177 *prefs = NULL; | |
| 178 | |
| 179 base::ListValue args_list; | |
| 180 args_list.Append(base::Value::CreateStringValue("prefs_fetched_callback")); | |
| 181 for (std::vector<std::string>::const_iterator name = names.begin(); | |
| 182 name != names.end(); ++name) | |
| 183 args_list.Append(base::Value::CreateStringValue(*name)); | |
| 184 std::string args_json; | |
| 185 base::JSONWriter::Write(&args_list, &args_json); | |
| 186 std::wstringstream javascript; | |
| 187 javascript << "prefs_fetched_callback = function(dict) {" | |
| 188 << " window.domAutomationController.send(JSON.stringify(dict));" | |
| 189 << "};" | |
| 190 << "chrome.send('fetchPrefs', " << args_json.c_str() << ");"; | |
| 191 | |
| 192 std::string fetched_json; | |
| 193 ASSERT_TRUE(content::ExecuteJavaScriptAndExtractString( | |
| 194 render_view_host_, L"", javascript.str(), &fetched_json)); | |
| 195 base::Value* fetched_value = base::JSONReader::Read(fetched_json); | |
| 196 base::DictionaryValue* fetched_dict; | |
| 197 ASSERT_TRUE(fetched_value); | |
| 198 ASSERT_TRUE(fetched_value->GetAsDictionary(&fetched_dict)); | |
| 199 *prefs = fetched_dict; | |
| 200 } | |
| 201 | |
| 202 // Sets user policies through the mock policy provider. | |
| 203 void PreferencesBrowserTest::SetUserPolicies( | |
| 204 const std::vector<std::string>& names, | |
| 205 const std::vector<base::Value*>& values, | |
| 206 policy::PolicyLevel level) { | |
| 207 ASSERT_TRUE(names.size() == values.size()); | |
| 208 policy::PolicyMap map; | |
| 209 for (size_t i = 0; i < names.size(); ++i) | |
| 210 map.Set(names[i], level, policy::POLICY_SCOPE_USER, values[i]->DeepCopy()); | |
| 211 policy_provider_.UpdateChromePolicy(map); | |
| 212 } | |
| 213 | |
| 214 // Helper deleting a vector of values. | |
| 215 void PreferencesBrowserTest::DeleteValues(std::vector<base::Value*>& values){ | |
| 216 for (std::vector<base::Value*>::iterator value = values.begin(); | |
| 217 value != values.end(); ++value) | |
| 218 delete *value; | |
| 219 values.clear(); | |
| 220 } | |
| 221 | |
| 222 // Tests verifying that the JavaScript Preferences class, the underlying C++ | |
| 223 // CoreOptionsHandler and the specialized classes handling Chrome OS device and | |
| 224 // proxy prefs behave correctly. | |
| 225 | |
| 226 // Verifies that pref values received by observer callbacks are decorated | |
| 227 // correctly when the prefs are set from JavaScript. | |
| 228 IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, SetPrefs) { | |
| 229 // Prefs handled by CoreOptionsHandler. | |
| 230 VerifySetPref(prefs::kAlternateErrorPagesEnabled, "Boolean", | |
| 231 base::Value::CreateBooleanValue(false), NULL); | |
| 232 VerifySetPref(prefs::kRestoreOnStartup, "Integer", | |
| 233 base::Value::CreateIntegerValue(4), NULL); | |
| 234 VerifySetPref(prefs::kEnterpriseWebStoreName, "String", | |
| 235 base::Value::CreateStringValue("Store"), NULL); | |
| 236 VerifySetPref(prefs::kEnterpriseWebStoreURL, "URL", | |
| 237 base::Value::CreateStringValue("http://www.google.com"), | |
| 238 base::Value::CreateStringValue("http://www.google.com/")); | |
| 239 } | |
| 240 | |
| 241 // Verifies that pref values are decorated correctly when fetched from | |
| 242 // JavaScript. | |
| 243 IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, FetchPrefs) { | |
| 244 // Pref names. | |
| 245 std::vector<std::string> pref_names; | |
| 246 // Boolean pref. | |
| 247 pref_names.push_back(prefs::kAlternateErrorPagesEnabled); | |
| 248 // Integer pref. | |
| 249 pref_names.push_back(prefs::kRestoreOnStartup); | |
| 250 // String pref. | |
| 251 pref_names.push_back(prefs::kEnterpriseWebStoreName); | |
| 252 // URL pref. | |
| 253 pref_names.push_back(prefs::kEnterpriseWebStoreURL); | |
| 254 // List pref. | |
| 255 pref_names.push_back(prefs::kURLsToRestoreOnStartup); | |
| 256 | |
| 257 // Corresponding policy names. | |
| 258 std::vector<std::string> policy_names; | |
| 259 policy_names.push_back(policy::key::kAlternateErrorPagesEnabled); | |
| 260 policy_names.push_back(policy::key::kRestoreOnStartup); | |
| 261 policy_names.push_back(policy::key::kEnterpriseWebStoreName); | |
| 262 policy_names.push_back(policy::key::kEnterpriseWebStoreURL); | |
| 263 policy_names.push_back(policy::key::kRestoreOnStartupURLs); | |
| 264 | |
| 265 // Default values. | |
| 266 std::vector<base::Value*> values; | |
| 267 values.push_back(base::Value::CreateBooleanValue(true)); | |
| 268 #if defined(OS_CHROMEOS) | |
| 269 values.push_back(base::Value::CreateIntegerValue(1)); | |
| 270 #else | |
| 271 values.push_back(base::Value::CreateIntegerValue(5)); | |
| 272 #endif | |
| 273 values.push_back(base::Value::CreateStringValue("")); | |
| 274 values.push_back(base::Value::CreateStringValue("")); | |
| 275 values.push_back(new base::ListValue); | |
| 276 | |
| 277 // Verify default values are fetched and decorated correctly. | |
| 278 base::DictionaryValue* fetched; | |
| 279 FetchPrefs(pref_names, &fetched); | |
| 280 VerifyPrefs(fetched, pref_names, values, "", false); | |
| 281 delete fetched; | |
| 282 | |
| 283 // Set recommended values. | |
| 284 DeleteValues(values); | |
| 285 values.push_back(base::Value::CreateBooleanValue(false)); | |
| 286 values.push_back(base::Value::CreateIntegerValue(4)); | |
| 287 values.push_back(base::Value::CreateStringValue("Store")); | |
| 288 values.push_back(base::Value::CreateStringValue("http://www.google.com")); | |
| 289 base::ListValue* list = new base::ListValue; | |
| 290 list->Append(base::Value::CreateStringValue("http://www.google.com")); | |
| 291 list->Append(base::Value::CreateStringValue("http://example.com")); | |
| 292 values.push_back(list); | |
| 293 SetUserPolicies(policy_names, values, policy::POLICY_LEVEL_RECOMMENDED); | |
| 294 | |
| 295 // Verify recommended values are fetched and decorated correctly. | |
| 296 FetchPrefs(pref_names, &fetched); | |
| 297 VerifyPrefs(fetched, pref_names, values, "recommended", false); | |
| 298 delete fetched; | |
| 299 | |
| 300 // Set mandatory values. | |
| 301 SetUserPolicies(policy_names, values, policy::POLICY_LEVEL_MANDATORY); | |
| 302 | |
| 303 // Verify mandatory values are fetched and decorated correctly. | |
| 304 FetchPrefs(pref_names, &fetched); | |
| 305 VerifyPrefs(fetched, pref_names, values, "policy", true); | |
| 306 delete fetched; | |
| 307 | |
| 308 DeleteValues(values); | |
| 309 } | |
| 310 | |
| 311 #if defined(OS_CHROMEOS) | |
| 312 // Verifies that pref values handled by the CoreChromeOSOptionsHandler class | |
| 313 // are decorated correctly when requested from JavaScript. | |
| 314 IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, ChromeOSDeviceFetchPrefs) { | |
| 315 // Pref names. | |
| 316 std::vector<std::string> names; | |
| 317 // Boolean pref. | |
| 318 names.push_back(chromeos::kAccountsPrefAllowGuest); | |
| 319 // String pref. | |
| 320 names.push_back(chromeos::kReleaseChannel); | |
| 321 // List pref. | |
| 322 names.push_back(chromeos::kAccountsPrefUsers); | |
| 323 | |
| 324 // Default pref values. | |
| 325 std::vector<base::Value*> values; | |
| 326 values.push_back(base::Value::CreateBooleanValue(true)); | |
| 327 values.push_back(base::Value::CreateStringValue("")); | |
| 328 values.push_back(new base::ListValue); | |
| 329 | |
| 330 // Verify default values are fetched and decorated correctly. | |
| 331 base::DictionaryValue* fetched; | |
| 332 FetchPrefs(names, &fetched); | |
| 333 VerifyPrefs(fetched, names, values, "", true); | |
| 334 delete fetched; | |
| 335 | |
| 336 // Set mandatory values. | |
| 337 DeleteValues(values); | |
| 338 values.push_back(base::Value::CreateBooleanValue(false)); | |
| 339 values.push_back(base::Value::CreateStringValue("stable-channel")); | |
| 340 base::ListValue* list = new base::ListValue; | |
| 341 list->Append(base::Value::CreateStringValue("me@google.com")); | |
| 342 list->Append(base::Value::CreateStringValue("you@google.com")); | |
| 343 values.push_back(list); | |
| 344 ASSERT_EQ(names.size(), values.size()); | |
| 345 chromeos::CrosSettings* cros_settings = chromeos::CrosSettings::Get(); | |
| 346 for (size_t i = 0; i < names.size(); ++i) | |
| 347 cros_settings->Set(names[i], *values[i]); | |
| 348 | |
| 349 // Verify mandatory values are fetched and decorated correctly. | |
| 350 DeleteValues(values); | |
| 351 values.push_back(base::Value::CreateBooleanValue(false)); | |
| 352 values.push_back(base::Value::CreateStringValue("stable-channel")); | |
| 353 list = new base::ListValue; | |
| 354 base::DictionaryValue* dict = new base::DictionaryValue; | |
| 355 dict->SetString("username", "me@google.com"); | |
| 356 dict->SetString("name", "me@google.com"); | |
| 357 dict->SetString("email", ""); | |
| 358 dict->SetBoolean("owner", false); | |
| 359 list->Append(dict); | |
| 360 dict = new base::DictionaryValue; | |
| 361 dict->SetString("username", "you@google.com"); | |
| 362 dict->SetString("name", "you@google.com"); | |
| 363 dict->SetString("email", ""); | |
| 364 dict->SetBoolean("owner", false); | |
| 365 list->Append(dict); | |
| 366 values.push_back(list); | |
| 367 FetchPrefs(names, &fetched); | |
| 368 // FIXME(bartfab): Find a way to simulate enterprise enrollment in browser | |
| 369 // tests. Only if Chrome thinks that it is enrolled will the device prefs be | |
| 370 // decorated with "controlledBy: policy". | |
| 371 VerifyPrefs(fetched, names, values, "", true); | |
| 372 delete fetched; | |
| 373 | |
| 374 DeleteValues(values); | |
| 375 } | |
| 376 | |
| 377 // Verifies that pref values handled by the Chrome OS proxy settings parser are | |
| 378 // decorated correctly when requested from JavaScript. | |
| 379 IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, ChromeOSProxyFetchPrefs) { | |
| 380 // Pref names. | |
| 381 std::vector<std::string> names; | |
| 382 // Boolean pref. | |
| 383 names.push_back(chromeos::kProxySingle); | |
| 384 // Integer pref. | |
| 385 names.push_back(chromeos::kProxySingleHttpPort); | |
| 386 // String pref. | |
| 387 names.push_back(chromeos::kProxySingleHttp); | |
| 388 // List pref. | |
| 389 names.push_back(chromeos::kProxyIgnoreList); | |
| 390 | |
| 391 // Default values. | |
| 392 std::vector<base::Value*> values; | |
| 393 values.push_back(base::Value::CreateBooleanValue(false)); | |
| 394 values.push_back(base::Value::CreateStringValue("")); | |
| 395 values.push_back(base::Value::CreateStringValue("")); | |
| 396 values.push_back(new base::ListValue()); | |
| 397 | |
| 398 // Verify default values are fetched and decorated correctly. | |
| 399 base::DictionaryValue* fetched; | |
| 400 FetchPrefs(names, &fetched); | |
| 401 VerifyPrefs(fetched, names, values, "", false); | |
| 402 delete fetched; | |
| 403 | |
| 404 // Set user-modified values. | |
| 405 DeleteValues(values); | |
| 406 values.push_back(base::Value::CreateBooleanValue(true)); | |
| 407 values.push_back(base::Value::CreateIntegerValue(8080)); | |
| 408 values.push_back(base::Value::CreateStringValue("127.0.0.1")); | |
| 409 base::ListValue* list = new base::ListValue(); | |
| 410 list->Append(base::Value::CreateStringValue("www.google.com")); | |
| 411 list->Append(base::Value::CreateStringValue("example.com")); | |
| 412 values.push_back(list); | |
| 413 ASSERT_EQ(names.size(), values.size()); | |
| 414 Profile* profile = browser()->profile(); | |
| 415 // Do not set the Boolean pref. It will toogle automatically. | |
| 416 for (size_t i = 1; i < names.size(); ++i) | |
| 417 chromeos::proxy_cros_settings_parser::SetProxyPrefValue( | |
| 418 profile, names[i], values[i]->DeepCopy()); | |
| 419 | |
| 420 // Verify user-modified values are fetched and decorated correctly. | |
| 421 FetchPrefs(names, &fetched); | |
| 422 VerifyPrefs(fetched, names, values, "", false); | |
| 423 delete fetched; | |
| 424 | |
| 425 DeleteValues(values); | |
| 426 } | |
| 427 #endif | |
| OLD | NEW |