| // 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 <stddef.h> |
| #include <stdint.h> |
| |
| #include <string> |
| |
| #include "base/bind_helpers.h" |
| #include "base/stl_util.h" |
| #include "base/time/time.h" |
| #include "base/values.h" |
| #include "components/prefs/json_pref_store.h" |
| #include "components/prefs/mock_pref_change_callback.h" |
| #include "components/prefs/pref_change_registrar.h" |
| #include "components/prefs/pref_notifier_impl.h" |
| #include "components/prefs/pref_registry_simple.h" |
| #include "components/prefs/pref_service_factory.h" |
| #include "components/prefs/pref_value_store.h" |
| #include "components/prefs/testing_pref_service.h" |
| #include "components/prefs/testing_pref_store.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| using testing::_; |
| using testing::Mock; |
| |
| namespace { |
| |
| const char kPrefName[] = "pref.name"; |
| const char kManagedPref[] = "managed_pref"; |
| const char kRecommendedPref[] = "recommended_pref"; |
| const char kSupervisedPref[] = "supervised_pref"; |
| |
| } // namespace |
| |
| TEST(PrefServiceTest, NoObserverFire) { |
| TestingPrefServiceSimple prefs; |
| |
| const char pref_name[] = "homepage"; |
| prefs.registry()->RegisterStringPref(pref_name, std::string()); |
| |
| const char new_pref_value[] = "http://www.google.com/"; |
| MockPrefChangeCallback obs(&prefs); |
| PrefChangeRegistrar registrar; |
| registrar.Init(&prefs); |
| registrar.Add(pref_name, obs.GetCallback()); |
| |
| // This should fire the checks in MockPrefChangeCallback::OnPreferenceChanged. |
| const base::Value expected_value(new_pref_value); |
| obs.Expect(pref_name, &expected_value); |
| prefs.SetString(pref_name, new_pref_value); |
| Mock::VerifyAndClearExpectations(&obs); |
| |
| // Setting the pref to the same value should not set the pref value a second |
| // time. |
| EXPECT_CALL(obs, OnPreferenceChanged(_)).Times(0); |
| prefs.SetString(pref_name, new_pref_value); |
| Mock::VerifyAndClearExpectations(&obs); |
| |
| // Clearing the pref should cause the pref to fire. |
| const base::Value expected_default_value((std::string())); |
| obs.Expect(pref_name, &expected_default_value); |
| prefs.ClearPref(pref_name); |
| Mock::VerifyAndClearExpectations(&obs); |
| |
| // Clearing the pref again should not cause the pref to fire. |
| EXPECT_CALL(obs, OnPreferenceChanged(_)).Times(0); |
| prefs.ClearPref(pref_name); |
| Mock::VerifyAndClearExpectations(&obs); |
| } |
| |
| TEST(PrefServiceTest, HasPrefPath) { |
| TestingPrefServiceSimple prefs; |
| |
| const char path[] = "fake.path"; |
| |
| // Shouldn't initially have a path. |
| EXPECT_FALSE(prefs.HasPrefPath(path)); |
| |
| // Register the path. This doesn't set a value, so the path still shouldn't |
| // exist. |
| prefs.registry()->RegisterStringPref(path, std::string()); |
| EXPECT_FALSE(prefs.HasPrefPath(path)); |
| |
| // Set a value and make sure we have a path. |
| prefs.SetString(path, "blah"); |
| EXPECT_TRUE(prefs.HasPrefPath(path)); |
| } |
| |
| TEST(PrefServiceTest, Observers) { |
| const char pref_name[] = "homepage"; |
| |
| TestingPrefServiceSimple prefs; |
| prefs.SetUserPref(pref_name, |
| std::make_unique<base::Value>("http://www.cnn.com")); |
| prefs.registry()->RegisterStringPref(pref_name, std::string()); |
| |
| const char new_pref_value[] = "http://www.google.com/"; |
| const base::Value expected_new_pref_value(new_pref_value); |
| MockPrefChangeCallback obs(&prefs); |
| PrefChangeRegistrar registrar; |
| registrar.Init(&prefs); |
| registrar.Add(pref_name, obs.GetCallback()); |
| |
| PrefChangeRegistrar registrar_two; |
| registrar_two.Init(&prefs); |
| |
| // This should fire the checks in MockPrefChangeCallback::OnPreferenceChanged. |
| obs.Expect(pref_name, &expected_new_pref_value); |
| prefs.SetString(pref_name, new_pref_value); |
| Mock::VerifyAndClearExpectations(&obs); |
| |
| // Now try adding a second pref observer. |
| const char new_pref_value2[] = "http://www.youtube.com/"; |
| const base::Value expected_new_pref_value2(new_pref_value2); |
| MockPrefChangeCallback obs2(&prefs); |
| obs.Expect(pref_name, &expected_new_pref_value2); |
| obs2.Expect(pref_name, &expected_new_pref_value2); |
| registrar_two.Add(pref_name, obs2.GetCallback()); |
| // This should fire the checks in obs and obs2. |
| prefs.SetString(pref_name, new_pref_value2); |
| Mock::VerifyAndClearExpectations(&obs); |
| Mock::VerifyAndClearExpectations(&obs2); |
| |
| // Set a recommended value. |
| const base::Value recommended_pref_value("http://www.gmail.com/"); |
| obs.Expect(pref_name, &expected_new_pref_value2); |
| obs2.Expect(pref_name, &expected_new_pref_value2); |
| // This should fire the checks in obs and obs2 but with an unchanged value |
| // as the recommended value is being overridden by the user-set value. |
| prefs.SetRecommendedPref(pref_name, recommended_pref_value.CreateDeepCopy()); |
| Mock::VerifyAndClearExpectations(&obs); |
| Mock::VerifyAndClearExpectations(&obs2); |
| |
| // Make sure obs2 still works after removing obs. |
| registrar.Remove(pref_name); |
| EXPECT_CALL(obs, OnPreferenceChanged(_)).Times(0); |
| obs2.Expect(pref_name, &expected_new_pref_value); |
| // This should only fire the observer in obs2. |
| prefs.SetString(pref_name, new_pref_value); |
| Mock::VerifyAndClearExpectations(&obs); |
| Mock::VerifyAndClearExpectations(&obs2); |
| } |
| |
| // Make sure that if a preference changes type, so the wrong type is stored in |
| // the user pref file, it uses the correct fallback value instead. |
| TEST(PrefServiceTest, GetValueChangedType) { |
| const int kTestValue = 10; |
| TestingPrefServiceSimple prefs; |
| prefs.registry()->RegisterIntegerPref(kPrefName, kTestValue); |
| |
| // Check falling back to a recommended value. |
| prefs.SetUserPref(kPrefName, std::make_unique<base::Value>("not an integer")); |
| const PrefService::Preference* pref = prefs.FindPreference(kPrefName); |
| ASSERT_TRUE(pref); |
| const base::Value* value = pref->GetValue(); |
| ASSERT_TRUE(value); |
| EXPECT_EQ(base::Value::Type::INTEGER, value->type()); |
| int actual_int_value = -1; |
| EXPECT_TRUE(value->GetAsInteger(&actual_int_value)); |
| EXPECT_EQ(kTestValue, actual_int_value); |
| } |
| |
| TEST(PrefServiceTest, GetValueAndGetRecommendedValue) { |
| const int kDefaultValue = 5; |
| const int kUserValue = 10; |
| const int kRecommendedValue = 15; |
| TestingPrefServiceSimple prefs; |
| prefs.registry()->RegisterIntegerPref(kPrefName, kDefaultValue); |
| |
| // Create pref with a default value only. |
| const PrefService::Preference* pref = prefs.FindPreference(kPrefName); |
| ASSERT_TRUE(pref); |
| |
| // Check that GetValue() returns the default value. |
| const base::Value* value = pref->GetValue(); |
| ASSERT_TRUE(value); |
| EXPECT_EQ(base::Value::Type::INTEGER, value->type()); |
| int actual_int_value = -1; |
| EXPECT_TRUE(value->GetAsInteger(&actual_int_value)); |
| EXPECT_EQ(kDefaultValue, actual_int_value); |
| |
| // Check that GetRecommendedValue() returns no value. |
| value = pref->GetRecommendedValue(); |
| ASSERT_FALSE(value); |
| |
| // Set a user-set value. |
| prefs.SetUserPref(kPrefName, std::make_unique<base::Value>(kUserValue)); |
| |
| // Check that GetValue() returns the user-set value. |
| value = pref->GetValue(); |
| ASSERT_TRUE(value); |
| EXPECT_EQ(base::Value::Type::INTEGER, value->type()); |
| actual_int_value = -1; |
| EXPECT_TRUE(value->GetAsInteger(&actual_int_value)); |
| EXPECT_EQ(kUserValue, actual_int_value); |
| |
| // Check that GetRecommendedValue() returns no value. |
| value = pref->GetRecommendedValue(); |
| ASSERT_FALSE(value); |
| |
| // Set a recommended value. |
| prefs.SetRecommendedPref(kPrefName, |
| std::make_unique<base::Value>(kRecommendedValue)); |
| |
| // Check that GetValue() returns the user-set value. |
| value = pref->GetValue(); |
| ASSERT_TRUE(value); |
| EXPECT_EQ(base::Value::Type::INTEGER, value->type()); |
| actual_int_value = -1; |
| EXPECT_TRUE(value->GetAsInteger(&actual_int_value)); |
| EXPECT_EQ(kUserValue, actual_int_value); |
| |
| // Check that GetRecommendedValue() returns the recommended value. |
| value = pref->GetRecommendedValue(); |
| ASSERT_TRUE(value); |
| EXPECT_EQ(base::Value::Type::INTEGER, value->type()); |
| actual_int_value = -1; |
| EXPECT_TRUE(value->GetAsInteger(&actual_int_value)); |
| EXPECT_EQ(kRecommendedValue, actual_int_value); |
| |
| // Remove the user-set value. |
| prefs.RemoveUserPref(kPrefName); |
| |
| // Check that GetValue() returns the recommended value. |
| value = pref->GetValue(); |
| ASSERT_TRUE(value); |
| EXPECT_EQ(base::Value::Type::INTEGER, value->type()); |
| actual_int_value = -1; |
| EXPECT_TRUE(value->GetAsInteger(&actual_int_value)); |
| EXPECT_EQ(kRecommendedValue, actual_int_value); |
| |
| // Check that GetRecommendedValue() returns the recommended value. |
| value = pref->GetRecommendedValue(); |
| ASSERT_TRUE(value); |
| EXPECT_EQ(base::Value::Type::INTEGER, value->type()); |
| actual_int_value = -1; |
| EXPECT_TRUE(value->GetAsInteger(&actual_int_value)); |
| EXPECT_EQ(kRecommendedValue, actual_int_value); |
| } |
| |
| TEST(PrefServiceTest, SetTimeValue_RegularTime) { |
| TestingPrefServiceSimple prefs; |
| |
| // Register a null time as the default. |
| prefs.registry()->RegisterTimePref(kPrefName, base::Time()); |
| EXPECT_TRUE(prefs.GetTime(kPrefName).is_null()); |
| |
| // Set a time and make sure that we can read it without any loss of precision. |
| const base::Time time = base::Time::Now(); |
| prefs.SetTime(kPrefName, time); |
| EXPECT_EQ(time, prefs.GetTime(kPrefName)); |
| } |
| |
| TEST(PrefServiceTest, SetTimeValue_NullTime) { |
| TestingPrefServiceSimple prefs; |
| |
| // Register a non-null time as the default. |
| const base::Time default_time = base::Time::FromDeltaSinceWindowsEpoch( |
| base::TimeDelta::FromMicroseconds(12345)); |
| prefs.registry()->RegisterTimePref(kPrefName, default_time); |
| EXPECT_FALSE(prefs.GetTime(kPrefName).is_null()); |
| |
| // Set a null time and make sure that it remains null upon deserialization. |
| prefs.SetTime(kPrefName, base::Time()); |
| EXPECT_TRUE(prefs.GetTime(kPrefName).is_null()); |
| } |
| |
| TEST(PrefServiceTest, SetTimeDeltaValue_RegularTimeDelta) { |
| TestingPrefServiceSimple prefs; |
| |
| // Register a zero time delta as the default. |
| prefs.registry()->RegisterTimeDeltaPref(kPrefName, base::TimeDelta()); |
| EXPECT_TRUE(prefs.GetTimeDelta(kPrefName).is_zero()); |
| |
| // Set a time delta and make sure that we can read it without any loss of |
| // precision. |
| const base::TimeDelta delta = base::Time::Now() - base::Time(); |
| prefs.SetTimeDelta(kPrefName, delta); |
| EXPECT_EQ(delta, prefs.GetTimeDelta(kPrefName)); |
| } |
| |
| TEST(PrefServiceTest, SetTimeDeltaValue_ZeroTimeDelta) { |
| TestingPrefServiceSimple prefs; |
| |
| // Register a non-zero time delta as the default. |
| const base::TimeDelta default_delta = |
| base::TimeDelta::FromMicroseconds(12345); |
| prefs.registry()->RegisterTimeDeltaPref(kPrefName, default_delta); |
| EXPECT_FALSE(prefs.GetTimeDelta(kPrefName).is_zero()); |
| |
| // Set a zero time delta and make sure that it remains zero upon |
| // deserialization. |
| prefs.SetTimeDelta(kPrefName, base::TimeDelta()); |
| EXPECT_TRUE(prefs.GetTimeDelta(kPrefName).is_zero()); |
| } |
| |
| // A PrefStore which just stores the last write flags that were used to write |
| // values to it. |
| class WriteFlagChecker : public TestingPrefStore { |
| public: |
| WriteFlagChecker() {} |
| |
| void ReportValueChanged(const std::string& key, uint32_t flags) override { |
| SetLastWriteFlags(flags); |
| } |
| |
| void SetValue(const std::string& key, |
| std::unique_ptr<base::Value> value, |
| uint32_t flags) override { |
| SetLastWriteFlags(flags); |
| } |
| |
| void SetValueSilently(const std::string& key, |
| std::unique_ptr<base::Value> value, |
| uint32_t flags) override { |
| SetLastWriteFlags(flags); |
| } |
| |
| void RemoveValue(const std::string& key, uint32_t flags) override { |
| SetLastWriteFlags(flags); |
| } |
| |
| uint32_t GetLastFlagsAndClear() { |
| CHECK(last_write_flags_set_); |
| uint32_t result = last_write_flags_; |
| last_write_flags_set_ = false; |
| last_write_flags_ = WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS; |
| return result; |
| } |
| |
| bool last_write_flags_set() { return last_write_flags_set_; } |
| |
| private: |
| ~WriteFlagChecker() override {} |
| |
| void SetLastWriteFlags(uint32_t flags) { |
| CHECK(!last_write_flags_set_); |
| last_write_flags_set_ = true; |
| last_write_flags_ = flags; |
| } |
| |
| bool last_write_flags_set_ = false; |
| uint32_t last_write_flags_ = WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS; |
| }; |
| |
| TEST(PrefServiceTest, WriteablePrefStoreFlags) { |
| scoped_refptr<WriteFlagChecker> flag_checker(new WriteFlagChecker); |
| scoped_refptr<PrefRegistrySimple> registry(new PrefRegistrySimple); |
| PrefServiceFactory factory; |
| factory.set_user_prefs(flag_checker); |
| std::unique_ptr<PrefService> prefs(factory.Create(registry.get())); |
| |
| // The first 8 bits of write flags are reserved for subclasses. Create a |
| // custom flag in this range |
| uint32_t kCustomRegistrationFlag = 1 << 2; |
| |
| // A map of the registration flags that will be tested and the write flags |
| // they are expected to convert to. |
| struct RegistrationToWriteFlags { |
| const char* pref_name; |
| uint32_t registration_flags; |
| uint32_t write_flags; |
| }; |
| const RegistrationToWriteFlags kRegistrationToWriteFlags[] = { |
| {"none", PrefRegistry::NO_REGISTRATION_FLAGS, |
| WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS}, |
| {"lossy", PrefRegistry::LOSSY_PREF, |
| WriteablePrefStore::LOSSY_PREF_WRITE_FLAG}, |
| {"custom", kCustomRegistrationFlag, |
| WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS}, |
| {"lossyandcustom", PrefRegistry::LOSSY_PREF | kCustomRegistrationFlag, |
| WriteablePrefStore::LOSSY_PREF_WRITE_FLAG}}; |
| |
| for (size_t i = 0; i < base::size(kRegistrationToWriteFlags); ++i) { |
| RegistrationToWriteFlags entry = kRegistrationToWriteFlags[i]; |
| registry->RegisterDictionaryPref(entry.pref_name, |
| entry.registration_flags); |
| |
| SCOPED_TRACE("Currently testing pref with name: " + |
| std::string(entry.pref_name)); |
| |
| prefs->GetMutableUserPref(entry.pref_name, base::Value::Type::DICTIONARY); |
| EXPECT_TRUE(flag_checker->last_write_flags_set()); |
| EXPECT_EQ(entry.write_flags, flag_checker->GetLastFlagsAndClear()); |
| |
| prefs->ReportUserPrefChanged(entry.pref_name); |
| EXPECT_TRUE(flag_checker->last_write_flags_set()); |
| EXPECT_EQ(entry.write_flags, flag_checker->GetLastFlagsAndClear()); |
| |
| prefs->ClearPref(entry.pref_name); |
| EXPECT_TRUE(flag_checker->last_write_flags_set()); |
| EXPECT_EQ(entry.write_flags, flag_checker->GetLastFlagsAndClear()); |
| |
| prefs->SetUserPrefValue(entry.pref_name, |
| std::make_unique<base::DictionaryValue>()); |
| EXPECT_TRUE(flag_checker->last_write_flags_set()); |
| EXPECT_EQ(entry.write_flags, flag_checker->GetLastFlagsAndClear()); |
| } |
| } |
| |
| class PrefServiceSetValueTest : public testing::Test { |
| protected: |
| static const char kName[]; |
| static const char kValue[]; |
| |
| PrefServiceSetValueTest() : observer_(&prefs_) {} |
| |
| TestingPrefServiceSimple prefs_; |
| MockPrefChangeCallback observer_; |
| }; |
| |
| const char PrefServiceSetValueTest::kName[] = "name"; |
| const char PrefServiceSetValueTest::kValue[] = "value"; |
| |
| TEST_F(PrefServiceSetValueTest, SetStringValue) { |
| const char default_string[] = "default"; |
| const base::Value default_value(default_string); |
| prefs_.registry()->RegisterStringPref(kName, default_string); |
| |
| PrefChangeRegistrar registrar; |
| registrar.Init(&prefs_); |
| registrar.Add(kName, observer_.GetCallback()); |
| |
| // Changing the controlling store from default to user triggers notification. |
| observer_.Expect(kName, &default_value); |
| prefs_.Set(kName, default_value); |
| Mock::VerifyAndClearExpectations(&observer_); |
| |
| EXPECT_CALL(observer_, OnPreferenceChanged(_)).Times(0); |
| prefs_.Set(kName, default_value); |
| Mock::VerifyAndClearExpectations(&observer_); |
| |
| base::Value new_value(kValue); |
| observer_.Expect(kName, &new_value); |
| prefs_.Set(kName, new_value); |
| Mock::VerifyAndClearExpectations(&observer_); |
| } |
| |
| TEST_F(PrefServiceSetValueTest, SetDictionaryValue) { |
| prefs_.registry()->RegisterDictionaryPref(kName); |
| PrefChangeRegistrar registrar; |
| registrar.Init(&prefs_); |
| registrar.Add(kName, observer_.GetCallback()); |
| |
| EXPECT_CALL(observer_, OnPreferenceChanged(_)).Times(0); |
| prefs_.RemoveUserPref(kName); |
| Mock::VerifyAndClearExpectations(&observer_); |
| |
| base::DictionaryValue new_value; |
| new_value.SetString(kName, kValue); |
| observer_.Expect(kName, &new_value); |
| prefs_.Set(kName, new_value); |
| Mock::VerifyAndClearExpectations(&observer_); |
| |
| EXPECT_CALL(observer_, OnPreferenceChanged(_)).Times(0); |
| prefs_.Set(kName, new_value); |
| Mock::VerifyAndClearExpectations(&observer_); |
| |
| base::DictionaryValue empty; |
| observer_.Expect(kName, &empty); |
| prefs_.Set(kName, empty); |
| Mock::VerifyAndClearExpectations(&observer_); |
| } |
| |
| TEST_F(PrefServiceSetValueTest, SetListValue) { |
| prefs_.registry()->RegisterListPref(kName); |
| PrefChangeRegistrar registrar; |
| registrar.Init(&prefs_); |
| registrar.Add(kName, observer_.GetCallback()); |
| |
| EXPECT_CALL(observer_, OnPreferenceChanged(_)).Times(0); |
| prefs_.RemoveUserPref(kName); |
| Mock::VerifyAndClearExpectations(&observer_); |
| |
| base::ListValue new_value; |
| new_value.AppendString(kValue); |
| observer_.Expect(kName, &new_value); |
| prefs_.Set(kName, new_value); |
| Mock::VerifyAndClearExpectations(&observer_); |
| |
| EXPECT_CALL(observer_, OnPreferenceChanged(_)).Times(0); |
| prefs_.Set(kName, new_value); |
| Mock::VerifyAndClearExpectations(&observer_); |
| |
| base::ListValue empty; |
| observer_.Expect(kName, &empty); |
| prefs_.Set(kName, empty); |
| Mock::VerifyAndClearExpectations(&observer_); |
| } |
| |
| class PrefValueStoreChangeTest : public testing::Test { |
| protected: |
| PrefValueStoreChangeTest() |
| : user_pref_store_(base::MakeRefCounted<TestingPrefStore>()), |
| pref_registry_(base::MakeRefCounted<PrefRegistrySimple>()) {} |
| |
| ~PrefValueStoreChangeTest() override = default; |
| |
| void SetUp() override { |
| auto pref_notifier = std::make_unique<PrefNotifierImpl>(); |
| auto pref_value_store = std::make_unique<PrefValueStore>( |
| nullptr /* managed_prefs */, nullptr /* supervised_user_prefs */, |
| nullptr /* extension_prefs */, new TestingPrefStore(), |
| user_pref_store_.get(), nullptr /* recommended_prefs */, |
| pref_registry_->defaults().get(), pref_notifier.get()); |
| pref_service_ = std::make_unique<PrefService>( |
| std::move(pref_notifier), std::move(pref_value_store), user_pref_store_, |
| pref_registry_, base::DoNothing(), false); |
| pref_registry_->RegisterIntegerPref(kManagedPref, 1); |
| pref_registry_->RegisterIntegerPref(kRecommendedPref, 2); |
| pref_registry_->RegisterIntegerPref(kSupervisedPref, 3); |
| } |
| |
| std::unique_ptr<PrefService> pref_service_; |
| scoped_refptr<TestingPrefStore> user_pref_store_; |
| scoped_refptr<PrefRegistrySimple> pref_registry_; |
| }; |
| |
| // Check that value from the new PrefValueStore will be correctly retrieved. |
| TEST_F(PrefValueStoreChangeTest, ChangePrefValueStore) { |
| const PrefService::Preference* preference = |
| pref_service_->FindPreference(kManagedPref); |
| EXPECT_TRUE(preference->IsDefaultValue()); |
| EXPECT_EQ(base::Value(1), *(preference->GetValue())); |
| const PrefService::Preference* supervised = |
| pref_service_->FindPreference(kSupervisedPref); |
| EXPECT_TRUE(supervised->IsDefaultValue()); |
| EXPECT_EQ(base::Value(3), *(supervised->GetValue())); |
| const PrefService::Preference* recommended = |
| pref_service_->FindPreference(kRecommendedPref); |
| EXPECT_TRUE(recommended->IsDefaultValue()); |
| EXPECT_EQ(base::Value(2), *(recommended->GetValue())); |
| |
| user_pref_store_->SetInteger(kManagedPref, 10); |
| EXPECT_TRUE(preference->IsUserControlled()); |
| ASSERT_EQ(base::Value(10), *(preference->GetValue())); |
| |
| scoped_refptr<TestingPrefStore> managed_pref_store = |
| base::MakeRefCounted<TestingPrefStore>(); |
| pref_service_->ChangePrefValueStore( |
| managed_pref_store.get(), nullptr /* supervised_user_prefs */, |
| nullptr /* extension_prefs */, nullptr /* recommended_prefs */); |
| EXPECT_TRUE(preference->IsUserControlled()); |
| ASSERT_EQ(base::Value(10), *(preference->GetValue())); |
| |
| // Test setting a managed pref after overriding the managed PrefStore. |
| managed_pref_store->SetInteger(kManagedPref, 20); |
| EXPECT_TRUE(preference->IsManaged()); |
| ASSERT_EQ(base::Value(20), *(preference->GetValue())); |
| |
| // Test overriding the supervised and recommended PrefStore with already set |
| // prefs. |
| scoped_refptr<TestingPrefStore> supervised_pref_store = |
| base::MakeRefCounted<TestingPrefStore>(); |
| scoped_refptr<TestingPrefStore> recommened_pref_store = |
| base::MakeRefCounted<TestingPrefStore>(); |
| supervised_pref_store->SetInteger(kManagedPref, 30); |
| supervised_pref_store->SetInteger(kSupervisedPref, 31); |
| recommened_pref_store->SetInteger(kManagedPref, 40); |
| recommened_pref_store->SetInteger(kRecommendedPref, 41); |
| pref_service_->ChangePrefValueStore( |
| nullptr /* managed_prefs */, supervised_pref_store.get(), |
| nullptr /* extension_prefs */, recommened_pref_store.get()); |
| EXPECT_TRUE(preference->IsManaged()); |
| ASSERT_EQ(base::Value(20), *(preference->GetValue())); |
| EXPECT_TRUE(supervised->IsManagedByCustodian()); |
| EXPECT_EQ(base::Value(31), *(supervised->GetValue())); |
| EXPECT_TRUE(recommended->IsRecommended()); |
| EXPECT_EQ(base::Value(41), *(recommended->GetValue())); |
| } |
| |
| // Tests that PrefChangeRegistrar works after PrefValueStore is changed. |
| TEST_F(PrefValueStoreChangeTest, PrefChangeRegistrar) { |
| MockPrefChangeCallback obs(pref_service_.get()); |
| PrefChangeRegistrar registrar; |
| registrar.Init(pref_service_.get()); |
| registrar.Add(kManagedPref, obs.GetCallback()); |
| registrar.Add(kSupervisedPref, obs.GetCallback()); |
| registrar.Add(kRecommendedPref, obs.GetCallback()); |
| |
| base::Value expected_value(10); |
| obs.Expect(kManagedPref, &expected_value); |
| user_pref_store_->SetInteger(kManagedPref, 10); |
| Mock::VerifyAndClearExpectations(&obs); |
| expected_value = base::Value(11); |
| obs.Expect(kRecommendedPref, &expected_value); |
| user_pref_store_->SetInteger(kRecommendedPref, 11); |
| Mock::VerifyAndClearExpectations(&obs); |
| |
| // Test overriding the managed and supervised PrefStore with already set |
| // prefs. |
| scoped_refptr<TestingPrefStore> managed_pref_store = |
| base::MakeRefCounted<TestingPrefStore>(); |
| scoped_refptr<TestingPrefStore> supervised_pref_store = |
| base::MakeRefCounted<TestingPrefStore>(); |
| // Update |kManagedPref| before changing the PrefValueStore, the |
| // PrefChangeRegistrar should get notified on |kManagedPref| as its value |
| // changes. |
| managed_pref_store->SetInteger(kManagedPref, 20); |
| // Due to store precedence, the value of |kRecommendedPref| will not be |
| // changed so PrefChangeRegistrar will not be notified. |
| managed_pref_store->SetInteger(kRecommendedPref, 11); |
| supervised_pref_store->SetInteger(kManagedPref, 30); |
| supervised_pref_store->SetInteger(kRecommendedPref, 21); |
| expected_value = base::Value(20); |
| obs.Expect(kManagedPref, &expected_value); |
| pref_service_->ChangePrefValueStore( |
| managed_pref_store.get(), supervised_pref_store.get(), |
| nullptr /* extension_prefs */, nullptr /* recommended_prefs */); |
| Mock::VerifyAndClearExpectations(&obs); |
| |
| // Update a pref value after PrefValueStore change, it should also work. |
| expected_value = base::Value(31); |
| obs.Expect(kSupervisedPref, &expected_value); |
| supervised_pref_store->SetInteger(kSupervisedPref, 31); |
| Mock::VerifyAndClearExpectations(&obs); |
| } |