// 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/extensions/extension_prefs_unittest.h"

#include <algorithm>
#include <memory>
#include <optional>
#include <utility>

#include "base/files/scoped_temp_dir.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/scoped_observation.h"
#include "base/strings/string_number_conversions.h"
#include "base/task/single_thread_task_runner.h"
#include "base/time/time.h"
#include "base/values.h"
#include "chrome/browser/extensions/install_tracker.h"
#include "chrome/common/chrome_paths.h"
#include "components/content_settings/core/browser/content_settings_registry.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/mock_pref_change_callback.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "components/sync/model/string_ordinal.h"
#include "components/sync_preferences/pref_service_syncable.h"
#include "extensions/browser/blocklist_extension_prefs.h"
#include "extensions/browser/blocklist_state.h"
#include "extensions/browser/disable_reason.h"
#include "extensions/browser/extension_pref_value_map.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_prefs_observer.h"
#include "extensions/browser/install_flag.h"
#include "extensions/browser/install_prefs_helper.h"
#include "extensions/browser/pref_names.h"
#include "extensions/browser/pref_types.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_builder.h"
#include "extensions/common/extension_id.h"
#include "extensions/common/manifest_constants.h"
#include "extensions/common/permissions/permission_set.h"
#include "extensions/common/permissions/permissions_info.h"
#include "testing/gmock/include/gmock/gmock.h"

using base::Time;
using extensions::mojom::APIPermissionID;
using extensions::mojom::ManifestLocation;

namespace extensions {

static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
  int schemes = URLPattern::SCHEME_ALL;
  extent->AddPattern(URLPattern(schemes, pattern));
}

ExtensionPrefsTest::ExtensionPrefsTest()
    : prefs_(base::SingleThreadTaskRunner::GetCurrentDefault()) {}

ExtensionPrefsTest::~ExtensionPrefsTest() = default;

void ExtensionPrefsTest::RegisterPreferences(
    user_prefs::PrefRegistrySyncable* registry) {}

void ExtensionPrefsTest::SetUp() {
  RegisterPreferences(prefs_.pref_registry().get());
  Initialize();
}

void ExtensionPrefsTest::TearDown() {
  Verify();

  // Shutdown the InstallTracker early, which is a dependency on some
  // ExtensionPrefTests (and depends on PrefService being available in
  // shutdown).
  InstallTracker::Get(prefs_.profile())->Shutdown();

  // Reset ExtensionPrefs, and re-verify.
  prefs_.ResetPrefRegistry();
  RegisterPreferences(prefs_.pref_registry().get());
  prefs_.RecreateExtensionPrefs();
  Verify();
  prefs_.pref_service()->CommitPendingWrite();
  base::RunLoop().RunUntilIdle();
}

// Tests the LastPingDay/SetLastPingDay functions.
class ExtensionPrefsLastPingDay : public ExtensionPrefsTest {
 public:
  ExtensionPrefsLastPingDay()
      : extension_time_(Time::Now() - base::Hours(4)),
        blocklist_time_(Time::Now() - base::Hours(2)) {}

  void Initialize() override {
    extension_id_ = prefs_.AddExtensionAndReturnId("last_ping_day");
    EXPECT_TRUE(prefs()->LastPingDay(extension_id_).is_null());
    prefs()->SetLastPingDay(extension_id_, extension_time_);
    prefs()->SetBlocklistLastPingDay(blocklist_time_);
  }

  void Verify() override {
    Time result = prefs()->LastPingDay(extension_id_);
    EXPECT_FALSE(result.is_null());
    EXPECT_TRUE(result == extension_time_);
    result = prefs()->BlocklistLastPingDay();
    EXPECT_FALSE(result.is_null());
    EXPECT_TRUE(result == blocklist_time_);
  }

 private:
  Time extension_time_;
  Time blocklist_time_;
  ExtensionId extension_id_;
};
TEST_F(ExtensionPrefsLastPingDay, LastPingDay) {}

// Tests the migration of a deprecated disable reason.
class ExtensionPrefsDeprecatedDisableReason : public ExtensionPrefsTest {
 public:
  void Initialize() override {
    extension1_ = prefs_.AddExtension("test1");
    DisableReasonSet disable_reasons = {
        disable_reason::DEPRECATED_DISABLE_UNKNOWN_FROM_SYNC};
    prefs()->AddDisableReasons(extension1_->id(), disable_reasons);
    extension2_ = prefs_.AddExtension("test2");
    disable_reasons.insert(disable_reason::DISABLE_PERMISSIONS_INCREASE);
    prefs()->AddDisableReasons(extension2_->id(), disable_reasons);
    prefs()->MigrateDeprecatedDisableReasons();
  }

  void Verify() override {
    EXPECT_THAT(
        prefs()->GetDisableReasons(extension1_->id()),
        testing::UnorderedElementsAre(disable_reason::DISABLE_USER_ACTION));
    // Verify that if an extension has a disable reason in addition to the
    // deprecated reason, we don't add the user action disable reason.
    EXPECT_THAT(prefs()->GetDisableReasons(extension2_->id()),
                testing::UnorderedElementsAre(
                    disable_reason::DISABLE_PERMISSIONS_INCREASE));
  }

 private:
  scoped_refptr<Extension> extension1_;
  scoped_refptr<Extension> extension2_;
};

TEST_F(ExtensionPrefsDeprecatedDisableReason, MigrateExtensionState) {}

class ExtensionPrefsEscalatePermissions : public ExtensionPrefsTest {
 public:
  void Initialize() override {
    extension = prefs_.AddExtension("test");
    prefs()->AddDisableReasons(extension->id(),
                               {disable_reason::DISABLE_PERMISSIONS_INCREASE});
  }

  void Verify() override {
    EXPECT_TRUE(prefs()->DidExtensionEscalatePermissions(extension->id()));
  }

 private:
  scoped_refptr<Extension> extension;
};
TEST_F(ExtensionPrefsEscalatePermissions, EscalatePermissions) {}

// Tests the AddGrantedPermissions / GetGrantedPermissions functions.
class ExtensionPrefsGrantedPermissions : public ExtensionPrefsTest {
 public:
  void Initialize() override {
    const APIPermissionInfo* permission_info =
        PermissionsInfo::GetInstance()->GetByID(
            mojom::APIPermissionID::kSocket);

    extension_id_ = prefs_.AddExtensionAndReturnId("test");

    api_perm_set1_.insert(APIPermissionID::kTab);
    api_perm_set1_.insert(APIPermissionID::kBookmark);
    std::unique_ptr<APIPermission> permission(
        permission_info->CreateAPIPermission());
    {
      base::Value::List list;
      list.Append("tcp-connect:*.example.com:80");
      list.Append("udp-bind::8080");
      list.Append("udp-send-to::8888");
      base::Value value(std::move(list));
      ASSERT_TRUE(permission->FromValue(&value, nullptr, nullptr));
    }
    api_perm_set1_.insert(std::move(permission));

    api_perm_set2_.insert(APIPermissionID::kHistory);

    AddPattern(&ehost_perm_set1_, "http://*.google.com/*");
    AddPattern(&ehost_perm_set1_, "http://example.com/*");
    AddPattern(&ehost_perm_set1_, "chrome://favicon/*");

    AddPattern(&ehost_perm_set2_, "https://*.google.com/*");
    // with duplicate:
    AddPattern(&ehost_perm_set2_, "http://*.google.com/*");

    AddPattern(&shost_perm_set1_, "http://reddit.com/r/test/*");
    AddPattern(&shost_perm_set2_, "http://reddit.com/r/test/*");
    AddPattern(&shost_perm_set2_, "http://somesite.com/*");
    AddPattern(&shost_perm_set2_, "http://example.com/*");

    APIPermissionSet expected_apis = api_perm_set1_.Clone();

    AddPattern(&ehost_permissions_, "http://*.google.com/*");
    AddPattern(&ehost_permissions_, "http://example.com/*");
    AddPattern(&ehost_permissions_, "chrome://favicon/*");
    AddPattern(&ehost_permissions_, "https://*.google.com/*");

    AddPattern(&shost_permissions_, "http://reddit.com/r/test/*");
    AddPattern(&shost_permissions_, "http://somesite.com/*");
    AddPattern(&shost_permissions_, "http://example.com/*");

    // Make sure both granted api and host permissions start empty.
    EXPECT_TRUE(prefs()->GetGrantedPermissions(extension_id_)->IsEmpty());

    {
      // Add part of the api permissions.
      prefs()->AddGrantedPermissions(
          extension_id_,
          PermissionSet(api_perm_set1_.Clone(), ManifestPermissionSet(),
                        URLPatternSet(), URLPatternSet()));
      std::unique_ptr<const PermissionSet> granted_permissions =
          prefs()->GetGrantedPermissions(extension_id_);
      EXPECT_TRUE(granted_permissions.get());
      EXPECT_FALSE(granted_permissions->IsEmpty());
      EXPECT_EQ(expected_apis, granted_permissions->apis());
      EXPECT_TRUE(granted_permissions->effective_hosts().is_empty());
    }

    {
      // Add part of the explicit host permissions.
      prefs()->AddGrantedPermissions(
          extension_id_,
          PermissionSet(APIPermissionSet(), ManifestPermissionSet(),
                        ehost_perm_set1_.Clone(), URLPatternSet()));
      std::unique_ptr<const PermissionSet> granted_permissions =
          prefs()->GetGrantedPermissions(extension_id_);
      EXPECT_FALSE(granted_permissions->IsEmpty());
      EXPECT_EQ(expected_apis, granted_permissions->apis());
      EXPECT_EQ(ehost_perm_set1_, granted_permissions->explicit_hosts());
      EXPECT_EQ(ehost_perm_set1_, granted_permissions->effective_hosts());
    }

    {
      // Add part of the scriptable host permissions.
      prefs()->AddGrantedPermissions(
          extension_id_,
          PermissionSet(APIPermissionSet(), ManifestPermissionSet(),
                        URLPatternSet(), shost_perm_set1_.Clone()));
      std::unique_ptr<const PermissionSet> granted_permissions =
          prefs()->GetGrantedPermissions(extension_id_);
      EXPECT_FALSE(granted_permissions->IsEmpty());
      EXPECT_EQ(expected_apis, granted_permissions->apis());
      EXPECT_EQ(ehost_perm_set1_, granted_permissions->explicit_hosts());
      EXPECT_EQ(shost_perm_set1_, granted_permissions->scriptable_hosts());

      effective_permissions_ =
          URLPatternSet::CreateUnion(ehost_perm_set1_, shost_perm_set1_);
      EXPECT_EQ(effective_permissions_, granted_permissions->effective_hosts());
    }

    {
      // Add the rest of the permissions.
      APIPermissionSet::Union(expected_apis, api_perm_set2_, &api_permissions_);
      prefs()->AddGrantedPermissions(
          extension_id_,
          PermissionSet(api_perm_set2_.Clone(), ManifestPermissionSet(),
                        ehost_perm_set2_.Clone(), shost_perm_set2_.Clone()));

      std::unique_ptr<const PermissionSet> granted_permissions =
          prefs()->GetGrantedPermissions(extension_id_);
      EXPECT_TRUE(granted_permissions.get());
      EXPECT_FALSE(granted_permissions->IsEmpty());
      EXPECT_EQ(api_permissions_, granted_permissions->apis());
      EXPECT_EQ(ehost_permissions_, granted_permissions->explicit_hosts());
      EXPECT_EQ(shost_permissions_, granted_permissions->scriptable_hosts());
      effective_permissions_ =
          URLPatternSet::CreateUnion(ehost_permissions_, shost_permissions_);
      EXPECT_EQ(effective_permissions_, granted_permissions->effective_hosts());
    }
  }

  void Verify() override {
    std::unique_ptr<const PermissionSet> permissions =
        prefs()->GetGrantedPermissions(extension_id_);
    EXPECT_TRUE(permissions.get());
    EXPECT_EQ(api_permissions_, permissions->apis());
    EXPECT_EQ(ehost_permissions_, permissions->explicit_hosts());
    EXPECT_EQ(shost_permissions_, permissions->scriptable_hosts());
  }

 private:
  ExtensionId extension_id_;
  APIPermissionSet api_perm_set1_;
  APIPermissionSet api_perm_set2_;
  URLPatternSet ehost_perm_set1_;
  URLPatternSet ehost_perm_set2_;
  URLPatternSet shost_perm_set1_;
  URLPatternSet shost_perm_set2_;

  APIPermissionSet api_permissions_;
  URLPatternSet ehost_permissions_;
  URLPatternSet shost_permissions_;
  URLPatternSet effective_permissions_;
};
TEST_F(ExtensionPrefsGrantedPermissions, GrantedPermissions) {}

// Tests the SetDesiredActivePermissions / GetDesiredActivePermissions
// functions.
class ExtensionPrefsActivePermissions : public ExtensionPrefsTest {
 public:
  void Initialize() override {
    extension_id_ = prefs_.AddExtensionAndReturnId("test");

    {
      APIPermissionSet api_perms;
      api_perms.insert(APIPermissionID::kTab);
      api_perms.insert(APIPermissionID::kBookmark);
      api_perms.insert(APIPermissionID::kHistory);

      URLPatternSet ehosts;
      AddPattern(&ehosts, "http://*.google.com/*");
      AddPattern(&ehosts, "http://example.com/*");
      AddPattern(&ehosts, "chrome://favicon/*");

      URLPatternSet shosts;
      AddPattern(&shosts, "https://*.google.com/*");
      AddPattern(&shosts, "http://reddit.com/r/test/*");

      active_perms_ = std::make_unique<PermissionSet>(
          std::move(api_perms), ManifestPermissionSet(), std::move(ehosts),
          std::move(shosts));
    }

    // Make sure the active permissions start empty.
    std::unique_ptr<const PermissionSet> active =
        prefs()->GetDesiredActivePermissions(extension_id_);
    EXPECT_TRUE(active->IsEmpty());

    // Set the desired active permissions.
    prefs()->SetDesiredActivePermissions(extension_id_, *active_perms_);
    active = prefs()->GetDesiredActivePermissions(extension_id_);
    EXPECT_EQ(active_perms_->apis(), active->apis());
    EXPECT_EQ(active_perms_->explicit_hosts(), active->explicit_hosts());
    EXPECT_EQ(active_perms_->scriptable_hosts(), active->scriptable_hosts());
    EXPECT_EQ(*active_perms_, *active);

    // Reset the desired active permissions.
    active_perms_ = std::make_unique<PermissionSet>();
    prefs()->SetDesiredActivePermissions(extension_id_, *active_perms_);
    active = prefs()->GetDesiredActivePermissions(extension_id_);
    EXPECT_EQ(*active_perms_, *active);
  }

  void Verify() override {
    std::unique_ptr<const PermissionSet> permissions =
        prefs()->GetDesiredActivePermissions(extension_id_);
    EXPECT_EQ(*active_perms_, *permissions);
  }

 private:
  ExtensionId extension_id_;
  std::unique_ptr<const PermissionSet> active_perms_;
};
TEST_F(ExtensionPrefsActivePermissions, SetAndGetDesiredActivePermissions) {}

// Tests the GetVersionString function.
class ExtensionPrefsVersionString : public ExtensionPrefsTest {
 public:
  void Initialize() override {
    extension = prefs_.AddExtension("test");
    EXPECT_EQ("0.1", prefs()->GetVersionString(extension->id()));
    prefs()->OnExtensionUninstalled(extension->id(),
                                    ManifestLocation::kInternal, false);
  }

  void Verify() override {
    EXPECT_EQ("", prefs()->GetVersionString(extension->id()));
  }

 private:
  scoped_refptr<Extension> extension;
};
TEST_F(ExtensionPrefsVersionString, VersionString) {}

class ExtensionPrefsAcknowledgment : public ExtensionPrefsTest {
 public:
  void Initialize() override {
    not_installed_id_ = "pghjnghklobnfoidcldiidjjjhkeeaoi";

    // Install some extensions.
    for (int i = 0; i < 5; i++) {
      std::string name = "test" + base::NumberToString(i);
      extensions_.push_back(prefs_.AddExtension(name));
    }
    EXPECT_EQ(std::nullopt,
              prefs()->GetInstalledExtensionInfo(not_installed_id_));

    ExtensionList::const_iterator iter;
    for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) {
      std::string id = (*iter)->id();
      EXPECT_FALSE(prefs()->IsExternalExtensionAcknowledged(id));
      EXPECT_FALSE(prefs()->IsBlocklistedExtensionAcknowledged(id));
      if (external_id_.empty()) {
        external_id_ = id;
        continue;
      }
      if (blocklisted_id_.empty()) {
        blocklisted_id_ = id;
        continue;
      }
    }
    // For each type of acknowledgment, acknowledge one installed and one
    // not-installed extension id.
    prefs()->AcknowledgeExternalExtension(external_id_);
    prefs()->AcknowledgeBlocklistedExtension(blocklisted_id_);
    prefs()->AcknowledgeExternalExtension(not_installed_id_);
    prefs()->AcknowledgeBlocklistedExtension(not_installed_id_);
  }

  void Verify() override {
    ExtensionList::const_iterator iter;
    for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) {
      std::string id = (*iter)->id();
      if (id == external_id_) {
        EXPECT_TRUE(prefs()->IsExternalExtensionAcknowledged(id));
      } else {
        EXPECT_FALSE(prefs()->IsExternalExtensionAcknowledged(id));
      }
      if (id == blocklisted_id_) {
        EXPECT_TRUE(prefs()->IsBlocklistedExtensionAcknowledged(id));
      } else {
        EXPECT_FALSE(prefs()->IsBlocklistedExtensionAcknowledged(id));
      }
    }
    EXPECT_TRUE(prefs()->IsExternalExtensionAcknowledged(not_installed_id_));
    EXPECT_TRUE(prefs()->IsBlocklistedExtensionAcknowledged(not_installed_id_));
  }

 private:
  ExtensionList extensions_;

  std::string not_installed_id_;
  std::string external_id_;
  std::string blocklisted_id_;
};
TEST_F(ExtensionPrefsAcknowledgment, Acknowledgment) {}

// Tests the idle install information functions.
class ExtensionPrefsDelayedInstallInfo : public ExtensionPrefsTest {
 public:
  // Sets idle install information for one test extension.
  void SetIdleInfo(const std::string& id, int num) {
    base::Value::Dict manifest;
    manifest.Set(manifest_keys::kName, "test");
    manifest.Set(manifest_keys::kVersion, "1." + base::NumberToString(num));
    manifest.Set(manifest_keys::kManifestVersion, 2);
    base::FilePath path =
        prefs_.extensions_dir().AppendASCII(base::NumberToString(num));
    std::string errors;
    scoped_refptr<Extension> extension =
        Extension::Create(path, ManifestLocation::kInternal, manifest,
                          Extension::NO_FLAGS, id, &errors);
    ASSERT_TRUE(extension.get()) << errors;
    ASSERT_EQ(id, extension->id());
    prefs()->SetDelayedInstallInfo(extension.get(), /*disable_reasons=*/{},
                                   kInstallFlagNone,
                                   ExtensionPrefs::DelayReason::kWaitForIdle,
                                   syncer::StringOrdinal(), std::string());
  }

  // Verifies that we get back expected idle install information previously
  // set by SetIdleInfo.
  void VerifyIdleInfo(const std::string& id, int num) {
    std::optional<ExtensionInfo> info(prefs()->GetDelayedInstallInfo(id));
    ASSERT_TRUE(info);
    const std::string* version =
        info->extension_manifest->FindString("version");
    ASSERT_TRUE(version);
    ASSERT_EQ("1." + base::NumberToString(num), *version);
    ASSERT_EQ(base::NumberToString(num),
              info->extension_path.BaseName().MaybeAsASCII());
  }

  bool HasInfoForId(const ExtensionPrefs::ExtensionsInfo& info,
                    const std::string& id) {
    return std::ranges::find_if(info.begin(), info.end(),
                                [&id](const ExtensionInfo& info) {
                                  return info.extension_id == id;
                                }) != info.end();
  }

  void Initialize() override {
    base::PathService::Get(chrome::DIR_TEST_DATA, &basedir_);
    now_ = Time::Now();
    id1_ = prefs_.AddExtensionAndReturnId("1");
    id2_ = prefs_.AddExtensionAndReturnId("2");
    id3_ = prefs_.AddExtensionAndReturnId("3");
    id4_ = prefs_.AddExtensionAndReturnId("4");

    // Set info for two extensions, then remove it.
    SetIdleInfo(id1_, 1);
    SetIdleInfo(id2_, 2);
    VerifyIdleInfo(id1_, 1);
    VerifyIdleInfo(id2_, 2);
    ExtensionPrefs::ExtensionsInfo info = prefs()->GetAllDelayedInstallInfo();
    EXPECT_EQ(2u, info.size());
    EXPECT_TRUE(HasInfoForId(info, id1_));
    EXPECT_TRUE(HasInfoForId(info, id2_));
    prefs()->RemoveDelayedInstallInfo(id1_);
    prefs()->RemoveDelayedInstallInfo(id2_);
    info = prefs()->GetAllDelayedInstallInfo();
    EXPECT_TRUE(info.empty());

    // Try getting/removing info for an id that used to have info set.
    EXPECT_FALSE(prefs()->GetDelayedInstallInfo(id1_));
    EXPECT_FALSE(prefs()->RemoveDelayedInstallInfo(id1_));

    // Try getting/removing info for an id that has not yet had any info set.
    EXPECT_FALSE(prefs()->GetDelayedInstallInfo(id3_));
    EXPECT_FALSE(prefs()->RemoveDelayedInstallInfo(id3_));

    // Set info for 4 extensions, then remove for one of them.
    SetIdleInfo(id1_, 1);
    SetIdleInfo(id2_, 2);
    SetIdleInfo(id3_, 3);
    SetIdleInfo(id4_, 4);
    VerifyIdleInfo(id1_, 1);
    VerifyIdleInfo(id2_, 2);
    VerifyIdleInfo(id3_, 3);
    VerifyIdleInfo(id4_, 4);
    prefs()->RemoveDelayedInstallInfo(id3_);
  }

  void Verify() override {
    // Make sure the info for the 3 extensions we expect is present.
    ExtensionPrefs::ExtensionsInfo info = prefs()->GetAllDelayedInstallInfo();
    EXPECT_EQ(3u, info.size());
    EXPECT_TRUE(HasInfoForId(info, id1_));
    EXPECT_TRUE(HasInfoForId(info, id2_));
    EXPECT_TRUE(HasInfoForId(info, id4_));
    VerifyIdleInfo(id1_, 1);
    VerifyIdleInfo(id2_, 2);
    VerifyIdleInfo(id4_, 4);

    // Make sure there isn't info the for the one extension id we removed.
    EXPECT_FALSE(prefs()->GetDelayedInstallInfo(id3_));
  }

 protected:
  Time now_;
  base::FilePath basedir_;
  std::string id1_;
  std::string id2_;
  std::string id3_;
  std::string id4_;
};
TEST_F(ExtensionPrefsDelayedInstallInfo, DelayedInstallInfo) {}

// Tests the FinishDelayedInstallInfo function.
class ExtensionPrefsFinishDelayedInstallInfo : public ExtensionPrefsTest {
 public:
  void Initialize() override {
    base::Value::Dict dictionary;
    dictionary.Set(manifest_keys::kName, "test");
    dictionary.Set(manifest_keys::kVersion, "0.1");
    dictionary.Set(manifest_keys::kManifestVersion, 2);
    dictionary.SetByDottedPath(manifest_keys::kBackgroundPage,
                               "background.html");
    scoped_refptr<Extension> extension = prefs_.AddExtensionWithManifest(
        dictionary, ManifestLocation::kInternal);
    id_ = extension->id();

    // Set idle info
    base::Value::Dict manifest;
    manifest.Set(manifest_keys::kName, "test");
    manifest.Set(manifest_keys::kVersion, "0.2");
    manifest.Set(manifest_keys::kManifestVersion, 2);
    base::Value::List scripts;
    scripts.Append("test.js");
    manifest.SetByDottedPath(manifest_keys::kBackgroundScripts,
                             std::move(scripts));
    base::FilePath path = prefs_.extensions_dir().AppendASCII("test_0.2");
    std::string errors;
    scoped_refptr<Extension> new_extension =
        Extension::Create(path, ManifestLocation::kInternal, manifest,
                          Extension::NO_FLAGS, id_, &errors);
    ASSERT_TRUE(new_extension.get()) << errors;
    ASSERT_EQ(id_, new_extension->id());
    prefs()->SetDelayedInstallInfo(new_extension.get(), /*disable_reasons=*/{},
                                   kInstallFlagNone,
                                   ExtensionPrefs::DelayReason::kWaitForIdle,
                                   syncer::StringOrdinal(), "Param");

    // Finish idle installation
    ASSERT_TRUE(prefs()->FinishDelayedInstallInfo(id_));
  }

  void Verify() override {
    EXPECT_FALSE(prefs()->GetDelayedInstallInfo(id_));
    EXPECT_EQ(std::string("Param"), GetInstallParam(prefs(), id_));

    const base::Value::Dict* dict = prefs()->ReadPrefAsDict(id_, "manifest");
    ASSERT_TRUE(dict);
    const std::string* name = dict->FindString(manifest_keys::kName);
    ASSERT_TRUE(name);
    EXPECT_EQ("test", *name);
    const std::string* version = dict->FindString(manifest_keys::kVersion);
    ASSERT_TRUE(version);
    EXPECT_EQ("0.2", *version);
    EXPECT_FALSE(dict->FindString(manifest_keys::kBackgroundPage));
    const base::Value::List* scripts =
        dict->FindListByDottedPath(manifest_keys::kBackgroundScripts);
    ASSERT_TRUE(scripts);
    EXPECT_EQ(1u, scripts->size());
  }

 protected:
  std::string id_;
};

TEST_F(ExtensionPrefsFinishDelayedInstallInfo, FinishDelayedInstallInfo) {}

class ExtensionPrefsOnExtensionInstalled : public ExtensionPrefsTest {
 public:
  void Initialize() override {
    extension_ = prefs_.AddExtension("on_extension_installed");
    EXPECT_FALSE(prefs()->IsExtensionDisabled(extension_->id()));
    prefs()->OnExtensionInstalled(extension_.get(),
                                  {disable_reason::DISABLE_USER_ACTION},
                                  syncer::StringOrdinal(), "Param");
  }

  void Verify() override {
    EXPECT_TRUE(prefs()->IsExtensionDisabled(extension_->id()));
    EXPECT_EQ(std::string("Param"), GetInstallParam(prefs(), extension_->id()));
  }

 private:
  scoped_refptr<Extension> extension_;
};
TEST_F(ExtensionPrefsOnExtensionInstalled, ExtensionPrefsOnExtensionInstalled) {
}

class ExtensionPrefsPopulatesInstallTimePrefs : public ExtensionPrefsTest {
 public:
  void Initialize() override {
    extension_ = prefs_.AddExtension("test1");
    // Cache the first install time.
    first_install_time_ = GetFirstInstallTime(prefs(), extension_->id());
    auto last_update_time = GetLastUpdateTime(prefs(), extension_->id());
    // First time install will result in same value for both first_install_time
    // and last_update_time prefs.
    EXPECT_NE(base::Time(), first_install_time_);
    EXPECT_NE(base::Time(), last_update_time);
    EXPECT_EQ(first_install_time_, last_update_time);

    // Update the extension.
    extension_ = prefs_.AddExtension("test1");
  }

  void Verify() override {
    auto first_install_time = GetFirstInstallTime(prefs(), extension_->id());
    auto last_update_time = GetLastUpdateTime(prefs(), extension_->id());
    EXPECT_NE(base::Time(), first_install_time);
    EXPECT_NE(base::Time(), last_update_time);
    // Verify that the first_install_time remains unchanged after the extension
    // update.
    EXPECT_EQ(first_install_time, first_install_time_);
    // Verify that the last_update_time is no longer the same as the
    // first_install_time after the extension update.
    EXPECT_NE(first_install_time, last_update_time);
  }

 private:
  scoped_refptr<Extension> extension_;
  base::Time first_install_time_;
};
TEST_F(ExtensionPrefsPopulatesInstallTimePrefs,
       ExtensionPrefsPopulatesInstallTimePrefs) {}

class ExtensionPrefsMigratesToLastUpdateTime : public ExtensionPrefsTest {
 public:
  void Initialize() override {
    extension_ = prefs_.AddExtension("test1");
    // Re-create migration scenario by removing the new first_install_time,
    // last_update_time pref keys and adding back the legacy install_time key.
    prefs()->UpdateExtensionPref(extension_->id(), kLastUpdateTimePrefKey,
                                 std::nullopt);
    prefs()->UpdateExtensionPref(extension_->id(), kFirstInstallTimePrefKey,
                                 std::nullopt);
    time_str_ = base::NumberToString(
        base::Time::Now().ToDeltaSinceWindowsEpoch().InMicroseconds());
    prefs()->SetStringPref(extension_->id(), kOldInstallTimePrefMap, time_str_);

    // Run the migration routine.
    prefs()->BackfillAndMigrateInstallTimePrefs();
  }

  void Verify() override {
    auto* dict = prefs()->GetExtensionPref(extension_->id());

    // Verify the legacy install_time key has been removed and replaced by
    // the last_update_time key. Also verify that the first_install_time key
    // has been added and has the same value as the last_update_time key.
    EXPECT_FALSE(dict->FindString(kOldInstallTimePrefKey));
    const std::string* first_install_time =
        dict->FindString(kFirstInstallTimePrefKey);
    ASSERT_TRUE(first_install_time);
    EXPECT_EQ(*first_install_time, time_str_);
    const std::string* last_update_time =
        dict->FindString(kLastUpdateTimePrefKey);
    ASSERT_TRUE(last_update_time);
    EXPECT_EQ(*last_update_time, time_str_);
  }

 private:
  scoped_refptr<Extension> extension_;
  std::string time_str_;
  static constexpr char kFirstInstallTimePrefKey[] = "first_install_time";
  static constexpr char kLastUpdateTimePrefKey[] = "last_update_time";
  static constexpr char kOldInstallTimePrefKey[] = "install_time";
  static constexpr PrefMap kOldInstallTimePrefMap = {
      kOldInstallTimePrefKey, PrefType::kString, PrefScope::kExtensionSpecific};
};
TEST_F(ExtensionPrefsMigratesToLastUpdateTime,
       ExtensionPrefsMigratesToLastUpdateTime) {}

// Tests that the bit map pref value is cleared if the value matches the default
// bit.
class ExtensionPrefsBitMapPrefValueClearedIfEqualsDefaultValue
    : public ExtensionPrefsTest {
 public:
  void Initialize() override {
    extension_ = prefs_.AddExtension("test1");
    prefs()->ModifyBitMapPrefBits(
        extension_->id(), disable_reason::DISABLE_PERMISSIONS_INCREASE,
        ExtensionPrefs::BitMapPrefOperation::kAdd, "disable_reasons",
        disable_reason::DISABLE_USER_ACTION);
    // Set the bit map pref value to the default value, it should clear the
    // pref.
    prefs()->ModifyBitMapPrefBits(
        extension_->id(), disable_reason::DISABLE_USER_ACTION,
        ExtensionPrefs::BitMapPrefOperation::kReplace, "disable_reasons",
        disable_reason::DISABLE_USER_ACTION);
  }

  void Verify() override {
    const base::Value::Dict* ext = prefs()->GetExtensionPref(extension_->id());
    ASSERT_TRUE(ext);
    // The pref value should be cleared.
    EXPECT_FALSE(ext->FindInt("disable_reasons"));
  }

 private:
  scoped_refptr<Extension> extension_;
};

TEST_F(ExtensionPrefsBitMapPrefValueClearedIfEqualsDefaultValue,
       ExtensionPrefsBitMapPrefValueClearedIfEqualsDefaultValue) {}

class ExtensionPrefsFlags : public ExtensionPrefsTest {
 public:
  void Initialize() override {
    {
      base::Value::Dict dictionary;
      dictionary.Set(manifest_keys::kName, "from_webstore");
      dictionary.Set(manifest_keys::kVersion, "0.1");
      dictionary.Set(manifest_keys::kManifestVersion, 2);
      webstore_extension_ = prefs_.AddExtensionWithManifestAndFlags(
          dictionary, ManifestLocation::kInternal, Extension::FROM_WEBSTORE);
    }

    {
      base::Value::Dict dictionary;
      dictionary.Set(manifest_keys::kName, "was_installed_by_default");
      dictionary.Set(manifest_keys::kVersion, "0.1");
      dictionary.Set(manifest_keys::kManifestVersion, 2);
      default_extension_ = prefs_.AddExtensionWithManifestAndFlags(
          dictionary, ManifestLocation::kInternal,
          Extension::WAS_INSTALLED_BY_DEFAULT);
    }

    {
      base::Value::Dict dictionary;
      dictionary.Set(manifest_keys::kName, "was_installed_by_oem");
      dictionary.Set(manifest_keys::kVersion, "0.1");
      dictionary.Set(manifest_keys::kManifestVersion, 2);
      oem_extension_ = prefs_.AddExtensionWithManifestAndFlags(
          dictionary, ManifestLocation::kInternal,
          Extension::WAS_INSTALLED_BY_OEM);
    }
  }

  void Verify() override {
    EXPECT_TRUE(IsFromWebStore(prefs(), webstore_extension_->id()));
    EXPECT_TRUE(WasInstalledByDefault(prefs(), default_extension_->id()));
    EXPECT_TRUE(WasInstalledByOem(prefs(), oem_extension_->id()));
  }

 private:
  scoped_refptr<Extension> webstore_extension_;
  scoped_refptr<Extension> default_extension_;
  scoped_refptr<Extension> oem_extension_;
};
TEST_F(ExtensionPrefsFlags, ExtensionPrefsFlags) {}

PrefsPrepopulatedTestBase::PrefsPrepopulatedTestBase() {
  base::Value::Dict simple_dict;
  std::string error;

  simple_dict.Set(manifest_keys::kVersion, "1.0.0.0");
  simple_dict.Set(manifest_keys::kManifestVersion, 2);
  simple_dict.Set(manifest_keys::kName, "unused");

  extension1_ = Extension::Create(prefs_.temp_dir().AppendASCII("ext1_"),
                                  ManifestLocation::kExternalPref, simple_dict,
                                  Extension::NO_FLAGS, &error);
  extension2_ = Extension::Create(prefs_.temp_dir().AppendASCII("ext2_"),
                                  ManifestLocation::kExternalPref, simple_dict,
                                  Extension::NO_FLAGS, &error);
  extension3_ = Extension::Create(prefs_.temp_dir().AppendASCII("ext3_"),
                                  ManifestLocation::kExternalPref, simple_dict,
                                  Extension::NO_FLAGS, &error);
  extension4_ = Extension::Create(prefs_.temp_dir().AppendASCII("ext4_"),
                                  ManifestLocation::kExternalPref, simple_dict,
                                  Extension::NO_FLAGS, &error);

  internal_extension_ = Extension::Create(
      prefs_.temp_dir().AppendASCII("internal extension"),
      ManifestLocation::kInternal, simple_dict, Extension::NO_FLAGS, &error);
}

PrefsPrepopulatedTestBase::~PrefsPrepopulatedTestBase() = default;

// Tests clearing the last launched preference.
class ExtensionPrefsClearLastLaunched : public ExtensionPrefsTest {
 public:
  ~ExtensionPrefsClearLastLaunched() override = default;

  void Initialize() override {
    extension_a_ = prefs_.AddExtension("a");
    extension_b_ = prefs_.AddExtension("b");
  }

  void Verify() override {
    // Set last launched times for each extension.
    prefs()->SetLastLaunchTime(extension_a_->id(), base::Time::Now());
    prefs()->SetLastLaunchTime(extension_b_->id(), base::Time::Now());

    // Also set some other preference for one of the extensions.
    prefs()->SetAllowFileAccess(extension_a_->id(), true);

    // Now clear the launch times.
    prefs()->ClearLastLaunchTimes();

    // All launch times should be gone.
    EXPECT_EQ(base::Time(), prefs()->GetLastLaunchTime(extension_a_->id()));
    EXPECT_EQ(base::Time(), prefs()->GetLastLaunchTime(extension_b_->id()));

    // Other preferences should be untouched.
    EXPECT_TRUE(prefs()->AllowFileAccess(extension_a_->id()));
  }

 private:
  scoped_refptr<const Extension> extension_a_;
  scoped_refptr<const Extension> extension_b_;
};
TEST_F(ExtensionPrefsClearLastLaunched, ExtensionPrefsClearLastLaunched) {}

class ExtensionPrefsComponentExtension : public ExtensionPrefsTest {
 public:
  ~ExtensionPrefsComponentExtension() override = default;
  void Initialize() override {
    // Adding a component extension.
    component_extension_ =
        ExtensionBuilder("a")
            .SetLocation(ManifestLocation::kComponent)
            .SetPath(prefs_.extensions_dir().AppendASCII("a"))
            .Build();
    prefs_.AddExtension(component_extension_.get());

    // Adding a non component extension.
    no_component_extension_ =
        ExtensionBuilder("b")
            .SetLocation(ManifestLocation::kInternal)
            .SetPath(prefs_.extensions_dir().AppendASCII("b"))
            .Build();
    prefs_.AddExtension(no_component_extension_.get());

    APIPermissionSet api_perms;
    api_perms.insert(APIPermissionID::kTab);
    api_perms.insert(APIPermissionID::kBookmark);
    api_perms.insert(APIPermissionID::kHistory);

    URLPatternSet shosts;
    AddPattern(&shosts, "chrome://print/*");

    active_perms_ = std::make_unique<PermissionSet>(
        std::move(api_perms), ManifestPermissionSet(), URLPatternSet(),
        std::move(shosts));
    // Set the desired active permissions.
    prefs()->SetDesiredActivePermissions(component_extension_->id(),
                                         *active_perms_);
    prefs()->SetDesiredActivePermissions(no_component_extension_->id(),
                                         *active_perms_);
  }

  void Verify() override {
    // Component extension can access chrome://print/*.
    std::unique_ptr<const PermissionSet> component_permissions =
        prefs()->GetDesiredActivePermissions(component_extension_->id());
    EXPECT_EQ(1u, component_permissions->scriptable_hosts().size());

    // Non Component extension can not access chrome://print/*.
    std::unique_ptr<const PermissionSet> no_component_permissions =
        prefs()->GetDesiredActivePermissions(no_component_extension_->id());
    EXPECT_EQ(0u, no_component_permissions->scriptable_hosts().size());

    // |URLPattern::SCHEME_CHROMEUI| scheme will be added in valid_schemes for
    // component extensions.
    URLPatternSet scriptable_hosts;
    std::string pref_key = "active_permissions.scriptable_host";
    int valid_schemes = URLPattern::SCHEME_ALL & ~URLPattern::SCHEME_CHROMEUI;

    EXPECT_TRUE(prefs()->ReadPrefAsURLPatternSet(component_extension_->id(),
                                                 pref_key, &scriptable_hosts,
                                                 valid_schemes));

    EXPECT_FALSE(prefs()->ReadPrefAsURLPatternSet(no_component_extension_->id(),
                                                  pref_key, &scriptable_hosts,
                                                  valid_schemes));

    // Both extensions should be registered with the ExtensionPrefValueMap.
    // See https://crbug.com/454513.
    EXPECT_TRUE(prefs_.extension_pref_value_map()->CanExtensionControlPref(
        component_extension_->id(), "a_pref", false));
    EXPECT_TRUE(prefs_.extension_pref_value_map()->CanExtensionControlPref(
        no_component_extension_->id(), "a_pref", false));
  }

 private:
  std::unique_ptr<const PermissionSet> active_perms_;
  scoped_refptr<const Extension> component_extension_;
  scoped_refptr<const Extension> no_component_extension_;
};
TEST_F(ExtensionPrefsComponentExtension, ExtensionPrefsComponentExtension) {}

// Tests reading and writing runtime granted permissions.
class ExtensionPrefsRuntimeGrantedPermissions : public ExtensionPrefsTest {
 public:
  ExtensionPrefsRuntimeGrantedPermissions() = default;

  ExtensionPrefsRuntimeGrantedPermissions(
      const ExtensionPrefsRuntimeGrantedPermissions&) = delete;
  ExtensionPrefsRuntimeGrantedPermissions& operator=(
      const ExtensionPrefsRuntimeGrantedPermissions&) = delete;

  ~ExtensionPrefsRuntimeGrantedPermissions() override = default;

  void Initialize() override {
    extension_a_ = prefs_.AddExtension("a");
    extension_b_ = prefs_.AddExtension("b");

    // By default, runtime-granted permissions are empty.
    EXPECT_TRUE(
        prefs()->GetRuntimeGrantedPermissions(extension_a_->id())->IsEmpty());
    EXPECT_TRUE(
        prefs()->GetRuntimeGrantedPermissions(extension_b_->id())->IsEmpty());

    URLPattern example_com(URLPattern::SCHEME_ALL, "https://example.com/*");
    URLPattern chromium_org(URLPattern::SCHEME_ALL, "https://chromium.org/*");

    {
      // Add two hosts to the runtime granted permissions. Verify they were
      // correctly added.
      URLPatternSet added_urls({example_com, chromium_org});
      PermissionSet added_permissions(APIPermissionSet(),
                                      ManifestPermissionSet(),
                                      std::move(added_urls), URLPatternSet());
      prefs()->AddRuntimeGrantedPermissions(extension_a_->id(),
                                            added_permissions);

      std::unique_ptr<const PermissionSet> retrieved_permissions =
          prefs()->GetRuntimeGrantedPermissions(extension_a_->id());
      ASSERT_TRUE(retrieved_permissions);
      EXPECT_EQ(added_permissions, *retrieved_permissions);
    }

    {
      // Remove one of the hosts. The only remaining host should be
      // example.com
      URLPatternSet removed_urls({chromium_org});
      PermissionSet removed_permissions(
          APIPermissionSet(), ManifestPermissionSet(), std::move(removed_urls),
          URLPatternSet());
      prefs()->RemoveRuntimeGrantedPermissions(extension_a_->id(),
                                               removed_permissions);

      URLPatternSet remaining_urls({example_com});
      PermissionSet remaining_permissions(
          APIPermissionSet(), ManifestPermissionSet(),
          std::move(remaining_urls), URLPatternSet());
      std::unique_ptr<const PermissionSet> retrieved_permissions =
          prefs()->GetRuntimeGrantedPermissions(extension_a_->id());
      ASSERT_TRUE(retrieved_permissions);
      EXPECT_EQ(remaining_permissions, *retrieved_permissions);
    }

    // The second extension should still have no runtime-granted permissions.
    EXPECT_TRUE(
        prefs()->GetRuntimeGrantedPermissions(extension_b_->id())->IsEmpty());
  }

  void Verify() override {
    {
      // The first extension should still have example.com as the granted
      // permission.
      URLPattern example_com(URLPattern::SCHEME_ALL, "https://example.com/*");
      URLPatternSet remaining_urls({example_com});
      PermissionSet remaining_permissions(
          APIPermissionSet(), ManifestPermissionSet(),
          std::move(remaining_urls), URLPatternSet());
      std::unique_ptr<const PermissionSet> retrieved_permissions =
          prefs()->GetRuntimeGrantedPermissions(extension_a_->id());
      ASSERT_TRUE(retrieved_permissions);
      EXPECT_EQ(remaining_permissions, *retrieved_permissions);
    }

    EXPECT_TRUE(
        prefs()->GetRuntimeGrantedPermissions(extension_b_->id())->IsEmpty());
  }

 private:
  scoped_refptr<const Extension> extension_a_;
  scoped_refptr<const Extension> extension_b_;
};
TEST_F(ExtensionPrefsRuntimeGrantedPermissions,
       ExtensionPrefsRuntimeGrantedPermissions) {}

// Tests the removal of obsolete keys from extension pref entries.
class ExtensionPrefsObsoletePrefRemoval : public ExtensionPrefsTest {
 public:
  ExtensionPrefsObsoletePrefRemoval() = default;

  ExtensionPrefsObsoletePrefRemoval(const ExtensionPrefsObsoletePrefRemoval&) =
      delete;
  ExtensionPrefsObsoletePrefRemoval& operator=(
      const ExtensionPrefsObsoletePrefRemoval&) = delete;

  ~ExtensionPrefsObsoletePrefRemoval() override = default;

  void Initialize() override {
    extension_ = prefs_.AddExtension("a");
    constexpr char kTestValue[] = "test_value";
    prefs()->UpdateExtensionPref(extension_->id(),
                                 ExtensionPrefs::kFakeObsoletePrefForTesting,
                                 base::Value(kTestValue));
    std::string str_value;
    EXPECT_TRUE(prefs()->ReadPrefAsString(
        extension_->id(), ExtensionPrefs::kFakeObsoletePrefForTesting,
        &str_value));
    EXPECT_EQ(kTestValue, str_value);

    prefs()->MigrateObsoleteExtensionPrefs();
  }

  void Verify() override {
    std::string str_value;
    EXPECT_FALSE(prefs()->ReadPrefAsString(
        extension_->id(), ExtensionPrefs::kFakeObsoletePrefForTesting,
        &str_value));
  }

 private:
  scoped_refptr<const Extension> extension_;
};

TEST_F(ExtensionPrefsObsoletePrefRemoval, ExtensionPrefsObsoletePrefRemoval) {}

// Tests the migration of renamed keys from extension pref entries.
class ExtensionPrefsMigratedPref : public ExtensionPrefsTest {
 public:
  ExtensionPrefsMigratedPref() = default;

  ExtensionPrefsMigratedPref(const ExtensionPrefsMigratedPref&) = delete;
  ExtensionPrefsMigratedPref& operator=(const ExtensionPrefsMigratedPref&) =
      delete;

  ~ExtensionPrefsMigratedPref() override = default;

  void Initialize() override {
    extension_ = prefs_.AddExtension("a");
    prefs()->MigrateObsoleteExtensionPrefs();
  }

  void Verify() override {}

 private:
  scoped_refptr<const Extension> extension_;
};

TEST_F(ExtensionPrefsMigratedPref, ExtensionPrefsMigratedPref) {}

// Tests the removal of obsolete keys from extension pref entries.
class ExtensionPrefsIsExternalExtensionUninstalled : public ExtensionPrefsTest {
 public:
  ExtensionPrefsIsExternalExtensionUninstalled() = default;
  ExtensionPrefsIsExternalExtensionUninstalled(
      const ExtensionPrefsIsExternalExtensionUninstalled& other) = delete;
  ExtensionPrefsIsExternalExtensionUninstalled& operator=(
      const ExtensionPrefsIsExternalExtensionUninstalled& other) = delete;
  ~ExtensionPrefsIsExternalExtensionUninstalled() override = default;

  void Initialize() override {
    uninstalled_external_id_ =
        prefs_
            .AddExtensionWithLocation("external uninstall",
                                      ManifestLocation::kExternalPref)
            ->id();
    uninstalled_by_program_external_id_ =
        prefs_
            .AddExtensionWithLocation("external uninstall by program",
                                      ManifestLocation::kExternalPref)
            ->id();
    installed_external_id_ =
        prefs_
            .AddExtensionWithLocation("external install",
                                      ManifestLocation::kExternalPref)
            ->id();
    uninstalled_internal_id_ =
        prefs_
            .AddExtensionWithLocation("internal uninstall",
                                      ManifestLocation::kInternal)
            ->id();
    installed_internal_id_ =
        prefs_
            .AddExtensionWithLocation("internal install",
                                      ManifestLocation::kInternal)
            ->id();

    prefs()->OnExtensionUninstalled(uninstalled_external_id_,
                                    ManifestLocation::kExternalPref, false);
    prefs()->OnExtensionUninstalled(uninstalled_by_program_external_id_,
                                    ManifestLocation::kExternalPref, true);
    prefs()->OnExtensionUninstalled(uninstalled_internal_id_,
                                    ManifestLocation::kInternal, false);
  }

  void Verify() override {
    EXPECT_TRUE(
        prefs()->IsExternalExtensionUninstalled(uninstalled_external_id_));
    EXPECT_FALSE(prefs()->IsExternalExtensionUninstalled(
        uninstalled_by_program_external_id_));
    EXPECT_FALSE(
        prefs()->IsExternalExtensionUninstalled(installed_external_id_));
    EXPECT_FALSE(
        prefs()->IsExternalExtensionUninstalled(uninstalled_internal_id_));
    EXPECT_FALSE(
        prefs()->IsExternalExtensionUninstalled(installed_internal_id_));
  }

 private:
  std::string uninstalled_external_id_;
  std::string uninstalled_by_program_external_id_;
  std::string installed_external_id_;
  std::string uninstalled_internal_id_;
  std::string installed_internal_id_;
};

TEST_F(ExtensionPrefsIsExternalExtensionUninstalled,
       ExtensionPrefsIsExternalExtensionUninstalled) {}

#if BUILDFLAG(IS_CHROMEOS)
class ExtensionPrefsApplyPendingUpdates
    : public ExtensionPrefsTest,
      public testing::WithParamInterface<std::tuple<std::string, bool>> {
 public:
  void Initialize() override {
    auto [pref, value] = GetParam();
    extension_ = prefs_.AddExtension("apply_pending_updates");
    prefs()->UpdateExtensionPref(extension_->id(), pref + "-pending",
                                 base::Value(value));
  }

  void Verify() override {}

 protected:
  scoped_refptr<Extension> extension_;
};

INSTANTIATE_TEST_SUITE_P(
    PendingUpdates,
    ExtensionPrefsApplyPendingUpdates,
    ::testing::Combine(::testing::Values("newAllowFileAccess", "incognito"),
                       ::testing::Bool()));

TEST_P(ExtensionPrefsApplyPendingUpdates, ExtensionPrefsApplyPendingUpdates) {
  auto id = extension_->id();
  bool actual = false;
  auto [pref, value] = GetParam();

  ASSERT_TRUE(prefs()->HasPrefForExtension(id));
  ASSERT_TRUE(prefs()->ReadPrefAsBoolean(id, pref + "-pending", &actual));
  ASSERT_EQ(actual, value);
  ASSERT_FALSE(prefs()->ReadPrefAsBoolean(id, pref, &actual));

  prefs()->ApplyPendingUpdates();

  ASSERT_FALSE(prefs()->ReadPrefAsBoolean(id, pref + "-pending", &actual));
  ASSERT_TRUE(prefs()->ReadPrefAsBoolean(id, pref, &actual));
  ASSERT_EQ(actual, value);
}
#endif  // BUILDFLAG(IS_CHROMEOS)

////////////////////////////////////////////////////////////////////////////////
// The following are ExtensionPrefs tests that don't use the same
// Initialize(), Verify(), <recreate>, Verify() flow that the others do, and
// instead just use a normal testing::Test setup.

using ExtensionPrefsSimpleTest = testing::Test;

// Tests that raw manipulation of extension disable reasons works and unknown
// values can be written / read back. This also also tests that the non-raw
// getter collapses unknown values to DISABLE_UNKNOWN.
TEST_F(ExtensionPrefsSimpleTest, DisableReasonsRawManipulation) {
  content::BrowserTaskEnvironment task_environment;
  TestExtensionPrefs prefs(base::SingleThreadTaskRunner::GetCurrentDefault());
  std::string extension_id = prefs.AddExtension("Test Extension")->id();

  ExtensionPrefs* extension_prefs = prefs.prefs();
  ASSERT_FALSE(extension_prefs->IsExtensionDisabled(extension_id));

  auto passkey = ExtensionPrefs::DisableReasonRawManipulationPasskey();
  constexpr int kUnknownReason_1 = disable_reason::DISABLE_REASON_LAST + 1;
  constexpr int kUnknownReason_2 = disable_reason::DISABLE_REASON_LAST + 2;
  constexpr int kUnknownReason_3 = disable_reason::DISABLE_REASON_LAST + 3;
  constexpr disable_reason::DisableReason kKnownReason_1 =
      disable_reason::DISABLE_USER_ACTION;
  constexpr disable_reason::DisableReason kKnownReason_2 =
      disable_reason::DISABLE_PERMISSIONS_INCREASE;

  // Disable the extension with known and unknown reasons.
  extension_prefs->ReplaceRawDisableReasons(passkey, extension_id,
                                            {kKnownReason_1, kUnknownReason_1});
  EXPECT_THAT(extension_prefs->GetRawDisableReasons(passkey, extension_id),
              testing::UnorderedElementsAre(kKnownReason_1, kUnknownReason_1));
  EXPECT_THAT(extension_prefs->GetDisableReasons(extension_id),
              testing::UnorderedElementsAre(kKnownReason_1,
                                            disable_reason::DISABLE_UNKNOWN));

  // Add one known and one unknown reason.
  extension_prefs->AddRawDisableReasons(passkey, extension_id,
                                        {kKnownReason_2, kUnknownReason_2});
  EXPECT_THAT(extension_prefs->GetRawDisableReasons(passkey, extension_id),
              testing::UnorderedElementsAre(kKnownReason_1, kUnknownReason_1,
                                            kKnownReason_2, kUnknownReason_2));
  EXPECT_THAT(extension_prefs->GetDisableReasons(extension_id),
              testing::UnorderedElementsAre(kKnownReason_1, kKnownReason_2,
                                            disable_reason::DISABLE_UNKNOWN));

  // Try replacing the disable reason set.
  extension_prefs->ReplaceRawDisableReasons(passkey, extension_id,
                                            {kUnknownReason_3, kKnownReason_1});
  EXPECT_THAT(extension_prefs->GetRawDisableReasons(passkey, extension_id),
              testing::UnorderedElementsAre(kUnknownReason_3, kKnownReason_1));
  EXPECT_THAT(extension_prefs->GetDisableReasons(extension_id),
              testing::UnorderedElementsAre(kKnownReason_1,
                                            disable_reason::DISABLE_UNKNOWN));

  // Try replacing the disable reason set with only known reasons.
  extension_prefs->ReplaceRawDisableReasons(passkey, extension_id,
                                            {kKnownReason_1, kKnownReason_2});
  EXPECT_THAT(extension_prefs->GetRawDisableReasons(passkey, extension_id),
              testing::UnorderedElementsAre(kKnownReason_1, kKnownReason_2));
  EXPECT_THAT(extension_prefs->GetDisableReasons(extension_id),
              testing::UnorderedElementsAre(kKnownReason_1, kKnownReason_2));
}

// Tests the generic Get/Set functions for profile wide extension prefs.
TEST_F(ExtensionPrefsSimpleTest, ProfileExtensionPrefsMapTest) {
  constexpr PrefMap kTestBooleanPref = {"test.boolean", PrefType::kBool,
                                        PrefScope::kProfile};
  constexpr PrefMap kTestIntegerPref = {"test.integer", PrefType::kInteger,
                                        PrefScope::kProfile};
  constexpr PrefMap kTestStringPref = {"test.string", PrefType::kString,
                                       PrefScope::kProfile};
  constexpr PrefMap kTestTimePref = {"test.time", PrefType::kTime,
                                     PrefScope::kProfile};
  constexpr PrefMap kTestGURLPref = {"test.gurl", PrefType::kGURL,
                                     PrefScope::kProfile};
  constexpr PrefMap kTestDictPref = {"test.dict", PrefType::kDictionary,
                                     PrefScope::kProfile};

  content::BrowserTaskEnvironment task_environment_;
  TestExtensionPrefs prefs(base::SingleThreadTaskRunner::GetCurrentDefault());

  auto* registry = prefs.pref_registry().get();
  registry->RegisterBooleanPref(kTestBooleanPref.name, false);
  registry->RegisterIntegerPref(kTestIntegerPref.name, 0);
  registry->RegisterStringPref(kTestStringPref.name, std::string());
  registry->RegisterTimePref(kTestTimePref.name, base::Time());
  registry->RegisterStringPref(kTestGURLPref.name, std::string());
  registry->RegisterDictionaryPref(kTestDictPref.name);

  prefs.prefs()->SetBooleanPref(kTestBooleanPref, true);
  prefs.prefs()->SetIntegerPref(kTestIntegerPref, 1);
  prefs.prefs()->SetStringPref(kTestStringPref, "foo");
  base::Time time = base::Time::Now();
  prefs.prefs()->SetTimePref(kTestTimePref, time);
  GURL url = GURL("https://example/com");
  prefs.prefs()->SetGURLPref(kTestGURLPref, url);
  base::Value::Dict dict;
  dict.Set("key", "val");
  prefs.prefs()->SetDictionaryPref(kTestDictPref, std::move(dict));

  EXPECT_TRUE(prefs.prefs()->GetPrefAsBoolean(kTestBooleanPref));
  EXPECT_EQ(prefs.prefs()->GetPrefAsInteger(kTestIntegerPref), 1);
  EXPECT_EQ(prefs.prefs()->GetPrefAsString(kTestStringPref), "foo");
  EXPECT_EQ(prefs.prefs()->GetPrefAsTime(kTestTimePref), time);
  EXPECT_EQ(prefs.prefs()->GetPrefAsGURL(kTestGURLPref), url);
  const std::string* string_ptr =
      prefs.prefs()->GetPrefAsDictionary(kTestDictPref).FindString("key");
  EXPECT_TRUE(string_ptr);
  EXPECT_EQ(*string_ptr, "val");
}

TEST_F(ExtensionPrefsSimpleTest, DisableReasonsObserverTest) {
  content::BrowserTaskEnvironment task_environment;
  TestExtensionPrefs test_prefs(
      base::SingleThreadTaskRunner::GetCurrentDefault());
  const ExtensionId extension_id = test_prefs.AddExtensionAndReturnId("test");

  class Observer : public ExtensionPrefsObserver {
   public:
    explicit Observer(ExtensionPrefs* prefs) {
      scoped_observation_.Observe(prefs);
    }
    ~Observer() = default;

    MOCK_METHOD(void,
                OnExtensionDisableReasonsChanged,
                (const ExtensionId& extension_id,
                 DisableReasonSet disabled_reasons),
                (override));
    MOCK_METHOD(void,
                OnExtensionStateChanged,
                (const ExtensionId& extension_id, bool state),
                (override));

   private:
    base::ScopedObservation<ExtensionPrefs, ExtensionPrefsObserver>
        scoped_observation_{this};
  };

  ExtensionPrefs* extension_prefs = test_prefs.prefs();
  ASSERT_FALSE(extension_prefs->IsExtensionDisabled(extension_id));

  const disable_reason::DisableReason disable_reason_1 =
      disable_reason::DISABLE_USER_ACTION;
  const disable_reason::DisableReason disable_reason_2 =
      disable_reason::DISABLE_PERMISSIONS_INCREASE;

  // The extension is initially enabled. This test sequentially adds and then
  // removes two disable reasons. This is how the disable reason change:
  //
  // S0: {}
  // S1: {disable_reason_1}
  // S2: {disable_reason_1, disable_reason_2}
  // S3: {disable_reason_1}
  // S4: {}
  //
  // OnExtensionDisableReasonsChanged() should be called for every state, except
  // the initial state (S0).
  //
  // OnExtensionStateChanged() should be called when the first disable reason is
  // added (S1) and when the last disable reason is removed (S4).
  Observer observer(extension_prefs);
  ::testing::InSequence sequence;

  // S1.
  EXPECT_CALL(observer, OnExtensionDisableReasonsChanged(
                            extension_id,
                            testing::UnorderedElementsAre(disable_reason_1)))
      .Times(1);
  EXPECT_CALL(observer, OnExtensionStateChanged(extension_id, false)).Times(1);

  // S2.
  EXPECT_CALL(observer,
              OnExtensionDisableReasonsChanged(
                  extension_id, testing::UnorderedElementsAre(
                                    disable_reason_1, disable_reason_2)))
      .Times(1);

  // S3.
  EXPECT_CALL(observer, OnExtensionDisableReasonsChanged(
                            extension_id,
                            testing::UnorderedElementsAre(disable_reason_1)))
      .Times(1);

  // S4.
  EXPECT_CALL(observer, OnExtensionDisableReasonsChanged(extension_id,
                                                         testing::IsEmpty()))
      .Times(1);
  EXPECT_CALL(observer, OnExtensionStateChanged(extension_id, true)).Times(1);

  extension_prefs->AddDisableReason(extension_id, disable_reason_1);
  extension_prefs->AddDisableReason(extension_id, disable_reason_2);
  extension_prefs->RemoveDisableReason(extension_id, disable_reason_2);
  extension_prefs->RemoveDisableReason(extension_id, disable_reason_1);
}

TEST_F(ExtensionPrefsSimpleTest, ExtensionSpecificPrefsMapTest) {
  constexpr PrefMap kTestBooleanPref = {"test.boolean", PrefType::kBool,
                                        PrefScope::kExtensionSpecific};
  constexpr PrefMap kTestIntegerPref = {"test.integer", PrefType::kInteger,
                                        PrefScope::kExtensionSpecific};
  constexpr PrefMap kTestStringPref = {"test.string", PrefType::kString,
                                       PrefScope::kExtensionSpecific};
  constexpr PrefMap kTestDictPref = {"test.dict", PrefType::kDictionary,
                                     PrefScope::kExtensionSpecific};
  constexpr PrefMap kTestListPref = {"test.list", PrefType::kList,
                                     PrefScope::kExtensionSpecific};
  constexpr PrefMap kTestTimePref = {"test.time", PrefType::kTime,
                                     PrefScope::kExtensionSpecific};

  content::BrowserTaskEnvironment task_environment_;
  TestExtensionPrefs prefs(base::SingleThreadTaskRunner::GetCurrentDefault());

  std::string extension_id = prefs.AddExtensionAndReturnId("1");
  prefs.prefs()->SetBooleanPref(extension_id, kTestBooleanPref, true);
  prefs.prefs()->SetIntegerPref(extension_id, kTestIntegerPref, 1);
  prefs.prefs()->SetStringPref(extension_id, kTestStringPref, "foo");
  base::Value::Dict dict;
  dict.Set("key", "val");
  prefs.prefs()->SetDictionaryPref(extension_id, kTestDictPref,
                                   std::move(dict));
  base::Value::List list;
  list.Append("list_val");
  prefs.prefs()->SetListPref(extension_id, kTestListPref, std::move(list));
  base::Time time = base::Time::Now();
  prefs.prefs()->SetTimePref(extension_id, kTestTimePref, time);

  bool bool_value = false;
  EXPECT_TRUE(prefs.prefs()->ReadPrefAsBoolean(extension_id, kTestBooleanPref,
                                               &bool_value));
  EXPECT_TRUE(bool_value);
  int int_value = 0;
  EXPECT_TRUE(prefs.prefs()->ReadPrefAsInteger(extension_id, kTestIntegerPref,
                                               &int_value));
  EXPECT_EQ(int_value, 1);
  std::string string_value;
  EXPECT_TRUE(prefs.prefs()->ReadPrefAsString(extension_id, kTestStringPref,
                                              &string_value));
  EXPECT_EQ(string_value, "foo");

  const base::Value::Dict* dict_val =
      prefs.prefs()->ReadPrefAsDictionary(extension_id, kTestDictPref);
  ASSERT_TRUE(dict_val);
  const std::string* string_ptr = dict_val->FindString("key");
  ASSERT_TRUE(string_ptr);
  EXPECT_EQ(*string_ptr, "val");

  const base::Value::List* list_val =
      prefs.prefs()->ReadPrefAsList(extension_id, kTestListPref);
  ASSERT_TRUE(list_val);
  ASSERT_FALSE(list_val->empty());
  ASSERT_TRUE((*list_val)[0].is_string());
  EXPECT_EQ((*list_val)[0].GetString(), "list_val");

  EXPECT_EQ(time, prefs.prefs()->ReadPrefAsTime(extension_id, kTestTimePref));
}

TEST_F(ExtensionPrefsSimpleTest, HasOnlyDisableReasonTest) {
  content::BrowserTaskEnvironment task_environment;
  TestExtensionPrefs prefs(base::SingleThreadTaskRunner::GetCurrentDefault());
  std::string extension_id = prefs.AddExtension("Test Extension")->id();
  ExtensionPrefs* extension_prefs = prefs.prefs();

  // No disable reasons to begin with.
  EXPECT_FALSE(extension_prefs->HasOnlyDisableReason(
      extension_id, disable_reason::DISABLE_USER_ACTION));

  // Add a disable reason.
  extension_prefs->AddDisableReason(extension_id,
                                    disable_reason::DISABLE_USER_ACTION);
  EXPECT_TRUE(extension_prefs->HasOnlyDisableReason(
      extension_id, disable_reason::DISABLE_USER_ACTION));

  // Add another disable reason.
  extension_prefs->AddDisableReason(extension_id,
                                    disable_reason::DISABLE_EXTERNAL_EXTENSION);
  EXPECT_FALSE(extension_prefs->HasOnlyDisableReason(
      extension_id, disable_reason::DISABLE_USER_ACTION));
  EXPECT_FALSE(extension_prefs->HasOnlyDisableReason(
      extension_id, disable_reason::DISABLE_EXTERNAL_EXTENSION));

  // Remove the first disable reason.
  extension_prefs->RemoveDisableReason(extension_id,
                                       disable_reason::DISABLE_USER_ACTION);
  EXPECT_TRUE(extension_prefs->HasOnlyDisableReason(
      extension_id, disable_reason::DISABLE_EXTERNAL_EXTENSION));
}

TEST_F(ExtensionPrefsSimpleTest, RemoveDisableReasons) {
  content::BrowserTaskEnvironment task_environment;
  TestExtensionPrefs prefs(base::SingleThreadTaskRunner::GetCurrentDefault());
  std::string extension_id = prefs.AddExtension("Test Extension")->id();
  ExtensionPrefs* extension_prefs = prefs.prefs();
  extension_prefs->AddDisableReasons(
      extension_id, {disable_reason::DISABLE_USER_ACTION,
                     disable_reason::DISABLE_EXTERNAL_EXTENSION,
                     disable_reason::DISABLE_CORRUPTED});

  // Remove one disable reason.
  extension_prefs->RemoveDisableReason(extension_id,
                                       disable_reason::DISABLE_USER_ACTION);
  EXPECT_THAT(
      extension_prefs->GetDisableReasons(extension_id),
      testing::UnorderedElementsAre(disable_reason::DISABLE_EXTERNAL_EXTENSION,
                                    disable_reason::DISABLE_CORRUPTED));

  // Try removing a disable reason that doesn't exist.
  extension_prefs->RemoveDisableReasons(extension_id,
                                        {disable_reason::DISABLE_RELOAD});
  EXPECT_THAT(
      extension_prefs->GetDisableReasons(extension_id),
      testing::UnorderedElementsAre(disable_reason::DISABLE_EXTERNAL_EXTENSION,
                                    disable_reason::DISABLE_CORRUPTED));

  // Remove the remaining disable reasons.
  extension_prefs->RemoveDisableReasons(
      extension_id, {disable_reason::DISABLE_EXTERNAL_EXTENSION,
                     disable_reason::DISABLE_CORRUPTED});
  EXPECT_TRUE(extension_prefs->GetDisableReasons(extension_id).empty());
}

}  // namespace extensions
