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/prefs/json_pref_store.h"
8 #include "base/prefs/mock_pref_change_callback.h"
9 #include "base/prefs/pref_change_registrar.h"
10 #include "base/prefs/pref_registry_simple.h"
11 #include "base/prefs/pref_service_factory.h"
12 #include "base/prefs/pref_value_store.h"
13 #include "base/prefs/testing_pref_service.h"
14 #include "base/prefs/testing_pref_store.h"
15 #include "base/values.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
22 const char kPrefName
[] = "pref.name";
24 TEST(PrefServiceTest
, NoObserverFire
) {
25 TestingPrefServiceSimple prefs
;
27 const char pref_name
[] = "homepage";
28 prefs
.registry()->RegisterStringPref(pref_name
, std::string());
30 const char new_pref_value
[] = "http://www.google.com/";
31 MockPrefChangeCallback
obs(&prefs
);
32 PrefChangeRegistrar registrar
;
33 registrar
.Init(&prefs
);
34 registrar
.Add(pref_name
, obs
.GetCallback());
36 // This should fire the checks in MockPrefChangeCallback::OnPreferenceChanged.
37 const base::StringValue
expected_value(new_pref_value
);
38 obs
.Expect(pref_name
, &expected_value
);
39 prefs
.SetString(pref_name
, new_pref_value
);
40 Mock::VerifyAndClearExpectations(&obs
);
42 // Setting the pref to the same value should not set the pref value a second
44 EXPECT_CALL(obs
, OnPreferenceChanged(_
)).Times(0);
45 prefs
.SetString(pref_name
, new_pref_value
);
46 Mock::VerifyAndClearExpectations(&obs
);
48 // Clearing the pref should cause the pref to fire.
49 const base::StringValue
expected_default_value((std::string()));
50 obs
.Expect(pref_name
, &expected_default_value
);
51 prefs
.ClearPref(pref_name
);
52 Mock::VerifyAndClearExpectations(&obs
);
54 // Clearing the pref again should not cause the pref to fire.
55 EXPECT_CALL(obs
, OnPreferenceChanged(_
)).Times(0);
56 prefs
.ClearPref(pref_name
);
57 Mock::VerifyAndClearExpectations(&obs
);
60 TEST(PrefServiceTest
, HasPrefPath
) {
61 TestingPrefServiceSimple prefs
;
63 const char path
[] = "fake.path";
65 // Shouldn't initially have a path.
66 EXPECT_FALSE(prefs
.HasPrefPath(path
));
68 // Register the path. This doesn't set a value, so the path still shouldn't
70 prefs
.registry()->RegisterStringPref(path
, std::string());
71 EXPECT_FALSE(prefs
.HasPrefPath(path
));
73 // Set a value and make sure we have a path.
74 prefs
.SetString(path
, "blah");
75 EXPECT_TRUE(prefs
.HasPrefPath(path
));
78 TEST(PrefServiceTest
, Observers
) {
79 const char pref_name
[] = "homepage";
81 TestingPrefServiceSimple prefs
;
82 prefs
.SetUserPref(pref_name
,
83 new base::StringValue("http://www.cnn.com"));
84 prefs
.registry()->RegisterStringPref(pref_name
, std::string());
86 const char new_pref_value
[] = "http://www.google.com/";
87 const base::StringValue
expected_new_pref_value(new_pref_value
);
88 MockPrefChangeCallback
obs(&prefs
);
89 PrefChangeRegistrar registrar
;
90 registrar
.Init(&prefs
);
91 registrar
.Add(pref_name
, obs
.GetCallback());
93 PrefChangeRegistrar registrar_two
;
94 registrar_two
.Init(&prefs
);
96 // This should fire the checks in MockPrefChangeCallback::OnPreferenceChanged.
97 obs
.Expect(pref_name
, &expected_new_pref_value
);
98 prefs
.SetString(pref_name
, new_pref_value
);
99 Mock::VerifyAndClearExpectations(&obs
);
101 // Now try adding a second pref observer.
102 const char new_pref_value2
[] = "http://www.youtube.com/";
103 const base::StringValue
expected_new_pref_value2(new_pref_value2
);
104 MockPrefChangeCallback
obs2(&prefs
);
105 obs
.Expect(pref_name
, &expected_new_pref_value2
);
106 obs2
.Expect(pref_name
, &expected_new_pref_value2
);
107 registrar_two
.Add(pref_name
, obs2
.GetCallback());
108 // This should fire the checks in obs and obs2.
109 prefs
.SetString(pref_name
, new_pref_value2
);
110 Mock::VerifyAndClearExpectations(&obs
);
111 Mock::VerifyAndClearExpectations(&obs2
);
113 // Set a recommended value.
114 const base::StringValue
recommended_pref_value("http://www.gmail.com/");
115 obs
.Expect(pref_name
, &expected_new_pref_value2
);
116 obs2
.Expect(pref_name
, &expected_new_pref_value2
);
117 // This should fire the checks in obs and obs2 but with an unchanged value
118 // as the recommended value is being overridden by the user-set value.
119 prefs
.SetRecommendedPref(pref_name
, recommended_pref_value
.DeepCopy());
120 Mock::VerifyAndClearExpectations(&obs
);
121 Mock::VerifyAndClearExpectations(&obs2
);
123 // Make sure obs2 still works after removing obs.
124 registrar
.Remove(pref_name
);
125 EXPECT_CALL(obs
, OnPreferenceChanged(_
)).Times(0);
126 obs2
.Expect(pref_name
, &expected_new_pref_value
);
127 // This should only fire the observer in obs2.
128 prefs
.SetString(pref_name
, new_pref_value
);
129 Mock::VerifyAndClearExpectations(&obs
);
130 Mock::VerifyAndClearExpectations(&obs2
);
133 // Make sure that if a preference changes type, so the wrong type is stored in
134 // the user pref file, it uses the correct fallback value instead.
135 TEST(PrefServiceTest
, GetValueChangedType
) {
136 const int kTestValue
= 10;
137 TestingPrefServiceSimple prefs
;
138 prefs
.registry()->RegisterIntegerPref(kPrefName
, kTestValue
);
140 // Check falling back to a recommended value.
141 prefs
.SetUserPref(kPrefName
,
142 new base::StringValue("not an integer"));
143 const PrefService::Preference
* pref
= prefs
.FindPreference(kPrefName
);
145 const base::Value
* value
= pref
->GetValue();
147 EXPECT_EQ(base::Value::TYPE_INTEGER
, value
->GetType());
148 int actual_int_value
= -1;
149 EXPECT_TRUE(value
->GetAsInteger(&actual_int_value
));
150 EXPECT_EQ(kTestValue
, actual_int_value
);
153 TEST(PrefServiceTest
, GetValueAndGetRecommendedValue
) {
154 const int kDefaultValue
= 5;
155 const int kUserValue
= 10;
156 const int kRecommendedValue
= 15;
157 TestingPrefServiceSimple prefs
;
158 prefs
.registry()->RegisterIntegerPref(kPrefName
, kDefaultValue
);
160 // Create pref with a default value only.
161 const PrefService::Preference
* pref
= prefs
.FindPreference(kPrefName
);
164 // Check that GetValue() returns the default value.
165 const base::Value
* value
= pref
->GetValue();
167 EXPECT_EQ(base::Value::TYPE_INTEGER
, value
->GetType());
168 int actual_int_value
= -1;
169 EXPECT_TRUE(value
->GetAsInteger(&actual_int_value
));
170 EXPECT_EQ(kDefaultValue
, actual_int_value
);
172 // Check that GetRecommendedValue() returns no value.
173 value
= pref
->GetRecommendedValue();
176 // Set a user-set value.
177 prefs
.SetUserPref(kPrefName
, new base::FundamentalValue(kUserValue
));
179 // Check that GetValue() returns the user-set value.
180 value
= pref
->GetValue();
182 EXPECT_EQ(base::Value::TYPE_INTEGER
, value
->GetType());
183 actual_int_value
= -1;
184 EXPECT_TRUE(value
->GetAsInteger(&actual_int_value
));
185 EXPECT_EQ(kUserValue
, actual_int_value
);
187 // Check that GetRecommendedValue() returns no value.
188 value
= pref
->GetRecommendedValue();
191 // Set a recommended value.
192 prefs
.SetRecommendedPref(kPrefName
,
193 new base::FundamentalValue(kRecommendedValue
));
195 // Check that GetValue() returns the user-set value.
196 value
= pref
->GetValue();
198 EXPECT_EQ(base::Value::TYPE_INTEGER
, value
->GetType());
199 actual_int_value
= -1;
200 EXPECT_TRUE(value
->GetAsInteger(&actual_int_value
));
201 EXPECT_EQ(kUserValue
, actual_int_value
);
203 // Check that GetRecommendedValue() returns the recommended value.
204 value
= pref
->GetRecommendedValue();
206 EXPECT_EQ(base::Value::TYPE_INTEGER
, value
->GetType());
207 actual_int_value
= -1;
208 EXPECT_TRUE(value
->GetAsInteger(&actual_int_value
));
209 EXPECT_EQ(kRecommendedValue
, actual_int_value
);
211 // Remove the user-set value.
212 prefs
.RemoveUserPref(kPrefName
);
214 // Check that GetValue() returns the recommended value.
215 value
= pref
->GetValue();
217 EXPECT_EQ(base::Value::TYPE_INTEGER
, value
->GetType());
218 actual_int_value
= -1;
219 EXPECT_TRUE(value
->GetAsInteger(&actual_int_value
));
220 EXPECT_EQ(kRecommendedValue
, actual_int_value
);
222 // Check that GetRecommendedValue() returns the recommended value.
223 value
= pref
->GetRecommendedValue();
225 EXPECT_EQ(base::Value::TYPE_INTEGER
, value
->GetType());
226 actual_int_value
= -1;
227 EXPECT_TRUE(value
->GetAsInteger(&actual_int_value
));
228 EXPECT_EQ(kRecommendedValue
, actual_int_value
);
231 // A PrefStore which just stores the last write flags that were used to write
233 class WriteFlagChecker
: public TestingPrefStore
{
235 WriteFlagChecker() {}
237 void ReportValueChanged(const std::string
& key
, uint32 flags
) override
{
238 SetLastWriteFlags(flags
);
241 void SetValue(const std::string
& key
,
242 scoped_ptr
<base::Value
> value
,
243 uint32 flags
) override
{
244 SetLastWriteFlags(flags
);
247 void SetValueSilently(const std::string
& key
,
248 scoped_ptr
<base::Value
> value
,
249 uint32 flags
) override
{
250 SetLastWriteFlags(flags
);
253 void RemoveValue(const std::string
& key
, uint32 flags
) override
{
254 SetLastWriteFlags(flags
);
257 uint32
GetLastFlagsAndClear() {
258 CHECK(last_write_flags_set_
);
259 uint32 result
= last_write_flags_
;
260 last_write_flags_set_
= false;
261 last_write_flags_
= WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS
;
265 bool last_write_flags_set() { return last_write_flags_set_
; }
268 ~WriteFlagChecker() override
{}
270 void SetLastWriteFlags(uint32 flags
) {
271 CHECK(!last_write_flags_set_
);
272 last_write_flags_set_
= true;
273 last_write_flags_
= flags
;
276 bool last_write_flags_set_
= false;
277 uint32 last_write_flags_
= WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS
;
280 TEST(PrefServiceTest
, WriteablePrefStoreFlags
) {
281 scoped_refptr
<WriteFlagChecker
> flag_checker(new WriteFlagChecker
);
282 scoped_refptr
<PrefRegistrySimple
> registry(new PrefRegistrySimple
);
283 base::PrefServiceFactory factory
;
284 factory
.set_user_prefs(flag_checker
);
285 scoped_ptr
<PrefService
> prefs(factory
.Create(registry
.get()));
287 // The first 8 bits of write flags are reserved for subclasses. Create a
288 // custom flag in this range
289 uint32 kCustomRegistrationFlag
= 1 << 2;
291 // A map of the registration flags that will be tested and the write flags
292 // they are expected to convert to.
293 struct RegistrationToWriteFlags
{
294 const char* pref_name
;
295 uint32 registration_flags
;
298 const RegistrationToWriteFlags kRegistrationToWriteFlags
[] = {
300 PrefRegistry::NO_REGISTRATION_FLAGS
,
301 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS
},
303 PrefRegistry::LOSSY_PREF
,
304 WriteablePrefStore::LOSSY_PREF_WRITE_FLAG
},
306 kCustomRegistrationFlag
,
307 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS
},
309 PrefRegistry::LOSSY_PREF
| kCustomRegistrationFlag
,
310 WriteablePrefStore::LOSSY_PREF_WRITE_FLAG
}};
312 for (size_t i
= 0; i
< arraysize(kRegistrationToWriteFlags
); ++i
) {
313 RegistrationToWriteFlags entry
= kRegistrationToWriteFlags
[i
];
314 registry
->RegisterDictionaryPref(
315 entry
.pref_name
, new base::DictionaryValue(), entry
.registration_flags
);
317 SCOPED_TRACE("Currently testing pref with name: " +
318 std::string(entry
.pref_name
));
320 prefs
->GetMutableUserPref(entry
.pref_name
, base::Value::TYPE_DICTIONARY
);
321 EXPECT_TRUE(flag_checker
->last_write_flags_set());
322 EXPECT_EQ(entry
.write_flags
, flag_checker
->GetLastFlagsAndClear());
324 prefs
->ReportUserPrefChanged(entry
.pref_name
);
325 EXPECT_TRUE(flag_checker
->last_write_flags_set());
326 EXPECT_EQ(entry
.write_flags
, flag_checker
->GetLastFlagsAndClear());
328 prefs
->ClearPref(entry
.pref_name
);
329 EXPECT_TRUE(flag_checker
->last_write_flags_set());
330 EXPECT_EQ(entry
.write_flags
, flag_checker
->GetLastFlagsAndClear());
332 prefs
->SetUserPrefValue(entry
.pref_name
, new base::DictionaryValue());
333 EXPECT_TRUE(flag_checker
->last_write_flags_set());
334 EXPECT_EQ(entry
.write_flags
, flag_checker
->GetLastFlagsAndClear());
338 class PrefServiceSetValueTest
: public testing::Test
{
340 static const char kName
[];
341 static const char kValue
[];
343 PrefServiceSetValueTest() : observer_(&prefs_
) {}
345 TestingPrefServiceSimple prefs_
;
346 MockPrefChangeCallback observer_
;
349 const char PrefServiceSetValueTest::kName
[] = "name";
350 const char PrefServiceSetValueTest::kValue
[] = "value";
352 TEST_F(PrefServiceSetValueTest
, SetStringValue
) {
353 const char default_string
[] = "default";
354 const base::StringValue
default_value(default_string
);
355 prefs_
.registry()->RegisterStringPref(kName
, default_string
);
357 PrefChangeRegistrar registrar
;
358 registrar
.Init(&prefs_
);
359 registrar
.Add(kName
, observer_
.GetCallback());
361 // Changing the controlling store from default to user triggers notification.
362 observer_
.Expect(kName
, &default_value
);
363 prefs_
.Set(kName
, default_value
);
364 Mock::VerifyAndClearExpectations(&observer_
);
366 EXPECT_CALL(observer_
, OnPreferenceChanged(_
)).Times(0);
367 prefs_
.Set(kName
, default_value
);
368 Mock::VerifyAndClearExpectations(&observer_
);
370 base::StringValue
new_value(kValue
);
371 observer_
.Expect(kName
, &new_value
);
372 prefs_
.Set(kName
, new_value
);
373 Mock::VerifyAndClearExpectations(&observer_
);
376 TEST_F(PrefServiceSetValueTest
, SetDictionaryValue
) {
377 prefs_
.registry()->RegisterDictionaryPref(kName
);
378 PrefChangeRegistrar registrar
;
379 registrar
.Init(&prefs_
);
380 registrar
.Add(kName
, observer_
.GetCallback());
382 EXPECT_CALL(observer_
, OnPreferenceChanged(_
)).Times(0);
383 prefs_
.RemoveUserPref(kName
);
384 Mock::VerifyAndClearExpectations(&observer_
);
386 base::DictionaryValue new_value
;
387 new_value
.SetString(kName
, kValue
);
388 observer_
.Expect(kName
, &new_value
);
389 prefs_
.Set(kName
, new_value
);
390 Mock::VerifyAndClearExpectations(&observer_
);
392 EXPECT_CALL(observer_
, OnPreferenceChanged(_
)).Times(0);
393 prefs_
.Set(kName
, new_value
);
394 Mock::VerifyAndClearExpectations(&observer_
);
396 base::DictionaryValue empty
;
397 observer_
.Expect(kName
, &empty
);
398 prefs_
.Set(kName
, empty
);
399 Mock::VerifyAndClearExpectations(&observer_
);
402 TEST_F(PrefServiceSetValueTest
, SetListValue
) {
403 prefs_
.registry()->RegisterListPref(kName
);
404 PrefChangeRegistrar registrar
;
405 registrar
.Init(&prefs_
);
406 registrar
.Add(kName
, observer_
.GetCallback());
408 EXPECT_CALL(observer_
, OnPreferenceChanged(_
)).Times(0);
409 prefs_
.RemoveUserPref(kName
);
410 Mock::VerifyAndClearExpectations(&observer_
);
412 base::ListValue new_value
;
413 new_value
.Append(new base::StringValue(kValue
));
414 observer_
.Expect(kName
, &new_value
);
415 prefs_
.Set(kName
, new_value
);
416 Mock::VerifyAndClearExpectations(&observer_
);
418 EXPECT_CALL(observer_
, OnPreferenceChanged(_
)).Times(0);
419 prefs_
.Set(kName
, new_value
);
420 Mock::VerifyAndClearExpectations(&observer_
);
422 base::ListValue empty
;
423 observer_
.Expect(kName
, &empty
);
424 prefs_
.Set(kName
, empty
);
425 Mock::VerifyAndClearExpectations(&observer_
);