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 user 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 void PreferencesBrowserTest::VerifyValue(const base::DictionaryValue* dict, | |
77 const std::string& key, | |
78 base::Value* expected) { | |
79 const base::Value* actual = NULL; | |
80 EXPECT_TRUE(dict->Get(key, &actual)) << "Was checking key: " << key; | |
81 EXPECT_EQ(*expected, *actual) << "Was checking key: " << key; | |
82 delete expected; | |
83 } | |
84 | |
85 void PreferencesBrowserTest::VerifyDict(const base::DictionaryValue* dict, | |
86 const base::Value* value, | |
87 const std::string& controlledBy, | |
88 bool disabled) { | |
89 VerifyValue(dict, "value", value->DeepCopy()); | |
90 if (!controlledBy.empty()) { | |
91 VerifyValue(dict, "controlledBy", | |
92 base::Value::CreateStringValue(controlledBy)); | |
93 } else { | |
94 EXPECT_FALSE(dict->HasKey("controlledBy")); | |
95 } | |
96 | |
97 if (disabled) | |
98 VerifyValue(dict, "disabled", base::Value::CreateBooleanValue(true)); | |
99 else if (dict->HasKey("disabled")) | |
100 VerifyValue(dict, "disabled", base::Value::CreateBooleanValue(false)); | |
101 } | |
102 | |
103 void PreferencesBrowserTest::VerifyPref(const base::DictionaryValue* prefs, | |
104 const std::string& name, | |
105 const base::Value* value, | |
106 const std::string& controlledBy, | |
107 bool disabled) { | |
108 const base::Value* pref; | |
109 const base::DictionaryValue* dict; | |
110 ASSERT_TRUE(prefs->Get(name, &pref)); | |
111 ASSERT_TRUE(pref->GetAsDictionary(&dict)); | |
112 VerifyDict(dict, value, controlledBy, disabled); | |
113 } | |
114 | |
115 void PreferencesBrowserTest::VerifyPrefs( | |
116 const base::DictionaryValue* prefs, | |
117 const std::vector<std::string>& names, | |
118 const std::vector<base::Value*>& values, | |
119 const std::string& controlledBy, | |
120 bool disabled) { | |
121 ASSERT_TRUE(prefs); | |
James Hawkins
2012/08/07 18:29:50
nit: Don't assert here.
bartfab (slow)
2012/08/07 18:35:56
There is a reason for this assert: VerifyPrefs() i
James Hawkins
2012/08/07 18:37:38
I'm not going to nit it to death, but yes, I would
bartfab (slow)
2012/08/07 18:41:21
No problem, I replaced the ASSERT in the method wi
| |
122 ASSERT_EQ(names.size(), values.size()); | |
123 for (size_t i = 0; i < names.size(); ++i) | |
124 VerifyPref(prefs, names[i], values[i], controlledBy, disabled); | |
125 } | |
126 | |
127 void PreferencesBrowserTest::VerifySetPref(const std::string& name, | |
128 const std::string& type, | |
129 base::Value* set_value, | |
130 base::Value* expected_value) { | |
131 std::string set_value_json; | |
132 base::JSONWriter::Write(set_value, &set_value_json); | |
133 std::wstringstream javascript; | |
134 javascript << "pref_changed_callback = function(notification) {" | |
135 << " if (notification[0] == '" << name.c_str() << "') {" | |
136 << " pref_changed_callback = function() {};" | |
137 << " window.domAutomationController.send(" | |
138 << " JSON.stringify(notification[1]));" | |
139 << " }" | |
140 << "};" | |
141 << "chrome.send('observePrefs', ['pref_changed_callback'," | |
142 << " '" << name.c_str() << "']);" | |
143 << "Preferences.set" << type.c_str() << "Pref(" | |
144 << " '" << name.c_str() << "'," | |
145 << " " << set_value_json.c_str() << ");"; | |
146 std::string actual_json; | |
147 ASSERT_TRUE(content::ExecuteJavaScriptAndExtractString( | |
148 render_view_host_, L"", javascript.str(), &actual_json)); | |
149 | |
150 base::Value* actual_value = base::JSONReader::Read(actual_json); | |
151 const base::DictionaryValue* actual_dict; | |
152 ASSERT_TRUE(actual_value); | |
153 ASSERT_TRUE(actual_value->GetAsDictionary(&actual_dict)); | |
154 VerifyDict(actual_dict, expected_value ? expected_value : set_value, | |
155 "", false); | |
156 delete set_value; | |
James Hawkins
2012/08/07 18:29:50
nit: Use a scoped_ptr parameter instead of manuall
bartfab (slow)
2012/08/07 18:35:56
Done.
| |
157 delete expected_value; | |
158 } | |
159 | |
160 void PreferencesBrowserTest::FetchPrefs(const std::vector<std::string>& names, | |
161 base::DictionaryValue** prefs) { | |
162 *prefs = NULL; | |
163 | |
164 base::ListValue args_list; | |
165 args_list.Append(base::Value::CreateStringValue("prefs_fetched_callback")); | |
166 for (std::vector<std::string>::const_iterator name = names.begin(); | |
167 name != names.end(); ++name) | |
168 args_list.Append(base::Value::CreateStringValue(*name)); | |
169 std::string args_json; | |
170 base::JSONWriter::Write(&args_list, &args_json); | |
171 std::wstringstream javascript; | |
172 javascript << "prefs_fetched_callback = function(dict) {" | |
173 << " window.domAutomationController.send(JSON.stringify(dict));" | |
174 << "};" | |
175 << "chrome.send('fetchPrefs', " << args_json.c_str() << ");"; | |
176 | |
177 std::string fetched_json; | |
178 ASSERT_TRUE(content::ExecuteJavaScriptAndExtractString( | |
179 render_view_host_, L"", javascript.str(), &fetched_json)); | |
180 base::Value* fetched_value = base::JSONReader::Read(fetched_json); | |
181 base::DictionaryValue* fetched_dict; | |
182 ASSERT_TRUE(fetched_value); | |
183 ASSERT_TRUE(fetched_value->GetAsDictionary(&fetched_dict)); | |
184 *prefs = fetched_dict; | |
185 } | |
186 | |
187 void PreferencesBrowserTest::SetUserPolicies( | |
188 const std::vector<std::string>& names, | |
189 const std::vector<base::Value*>& values, | |
190 policy::PolicyLevel level) { | |
191 ASSERT_TRUE(names.size() == values.size()); | |
192 policy::PolicyMap map; | |
193 for (size_t i = 0; i < names.size(); ++i) | |
194 map.Set(names[i], level, policy::POLICY_SCOPE_USER, values[i]->DeepCopy()); | |
195 policy_provider_.UpdateChromePolicy(map); | |
196 } | |
197 | |
198 void PreferencesBrowserTest::DeleteValues(std::vector<base::Value*>& values){ | |
199 for (std::vector<base::Value*>::iterator value = values.begin(); | |
200 value != values.end(); ++value) | |
201 delete *value; | |
202 values.clear(); | |
203 } | |
204 | |
205 // Verifies that pref values received by observer callbacks are decorated | |
206 // correctly when the prefs are set from JavaScript. | |
207 IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, SetPrefs) { | |
208 // Prefs handled by CoreOptionsHandler. | |
209 VerifySetPref(prefs::kAlternateErrorPagesEnabled, "Boolean", | |
210 base::Value::CreateBooleanValue(false), NULL); | |
211 VerifySetPref(prefs::kRestoreOnStartup, "Integer", | |
212 base::Value::CreateIntegerValue(4), NULL); | |
213 VerifySetPref(prefs::kEnterpriseWebStoreName, "String", | |
214 base::Value::CreateStringValue("Store"), NULL); | |
215 VerifySetPref(prefs::kEnterpriseWebStoreURL, "URL", | |
216 base::Value::CreateStringValue("http://www.google.com"), | |
217 base::Value::CreateStringValue("http://www.google.com/")); | |
218 } | |
219 | |
220 // Verifies that pref values are decorated correctly when fetched from | |
221 // JavaScript. | |
222 IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, FetchPrefs) { | |
223 // Pref names. | |
224 std::vector<std::string> pref_names; | |
225 // Boolean pref. | |
226 pref_names.push_back(prefs::kAlternateErrorPagesEnabled); | |
227 // Integer pref. | |
228 pref_names.push_back(prefs::kRestoreOnStartup); | |
229 // String pref. | |
230 pref_names.push_back(prefs::kEnterpriseWebStoreName); | |
231 // URL pref. | |
232 pref_names.push_back(prefs::kEnterpriseWebStoreURL); | |
233 // List pref. | |
234 pref_names.push_back(prefs::kURLsToRestoreOnStartup); | |
235 | |
236 // Corresponding policy names. | |
237 std::vector<std::string> policy_names; | |
238 policy_names.push_back(policy::key::kAlternateErrorPagesEnabled); | |
239 policy_names.push_back(policy::key::kRestoreOnStartup); | |
240 policy_names.push_back(policy::key::kEnterpriseWebStoreName); | |
241 policy_names.push_back(policy::key::kEnterpriseWebStoreURL); | |
242 policy_names.push_back(policy::key::kRestoreOnStartupURLs); | |
243 | |
244 // Default values. | |
245 std::vector<base::Value*> values; | |
246 values.push_back(base::Value::CreateBooleanValue(true)); | |
247 #if defined(OS_CHROMEOS) | |
248 values.push_back(base::Value::CreateIntegerValue(1)); | |
249 #else | |
250 values.push_back(base::Value::CreateIntegerValue(5)); | |
251 #endif | |
252 values.push_back(base::Value::CreateStringValue("")); | |
253 values.push_back(base::Value::CreateStringValue("")); | |
254 values.push_back(new base::ListValue); | |
255 | |
256 // Verify default values are fetched and decorated correctly. | |
257 base::DictionaryValue* fetched; | |
258 FetchPrefs(pref_names, &fetched); | |
259 VerifyPrefs(fetched, pref_names, values, "", false); | |
260 delete fetched; | |
261 | |
262 // Set recommended values. | |
263 DeleteValues(values); | |
264 values.push_back(base::Value::CreateBooleanValue(false)); | |
265 values.push_back(base::Value::CreateIntegerValue(4)); | |
266 values.push_back(base::Value::CreateStringValue("Store")); | |
267 values.push_back(base::Value::CreateStringValue("http://www.google.com")); | |
268 base::ListValue* list = new base::ListValue; | |
269 list->Append(base::Value::CreateStringValue("http://www.google.com")); | |
270 list->Append(base::Value::CreateStringValue("http://example.com")); | |
271 values.push_back(list); | |
272 SetUserPolicies(policy_names, values, policy::POLICY_LEVEL_RECOMMENDED); | |
273 | |
274 // Verify recommended values are fetched and decorated correctly. | |
275 FetchPrefs(pref_names, &fetched); | |
276 VerifyPrefs(fetched, pref_names, values, "recommended", false); | |
277 delete fetched; | |
278 | |
279 // Set mandatory values. | |
280 SetUserPolicies(policy_names, values, policy::POLICY_LEVEL_MANDATORY); | |
281 | |
282 // Verify mandatory values are fetched and decorated correctly. | |
283 FetchPrefs(pref_names, &fetched); | |
284 VerifyPrefs(fetched, pref_names, values, "policy", true); | |
285 delete fetched; | |
286 | |
287 DeleteValues(values); | |
288 } | |
289 | |
290 #if defined(OS_CHROMEOS) | |
291 // Verifies that pref values handled by the CoreChromeOSOptionsHandler class | |
292 // are decorated correctly when requested from JavaScript. | |
293 IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, ChromeOSDeviceFetchPrefs) { | |
294 // Pref names. | |
295 std::vector<std::string> names; | |
296 // Boolean pref. | |
297 names.push_back(chromeos::kAccountsPrefAllowGuest); | |
298 // String pref. | |
299 names.push_back(chromeos::kReleaseChannel); | |
300 // List pref. | |
301 names.push_back(chromeos::kAccountsPrefUsers); | |
302 | |
303 // Default pref values. | |
304 std::vector<base::Value*> values; | |
305 values.push_back(base::Value::CreateBooleanValue(true)); | |
306 values.push_back(base::Value::CreateStringValue("")); | |
307 values.push_back(new base::ListValue); | |
308 | |
309 // Verify default values are fetched and decorated correctly. | |
310 base::DictionaryValue* fetched; | |
311 FetchPrefs(names, &fetched); | |
312 VerifyPrefs(fetched, names, values, "", true); | |
313 delete fetched; | |
314 | |
315 // Set mandatory values. | |
316 DeleteValues(values); | |
317 values.push_back(base::Value::CreateBooleanValue(false)); | |
318 values.push_back(base::Value::CreateStringValue("stable-channel")); | |
319 base::ListValue* list = new base::ListValue; | |
320 list->Append(base::Value::CreateStringValue("me@google.com")); | |
321 list->Append(base::Value::CreateStringValue("you@google.com")); | |
322 values.push_back(list); | |
323 ASSERT_EQ(names.size(), values.size()); | |
324 chromeos::CrosSettings* cros_settings = chromeos::CrosSettings::Get(); | |
325 for (size_t i = 0; i < names.size(); ++i) | |
326 cros_settings->Set(names[i], *values[i]); | |
327 | |
328 // Verify mandatory values are fetched and decorated correctly. | |
329 DeleteValues(values); | |
330 values.push_back(base::Value::CreateBooleanValue(false)); | |
331 values.push_back(base::Value::CreateStringValue("stable-channel")); | |
332 list = new base::ListValue; | |
333 base::DictionaryValue* dict = new base::DictionaryValue; | |
334 dict->SetString("username", "me@google.com"); | |
335 dict->SetString("name", "me@google.com"); | |
336 dict->SetString("email", ""); | |
337 dict->SetBoolean("owner", false); | |
338 list->Append(dict); | |
339 dict = new base::DictionaryValue; | |
340 dict->SetString("username", "you@google.com"); | |
341 dict->SetString("name", "you@google.com"); | |
342 dict->SetString("email", ""); | |
343 dict->SetBoolean("owner", false); | |
344 list->Append(dict); | |
345 values.push_back(list); | |
346 FetchPrefs(names, &fetched); | |
347 // FIXME(bartfab): Find a way to simulate enterprise enrollment in browser | |
348 // tests. Only if Chrome thinks that it is enrolled will the device prefs be | |
349 // decorated with "controlledBy: policy". | |
350 VerifyPrefs(fetched, names, values, "", true); | |
351 delete fetched; | |
352 | |
353 DeleteValues(values); | |
354 } | |
355 | |
356 // Verifies that pref values handled by the Chrome OS proxy settings parser are | |
357 // decorated correctly when requested from JavaScript. | |
358 IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, ChromeOSProxyFetchPrefs) { | |
359 // Pref names. | |
360 std::vector<std::string> names; | |
361 // Boolean pref. | |
362 names.push_back(chromeos::kProxySingle); | |
363 // Integer pref. | |
364 names.push_back(chromeos::kProxySingleHttpPort); | |
365 // String pref. | |
366 names.push_back(chromeos::kProxySingleHttp); | |
367 // List pref. | |
368 names.push_back(chromeos::kProxyIgnoreList); | |
369 | |
370 // Default values. | |
371 std::vector<base::Value*> values; | |
372 values.push_back(base::Value::CreateBooleanValue(false)); | |
373 values.push_back(base::Value::CreateStringValue("")); | |
374 values.push_back(base::Value::CreateStringValue("")); | |
375 values.push_back(new base::ListValue()); | |
376 | |
377 // Verify default values are fetched and decorated correctly. | |
378 base::DictionaryValue* fetched; | |
379 FetchPrefs(names, &fetched); | |
380 VerifyPrefs(fetched, names, values, "", false); | |
381 delete fetched; | |
382 | |
383 // Set user-modified values. | |
384 DeleteValues(values); | |
385 values.push_back(base::Value::CreateBooleanValue(true)); | |
386 values.push_back(base::Value::CreateIntegerValue(8080)); | |
387 values.push_back(base::Value::CreateStringValue("127.0.0.1")); | |
388 base::ListValue* list = new base::ListValue(); | |
389 list->Append(base::Value::CreateStringValue("www.google.com")); | |
390 list->Append(base::Value::CreateStringValue("example.com")); | |
391 values.push_back(list); | |
392 ASSERT_EQ(names.size(), values.size()); | |
393 Profile* profile = browser()->profile(); | |
394 // Do not set the Boolean pref. It will toogle automatically. | |
395 for (size_t i = 1; i < names.size(); ++i) | |
396 chromeos::proxy_cros_settings_parser::SetProxyPrefValue( | |
397 profile, names[i], values[i]->DeepCopy()); | |
398 | |
399 // Verify user-modified values are fetched and decorated correctly. | |
400 FetchPrefs(names, &fetched); | |
401 VerifyPrefs(fetched, names, values, "", false); | |
402 delete fetched; | |
403 | |
404 DeleteValues(values); | |
405 } | |
406 #endif | |
OLD | NEW |