1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
10 #include "base/functional/callback_helpers.h"
11 #include "base/time/time.h"
12 #include "base/values.h"
13 #include "components/prefs/json_pref_store.h"
14 #include "components/prefs/mock_pref_change_callback.h"
15 #include "components/prefs/pref_change_registrar.h"
16 #include "components/prefs/pref_notifier_impl.h"
17 #include "components/prefs/pref_registry_simple.h"
18 #include "components/prefs/pref_service_factory.h"
19 #include "components/prefs/pref_value_store.h"
20 #include "components/prefs/testing_pref_service.h"
21 #include "components/prefs/testing_pref_store.h"
22 #include "testing/gmock/include/gmock/gmock.h"
23 #include "testing/gtest/include/gtest/gtest.h"
30 const char kPrefName[] = "pref.name";
31 const char kStandaloneBrowserPref[] = "standalone_browser_pref";
35 TEST(PrefServiceTest, NoObserverFire) {
36 TestingPrefServiceSimple prefs;
38 const char pref_name[] = "homepage";
39 prefs.registry()->RegisterStringPref(pref_name, std::string());
41 const char new_pref_value[] = "http://www.google.com/";
42 MockPrefChangeCallback obs(&prefs);
43 PrefChangeRegistrar registrar;
44 registrar.Init(&prefs);
45 registrar.Add(pref_name, obs.GetCallback());
47 // This should fire the checks in MockPrefChangeCallback::OnPreferenceChanged.
48 const base::Value expected_value(new_pref_value);
49 obs.Expect(pref_name, &expected_value);
50 prefs.SetString(pref_name, new_pref_value);
51 Mock::VerifyAndClearExpectations(&obs);
53 // Setting the pref to the same value should not set the pref value a second
55 EXPECT_CALL(obs, OnPreferenceChanged(_)).Times(0);
56 prefs.SetString(pref_name, new_pref_value);
57 Mock::VerifyAndClearExpectations(&obs);
59 // Clearing the pref should cause the pref to fire.
60 const base::Value expected_default_value((std::string()));
61 obs.Expect(pref_name, &expected_default_value);
62 prefs.ClearPref(pref_name);
63 Mock::VerifyAndClearExpectations(&obs);
65 // Clearing the pref again should not cause the pref to fire.
66 EXPECT_CALL(obs, OnPreferenceChanged(_)).Times(0);
67 prefs.ClearPref(pref_name);
68 Mock::VerifyAndClearExpectations(&obs);
71 TEST(PrefServiceTest, HasPrefPath) {
72 TestingPrefServiceSimple prefs;
74 const char path[] = "fake.path";
76 // Shouldn't initially have a path.
77 EXPECT_FALSE(prefs.HasPrefPath(path));
79 // Register the path. This doesn't set a value, so the path still shouldn't
81 prefs.registry()->RegisterStringPref(path, std::string());
82 EXPECT_FALSE(prefs.HasPrefPath(path));
84 // Set a value and make sure we have a path.
85 prefs.SetString(path, "blah");
86 EXPECT_TRUE(prefs.HasPrefPath(path));
89 TEST(PrefServiceTest, Observers) {
90 const char pref_name[] = "homepage";
92 TestingPrefServiceSimple prefs;
93 prefs.SetUserPref(pref_name, base::Value("http://www.cnn.com"));
94 prefs.registry()->RegisterStringPref(pref_name, std::string());
96 const char new_pref_value[] = "http://www.google.com/";
97 const base::Value expected_new_pref_value(new_pref_value);
98 MockPrefChangeCallback obs(&prefs);
99 PrefChangeRegistrar registrar;
100 registrar.Init(&prefs);
101 registrar.Add(pref_name, obs.GetCallback());
103 PrefChangeRegistrar registrar_two;
104 registrar_two.Init(&prefs);
106 // This should fire the checks in MockPrefChangeCallback::OnPreferenceChanged.
107 obs.Expect(pref_name, &expected_new_pref_value);
108 prefs.SetString(pref_name, new_pref_value);
109 Mock::VerifyAndClearExpectations(&obs);
111 // Now try adding a second pref observer.
112 const char new_pref_value2[] = "http://www.youtube.com/";
113 const base::Value expected_new_pref_value2(new_pref_value2);
114 MockPrefChangeCallback obs2(&prefs);
115 obs.Expect(pref_name, &expected_new_pref_value2);
116 obs2.Expect(pref_name, &expected_new_pref_value2);
117 registrar_two.Add(pref_name, obs2.GetCallback());
118 // This should fire the checks in obs and obs2.
119 prefs.SetString(pref_name, new_pref_value2);
120 Mock::VerifyAndClearExpectations(&obs);
121 Mock::VerifyAndClearExpectations(&obs2);
123 // Set a recommended value.
124 const base::Value recommended_pref_value("http://www.gmail.com/");
125 obs.Expect(pref_name, &expected_new_pref_value2);
126 obs2.Expect(pref_name, &expected_new_pref_value2);
127 // This should fire the checks in obs and obs2 but with an unchanged value
128 // as the recommended value is being overridden by the user-set value.
129 prefs.SetRecommendedPref(pref_name, recommended_pref_value.Clone());
130 Mock::VerifyAndClearExpectations(&obs);
131 Mock::VerifyAndClearExpectations(&obs2);
133 // Make sure obs2 still works after removing obs.
134 registrar.Remove(pref_name);
135 EXPECT_CALL(obs, OnPreferenceChanged(_)).Times(0);
136 obs2.Expect(pref_name, &expected_new_pref_value);
137 // This should only fire the observer in obs2.
138 prefs.SetString(pref_name, new_pref_value);
139 Mock::VerifyAndClearExpectations(&obs);
140 Mock::VerifyAndClearExpectations(&obs2);
143 // Make sure that if a preference changes type, so the wrong type is stored in
144 // the user pref file, it uses the correct fallback value instead.
145 TEST(PrefServiceTest, GetValueChangedType) {
146 const int kTestValue = 10;
147 TestingPrefServiceSimple prefs;
148 prefs.registry()->RegisterIntegerPref(kPrefName, kTestValue);
150 // Check falling back to a recommended value.
151 prefs.SetUserPref(kPrefName, base::Value("not an integer"));
152 const PrefService::Preference* pref = prefs.FindPreference(kPrefName);
154 const base::Value* value = pref->GetValue();
156 EXPECT_EQ(base::Value::Type::INTEGER, value->type());
157 ASSERT_TRUE(value->is_int());
158 EXPECT_EQ(kTestValue, value->GetInt());
161 TEST(PrefServiceTest, GetValueAndGetRecommendedValue) {
162 const int kDefaultValue = 5;
163 const int kUserValue = 10;
164 const int kRecommendedValue = 15;
165 TestingPrefServiceSimple prefs;
166 prefs.registry()->RegisterIntegerPref(kPrefName, kDefaultValue);
168 // Create pref with a default value only.
169 const PrefService::Preference* pref = prefs.FindPreference(kPrefName);
172 // Check that GetValue() returns the default value.
173 const base::Value* value = pref->GetValue();
175 EXPECT_EQ(base::Value::Type::INTEGER, value->type());
176 ASSERT_TRUE(value->is_int());
177 EXPECT_EQ(kDefaultValue, value->GetInt());
179 // Check that GetRecommendedValue() returns no value.
180 value = pref->GetRecommendedValue();
183 // Set a user-set value.
184 prefs.SetUserPref(kPrefName, base::Value(kUserValue));
186 // Check that GetValue() returns the user-set value.
187 value = pref->GetValue();
189 EXPECT_EQ(base::Value::Type::INTEGER, value->type());
190 ASSERT_TRUE(value->is_int());
191 EXPECT_EQ(kUserValue, value->GetInt());
193 // Check that GetRecommendedValue() returns no value.
194 value = pref->GetRecommendedValue();
197 // Set a recommended value.
198 prefs.SetRecommendedPref(kPrefName, base::Value(kRecommendedValue));
200 // Check that GetValue() returns the user-set value.
201 value = pref->GetValue();
203 EXPECT_EQ(base::Value::Type::INTEGER, value->type());
204 ASSERT_TRUE(value->is_int());
205 EXPECT_EQ(kUserValue, value->GetInt());
207 // Check that GetRecommendedValue() returns the recommended value.
208 value = pref->GetRecommendedValue();
210 EXPECT_EQ(base::Value::Type::INTEGER, value->type());
211 ASSERT_TRUE(value->is_int());
212 EXPECT_EQ(kRecommendedValue, value->GetInt());
214 // Remove the user-set value.
215 prefs.RemoveUserPref(kPrefName);
217 // Check that GetValue() returns the recommended value.
218 value = pref->GetValue();
220 EXPECT_EQ(base::Value::Type::INTEGER, value->type());
221 ASSERT_TRUE(value->is_int());
222 EXPECT_EQ(kRecommendedValue, value->GetInt());
224 // Check that GetRecommendedValue() returns the recommended value.
225 value = pref->GetRecommendedValue();
227 EXPECT_EQ(base::Value::Type::INTEGER, value->type());
228 ASSERT_TRUE(value->is_int());
229 EXPECT_EQ(kRecommendedValue, value->GetInt());
232 TEST(PrefServiceTest, SetTimeValue_RegularTime) {
233 TestingPrefServiceSimple prefs;
235 // Register a null time as the default.
236 prefs.registry()->RegisterTimePref(kPrefName, base::Time());
237 EXPECT_TRUE(prefs.GetTime(kPrefName).is_null());
239 // Set a time and make sure that we can read it without any loss of precision.
240 const base::Time time = base::Time::Now();
241 prefs.SetTime(kPrefName, time);
242 EXPECT_EQ(time, prefs.GetTime(kPrefName));
245 TEST(PrefServiceTest, SetTimeValue_NullTime) {
246 TestingPrefServiceSimple prefs;
248 // Register a non-null time as the default.
249 const base::Time default_time =
250 base::Time::FromDeltaSinceWindowsEpoch(base::Microseconds(12345));
251 prefs.registry()->RegisterTimePref(kPrefName, default_time);
252 EXPECT_FALSE(prefs.GetTime(kPrefName).is_null());
254 // Set a null time and make sure that it remains null upon deserialization.
255 prefs.SetTime(kPrefName, base::Time());
256 EXPECT_TRUE(prefs.GetTime(kPrefName).is_null());
259 TEST(PrefServiceTest, SetTimeDeltaValue_RegularTimeDelta) {
260 TestingPrefServiceSimple prefs;
262 // Register a zero time delta as the default.
263 prefs.registry()->RegisterTimeDeltaPref(kPrefName, base::TimeDelta());
264 EXPECT_TRUE(prefs.GetTimeDelta(kPrefName).is_zero());
266 // Set a time delta and make sure that we can read it without any loss of
268 const base::TimeDelta delta = base::Time::Now() - base::Time();
269 prefs.SetTimeDelta(kPrefName, delta);
270 EXPECT_EQ(delta, prefs.GetTimeDelta(kPrefName));
273 TEST(PrefServiceTest, SetTimeDeltaValue_ZeroTimeDelta) {
274 TestingPrefServiceSimple prefs;
276 // Register a non-zero time delta as the default.
277 const base::TimeDelta default_delta = base::Microseconds(12345);
278 prefs.registry()->RegisterTimeDeltaPref(kPrefName, default_delta);
279 EXPECT_FALSE(prefs.GetTimeDelta(kPrefName).is_zero());
281 // Set a zero time delta and make sure that it remains zero upon
283 prefs.SetTimeDelta(kPrefName, base::TimeDelta());
284 EXPECT_TRUE(prefs.GetTimeDelta(kPrefName).is_zero());
287 // A PrefStore which just stores the last write flags that were used to write
289 class WriteFlagChecker : public TestingPrefStore {
291 WriteFlagChecker() {}
293 void ReportValueChanged(const std::string& key, uint32_t flags) override {
294 SetLastWriteFlags(flags);
297 void SetValue(const std::string& key,
299 uint32_t flags) override {
300 SetLastWriteFlags(flags);
303 void SetValueSilently(const std::string& key,
305 uint32_t flags) override {
306 SetLastWriteFlags(flags);
309 void RemoveValue(const std::string& key, uint32_t flags) override {
310 SetLastWriteFlags(flags);
313 uint32_t GetLastFlagsAndClear() {
314 CHECK(last_write_flags_set_);
315 uint32_t result = last_write_flags_;
316 last_write_flags_set_ = false;
317 last_write_flags_ = WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS;
321 bool last_write_flags_set() { return last_write_flags_set_; }
324 ~WriteFlagChecker() override {}
326 void SetLastWriteFlags(uint32_t flags) {
327 CHECK(!last_write_flags_set_);
328 last_write_flags_set_ = true;
329 last_write_flags_ = flags;
332 bool last_write_flags_set_ = false;
333 uint32_t last_write_flags_ = WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS;
336 TEST(PrefServiceTest, WriteablePrefStoreFlags) {
337 scoped_refptr<WriteFlagChecker> flag_checker(new WriteFlagChecker);
338 scoped_refptr<PrefRegistrySimple> registry(new PrefRegistrySimple);
339 PrefServiceFactory factory;
340 factory.set_user_prefs(flag_checker);
341 std::unique_ptr<PrefService> prefs(factory.Create(registry.get()));
343 // The first 8 bits of write flags are reserved for subclasses. Create a
344 // custom flag in this range
345 uint32_t kCustomRegistrationFlag = 1 << 2;
347 // A map of the registration flags that will be tested and the write flags
348 // they are expected to convert to.
349 struct RegistrationToWriteFlags {
350 const char* pref_name;
351 uint32_t registration_flags;
352 uint32_t write_flags;
354 const RegistrationToWriteFlags kRegistrationToWriteFlags[] = {
356 PrefRegistry::NO_REGISTRATION_FLAGS,
357 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS},
359 PrefRegistry::LOSSY_PREF,
360 WriteablePrefStore::LOSSY_PREF_WRITE_FLAG},
362 kCustomRegistrationFlag,
363 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS},
365 PrefRegistry::LOSSY_PREF | kCustomRegistrationFlag,
366 WriteablePrefStore::LOSSY_PREF_WRITE_FLAG}};
368 for (size_t i = 0; i < std::size(kRegistrationToWriteFlags); ++i) {
369 RegistrationToWriteFlags entry = kRegistrationToWriteFlags[i];
370 registry->RegisterDictionaryPref(entry.pref_name,
371 entry.registration_flags);
373 SCOPED_TRACE("Currently testing pref with name: " +
374 std::string(entry.pref_name));
376 prefs->GetMutableUserPref(entry.pref_name, base::Value::Type::DICT);
377 EXPECT_TRUE(flag_checker->last_write_flags_set());
378 EXPECT_EQ(entry.write_flags, flag_checker->GetLastFlagsAndClear());
380 prefs->ReportUserPrefChanged(entry.pref_name);
381 EXPECT_TRUE(flag_checker->last_write_flags_set());
382 EXPECT_EQ(entry.write_flags, flag_checker->GetLastFlagsAndClear());
384 prefs->ClearPref(entry.pref_name);
385 EXPECT_TRUE(flag_checker->last_write_flags_set());
386 EXPECT_EQ(entry.write_flags, flag_checker->GetLastFlagsAndClear());
388 prefs->SetUserPrefValue(entry.pref_name,
389 base::Value(base::Value::Type::DICT));
390 EXPECT_TRUE(flag_checker->last_write_flags_set());
391 EXPECT_EQ(entry.write_flags, flag_checker->GetLastFlagsAndClear());
395 class PrefServiceSetValueTest : public testing::Test {
397 static const char kName[];
398 static const char kValue[];
400 PrefServiceSetValueTest() : observer_(&prefs_) {}
402 TestingPrefServiceSimple prefs_;
403 MockPrefChangeCallback observer_;
406 const char PrefServiceSetValueTest::kName[] = "name";
407 const char PrefServiceSetValueTest::kValue[] = "value";
409 TEST_F(PrefServiceSetValueTest, SetStringValue) {
410 const char default_string[] = "default";
411 const base::Value default_value(default_string);
412 prefs_.registry()->RegisterStringPref(kName, default_string);
414 PrefChangeRegistrar registrar;
415 registrar.Init(&prefs_);
416 registrar.Add(kName, observer_.GetCallback());
418 // Changing the controlling store from default to user triggers notification.
419 observer_.Expect(kName, &default_value);
420 prefs_.Set(kName, default_value);
421 Mock::VerifyAndClearExpectations(&observer_);
423 EXPECT_CALL(observer_, OnPreferenceChanged(_)).Times(0);
424 prefs_.Set(kName, default_value);
425 Mock::VerifyAndClearExpectations(&observer_);
427 base::Value new_value(kValue);
428 observer_.Expect(kName, &new_value);
429 prefs_.Set(kName, new_value);
430 Mock::VerifyAndClearExpectations(&observer_);
433 TEST_F(PrefServiceSetValueTest, SetDictionaryValue) {
434 prefs_.registry()->RegisterDictionaryPref(kName);
435 PrefChangeRegistrar registrar;
436 registrar.Init(&prefs_);
437 registrar.Add(kName, observer_.GetCallback());
439 EXPECT_CALL(observer_, OnPreferenceChanged(_)).Times(0);
440 prefs_.RemoveUserPref(kName);
441 Mock::VerifyAndClearExpectations(&observer_);
443 base::Value::Dict new_value_dict;
444 new_value_dict.Set(kName, kValue);
445 base::Value new_value(std::move(new_value_dict));
446 observer_.Expect(kName, &new_value);
447 prefs_.Set(kName, new_value);
448 Mock::VerifyAndClearExpectations(&observer_);
450 EXPECT_CALL(observer_, OnPreferenceChanged(_)).Times(0);
451 prefs_.Set(kName, new_value);
452 Mock::VerifyAndClearExpectations(&observer_);
454 base::Value empty((base::Value::Dict()));
455 observer_.Expect(kName, &empty);
456 prefs_.Set(kName, empty);
457 Mock::VerifyAndClearExpectations(&observer_);
460 TEST_F(PrefServiceSetValueTest, SetListValue) {
461 prefs_.registry()->RegisterListPref(kName);
462 PrefChangeRegistrar registrar;
463 registrar.Init(&prefs_);
464 registrar.Add(kName, observer_.GetCallback());
466 EXPECT_CALL(observer_, OnPreferenceChanged(_)).Times(0);
467 prefs_.RemoveUserPref(kName);
468 Mock::VerifyAndClearExpectations(&observer_);
470 base::Value::List new_value_list;
471 new_value_list.Append(kValue);
472 base::Value new_value(std::move(new_value_list));
473 observer_.Expect(kName, &new_value);
474 prefs_.Set(kName, new_value);
475 Mock::VerifyAndClearExpectations(&observer_);
477 EXPECT_CALL(observer_, OnPreferenceChanged(_)).Times(0);
478 prefs_.Set(kName, new_value);
479 Mock::VerifyAndClearExpectations(&observer_);
481 base::Value empty((base::Value::List()));
482 observer_.Expect(kName, &empty);
483 prefs_.Set(kName, empty);
484 Mock::VerifyAndClearExpectations(&observer_);
487 class PrefStandaloneBrowserPrefsTest : public testing::Test {
489 PrefStandaloneBrowserPrefsTest()
490 : user_pref_store_(base::MakeRefCounted<TestingPrefStore>()),
491 standalone_browser_pref_store_(
492 base::MakeRefCounted<TestingPrefStore>()),
493 pref_registry_(base::MakeRefCounted<PrefRegistrySimple>()) {}
495 ~PrefStandaloneBrowserPrefsTest() override = default;
497 void SetUp() override {
498 auto pref_notifier = std::make_unique<PrefNotifierImpl>();
499 auto pref_value_store = std::make_unique<PrefValueStore>(
500 nullptr /* managed_prefs */, nullptr /* supervised_user_prefs */,
501 nullptr /* extension_prefs */, standalone_browser_pref_store_.get(),
502 new TestingPrefStore(), user_pref_store_.get(),
503 nullptr /* recommended_prefs */, pref_registry_->defaults().get(),
504 pref_notifier.get());
505 pref_service_ = std::make_unique<PrefService>(
506 std::move(pref_notifier), std::move(pref_value_store), user_pref_store_,
507 standalone_browser_pref_store_, pref_registry_, base::DoNothing(),
509 pref_registry_->RegisterIntegerPref(kStandaloneBrowserPref, 4);
512 std::unique_ptr<PrefService> pref_service_;
513 scoped_refptr<TestingPrefStore> user_pref_store_;
514 scoped_refptr<TestingPrefStore> standalone_browser_pref_store_;
515 scoped_refptr<PrefRegistrySimple> pref_registry_;
518 // Check that the standalone browser pref store is correctly initialized,
519 // written to, read, and has correct precedence.
520 TEST_F(PrefStandaloneBrowserPrefsTest, CheckStandaloneBrowserPref) {
521 const PrefService::Preference* preference =
522 pref_service_->FindPreference(kStandaloneBrowserPref);
523 EXPECT_TRUE(preference->IsDefaultValue());
524 EXPECT_EQ(base::Value(4), *(preference->GetValue()));
525 user_pref_store_->SetInteger(kStandaloneBrowserPref, 11);
526 EXPECT_EQ(base::Value(11), *(preference->GetValue()));
527 // The standalone_browser_pref_store has higher precedence.
528 standalone_browser_pref_store_->SetInteger(kStandaloneBrowserPref, 10);
529 ASSERT_EQ(base::Value(10), *(preference->GetValue()));
530 // Removing user_pref_store value shouldn't change the pref value.
531 user_pref_store_->RemoveValue(kStandaloneBrowserPref,
532 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
533 ASSERT_EQ(base::Value(10), *(preference->GetValue()));
534 // Now removing the standalone_browser_pref_store value should revert the
536 standalone_browser_pref_store_->RemoveValue(
537 kStandaloneBrowserPref, WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
538 EXPECT_EQ(base::Value(4), *(preference->GetValue()));