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

#include "chrome/browser/extensions/extension_management.h"

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

#include "base/containers/contains.h"
#include "base/json/json_reader.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.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_urls.h"
#include "extensions/common/manifest.h"
#include "extensions/common/manifest_constants.h"
#include "extensions/common/permissions/api_permission.h"
#include "extensions/common/permissions/permissions_info.h"
#include "extensions/common/url_pattern.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 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 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) {
    base::JSONReader::ValueWithError result =
        base::JSONReader::ReadAndReturnValueWithError(
            example_dict_preference,
            base::JSONParserOptions::JSON_ALLOW_TRAILING_COMMAS);
    ASSERT_TRUE(result.value && result.value->is_dict())
        << result.error_message;
    SetPref(true, pref_names::kExtensionManagement,
            base::Value::ToUniquePtrValue(std::move(*result.value)));
  }

  // 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::DictionaryValue manifest_dict;
    manifest_dict.SetString(manifest_keys::kName, "test");
    manifest_dict.SetString(manifest_keys::kVersion, version);
    manifest_dict.SetInteger(manifest_keys::kManifestVersion, 2);
    manifest_dict.SetString(manifest_keys::kUpdateURL, update_url);
    std::string error;
    scoped_refptr<const Extension> extension =
        Extension::Create(base::FilePath(), location, 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_;
  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::DictionaryValue values;
    CreateExtensionFromValues(location, &values);
  }

  void CreateHostedApp(ManifestLocation location) {
    base::DictionaryValue values;
    values.Set(extensions::manifest_keys::kWebURLs,
               std::make_unique<base::ListValue>());
    values.SetString(extensions::manifest_keys::kLaunchWebURL,
                     "http://www.example.com");
    CreateExtensionFromValues(location, &values);
  }

  void CreateExtensionFromValues(ManifestLocation location,
                                 base::DictionaryValue* values) {
    values->SetString(extensions::manifest_keys::kName, "test");
    values->SetString(extensions::manifest_keys::kVersion, "0.1");
    values->SetInteger(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::ListValue* blocklist);
  bool UserMayLoad(const base::ListValue* blocklist,
                   const base::ListValue* allowlist,
                   const base::DictionaryValue* forcelist,
                   const base::ListValue* 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::ListValue* blocklist) {
  SetUpPolicyProvider();
  if (blocklist)
    SetPref(true, pref_names::kInstallDenyList, blocklist->CreateDeepCopy());
  return extension_management_->BlocklistedByDefault();
}

bool ExtensionAdminPolicyTest::UserMayLoad(
    const base::ListValue* blocklist,
    const base::ListValue* allowlist,
    const base::DictionaryValue* forcelist,
    const base::ListValue* allowed_types,
    const Extension* extension,
    std::u16string* error) {
  SetUpPolicyProvider();
  if (blocklist)
    SetPref(true, pref_names::kInstallDenyList, blocklist->CreateDeepCopy());
  if (allowlist)
    SetPref(true, pref_names::kInstallAllowList, allowlist->CreateDeepCopy());
  if (forcelist)
    SetPref(true, pref_names::kInstallForceList, forcelist->CreateDeepCopy());
  if (allowed_types)
    SetPref(true, pref_names::kAllowedTypes, allowed_types->CreateDeepCopy());
  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::ListValue allowed_sites_pref;
  allowed_sites_pref.AppendString("https://www.example.com/foo");
  allowed_sites_pref.AppendString("https://corp.mycompany.com/*");
  SetPref(true, pref_names::kAllowedInstallSites,
          allowed_sites_pref.CreateDeepCopy());
  const URLPatternSet& allowed_sites = ReadGlobalSettings()->install_sources;
  ASSERT_TRUE(ReadGlobalSettings()->has_restricted_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::ListValue allowed_types_pref;
  allowed_types_pref.AppendInteger(Manifest::TYPE_THEME);
  allowed_types_pref.AppendInteger(Manifest::TYPE_USER_SCRIPT);

  SetPref(true, pref_names::kAllowedTypes, allowed_types_pref.CreateDeepCopy());
  const std::vector<Manifest::Type>& allowed_types =
      ReadGlobalSettings()->allowed_types;
  ASSERT_TRUE(ReadGlobalSettings()->has_restricted_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::ListValue denied_list_pref;
  denied_list_pref.AppendString(kTargetExtension);

  SetPref(true, pref_names::kInstallDenyList,
          denied_list_pref.CreateDeepCopy());
  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::ListValue denied_list_pref;
  denied_list_pref.AppendString("*");
  base::ListValue allowed_list_pref;
  allowed_list_pref.AppendString(kTargetExtension);

  SetPref(true, pref_names::kInstallDenyList,
          denied_list_pref.CreateDeepCopy());
  SetPref(true, pref_names::kInstallAllowList,
          allowed_list_pref.CreateDeepCopy());
  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,
          allowed_list_pref.CreateDeepCopy());
  EXPECT_EQ(GetInstallationModeById(kTargetExtension),
            ExtensionManagement::INSTALLATION_BLOCKED);
}

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

  SetPref(true, pref_names::kInstallForceList,
          forced_list_pref.CreateDeepCopy());
  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.CreateDeepCopy());
  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::DictionaryValue 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.CreateDeepCopy());
  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::DictionaryValue forced_list_pref;
  ExternalPolicyLoader::AddExtension(&forced_list_pref, kTargetExtension2,
                                     kExampleUpdateUrl);
  SetPref(true, pref_names::kInstallForceList,
          forced_list_pref.CreateDeepCopy());

  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::DictionaryValue 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.CreateDeepCopy());
  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 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.
  EXPECT_TRUE(ReadGlobalSettings()->has_restricted_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")));

  EXPECT_TRUE(ReadGlobalSettings()->has_restricted_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));
}

// 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_);
    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::ListValue allowed_sites_pref;
  allowed_sites_pref.AppendString("https://www.example.com/foo");
  SetPref(true, pref_names::kAllowedInstallSites,
          allowed_sites_pref.CreateDeepCopy());
  EXPECT_TRUE(ReadGlobalSettings()->has_restricted_install_sources);
  EXPECT_TRUE(ReadGlobalSettings()->install_sources.MatchesURL(
      GURL("https://www.example.com/foo")));

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

  // Updates the new dictionary preference.
  {
    PrefUpdater updater(pref_service_);
    updater.AddInstallSource("https://corp.mycompany.com/*");
  }
  EXPECT_TRUE(ReadGlobalSettings()->has_restricted_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::ListValue allowed_types_pref;
  allowed_types_pref.AppendInteger(Manifest::TYPE_USER_SCRIPT);
  SetPref(true, pref_names::kAllowedTypes, allowed_types_pref.CreateDeepCopy());
  EXPECT_TRUE(ReadGlobalSettings()->has_restricted_allowed_types);
  EXPECT_EQ(ReadGlobalSettings()->allowed_types.size(), 1u);
  EXPECT_EQ(ReadGlobalSettings()->allowed_types[0], Manifest::TYPE_USER_SCRIPT);

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

  // Updates the new dictionary preference.
  {
    PrefUpdater updater(pref_service_);
    updater.AddAllowedType("theme");
  }
  EXPECT_TRUE(ReadGlobalSettings()->has_restricted_allowed_types);
  EXPECT_EQ(ReadGlobalSettings()->allowed_types.size(), 1u);
  EXPECT_EQ(ReadGlobalSettings()->allowed_types[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_);
    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::ListValue denied_list_pref;
  denied_list_pref.AppendString("*");
  denied_list_pref.AppendString(kTargetExtension2);
  SetPref(true, pref_names::kInstallDenyList,
          denied_list_pref.CreateDeepCopy());

  base::ListValue allowed_list_pref;
  allowed_list_pref.AppendString(kTargetExtension);
  SetPref(true, pref_names::kInstallAllowList,
          allowed_list_pref.CreateDeepCopy());

  // 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_);
    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::ListValue denied_list_pref;
  denied_list_pref.AppendString(kTargetExtension);
  SetPref(true, pref_names::kInstallDenyList,
          denied_list_pref.CreateDeepCopy());

  base::ListValue allowed_list_pref;
  allowed_list_pref.AppendString(kTargetExtension2);
  SetPref(true, pref_names::kInstallAllowList,
          allowed_list_pref.CreateDeepCopy());

  // 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::ListValue denied_list_pref;
  denied_list_pref.AppendString(kTargetExtension);
  SetPref(true, pref_names::kInstallDenyList,
          denied_list_pref.CreateDeepCopy());

  // Set the new dictionary preference.
  {
    PrefUpdater updater(pref_service_);
    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_);
  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_);
  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));
}

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

  base::ListValue blocklist;
  blocklist.AppendString(kNonExistingExtension);
  EXPECT_FALSE(BlocklistedByDefault(&blocklist));
  blocklist.AppendString("*");
  EXPECT_TRUE(BlocklistedByDefault(&blocklist));

  blocklist.Clear();
  blocklist.AppendString("*");
  EXPECT_TRUE(BlocklistedByDefault(&blocklist));
}

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

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

  blocklist.AppendString("*");
  EXPECT_TRUE(UserMayLoad(&blocklist, nullptr, 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, nullptr, extension_.get(),
                          nullptr));
  base::ListValue blocklist;
  EXPECT_TRUE(UserMayLoad(&blocklist, nullptr, nullptr, nullptr,
                          extension_.get(), nullptr));
  std::u16string error;
  EXPECT_TRUE(UserMayLoad(&blocklist, nullptr, 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::ListValue allowlist;
  allowlist.AppendString(extension_->id());
  EXPECT_TRUE(UserMayLoad(nullptr, &allowlist, nullptr, nullptr,
                          extension_.get(), nullptr));

  base::ListValue blocklist;
  blocklist.AppendString(extension_->id());
  EXPECT_TRUE(UserMayLoad(nullptr, &allowlist, nullptr, nullptr,
                          extension_.get(), nullptr));
  std::u16string error;
  EXPECT_TRUE(UserMayLoad(nullptr, &allowlist, nullptr, 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::ListValue blocklist;
  blocklist.AppendString("*");
  EXPECT_FALSE(UserMayLoad(&blocklist, nullptr, nullptr, nullptr,
                           extension_.get(), nullptr));
  std::u16string error;
  EXPECT_FALSE(UserMayLoad(&blocklist, nullptr, nullptr, nullptr,
                           extension_.get(), &error));
  EXPECT_FALSE(error.empty());

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

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

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

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

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

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

  CreateHostedApp(ManifestLocation::kExternalPolicyDownload);
  EXPECT_FALSE(UserMayLoad(nullptr, 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
