Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4426)

Unified Diff: chrome/browser/ui/webui/options2/preferences_browsertest.cc

Issue 10834109: Consistently decorate pref values sent to the settings UI code (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Browser test added. Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/webui/options2/preferences_browsertest.cc
diff --git a/chrome/browser/ui/webui/options2/preferences_browsertest.cc b/chrome/browser/ui/webui/options2/preferences_browsertest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..2441f59b43795afc64b43d8e7a102b4db804264b
--- /dev/null
+++ b/chrome/browser/ui/webui/options2/preferences_browsertest.cc
@@ -0,0 +1,427 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/options2/preferences_browsertest.h"
+
+#include <iostream>
+#include <sstream>
+
+#include "base/json/json_reader.h"
+#include "base/json/json_writer.h"
+#include "base/values.h"
+#include "chrome/browser/policy/browser_policy_connector.h"
+#include "chrome/browser/policy/policy_map.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_tabstrip.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/common/url_constants.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/common/content_client.h"
+#include "content/public/test/browser_test_utils.h"
+#include "googleurl/src/gurl.h"
+#include "policy/policy_constants.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+#if defined(OS_CHROMEOS)
+#include "chrome/browser/chromeos/settings/cros_settings_names.h"
+#include "chrome/browser/chromeos/settings/cros_settings.h"
+#include "chrome/browser/chromeos/proxy_cros_settings_parser.h"
+#endif
+
+using testing::Return;
+
+namespace base {
+
+// Helper for using EXPECT_EQ() with base::Value.
+bool operator==(const base::Value& first, const base::Value& second) {
+ return first.Equals(&second);
+}
+
+// Helper for pretty-printing the contents of base::Value in case of failures.
+void PrintTo(const Value& value, std::ostream* stream) {
+ std::string json;
+ JSONWriter::Write(&value, &json);
+ *stream << json;
+}
+
+} // namespace base
+
+PreferencesBrowserTest::PreferencesBrowserTest() {
+}
+
+// Sets up a mock policy provider.
+void PreferencesBrowserTest::SetUpInProcessBrowserTestFixture() {
+ EXPECT_CALL(policy_provider_, IsInitializationComplete())
+ .WillRepeatedly(Return(true));
+ policy::BrowserPolicyConnector::SetPolicyProviderForTesting(
+ &policy_provider_);
+};
+
+// Navigates to the settings page, causing the JS preference handling classes to
+// be loaded and initialized.
+void PreferencesBrowserTest::SetUpOnMainThread() {
+ ui_test_utils::NavigateToURL(browser(),
+ GURL(chrome::kChromeUISettingsFrameURL));
+ content::WebContents* web_contents = chrome::GetActiveWebContents(browser());
+ ASSERT_TRUE(web_contents);
+ render_view_host_ = web_contents->GetRenderViewHost();
+ ASSERT_TRUE(render_view_host_);
+}
+
+// Verifies that a dictionary contains a (key, value) pair.
+void PreferencesBrowserTest::VerifyValue(const base::DictionaryValue* dict,
+ const std::string& key,
+ 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.
+ 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.
+ ASSERT_TRUE(expected);
+ const base::Value* actual;
+ 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.
+ ASSERT_EQ(*expected, *actual) << "Was checking key: " << key;
+ delete expected;
+}
+
+// Verifies that a pref value has been decorated correctly.
+void PreferencesBrowserTest::VerifyDict(const base::DictionaryValue* dict,
+ const base::Value* value,
+ const std::string& controlledBy,
+ bool disabled) {
+ ASSERT_TRUE(dict);
+ VerifyValue(dict, "value", value->DeepCopy());
+ if (!controlledBy.empty()) {
+ VerifyValue(dict, "controlledBy",
+ base::Value::CreateStringValue(controlledBy));
+ } else {
+ EXPECT_FALSE(dict->HasKey("controlledBy"));
+ }
+
+ if (disabled)
+ VerifyValue(dict, "disabled", base::Value::CreateBooleanValue(true));
+ else if (dict->HasKey("disabled"))
+ VerifyValue(dict, "disabled", base::Value::CreateBooleanValue(false));
+}
+
+// Verifies that a dictionary contains a given pref and that its value has been
+// decorated correctly.
+void PreferencesBrowserTest::VerifyPref(const base::DictionaryValue* prefs,
+ const std::string& name,
+ const base::Value* value,
+ const std::string& controlledBy,
+ bool disabled) {
+ ASSERT_TRUE(prefs);
+ ASSERT_TRUE(value);
+ const base::Value* pref;
+ const base::DictionaryValue* dict;
+ ASSERT_TRUE(prefs->Get(name, &pref));
+ ASSERT_TRUE(pref->GetAsDictionary(&dict));
+ VerifyDict(dict, value, controlledBy, disabled);
+}
+
+// Verifies that a dictionary contains a given list of prefs and that their
+// values have been decorated correctly.
+void PreferencesBrowserTest::VerifyPrefs(
+ const base::DictionaryValue* prefs,
+ const std::vector<std::string>& names,
+ const std::vector<base::Value*>& values,
+ const std::string& controlledBy,
+ bool disabled) {
+ ASSERT_TRUE(prefs);
+ ASSERT_EQ(names.size(), values.size());
+ for (size_t i = 0; i < names.size(); ++i)
+ VerifyPref(prefs, names[i], values[i], controlledBy, disabled);
+}
+
+// Sets a pref value from JavaScript, waits for an observer callback to fire and
+// returns the decorated value received.
+void PreferencesBrowserTest::VerifySetPref(const std::string& name,
+ const std::string& type,
+ base::Value* set_value,
+ base::Value* expected_value) {
+ std::string set_value_json;
+ base::JSONWriter::Write(set_value, &set_value_json);
+ std::wstringstream javascript;
+ javascript << "pref_changed_callback = function(notification) {"
+ << " if (notification[0] == '" << name.c_str() << "') {"
+ << " pref_changed_callback = function() {};"
+ << " window.domAutomationController.send("
+ << " JSON.stringify(notification[1]));"
+ << " }"
+ << "};"
+ << "chrome.send('observePrefs', ['pref_changed_callback',"
+ << " '" << name.c_str() << "']);"
+ << "Preferences.set" << type.c_str() << "Pref("
+ << " '" << name.c_str() << "',"
+ << " " << set_value_json.c_str() << ");";
+ std::string actual_json;
+ ASSERT_TRUE(content::ExecuteJavaScriptAndExtractString(
+ render_view_host_, L"", javascript.str(), &actual_json));
+
+ base::Value* actual_value = base::JSONReader::Read(actual_json);
+ const base::DictionaryValue* actual_dict;
+ ASSERT_TRUE(actual_value);
+ ASSERT_TRUE(actual_value->GetAsDictionary(&actual_dict));
+ VerifyDict(actual_dict, expected_value ? expected_value : set_value,
+ "", false);
+ delete set_value;
+ delete expected_value;
+}
+
+// Requests a list of pref values from JavaScript, waits for a callback to fire
+// and returns the decorated values received.
+void PreferencesBrowserTest::FetchPrefs(const std::vector<std::string>& names,
+ base::DictionaryValue** prefs) {
+ *prefs = NULL;
+
+ base::ListValue args_list;
+ args_list.Append(base::Value::CreateStringValue("prefs_fetched_callback"));
+ for (std::vector<std::string>::const_iterator name = names.begin();
+ name != names.end(); ++name)
+ args_list.Append(base::Value::CreateStringValue(*name));
+ std::string args_json;
+ base::JSONWriter::Write(&args_list, &args_json);
+ std::wstringstream javascript;
+ javascript << "prefs_fetched_callback = function(dict) {"
+ << " window.domAutomationController.send(JSON.stringify(dict));"
+ << "};"
+ << "chrome.send('fetchPrefs', " << args_json.c_str() << ");";
+
+ std::string fetched_json;
+ ASSERT_TRUE(content::ExecuteJavaScriptAndExtractString(
+ render_view_host_, L"", javascript.str(), &fetched_json));
+ base::Value* fetched_value = base::JSONReader::Read(fetched_json);
+ base::DictionaryValue* fetched_dict;
+ ASSERT_TRUE(fetched_value);
+ ASSERT_TRUE(fetched_value->GetAsDictionary(&fetched_dict));
+ *prefs = fetched_dict;
+}
+
+// Sets user policies through the mock policy provider.
+void PreferencesBrowserTest::SetUserPolicies(
+ const std::vector<std::string>& names,
+ const std::vector<base::Value*>& values,
+ policy::PolicyLevel level) {
+ ASSERT_TRUE(names.size() == values.size());
+ policy::PolicyMap map;
+ for (size_t i = 0; i < names.size(); ++i)
+ map.Set(names[i], level, policy::POLICY_SCOPE_USER, values[i]->DeepCopy());
+ policy_provider_.UpdateChromePolicy(map);
+}
+
+// Helper deleting a vector of values.
+void PreferencesBrowserTest::DeleteValues(std::vector<base::Value*>& values){
+ for (std::vector<base::Value*>::iterator value = values.begin();
+ value != values.end(); ++value)
+ delete *value;
+ values.clear();
+}
+
+// Tests verifying that the JavaScript Preferences class, the underlying C++
+// CoreOptionsHandler and the specialized classes handling Chrome OS device and
+// proxy prefs behave correctly.
+
+// Verifies that pref values received by observer callbacks are decorated
+// correctly when the prefs are set from JavaScript.
+IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, SetPrefs) {
+ // Prefs handled by CoreOptionsHandler.
+ VerifySetPref(prefs::kAlternateErrorPagesEnabled, "Boolean",
+ base::Value::CreateBooleanValue(false), NULL);
+ VerifySetPref(prefs::kRestoreOnStartup, "Integer",
+ base::Value::CreateIntegerValue(4), NULL);
+ VerifySetPref(prefs::kEnterpriseWebStoreName, "String",
+ base::Value::CreateStringValue("Store"), NULL);
+ VerifySetPref(prefs::kEnterpriseWebStoreURL, "URL",
+ base::Value::CreateStringValue("http://www.google.com"),
+ base::Value::CreateStringValue("http://www.google.com/"));
+}
+
+// Verifies that pref values are decorated correctly when fetched from
+// JavaScript.
+IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, FetchPrefs) {
+ // Pref names.
+ std::vector<std::string> pref_names;
+ // Boolean pref.
+ pref_names.push_back(prefs::kAlternateErrorPagesEnabled);
+ // Integer pref.
+ pref_names.push_back(prefs::kRestoreOnStartup);
+ // String pref.
+ pref_names.push_back(prefs::kEnterpriseWebStoreName);
+ // URL pref.
+ pref_names.push_back(prefs::kEnterpriseWebStoreURL);
+ // List pref.
+ pref_names.push_back(prefs::kURLsToRestoreOnStartup);
+
+ // Corresponding policy names.
+ std::vector<std::string> policy_names;
+ policy_names.push_back(policy::key::kAlternateErrorPagesEnabled);
+ policy_names.push_back(policy::key::kRestoreOnStartup);
+ policy_names.push_back(policy::key::kEnterpriseWebStoreName);
+ policy_names.push_back(policy::key::kEnterpriseWebStoreURL);
+ policy_names.push_back(policy::key::kRestoreOnStartupURLs);
+
+ // Default values.
+ std::vector<base::Value*> values;
+ values.push_back(base::Value::CreateBooleanValue(true));
+#if defined(OS_CHROMEOS)
+ values.push_back(base::Value::CreateIntegerValue(1));
+#else
+ values.push_back(base::Value::CreateIntegerValue(5));
+#endif
+ values.push_back(base::Value::CreateStringValue(""));
+ values.push_back(base::Value::CreateStringValue(""));
+ values.push_back(new base::ListValue);
+
+ // Verify default values are fetched and decorated correctly.
+ base::DictionaryValue* fetched;
+ FetchPrefs(pref_names, &fetched);
+ VerifyPrefs(fetched, pref_names, values, "", false);
+ delete fetched;
+
+ // Set recommended values.
+ DeleteValues(values);
+ values.push_back(base::Value::CreateBooleanValue(false));
+ values.push_back(base::Value::CreateIntegerValue(4));
+ values.push_back(base::Value::CreateStringValue("Store"));
+ values.push_back(base::Value::CreateStringValue("http://www.google.com"));
+ base::ListValue* list = new base::ListValue;
+ list->Append(base::Value::CreateStringValue("http://www.google.com"));
+ list->Append(base::Value::CreateStringValue("http://example.com"));
+ values.push_back(list);
+ SetUserPolicies(policy_names, values, policy::POLICY_LEVEL_RECOMMENDED);
+
+ // Verify recommended values are fetched and decorated correctly.
+ FetchPrefs(pref_names, &fetched);
+ VerifyPrefs(fetched, pref_names, values, "recommended", false);
+ delete fetched;
+
+ // Set mandatory values.
+ SetUserPolicies(policy_names, values, policy::POLICY_LEVEL_MANDATORY);
+
+ // Verify mandatory values are fetched and decorated correctly.
+ FetchPrefs(pref_names, &fetched);
+ VerifyPrefs(fetched, pref_names, values, "policy", true);
+ delete fetched;
+
+ DeleteValues(values);
+}
+
+#if defined(OS_CHROMEOS)
+// Verifies that pref values handled by the CoreChromeOSOptionsHandler class
+// are decorated correctly when requested from JavaScript.
+IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, ChromeOSDeviceFetchPrefs) {
+ // Pref names.
+ std::vector<std::string> names;
+ // Boolean pref.
+ names.push_back(chromeos::kAccountsPrefAllowGuest);
+ // String pref.
+ names.push_back(chromeos::kReleaseChannel);
+ // List pref.
+ names.push_back(chromeos::kAccountsPrefUsers);
+
+ // Default pref values.
+ std::vector<base::Value*> values;
+ values.push_back(base::Value::CreateBooleanValue(true));
+ values.push_back(base::Value::CreateStringValue(""));
+ values.push_back(new base::ListValue);
+
+ // Verify default values are fetched and decorated correctly.
+ base::DictionaryValue* fetched;
+ FetchPrefs(names, &fetched);
+ VerifyPrefs(fetched, names, values, "", true);
+ delete fetched;
+
+ // Set mandatory values.
+ DeleteValues(values);
+ values.push_back(base::Value::CreateBooleanValue(false));
+ values.push_back(base::Value::CreateStringValue("stable-channel"));
+ base::ListValue* list = new base::ListValue;
+ list->Append(base::Value::CreateStringValue("me@google.com"));
+ list->Append(base::Value::CreateStringValue("you@google.com"));
+ values.push_back(list);
+ ASSERT_EQ(names.size(), values.size());
+ chromeos::CrosSettings* cros_settings = chromeos::CrosSettings::Get();
+ for (size_t i = 0; i < names.size(); ++i)
+ cros_settings->Set(names[i], *values[i]);
+
+ // Verify mandatory values are fetched and decorated correctly.
+ DeleteValues(values);
+ values.push_back(base::Value::CreateBooleanValue(false));
+ values.push_back(base::Value::CreateStringValue("stable-channel"));
+ list = new base::ListValue;
+ base::DictionaryValue* dict = new base::DictionaryValue;
+ dict->SetString("username", "me@google.com");
+ dict->SetString("name", "me@google.com");
+ dict->SetString("email", "");
+ dict->SetBoolean("owner", false);
+ list->Append(dict);
+ dict = new base::DictionaryValue;
+ dict->SetString("username", "you@google.com");
+ dict->SetString("name", "you@google.com");
+ dict->SetString("email", "");
+ dict->SetBoolean("owner", false);
+ list->Append(dict);
+ values.push_back(list);
+ FetchPrefs(names, &fetched);
+ // FIXME(bartfab): Find a way to simulate enterprise enrollment in browser
+ // tests. Only if Chrome thinks that it is enrolled will the device prefs be
+ // decorated with "controlledBy: policy".
+ VerifyPrefs(fetched, names, values, "", true);
+ delete fetched;
+
+ DeleteValues(values);
+}
+
+// Verifies that pref values handled by the Chrome OS proxy settings parser are
+// decorated correctly when requested from JavaScript.
+IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, ChromeOSProxyFetchPrefs) {
+ // Pref names.
+ std::vector<std::string> names;
+ // Boolean pref.
+ names.push_back(chromeos::kProxySingle);
+ // Integer pref.
+ names.push_back(chromeos::kProxySingleHttpPort);
+ // String pref.
+ names.push_back(chromeos::kProxySingleHttp);
+ // List pref.
+ names.push_back(chromeos::kProxyIgnoreList);
+
+ // Default values.
+ std::vector<base::Value*> values;
+ values.push_back(base::Value::CreateBooleanValue(false));
+ values.push_back(base::Value::CreateStringValue(""));
+ values.push_back(base::Value::CreateStringValue(""));
+ values.push_back(new base::ListValue());
+
+ // Verify default values are fetched and decorated correctly.
+ base::DictionaryValue* fetched;
+ FetchPrefs(names, &fetched);
+ VerifyPrefs(fetched, names, values, "", false);
+ delete fetched;
+
+ // Set user-modified values.
+ DeleteValues(values);
+ values.push_back(base::Value::CreateBooleanValue(true));
+ values.push_back(base::Value::CreateIntegerValue(8080));
+ values.push_back(base::Value::CreateStringValue("127.0.0.1"));
+ base::ListValue* list = new base::ListValue();
+ list->Append(base::Value::CreateStringValue("www.google.com"));
+ list->Append(base::Value::CreateStringValue("example.com"));
+ values.push_back(list);
+ ASSERT_EQ(names.size(), values.size());
+ Profile* profile = browser()->profile();
+ // Do not set the Boolean pref. It will toogle automatically.
+ for (size_t i = 1; i < names.size(); ++i)
+ chromeos::proxy_cros_settings_parser::SetProxyPrefValue(
+ profile, names[i], values[i]->DeepCopy());
+
+ // Verify user-modified values are fetched and decorated correctly.
+ FetchPrefs(names, &fetched);
+ VerifyPrefs(fetched, names, values, "", false);
+ delete fetched;
+
+ DeleteValues(values);
+}
+#endif

Powered by Google App Engine
This is Rietveld 408576698