// Copyright 2014 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_management.h"

#include <memory>
#include <string>
#include <vector>

#include "base/containers/contains.h"
#include "base/feature_list.h"
#include "base/json/json_reader.h"
#include "base/memory/raw_ptr.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/test/scoped_feature_list.h"
#include "base/values.h"
#include "chrome/browser/extensions/extension_management_internal.h"
#include "chrome/browser/extensions/extension_management_test_util.h"
#include "chrome/browser/extensions/external_policy_loader.h"
#include "chrome/browser/extensions/standard_management_policy_provider.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/testing_profile.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "content/public/test/browser_task_environment.h"
#include "extensions/browser/pref_names.h"
#include "extensions/common/extension_features.h"
#include "extensions/common/extension_urls.h"
#include "extensions/common/manifest.h"
#include "extensions/common/manifest_constants.h"
#include "extensions/common/permissions/api_permission.h"
#include "extensions/common/permissions/api_permission_set.h"
#include "extensions/common/permissions/permissions_info.h"
#include "extensions/common/url_pattern.h"
#include "extensions/common/url_pattern_set.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

using extensions::mojom::APIPermissionID;
using extensions::mojom::ManifestLocation;

namespace extensions {

namespace {

const char kTargetExtension[] = "abcdefghijklmnopabcdefghijklmnop";
const char kTargetExtension2[] = "bcdefghijklmnopabcdefghijklmnopa";
const char kTargetExtension3[] = "cdefghijklmnopabcdefghijklmnopab";
const char kTargetExtension4[] = "defghijklmnopabcdefghijklmnopabc";
const char kTargetExtension5[] = "efghijklmnopabcdefghijklmnopabcd";
const char kTargetExtension6[] = "fghijklmnopabcdefghijklmnopabcde";
const char kTargetExtension7[] = "ghijklmnopabcdefghijklmnopabcdef";
const char kTargetExtension8[] = "hijklmnopabcdefghijklmnopabcdefg";
const char kTargetExtension9[] = "ijklmnopabcdefghijklmnopabcdefgh";
const char kExampleUpdateUrl[] = "http://example.com/update_url";

const char kNonExistingExtension[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
const char kNonExistingUpdateUrl[] = "http://example.net/update.xml";

const char kExampleForceInstalledDictPreference[] = R"({
  "abcdefghijklmnopabcdefghijklmnop" : {
    "installation_mode" : "force_installed",
    "update_url" : "http://example.com/update_url",
    "override_update_url": true,
  },
  "bcdefghijklmnopabcdefghijklmnopa" : {
    "installation_mode" : "force_installed",
    "update_url" : "http://example.com/update_url"
  }
})";

const char kExampleDictPreferenceWithoutInstallationMode[] = R"({
  "abcdefghijklmnopabcdefghijklmnop" : {
    "override_update_url": true,
  },
  "bcdefghijklmnopabcdefghijklmnopa" : {
    "minimum_version_required": "1.1.0"
  }
})";

const char kExampleDictPreferenceWithMultipleEntries[] = R"({
  "abcdefghijklmnopabcdefghijklmnop,bcdefghijklmnopabcdefghijklmnopa" : {
    "installation_mode": "blocked",
  },
  "bcdefghijklmnopabcdefghijklmnopa,cdefghijklmnopabcdefghijklmnopab" : {
    "minimum_version_required": "2.0"
  }
})";

const char kExampleDictPreference[] =
    R"(
{
  "abcdefghijklmnopabcdefghijklmnop": {
    "installation_mode": "allowed",
    "blocked_permissions": ["fileSystem", "bookmarks", "downloads"],
    "minimum_version_required": "1.1.0",
    "runtime_allowed_hosts": ["<all_urls>"],
  },
  "bcdefghijklmnopabcdefghijklmnopa": {
    "installation_mode": "force_installed",
    "update_url": "http://example.com/update_url",
    "blocked_permissions": ["downloads"],
  },
  "cdefghijklmnopabcdefghijklmnopab": {
    "installation_mode": "normal_installed",
    "update_url": "http://example.com/update_url",
    "blocked_permissions": ["fileSystem", "history"],
  },
  "defghijklmnopabcdefghijklmnopabc": {
    "installation_mode": "blocked",
    "runtime_blocked_hosts": ["*://*.foo.com", "https://bar.org/test"],
    "blocked_install_message": "Custom Error Extension4",
  },
  "efghijklmnopabcdefghijklmnopabcd,fghijklmnopabcdefghijklmnopabcde": {
    "installation_mode": "allowed",
  },
  "ghijklmnopabcdefghijklmnopabcdef,hijklmnopabcdefghijklmnopabcdefg,": {
    "installation_mode": "allowed",
  },
  "ijklmnopabcdefghijklmnopabcdefgh": {
    "installation_mode": "removed",
  },
  "update_url:http://example.com/update_url": {
    "installation_mode": "allowed",
    "blocked_permissions": ["fileSystem", "bookmarks"],
  },
  "*": {
    "installation_mode": "blocked",
    "install_sources": ["*://foo.com/*"],
    "allowed_types": ["theme", "user_script"],
    "blocked_permissions": ["fileSystem", "downloads"],
    "runtime_blocked_hosts": ["*://*.example.com"],
    "blocked_install_message": "Custom Error Default",
  },
})";

const char kExampleDictNoCustomError[] =
    "{"
    "  \"*\": {"
    "    \"installation_mode\": \"blocked\","
    "  },"
    "}";

}  // namespace

class ExtensionManagementServiceTest : public testing::Test {
 public:
  typedef ExtensionManagementPrefUpdater<
      sync_preferences::TestingPrefServiceSyncable>
      PrefUpdater;

  ExtensionManagementServiceTest() = default;
  ~ExtensionManagementServiceTest() override = default;

  // testing::Test:
  void SetUp() override { InitPrefService(); }

  void InitPrefService() {
    extension_management_.reset();
    profile_ = std::make_unique<TestingProfile>();
    pref_service_ = profile_->GetTestingPrefService();
    extension_management_ =
        std::make_unique<ExtensionManagement>(profile_.get());
  }

  void SetPref(bool managed,
               const char* path,
               std::unique_ptr<base::Value> value) {
    if (managed)
      pref_service_->SetManagedPref(path, std::move(value));
    else
      pref_service_->SetUserPref(path, std::move(value));
  }

  void SetPref(bool managed, const char* path, base::Value value) {
    SetPref(managed, path, base::Value::ToUniquePtrValue(std::move(value)));
  }

  void SetPref(bool managed, const char* path, base::Value::Dict dict) {
    SetPref(managed, path, base::Value(std::move(dict)));
  }

  void RemovePref(bool managed, const char* path) {
    if (managed)
      pref_service_->RemoveManagedPref(path);
    else
      pref_service_->RemoveUserPref(path);
  }

  const internal::GlobalSettings* ReadGlobalSettings() {
    return extension_management_->global_settings_.get();
  }

  ExtensionManagement::InstallationMode GetInstallationModeById(
      const std::string& id) {
    return GetInstallationMode(id, kNonExistingUpdateUrl);
  }

  ExtensionManagement::InstallationMode GetInstallationModeByUpdateUrl(
      const std::string& update_url) {
    return GetInstallationMode(kNonExistingExtension, update_url);
  }

  void CheckAutomaticallyInstalledUpdateUrl(const std::string& id,
                                            const std::string& update_url) {
    auto iter = extension_management_->settings_by_id_.find(id);
    ASSERT_TRUE(iter != extension_management_->settings_by_id_.end());
    ASSERT_TRUE((iter->second->installation_mode ==
                 ExtensionManagement::INSTALLATION_FORCED) ||
                (iter->second->installation_mode ==
                 ExtensionManagement::INSTALLATION_RECOMMENDED));
    EXPECT_EQ(iter->second->update_url, update_url);
  }

  APIPermissionSet GetBlockedAPIPermissionsById(const std::string& id) {
    return GetBlockedAPIPermissions(id, kNonExistingUpdateUrl);
  }

  APIPermissionSet GetBlockedAPIPermissionsByUpdateUrl(
      const std::string& update_url) {
    return GetBlockedAPIPermissions(kNonExistingExtension, update_url);
  }

  void SetExampleDictPref(const base::StringPiece example_dict_preference) {
    auto result = base::JSONReader::ReadAndReturnValueWithError(
        example_dict_preference,
        base::JSONParserOptions::JSON_ALLOW_TRAILING_COMMAS);
    ASSERT_TRUE(result.has_value()) << result.error().message;
    ASSERT_TRUE(result->is_dict());
    SetPref(true, pref_names::kExtensionManagement, std::move(*result));
  }

  // Wrapper of ExtensionManagement::GetInstallationMode, |id| and
  // |update_url| are used to construct an Extension for testing.
  ExtensionManagement::InstallationMode GetInstallationMode(
      const std::string& id,
      const std::string& update_url) {
    scoped_refptr<const Extension> extension =
        CreateExtension(ManifestLocation::kUnpacked, "0.1", id, update_url);
    return extension_management_->GetInstallationMode(extension.get());
  }

  // Wrapper of ExtensionManagement::GetPolicyBlockedHosts, |id| is used
  // to construct an Extension for testing.
  URLPatternSet GetPolicyBlockedHosts(const std::string& id) {
    scoped_refptr<const Extension> extension = CreateExtension(
        ManifestLocation::kUnpacked, "0.1", id, kNonExistingUpdateUrl);
    return extension_management_->GetPolicyBlockedHosts(extension.get())
        .Clone();
  }

  // Wrapper of ExtensionManagement::GetPolicyAllowedHosts, |id| is used
  // to construct an Extension for testing.
  URLPatternSet GetPolicyAllowedHosts(const std::string& id) {
    scoped_refptr<const Extension> extension = CreateExtension(
        ManifestLocation::kUnpacked, "0.1", id, kNonExistingUpdateUrl);
    return extension_management_->GetPolicyAllowedHosts(extension.get())
        .Clone();
  }

  // Wrapper of ExtensionManagement::BlockedInstallMessage, |id| is used
  // in case the message is extension specific.
  const std::string GetBlockedInstallMessage(const std::string& id) {
    return extension_management_->BlockedInstallMessage(id);
  }

  // Wrapper of ExtensionManagement::GetBlockedAPIPermissions, |id| and
  // |update_url| are used to construct an Extension for testing.
  APIPermissionSet GetBlockedAPIPermissions(const std::string& id,
                                            const std::string& update_url) {
    scoped_refptr<const Extension> extension =
        CreateExtension(ManifestLocation::kUnpacked, "0.1", id, update_url);
    return extension_management_->GetBlockedAPIPermissions(extension.get());
  }

  // Wrapper of ExtensionManagement::CheckMinimumVersion, |id| and
  // |version| are used to construct an Extension for testing.
  bool CheckMinimumVersion(const std::string& id, const std::string& version) {
    scoped_refptr<const Extension> extension = CreateExtension(
        ManifestLocation::kUnpacked, version, id, kNonExistingUpdateUrl);
    std::string minimum_version_required;
    bool ret = extension_management_->CheckMinimumVersion(
        extension.get(), &minimum_version_required);
    EXPECT_EQ(ret, minimum_version_required.empty());
    EXPECT_EQ(ret, extension_management_->CheckMinimumVersion(extension.get(),
                                                              nullptr));
    return ret;
  }

 protected:
  // Create an extension with specified |location|, |version|, |id| and
  // |update_url|.
  scoped_refptr<const Extension> CreateExtension(
      ManifestLocation location,
      const std::string& version,
      const std::string& id,
      const std::string& update_url) {
    base::Value::Dict manifest_dict;
    manifest_dict.Set(manifest_keys::kName, "test");
    manifest_dict.Set(manifest_keys::kVersion, version);
    manifest_dict.Set(manifest_keys::kManifestVersion, 2);
    manifest_dict.Set(manifest_keys::kUpdateURL, update_url);
    std::string error;
    scoped_refptr<const Extension> extension =
        Extension::Create(base::FilePath(), location, std::move(manifest_dict),
                          Extension::NO_FLAGS, id, &error);
    CHECK(extension.get()) << error;
    return extension;
  }

  bool IsUpdateUrlOverridden(const ExtensionId& extension_id) {
    return extension_management_->IsUpdateUrlOverridden(extension_id);
  }

  content::BrowserTaskEnvironment task_environment_;
  std::unique_ptr<TestingProfile> profile_;
  raw_ptr<sync_preferences::TestingPrefServiceSyncable> pref_service_;
  std::unique_ptr<ExtensionManagement> extension_management_;
};

class ExtensionAdminPolicyTest : public ExtensionManagementServiceTest {
 public:
  ExtensionAdminPolicyTest() {}
  ~ExtensionAdminPolicyTest() override {}

  void SetUpPolicyProvider() {
    provider_ = std::make_unique<StandardManagementPolicyProvider>(
        extension_management_.get());
  }

  void CreateExtension(ManifestLocation location) {
    base::Value::Dict values;
    CreateExtensionFromValues(location, &values);
  }

  void CreateHostedApp(ManifestLocation location) {
    base::Value::Dict values;
    values.SetByDottedPath(extensions::manifest_keys::kWebURLs,
                           base::Value(base::Value::Type::LIST));
    values.SetByDottedPath(extensions::manifest_keys::kLaunchWebURL,
                           "http://www.example.com");
    CreateExtensionFromValues(location, &values);
  }

  void CreateExtensionFromValues(ManifestLocation location,
                                 base::Value::Dict* values) {
    values->Set(extensions::manifest_keys::kName, "test");
    values->Set(extensions::manifest_keys::kVersion, "0.1");
    values->Set(extensions::manifest_keys::kManifestVersion, 2);
    std::string error;
    extension_ = Extension::Create(base::FilePath(), location, *values,
                                   Extension::NO_FLAGS, &error);
    ASSERT_TRUE(extension_.get());
  }

  // Wrappers for legacy admin policy functions, for testing purpose only.
  bool BlocklistedByDefault(const base::Value::List* blocklist);
  bool UserMayLoad(const base::Value::List* blocklist,
                   const base::Value::List* allowlist,
                   const base::Value::List* allowed_types,
                   const Extension* extension,
                   std::u16string* error);
  bool UserMayModifySettings(const Extension* extension, std::u16string* error);
  bool ExtensionMayModifySettings(const Extension* source_extension,
                                  const Extension* extension,
                                  std::u16string* error);
  bool MustRemainEnabled(const Extension* extension, std::u16string* error);

 protected:
  std::unique_ptr<StandardManagementPolicyProvider> provider_;
  scoped_refptr<Extension> extension_;
};

bool ExtensionAdminPolicyTest::BlocklistedByDefault(
    const base::Value::List* blocklist) {
  SetUpPolicyProvider();
  if (blocklist)
    SetPref(true, pref_names::kInstallDenyList,
            base::Value(blocklist->Clone()));
  return extension_management_->BlocklistedByDefault();
}

bool ExtensionAdminPolicyTest::UserMayLoad(
    const base::Value::List* blocklist,
    const base::Value::List* allowlist,
    const base::Value::List* allowed_types,
    const Extension* extension,
    std::u16string* error) {
  SetUpPolicyProvider();
  if (blocklist)
    SetPref(true, pref_names::kInstallDenyList,
            base::Value(blocklist->Clone()));
  if (allowlist)
    SetPref(true, pref_names::kInstallAllowList,
            base::Value(allowlist->Clone()));
  if (allowed_types)
    SetPref(true, pref_names::kAllowedTypes,
            base::Value(allowed_types->Clone()));
  return provider_->UserMayLoad(extension, error);
}

bool ExtensionAdminPolicyTest::UserMayModifySettings(const Extension* extension,
                                                     std::u16string* error) {
  SetUpPolicyProvider();
  return provider_->UserMayModifySettings(extension, error);
}

bool ExtensionAdminPolicyTest::ExtensionMayModifySettings(
    const Extension* source_extension,
    const Extension* extension,
    std::u16string* error) {
  SetUpPolicyProvider();
  return provider_->ExtensionMayModifySettings(source_extension, extension,
                                               error);
}

bool ExtensionAdminPolicyTest::MustRemainEnabled(const Extension* extension,
                                                 std::u16string* error) {
  SetUpPolicyProvider();
  return provider_->MustRemainEnabled(extension, error);
}

// Verify that preference controlled by legacy ExtensionInstallSources policy is
// handled well.
TEST_F(ExtensionManagementServiceTest, LegacyInstallSources) {
  base::Value::List allowed_sites_pref;
  allowed_sites_pref.Append("https://www.example.com/foo");
  allowed_sites_pref.Append("https://corp.mycompany.com/*");
  SetPref(true, pref_names::kAllowedInstallSites,
          base::Value(std::move(allowed_sites_pref)));
  ASSERT_TRUE(ReadGlobalSettings()->install_sources);
  const URLPatternSet& allowed_sites = *ReadGlobalSettings()->install_sources;
  EXPECT_FALSE(allowed_sites.is_empty());
  EXPECT_TRUE(allowed_sites.MatchesURL(GURL("https://www.example.com/foo")));
  EXPECT_FALSE(allowed_sites.MatchesURL(GURL("https://www.example.com/bar")));
  EXPECT_TRUE(
      allowed_sites.MatchesURL(GURL("https://corp.mycompany.com/entry")));
  EXPECT_FALSE(
      allowed_sites.MatchesURL(GURL("https://www.mycompany.com/entry")));
}

// Verify that preference controlled by legacy ExtensionAllowedTypes policy is
// handled well.
TEST_F(ExtensionManagementServiceTest, LegacyAllowedTypes) {
  base::Value::List allowed_types_pref;
  allowed_types_pref.Append(Manifest::TYPE_THEME);
  allowed_types_pref.Append(Manifest::TYPE_USER_SCRIPT);

  SetPref(true, pref_names::kAllowedTypes,
          base::Value(std::move(allowed_types_pref)));
  ASSERT_TRUE(ReadGlobalSettings()->allowed_types);
  const std::vector<Manifest::Type>& allowed_types =
      *ReadGlobalSettings()->allowed_types;
  EXPECT_EQ(allowed_types.size(), 2u);
  EXPECT_FALSE(base::Contains(allowed_types, Manifest::TYPE_EXTENSION));
  EXPECT_TRUE(base::Contains(allowed_types, Manifest::TYPE_THEME));
  EXPECT_TRUE(base::Contains(allowed_types, Manifest::TYPE_USER_SCRIPT));
}

// Verify that preference controlled by legacy ExtensionInstallBlocklist policy
// is handled well.
TEST_F(ExtensionManagementServiceTest, LegacyInstallBlocklist) {
  base::Value::List denied_list_pref;
  denied_list_pref.Append(kTargetExtension);

  SetPref(true, pref_names::kInstallDenyList,
          base::Value(std::move(denied_list_pref)));
  EXPECT_EQ(GetInstallationModeById(kTargetExtension),
            ExtensionManagement::INSTALLATION_BLOCKED);
  EXPECT_EQ(GetInstallationModeById(kNonExistingExtension),
            ExtensionManagement::INSTALLATION_ALLOWED);
}

// Verify that preference controlled by legacy ExtensionInstallAllowlist policy
// is handled well.
TEST_F(ExtensionManagementServiceTest, LegacyAllowlist) {
  base::Value::List denied_list_pref;
  denied_list_pref.Append("*");
  base::Value::List allowed_list_pref;
  allowed_list_pref.Append(kTargetExtension);

  SetPref(true, pref_names::kInstallDenyList,
          base::Value(std::move(denied_list_pref)));
  SetPref(true, pref_names::kInstallAllowList,
          base::Value(allowed_list_pref.Clone()));
  EXPECT_EQ(GetInstallationModeById(kTargetExtension),
            ExtensionManagement::INSTALLATION_ALLOWED);
  EXPECT_EQ(GetInstallationModeById(kNonExistingExtension),
            ExtensionManagement::INSTALLATION_BLOCKED);

  // Verify that install allowlist preference set by user is ignored.
  RemovePref(true, pref_names::kInstallAllowList);
  SetPref(false, pref_names::kInstallAllowList,
          base::Value(std::move(allowed_list_pref)));
  EXPECT_EQ(GetInstallationModeById(kTargetExtension),
            ExtensionManagement::INSTALLATION_BLOCKED);
}

// Verify that preference controlled by legacy ExtensionInstallForcelist policy
// is handled well.
TEST_F(ExtensionManagementServiceTest, LegacyInstallForcelist) {
  base::Value::Dict forced_list_pref;
  ExternalPolicyLoader::AddExtension(forced_list_pref, kTargetExtension,
                                     kExampleUpdateUrl);

  SetPref(true, pref_names::kInstallForceList, forced_list_pref.Clone());
  EXPECT_EQ(GetInstallationModeById(kTargetExtension),
            ExtensionManagement::INSTALLATION_FORCED);
  CheckAutomaticallyInstalledUpdateUrl(kTargetExtension, kExampleUpdateUrl);
  EXPECT_EQ(GetInstallationModeById(kNonExistingExtension),
            ExtensionManagement::INSTALLATION_ALLOWED);

  // Verify that install forcelist preference set by user is ignored.
  RemovePref(true, pref_names::kInstallForceList);
  SetPref(false, pref_names::kInstallForceList, forced_list_pref.Clone());
  EXPECT_EQ(GetInstallationModeById(kTargetExtension),
            ExtensionManagement::INSTALLATION_ALLOWED);
}

// Verify that update url is overridden for extensions specified in
// |kInstallForcelist| pref but |installation_mode| is missing in
// |kExtensionSettings| pref.
TEST_F(ExtensionManagementServiceTest,
       InstallUpdateUrlEnforcedForceInstalledPref) {
  base::Value::Dict forced_list_pref;
  ExternalPolicyLoader::AddExtension(forced_list_pref, kTargetExtension,
                                     kExampleUpdateUrl);
  ExternalPolicyLoader::AddExtension(forced_list_pref, kTargetExtension2,
                                     kExampleUpdateUrl);

  SetPref(true, pref_names::kInstallForceList, forced_list_pref.Clone());
  EXPECT_EQ(GetInstallationModeById(kTargetExtension),
            ExtensionManagement::INSTALLATION_FORCED);
  EXPECT_EQ(GetInstallationModeById(kTargetExtension2),
            ExtensionManagement::INSTALLATION_FORCED);

  SetExampleDictPref(kExampleDictPreferenceWithoutInstallationMode);

  // Verify that the update URL is overridden for kTargetExtension.
  EXPECT_EQ(GetInstallationModeById(kTargetExtension),
            ExtensionManagement::INSTALLATION_FORCED);
  EXPECT_TRUE(IsUpdateUrlOverridden(kTargetExtension));

  // Verify that the update URL is not overridden for kTargetExtension2 because
  // |override_update_url| flag is not specified for it in |kExtensionSettings|
  // pref.
  EXPECT_EQ(GetInstallationModeById(kTargetExtension2),
            ExtensionManagement::INSTALLATION_FORCED);
  EXPECT_FALSE(IsUpdateUrlOverridden(kTargetExtension2));
}

// Verify that update url is not overridden for extensions not specified in
// |kInstallForcelist| and |installation_mode| is missing in
// |kExtensionSettings|.
TEST_F(ExtensionManagementServiceTest,
       InstallUpdateUrlEnforcedForceInstalledPrefMissing) {
  base::Value::Dict forced_list_pref;
  ExternalPolicyLoader::AddExtension(forced_list_pref, kTargetExtension2,
                                     kExampleUpdateUrl);
  SetPref(true, pref_names::kInstallForceList, forced_list_pref.Clone());

  EXPECT_EQ(GetInstallationModeById(kTargetExtension2),
            ExtensionManagement::INSTALLATION_FORCED);

  SetExampleDictPref(kExampleDictPreferenceWithoutInstallationMode);

  // Verify that the update URL is not overridden for kTargetExtension as it is
  // not listed in |kInstallForcelist| pref.
  EXPECT_NE(GetInstallationModeById(kTargetExtension),
            ExtensionManagement::INSTALLATION_FORCED);
  EXPECT_FALSE(IsUpdateUrlOverridden(kTargetExtension));
}

// Verify that update url is overridden for extensions which are marked as
// 'force_installed' and |override_update_url| is true for them in
// |kExtensionSettings|.
TEST_F(ExtensionManagementServiceTest,
       InstallUpdateUrlEnforcedExtensionSettings) {
  SetExampleDictPref(kExampleForceInstalledDictPreference);

  // Verify that the update URL is overridden for kTargetExtension.
  EXPECT_EQ(GetInstallationModeById(kTargetExtension),
            ExtensionManagement::INSTALLATION_FORCED);
  EXPECT_TRUE(IsUpdateUrlOverridden(kTargetExtension));

  // Verify that the update URL is not overridden for kTargetExtension2 because
  // |override_update_url| flag is not specified for it in |kExtensionSettings|
  // pref.
  EXPECT_EQ(GetInstallationModeById(kTargetExtension2),
            ExtensionManagement::INSTALLATION_FORCED);
  EXPECT_FALSE(IsUpdateUrlOverridden(kTargetExtension2));
}

// Verify that the force-installed extension specified in the preference
// |kInstallUpdateUrlEnforced| is ignored if the update URL is a webstore update
// URL.
TEST_F(ExtensionManagementServiceTest,
       InstallUpdateUrlEnforcedWebstoreUpdateUrl) {
  base::Value::Dict forced_list_pref;
  ExternalPolicyLoader::AddExtension(forced_list_pref, kTargetExtension,
                                     extension_urls::kChromeWebstoreUpdateURL);
  ExternalPolicyLoader::AddExtension(forced_list_pref, kTargetExtension2,
                                     kExampleUpdateUrl);

  SetPref(true, pref_names::kInstallForceList, forced_list_pref.Clone());
  EXPECT_EQ(GetInstallationModeById(kTargetExtension),
            ExtensionManagement::INSTALLATION_FORCED);
  EXPECT_EQ(GetInstallationModeById(kTargetExtension2),
            ExtensionManagement::INSTALLATION_FORCED);

  SetExampleDictPref(kExampleDictPreferenceWithoutInstallationMode);

  // Verify that the update URL is not overridden for kTargetExtension because
  // |update_url| is a Chrome web store URL.
  EXPECT_EQ(GetInstallationModeById(kTargetExtension),
            ExtensionManagement::INSTALLATION_FORCED);
  EXPECT_FALSE(IsUpdateUrlOverridden(kTargetExtension));
}

// Tests handling of exceeding number of urls
TEST_F(ExtensionManagementServiceTest, HostsMaximumExceeded) {
  const char policy_template[] =
      "{"
      "  \"abcdefghijklmnopabcdefghijklmnop\": {"
      "    \"installation_mode\": \"allowed\","
      "    \"runtime_blocked_hosts\": [%s],"
      "    \"runtime_allowed_hosts\": [%s]"
      "  }"
      "}";

  std::string urls;
  for (size_t i = 0; i < 200; ++i)
    urls.append("\"*://example" + base::NumberToString(i) + ".com\",");

  std::string policy =
      base::StringPrintf(policy_template, urls.c_str(), urls.c_str());
  SetExampleDictPref(policy);
  EXPECT_EQ(100u, GetPolicyBlockedHosts(kTargetExtension).size());
  EXPECT_EQ(100u, GetPolicyAllowedHosts(kTargetExtension).size());
}

// Tests that multiple entries for a dictionary are all applied.
TEST_F(ExtensionManagementServiceTest, MultipleEntries) {
  SetExampleDictPref(kExampleDictPreferenceWithMultipleEntries);

  EXPECT_EQ(GetInstallationModeById(kTargetExtension2),
            ExtensionManagement::INSTALLATION_BLOCKED);

  EXPECT_FALSE(CheckMinimumVersion(kTargetExtension2, "1.0"));
}

// Tests parsing of new dictionary preference.
TEST_F(ExtensionManagementServiceTest, PreferenceParsing) {
  SetExampleDictPref(kExampleDictPreference);

  // Verifies the installation mode settings.
  EXPECT_TRUE(extension_management_->BlocklistedByDefault());
  EXPECT_EQ(GetInstallationModeById(kTargetExtension),
            ExtensionManagement::INSTALLATION_ALLOWED);
  EXPECT_EQ(GetInstallationModeById(kTargetExtension2),
            ExtensionManagement::INSTALLATION_FORCED);
  CheckAutomaticallyInstalledUpdateUrl(kTargetExtension2, kExampleUpdateUrl);
  EXPECT_EQ(GetInstallationModeById(kTargetExtension3),
            ExtensionManagement::INSTALLATION_RECOMMENDED);
  CheckAutomaticallyInstalledUpdateUrl(kTargetExtension3, kExampleUpdateUrl);
  EXPECT_EQ(GetInstallationModeById(kNonExistingExtension),
            ExtensionManagement::INSTALLATION_BLOCKED);
  EXPECT_EQ(GetInstallationModeByUpdateUrl(kExampleUpdateUrl),
            ExtensionManagement::INSTALLATION_ALLOWED);
  EXPECT_TRUE(GetPolicyBlockedHosts(kTargetExtension).is_empty());
  EXPECT_TRUE(GetPolicyBlockedHosts(kTargetExtension4)
                  .MatchesURL(GURL("http://test.foo.com/test")));
  EXPECT_TRUE(GetPolicyBlockedHosts(kTargetExtension4)
                  .MatchesURL(GURL("https://bar.org/test")));
  EXPECT_TRUE(GetBlockedInstallMessage(kTargetExtension).empty());
  EXPECT_EQ("Custom Error Extension4",
            GetBlockedInstallMessage(kTargetExtension4));
  EXPECT_EQ("Custom Error Default",
            GetBlockedInstallMessage(kNonExistingExtension));

  // Verifies using multiple extensions as a key.
  EXPECT_EQ(GetInstallationModeById(kTargetExtension5),
            ExtensionManagement::INSTALLATION_ALLOWED);
  EXPECT_EQ(GetInstallationModeById(kTargetExtension6),
            ExtensionManagement::INSTALLATION_ALLOWED);
  EXPECT_EQ(GetInstallationModeById(kTargetExtension7),
            ExtensionManagement::INSTALLATION_ALLOWED);
  EXPECT_EQ(GetInstallationModeById(kTargetExtension8),
            ExtensionManagement::INSTALLATION_ALLOWED);

  // Verifies global settings.
  ASSERT_TRUE(ReadGlobalSettings()->install_sources);
  const URLPatternSet& allowed_sites = *ReadGlobalSettings()->install_sources;
  EXPECT_EQ(allowed_sites.size(), 1u);
  EXPECT_TRUE(allowed_sites.MatchesURL(GURL("http://foo.com/entry")));
  EXPECT_FALSE(allowed_sites.MatchesURL(GURL("http://bar.com/entry")));
  EXPECT_TRUE(GetPolicyBlockedHosts(kNonExistingExtension)
                  .MatchesURL(GURL("http://example.com/default")));

  ASSERT_TRUE(ReadGlobalSettings()->allowed_types);
  const std::vector<Manifest::Type>& allowed_types =
      *ReadGlobalSettings()->allowed_types;
  EXPECT_EQ(allowed_types.size(), 2u);
  EXPECT_TRUE(base::Contains(allowed_types, Manifest::TYPE_THEME));
  EXPECT_TRUE(base::Contains(allowed_types, Manifest::TYPE_USER_SCRIPT));

  // Verifies blocked permission allowlist settings.
  APIPermissionSet api_permission_set;
  api_permission_set.clear();
  api_permission_set.insert(APIPermissionID::kFileSystem);
  api_permission_set.insert(APIPermissionID::kDownloads);
  EXPECT_EQ(api_permission_set,
            GetBlockedAPIPermissionsById(kNonExistingExtension));

  api_permission_set.clear();
  api_permission_set.insert(APIPermissionID::kFileSystem);
  api_permission_set.insert(APIPermissionID::kDownloads);
  api_permission_set.insert(APIPermissionID::kBookmark);
  EXPECT_EQ(api_permission_set, GetBlockedAPIPermissionsById(kTargetExtension));

  api_permission_set.clear();
  api_permission_set.insert(APIPermissionID::kDownloads);
  EXPECT_EQ(api_permission_set,
            GetBlockedAPIPermissionsById(kTargetExtension2));

  api_permission_set.clear();
  api_permission_set.insert(APIPermissionID::kFileSystem);
  api_permission_set.insert(APIPermissionID::kHistory);
  EXPECT_EQ(api_permission_set,
            GetBlockedAPIPermissionsById(kTargetExtension3));

  api_permission_set.clear();
  api_permission_set.insert(APIPermissionID::kFileSystem);
  api_permission_set.insert(APIPermissionID::kBookmark);
  EXPECT_EQ(api_permission_set,
            GetBlockedAPIPermissionsByUpdateUrl(kExampleUpdateUrl));

  // Verifies minimum version settings.
  EXPECT_FALSE(CheckMinimumVersion(kTargetExtension, "1.0.99"));
  EXPECT_TRUE(CheckMinimumVersion(kTargetExtension, "1.1"));
  EXPECT_TRUE(CheckMinimumVersion(kTargetExtension, "1.1.0.1"));

  // Verifies that an extension using the default scope where
  // no custom blocked install message is defined returns an empty string.
  SetExampleDictPref(kExampleDictNoCustomError);
  EXPECT_EQ("", GetBlockedInstallMessage(kNonExistingExtension));
}

// Tests the handling of installation mode in case it's specified in both
// per-extension and per-update-url settings.
TEST_F(ExtensionManagementServiceTest, InstallationModeConflictHandling) {
  SetExampleDictPref(kExampleDictPreference);

  // Per-extension installation mode settings should always override
  // per-update-url settings.
  EXPECT_EQ(GetInstallationMode(kTargetExtension, kExampleUpdateUrl),
            ExtensionManagement::INSTALLATION_ALLOWED);
  EXPECT_EQ(GetInstallationMode(kTargetExtension2, kExampleUpdateUrl),
            ExtensionManagement::INSTALLATION_FORCED);
  EXPECT_EQ(GetInstallationMode(kTargetExtension3, kExampleUpdateUrl),
            ExtensionManagement::INSTALLATION_RECOMMENDED);
}

// Tests the handling of blocked permissions in case it's specified in both
// per-extension and per-update-url settings.
TEST_F(ExtensionManagementServiceTest, BlockedPermissionsConflictHandling) {
  SetExampleDictPref(kExampleDictPreference);

  // Both settings should be overridden.
  APIPermissionSet blocked_permissions_for_update_url;
  blocked_permissions_for_update_url.insert(APIPermissionID::kFileSystem);
  blocked_permissions_for_update_url.insert(APIPermissionID::kBookmark);

  APIPermissionSet api_permission_set;

  api_permission_set = blocked_permissions_for_update_url.Clone();
  api_permission_set.insert(APIPermissionID::kFileSystem);
  api_permission_set.insert(APIPermissionID::kDownloads);
  api_permission_set.insert(APIPermissionID::kBookmark);
  EXPECT_EQ(api_permission_set,
            GetBlockedAPIPermissions(kTargetExtension, kExampleUpdateUrl));

  api_permission_set = blocked_permissions_for_update_url.Clone();
  api_permission_set.insert(APIPermissionID::kDownloads);
  EXPECT_EQ(api_permission_set,
            GetBlockedAPIPermissions(kTargetExtension2, kExampleUpdateUrl));

  api_permission_set = blocked_permissions_for_update_url.Clone();
  api_permission_set.insert(APIPermissionID::kFileSystem);
  api_permission_set.insert(APIPermissionID::kHistory);
  EXPECT_EQ(api_permission_set,
            GetBlockedAPIPermissions(kTargetExtension3, kExampleUpdateUrl));

  // Default blocked permissions will not be inherited.
  EXPECT_EQ(blocked_permissions_for_update_url,
            GetBlockedAPIPermissions(kTargetExtension4, kExampleUpdateUrl));
  EXPECT_EQ(
      APIPermissionSet(),
      GetBlockedAPIPermissions(kTargetExtension4,
                               "https://www.example.com/another_update_url"));
}

TEST_F(ExtensionManagementServiceTest, DefaultHostExtensionsOverride) {
  SetExampleDictPref(base::StringPrintf(
      R"({
    "%s": {
      "runtime_allowed_hosts": ["https://allow.extension.com"],
      "runtime_blocked_hosts": ["https://block.extension.com"],
    },
    "%s": {},
    "*": {
      "runtime_allowed_hosts": ["https://allow.default.com"],
      "runtime_blocked_hosts": ["https://block.default.com"],
    },
  })",
      kTargetExtension, kTargetExtension2));

  // Override allow/block host for the first extension.
  URLPatternSet expected_extension_allowed_set_1;
  URLPatternSet expected_extension_blocked_set_1;
  expected_extension_allowed_set_1.AddPattern(
      {URLPattern::SCHEME_ALL, "https://allow.extension.com/*"});
  expected_extension_blocked_set_1.AddPattern(
      {URLPattern::SCHEME_ALL, "https://block.extension.com/*"});

  EXPECT_EQ(expected_extension_allowed_set_1,
            GetPolicyAllowedHosts(kTargetExtension));
  EXPECT_EQ(expected_extension_blocked_set_1,
            GetPolicyBlockedHosts(kTargetExtension));

  // Empty allow/block host for the second extension.
  EXPECT_EQ(URLPatternSet(), GetPolicyAllowedHosts(kTargetExtension2));
  EXPECT_EQ(URLPatternSet(), GetPolicyBlockedHosts(kTargetExtension2));

  // Default allow/block host for the third extension.
  URLPatternSet expected_extension_allowed_set_3;
  URLPatternSet expected_extension_blocked_set_3;
  expected_extension_allowed_set_3.AddPattern(
      {URLPattern::SCHEME_ALL, "https://allow.default.com/*"});
  expected_extension_blocked_set_3.AddPattern(
      {URLPattern::SCHEME_ALL, "https://block.default.com/*"});

  EXPECT_EQ(expected_extension_allowed_set_3,
            GetPolicyAllowedHosts(kTargetExtension3));
  EXPECT_EQ(expected_extension_blocked_set_3,
            GetPolicyBlockedHosts(kTargetExtension3));
}

// Tests the 'minimum_version_required' settings of extension management.
TEST_F(ExtensionManagementServiceTest, kMinimumVersionRequired) {
  EXPECT_TRUE(CheckMinimumVersion(kTargetExtension, "0.0"));
  EXPECT_TRUE(CheckMinimumVersion(kTargetExtension, "3.0.0"));
  EXPECT_TRUE(CheckMinimumVersion(kTargetExtension, "9999.0"));

  {
    PrefUpdater pref(pref_service_.get());
    pref.SetMinimumVersionRequired(kTargetExtension, "3.0");
  }

  EXPECT_FALSE(CheckMinimumVersion(kTargetExtension, "0.0"));
  EXPECT_FALSE(CheckMinimumVersion(kTargetExtension, "2.99"));
  EXPECT_TRUE(CheckMinimumVersion(kTargetExtension, "3.0.0"));
  EXPECT_TRUE(CheckMinimumVersion(kTargetExtension, "3.0.1"));
  EXPECT_TRUE(CheckMinimumVersion(kTargetExtension, "4.0"));
}

// Tests functionality of new preference as to deprecate legacy
// ExtensionInstallSources policy.
TEST_F(ExtensionManagementServiceTest, NewInstallSources) {
  // Set the legacy preference, and verifies that it works.
  base::Value::List allowed_sites_pref;
  allowed_sites_pref.Append("https://www.example.com/foo");
  SetPref(true, pref_names::kAllowedInstallSites,
          base::Value(std::move(allowed_sites_pref)));
  ASSERT_TRUE(ReadGlobalSettings()->install_sources);
  EXPECT_TRUE(ReadGlobalSettings()->install_sources->MatchesURL(
      GURL("https://www.example.com/foo")));

  // Set the new dictionary preference.
  {
    PrefUpdater updater(pref_service_.get());
    updater.ClearInstallSources();
  }
  // Verifies that the new one overrides the legacy ones.
  ASSERT_TRUE(ReadGlobalSettings()->install_sources);
  EXPECT_FALSE(ReadGlobalSettings()->install_sources->MatchesURL(
      GURL("https://www.example.com/foo")));

  // Updates the new dictionary preference.
  {
    PrefUpdater updater(pref_service_.get());
    updater.AddInstallSource("https://corp.mycompany.com/*");
  }
  ASSERT_TRUE(ReadGlobalSettings()->install_sources);
  EXPECT_TRUE(ReadGlobalSettings()->install_sources->MatchesURL(
      GURL("https://corp.mycompany.com/entry")));
}

// Tests functionality of new preference as to deprecate legacy
// ExtensionAllowedTypes policy.
TEST_F(ExtensionManagementServiceTest, NewAllowedTypes) {
  // Set the legacy preference, and verifies that it works.
  base::Value::List allowed_types_pref;
  allowed_types_pref.Append(Manifest::TYPE_USER_SCRIPT);
  SetPref(true, pref_names::kAllowedTypes,
          base::Value(allowed_types_pref.Clone()));
  ASSERT_TRUE(ReadGlobalSettings()->allowed_types);
  EXPECT_EQ(ReadGlobalSettings()->allowed_types->size(), 1u);
  EXPECT_EQ(ReadGlobalSettings()->allowed_types.value()[0],
            Manifest::TYPE_USER_SCRIPT);

  // Set the new dictionary preference.
  {
    PrefUpdater updater(pref_service_.get());
    updater.ClearAllowedTypes();
  }
  // Verifies that the new one overrides the legacy ones.
  ASSERT_TRUE(ReadGlobalSettings()->allowed_types);
  EXPECT_EQ(ReadGlobalSettings()->allowed_types->size(), 0u);

  // Updates the new dictionary preference.
  {
    PrefUpdater updater(pref_service_.get());
    updater.AddAllowedType("theme");
  }
  ASSERT_TRUE(ReadGlobalSettings()->allowed_types);
  EXPECT_EQ(ReadGlobalSettings()->allowed_types->size(), 1u);
  EXPECT_EQ(ReadGlobalSettings()->allowed_types.value()[0],
            Manifest::TYPE_THEME);
}

// Tests functionality of new preference as to deprecate legacy
// ExtensionInstallBlocklist policy.
TEST_F(ExtensionManagementServiceTest, NewInstallBlocklist) {
  // Set the new dictionary preference.
  {
    PrefUpdater updater(pref_service_.get());
    updater.SetBlocklistedByDefault(false);  // Allowed by default.
    updater.SetIndividualExtensionInstallationAllowed(kTargetExtension, false);
    updater.ClearPerExtensionSettings(kTargetExtension2);
  }
  EXPECT_FALSE(extension_management_->BlocklistedByDefault());
  EXPECT_EQ(GetInstallationModeById(kTargetExtension),
            ExtensionManagement::INSTALLATION_BLOCKED);
  EXPECT_EQ(GetInstallationModeById(kNonExistingExtension),
            ExtensionManagement::INSTALLATION_ALLOWED);

  // Set legacy preference.
  base::Value::List denied_list_pref;
  denied_list_pref.Append("*");
  denied_list_pref.Append(kTargetExtension2);
  SetPref(true, pref_names::kInstallDenyList,
          base::Value(std::move(denied_list_pref)));

  base::Value::List allowed_list_pref;
  allowed_list_pref.Append(kTargetExtension);
  SetPref(true, pref_names::kInstallAllowList,
          base::Value(std::move(allowed_list_pref)));

  // Verifies that the new one have higher priority over the legacy ones.
  EXPECT_FALSE(extension_management_->BlocklistedByDefault());
  EXPECT_EQ(GetInstallationModeById(kTargetExtension),
            ExtensionManagement::INSTALLATION_BLOCKED);
  EXPECT_EQ(GetInstallationModeById(kTargetExtension2),
            ExtensionManagement::INSTALLATION_BLOCKED);
  EXPECT_EQ(GetInstallationModeById(kNonExistingExtension),
            ExtensionManagement::INSTALLATION_ALLOWED);
}

// Tests functionality of new preference as to deprecate legacy
// ExtensionInstallAllowlist policy.
TEST_F(ExtensionManagementServiceTest, NewAllowlist) {
  // Set the new dictionary preference.
  {
    PrefUpdater updater(pref_service_.get());
    updater.SetBlocklistedByDefault(true);  // Disallowed by default.
    updater.SetIndividualExtensionInstallationAllowed(kTargetExtension, true);
    updater.ClearPerExtensionSettings(kTargetExtension2);
  }
  EXPECT_TRUE(extension_management_->BlocklistedByDefault());
  EXPECT_EQ(GetInstallationModeById(kTargetExtension),
            ExtensionManagement::INSTALLATION_ALLOWED);
  EXPECT_EQ(GetInstallationModeById(kNonExistingExtension),
            ExtensionManagement::INSTALLATION_BLOCKED);

  // Set legacy preference.
  base::Value::List denied_list_pref;
  denied_list_pref.Append(kTargetExtension);
  SetPref(true, pref_names::kInstallDenyList,
          base::Value(std::move(denied_list_pref)));

  base::Value::List allowed_list_pref;
  allowed_list_pref.Append(kTargetExtension2);
  SetPref(true, pref_names::kInstallAllowList,
          base::Value(std::move(allowed_list_pref)));

  // Verifies that the new one have higher priority over the legacy ones.
  EXPECT_TRUE(extension_management_->BlocklistedByDefault());
  EXPECT_EQ(GetInstallationModeById(kTargetExtension),
            ExtensionManagement::INSTALLATION_ALLOWED);
  EXPECT_EQ(GetInstallationModeById(kTargetExtension2),
            ExtensionManagement::INSTALLATION_ALLOWED);
  EXPECT_EQ(GetInstallationModeById(kNonExistingExtension),
            ExtensionManagement::INSTALLATION_BLOCKED);
}

// Tests functionality of new preference as to deprecate legacy
// ExtensionInstallForcelist policy.
TEST_F(ExtensionManagementServiceTest, NewInstallForcelist) {
  // Set some legacy preferences, to verify that the new one overrides the
  // legacy ones.
  base::Value::List denied_list_pref;
  denied_list_pref.Append(kTargetExtension);
  SetPref(true, pref_names::kInstallDenyList,
          base::Value(std::move(denied_list_pref)));

  // Set the new dictionary preference.
  {
    PrefUpdater updater(pref_service_.get());
    updater.SetIndividualExtensionAutoInstalled(
        kTargetExtension, kExampleUpdateUrl, true);
  }
  EXPECT_EQ(GetInstallationModeById(kTargetExtension),
            ExtensionManagement::INSTALLATION_FORCED);
  CheckAutomaticallyInstalledUpdateUrl(kTargetExtension, kExampleUpdateUrl);
  EXPECT_EQ(GetInstallationModeById(kNonExistingExtension),
            ExtensionManagement::INSTALLATION_ALLOWED);
}

// Tests the behavior of IsInstallationExplicitlyAllowed().
TEST_F(ExtensionManagementServiceTest, IsInstallationExplicitlyAllowed) {
  SetExampleDictPref(kExampleDictPreference);

  // Constant name indicates the installation_mode of extensions in example
  // preference.
  const char* allowed = kTargetExtension;
  const char* forced  = kTargetExtension2;
  const char* recommended = kTargetExtension3;
  const char* blocked = kTargetExtension4;
  const char* removed = kTargetExtension9;
  const char* not_specified = kNonExistingExtension;

  // BlocklistedByDefault() is true in example preference.
  EXPECT_TRUE(extension_management_->IsInstallationExplicitlyAllowed(allowed));
  EXPECT_TRUE(extension_management_->IsInstallationExplicitlyAllowed(forced));
  EXPECT_TRUE(
      extension_management_->IsInstallationExplicitlyAllowed(recommended));
  EXPECT_FALSE(extension_management_->IsInstallationExplicitlyAllowed(blocked));
  EXPECT_FALSE(extension_management_->IsInstallationExplicitlyAllowed(removed));
  EXPECT_FALSE(
      extension_management_->IsInstallationExplicitlyAllowed(not_specified));

  // Set BlocklistedByDefault() to false.
  PrefUpdater pref(pref_service_.get());
  pref.SetBlocklistedByDefault(false);

  // The result should remain the same.
  EXPECT_TRUE(extension_management_->IsInstallationExplicitlyAllowed(allowed));
  EXPECT_TRUE(extension_management_->IsInstallationExplicitlyAllowed(forced));
  EXPECT_TRUE(
      extension_management_->IsInstallationExplicitlyAllowed(recommended));
  EXPECT_FALSE(extension_management_->IsInstallationExplicitlyAllowed(blocked));
  EXPECT_FALSE(extension_management_->IsInstallationExplicitlyAllowed(removed));
  EXPECT_FALSE(
      extension_management_->IsInstallationExplicitlyAllowed(not_specified));
}

TEST_F(ExtensionManagementServiceTest, IsInstallationExplicitlyBlocked) {
  SetExampleDictPref(kExampleDictPreference);

  // Constant name indicates the installation_mode of extensions in example
  // preference.
  const char* allowed = kTargetExtension;
  const char* forced = kTargetExtension2;
  const char* recommended = kTargetExtension3;
  const char* blocked = kTargetExtension4;
  const char* removed = kTargetExtension9;
  const char* not_specified = kNonExistingExtension;

  // BlocklistedByDefault() is true in example preference.
  EXPECT_FALSE(extension_management_->IsInstallationExplicitlyBlocked(allowed));
  EXPECT_FALSE(extension_management_->IsInstallationExplicitlyBlocked(forced));
  EXPECT_FALSE(
      extension_management_->IsInstallationExplicitlyBlocked(recommended));
  EXPECT_TRUE(extension_management_->IsInstallationExplicitlyBlocked(blocked));
  EXPECT_TRUE(extension_management_->IsInstallationExplicitlyBlocked(removed));
  EXPECT_FALSE(
      extension_management_->IsInstallationExplicitlyBlocked(not_specified));

  PrefUpdater pref(pref_service_.get());
  pref.SetBlocklistedByDefault(false);

  EXPECT_FALSE(extension_management_->IsInstallationExplicitlyBlocked(allowed));
  EXPECT_FALSE(extension_management_->IsInstallationExplicitlyBlocked(forced));
  EXPECT_FALSE(
      extension_management_->IsInstallationExplicitlyBlocked(recommended));
  EXPECT_TRUE(extension_management_->IsInstallationExplicitlyBlocked(blocked));
  EXPECT_TRUE(extension_management_->IsInstallationExplicitlyBlocked(removed));
  EXPECT_FALSE(
      extension_management_->IsInstallationExplicitlyBlocked(not_specified));
}

TEST_F(ExtensionManagementServiceTest,
       ExtensionsAreBlockedByDefaultForExtensionRequest) {
  // When extension request policy is set to true, all extensions are blocked by
  // default.
  SetPref(true, prefs::kCloudExtensionRequestEnabled,
          std::make_unique<base::Value>(true));
  EXPECT_TRUE(extension_management_->BlocklistedByDefault());
  EXPECT_EQ(ExtensionManagement::INSTALLATION_BLOCKED,
            GetInstallationModeById(kTargetExtension));
  // However, it will be overridden by ExtensionSettings
  SetExampleDictPref(R"({
    "*": {
      "installation_mode": "removed",
    }
  })");
  EXPECT_EQ(ExtensionManagement::INSTALLATION_REMOVED,
            GetInstallationModeById(kTargetExtension));
}

TEST_F(ExtensionManagementServiceTest, ManifestV2Default) {
  SetPref(true, pref_names::kManifestV2Availability,
          base::Value(static_cast<int>(
              internal::GlobalSettings::ManifestV2Setting::kDefault)));
  bool is_manifest_v3_only = base::FeatureList::IsEnabled(
      extensions_features::kExtensionsManifestV3Only);
  EXPECT_EQ(!is_manifest_v3_only,
            extension_management_->IsAllowedManifestVersion(
                2, kTargetExtension, Manifest::Type::TYPE_EXTENSION));
  EXPECT_TRUE(extension_management_->IsAllowedManifestVersion(
      3, kTargetExtension, Manifest::Type::TYPE_EXTENSION));
}

TEST_F(ExtensionManagementServiceTest, ManifestV2Disabled) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndDisableFeature(
      extensions_features::kExtensionsManifestV3Only);
  SetPref(true, pref_names::kManifestV2Availability,
          base::Value(static_cast<int>(
              internal::GlobalSettings::ManifestV2Setting::kDisabled)));
  EXPECT_FALSE(extension_management_->IsAllowedManifestVersion(
      2, kTargetExtension, Manifest::Type::TYPE_EXTENSION));
  EXPECT_TRUE(extension_management_->IsAllowedManifestVersion(
      3, kTargetExtension, Manifest::Type::TYPE_EXTENSION));
}

TEST_F(ExtensionManagementServiceTest, ManifestV2Enabled) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeature(
      extensions_features::kExtensionsManifestV3Only);
  SetPref(true, pref_names::kManifestV2Availability,
          base::Value(static_cast<int>(
              internal::GlobalSettings::ManifestV2Setting::kEnabled)));
  EXPECT_TRUE(extension_management_->IsAllowedManifestVersion(
      2, kTargetExtension, Manifest::Type::TYPE_EXTENSION));
  EXPECT_TRUE(extension_management_->IsAllowedManifestVersion(
      3, kTargetExtension, Manifest::Type::TYPE_EXTENSION));
}

TEST_F(ExtensionManagementServiceTest, ManifestV2EnabledForForceInstalled) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeature(
      extensions_features::kExtensionsManifestV3Only);
  SetPref(
      true, pref_names::kManifestV2Availability,
      base::Value(static_cast<int>(internal::GlobalSettings::ManifestV2Setting::
                                       kEnabledForForceInstalled)));
  EXPECT_FALSE(extension_management_->IsAllowedManifestVersion(
      2, kTargetExtension, Manifest::Type::TYPE_EXTENSION));
  EXPECT_TRUE(extension_management_->IsAllowedManifestVersion(
      3, kTargetExtension, Manifest::Type::TYPE_EXTENSION));

  base::Value::Dict forced_list_pref;
  ExternalPolicyLoader::AddExtension(forced_list_pref, kTargetExtension,
                                     kExampleUpdateUrl);
  SetPref(true, pref_names::kInstallForceList, forced_list_pref.Clone());

  EXPECT_TRUE(extension_management_->IsAllowedManifestVersion(
      2, kTargetExtension, Manifest::Type::TYPE_EXTENSION));
  EXPECT_TRUE(extension_management_->IsAllowedManifestVersion(
      3, kTargetExtension, Manifest::Type::TYPE_EXTENSION));
}

TEST_F(ExtensionManagementServiceTest, ManifestV2EnabledForExtensionOnly) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeature(
      extensions_features::kExtensionsManifestV3Only);
  SetPref(true, pref_names::kManifestV2Availability,
          base::Value(static_cast<int>(
              internal::GlobalSettings::ManifestV2Setting::kEnabled)));
  EXPECT_TRUE(extension_management_->IsAllowedManifestVersion(
      2, kTargetExtension, Manifest::Type::TYPE_EXTENSION));
  EXPECT_TRUE(extension_management_->IsAllowedManifestVersion(
      2, kTargetExtension, Manifest::Type::TYPE_LOGIN_SCREEN_EXTENSION));
  EXPECT_FALSE(extension_management_->IsAllowedManifestVersion(
      2, kTargetExtension, Manifest::Type::TYPE_HOSTED_APP));
}

// Tests the flag value indicating that extensions are blocklisted by default.
TEST_F(ExtensionAdminPolicyTest, BlocklistedByDefault) {
  EXPECT_FALSE(BlocklistedByDefault(nullptr));

  base::Value::List blocklist;
  blocklist.Append(kNonExistingExtension);
  EXPECT_FALSE(BlocklistedByDefault(&blocklist));
  blocklist.Append("*");
  EXPECT_TRUE(BlocklistedByDefault(&blocklist));

  blocklist.clear();
  blocklist.Append("*");
  EXPECT_TRUE(BlocklistedByDefault(&blocklist));
}

// Tests UserMayLoad for required extensions.
TEST_F(ExtensionAdminPolicyTest, UserMayLoadRequired) {
  CreateExtension(ManifestLocation::kComponent);
  EXPECT_TRUE(
      UserMayLoad(nullptr, nullptr, nullptr, extension_.get(), nullptr));
  std::u16string error;
  EXPECT_TRUE(UserMayLoad(nullptr, nullptr, nullptr, extension_.get(), &error));
  EXPECT_TRUE(error.empty());

  // Required extensions may load even if they're on the blocklist.
  base::Value::List blocklist;
  blocklist.Append(extension_->id());
  EXPECT_TRUE(
      UserMayLoad(&blocklist, nullptr, nullptr, extension_.get(), nullptr));

  blocklist.Append("*");
  EXPECT_TRUE(
      UserMayLoad(&blocklist, nullptr, nullptr, extension_.get(), nullptr));
}

// Tests UserMayLoad when no blocklist exists, or it's empty.
TEST_F(ExtensionAdminPolicyTest, UserMayLoadNoBlocklist) {
  CreateExtension(ManifestLocation::kInternal);
  EXPECT_TRUE(
      UserMayLoad(nullptr, nullptr, nullptr, extension_.get(), nullptr));
  base::Value::List blocklist;
  EXPECT_TRUE(
      UserMayLoad(&blocklist, nullptr, nullptr, extension_.get(), nullptr));
  std::u16string error;
  EXPECT_TRUE(
      UserMayLoad(&blocklist, nullptr, nullptr, extension_.get(), &error));
  EXPECT_TRUE(error.empty());
}

// Tests UserMayLoad for an extension on the allowlist.
TEST_F(ExtensionAdminPolicyTest, UserMayLoadAllowlisted) {
  CreateExtension(ManifestLocation::kInternal);

  base::Value::List allowlist;
  allowlist.Append(extension_->id());
  EXPECT_TRUE(
      UserMayLoad(nullptr, &allowlist, nullptr, extension_.get(), nullptr));

  base::Value::List blocklist;
  blocklist.Append(extension_->id());
  EXPECT_TRUE(
      UserMayLoad(nullptr, &allowlist, nullptr, extension_.get(), nullptr));
  std::u16string error;
  EXPECT_TRUE(
      UserMayLoad(nullptr, &allowlist, nullptr, extension_.get(), &error));
  EXPECT_TRUE(error.empty());
}

// Tests UserMayLoad for an extension on the blocklist.
TEST_F(ExtensionAdminPolicyTest, UserMayLoadBlocklisted) {
  CreateExtension(ManifestLocation::kInternal);

  // Blocklisted by default.
  base::Value::List blocklist;
  blocklist.Append("*");
  EXPECT_FALSE(
      UserMayLoad(&blocklist, nullptr, nullptr, extension_.get(), nullptr));
  std::u16string error;
  EXPECT_FALSE(
      UserMayLoad(&blocklist, nullptr, nullptr, extension_.get(), &error));
  EXPECT_FALSE(error.empty());

  // Extension on the blocklist, with and without wildcard.
  blocklist.Append(extension_->id());
  EXPECT_FALSE(
      UserMayLoad(&blocklist, nullptr, nullptr, extension_.get(), nullptr));
  blocklist.clear();
  blocklist.Append(extension_->id());
  EXPECT_FALSE(
      UserMayLoad(&blocklist, nullptr, nullptr, extension_.get(), nullptr));

  // With a allowlist. There's no such thing as a allowlist wildcard.
  base::Value::List allowlist;
  allowlist.Append("behllobkkfkfnphdnhnkndlbkcpglgmj");
  EXPECT_FALSE(
      UserMayLoad(&blocklist, &allowlist, nullptr, extension_.get(), nullptr));
  allowlist.Append("*");
  EXPECT_FALSE(
      UserMayLoad(&blocklist, &allowlist, nullptr, extension_.get(), nullptr));
}

TEST_F(ExtensionAdminPolicyTest, UserMayLoadAllowedTypes) {
  CreateExtension(ManifestLocation::kInternal);
  EXPECT_TRUE(
      UserMayLoad(nullptr, nullptr, nullptr, extension_.get(), nullptr));

  base::Value::List allowed_types;
  EXPECT_FALSE(
      UserMayLoad(nullptr, nullptr, &allowed_types, extension_.get(), nullptr));

  allowed_types.Append(Manifest::TYPE_EXTENSION);
  EXPECT_TRUE(
      UserMayLoad(nullptr, nullptr, &allowed_types, extension_.get(), nullptr));

  CreateHostedApp(ManifestLocation::kInternal);
  EXPECT_FALSE(
      UserMayLoad(nullptr, nullptr, &allowed_types, extension_.get(), nullptr));

  CreateHostedApp(ManifestLocation::kExternalPolicyDownload);
  EXPECT_FALSE(
      UserMayLoad(nullptr, nullptr, &allowed_types, extension_.get(), nullptr));
}

TEST_F(ExtensionAdminPolicyTest, UserMayModifySettings) {
  CreateExtension(ManifestLocation::kInternal);
  EXPECT_TRUE(UserMayModifySettings(extension_.get(), nullptr));
  std::u16string error;
  EXPECT_TRUE(UserMayModifySettings(extension_.get(), &error));
  EXPECT_TRUE(error.empty());

  CreateExtension(ManifestLocation::kExternalPolicyDownload);
  error.clear();
  EXPECT_FALSE(UserMayModifySettings(extension_.get(), nullptr));
  EXPECT_FALSE(UserMayModifySettings(extension_.get(), &error));
  EXPECT_FALSE(error.empty());
}

TEST_F(ExtensionAdminPolicyTest, ExtensionMayModifySettings) {
  CreateExtension(ManifestLocation::kExternalPolicyDownload);
  auto external_policy_download = extension_;
  CreateExtension(ManifestLocation::kExternalPolicy);
  auto external_policy = extension_;
  CreateExtension(ManifestLocation::kExternalPref);
  auto external_pref = extension_;
  CreateExtension(ManifestLocation::kComponent);
  auto component = extension_;
  CreateExtension(ManifestLocation::kComponent);
  auto component2 = extension_;
  // Make sure that component/policy/external extensions cannot modify component
  // extensions (no extension may modify a component extension).
  EXPECT_FALSE(ExtensionMayModifySettings(external_policy_download.get(),
                                          component.get(), nullptr));
  EXPECT_FALSE(
      ExtensionMayModifySettings(component2.get(), component.get(), nullptr));
  EXPECT_FALSE(ExtensionMayModifySettings(external_pref.get(), component.get(),
                                          nullptr));

  // Only component/policy extensions *can* modify policy extensions, and eg.
  // external cannot.
  EXPECT_TRUE(ExtensionMayModifySettings(
      external_policy.get(), external_policy_download.get(), nullptr));
  EXPECT_TRUE(ExtensionMayModifySettings(
      component.get(), external_policy_download.get(), nullptr));
  EXPECT_FALSE(ExtensionMayModifySettings(
      external_pref.get(), external_policy_download.get(), nullptr));
}

TEST_F(ExtensionAdminPolicyTest, MustRemainEnabled) {
  CreateExtension(ManifestLocation::kExternalPolicyDownload);
  EXPECT_TRUE(MustRemainEnabled(extension_.get(), nullptr));
  std::u16string error;
  EXPECT_TRUE(MustRemainEnabled(extension_.get(), &error));
  EXPECT_FALSE(error.empty());

  CreateExtension(ManifestLocation::kInternal);
  error.clear();
  EXPECT_FALSE(MustRemainEnabled(extension_.get(), nullptr));
  EXPECT_FALSE(MustRemainEnabled(extension_.get(), &error));
  EXPECT_TRUE(error.empty());
}

}  // namespace extensions
