// 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/macros.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 < arraysize(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);
}
