// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/themes/theme_syncable_service.h"

#include <memory>
#include <optional>

#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/functional/bind.h"
#include "base/json/json_string_value_serializer.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/no_destructor.h"
#include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/values_test_util.h"
#include "base/time/time.h"
#include "base/values.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_service_test_base.h"
#include "chrome/browser/extensions/test_extension_system.h"
#include "chrome/browser/prefs/browser_prefs.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search/background/ntp_custom_background_service_constants.h"
#include "chrome/browser/themes/test/theme_service_changed_waiter.h"
#include "chrome/browser/themes/theme_helper.h"
#include "chrome/browser/themes/theme_service.h"
#include "chrome/browser/themes/theme_service_factory.h"
#include "chrome/browser/themes/theme_service_utils.h"
#include "chrome/common/extensions/extension_test_util.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/testing_profile.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/sync/base/client_tag_hash.h"
#include "components/sync/base/features.h"
#include "components/sync/model/sync_change.h"
#include "components/sync/protocol/entity_specifics.pb.h"
#include "components/sync/protocol/proto_value_conversions.h"
#include "components/sync/protocol/theme_specifics.pb.h"
#include "components/sync/test/fake_sync_change_processor.h"
#include "components/sync/test/sync_change_processor_wrapper_for_test.h"
#include "components/sync_preferences/pref_service_syncable.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "content/public/test/browser_task_environment.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/extension.h"
#include "extensions/common/manifest_constants.h"
#include "extensions/common/manifest_url_handlers.h"
#include "extensions/common/permissions/api_permission_set.h"
#include "extensions/common/permissions/permission_set.h"
#include "testing/gtest/include/gtest/gtest.h"

#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "chrome/browser/ash/login/users/chrome_user_manager_impl.h"
#include "chrome/browser/ash/settings/scoped_cros_settings_test_helper.h"
#include "components/user_manager/scoped_user_manager.h"
#endif

using std::string;

namespace {

static const char kCustomThemeName[] = "name";
static const char kCustomThemeUrl[] = "http://update.url/foo";

#if BUILDFLAG(IS_WIN)
const base::FilePath::CharType kExtensionFilePath[] =
    FILE_PATH_LITERAL("c:\\foo");
#elif BUILDFLAG(IS_POSIX)
const base::FilePath::CharType kExtensionFilePath[] = FILE_PATH_LITERAL("/oo");
#else
#error "Unknown platform"
#endif

constexpr char kTestUrl[] = "https://www.foo.com";

MATCHER_P2(DictionaryValuePtrHas, key, value, "") {
  return arg && arg->is_dict() &&
         base::test::DictionaryHasValue(key, base::Value(value))
             .Matches(arg->GetDict());
}

const ThemeHelper& GetThemeHelper() {
  static base::NoDestructor<std::unique_ptr<ThemeHelper>> theme_helper(
      std::make_unique<ThemeHelper>());
  return **theme_helper;
}

class FakeThemeService : public ThemeService {
 public:
  FakeThemeService() : ThemeService(nullptr, GetThemeHelper()) {}

  // ThemeService:
  void DoSetTheme(const extensions::Extension* extension,
                  bool suppress_infobar) override {
    is_dirty_ = true;
    theme_extension_ = extension;
    using_system_theme_ = false;
    using_default_theme_ = false;
    using_policy_theme_ = false;
    might_show_infobar_ = !suppress_infobar;
    color_ = 0;
  }

  void BuildAutogeneratedThemeFromColor(SkColor color) override {
    is_dirty_ = true;
    color_ = color;
    theme_extension_.reset();
    using_system_theme_ = false;
    using_default_theme_ = false;
    using_policy_theme_ = false;
  }

  void UseTheme(ui::SystemTheme system_theme) override {
    if (system_theme == ui::SystemTheme::kDefault) {
      UseDefaultTheme();
    } else {
      UseSystemTheme();
    }
  }

  void UseDefaultTheme() override {
    is_dirty_ = true;
    using_default_theme_ = true;
    using_system_theme_ = false;
    using_policy_theme_ = false;
    theme_extension_.reset();
    color_ = 0;
  }

  void UseSystemTheme() override {
    is_dirty_ = true;
    using_system_theme_ = true;
    using_default_theme_ = false;
    using_policy_theme_ = false;
    theme_extension_.reset();
    color_ = 0;
  }

  void BuildAutogeneratedPolicyTheme() override {
    is_dirty_ = true;
    color_ = SkColorSetRGB(100, 100, 0);
    theme_extension_.reset();
    using_system_theme_ = false;
    using_default_theme_ = false;
    using_policy_theme_ = true;
  }

  bool IsSystemThemeDistinctFromDefaultTheme() const override {
    return distinct_from_default_theme_;
  }

  void set_distinct_from_default_theme(bool is_distinct) {
    distinct_from_default_theme_ = is_distinct;
  }

  bool UsingDefaultTheme() const override { return using_default_theme_; }

  bool UsingSystemTheme() const override { return using_system_theme_; }

  bool UsingExtensionTheme() const override { return !!theme_extension_; }

  bool UsingAutogeneratedTheme() const override { return color_ != 0; }

  bool UsingPolicyTheme() const override { return using_policy_theme_; }

  string GetThemeID() const override {
    return UsingExtensionTheme() ? theme_extension_->id() : std::string();
  }

  SkColor GetAutogeneratedThemeColor() const override { return color_; }

  bool GetIsGrayscale() const override { return false; }

  ThemeService::BrowserColorScheme GetBrowserColorScheme() const override {
    return ThemeService::BrowserColorScheme::kSystem;
  }

  const extensions::Extension* theme_extension() const {
    return theme_extension_.get();
  }

  bool is_dirty() const { return is_dirty_; }

  void MarkClean() { is_dirty_ = false; }

  bool might_show_infobar() const { return might_show_infobar_; }

 private:
  bool using_system_theme_ = false;
  bool using_default_theme_ = false;
  bool using_policy_theme_ = false;
  bool distinct_from_default_theme_ = false;
  scoped_refptr<const extensions::Extension> theme_extension_;
  bool is_dirty_ = false;
  bool might_show_infobar_ = false;
  SkColor color_;
};

scoped_refptr<extensions::Extension> MakeThemeExtension(
    const base::FilePath& extension_path,
    const string& name,
    extensions::mojom::ManifestLocation location,
    const string& update_url) {
  base::Value::Dict source;
  source.Set(extensions::manifest_keys::kName, name);
  source.Set(extensions::manifest_keys::kTheme, base::Value::Dict());
  source.Set(extensions::manifest_keys::kUpdateURL, update_url);
  source.Set(extensions::manifest_keys::kVersion, "0.0.0.0");
  string error;
  scoped_refptr<extensions::Extension> extension =
      extensions::Extension::Create(extension_path, location, source,
                                    extensions::Extension::NO_FLAGS, &error);
  EXPECT_TRUE(extension.get());
  EXPECT_EQ("", error);
  return extension;
}

syncer::SyncDataList MakeThemeDataList(
    const sync_pb::ThemeSpecifics& theme_specifics) {
  syncer::SyncDataList list;
  sync_pb::EntitySpecifics entity_specifics;
  entity_specifics.mutable_theme()->CopyFrom(theme_specifics);
  list.push_back(syncer::SyncData::CreateLocalData(
      ThemeSyncableService::kSyncEntityClientTag,
      ThemeSyncableService::kSyncEntityTitle, entity_specifics));
  return list;
}

syncer::SyncChangeList MakeThemeChangeList(
    const sync_pb::ThemeSpecifics& theme_specifics) {
  syncer::SyncChangeList change_list;
  sync_pb::EntitySpecifics entity_specifics;
  entity_specifics.mutable_theme()->CopyFrom(theme_specifics);
  change_list.push_back(syncer::SyncChange(
      FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
      syncer::SyncData::CreateRemoteData(
          entity_specifics, syncer::ClientTagHash::FromHashed("unused"))));
  return change_list;
}

}  // namespace

// ThemeSyncableServiceTest ----------------------------------------------------

class ThemeSyncableServiceTest : public testing::Test,
                                 public ThemeSyncableService::Observer {
 protected:
  ThemeSyncableServiceTest() : fake_theme_service_(nullptr) {}

  ~ThemeSyncableServiceTest() override {}

  void SetUp() override {
    // Setting a matching update URL is necessary to make the test theme
    // considered syncable.
    extension_test_util::SetGalleryUpdateURL(GURL(kCustomThemeUrl));

    TestingProfile::Builder builder;
    builder.AddTestingFactory(
        ThemeServiceFactory::GetInstance(),
        base::BindRepeating([](content::BrowserContext* context)
                                -> std::unique_ptr<KeyedService> {
          return std::make_unique<FakeThemeService>();
        }));
    profile_ = builder.Build();
    fake_theme_service_ = static_cast<FakeThemeService*>(
        ThemeServiceFactory::GetForProfile(profile_.get()));
    theme_sync_service_ = std::make_unique<ThemeSyncableService>(
        profile_.get(), fake_theme_service_);
    theme_sync_service_->AddObserver(this);
    fake_change_processor_ =
        std::make_unique<syncer::FakeSyncChangeProcessor>();
    SetUpExtension();
  }

  void TearDown() override {
    theme_sync_service_.reset();
    profile_.reset();
    base::RunLoop().RunUntilIdle();
  }

  void SetUpExtension() {
    base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
    extensions::TestExtensionSystem* test_ext_system =
        static_cast<extensions::TestExtensionSystem*>(
            extensions::ExtensionSystem::Get(profile_.get()));
    extensions::ExtensionService* service =
        test_ext_system->CreateExtensionService(
            &command_line, base::FilePath(kExtensionFilePath), false);
    EXPECT_TRUE(service->extensions_enabled());
    service->Init();
    base::RunLoop().RunUntilIdle();

    // Create and add custom theme extension so the ThemeSyncableService can
    // find it.
    theme_extension_ =
        MakeThemeExtension(base::FilePath(kExtensionFilePath), kCustomThemeName,
                           GetThemeLocation(), kCustomThemeUrl);
    extensions::ExtensionPrefs::Get(profile_.get())
        ->AddGrantedPermissions(theme_extension_->id(),
                                extensions::PermissionSet());
    service->AddExtension(theme_extension_.get());
    extensions::ExtensionRegistry* registry =
        extensions::ExtensionRegistry::Get(profile_.get());
    ASSERT_EQ(1u, registry->enabled_extensions().size());
  }

  // Overridden in PolicyInstalledThemeTest below.
  virtual extensions::mojom::ManifestLocation GetThemeLocation() {
    return extensions::mojom::ManifestLocation::kInternal;
  }

  void OnThemeSyncStarted(ThemeSyncableService::ThemeSyncState state) override {
    state_ = state;
  }

  bool HasThemeSyncStarted() { return state_ != std::nullopt; }

  bool HasThemeSyncTriggeredExtensionInstallation() {
    return state_ && *state_ == ThemeSyncableService::ThemeSyncState::
                                    kWaitingForExtensionInstallation;
  }

  // Needed for setting up extension service.
  content::BrowserTaskEnvironment task_environment_;

#if BUILDFLAG(IS_CHROMEOS_ASH)
  ash::ScopedCrosSettingsTestHelper cros_settings_test_helper_;
  user_manager::ScopedUserManager test_user_manager_{
      ash::ChromeUserManagerImpl::CreateChromeUserManager()};
#endif

  std::unique_ptr<TestingProfile> profile_;
  raw_ptr<FakeThemeService, DanglingUntriaged> fake_theme_service_;
  scoped_refptr<extensions::Extension> theme_extension_;
  std::unique_ptr<ThemeSyncableService> theme_sync_service_;
  std::unique_ptr<syncer::FakeSyncChangeProcessor> fake_change_processor_;
  std::optional<ThemeSyncableService::ThemeSyncState> state_;
};

TEST_F(ThemeSyncableServiceTest, AreThemeSpecificsEquivalent) {
  sync_pb::ThemeSpecifics a, b;
  EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, false));
  EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, true));

  // Custom vs. non-custom.

  a.set_use_custom_theme(true);
  EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, false));
  EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, true));

  a.set_use_custom_theme(false);
  b.set_use_custom_theme(true);
  EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, false));
  EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, true));

  // Custom theme equality for extensions.
  a.set_use_custom_theme(true);
  b.set_use_custom_theme(true);
  EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, false));
  EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, true));

  a.set_custom_theme_id("id");
  EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, false));
  EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, true));

  b.set_custom_theme_id("id");
  EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, false));
  EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, true));

  a.set_custom_theme_update_url("http://update.url");
  EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, false));
  EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, true));

  a.set_custom_theme_name("name");
  EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, false));
  EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, true));

  // Theme equality for autogenerated.
  a.set_use_custom_theme(true);
  b.set_use_custom_theme(false);
  b.mutable_autogenerated_color_theme()->set_color(SkColorSetRGB(0, 0, 0));
  EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, false));
  EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, true));

  b.set_use_custom_theme(true);
  b.clear_autogenerated_color_theme();
  a.set_use_custom_theme(false);
  a.mutable_autogenerated_color_theme()->set_color(SkColorSetRGB(0, 0, 0));
  EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, false));
  EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, true));

  b.set_use_custom_theme(false);
  b.mutable_autogenerated_color_theme()->set_color(SkColorSetRGB(0, 0, 100));
  a.mutable_autogenerated_color_theme()->set_color(SkColorSetRGB(0, 0, 100));
  EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, false));
  EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, true));

  b.mutable_autogenerated_color_theme()->set_color(SkColorSetRGB(0, 0, 200));
  EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, false));
  EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, true));

  // No theme equality.

  a.clear_autogenerated_color_theme();
  b.clear_autogenerated_color_theme();
  EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, false));
  EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, true));

  a.set_use_system_theme_by_default(true);
  EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, false));
  EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, true));

  b.set_use_system_theme_by_default(true);
  EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, false));
  EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, true));
}

TEST_F(ThemeSyncableServiceTest, SetCurrentThemeDefaultTheme) {
  // Set up theme service to use custom theme.
  fake_theme_service_->SetTheme(theme_extension_.get());

  std::optional<syncer::ModelError> error =
      theme_sync_service_->MergeDataAndStartSyncing(
          syncer::THEMES, MakeThemeDataList(sync_pb::ThemeSpecifics()),
          std::unique_ptr<syncer::SyncChangeProcessor>(
              new syncer::SyncChangeProcessorWrapperForTest(
                  fake_change_processor_.get())));
  EXPECT_TRUE(HasThemeSyncStarted());
  EXPECT_FALSE(error.has_value()) << error.value().message();
  EXPECT_FALSE(fake_theme_service_->UsingDefaultTheme());
  EXPECT_EQ(fake_theme_service_->theme_extension(), theme_extension_.get());
}

TEST_F(ThemeSyncableServiceTest, SetCurrentThemeSystemTheme) {
  sync_pb::ThemeSpecifics theme_specifics;
  theme_specifics.set_use_system_theme_by_default(true);

  // Set up theme service to use custom theme.
  fake_theme_service_->SetTheme(theme_extension_.get());
  std::optional<syncer::ModelError> error =
      theme_sync_service_->MergeDataAndStartSyncing(
          syncer::THEMES, MakeThemeDataList(theme_specifics),
          std::unique_ptr<syncer::SyncChangeProcessor>(
              new syncer::SyncChangeProcessorWrapperForTest(
                  fake_change_processor_.get())));
  EXPECT_TRUE(HasThemeSyncStarted());
  EXPECT_FALSE(error.has_value()) << error.value().message();
  EXPECT_FALSE(fake_theme_service_->UsingSystemTheme());
  EXPECT_EQ(fake_theme_service_->theme_extension(), theme_extension_.get());
}

TEST_F(ThemeSyncableServiceTest, SetCurrentThemeCustomTheme_Extension) {
  sync_pb::ThemeSpecifics theme_specifics;
  theme_specifics.set_use_custom_theme(true);
  theme_specifics.set_custom_theme_id(theme_extension_->id());
  theme_specifics.set_custom_theme_name(kCustomThemeName);
  theme_specifics.set_custom_theme_update_url(kCustomThemeUrl);

  // Set up theme service to use default theme.
  fake_theme_service_->UseDefaultTheme();
  std::optional<syncer::ModelError> error =
      theme_sync_service_->MergeDataAndStartSyncing(
          syncer::THEMES, MakeThemeDataList(theme_specifics),
          std::unique_ptr<syncer::SyncChangeProcessor>(
              new syncer::SyncChangeProcessorWrapperForTest(
                  fake_change_processor_.get())));
  EXPECT_TRUE(HasThemeSyncStarted());
  EXPECT_FALSE(HasThemeSyncTriggeredExtensionInstallation());
  EXPECT_FALSE(error.has_value()) << error.value().message();
  EXPECT_EQ(fake_theme_service_->theme_extension(), theme_extension_.get());
}

TEST_F(ThemeSyncableServiceTest, SetCurrentThemeCustomTheme_Extension_Install) {
  sync_pb::ThemeSpecifics theme_specifics;
  theme_specifics.set_use_custom_theme(true);
  // Use an arbitrary id (such an extension is not installed, yet).
  theme_specifics.set_custom_theme_id("fake_extension_id");
  theme_specifics.set_custom_theme_name(kCustomThemeName);
  theme_specifics.set_custom_theme_update_url(kCustomThemeUrl);

  // Set up theme service to use default theme.
  fake_theme_service_->UseDefaultTheme();
  std::optional<syncer::ModelError> error =
      theme_sync_service_->MergeDataAndStartSyncing(
          syncer::THEMES, MakeThemeDataList(theme_specifics),
          std::unique_ptr<syncer::SyncChangeProcessor>(
              new syncer::SyncChangeProcessorWrapperForTest(
                  fake_change_processor_.get())));
  EXPECT_TRUE(HasThemeSyncStarted());
  EXPECT_FALSE(error.has_value()) << error.value().message();
  // The theme is not installed yet and thus, the default theme is still used.
  EXPECT_TRUE(fake_theme_service_->UsingDefaultTheme());
  EXPECT_TRUE(HasThemeSyncTriggeredExtensionInstallation());
  EXPECT_TRUE(extensions::ExtensionSystem::Get(profile_.get())
                  ->extension_service()
                  ->pending_extension_manager()
                  ->HasPendingExtensionFromSync());
}

TEST_F(ThemeSyncableServiceTest, SetCurrentThemeCustomTheme_Autogenerated) {
  sync_pb::ThemeSpecifics theme_specifics;
  theme_specifics.set_use_custom_theme(false);
  theme_specifics.mutable_autogenerated_color_theme()->set_color(
      SkColorSetRGB(0, 0, 100));

  // Set up theme service to use default theme.
  fake_theme_service_->UseDefaultTheme();
  std::optional<syncer::ModelError> error =
      theme_sync_service_->MergeDataAndStartSyncing(
          syncer::THEMES, MakeThemeDataList(theme_specifics),
          std::unique_ptr<syncer::SyncChangeProcessor>(
              new syncer::SyncChangeProcessorWrapperForTest(
                  fake_change_processor_.get())));
  EXPECT_TRUE(HasThemeSyncStarted());
  EXPECT_FALSE(error.has_value()) << error.value().message();
  EXPECT_EQ(fake_theme_service_->GetAutogeneratedThemeColor(),
            SkColorSetRGB(0, 0, 100));
}

TEST_F(ThemeSyncableServiceTest, DontResetThemeWhenSpecificsAreEqual) {
  // Set up theme service to use default theme and expect no changes.
  fake_theme_service_->UseDefaultTheme();
  fake_theme_service_->MarkClean();
  std::optional<syncer::ModelError> error =
      theme_sync_service_->MergeDataAndStartSyncing(
          syncer::THEMES, MakeThemeDataList(sync_pb::ThemeSpecifics()),
          std::unique_ptr<syncer::SyncChangeProcessor>(
              new syncer::SyncChangeProcessorWrapperForTest(
                  fake_change_processor_.get())));
  EXPECT_TRUE(HasThemeSyncStarted());
  EXPECT_FALSE(error.has_value()) << error.value().message();
  EXPECT_FALSE(fake_theme_service_->is_dirty());
}

TEST_F(ThemeSyncableServiceTest, UpdateThemeSpecifics_CurrentTheme_Extension) {
  // Set up theme service to use custom theme.
  fake_theme_service_->SetTheme(theme_extension_.get());

  std::optional<syncer::ModelError> error =
      theme_sync_service_->MergeDataAndStartSyncing(
          syncer::THEMES, syncer::SyncDataList(),
          std::unique_ptr<syncer::SyncChangeProcessor>(
              new syncer::SyncChangeProcessorWrapperForTest(
                  fake_change_processor_.get())));
  EXPECT_FALSE(error.has_value()) << error.value().message();
  const syncer::SyncChangeList& changes = fake_change_processor_->changes();
  ASSERT_EQ(1u, changes.size());
  EXPECT_EQ(syncer::SyncChange::ACTION_ADD, changes[0].change_type());
  EXPECT_EQ(syncer::THEMES, changes[0].sync_data().GetDataType());

  const sync_pb::ThemeSpecifics& theme_specifics =
      changes[0].sync_data().GetSpecifics().theme();
  EXPECT_TRUE(theme_specifics.use_custom_theme());
  EXPECT_EQ(theme_extension_->id(), theme_specifics.custom_theme_id());
  EXPECT_EQ(theme_extension_->name(), theme_specifics.custom_theme_name());
  EXPECT_EQ(
      extensions::ManifestURL::GetUpdateURL(theme_extension_.get()).spec(),
      theme_specifics.custom_theme_update_url());
}

TEST_F(ThemeSyncableServiceTest,
       UpdateThemeSpecifics_CurrentTheme_Autogenerated) {
  // Set up theme service to use autogenerated theme.
  fake_theme_service_->BuildAutogeneratedThemeFromColor(
      SkColorSetRGB(0, 0, 100));

  std::optional<syncer::ModelError> error =
      theme_sync_service_->MergeDataAndStartSyncing(
          syncer::THEMES, syncer::SyncDataList(),
          std::unique_ptr<syncer::SyncChangeProcessor>(
              new syncer::SyncChangeProcessorWrapperForTest(
                  fake_change_processor_.get())));
  EXPECT_FALSE(error.has_value()) << error.value().message();
  const syncer::SyncChangeList& changes = fake_change_processor_->changes();
  ASSERT_EQ(1u, changes.size());
  EXPECT_EQ(syncer::SyncChange::ACTION_ADD, changes[0].change_type());
  EXPECT_EQ(syncer::THEMES, changes[0].sync_data().GetDataType());

  const sync_pb::ThemeSpecifics& theme_specifics =
      changes[0].sync_data().GetSpecifics().theme();
  EXPECT_FALSE(theme_specifics.use_custom_theme());
  EXPECT_EQ(fake_theme_service_->GetAutogeneratedThemeColor(),
            theme_specifics.autogenerated_color_theme().color());
}

TEST_F(ThemeSyncableServiceTest, UpdateThemeSpecifics_CurrentTheme_Policy) {
  // Set up theme service to use policy theme.
  fake_theme_service_->BuildAutogeneratedPolicyTheme();

  std::optional<syncer::ModelError> error =
      theme_sync_service_->MergeDataAndStartSyncing(
          syncer::THEMES, syncer::SyncDataList(),
          std::unique_ptr<syncer::SyncChangeProcessor>(
              new syncer::SyncChangeProcessorWrapperForTest(
                  fake_change_processor_.get())));
  EXPECT_FALSE(error.has_value()) << error.value().message();
  // Applying policy theme doesn't trigger sync changes.
  const syncer::SyncChangeList& changes = fake_change_processor_->changes();
  ASSERT_EQ(0u, changes.size());
}

TEST_F(ThemeSyncableServiceTest, GetAllSyncDataForTesting_Extension) {
  // Set up theme service to use custom theme.
  fake_theme_service_->SetTheme(theme_extension_.get());

  syncer::SyncDataList data_list =
      theme_sync_service_->GetAllSyncDataForTesting(syncer::THEMES);

  ASSERT_EQ(1u, data_list.size());
  const sync_pb::ThemeSpecifics& theme_specifics =
      data_list[0].GetSpecifics().theme();
  EXPECT_TRUE(theme_specifics.use_custom_theme());
  EXPECT_EQ(theme_extension_->id(), theme_specifics.custom_theme_id());
  EXPECT_EQ(theme_extension_->name(), theme_specifics.custom_theme_name());
  EXPECT_EQ(
      extensions::ManifestURL::GetUpdateURL(theme_extension_.get()).spec(),
      theme_specifics.custom_theme_update_url());
}

TEST_F(ThemeSyncableServiceTest, GetAllSyncDataForTesting_Autogenerated) {
  // Set up theme service to use autogenerated theme.
  fake_theme_service_->BuildAutogeneratedThemeFromColor(
      SkColorSetRGB(0, 0, 100));

  syncer::SyncDataList data_list =
      theme_sync_service_->GetAllSyncDataForTesting(syncer::THEMES);

  ASSERT_EQ(1u, data_list.size());
  const sync_pb::ThemeSpecifics& theme_specifics =
      data_list[0].GetSpecifics().theme();
  EXPECT_FALSE(theme_specifics.use_custom_theme());
  EXPECT_EQ(fake_theme_service_->GetAutogeneratedThemeColor(),
            theme_specifics.autogenerated_color_theme().color());
}

TEST_F(ThemeSyncableServiceTest, GetAllSyncDataForTesting_Policy) {
  // Set up theme service to use policy theme.
  fake_theme_service_->BuildAutogeneratedPolicyTheme();

  // Themes applied through policy shouldn't be synced.
  syncer::SyncDataList data_list =
      theme_sync_service_->GetAllSyncDataForTesting(syncer::THEMES);
  ASSERT_EQ(0u, data_list.size());
}

TEST_F(ThemeSyncableServiceTest, ProcessSyncThemeChange_Extension) {
  // Set up theme service to use default theme.
  fake_theme_service_->UseDefaultTheme();
  fake_theme_service_->MarkClean();

  // Start syncing.
  std::optional<syncer::ModelError> error =
      theme_sync_service_->MergeDataAndStartSyncing(
          syncer::THEMES, MakeThemeDataList(sync_pb::ThemeSpecifics()),
          std::unique_ptr<syncer::SyncChangeProcessor>(
              new syncer::SyncChangeProcessorWrapperForTest(
                  fake_change_processor_.get())));
  EXPECT_FALSE(error.has_value()) << error.value().message();
  // Don't expect theme change initially because specifics are equal.
  EXPECT_FALSE(fake_theme_service_->is_dirty());

  // Change specifics to use custom theme and update.
  sync_pb::ThemeSpecifics theme_specifics;
  theme_specifics.set_use_custom_theme(true);
  theme_specifics.set_custom_theme_id(theme_extension_->id());
  theme_specifics.set_custom_theme_name(kCustomThemeName);
  theme_specifics.set_custom_theme_update_url(kCustomThemeUrl);
  sync_pb::EntitySpecifics entity_specifics;
  entity_specifics.mutable_theme()->CopyFrom(theme_specifics);
  syncer::SyncChangeList change_list;
  change_list.push_back(syncer::SyncChange(
      FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
      syncer::SyncData::CreateRemoteData(
          entity_specifics, syncer::ClientTagHash::FromHashed("unused"))));
  std::optional<syncer::ModelError> process_error =
      theme_sync_service_->ProcessSyncChanges(FROM_HERE, change_list);
  EXPECT_FALSE(process_error.has_value()) << process_error.value().message();
  EXPECT_EQ(fake_theme_service_->theme_extension(), theme_extension_.get());
  // Don't show an infobar for theme installation. Regression test for
  // crbug.com/731688
  EXPECT_FALSE(fake_theme_service_->might_show_infobar());
}

TEST_F(ThemeSyncableServiceTest, ProcessSyncThemeChange_Autogenerated) {
  // Set up theme service to use default theme.
  fake_theme_service_->UseDefaultTheme();
  fake_theme_service_->MarkClean();

  // Start syncing.
  std::optional<syncer::ModelError> error =
      theme_sync_service_->MergeDataAndStartSyncing(
          syncer::THEMES, MakeThemeDataList(sync_pb::ThemeSpecifics()),
          std::unique_ptr<syncer::SyncChangeProcessor>(
              new syncer::SyncChangeProcessorWrapperForTest(
                  fake_change_processor_.get())));
  EXPECT_FALSE(error.has_value()) << error.value().message();
  // Don't expect theme change initially because specifics are equal.
  EXPECT_FALSE(fake_theme_service_->is_dirty());

  // Change specifics to use custom theme and update.
  sync_pb::ThemeSpecifics theme_specifics;
  theme_specifics.set_use_custom_theme(false);
  theme_specifics.mutable_autogenerated_color_theme()->set_color(
      SkColorSetRGB(0, 0, 100));
  sync_pb::EntitySpecifics entity_specifics;
  entity_specifics.mutable_theme()->CopyFrom(theme_specifics);
  syncer::SyncChangeList change_list;
  change_list.push_back(syncer::SyncChange(
      FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
      syncer::SyncData::CreateRemoteData(
          entity_specifics, syncer::ClientTagHash::FromHashed("unused"))));
  std::optional<syncer::ModelError> process_error =
      theme_sync_service_->ProcessSyncChanges(FROM_HERE, change_list);
  EXPECT_FALSE(process_error.has_value()) << process_error.value().message();
  EXPECT_EQ(fake_theme_service_->GetAutogeneratedThemeColor(),
            SkColorSetRGB(0, 0, 100));
}

TEST_F(ThemeSyncableServiceTest, OnThemeChangeByUser_Extension) {
  // Set up theme service to use default theme.
  fake_theme_service_->UseDefaultTheme();

  // Start syncing.
  std::optional<syncer::ModelError> error =
      theme_sync_service_->MergeDataAndStartSyncing(
          syncer::THEMES, MakeThemeDataList(sync_pb::ThemeSpecifics()),
          std::unique_ptr<syncer::SyncChangeProcessor>(
              new syncer::SyncChangeProcessorWrapperForTest(
                  fake_change_processor_.get())));
  EXPECT_FALSE(error.has_value()) << error.value().message();
  const syncer::SyncChangeList& changes = fake_change_processor_->changes();
  EXPECT_EQ(0u, changes.size());

  // Change current theme to custom theme and notify theme_sync_service_.
  fake_theme_service_->SetTheme(theme_extension_.get());
  theme_sync_service_->OnThemeChanged();
  EXPECT_EQ(1u, changes.size());
  const sync_pb::ThemeSpecifics& change_specifics =
      changes[0].sync_data().GetSpecifics().theme();
  EXPECT_TRUE(change_specifics.use_custom_theme());
  EXPECT_EQ(theme_extension_->id(), change_specifics.custom_theme_id());
  EXPECT_EQ(theme_extension_->name(), change_specifics.custom_theme_name());
  EXPECT_EQ(
      extensions::ManifestURL::GetUpdateURL(theme_extension_.get()).spec(),
      change_specifics.custom_theme_update_url());
}

TEST_F(ThemeSyncableServiceTest, OnThemeChangeByUser_Autogenerated) {
  // Set up theme service to use default theme.
  fake_theme_service_->UseDefaultTheme();

  // Start syncing.
  std::optional<syncer::ModelError> error =
      theme_sync_service_->MergeDataAndStartSyncing(
          syncer::THEMES, MakeThemeDataList(sync_pb::ThemeSpecifics()),
          std::unique_ptr<syncer::SyncChangeProcessor>(
              new syncer::SyncChangeProcessorWrapperForTest(
                  fake_change_processor_.get())));
  EXPECT_FALSE(error.has_value()) << error.value().message();
  const syncer::SyncChangeList& changes = fake_change_processor_->changes();
  EXPECT_EQ(0u, changes.size());

  // Change current theme to custom theme and notify theme_sync_service_.
  fake_theme_service_->BuildAutogeneratedThemeFromColor(
      SkColorSetRGB(0, 0, 100));
  theme_sync_service_->OnThemeChanged();
  EXPECT_EQ(1u, changes.size());
  const sync_pb::ThemeSpecifics& change_specifics =
      changes[0].sync_data().GetSpecifics().theme();
  EXPECT_FALSE(change_specifics.use_custom_theme());
  EXPECT_EQ(fake_theme_service_->GetAutogeneratedThemeColor(),
            SkColorSetRGB(0, 0, 100));
}

TEST_F(ThemeSyncableServiceTest, StopSync) {
  // Set up theme service to use default theme.
  fake_theme_service_->UseDefaultTheme();

  // Start syncing.
  std::optional<syncer::ModelError> merge_error =
      theme_sync_service_->MergeDataAndStartSyncing(
          syncer::THEMES, MakeThemeDataList(sync_pb::ThemeSpecifics()),
          std::unique_ptr<syncer::SyncChangeProcessor>(
              new syncer::SyncChangeProcessorWrapperForTest(
                  fake_change_processor_.get())));
  EXPECT_FALSE(merge_error.has_value()) << merge_error.value().message();
  const syncer::SyncChangeList& changes = fake_change_processor_->changes();
  EXPECT_EQ(0u, changes.size());

  // Stop syncing.
  theme_sync_service_->StopSyncing(syncer::THEMES);

  // Change current theme to custom theme and notify theme_sync_service_.
  // No change is output because sync has stopped.
  fake_theme_service_->SetTheme(theme_extension_.get());
  theme_sync_service_->OnThemeChanged();
  EXPECT_EQ(0u, changes.size());

  // ProcessSyncChanges() should return error when sync has stopped.
  std::optional<syncer::ModelError> process_error =
      theme_sync_service_->ProcessSyncChanges(FROM_HERE, changes);
  EXPECT_TRUE(process_error.has_value());
  EXPECT_EQ("Theme syncable service is not started.",
            process_error.value().message());
}

TEST_F(ThemeSyncableServiceTest, RestoreSystemThemeBitWhenChangeToCustomTheme) {
  // Initialize to use system theme.
  fake_theme_service_->UseDefaultTheme();
  sync_pb::ThemeSpecifics theme_specifics;
  theme_specifics.set_use_system_theme_by_default(true);
  std::optional<syncer::ModelError> error =
      theme_sync_service_->MergeDataAndStartSyncing(
          syncer::THEMES, MakeThemeDataList(theme_specifics),
          std::unique_ptr<syncer::SyncChangeProcessor>(
              new syncer::SyncChangeProcessorWrapperForTest(
                  fake_change_processor_.get())));

  // Change to custom theme and notify theme_sync_service_.
  // use_system_theme_by_default bit should be preserved.
  fake_theme_service_->SetTheme(theme_extension_.get());
  theme_sync_service_->OnThemeChanged();
  const syncer::SyncChangeList& changes = fake_change_processor_->changes();
  EXPECT_EQ(1u, changes.size());
  const sync_pb::ThemeSpecifics& change_specifics =
      changes[0].sync_data().GetSpecifics().theme();
  EXPECT_TRUE(change_specifics.use_system_theme_by_default());
}

TEST_F(ThemeSyncableServiceTest, DistinctSystemTheme) {
  fake_theme_service_->set_distinct_from_default_theme(true);

  // Initialize to use native theme.
  fake_theme_service_->UseSystemTheme();
  fake_theme_service_->MarkClean();
  sync_pb::ThemeSpecifics theme_specifics;
  theme_specifics.set_use_system_theme_by_default(true);
  std::optional<syncer::ModelError> error =
      theme_sync_service_->MergeDataAndStartSyncing(
          syncer::THEMES, MakeThemeDataList(theme_specifics),
          std::unique_ptr<syncer::SyncChangeProcessor>(
              new syncer::SyncChangeProcessorWrapperForTest(
                  fake_change_processor_.get())));
  EXPECT_FALSE(fake_theme_service_->is_dirty());

  // Change to default theme and notify theme_sync_service_.
  // use_system_theme_by_default bit should be false.
  fake_theme_service_->UseDefaultTheme();
  theme_sync_service_->OnThemeChanged();
  syncer::SyncChangeList& changes = fake_change_processor_->changes();
  EXPECT_EQ(1u, changes.size());
  EXPECT_FALSE(changes[0]
                   .sync_data()
                   .GetSpecifics()
                   .theme()
                   .use_system_theme_by_default());

  // Change to native theme and notify theme_sync_service_.
  // use_system_theme_by_default bit should be true.
  changes.clear();
  fake_theme_service_->UseSystemTheme();
  theme_sync_service_->OnThemeChanged();
  EXPECT_EQ(1u, changes.size());
  EXPECT_TRUE(changes[0]
                  .sync_data()
                  .GetSpecifics()
                  .theme()
                  .use_system_theme_by_default());
}

TEST_F(ThemeSyncableServiceTest, SystemThemeSameAsDefaultTheme) {
  fake_theme_service_->set_distinct_from_default_theme(false);

  // Set up theme service to use default theme.
  fake_theme_service_->UseDefaultTheme();

  // Initialize to use custom theme with use_system_theme_by_default set true.
  sync_pb::ThemeSpecifics theme_specifics;
  theme_specifics.set_use_custom_theme(true);
  theme_specifics.set_custom_theme_id(theme_extension_->id());
  theme_specifics.set_custom_theme_name(kCustomThemeName);
  theme_specifics.set_custom_theme_update_url(kCustomThemeUrl);
  theme_specifics.set_use_system_theme_by_default(true);
  std::optional<syncer::ModelError> error =
      theme_sync_service_->MergeDataAndStartSyncing(
          syncer::THEMES, MakeThemeDataList(theme_specifics),
          std::unique_ptr<syncer::SyncChangeProcessor>(
              new syncer::SyncChangeProcessorWrapperForTest(
                  fake_change_processor_.get())));
  EXPECT_EQ(fake_theme_service_->theme_extension(), theme_extension_.get());

  // Change to default theme and notify theme_sync_service_.
  // use_system_theme_by_default bit should be preserved.
  fake_theme_service_->UseDefaultTheme();
  theme_sync_service_->OnThemeChanged();
  const syncer::SyncChangeList& changes = fake_change_processor_->changes();
  EXPECT_EQ(1u, changes.size());
  const sync_pb::ThemeSpecifics& change_specifics =
      changes[0].sync_data().GetSpecifics().theme();
  EXPECT_FALSE(change_specifics.use_custom_theme());
  EXPECT_TRUE(change_specifics.use_system_theme_by_default());
}

TEST_F(ThemeSyncableServiceTest, GetThemePrefNameInMigrationIfFlagDisabled) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndDisableFeature(syncer::kMoveThemePrefsToSpecifics);

  // The syncing pref name is returned.
  EXPECT_EQ(GetThemePrefNameInMigration(ThemePrefInMigration::kUserColor),
            prefs::kUserColorDoNotUse);
}

TEST_F(ThemeSyncableServiceTest, GetThemePrefNameInMigrationIfFlagEnabled) {
  base::test::ScopedFeatureList feature_list(
      syncer::kMoveThemePrefsToSpecifics);

  // The new non-syncing pref is returned.
  EXPECT_EQ(GetThemePrefNameInMigration(ThemePrefInMigration::kUserColor),
            prefs::kNonSyncingUserColorDoNotUse);
}

// PolicyInstalledThemeTest ----------------------------------------------------

class PolicyInstalledThemeTest : public ThemeSyncableServiceTest {
  extensions::mojom::ManifestLocation GetThemeLocation() override {
    return extensions::mojom::ManifestLocation::kExternalPolicyDownload;
  }
};

TEST_F(PolicyInstalledThemeTest, InstallThemeByPolicy) {
  // Set up theme service to use custom theme that was installed by policy.
  fake_theme_service_->SetTheme(theme_extension_.get());

  syncer::SyncDataList data_list =
      theme_sync_service_->GetAllSyncDataForTesting(syncer::THEMES);

  ASSERT_EQ(0u, data_list.size());
}

// RealThemeSyncableServiceTest ------------------------------------------------

// Uses the real `ThemeService` impl instead of the fake used by
// `ThemeSyncableServiceTest`, in order to more closely test production behavior
// and asserts.
class RealThemeSyncableServiceTest
    : public extensions::ExtensionServiceTestBase {
 protected:
  void SetUp() override {
    // Setting a matching update URL is necessary to make the test theme
    // considered syncable.
    extension_test_util::SetGalleryUpdateURL(GURL(kCustomThemeUrl));

    // Trying to write the theme pak just produces error messages.
    ThemeService::DisableThemePackForTesting();

    extensions::ExtensionServiceTestBase::SetUp();
    InitializeExtensionService(ExtensionServiceInitParams());
    service_->Init();

    theme_service_ = ThemeServiceFactory::GetForProfile(profile());

    theme_sync_service_ =
        std::make_unique<ThemeSyncableService>(profile(), theme_service_);
    fake_change_processor_ =
        std::make_unique<syncer::FakeSyncChangeProcessor>();

    // Create and add custom theme extension so the ThemeSyncableService can
    // find it.
    theme_extension_ = MakeThemeExtension(
        base::FilePath(kExtensionFilePath), kCustomThemeName,
        extensions::mojom::ManifestLocation::kInternal, kCustomThemeUrl);
    extensions::ExtensionPrefs::Get(profile())->AddGrantedPermissions(
        theme_extension_->id(), extensions::PermissionSet());
    service_->AddExtension(theme_extension_.get());
    ASSERT_EQ(1u, extensions::ExtensionRegistry::Get(profile())
                      ->enabled_extensions()
                      .size());
  }

  void TearDown() override {
    theme_sync_service_.reset();
    base::RunLoop().RunUntilIdle();
  }

  ThemeService* theme_service() { return theme_service_; }

  ThemeSyncableService* theme_sync_service() {
    return theme_sync_service_.get();
  }

  syncer::FakeSyncChangeProcessor* fake_change_processor() {
    return fake_change_processor_.get();
  }

  const extensions::Extension* theme_extension() const {
    return theme_extension_.get();
  }

 private:
  raw_ptr<ThemeService> theme_service_;
  std::unique_ptr<ThemeSyncableService> theme_sync_service_;
  std::unique_ptr<syncer::FakeSyncChangeProcessor> fake_change_processor_;
  scoped_refptr<extensions::Extension> theme_extension_;
};

// Regression test for crbug.com/1409996.
TEST_F(RealThemeSyncableServiceTest, ProcessSyncThemeChange_DisabledExtension) {
  // Set up theme service to use custom theme.
  {
    test::ThemeServiceChangedWaiter waiter(theme_service());
    theme_service()->SetTheme(theme_extension());
    waiter.WaitForThemeChanged();
  }

  // The custom theme should be set and enabled.
  EXPECT_TRUE(theme_service()->UsingExtensionTheme());
  EXPECT_EQ(theme_extension()->id(), theme_service()->GetThemeID());
  EXPECT_TRUE(service()->IsExtensionEnabled(theme_extension()->id()));

  // Now disable that theme by changing to an autogenerated theme.
  {
    test::ThemeServiceChangedWaiter waiter(theme_service());
    theme_service()->BuildAutogeneratedThemeFromColor(SkColorSetRGB(0, 0, 100));
    waiter.WaitForThemeChanged();
  }

  // The custom theme should no longer be set or enabled.
  EXPECT_FALSE(theme_service()->UsingExtensionTheme());
  EXPECT_FALSE(service()->IsExtensionEnabled(theme_extension()->id()));

  // Start syncing.
  std::optional<syncer::ModelError> error =
      theme_sync_service()->MergeDataAndStartSyncing(
          syncer::THEMES, syncer::SyncDataList(),
          std::make_unique<syncer::SyncChangeProcessorWrapperForTest>(
              fake_change_processor()));
  EXPECT_FALSE(error.has_value()) << error.value().message();

  // Process a sync update that updates back to the custom theme.
  sync_pb::ThemeSpecifics theme_specifics;
  theme_specifics.set_use_custom_theme(true);
  theme_specifics.set_custom_theme_id(theme_extension()->id());
  theme_specifics.set_custom_theme_name(kCustomThemeName);
  theme_specifics.set_custom_theme_update_url(kCustomThemeUrl);
  sync_pb::EntitySpecifics entity_specifics;
  entity_specifics.mutable_theme()->CopyFrom(theme_specifics);
  syncer::SyncChangeList change_list;
  change_list.emplace_back(
      FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
      syncer::SyncData::CreateRemoteData(
          entity_specifics, syncer::ClientTagHash::FromHashed("unused")));
  {
    test::ThemeServiceChangedWaiter waiter(theme_service());
    std::optional<syncer::ModelError> process_error =
        theme_sync_service()->ProcessSyncChanges(FROM_HERE, change_list);
    EXPECT_FALSE(process_error.has_value()) << process_error.value().message();
    waiter.WaitForThemeChanged();
  }

  // Ensure the custom theme has been re-set and re-enabled.
  EXPECT_TRUE(theme_service()->UsingExtensionTheme());
  EXPECT_EQ(theme_extension()->id(), theme_service()->GetThemeID());
  EXPECT_TRUE(service()->IsExtensionEnabled(theme_extension()->id()));
}

class ThemeSyncableServiceWithMigrationFlagDisabledTest
    : public RealThemeSyncableServiceTest {
 public:
  ThemeSyncableServiceWithMigrationFlagDisabledTest() {
    feature_list_.InitAndDisableFeature(syncer::kMoveThemePrefsToSpecifics);
  }

 private:
  base::test::ScopedFeatureList feature_list_;
};

TEST_F(ThemeSyncableServiceWithMigrationFlagDisabledTest,
       ShouldNotDownloadUserColorTheme) {
  sync_pb::ThemeSpecifics theme_specifics;
  sync_pb::ThemeSpecifics::UserColorTheme* user_color_theme =
      theme_specifics.mutable_user_color_theme();
  user_color_theme->set_color(SK_ColorRED);
  user_color_theme->set_browser_color_variant(BrowserColorVariantToProtoEnum(
      ui::mojom::BrowserColorVariant::kTonalSpot));

  // Start syncing.
  std::optional<syncer::ModelError> error =
      theme_sync_service()->MergeDataAndStartSyncing(
          syncer::THEMES, MakeThemeDataList(theme_specifics),
          std::make_unique<syncer::SyncChangeProcessorWrapperForTest>(
              fake_change_processor()));
  ASSERT_FALSE(error.has_value()) << error.value().message();

  EXPECT_EQ(theme_service()->GetUserColor(), std::nullopt);
  EXPECT_NE(theme_service()->GetBrowserColorVariant(),
            ui::mojom::BrowserColorVariant::kTonalSpot);
}

TEST_F(ThemeSyncableServiceWithMigrationFlagDisabledTest,
       ShouldNotUploadUserColorTheme) {
  // Start syncing.
  std::optional<syncer::ModelError> error =
      theme_sync_service()->MergeDataAndStartSyncing(
          syncer::THEMES, syncer::SyncDataList(),
          std::make_unique<syncer::SyncChangeProcessorWrapperForTest>(
              fake_change_processor()));
  ASSERT_FALSE(error.has_value()) << error.value().message();

  theme_service()->SetUserColorAndBrowserColorVariant(
      SK_ColorRED, ui::mojom::BrowserColorVariant::kTonalSpot);

  const syncer::SyncChangeList& changes = fake_change_processor()->changes();
  ASSERT_GE(changes.size(), 0u);
  EXPECT_FALSE(
      changes.back().sync_data().GetSpecifics().theme().has_user_color_theme());
}

TEST_F(ThemeSyncableServiceWithMigrationFlagDisabledTest,
       ShouldNotDownloadGrayscale) {
  sync_pb::ThemeSpecifics theme_specifics;
  theme_specifics.mutable_grayscale_theme_enabled();

  // Start syncing.
  std::optional<syncer::ModelError> error =
      theme_sync_service()->MergeDataAndStartSyncing(
          syncer::THEMES, MakeThemeDataList(theme_specifics),
          std::make_unique<syncer::SyncChangeProcessorWrapperForTest>(
              fake_change_processor()));
  ASSERT_FALSE(error.has_value()) << error.value().message();

  EXPECT_FALSE(theme_service()->GetIsGrayscale());
}

TEST_F(ThemeSyncableServiceWithMigrationFlagDisabledTest,
       ShouldNotUploadGrayscale) {
  // Start syncing.
  std::optional<syncer::ModelError> error =
      theme_sync_service()->MergeDataAndStartSyncing(
          syncer::THEMES, syncer::SyncDataList(),
          std::make_unique<syncer::SyncChangeProcessorWrapperForTest>(
              fake_change_processor()));
  ASSERT_FALSE(error.has_value()) << error.value().message();

  theme_service()->SetIsGrayscale(true);

  const syncer::SyncChangeList& changes = fake_change_processor()->changes();
  ASSERT_GE(changes.size(), 0u);
  EXPECT_FALSE(changes.back()
                   .sync_data()
                   .GetSpecifics()
                   .theme()
                   .has_grayscale_theme_enabled());
}

TEST_F(ThemeSyncableServiceWithMigrationFlagDisabledTest,
       ShouldNotDownloadBrowserColorScheme) {
  sync_pb::ThemeSpecifics theme_specifics;
  theme_specifics.set_browser_color_scheme(
      BrowserColorSchemeToProtoEnum(ThemeService::BrowserColorScheme::kLight));

  ASSERT_EQ(theme_service()->GetBrowserColorScheme(),
            ThemeService::BrowserColorScheme::kSystem);

  // Start syncing.
  std::optional<syncer::ModelError> error =
      theme_sync_service()->MergeDataAndStartSyncing(
          syncer::THEMES, MakeThemeDataList(theme_specifics),
          std::make_unique<syncer::SyncChangeProcessorWrapperForTest>(
              fake_change_processor()));
  ASSERT_FALSE(error.has_value()) << error.value().message();

  EXPECT_EQ(theme_service()->GetBrowserColorScheme(),
            ThemeService::BrowserColorScheme::kSystem);
}

TEST_F(ThemeSyncableServiceWithMigrationFlagDisabledTest,
       ShouldNotUploadBrowserColorScheme) {
  // Start syncing.
  std::optional<syncer::ModelError> error =
      theme_sync_service()->MergeDataAndStartSyncing(
          syncer::THEMES, syncer::SyncDataList(),
          std::make_unique<syncer::SyncChangeProcessorWrapperForTest>(
              fake_change_processor()));
  ASSERT_FALSE(error.has_value()) << error.value().message();

  theme_service()->SetBrowserColorScheme(
      ThemeService::BrowserColorScheme::kLight);

  const syncer::SyncChangeList& changes = fake_change_processor()->changes();
  ASSERT_GE(changes.size(), 0u);
  EXPECT_FALSE(changes.back()
                   .sync_data()
                   .GetSpecifics()
                   .theme()
                   .has_browser_color_scheme());
}

TEST_F(ThemeSyncableServiceWithMigrationFlagDisabledTest,
       ShouldNotDownloadNtpBackground) {
  sync_pb::ThemeSpecifics theme_specifics;
  theme_specifics.mutable_ntp_background()->set_url(kTestUrl);

  ASSERT_EQ(theme_service()->GetBrowserColorScheme(),
            ThemeService::BrowserColorScheme::kSystem);

  // Start syncing.
  std::optional<syncer::ModelError> error =
      theme_sync_service()->MergeDataAndStartSyncing(
          syncer::THEMES, MakeThemeDataList(theme_specifics),
          std::make_unique<syncer::SyncChangeProcessorWrapperForTest>(
              fake_change_processor()));
  ASSERT_FALSE(error.has_value()) << error.value().message();

  // TODO(crbug.com/356148174): Query NtpCustomBackgroundService for the
  // background state instead of reading the pref directly.
  EXPECT_FALSE(profile()->GetPrefs()->GetUserPrefValue(
      prefs::kNonSyncingNtpCustomBackgroundDictDoNotUse));
}

TEST_F(ThemeSyncableServiceWithMigrationFlagDisabledTest,
       ShouldNotUploadNtpBackground) {
  // Start syncing.
  std::optional<syncer::ModelError> error =
      theme_sync_service()->MergeDataAndStartSyncing(
          syncer::THEMES, syncer::SyncDataList(),
          std::make_unique<syncer::SyncChangeProcessorWrapperForTest>(
              fake_change_processor()));
  ASSERT_FALSE(error.has_value()) << error.value().message();
  {
    ScopedDictPrefUpdate dict(
        profile()->GetPrefs(),
        prefs::kNonSyncingNtpCustomBackgroundDictDoNotUse);
    dict->Set(kNtpCustomBackgroundURL, kTestUrl);
  }

  const syncer::SyncChangeList& changes = fake_change_processor()->changes();
  ASSERT_GE(changes.size(), 0u);
  EXPECT_FALSE(
      changes.back().sync_data().GetSpecifics().theme().has_ntp_background());
}

class ThemeSyncableServiceWithMigrationFlagEnabledTest
    : public RealThemeSyncableServiceTest {
 public:
  ThemeSyncableServiceWithMigrationFlagEnabledTest()
      : feature_list_(syncer::kMoveThemePrefsToSpecifics) {}

 private:
  base::test::ScopedFeatureList feature_list_;
};

TEST_F(ThemeSyncableServiceWithMigrationFlagEnabledTest,
       ShouldDownloadUserColorTheme) {
  sync_pb::ThemeSpecifics theme_specifics;
  sync_pb::ThemeSpecifics::UserColorTheme* user_color_theme =
      theme_specifics.mutable_user_color_theme();
  user_color_theme->set_color(SK_ColorRED);
  user_color_theme->set_browser_color_variant(BrowserColorVariantToProtoEnum(
      ui::mojom::BrowserColorVariant::kTonalSpot));

  // Start syncing.
  std::optional<syncer::ModelError> error =
      theme_sync_service()->MergeDataAndStartSyncing(
          syncer::THEMES, MakeThemeDataList(theme_specifics),
          std::make_unique<syncer::SyncChangeProcessorWrapperForTest>(
              fake_change_processor()));
  ASSERT_FALSE(error.has_value()) << error.value().message();

  EXPECT_EQ(theme_service()->GetThemeID(), ThemeService::kUserColorThemeID);
  EXPECT_EQ(theme_service()->GetUserColor(), SK_ColorRED);
  EXPECT_EQ(theme_service()->GetBrowserColorVariant(),
            ui::mojom::BrowserColorVariant::kTonalSpot);
  EXPECT_FALSE(theme_service()->UsingExtensionTheme());
  EXPECT_FALSE(theme_service()->UsingAutogeneratedTheme());
  EXPECT_FALSE(theme_service()->GetIsGrayscale());
  EXPECT_EQ(theme_service()->GetBrowserColorScheme(),
            ThemeService::BrowserColorScheme::kSystem);

  // Verify that the new prefs are used.
  EXPECT_EQ(
      profile()->GetPrefs()->GetInteger(prefs::kNonSyncingUserColorDoNotUse),
      static_cast<int>(SK_ColorRED));
  EXPECT_EQ(profile()->GetPrefs()->GetInteger(
                prefs::kNonSyncingBrowserColorVariantDoNotUse),
            static_cast<int>(ui::mojom::BrowserColorVariant::kTonalSpot));
}

TEST_F(ThemeSyncableServiceWithMigrationFlagEnabledTest,
       ShouldUploadUserColorTheme) {
  // Start syncing.
  std::optional<syncer::ModelError> error =
      theme_sync_service()->MergeDataAndStartSyncing(
          syncer::THEMES, syncer::SyncDataList(),
          std::make_unique<syncer::SyncChangeProcessorWrapperForTest>(
              fake_change_processor()));
  ASSERT_FALSE(error.has_value()) << error.value().message();

  theme_service()->SetUserColorAndBrowserColorVariant(
      SK_ColorRED, ui::mojom::BrowserColorVariant::kTonalSpot);

  const syncer::SyncChangeList& changes = fake_change_processor()->changes();
  ASSERT_GE(changes.size(), 0u);
  const sync_pb::ThemeSpecifics& change_specifics =
      changes.back().sync_data().GetSpecifics().theme();

  EXPECT_FALSE(change_specifics.use_custom_theme());
  ASSERT_TRUE(change_specifics.has_user_color_theme());
  EXPECT_EQ(SK_ColorRED, change_specifics.user_color_theme().color());
  EXPECT_EQ(ui::mojom::BrowserColorVariant::kTonalSpot,
            ProtoEnumToBrowserColorVariant(
                change_specifics.user_color_theme().browser_color_variant()));
  EXPECT_EQ(
      ThemeService::BrowserColorScheme::kSystem,
      ProtoEnumToBrowserColorScheme(change_specifics.browser_color_scheme()));

  // Verify that the old prefs are updated.
  EXPECT_EQ(profile()->GetPrefs()->GetInteger(prefs::kUserColorDoNotUse),
            static_cast<int>(SK_ColorRED));
  EXPECT_EQ(
      profile()->GetPrefs()->GetInteger(prefs::kBrowserColorVariantDoNotUse),
      static_cast<int>(ui::mojom::BrowserColorVariant::kTonalSpot));
}

TEST_F(ThemeSyncableServiceWithMigrationFlagEnabledTest,
       ShouldDownloadGrayscale) {
  sync_pb::ThemeSpecifics theme_specifics;
  theme_specifics.mutable_grayscale_theme_enabled();

  // Start syncing.
  std::optional<syncer::ModelError> error =
      theme_sync_service()->MergeDataAndStartSyncing(
          syncer::THEMES, MakeThemeDataList(theme_specifics),
          std::make_unique<syncer::SyncChangeProcessorWrapperForTest>(
              fake_change_processor()));
  ASSERT_FALSE(error.has_value()) << error.value().message();

  EXPECT_TRUE(theme_service()->GetIsGrayscale());
  EXPECT_EQ(theme_service()->GetThemeID(), "");
  EXPECT_EQ(theme_service()->GetUserColor(), std::nullopt);
  EXPECT_EQ(theme_service()->GetBrowserColorVariant(),
            ui::mojom::BrowserColorVariant::kSystem);
  EXPECT_FALSE(theme_service()->UsingExtensionTheme());
  EXPECT_FALSE(theme_service()->UsingAutogeneratedTheme());
  EXPECT_EQ(theme_service()->GetBrowserColorScheme(),
            ThemeService::BrowserColorScheme::kSystem);

  // Verify that the new pref is used.
  EXPECT_TRUE(profile()->GetPrefs()->GetBoolean(
      prefs::kNonSyncingGrayscaleThemeEnabledDoNotUse));
}

TEST_F(ThemeSyncableServiceWithMigrationFlagEnabledTest,
       ShouldUploadGrayscale) {
  // Start syncing.
  std::optional<syncer::ModelError> error =
      theme_sync_service()->MergeDataAndStartSyncing(
          syncer::THEMES, syncer::SyncDataList(),
          std::make_unique<syncer::SyncChangeProcessorWrapperForTest>(
              fake_change_processor()));
  ASSERT_FALSE(error.has_value()) << error.value().message();

  theme_service()->SetIsGrayscale(true);

  const syncer::SyncChangeList& changes = fake_change_processor()->changes();
  ASSERT_GE(changes.size(), 0u);
  const sync_pb::ThemeSpecifics& change_specifics =
      changes.back().sync_data().GetSpecifics().theme();
  EXPECT_FALSE(change_specifics.use_custom_theme());
  EXPECT_TRUE(change_specifics.has_grayscale_theme_enabled());
  EXPECT_EQ(
      ThemeService::BrowserColorScheme::kSystem,
      ProtoEnumToBrowserColorScheme(change_specifics.browser_color_scheme()));

  // Verify that the old pref is updated.
  EXPECT_TRUE(
      profile()->GetPrefs()->GetBoolean(prefs::kGrayscaleThemeEnabledDoNotUse));
}

TEST_F(ThemeSyncableServiceWithMigrationFlagEnabledTest,
       ShouldDownloadBrowserColorScheme) {
  sync_pb::ThemeSpecifics theme_specifics;
  theme_specifics.set_browser_color_scheme(
      BrowserColorSchemeToProtoEnum(ThemeService::BrowserColorScheme::kLight));

  ASSERT_EQ(theme_service()->GetBrowserColorScheme(),
            ThemeService::BrowserColorScheme::kSystem);

  // Start syncing.
  std::optional<syncer::ModelError> error =
      theme_sync_service()->MergeDataAndStartSyncing(
          syncer::THEMES, MakeThemeDataList(theme_specifics),
          std::make_unique<syncer::SyncChangeProcessorWrapperForTest>(
              fake_change_processor()));
  ASSERT_FALSE(error.has_value()) << error.value().message();

  EXPECT_EQ(theme_service()->GetBrowserColorScheme(),
            ThemeService::BrowserColorScheme::kLight);
  EXPECT_TRUE(theme_service()->UsingDefaultTheme());
  EXPECT_EQ(theme_service()->GetThemeID(), "");
  EXPECT_EQ(theme_service()->GetUserColor(), std::nullopt);
  EXPECT_EQ(theme_service()->GetBrowserColorVariant(),
            ui::mojom::BrowserColorVariant::kSystem);
  EXPECT_FALSE(theme_service()->GetIsGrayscale());
  EXPECT_FALSE(theme_service()->UsingExtensionTheme());
  EXPECT_FALSE(theme_service()->UsingAutogeneratedTheme());

  // Verify that the new pref is used.
  EXPECT_EQ(profile()->GetPrefs()->GetInteger(
                prefs::kNonSyncingBrowserColorSchemeDoNotUse),
            static_cast<int>(ThemeService::BrowserColorScheme::kLight));
}

TEST_F(ThemeSyncableServiceWithMigrationFlagEnabledTest,
       ShouldUploadBrowserColorScheme) {
  // Start syncing.
  std::optional<syncer::ModelError> error =
      theme_sync_service()->MergeDataAndStartSyncing(
          syncer::THEMES, syncer::SyncDataList(),
          std::make_unique<syncer::SyncChangeProcessorWrapperForTest>(
              fake_change_processor()));
  ASSERT_FALSE(error.has_value()) << error.value().message();

  theme_service()->SetBrowserColorScheme(
      ThemeService::BrowserColorScheme::kLight);

  const syncer::SyncChangeList& changes = fake_change_processor()->changes();
  ASSERT_GE(changes.size(), 0u);
  const sync_pb::ThemeSpecifics& change_specifics =
      changes.back().sync_data().GetSpecifics().theme();

  EXPECT_EQ(
      ThemeService::BrowserColorScheme::kLight,
      ProtoEnumToBrowserColorScheme(change_specifics.browser_color_scheme()));
  EXPECT_FALSE(change_specifics.use_custom_theme());
  EXPECT_FALSE(change_specifics.has_user_color_theme());
  EXPECT_FALSE(change_specifics.has_autogenerated_color_theme());
  EXPECT_FALSE(change_specifics.has_grayscale_theme_enabled());

  // Verify that the old pref is updated.
  EXPECT_EQ(
      profile()->GetPrefs()->GetInteger(prefs::kBrowserColorSchemeDoNotUse),
      static_cast<int>(ThemeService::BrowserColorScheme::kLight));
}

TEST_F(ThemeSyncableServiceWithMigrationFlagEnabledTest,
       ShouldDownloadNtpBackground) {
  sync_pb::ThemeSpecifics theme_specifics;
  sync_pb::ThemeSpecifics::NtpCustomBackground* ntp_background =
      theme_specifics.mutable_ntp_background();
  ntp_background->set_url(kTestUrl);
  ntp_background->set_attribution_line_1("attribution_line_1");
  ntp_background->set_attribution_line_2("attribution_line_2");
  ntp_background->set_attribution_action_url("attribution_action_url");
  ntp_background->set_collection_id("collection_id");
  ntp_background->set_resume_token("resume_token");
  ntp_background->set_refresh_timestamp_unix_epoch_seconds(1234567890);
  ntp_background->set_main_color(SK_ColorRED);

  // Start syncing.
  std::optional<syncer::ModelError> error =
      theme_sync_service()->MergeDataAndStartSyncing(
          syncer::THEMES, MakeThemeDataList(theme_specifics),
          std::make_unique<syncer::SyncChangeProcessorWrapperForTest>(
              fake_change_processor()));
  ASSERT_FALSE(error.has_value()) << error.value().message();

  base::Value::Dict expected_value =
      base::Value::Dict()
          .Set(kNtpCustomBackgroundURL, kTestUrl)
          .Set(kNtpCustomBackgroundAttributionLine1, "attribution_line_1")
          .Set(kNtpCustomBackgroundAttributionLine2, "attribution_line_2")
          .Set(kNtpCustomBackgroundAttributionActionURL,
               "attribution_action_url")
          .Set(kNtpCustomBackgroundCollectionId, "collection_id")
          .Set(kNtpCustomBackgroundResumeToken, "resume_token")
          .Set(kNtpCustomBackgroundRefreshTimestamp,
               static_cast<int>(1234567890))
          .Set(kNtpCustomBackgroundMainColor, static_cast<int>(SK_ColorRED));
  const base::Value* value = profile()->GetPrefs()->GetUserPrefValue(
      prefs::kNonSyncingNtpCustomBackgroundDictDoNotUse);
  ASSERT_TRUE(value);
  EXPECT_EQ(*value, expected_value);
}

TEST_F(ThemeSyncableServiceWithMigrationFlagEnabledTest,
       ShouldUploadNtpBackground) {
  // Start syncing.
  std::optional<syncer::ModelError> error =
      theme_sync_service()->MergeDataAndStartSyncing(
          syncer::THEMES, syncer::SyncDataList(),
          std::make_unique<syncer::SyncChangeProcessorWrapperForTest>(
              fake_change_processor()));
  ASSERT_FALSE(error.has_value()) << error.value().message();

  base::Value::Dict new_value =
      base::Value::Dict()
          .Set(kNtpCustomBackgroundURL, kTestUrl)
          .Set(kNtpCustomBackgroundAttributionLine1, "attribution_line_1")
          .Set(kNtpCustomBackgroundAttributionLine2, "attribution_line_2")
          .Set(kNtpCustomBackgroundAttributionActionURL,
               "attribution_action_url")
          .Set(kNtpCustomBackgroundCollectionId, "collection_id")
          .Set(kNtpCustomBackgroundResumeToken, "resume_token")
          .Set(kNtpCustomBackgroundRefreshTimestamp,
               static_cast<int>(1234567890))
          .Set(kNtpCustomBackgroundMainColor, static_cast<int>(SK_ColorRED));

  profile()->GetPrefs()->Set(prefs::kNonSyncingNtpCustomBackgroundDictDoNotUse,
                             base::Value(new_value.Clone()));

  const syncer::SyncChangeList& changes = fake_change_processor()->changes();
  ASSERT_GE(changes.size(), 0u);
  const sync_pb::ThemeSpecifics::NtpCustomBackground& ntp_background =
      changes.back().sync_data().GetSpecifics().theme().ntp_background();
  EXPECT_EQ(ntp_background.url(), kTestUrl);
  EXPECT_EQ(ntp_background.attribution_line_1(), "attribution_line_1");
  EXPECT_EQ(ntp_background.attribution_line_2(), "attribution_line_2");
  EXPECT_EQ(ntp_background.attribution_action_url(), "attribution_action_url");
  EXPECT_EQ(ntp_background.collection_id(), "collection_id");
  EXPECT_EQ(ntp_background.resume_token(), "resume_token");
  EXPECT_EQ(ntp_background.refresh_timestamp_unix_epoch_seconds(), 1234567890);
  EXPECT_EQ(ntp_background.main_color(), SK_ColorRED);

  // Verify that the old pref is updated.
  EXPECT_THAT(profile()->GetPrefs()->GetUserPrefValue(
                  prefs::kNtpCustomBackgroundDictDoNotUse),
              DictionaryValuePtrHas(kNtpCustomBackgroundURL, kTestUrl));
}

TEST_F(ThemeSyncableServiceWithMigrationFlagEnabledTest,
       ShouldApplyRemoteNtpBackgroundChange) {
  // Start syncing.
  std::optional<syncer::ModelError> error =
      theme_sync_service()->MergeDataAndStartSyncing(
          syncer::THEMES, syncer::SyncDataList(),
          std::make_unique<syncer::SyncChangeProcessorWrapperForTest>(
              fake_change_processor()));
  ASSERT_FALSE(error.has_value()) << error.value().message();

  EXPECT_FALSE(profile()->GetPrefs()->GetUserPrefValue(
      prefs::kNonSyncingNtpCustomBackgroundDictDoNotUse));

  // Process change with background set.
  {
    sync_pb::ThemeSpecifics theme_specifics;
    theme_specifics.mutable_ntp_background()->set_url(kTestUrl);

    ASSERT_FALSE(theme_sync_service()->ProcessSyncChanges(
        FROM_HERE, MakeThemeChangeList(theme_specifics)));
  }

  EXPECT_THAT(profile()->GetPrefs()->GetUserPrefValue(
                  prefs::kNonSyncingNtpCustomBackgroundDictDoNotUse),
              DictionaryValuePtrHas(kNtpCustomBackgroundURL, kTestUrl));
}

TEST_F(ThemeSyncableServiceWithMigrationFlagEnabledTest,
       ShouldNotApplyEmptyRemoteNtpBackgroundChange) {
  {
    ScopedDictPrefUpdate dict(
        profile()->GetPrefs(),
        prefs::kNonSyncingNtpCustomBackgroundDictDoNotUse);
    dict->Set(kNtpCustomBackgroundURL, kTestUrl);
  }

  // Start syncing.
  std::optional<syncer::ModelError> error =
      theme_sync_service()->MergeDataAndStartSyncing(
          syncer::THEMES, syncer::SyncDataList(),
          std::make_unique<syncer::SyncChangeProcessorWrapperForTest>(
              fake_change_processor()));
  ASSERT_FALSE(error.has_value()) << error.value().message();

  EXPECT_THAT(profile()->GetPrefs()->GetUserPrefValue(
                  prefs::kNonSyncingNtpCustomBackgroundDictDoNotUse),
              DictionaryValuePtrHas(kNtpCustomBackgroundURL, kTestUrl));

  // Process change with empty background.
  {
    sync_pb::ThemeSpecifics theme_specifics;
    theme_specifics.mutable_ntp_background();
    ASSERT_FALSE(theme_sync_service()->ProcessSyncChanges(
        FROM_HERE, MakeThemeChangeList(theme_specifics)));
  }

  // Removed as the default theme is applied.
  EXPECT_FALSE(profile()->GetPrefs()->GetUserPrefValue(
      prefs::kNonSyncingNtpCustomBackgroundDictDoNotUse));
}

TEST_F(ThemeSyncableServiceWithMigrationFlagEnabledTest,
       ShouldNotApplyMissingRemoteNtpBackgroundChange) {
  {
    ScopedDictPrefUpdate dict(
        profile()->GetPrefs(),
        prefs::kNonSyncingNtpCustomBackgroundDictDoNotUse);
    dict->Set(kNtpCustomBackgroundURL, kTestUrl);
  }

  // Start syncing.
  std::optional<syncer::ModelError> error =
      theme_sync_service()->MergeDataAndStartSyncing(
          syncer::THEMES, syncer::SyncDataList(),
          std::make_unique<syncer::SyncChangeProcessorWrapperForTest>(
              fake_change_processor()));
  ASSERT_FALSE(error.has_value()) << error.value().message();

  EXPECT_THAT(profile()->GetPrefs()->GetUserPrefValue(
                  prefs::kNonSyncingNtpCustomBackgroundDictDoNotUse),
              DictionaryValuePtrHas(kNtpCustomBackgroundURL, kTestUrl));

  // Process change with background not set.
  {
    sync_pb::ThemeSpecifics theme_specifics;
    ASSERT_FALSE(theme_sync_service()->ProcessSyncChanges(
        FROM_HERE, MakeThemeChangeList(theme_specifics)));
  }

  // Removed as the default theme is applied.
  EXPECT_FALSE(profile()->GetPrefs()->GetUserPrefValue(
      prefs::kNonSyncingNtpCustomBackgroundDictDoNotUse));
}

TEST_F(ThemeSyncableServiceWithMigrationFlagEnabledTest,
       ShouldApplyRemoteBrowserColorSchemeChanges) {
  // Start syncing.
  std::optional<syncer::ModelError> error =
      theme_sync_service()->MergeDataAndStartSyncing(
          syncer::THEMES, syncer::SyncDataList(),
          std::make_unique<syncer::SyncChangeProcessorWrapperForTest>(
              fake_change_processor()));
  ASSERT_FALSE(error.has_value()) << error.value().message();

  EXPECT_EQ(theme_service()->GetBrowserColorScheme(),
            ThemeService::BrowserColorScheme::kSystem);

  // Process change with user color set.
  {
    sync_pb::ThemeSpecifics theme_specifics;
    theme_specifics.set_browser_color_scheme(BrowserColorSchemeToProtoEnum(
        ThemeService::BrowserColorScheme::kLight));

    ASSERT_FALSE(theme_sync_service()->ProcessSyncChanges(
        FROM_HERE, MakeThemeChangeList(theme_specifics)));
  }

  EXPECT_EQ(theme_service()->GetBrowserColorScheme(),
            ThemeService::BrowserColorScheme::kLight);

  // Process change with user color not set.
  {
    sync_pb::ThemeSpecifics theme_specifics;

    ASSERT_FALSE(theme_sync_service()->ProcessSyncChanges(
        FROM_HERE, MakeThemeChangeList(theme_specifics)));
  }

  // No effect.
  EXPECT_EQ(theme_service()->GetBrowserColorScheme(),
            ThemeService::BrowserColorScheme::kLight);

  // Process change with user color set to default.
  {
    sync_pb::ThemeSpecifics theme_specifics;
    theme_specifics.set_browser_color_scheme(BrowserColorSchemeToProtoEnum(
        ThemeService::BrowserColorScheme::kSystem));

    ASSERT_FALSE(theme_sync_service()->ProcessSyncChanges(
        FROM_HERE, MakeThemeChangeList(theme_specifics)));
  }

  // Changes to default.
  EXPECT_EQ(theme_service()->GetBrowserColorScheme(),
            ThemeService::BrowserColorScheme::kSystem);
}

TEST_F(ThemeSyncableServiceWithMigrationFlagEnabledTest,
       ShouldPriortizeExtensionThemeOverUserColor) {
  sync_pb::ThemeSpecifics theme_specifics;
  // Set all fields (all the different theme types).
  theme_specifics.set_use_custom_theme(true);
  theme_specifics.set_custom_theme_id(theme_extension()->id());
  theme_specifics.set_custom_theme_name(kCustomThemeName);
  theme_specifics.set_custom_theme_update_url(kCustomThemeUrl);

  sync_pb::ThemeSpecifics::UserColorTheme* user_color_theme =
      theme_specifics.mutable_user_color_theme();
  user_color_theme->set_color(SK_ColorRED);
  user_color_theme->set_browser_color_variant(BrowserColorVariantToProtoEnum(
      ui::mojom::BrowserColorVariant::kTonalSpot));

  theme_specifics.set_browser_color_scheme(
      BrowserColorSchemeToProtoEnum(ThemeService::BrowserColorScheme::kLight));

  // Start syncing.
  {
    test::ThemeServiceChangedWaiter waiter(theme_service());
    std::optional<syncer::ModelError> error =
        theme_sync_service()->MergeDataAndStartSyncing(
            syncer::THEMES, MakeThemeDataList(theme_specifics),
            std::unique_ptr<syncer::SyncChangeProcessor>(
                new syncer::SyncChangeProcessorWrapperForTest(
                    fake_change_processor())));
    ASSERT_FALSE(error.has_value()) << error.value().message();
    waiter.WaitForThemeChanged();
  }

  EXPECT_TRUE(theme_service()->UsingExtensionTheme());
  EXPECT_FALSE(theme_service()->UsingAutogeneratedTheme());
  EXPECT_NE(theme_service()->GetThemeID(), ThemeService::kUserColorThemeID);
  EXPECT_EQ(theme_service()->GetUserColor(), std::nullopt);
  EXPECT_NE(theme_service()->GetBrowserColorVariant(),
            ui::mojom::BrowserColorVariant::kTonalSpot);
  EXPECT_FALSE(theme_service()->GetIsGrayscale());
  EXPECT_NE(theme_service()->GetBrowserColorScheme(),
            ThemeService::BrowserColorScheme::kLight);
}

TEST_F(ThemeSyncableServiceWithMigrationFlagEnabledTest,
       ShouldPriortizeExtensionThemeOverAutogeneratedTheme) {
  sync_pb::ThemeSpecifics theme_specifics;
  // Set all fields (all the different theme types).
  theme_specifics.set_use_custom_theme(true);
  theme_specifics.set_custom_theme_id(theme_extension()->id());
  theme_specifics.set_custom_theme_name(kCustomThemeName);
  theme_specifics.set_custom_theme_update_url(kCustomThemeUrl);
  theme_specifics.mutable_autogenerated_color_theme()->set_color(SK_ColorBLUE);
  theme_specifics.set_browser_color_scheme(
      BrowserColorSchemeToProtoEnum(ThemeService::BrowserColorScheme::kLight));

  // Start syncing.
  {
    test::ThemeServiceChangedWaiter waiter(theme_service());
    std::optional<syncer::ModelError> error =
        theme_sync_service()->MergeDataAndStartSyncing(
            syncer::THEMES, MakeThemeDataList(theme_specifics),
            std::unique_ptr<syncer::SyncChangeProcessor>(
                new syncer::SyncChangeProcessorWrapperForTest(
                    fake_change_processor())));
    ASSERT_FALSE(error.has_value()) << error.value().message();
    waiter.WaitForThemeChanged();
  }

  EXPECT_TRUE(theme_service()->UsingExtensionTheme());
  EXPECT_FALSE(theme_service()->UsingAutogeneratedTheme());
  EXPECT_NE(theme_service()->GetThemeID(), ThemeService::kAutogeneratedThemeID);
  EXPECT_EQ(theme_service()->GetUserColor(), std::nullopt);
  EXPECT_FALSE(theme_service()->GetIsGrayscale());
  EXPECT_NE(theme_service()->GetBrowserColorScheme(),
            ThemeService::BrowserColorScheme::kLight);
}

TEST_F(ThemeSyncableServiceWithMigrationFlagEnabledTest,
       ShouldPriortizeExtensionThemeOverGrayscale) {
  sync_pb::ThemeSpecifics theme_specifics;
  // Set all fields (all the different theme types).
  theme_specifics.set_use_custom_theme(true);
  theme_specifics.set_custom_theme_id(theme_extension()->id());
  theme_specifics.set_custom_theme_name(kCustomThemeName);
  theme_specifics.set_custom_theme_update_url(kCustomThemeUrl);
  theme_specifics.mutable_grayscale_theme_enabled();
  theme_specifics.set_browser_color_scheme(
      BrowserColorSchemeToProtoEnum(ThemeService::BrowserColorScheme::kLight));

  // Start syncing.
  {
    test::ThemeServiceChangedWaiter waiter(theme_service());
    std::optional<syncer::ModelError> error =
        theme_sync_service()->MergeDataAndStartSyncing(
            syncer::THEMES, MakeThemeDataList(theme_specifics),
            std::unique_ptr<syncer::SyncChangeProcessor>(
                new syncer::SyncChangeProcessorWrapperForTest(
                    fake_change_processor())));
    ASSERT_FALSE(error.has_value()) << error.value().message();
    waiter.WaitForThemeChanged();
  }

  EXPECT_TRUE(theme_service()->UsingExtensionTheme());
  EXPECT_FALSE(theme_service()->GetIsGrayscale());
  EXPECT_NE(theme_service()->GetBrowserColorScheme(),
            ThemeService::BrowserColorScheme::kLight);
  EXPECT_FALSE(theme_service()->UsingAutogeneratedTheme());
  EXPECT_EQ(theme_service()->GetUserColor(), std::nullopt);
  EXPECT_EQ(theme_service()->GetBrowserColorVariant(),
            ui::mojom::BrowserColorVariant::kSystem);
}

TEST_F(ThemeSyncableServiceWithMigrationFlagEnabledTest,
       ShouldPrioritizeExtensionThemeInAreThemeSpecificsEquivalent) {
  sync_pb::ThemeSpecifics a, b;
  a.set_use_custom_theme(true);
  a.set_browser_color_scheme(
      BrowserColorSchemeToProtoEnum(ThemeService::BrowserColorScheme::kLight));
  a.mutable_autogenerated_color_theme()->set_color(SK_ColorBLUE);
  a.set_use_system_theme_by_default(true);

  b.set_use_custom_theme(true);
  b.set_browser_color_scheme(
      BrowserColorSchemeToProtoEnum(ThemeService::BrowserColorScheme::kDark));
  b.mutable_grayscale_theme_enabled();
  b.set_use_system_theme_by_default(false);

  EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, true));
}

TEST_F(ThemeSyncableServiceWithMigrationFlagEnabledTest,
       ShouldConsiderBrowserColorSchemeInAreThemeSpecificsEquivalent) {
  sync_pb::ThemeSpecifics a, b;
  a.set_use_custom_theme(false);
  a.set_browser_color_scheme(
      BrowserColorSchemeToProtoEnum(ThemeService::BrowserColorScheme::kLight));
  a.mutable_autogenerated_color_theme()->set_color(SK_ColorBLUE);
  a.set_use_system_theme_by_default(true);

  b = a;
  b.mutable_autogenerated_color_theme()->set_color(SK_ColorRED);
  EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, false));

  b.mutable_autogenerated_color_theme()->set_color(SK_ColorRED);
  b.set_browser_color_scheme(
      BrowserColorSchemeToProtoEnum(ThemeService::BrowserColorScheme::kDark));
  // AreThemeSpecificsEquivalent returns false even though only the browser
  // color scheme differs.
  EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, false));
}

TEST_F(ThemeSyncableServiceWithMigrationFlagEnabledTest,
       ShouldConsiderNtpBackgroundInAreThemeSpecificsEquivalent) {
  sync_pb::ThemeSpecifics a, b;
  a.set_use_custom_theme(false);
  a.mutable_autogenerated_color_theme()->set_color(SK_ColorBLUE);
  a.mutable_ntp_background()->set_url(kTestUrl);

  b = a;

  sync_pb::ThemeSpecifics::NtpCustomBackground* background =
      b.mutable_ntp_background();

  // These fields do not matter when comparing two ntp background msgs.
  background->set_attribution_line_1("attribution_line_1");
  background->set_attribution_line_2("attribution_line_2");
  background->set_attribution_action_url("attribution_action_url");
  background->set_resume_token("resume_token");
  background->set_refresh_timestamp_unix_epoch_seconds(1234567890);
  EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, false));

  // Set a different url.
  background->set_url("https://www.bar.com");
  EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, false));

  // Set a different collection id.
  background->set_url(kTestUrl);
  background->set_collection_id("collection_id");
  EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, false));

  // Set a different main color.
  background->clear_collection_id();
  background->set_main_color(SK_ColorRED);
  EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, false));

  // Remove the ntp background.
  b.clear_ntp_background();
  EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEquivalent(a, b, false));
}

TEST_F(ThemeSyncableServiceWithMigrationFlagEnabledTest,
       ShouldApplyBrowserColorSchemeWithUserColorTheme) {
  sync_pb::ThemeSpecifics theme_specifics;
  theme_specifics.set_use_custom_theme(false);
  theme_specifics.set_browser_color_scheme(
      BrowserColorSchemeToProtoEnum(ThemeService::BrowserColorScheme::kLight));
  sync_pb::ThemeSpecifics::UserColorTheme* user_color_theme =
      theme_specifics.mutable_user_color_theme();
  user_color_theme->set_color(SK_ColorRED);
  user_color_theme->set_browser_color_variant(BrowserColorVariantToProtoEnum(
      ui::mojom::BrowserColorVariant::kTonalSpot));

  // Start syncing.
  std::optional<syncer::ModelError> error =
      theme_sync_service()->MergeDataAndStartSyncing(
          syncer::THEMES, MakeThemeDataList(theme_specifics),
          std::unique_ptr<syncer::SyncChangeProcessor>(
              new syncer::SyncChangeProcessorWrapperForTest(
                  fake_change_processor())));
  ASSERT_FALSE(error.has_value()) << error.value().message();

  EXPECT_FALSE(theme_service()->UsingExtensionTheme());
  EXPECT_FALSE(theme_service()->UsingAutogeneratedTheme());
  EXPECT_FALSE(theme_service()->GetIsGrayscale());
  EXPECT_EQ(theme_service()->GetThemeID(), ThemeService::kUserColorThemeID);
  EXPECT_EQ(theme_service()->GetUserColor(), SK_ColorRED);
  EXPECT_EQ(theme_service()->GetBrowserColorVariant(),
            ui::mojom::BrowserColorVariant::kTonalSpot);
  EXPECT_EQ(theme_service()->GetBrowserColorScheme(),
            ThemeService::BrowserColorScheme::kLight);
}

TEST_F(ThemeSyncableServiceWithMigrationFlagEnabledTest,
       ShouldApplyBrowserColorSchemeWithGrayscale) {
  sync_pb::ThemeSpecifics theme_specifics;
  theme_specifics.set_use_custom_theme(false);
  theme_specifics.mutable_grayscale_theme_enabled();
  theme_specifics.set_browser_color_scheme(
      BrowserColorSchemeToProtoEnum(ThemeService::BrowserColorScheme::kLight));

  // Start syncing.
  test::ThemeServiceChangedWaiter waiter(theme_service());
  std::optional<syncer::ModelError> error =
      theme_sync_service()->MergeDataAndStartSyncing(
          syncer::THEMES, MakeThemeDataList(theme_specifics),
          std::unique_ptr<syncer::SyncChangeProcessor>(
              new syncer::SyncChangeProcessorWrapperForTest(
                  fake_change_processor())));
  ASSERT_FALSE(error.has_value()) << error.value().message();

  EXPECT_FALSE(theme_service()->UsingExtensionTheme());
  EXPECT_FALSE(theme_service()->UsingAutogeneratedTheme());
  EXPECT_EQ(theme_service()->GetThemeID(), "");
  EXPECT_EQ(theme_service()->GetUserColor(), std::nullopt);
  EXPECT_EQ(theme_service()->GetBrowserColorVariant(),
            ui::mojom::BrowserColorVariant::kSystem);
  EXPECT_TRUE(theme_service()->GetIsGrayscale());
  EXPECT_EQ(theme_service()->GetBrowserColorScheme(),
            ThemeService::BrowserColorScheme::kLight);
}

TEST_F(ThemeSyncableServiceWithMigrationFlagEnabledTest,
       ShouldApplyBrowserColorSchemeWithAutogeneratedTheme) {
  sync_pb::ThemeSpecifics theme_specifics;
  theme_specifics.set_use_custom_theme(false);
  theme_specifics.mutable_autogenerated_color_theme()->set_color(SK_ColorBLUE);
  theme_specifics.set_browser_color_scheme(
      BrowserColorSchemeToProtoEnum(ThemeService::BrowserColorScheme::kLight));

  // Start syncing.
  std::optional<syncer::ModelError> error =
      theme_sync_service()->MergeDataAndStartSyncing(
          syncer::THEMES, MakeThemeDataList(theme_specifics),
          std::unique_ptr<syncer::SyncChangeProcessor>(
              new syncer::SyncChangeProcessorWrapperForTest(
                  fake_change_processor())));
  ASSERT_FALSE(error.has_value()) << error.value().message();

  EXPECT_FALSE(theme_service()->UsingExtensionTheme());
  EXPECT_TRUE(theme_service()->UsingAutogeneratedTheme());
  EXPECT_EQ(theme_service()->GetAutogeneratedThemeColor(), SK_ColorBLUE);
  EXPECT_EQ(theme_service()->GetThemeID(), ThemeService::kAutogeneratedThemeID);
  EXPECT_EQ(theme_service()->GetUserColor(), std::nullopt);
  EXPECT_EQ(theme_service()->GetBrowserColorVariant(),
            ui::mojom::BrowserColorVariant::kSystem);
  EXPECT_FALSE(theme_service()->GetIsGrayscale());
  EXPECT_EQ(theme_service()->GetBrowserColorScheme(),
            ThemeService::BrowserColorScheme::kLight);
}

TEST_F(ThemeSyncableServiceWithMigrationFlagEnabledTest,
       ShouldApplyNtpBackgroundWithUserColorTheme) {
  sync_pb::ThemeSpecifics theme_specifics;
  theme_specifics.set_use_custom_theme(false);
  theme_specifics.mutable_ntp_background()->set_url(kTestUrl);
  sync_pb::ThemeSpecifics::UserColorTheme* user_color_theme =
      theme_specifics.mutable_user_color_theme();
  user_color_theme->set_color(SK_ColorRED);
  user_color_theme->set_browser_color_variant(BrowserColorVariantToProtoEnum(
      ui::mojom::BrowserColorVariant::kTonalSpot));

  // Start syncing.
  std::optional<syncer::ModelError> error =
      theme_sync_service()->MergeDataAndStartSyncing(
          syncer::THEMES, MakeThemeDataList(theme_specifics),
          std::unique_ptr<syncer::SyncChangeProcessor>(
              new syncer::SyncChangeProcessorWrapperForTest(
                  fake_change_processor())));
  ASSERT_FALSE(error.has_value()) << error.value().message();

  EXPECT_FALSE(theme_service()->UsingExtensionTheme());
  EXPECT_FALSE(theme_service()->UsingAutogeneratedTheme());
  EXPECT_FALSE(theme_service()->GetIsGrayscale());
  EXPECT_EQ(theme_service()->GetThemeID(), ThemeService::kUserColorThemeID);
  EXPECT_EQ(theme_service()->GetUserColor(), SK_ColorRED);
  EXPECT_EQ(theme_service()->GetBrowserColorVariant(),
            ui::mojom::BrowserColorVariant::kTonalSpot);
  EXPECT_THAT(profile()->GetPrefs()->GetUserPrefValue(
                  prefs::kNonSyncingNtpCustomBackgroundDictDoNotUse),
              DictionaryValuePtrHas(kNtpCustomBackgroundURL, kTestUrl));
}

TEST_F(ThemeSyncableServiceWithMigrationFlagEnabledTest,
       ShouldApplyNtpBackgroundWithGrayscale) {
  sync_pb::ThemeSpecifics theme_specifics;
  theme_specifics.set_use_custom_theme(false);
  theme_specifics.mutable_grayscale_theme_enabled();
  theme_specifics.mutable_ntp_background()->set_url(kTestUrl);

  // Start syncing.
  std::optional<syncer::ModelError> error =
      theme_sync_service()->MergeDataAndStartSyncing(
          syncer::THEMES, MakeThemeDataList(theme_specifics),
          std::unique_ptr<syncer::SyncChangeProcessor>(
              new syncer::SyncChangeProcessorWrapperForTest(
                  fake_change_processor())));
  ASSERT_FALSE(error.has_value()) << error.value().message();

  EXPECT_FALSE(theme_service()->UsingExtensionTheme());
  EXPECT_FALSE(theme_service()->UsingAutogeneratedTheme());
  EXPECT_EQ(theme_service()->GetThemeID(), "");
  EXPECT_EQ(theme_service()->GetUserColor(), std::nullopt);
  EXPECT_EQ(theme_service()->GetBrowserColorVariant(),
            ui::mojom::BrowserColorVariant::kSystem);
  EXPECT_TRUE(theme_service()->GetIsGrayscale());
  EXPECT_THAT(profile()->GetPrefs()->GetUserPrefValue(
                  prefs::kNonSyncingNtpCustomBackgroundDictDoNotUse),
              DictionaryValuePtrHas(kNtpCustomBackgroundURL, kTestUrl));
}

TEST_F(ThemeSyncableServiceWithMigrationFlagEnabledTest,
       ShouldApplyNtpBackgroundWithAutogeneratedTheme) {
  sync_pb::ThemeSpecifics theme_specifics;
  theme_specifics.set_use_custom_theme(false);
  theme_specifics.mutable_autogenerated_color_theme()->set_color(SK_ColorBLUE);
  theme_specifics.mutable_ntp_background()->set_url(kTestUrl);

  // Start syncing.
  std::optional<syncer::ModelError> error =
      theme_sync_service()->MergeDataAndStartSyncing(
          syncer::THEMES, MakeThemeDataList(theme_specifics),
          std::unique_ptr<syncer::SyncChangeProcessor>(
              new syncer::SyncChangeProcessorWrapperForTest(
                  fake_change_processor())));
  ASSERT_FALSE(error.has_value()) << error.value().message();

  EXPECT_FALSE(theme_service()->UsingExtensionTheme());
  EXPECT_TRUE(theme_service()->UsingAutogeneratedTheme());
  EXPECT_EQ(theme_service()->GetAutogeneratedThemeColor(), SK_ColorBLUE);
  EXPECT_EQ(theme_service()->GetThemeID(), ThemeService::kAutogeneratedThemeID);
  EXPECT_EQ(theme_service()->GetUserColor(), std::nullopt);
  EXPECT_EQ(theme_service()->GetBrowserColorVariant(),
            ui::mojom::BrowserColorVariant::kSystem);
  EXPECT_FALSE(theme_service()->GetIsGrayscale());
  EXPECT_THAT(profile()->GetPrefs()->GetUserPrefValue(
                  prefs::kNonSyncingNtpCustomBackgroundDictDoNotUse),
              DictionaryValuePtrHas(kNtpCustomBackgroundURL, kTestUrl));
}

class ThemePrefsMigrationTest : public ::testing::Test {
 public:
  void SetUp() override {
    user_prefs::PrefRegistrySyncable* registry = pref_service_.registry();
    // Register all the prefs involved in the migration.
    registry->RegisterBooleanPref(prefs::kSyncingThemePrefsMigratedToNonSyncing,
                                  false);
    registry->RegisterIntegerPref(
        prefs::kBrowserColorSchemeDoNotUse,
        static_cast<int>(ThemeService::BrowserColorScheme::kSystem),
        user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
    registry->RegisterIntegerPref(
        prefs::kNonSyncingBrowserColorSchemeDoNotUse,
        static_cast<int>(ThemeService::BrowserColorScheme::kSystem));
    registry->RegisterIntegerPref(
        prefs::kUserColorDoNotUse, SK_ColorTRANSPARENT,
        user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
    registry->RegisterIntegerPref(prefs::kNonSyncingUserColorDoNotUse,
                                  SK_ColorTRANSPARENT);
    registry->RegisterIntegerPref(
        prefs::kBrowserColorVariantDoNotUse,
        static_cast<int>(ui::mojom::BrowserColorVariant::kSystem),
        user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
    registry->RegisterIntegerPref(
        prefs::kNonSyncingBrowserColorVariantDoNotUse,
        static_cast<int>(ui::mojom::BrowserColorVariant::kSystem));
    registry->RegisterBooleanPref(
        prefs::kGrayscaleThemeEnabledDoNotUse, false,
        user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
    registry->RegisterBooleanPref(
        prefs::kNonSyncingGrayscaleThemeEnabledDoNotUse, false);
    registry->RegisterDictionaryPref(prefs::kNtpCustomBackgroundDictDoNotUse);
    registry->RegisterDictionaryPref(
        prefs::kNonSyncingNtpCustomBackgroundDictDoNotUse);
  }

 protected:
  sync_preferences::TestingPrefServiceSyncable pref_service_;
};

TEST_F(ThemePrefsMigrationTest, MigrateSyncingThemePrefsToNonSyncing) {
  base::test::ScopedFeatureList feature_list(
      syncer::kMoveThemePrefsToSpecifics);

  ASSERT_FALSE(
      pref_service_.GetBoolean(prefs::kSyncingThemePrefsMigratedToNonSyncing));

  pref_service_.SetInteger(prefs::kUserColorDoNotUse, SK_ColorBLUE);
  EXPECT_FALSE(pref_service_.HasPrefPath(prefs::kNonSyncingUserColorDoNotUse));

  MigrateSyncingThemePrefsToNonSyncingIfNeeded(&pref_service_);
  EXPECT_TRUE(
      pref_service_.GetBoolean(prefs::kSyncingThemePrefsMigratedToNonSyncing));
  EXPECT_EQ(pref_service_.GetInteger(prefs::kNonSyncingUserColorDoNotUse),
            static_cast<int>(SK_ColorBLUE));
}

TEST_F(ThemePrefsMigrationTest,
       DoNotMigrateSyncingThemePrefsToNonSyncingIfFlagDisabled) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndDisableFeature(syncer::kMoveThemePrefsToSpecifics);

  ASSERT_FALSE(
      pref_service_.GetBoolean(prefs::kSyncingThemePrefsMigratedToNonSyncing));

  MigrateSyncingThemePrefsToNonSyncingIfNeeded(&pref_service_);
  EXPECT_FALSE(
      pref_service_.GetBoolean(prefs::kSyncingThemePrefsMigratedToNonSyncing));
}

TEST_F(ThemePrefsMigrationTest,
       DoNotMigrateSyncingThemePrefsToNonSyncingIfAlreadyDone) {
  base::test::ScopedFeatureList feature_list(
      syncer::kMoveThemePrefsToSpecifics);

  pref_service_.SetBoolean(prefs::kSyncingThemePrefsMigratedToNonSyncing, true);
  pref_service_.SetInteger(prefs::kUserColorDoNotUse, SK_ColorBLUE);

  MigrateSyncingThemePrefsToNonSyncingIfNeeded(&pref_service_);
  EXPECT_FALSE(pref_service_.HasPrefPath(prefs::kNonSyncingUserColorDoNotUse));
}

TEST_F(ThemePrefsMigrationTest,
       ClearFlagUponMigrateSyncingThemePrefsToNonSyncingIfFlagDisabled) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndDisableFeature(syncer::kMoveThemePrefsToSpecifics);

  // Migration has run before.
  pref_service_.SetBoolean(prefs::kSyncingThemePrefsMigratedToNonSyncing, true);

  MigrateSyncingThemePrefsToNonSyncingIfNeeded(&pref_service_);
  // Flag gets cleared to allow re-migration.
  EXPECT_FALSE(
      pref_service_.GetBoolean(prefs::kSyncingThemePrefsMigratedToNonSyncing));
}

class ThemePrefsMigrationShouldReadPrefsTest : public ::testing::Test {
 public:
  syncer::SyncDataList InitialPrefsSyncData() {
    syncer::SyncDataList initial_data;
    initial_data.push_back(CreateRemotePrefsSyncData(
        prefs::kBrowserColorSchemeDoNotUse,
        base::Value(
            static_cast<int>(ThemeService::BrowserColorScheme::kLight))));
    initial_data.push_back(CreateRemotePrefsSyncData(
        prefs::kUserColorDoNotUse, base::Value(static_cast<int>(SK_ColorRED))));
    initial_data.push_back(CreateRemotePrefsSyncData(
        prefs::kBrowserColorVariantDoNotUse,
        base::Value(
            static_cast<int>(ui::mojom::BrowserColorVariant::kTonalSpot))));
    return initial_data;
  }

 protected:
  syncer::SyncData CreateRemotePrefsSyncData(const std::string& name,
                                             const base::Value& value) {
    std::string serialized;
    JSONStringValueSerializer json(&serialized);
    EXPECT_TRUE(json.Serialize(value));
    sync_pb::EntitySpecifics entity_specifics;
    sync_pb::PreferenceSpecifics* specifics =
        entity_specifics.mutable_preference();
    specifics->set_name(name);
    specifics->set_value(serialized);
    return syncer::SyncData::CreateRemoteData(
        entity_specifics, syncer::ClientTagHash::FromUnhashed(
                              syncer::DataType::PREFERENCES, name));
  }

  content::BrowserTaskEnvironment task_environment_;
  TestingProfile profile_;
  ThemeService theme_service_{&profile_, GetThemeHelper()};
  raw_ptr<sync_preferences::TestingPrefServiceSyncable> prefs_ =
      profile_.GetTestingPrefService();
  std::unique_ptr<syncer::FakeSyncChangeProcessor> fake_change_processor_ =
      std::make_unique<syncer::FakeSyncChangeProcessor>();
};

// Verifies that if kMoveThemePrefsToSpecifics feature flag is not set, the
// migration flag is marked unset to allow migration again once the feature flag
// is enabled again.
TEST_F(ThemePrefsMigrationShouldReadPrefsTest,
       ClearShouldReadPrefFlagIfFeatureDisabled) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndDisableFeature(syncer::kMoveThemePrefsToSpecifics);

  // Migration has run before.
  prefs_->SetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs, false);

  ThemeSyncableService theme_syncable_service(&profile_, &theme_service_);

  // Flag gets cleared to allow re-migration.
  EXPECT_TRUE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs));
}

// Verifies that syncing prefs are read upon construction of
// ThemeSyncableService if prefs sync has already started.
TEST_F(ThemePrefsMigrationShouldReadPrefsTest,
       ShouldReadThemePrefsOnContructionIfPrefsAlreadySyncing) {
  base::test::ScopedFeatureList feature_list(
      syncer::kMoveThemePrefsToSpecifics);

  ASSERT_TRUE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs));

  // Start prefs sync.
  syncer::SyncableService* pref_sync_service =
      prefs_->GetSyncableService(syncer::PREFERENCES);
  ASSERT_FALSE(pref_sync_service->MergeDataAndStartSyncing(
      syncer::PREFERENCES, InitialPrefsSyncData(),
      std::make_unique<syncer::SyncChangeProcessorWrapperForTest>(
          fake_change_processor_.get())));

  ASSERT_TRUE(prefs_->IsSyncing());
  ThemeSyncableService theme_syncable_service(&profile_, &theme_service_);

  // Syncing prefs were copied.
  EXPECT_FALSE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs));
  EXPECT_EQ(prefs_->GetInteger(prefs::kNonSyncingBrowserColorSchemeDoNotUse),
            static_cast<int>(ThemeService::BrowserColorScheme::kLight));
  EXPECT_EQ(prefs_->GetInteger(prefs::kNonSyncingUserColorDoNotUse),
            static_cast<int>(SK_ColorRED));
  EXPECT_EQ(prefs_->GetInteger(prefs::kNonSyncingBrowserColorVariantDoNotUse),
            static_cast<int>(ui::mojom::BrowserColorVariant::kTonalSpot));
}

// Verifies that syncing theme prefs are read when prefs sync starts.
TEST_F(ThemePrefsMigrationShouldReadPrefsTest,
       ShouldReadThemePrefsWhenPrefsStartSyncing) {
  base::test::ScopedFeatureList feature_list(
      syncer::kMoveThemePrefsToSpecifics);

  ASSERT_TRUE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs));

  ASSERT_FALSE(prefs_->IsSyncing());
  ThemeSyncableService theme_syncable_service(&profile_, &theme_service_);

  // Start prefs sync.
  syncer::SyncableService* pref_sync_service =
      prefs_->GetSyncableService(syncer::PREFERENCES);
  ASSERT_FALSE(pref_sync_service->MergeDataAndStartSyncing(
      syncer::PREFERENCES, InitialPrefsSyncData(),
      std::make_unique<syncer::SyncChangeProcessorWrapperForTest>(
          fake_change_processor_.get())));

  // Syncing prefs have been copied.
  EXPECT_FALSE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs));
  EXPECT_EQ(prefs_->GetInteger(prefs::kNonSyncingBrowserColorSchemeDoNotUse),
            static_cast<int>(ThemeService::BrowserColorScheme::kLight));
  EXPECT_EQ(prefs_->GetInteger(prefs::kNonSyncingUserColorDoNotUse),
            static_cast<int>(SK_ColorRED));
  EXPECT_EQ(prefs_->GetInteger(prefs::kNonSyncingBrowserColorVariantDoNotUse),
            static_cast<int>(ui::mojom::BrowserColorVariant::kTonalSpot));
}

// Verifies that syncing theme prefs are not read if they have already been read
// before or if the migration flag has already been set.
TEST_F(ThemePrefsMigrationShouldReadPrefsTest,
       ShouldNotReadThemePrefsIfAlreadyRead) {
  base::test::ScopedFeatureList feature_list(
      syncer::kMoveThemePrefsToSpecifics);

  // Mark as already read.
  prefs_->SetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs, false);

  ThemeSyncableService theme_syncable_service(&profile_, &theme_service_);

  // Start prefs sync.
  syncer::SyncableService* pref_sync_service =
      prefs_->GetSyncableService(syncer::PREFERENCES);
  ASSERT_FALSE(pref_sync_service->MergeDataAndStartSyncing(
      syncer::PREFERENCES, InitialPrefsSyncData(),
      std::make_unique<syncer::SyncChangeProcessorWrapperForTest>(
          fake_change_processor_.get())));

  // Prefs are unchanged.
  EXPECT_FALSE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs));
  EXPECT_NE(prefs_->GetInteger(prefs::kNonSyncingBrowserColorSchemeDoNotUse),
            static_cast<int>(ThemeService::BrowserColorScheme::kLight));
  EXPECT_NE(prefs_->GetInteger(prefs::kNonSyncingUserColorDoNotUse),
            static_cast<int>(SK_ColorRED));
  EXPECT_NE(prefs_->GetInteger(prefs::kNonSyncingBrowserColorVariantDoNotUse),
            static_cast<int>(ui::mojom::BrowserColorVariant::kTonalSpot));
}

// Verifies that the migration flag is set and (thus) syncing prefs are not read
// if the incoming ThemeSpecifics contains the new fields.
TEST_F(ThemePrefsMigrationShouldReadPrefsTest,
       ShouldNotReadThemePrefsIfReadViaThemeSpecifics) {
  base::test::ScopedFeatureList feature_list(
      syncer::kMoveThemePrefsToSpecifics);

  ASSERT_TRUE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs));

  ASSERT_FALSE(prefs_->IsSyncing());
  ThemeSyncableService theme_syncable_service(&profile_, &theme_service_);

  sync_pb::ThemeSpecifics theme_specifics;
  theme_specifics.set_browser_color_scheme(
      sync_pb::ThemeSpecifics_BrowserColorScheme_DARK);

  // Start themes sync with specifics containing new field.
  std::optional<syncer::ModelError> error =
      theme_syncable_service.MergeDataAndStartSyncing(
          syncer::THEMES, MakeThemeDataList(theme_specifics),
          std::make_unique<syncer::SyncChangeProcessorWrapperForTest>(
              fake_change_processor_.get()));
  ASSERT_FALSE(error.has_value()) << error.value().message();

  // Migration flag is already set.
  EXPECT_FALSE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs));
  EXPECT_EQ(prefs_->GetInteger(prefs::kNonSyncingBrowserColorSchemeDoNotUse),
            static_cast<int>(ThemeService::BrowserColorScheme::kDark));

  // Start prefs sync.
  syncer::SyncableService* pref_sync_service =
      prefs_->GetSyncableService(syncer::PREFERENCES);
  ASSERT_FALSE(pref_sync_service->MergeDataAndStartSyncing(
      syncer::PREFERENCES, InitialPrefsSyncData(),
      std::make_unique<syncer::SyncChangeProcessorWrapperForTest>(
          fake_change_processor_.get())));

  // Syncing prefs have not been copied since ThemeSpecifics had the new fields.
  EXPECT_FALSE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs));
  EXPECT_NE(prefs_->GetInteger(prefs::kNonSyncingBrowserColorSchemeDoNotUse),
            static_cast<int>(ThemeService::BrowserColorScheme::kLight));
  EXPECT_NE(prefs_->GetInteger(prefs::kNonSyncingUserColorDoNotUse),
            static_cast<int>(SK_ColorRED));
  EXPECT_NE(prefs_->GetInteger(prefs::kNonSyncingBrowserColorVariantDoNotUse),
            static_cast<int>(ui::mojom::BrowserColorVariant::kTonalSpot));
}

// Verifies that syncing theme prefs are read if the incoming ThemeSpecifics
// didn't have the new fields.
TEST_F(ThemePrefsMigrationShouldReadPrefsTest,
       ShouldReadThemePrefsIfThemeSpecificsDoesNotHaveNewFields) {
  base::test::ScopedFeatureList feature_list(
      syncer::kMoveThemePrefsToSpecifics);

  ASSERT_TRUE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs));

  ASSERT_FALSE(prefs_->IsSyncing());
  ThemeSyncableService theme_syncable_service(&profile_, &theme_service_);

  sync_pb::ThemeSpecifics theme_specifics;
  theme_specifics.mutable_autogenerated_color_theme()->set_color(SK_ColorBLUE);

  // Start themes sync with specifics containing new field.
  ASSERT_FALSE(theme_syncable_service.MergeDataAndStartSyncing(
      syncer::THEMES, MakeThemeDataList(theme_specifics),
      std::make_unique<syncer::SyncChangeProcessorWrapperForTest>(
          fake_change_processor_.get())));

  EXPECT_TRUE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs));

  // Start prefs sync.
  syncer::SyncableService* pref_sync_service =
      prefs_->GetSyncableService(syncer::PREFERENCES);
  ASSERT_FALSE(pref_sync_service->MergeDataAndStartSyncing(
      syncer::PREFERENCES, InitialPrefsSyncData(),
      std::make_unique<syncer::SyncChangeProcessorWrapperForTest>(
          fake_change_processor_.get())));

  // Syncing prefs copied since ThemeSpecifics didn't have the new fields.
  EXPECT_FALSE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs));
  EXPECT_EQ(prefs_->GetInteger(prefs::kNonSyncingBrowserColorSchemeDoNotUse),
            static_cast<int>(ThemeService::BrowserColorScheme::kLight));
  EXPECT_EQ(prefs_->GetInteger(prefs::kNonSyncingUserColorDoNotUse),
            static_cast<int>(SK_ColorRED));
  EXPECT_EQ(prefs_->GetInteger(prefs::kNonSyncingBrowserColorVariantDoNotUse),
            static_cast<int>(ui::mojom::BrowserColorVariant::kTonalSpot));
}

// Verifies that the incoming ThemeSpecifics overwrites the value copied from
// the syncing theme prefs.
TEST_F(ThemePrefsMigrationShouldReadPrefsTest, ShouldPrioritizeThemeSpecifics) {
  base::test::ScopedFeatureList feature_list(
      syncer::kMoveThemePrefsToSpecifics);

  ASSERT_TRUE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs));

  ASSERT_FALSE(prefs_->IsSyncing());
  ThemeSyncableService theme_syncable_service(&profile_, &theme_service_);

  // Start prefs sync.
  syncer::SyncableService* pref_sync_service =
      prefs_->GetSyncableService(syncer::PREFERENCES);
  ASSERT_FALSE(pref_sync_service->MergeDataAndStartSyncing(
      syncer::PREFERENCES, InitialPrefsSyncData(),
      std::make_unique<syncer::SyncChangeProcessorWrapperForTest>(
          fake_change_processor_.get())));

  EXPECT_FALSE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs));
  EXPECT_EQ(prefs_->GetInteger(prefs::kNonSyncingBrowserColorSchemeDoNotUse),
            static_cast<int>(ThemeService::BrowserColorScheme::kLight));

  sync_pb::ThemeSpecifics theme_specifics;
  theme_specifics.set_browser_color_scheme(
      sync_pb::ThemeSpecifics_BrowserColorScheme_DARK);

  // Start themes sync with specifics containing new field.
  ASSERT_FALSE(theme_syncable_service.MergeDataAndStartSyncing(
      syncer::THEMES, MakeThemeDataList(theme_specifics),
      std::make_unique<syncer::SyncChangeProcessorWrapperForTest>(
          fake_change_processor_.get())));

  EXPECT_FALSE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs));
  // Overwrites the theme set by prefs.
  EXPECT_EQ(prefs_->GetInteger(prefs::kNonSyncingBrowserColorSchemeDoNotUse),
            static_cast<int>(ThemeService::BrowserColorScheme::kDark));
}
