// 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/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,
                                     std::make_unique<base::DictionaryValue>(),
                                     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);
}
