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.
7 #include "base/command_line.h"
8 #include "base/file_util.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/path_service.h"
11 #include "base/prefs/json_pref_store.h"
12 #include "base/prefs/public/pref_change_registrar.h"
13 #include "base/prefs/testing_pref_store.h"
14 #include "base/scoped_temp_dir.h"
15 #include "base/utf_string_conversions.h"
16 #include "base/values.h"
17 #include "chrome/browser/policy/configuration_policy_pref_store.h"
18 #include "chrome/browser/policy/mock_configuration_policy_provider.h"
19 #include "chrome/browser/prefs/browser_prefs.h"
20 #include "chrome/browser/prefs/command_line_pref_store.h"
21 #include "chrome/browser/prefs/pref_observer_mock.h"
22 #include "chrome/browser/prefs/pref_service_mock_builder.h"
23 #include "chrome/browser/prefs/pref_value_store.h"
24 #include "chrome/browser/prefs/scoped_user_pref_update.h"
25 #include "chrome/common/chrome_paths.h"
26 #include "chrome/common/chrome_switches.h"
27 #include "chrome/common/pref_names.h"
28 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
29 #include "chrome/test/base/testing_pref_service.h"
30 #include "chrome/test/base/testing_profile.h"
31 #include "content/public/test/test_browser_thread.h"
32 #include "content/public/test/web_contents_tester.h"
33 #include "testing/gmock/include/gmock/gmock.h"
34 #include "testing/gtest/include/gtest/gtest.h"
35 #include "ui/base/test/data/resource.h"
36 #include "webkit/glue/webpreferences.h"
38 using content::BrowserThread
;
39 using content::WebContentsTester
;
43 TEST(PrefServiceTest
, NoObserverFire
) {
44 TestingPrefService prefs
;
46 const char pref_name
[] = "homepage";
47 prefs
.RegisterStringPref(pref_name
, std::string());
49 const char new_pref_value
[] = "http://www.google.com/";
51 PrefChangeRegistrar registrar
;
52 registrar
.Init(&prefs
);
53 registrar
.Add(pref_name
, &obs
);
55 // This should fire the checks in PrefObserverMock::Observe.
56 const StringValue
expected_value(new_pref_value
);
57 obs
.Expect(&prefs
, pref_name
, &expected_value
);
58 prefs
.SetString(pref_name
, new_pref_value
);
59 Mock::VerifyAndClearExpectations(&obs
);
61 // Setting the pref to the same value should not set the pref value a second
63 EXPECT_CALL(obs
, OnPreferenceChanged(_
, _
)).Times(0);
64 prefs
.SetString(pref_name
, new_pref_value
);
65 Mock::VerifyAndClearExpectations(&obs
);
67 // Clearing the pref should cause the pref to fire.
68 const StringValue
expected_default_value("");
69 obs
.Expect(&prefs
, pref_name
, &expected_default_value
);
70 prefs
.ClearPref(pref_name
);
71 Mock::VerifyAndClearExpectations(&obs
);
73 // Clearing the pref again should not cause the pref to fire.
74 EXPECT_CALL(obs
, OnPreferenceChanged(_
, _
)).Times(0);
75 prefs
.ClearPref(pref_name
);
76 Mock::VerifyAndClearExpectations(&obs
);
79 TEST(PrefServiceTest
, HasPrefPath
) {
80 TestingPrefService prefs
;
82 const char path
[] = "fake.path";
84 // Shouldn't initially have a path.
85 EXPECT_FALSE(prefs
.HasPrefPath(path
));
87 // Register the path. This doesn't set a value, so the path still shouldn't
89 prefs
.RegisterStringPref(path
, std::string());
90 EXPECT_FALSE(prefs
.HasPrefPath(path
));
92 // Set a value and make sure we have a path.
93 prefs
.SetString(path
, "blah");
94 EXPECT_TRUE(prefs
.HasPrefPath(path
));
97 TEST(PrefServiceTest
, Observers
) {
98 const char pref_name
[] = "homepage";
100 TestingPrefService prefs
;
101 prefs
.SetUserPref(pref_name
, Value::CreateStringValue("http://www.cnn.com"));
102 prefs
.RegisterStringPref(pref_name
, std::string());
104 const char new_pref_value
[] = "http://www.google.com/";
105 const StringValue
expected_new_pref_value(new_pref_value
);
106 PrefObserverMock obs
;
107 PrefChangeRegistrar registrar
;
108 registrar
.Init(&prefs
);
109 registrar
.Add(pref_name
, &obs
);
111 PrefChangeRegistrar registrar_two
;
112 registrar_two
.Init(&prefs
);
114 // This should fire the checks in PrefObserverMock::Observe.
115 obs
.Expect(&prefs
, pref_name
, &expected_new_pref_value
);
116 prefs
.SetString(pref_name
, new_pref_value
);
117 Mock::VerifyAndClearExpectations(&obs
);
119 // Now try adding a second pref observer.
120 const char new_pref_value2
[] = "http://www.youtube.com/";
121 const StringValue
expected_new_pref_value2(new_pref_value2
);
122 PrefObserverMock obs2
;
123 obs
.Expect(&prefs
, pref_name
, &expected_new_pref_value2
);
124 obs2
.Expect(&prefs
, pref_name
, &expected_new_pref_value2
);
125 registrar_two
.Add(pref_name
, &obs2
);
126 // This should fire the checks in obs and obs2.
127 prefs
.SetString(pref_name
, new_pref_value2
);
128 Mock::VerifyAndClearExpectations(&obs
);
129 Mock::VerifyAndClearExpectations(&obs2
);
131 // Set a recommended value.
132 const StringValue
recommended_pref_value("http://www.gmail.com/");
133 obs
.Expect(&prefs
, pref_name
, &expected_new_pref_value2
);
134 obs2
.Expect(&prefs
, pref_name
, &expected_new_pref_value2
);
135 // This should fire the checks in obs and obs2 but with an unchanged value
136 // as the recommended value is being overridden by the user-set value.
137 prefs
.SetRecommendedPref(pref_name
, recommended_pref_value
.DeepCopy());
138 Mock::VerifyAndClearExpectations(&obs
);
139 Mock::VerifyAndClearExpectations(&obs2
);
141 // Make sure obs2 still works after removing obs.
142 registrar
.Remove(pref_name
);
143 EXPECT_CALL(obs
, OnPreferenceChanged(_
, _
)).Times(0);
144 obs2
.Expect(&prefs
, pref_name
, &expected_new_pref_value
);
145 // This should only fire the observer in obs2.
146 prefs
.SetString(pref_name
, new_pref_value
);
147 Mock::VerifyAndClearExpectations(&obs
);
148 Mock::VerifyAndClearExpectations(&obs2
);
151 // Make sure that if a preference changes type, so the wrong type is stored in
152 // the user pref file, it uses the correct fallback value instead.
153 TEST(PrefServiceTest
, GetValueChangedType
) {
154 const int kTestValue
= 10;
155 TestingPrefService prefs
;
156 prefs
.RegisterIntegerPref(prefs::kStabilityLaunchCount
, kTestValue
);
158 // Check falling back to a recommended value.
159 prefs
.SetUserPref(prefs::kStabilityLaunchCount
,
160 Value::CreateStringValue("not an integer"));
161 const PrefService::Preference
* pref
=
162 prefs
.FindPreference(prefs::kStabilityLaunchCount
);
164 const Value
* value
= pref
->GetValue();
166 EXPECT_EQ(Value::TYPE_INTEGER
, value
->GetType());
167 int actual_int_value
= -1;
168 EXPECT_TRUE(value
->GetAsInteger(&actual_int_value
));
169 EXPECT_EQ(kTestValue
, actual_int_value
);
172 TEST(PrefServiceTest
, UpdateCommandLinePrefStore
) {
173 TestingPrefService prefs
;
174 prefs
.RegisterBooleanPref(prefs::kCloudPrintProxyEnabled
, false);
176 // Check to make sure the value is as expected.
177 const PrefService::Preference
* pref
=
178 prefs
.FindPreference(prefs::kCloudPrintProxyEnabled
);
180 const Value
* value
= pref
->GetValue();
182 EXPECT_EQ(Value::TYPE_BOOLEAN
, value
->GetType());
183 bool actual_bool_value
= true;
184 EXPECT_TRUE(value
->GetAsBoolean(&actual_bool_value
));
185 EXPECT_FALSE(actual_bool_value
);
187 // Change the command line.
188 CommandLine
cmd_line(CommandLine::NO_PROGRAM
);
189 cmd_line
.AppendSwitch(switches::kEnableCloudPrintProxy
);
191 // Call UpdateCommandLinePrefStore and check to see if the value has changed.
192 prefs
.UpdateCommandLinePrefStore(&cmd_line
);
193 pref
= prefs
.FindPreference(prefs::kCloudPrintProxyEnabled
);
195 value
= pref
->GetValue();
197 EXPECT_EQ(Value::TYPE_BOOLEAN
, value
->GetType());
198 actual_bool_value
= false;
199 EXPECT_TRUE(value
->GetAsBoolean(&actual_bool_value
));
200 EXPECT_TRUE(actual_bool_value
);
203 TEST(PrefServiceTest
, GetValueAndGetRecommendedValue
) {
204 const int kDefaultValue
= 5;
205 const int kUserValue
= 10;
206 const int kRecommendedValue
= 15;
207 TestingPrefService prefs
;
208 prefs
.RegisterIntegerPref(prefs::kStabilityLaunchCount
, kDefaultValue
);
210 // Create pref with a default value only.
211 const PrefService::Preference
* pref
=
212 prefs
.FindPreference(prefs::kStabilityLaunchCount
);
215 // Check that GetValue() returns the default value.
216 const Value
* value
= pref
->GetValue();
218 EXPECT_EQ(Value::TYPE_INTEGER
, value
->GetType());
219 int actual_int_value
= -1;
220 EXPECT_TRUE(value
->GetAsInteger(&actual_int_value
));
221 EXPECT_EQ(kDefaultValue
, actual_int_value
);
223 // Check that GetRecommendedValue() returns no value.
224 value
= pref
->GetRecommendedValue();
227 // Set a user-set value.
228 prefs
.SetUserPref(prefs::kStabilityLaunchCount
,
229 Value::CreateIntegerValue(kUserValue
));
231 // Check that GetValue() returns the user-set value.
232 value
= pref
->GetValue();
234 EXPECT_EQ(Value::TYPE_INTEGER
, value
->GetType());
235 actual_int_value
= -1;
236 EXPECT_TRUE(value
->GetAsInteger(&actual_int_value
));
237 EXPECT_EQ(kUserValue
, actual_int_value
);
239 // Check that GetRecommendedValue() returns no value.
240 value
= pref
->GetRecommendedValue();
243 // Set a recommended value.
244 prefs
.SetRecommendedPref(prefs::kStabilityLaunchCount
,
245 Value::CreateIntegerValue(kRecommendedValue
));
247 // Check that GetValue() returns the user-set value.
248 value
= pref
->GetValue();
250 EXPECT_EQ(Value::TYPE_INTEGER
, value
->GetType());
251 actual_int_value
= -1;
252 EXPECT_TRUE(value
->GetAsInteger(&actual_int_value
));
253 EXPECT_EQ(kUserValue
, actual_int_value
);
255 // Check that GetRecommendedValue() returns the recommended value.
256 value
= pref
->GetRecommendedValue();
258 EXPECT_EQ(Value::TYPE_INTEGER
, value
->GetType());
259 actual_int_value
= -1;
260 EXPECT_TRUE(value
->GetAsInteger(&actual_int_value
));
261 EXPECT_EQ(kRecommendedValue
, actual_int_value
);
263 // Remove the user-set value.
264 prefs
.RemoveUserPref(prefs::kStabilityLaunchCount
);
266 // Check that GetValue() returns the recommended value.
267 value
= pref
->GetValue();
269 EXPECT_EQ(Value::TYPE_INTEGER
, value
->GetType());
270 actual_int_value
= -1;
271 EXPECT_TRUE(value
->GetAsInteger(&actual_int_value
));
272 EXPECT_EQ(kRecommendedValue
, actual_int_value
);
274 // Check that GetRecommendedValue() returns the recommended value.
275 value
= pref
->GetRecommendedValue();
277 EXPECT_EQ(Value::TYPE_INTEGER
, value
->GetType());
278 actual_int_value
= -1;
279 EXPECT_TRUE(value
->GetAsInteger(&actual_int_value
));
280 EXPECT_EQ(kRecommendedValue
, actual_int_value
);
283 class PrefServiceUserFilePrefsTest
: public testing::Test
{
285 virtual void SetUp() {
286 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
288 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA
, &data_dir_
));
289 data_dir_
= data_dir_
.AppendASCII("pref_service");
290 ASSERT_TRUE(file_util::PathExists(data_dir_
));
293 void ClearListValue(PrefService
* prefs
, const char* key
) {
294 ListPrefUpdate
updater(prefs
, key
);
298 void ClearDictionaryValue(PrefService
* prefs
, const char* key
) {
299 DictionaryPrefUpdate
updater(prefs
, key
);
303 // The path to temporary directory used to contain the test operations.
304 ScopedTempDir temp_dir_
;
305 // The path to the directory where the test data is stored.
307 // A message loop that we can use as the file thread message loop.
308 MessageLoop message_loop_
;
311 // Verifies that ListValue and DictionaryValue pref with non emtpy default
312 // preserves its empty value.
313 TEST_F(PrefServiceUserFilePrefsTest
, PreserveEmptyValue
) {
314 FilePath pref_file
= temp_dir_
.path().AppendASCII("write.json");
316 ASSERT_TRUE(file_util::CopyFile(
317 data_dir_
.AppendASCII("read.need_empty_value.json"),
320 PrefServiceMockBuilder builder
;
321 builder
.WithUserFilePrefs(pref_file
, message_loop_
.message_loop_proxy());
322 scoped_ptr
<PrefService
> prefs(builder
.Create());
324 // Register testing prefs.
325 prefs
->RegisterListPref("list",
326 PrefService::UNSYNCABLE_PREF
);
327 prefs
->RegisterDictionaryPref("dict",
328 PrefService::UNSYNCABLE_PREF
);
330 base::ListValue
* non_empty_list
= new base::ListValue
;
331 non_empty_list
->Append(base::Value::CreateStringValue("test"));
332 prefs
->RegisterListPref("list_needs_empty_value",
334 PrefService::UNSYNCABLE_PREF
);
336 base::DictionaryValue
* non_empty_dict
= new base::DictionaryValue
;
337 non_empty_dict
->SetString("dummy", "whatever");
338 prefs
->RegisterDictionaryPref("dict_needs_empty_value",
340 PrefService::UNSYNCABLE_PREF
);
342 // Set all testing prefs to empty.
343 ClearListValue(prefs
.get(), "list");
344 ClearListValue(prefs
.get(), "list_needs_empty_value");
345 ClearDictionaryValue(prefs
.get(), "dict");
346 ClearDictionaryValue(prefs
.get(), "dict_needs_empty_value");
349 prefs
->CommitPendingWrite();
350 message_loop_
.RunUntilIdle();
352 // Compare to expected output.
353 FilePath golden_output_file
=
354 data_dir_
.AppendASCII("write.golden.need_empty_value.json");
355 ASSERT_TRUE(file_util::PathExists(golden_output_file
));
356 EXPECT_TRUE(file_util::TextContentsEqual(golden_output_file
, pref_file
));
359 class PrefServiceSetValueTest
: public testing::Test
{
361 static const char kName
[];
362 static const char kValue
[];
364 TestingPrefService prefs_
;
365 PrefObserverMock observer_
;
368 const char PrefServiceSetValueTest::kName
[] = "name";
369 const char PrefServiceSetValueTest::kValue
[] = "value";
371 TEST_F(PrefServiceSetValueTest
, SetStringValue
) {
372 const char default_string
[] = "default";
373 const StringValue
default_value(default_string
);
374 prefs_
.RegisterStringPref(kName
, default_string
);
376 PrefChangeRegistrar registrar
;
377 registrar
.Init(&prefs_
);
378 registrar
.Add(kName
, &observer_
);
380 // Changing the controlling store from default to user triggers notification.
381 observer_
.Expect(&prefs_
, kName
, &default_value
);
382 prefs_
.Set(kName
, default_value
);
383 Mock::VerifyAndClearExpectations(&observer_
);
385 EXPECT_CALL(observer_
, OnPreferenceChanged(_
, _
)).Times(0);
386 prefs_
.Set(kName
, default_value
);
387 Mock::VerifyAndClearExpectations(&observer_
);
389 StringValue
new_value(kValue
);
390 observer_
.Expect(&prefs_
, kName
, &new_value
);
391 prefs_
.Set(kName
, new_value
);
392 Mock::VerifyAndClearExpectations(&observer_
);
395 TEST_F(PrefServiceSetValueTest
, SetDictionaryValue
) {
396 prefs_
.RegisterDictionaryPref(kName
);
397 PrefChangeRegistrar registrar
;
398 registrar
.Init(&prefs_
);
399 registrar
.Add(kName
, &observer_
);
401 EXPECT_CALL(observer_
, OnPreferenceChanged(_
, _
)).Times(0);
402 prefs_
.RemoveUserPref(kName
);
403 Mock::VerifyAndClearExpectations(&observer_
);
405 DictionaryValue new_value
;
406 new_value
.SetString(kName
, kValue
);
407 observer_
.Expect(&prefs_
, kName
, &new_value
);
408 prefs_
.Set(kName
, new_value
);
409 Mock::VerifyAndClearExpectations(&observer_
);
411 EXPECT_CALL(observer_
, OnPreferenceChanged(_
, _
)).Times(0);
412 prefs_
.Set(kName
, new_value
);
413 Mock::VerifyAndClearExpectations(&observer_
);
415 DictionaryValue empty
;
416 observer_
.Expect(&prefs_
, kName
, &empty
);
417 prefs_
.Set(kName
, empty
);
418 Mock::VerifyAndClearExpectations(&observer_
);
421 TEST_F(PrefServiceSetValueTest
, SetListValue
) {
422 prefs_
.RegisterListPref(kName
);
423 PrefChangeRegistrar registrar
;
424 registrar
.Init(&prefs_
);
425 registrar
.Add(kName
, &observer_
);
427 EXPECT_CALL(observer_
, OnPreferenceChanged(_
, _
)).Times(0);
428 prefs_
.RemoveUserPref(kName
);
429 Mock::VerifyAndClearExpectations(&observer_
);
432 new_value
.Append(Value::CreateStringValue(kValue
));
433 observer_
.Expect(&prefs_
, kName
, &new_value
);
434 prefs_
.Set(kName
, new_value
);
435 Mock::VerifyAndClearExpectations(&observer_
);
437 EXPECT_CALL(observer_
, OnPreferenceChanged(_
, _
)).Times(0);
438 prefs_
.Set(kName
, new_value
);
439 Mock::VerifyAndClearExpectations(&observer_
);
442 observer_
.Expect(&prefs_
, kName
, &empty
);
443 prefs_
.Set(kName
, empty
);
444 Mock::VerifyAndClearExpectations(&observer_
);
447 class PrefServiceWebKitPrefs
: public ChromeRenderViewHostTestHarness
{
449 PrefServiceWebKitPrefs() : ui_thread_(BrowserThread::UI
, &message_loop_
) {
452 virtual void SetUp() {
453 ChromeRenderViewHostTestHarness::SetUp();
455 // Supply our own profile so we use the correct profile data. The test
456 // harness is not supposed to overwrite a profile if it's already created.
458 // Set some (WebKit) user preferences.
459 TestingPrefService
* pref_services
= profile()->GetTestingPrefService();
460 #if defined(TOOLKIT_GTK)
461 pref_services
->SetUserPref(prefs::kUsesSystemTheme
,
462 Value::CreateBooleanValue(false));
464 pref_services
->SetUserPref(prefs::kDefaultCharset
,
465 Value::CreateStringValue("utf8"));
466 pref_services
->SetUserPref(prefs::kWebKitDefaultFontSize
,
467 Value::CreateIntegerValue(20));
468 pref_services
->SetUserPref(prefs::kWebKitTextAreasAreResizable
,
469 Value::CreateBooleanValue(false));
470 pref_services
->SetUserPref(prefs::kWebKitUsesUniversalDetector
,
471 Value::CreateBooleanValue(true));
472 pref_services
->SetUserPref("webkit.webprefs.foo",
473 Value::CreateStringValue("bar"));
477 content::TestBrowserThread ui_thread_
;
480 // Tests to see that webkit preferences are properly loaded and copied over
481 // to a WebPreferences object.
482 TEST_F(PrefServiceWebKitPrefs
, PrefsCopied
) {
483 webkit_glue::WebPreferences webkit_prefs
=
484 WebContentsTester::For(web_contents())->TestGetWebkitPrefs();
486 // These values have been overridden by the profile preferences.
487 EXPECT_EQ("UTF-8", webkit_prefs
.default_encoding
);
488 EXPECT_EQ(20, webkit_prefs
.default_font_size
);
489 EXPECT_FALSE(webkit_prefs
.text_areas_are_resizable
);
490 EXPECT_TRUE(webkit_prefs
.uses_universal_detector
);
492 // These should still be the default values.
493 #if defined(OS_MACOSX)
494 const char kDefaultFont
[] = "Times";
495 #elif defined(OS_CHROMEOS)
496 const char kDefaultFont
[] = "Tinos";
498 const char kDefaultFont
[] = "Times New Roman";
500 EXPECT_EQ(ASCIIToUTF16(kDefaultFont
),
501 webkit_prefs
.standard_font_family_map
[prefs::kWebKitCommonScript
]);
502 EXPECT_TRUE(webkit_prefs
.javascript_enabled
);