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

#include "chrome/browser/extensions/updater/extension_updater.h"

#include <stddef.h>
#include <stdint.h>

#include <algorithm>
#include <array>
#include <list>
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "base/command_line.h"
#include "base/containers/contains.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
#include "base/strings/escape.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
#include "base/version.h"
#include "build/branding_buildflags.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/extensions/crx_installer.h"
#include "chrome/browser/extensions/fake_crx_installer.h"
#include "chrome/browser/extensions/mock_crx_installer.h"
#include "chrome/browser/extensions/sync/extension_sync_data.h"
#include "chrome/browser/extensions/test_extension_service.h"
#include "chrome/browser/extensions/test_extension_system.h"
#include "chrome/browser/extensions/updater/chrome_extension_downloader_factory.h"
#include "chrome/browser/google/google_brand.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "components/crx_file/id_util.h"
#include "components/prefs/pref_service.h"
#include "components/signin/public/identity_manager/identity_test_environment.h"
#include "components/sync_preferences/pref_service_syncable.h"
#include "components/update_client/update_query_params.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/test_utils.h"
#include "extensions/browser/blocklist_extension_prefs.h"
#include "extensions/browser/blocklist_state.h"
#include "extensions/browser/delayed_install_manager.h"
#include "extensions/browser/disable_reason.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/pending_extension_manager.h"
#include "extensions/browser/pref_names.h"
#include "extensions/browser/test_extension_prefs.h"
#include "extensions/browser/updater/extension_downloader.h"
#include "extensions/browser/updater/extension_downloader_delegate.h"
#include "extensions/browser/updater/extension_downloader_test_delegate.h"
#include "extensions/browser/updater/extension_downloader_test_helper.h"
#include "extensions/browser/updater/extension_downloader_types.h"
#include "extensions/browser/updater/extension_update_data.h"
#include "extensions/browser/updater/manifest_fetch_data.h"
#include "extensions/browser/updater/request_queue_impl.h"
#include "extensions/buildflags/buildflags.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_builder.h"
#include "extensions/common/extension_urls.h"
#include "extensions/common/extensions_client.h"
#include "extensions/common/manifest_constants.h"
#include "extensions/common/manifest_url_handlers.h"
#include "extensions/common/mojom/manifest.mojom-shared.h"
#include "extensions/common/verifier_formats.h"
#include "net/base/backoff_entry.h"
#include "net/base/load_flags.h"
#include "net/http/http_request_headers.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
#include "services/network/test/test_url_loader_factory.h"
#include "services/network/test/test_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/third_party/mozilla/url_parse.h"

#if BUILDFLAG(IS_CHROMEOS)
#include "base/files/scoped_temp_dir.h"
#include "chrome/browser/ash/login/users/user_manager_delegate_impl.h"
#include "chrome/browser/ash/settings/scoped_cros_settings_test_helper.h"
#include "chrome/browser/extensions/load_error_reporter.h"
#include "chrome/browser/extensions/updater/chromeos_extension_cache_delegate.h"
#include "chrome/browser/extensions/updater/extension_cache_impl.h"
#include "chrome/browser/extensions/updater/local_extension_cache.h"
#include "chromeos/ash/components/settings/cros_settings.h"
#include "components/user_manager/scoped_user_manager.h"
#include "components/user_manager/user_manager_impl.h"
#endif

static_assert(BUILDFLAG(ENABLE_EXTENSIONS_CORE));

using base::Time;
using content::BrowserThread;
using extensions::mojom::ManifestLocation;
using testing::_;
using testing::DoAll;
using testing::InvokeWithoutArgs;
using testing::Mock;
using testing::NiceMock;
using testing::Return;
using testing::SetArgPointee;
using update_client::UpdateQueryParams;

namespace extensions {

using Error = ExtensionDownloaderDelegate::Error;
using PingResult = ExtensionDownloaderDelegate::PingResult;

namespace {

const net::BackoffEntry::Policy kNoBackoffPolicy = {
  // Number of initial errors (in sequence) to ignore before applying
  // exponential back-off rules.
  1000,

  // Initial delay for exponential back-off in ms.
  0,

  // Factor by which the waiting time will be multiplied.
  0,

  // Fuzzing percentage. ex: 10% will spread requests randomly
  // between 90%-100% of the calculated time.
  0,

  // Maximum amount of time we are willing to delay our request in ms.
  0,

  // Time to keep an entry from being discarded even when it
  // has no significant state, -1 to never discard.
  -1,

  // Don't use initial delay unless the last request was an error.
  false,
};

const char kAuthUserQueryKey[] = "authuser";

int kExpectedLoadFlags = net::LOAD_DISABLE_CACHE;

int kExpectedLoadFlagsForDownloadWithCookies = net::LOAD_DISABLE_CACHE;

// Fake authentication constants
const char kFakeOAuth2Token[] = "ce n'est pas un jeton";

// Manifest key used to make multiple extensions with the same ID.
constexpr char kExtensionManifestKey[] =
    "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDowC9B4+K6zbl4PnALNyOUgra/"
    "MPdD8gZ39Fk/IAJWt03qrN7vz1gd/"
    "mmrBg0EEIsyLRmUmfyVEfvcIUOZxFqn4A9D2aaRSvNHy9qkasZMBDEql8Nt2iNZm/"
    "kGS7sizidDV6Bc/vyLNiH1gKOXBQ42JIxKjgtrmnhGV2giw2vJGwIDAQAB";

constexpr base::TimeDelta kUpdateFrequency = base::Seconds(15);

// Extracts the integer value of the |authuser| query parameter. Returns 0 if
// the parameter is not set.
int GetAuthUserQueryValue(const GURL& url) {
  std::string_view query_piece = url.query();
  url::Component query(0, query_piece.length());
  url::Component key, value;
  while (url::ExtractQueryKeyValue(query_piece, &query, &key, &value)) {
    std::string_view key_string = query_piece.substr(key.begin, key.len);
    if (key_string == kAuthUserQueryKey) {
      int user_index = 0;
      base::StringToInt(query_piece.substr(value.begin, value.len),
                        &user_index);
      return user_index;
    }
  }
  return 0;
}

// A minimal stub implementation of the ExtensionRegistrar::Delegate.
class StubExtensionRegistrarDelegate : public ExtensionRegistrar::Delegate {
 public:
  StubExtensionRegistrarDelegate() = default;
  ~StubExtensionRegistrarDelegate() override = default;

  // ExtensionRegistrar::Delegate:
  void PreAddExtension(const Extension* extension,
                       const Extension* old_extension) override {}
  void OnAddNewOrUpdatedExtension(const Extension* extension) override {}
  void PostActivateExtension(
      scoped_refptr<const Extension> extension) override {}
  void PostDeactivateExtension(
      scoped_refptr<const Extension> extension) override {}
  void PreUninstallExtension(
      scoped_refptr<const Extension> extension) override {}
  void PostUninstallExtension(scoped_refptr<const Extension> extension,
                              base::OnceClosure done_callback) override {}
  void ShowExtensionDisabledError(const Extension* extension,
                                  bool is_remote_install) override {}
  void LoadExtensionForReload(const ExtensionId& extension_id,
                              const base::FilePath& path) override {}
  void LoadExtensionForReloadWithQuietFailure(
      const ExtensionId& extension_id,
      const base::FilePath& path) override {}
  bool CanEnableExtension(const Extension* extension) override { return true; }
  bool CanDisableExtension(const Extension* extension) override { return true; }
  void GrantActivePermissions(const Extension* extension) override {}
  void UpdateExternalExtensionAlert() override {}
  void OnExtensionInstalled(const Extension* extension,
                            const syncer::StringOrdinal& page_ordinal,
                            int install_flags,
                            base::Value::Dict ruleset_install_prefs) override {}
};

class MockUpdateService : public UpdateService {
 public:
  MockUpdateService()
      : UpdateService(nullptr,
                      nullptr,
                      base::BindRepeating([](const std::vector<std::string>&,
                                             base::OnceClosure callback) {
                        std::move(callback).Run();
                      })) {}
  MOCK_CONST_METHOD0(IsBusy, bool());
  MOCK_METHOD3(SendUninstallPing,
               void(const std::string& id,
                    const base::Version& version,
                    int reason));
  MOCK_METHOD(void,
              StartUpdateCheck,
              (const ExtensionUpdateCheckParams& params,
               UpdateFoundCallback update_found_callback,
               base::OnceClosure callback),
              (override));
};

}  // namespace

class TestCrxInstallerFactory
    : public ExtensionUpdater::CrxInstallerFactoryForTest {
 public:
  TestCrxInstallerFactory() = default;
  TestCrxInstallerFactory(const TestCrxInstallerFactory&) = delete;
  TestCrxInstallerFactory& operator=(const TestCrxInstallerFactory&) = delete;
  ~TestCrxInstallerFactory() override = default;

  const ExtensionId& crx_extension_id() const { return crx_extension_id_; }

  const base::FilePath& crx_install_path() const { return crx_install_path_; }

  // Add a fake crx installer to be returned by a call to
  // CreateUpdateInstaller() with a specific ID.
  void AddFakeCrxInstaller(const std::string& id,
                           scoped_refptr<CrxInstaller> crx_installer) {
    fake_crx_installers_[id] = crx_installer;
  }

  // ExtensionUpdaterDelegate:
  scoped_refptr<CrxInstaller> CreateUpdateInstaller(
      const CRXFileInfo& file,
      bool file_ownership_passed) override {
    crx_extension_id_ = file.extension_id;
    crx_install_path_ = file.path;

    if (base::Contains(fake_crx_installers_, crx_extension_id_)) {
      return fake_crx_installers_[crx_extension_id_];
    }

    return nullptr;
  }

 private:
  // Hold the set of ids that CreateUpdateInstaller() returns.
  std::map<std::string, scoped_refptr<CrxInstaller>> fake_crx_installers_;

  // The last values from the CRXFileInfo passed to CreateUpdateInstaller().
  ExtensionId crx_extension_id_;
  base::FilePath crx_install_path_;
};

// Helper to create ExtensionDownloader::Factory instances. This needs to be
// its own class, not part of ExtensionUpdaterTest, because individual tests
// create their own ExtensionDownloaderTestHelpers, and hence their own
// SharedURLLoaderFactory instances.
class TestDownloaderFactory {
 public:
  explicit TestDownloaderFactory(
      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
      : test_shared_url_loader_factory_(url_loader_factory) {}

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

  ~TestDownloaderFactory() = default;

  signin::IdentityTestEnvironment* identity_test_env() {
    return identity_test_env_.get();
  }

  const CoreAccountId& account_id() { return account_info_.account_id; }

  ExtensionDownloader::Factory GetDownloaderFactory() {
    return base::BindRepeating(
        &TestDownloaderFactory::CreateExtensionDownloader,
        base::Unretained(this));
  }

  ExtensionDownloader::Factory GetAuthenticatedDownloaderFactory() {
    return base::BindRepeating(
        &TestDownloaderFactory::CreateExtensionDownloaderWithIdentity,
        base::Unretained(this));
  }

  void OverrideDownloaderDelegate(ExtensionDownloaderDelegate* delegate) {
    downloader_delegate_override_ = delegate;
  }

 private:
  std::unique_ptr<ExtensionDownloader> CreateExtensionDownloader(
      ExtensionDownloaderDelegate* delegate) {
    std::unique_ptr<ExtensionDownloader> downloader =
        ChromeExtensionDownloaderFactory::CreateForURLLoaderFactory(
            test_shared_url_loader_factory_,
            downloader_delegate_override_ ? downloader_delegate_override_.get()
                                          : delegate,
            GetTestVerifierFormat());
    return downloader;
  }

  std::unique_ptr<ExtensionDownloader> CreateExtensionDownloaderWithIdentity(
      ExtensionDownloaderDelegate* delegate) {
    identity_test_env_ = std::make_unique<signin::IdentityTestEnvironment>();
    account_info_ = identity_test_env_->MakePrimaryAccountAvailable(
        "bobloblaw@lawblog.example.com", signin::ConsentLevel::kSync);

    std::unique_ptr<ExtensionDownloader> downloader(
        CreateExtensionDownloader(delegate));
    downloader->SetIdentityManager(identity_test_env_->identity_manager());
    return downloader;
  }

  AccountInfo account_info_;
  std::unique_ptr<signin::IdentityTestEnvironment> identity_test_env_;

  raw_ptr<ExtensionDownloaderDelegate> downloader_delegate_override_ = nullptr;

  scoped_refptr<network::SharedURLLoaderFactory>
      test_shared_url_loader_factory_;
};

bool ShouldInstallExtensionsOnly(const Extension* extension,
                                 content::BrowserContext* context) {
  return extension->GetType() == Manifest::TYPE_EXTENSION;
}

bool ShouldInstallThemesOnly(const Extension* extension,
                             content::BrowserContext* context) {
  return extension->is_theme();
}

bool ShouldAlwaysInstall(const Extension* extension,
                         content::BrowserContext* context) {
  return true;
}

// Loads some pending extension records into a pending extension manager.
void SetupPendingExtensionManagerForTest(
    int count,
    const GURL& update_url,
    PendingExtensionManager* pending_extension_manager) {
  for (int i = 1; i <= count; ++i) {
    PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install =
        (i % 2 == 0) ? &ShouldInstallThemesOnly : &ShouldInstallExtensionsOnly;
    const bool kIsFromSync = true;
    const bool kMarkAcknowledged = false;
    const bool kRemoteInstall = false;
    std::string id =
        crx_file::id_util::GenerateId(base::StringPrintf("extension%i", i));

    pending_extension_manager->AddForTesting(PendingExtensionInfo(
        id, std::string(), update_url, base::Version(), should_allow_install,
        kIsFromSync, ManifestLocation::kInternal, Extension::NO_FLAGS,
        kMarkAcknowledged, kRemoteInstall));
  }
}

// Takes a string with KEY=VALUE parameters separated by '&' in |params| and
// puts the key/value pairs into |result|. For keys with no value, the empty
// string is used. So for "a=1&b=foo&c", result would map "a" to "1", "b" to
// "foo", and "c" to "".
static void ExtractParameters(const std::string& params,
                              std::map<std::string, std::string>* result) {
  for (const std::string& pair : base::SplitString(
           params, "&", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
    std::vector<std::string> key_val = base::SplitString(
        pair, "=", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
    if (!key_val.empty()) {
      std::string key = key_val[0];
      EXPECT_TRUE(result->find(key) == result->end());
      (*result)[key] = (key_val.size() == 2) ? key_val[1] : std::string();
    } else {
      NOTREACHED();
    }
  }
}

// Helper function to extract the ping data param values for each extension in
// a manifest fetch url, returned in a map keyed by extension id.
// E.g. for "x=id%3Dabcdef%26ping%3Ddr%253D1%2526dr%253D1024" we'd return
// {"abcdef": {"dr": set("1", "1024")}}
typedef std::map<std::string, std::set<std::string>> ParamsMap;
static std::map<std::string, ParamsMap> GetPingDataFromURL(
    const GURL& manifest_url) {
  std::map<std::string, ParamsMap> result;

  base::StringPairs toplevel_params;
  base::SplitStringIntoKeyValuePairs(manifest_url.GetQuery(), '=', '&',
                                     &toplevel_params);
  for (const auto& param : toplevel_params) {
    if (param.first != "x")
      continue;

    // We've found "x=<something>", now unescape <something> and look for
    // the "id=<id>&ping=<ping_value>" parameters within.
    std::string unescaped = base::UnescapeBinaryURLComponent(param.second);
    base::StringPairs extension_params;
    base::SplitStringIntoKeyValuePairs(unescaped, '=', '&', &extension_params);
    std::multimap<std::string, std::string> param_map;
    param_map.insert(extension_params.begin(), extension_params.end());
    if (base::Contains(param_map, "id") && base::Contains(param_map, "ping")) {
      std::string id = param_map.find("id")->second;
      result[id] = ParamsMap();

      // Pull the key=value pairs out of the ping parameter for this id and
      // put into the result.
      std::string ping =
          base::UnescapeBinaryURLComponent(param_map.find("ping")->second);
      base::StringPairs ping_params;
      base::SplitStringIntoKeyValuePairs(ping, '=', '&', &ping_params);
      for (const auto& ping_param : ping_params) {
        if (!base::Contains(result[id], ping_param.first))
          result[id][ping_param.first] = std::set<std::string>();
        result[id][ping_param.first].insert(ping_param.second);
      }
    }
  }
  return result;
}

static void VerifyQueryAndExtractParameters(
    const std::string& query,
    std::map<std::string, std::string>* result) {
  std::map<std::string, std::string> params;
  ExtractParameters(query, &params);

  std::string omaha_params = UpdateQueryParams::Get(UpdateQueryParams::CRX);
  std::map<std::string, std::string> expected;
  ExtractParameters(omaha_params, &expected);

  for (auto it = expected.begin(); it != expected.end(); ++it) {
    EXPECT_EQ(it->second, params[it->first]);
  }

  EXPECT_EQ(1U, params.count("x"));
  std::string decoded = base::UnescapeBinaryURLComponent(params["x"]);
  ExtractParameters(decoded, result);
}

// All of our tests that need to use private APIs of ExtensionUpdater live
// inside this class (which is a friend to ExtensionUpdater).
class ExtensionUpdaterTest : public testing::Test {
 public:
  ExtensionUpdaterTest()
      : task_environment_(content::BrowserTaskEnvironment::IO_MAINLOOP) {}

  void SetUp() override {
    prefs_ = std::make_unique<TestExtensionPrefs>(
        base::SingleThreadTaskRunner::GetCurrentDefault(),
        std::make_unique<TestingProfile>());
    // The registrar needs a delegate in order to call certain methods on it.
    ExtensionRegistrar::Get(prefs_->browser_context())
        ->Init(&stub_extension_registrar_delegate_,
               /*extensions_enabled=*/true,
               base::CommandLine::ForCurrentProcess(), base::FilePath(),
               base::FilePath());
  }

  void TearDown() override {
    // Some tests create URLRequestContextGetters, whose destruction must run
    // on the IO thread. Make sure the IO loop spins before shutdown so that
    // those objects are released.
    RunUntilIdle();
    // Reset the ExtensionRegistrar delegate.
    ExtensionRegistrar::Get(prefs_->browser_context())
        ->Init(/*delegate=*/nullptr, /*extensions_enabled=*/true,
               base::CommandLine::ForCurrentProcess(), base::FilePath(),
               base::FilePath());
    prefs_.reset();
  }

  Profile* profile() {
    return Profile::FromBrowserContext(prefs_->browser_context());
  }

  ExtensionPrefs* extension_prefs() { return prefs_->prefs(); }

  PrefService* pref_service() { return prefs_->pref_service(); }

  // Creates test extensions and inserts them into list. The name and
  // version are all based on their index. If `update_url` is non-null, it
  // will be used as the update_url for each extension. If `key` is non-null,
  // it will be used as manifest_keys::kKey to force an extension to have a
  // particular ID. `key` is only valid if `count` is 1.
  // The `id` is used to distinguish extension names and make sure that
  // no two extensions share the same name.
  void CreateTestExtensions(int id,
                            int count,
                            ExtensionList* list,
                            const std::string* update_url,
                            ManifestLocation location,
                            std::optional<std::string> key = std::nullopt) {
    if (key.has_value()) {
      CHECK_EQ(count, 1) << "Can't create two extensions with the same key";
    }
    for (int i = 1; i <= count; i++) {
      base::Value::Dict manifest;
      manifest.Set(manifest_keys::kVersion, base::StringPrintf("%d.0.0.0", i));
      manifest.Set(manifest_keys::kName,
                   base::StringPrintf("Extension %d.%d", id, i));
      manifest.Set(manifest_keys::kManifestVersion, 2);
      if (update_url) {
        manifest.Set(manifest_keys::kUpdateURL, *update_url);
      }
      if (key.has_value()) {
        manifest.Set(manifest_keys::kKey, *key);
      }
      scoped_refptr<Extension> e =
          prefs_->AddExtensionWithManifest(manifest, location);
      ASSERT_TRUE(e.get() != nullptr);
      list->push_back(e);
    }
  }

  void SetExtensions(
      const ExtensionList& extensions,
      const ExtensionList& disabled_extensions,
      const ExtensionList& blocklisted_extensions = ExtensionList()) {
    auto* registry = ExtensionRegistry::Get(profile());
    registry->ClearAll();
    for (const auto& extension : extensions) {
      registry->AddEnabled(extension);
    }
    for (const auto& extension : disabled_extensions) {
      registry->AddDisabled(extension);
    }
    for (const auto& extension : blocklisted_extensions) {
      registry->AddBlocklisted(extension);
    }
  }

  void RunUntilIdle() {
    prefs_->pref_service()->CommitPendingWrite();
    base::RunLoop().RunUntilIdle();
  }

  void SimulateTimerFired(ExtensionUpdater* updater) { updater->NextCheck(); }

  void OverrideUpdateService(ExtensionUpdater* updater,
                             UpdateService* service) {
    updater->update_service_ = service;
  }

  bool CanUseUpdateService(ExtensionUpdater* updater,
                           const std::string& extension_id) {
    return updater->CanUseUpdateService(extension_id);
  }

  // Adds a Result with the given data to results.
  void AddParseResult(const std::string& id,
                      const std::string& version,
                      const std::string& url,
                      UpdateManifestResults* results) {
    UpdateManifestResult result;
    result.extension_id = id;
    result.version = version;
    result.crx_url = GURL(url);
    results->update_list.push_back(result);
  }

  void StartUpdateCheck(ExtensionDownloader* downloader,
                        ManifestFetchData* fetch_data) {
    downloader->StartUpdateCheck(
        std::unique_ptr<ManifestFetchData>(fetch_data));
  }

  size_t ManifestFetchersCount(ExtensionDownloader* downloader) {
    return downloader->manifests_queue_.size() +
           (downloader->HasActiveManifestRequestForTesting() ? 1 : 0);
  }

  std::set<std::string> GetRunningInstallIds(const ExtensionUpdater& updater) {
    std::set<std::string> ret;
    for (const auto& pair : updater.running_crx_installs_)
      ret.insert(pair.second.info.extension_id);
    return ret;
  }

  const DownloadFailure* GetFailureWithId(
      const std::vector<std::pair<ExtensionDownloaderTask, DownloadFailure>>&
          failures,
      const ExtensionId& id) {
    auto it = std::ranges::find(
        failures, id, [](const auto& failure) { return failure.first.id; });
    return it == failures.end() ? nullptr : &it->second;
  }

  void TestExtensionUpdateCheckRequests(bool pending) {
    // Create an extension with an update_url.
    ExtensionDownloaderTestHelper helper;
    TestDownloaderFactory factory(helper.url_loader_factory());
    TestCrxInstallerFactory crx_installer_factory;
    std::string update_url("http://foo.com/bar");
    ExtensionList extensions;
    PendingExtensionManager* pending_extension_manager =
        PendingExtensionManager::Get(profile());
    if (pending) {
      SetupPendingExtensionManagerForTest(1, GURL(update_url),
                                          pending_extension_manager);
    } else {
      CreateTestExtensions(1, 1, &extensions, &update_url,
                           ManifestLocation::kInternal);
      SetExtensions(extensions, ExtensionList());
    }

    // Set up and start the updater.
    ExtensionUpdater updater(profile());
    updater.InitAndEnable(extension_prefs(), pref_service(), base::Days(1),
                          nullptr, factory.GetDownloaderFactory());
    updater.set_crx_installer_factory_for_test(&crx_installer_factory);
    updater.Start();

    // Tell the update that it's time to do update checks.
    SimulateTimerFired(&updater);

    // Get the url our loader was asked to fetch.
    const ManifestFetchData& fetch =
        *updater.downloader_->manifests_queue_.active_request();

    const GURL& url = fetch.full_url();

    EXPECT_FALSE(url.is_empty());
    EXPECT_TRUE(url.is_valid());
    EXPECT_TRUE(url.SchemeIs("http"));
    EXPECT_EQ("foo.com", url.GetHost());
    EXPECT_EQ("/bar", url.GetPath());

    // Validate the extension request parameters in the query. It should
    // look something like "x=id%3D<id>%26v%3D<version>%26uc".
    EXPECT_TRUE(url.has_query());
    std::map<std::string, std::string> params;
    VerifyQueryAndExtractParameters(url.GetQuery(), &params);
    if (pending) {
      EXPECT_TRUE(pending_extension_manager->IsIdPending(params["id"]));
      EXPECT_EQ("0.0.0.0", params["v"]);
    } else {
      EXPECT_EQ(extensions[0]->id(), params["id"]);
      EXPECT_EQ(extensions[0]->VersionString(), params["v"]);
    }
    EXPECT_EQ("", params["uc"]);
  }

  void TestUpdateUrlDataEmpty() {
    ExtensionDownloaderTestHelper helper;
    const std::string id(32, 'a');
    const std::string version = "1.0";

    // Make sure that an empty update URL data string does not cause a ap=
    // option to appear in the x= parameter.
    GURL kUpdateURL("http://localhost/foo");
    std::unique_ptr<ManifestFetchData> fetch_data(
        CreateManifestFetchData(kUpdateURL));
    AddExtensionToFetchDataForTesting(fetch_data.get(), id, version,
                                      kUpdateURL);

    std::map<std::string, std::string> params;
    VerifyQueryAndExtractParameters(fetch_data->full_url().GetQuery(), &params);
    EXPECT_EQ(id, params["id"]);
    EXPECT_EQ(version, params["v"]);
    EXPECT_EQ(0U, params.count("ap"));
  }

  void TestUpdateUrlDataSimple() {
    const std::string id(32, 'a');
    const std::string version = "1.0";

    // Make sure that an update URL data string causes an appropriate ap=
    // option to appear in the x= parameter.
    std::unique_ptr<ManifestFetchData> fetch_data(
        CreateManifestFetchData(GURL("http://localhost/foo")));
    fetch_data->AddExtension(id, version,
                             ExtensionDownloaderTestHelper::GetTestPingData(),
                             "bar", std::string(), ManifestLocation::kInternal,
                             DownloadFetchPriority::kBackground);
    std::map<std::string, std::string> params;
    VerifyQueryAndExtractParameters(fetch_data->full_url().GetQuery(), &params);
    EXPECT_EQ(id, params["id"]);
    EXPECT_EQ(version, params["v"]);
    EXPECT_EQ("bar", params["ap"]);
  }

  void TestUpdateUrlDataCompound() {
    const std::string id(32, 'a');
    const std::string version = "1.0";

    // Make sure that an update URL data string causes an appropriate ap=
    // option to appear in the x= parameter.
    std::unique_ptr<ManifestFetchData> fetch_data(
        CreateManifestFetchData(GURL("http://localhost/foo")));
    fetch_data->AddExtension(
        id, version, ExtensionDownloaderTestHelper::GetTestPingData(),
        "a=1&b=2&c", std::string(), ManifestLocation::kInternal,
        DownloadFetchPriority::kBackground);
    std::map<std::string, std::string> params;
    VerifyQueryAndExtractParameters(fetch_data->full_url().GetQuery(), &params);
    EXPECT_EQ(id, params["id"]);
    EXPECT_EQ(version, params["v"]);
    EXPECT_EQ("a%3D1%26b%3D2%26c", params["ap"]);
  }

  void TestUpdateUrlDataFromUrl(
      const std::string& update_url,
      DownloadFetchPriority fetch_priority,
      int num_extensions,
      bool should_include_traffic_management_headers) {
    ExtensionDownloaderTestHelper helper;
    TestDownloaderFactory factory(helper.url_loader_factory());
    TestCrxInstallerFactory crx_installer_factory;
    ExtensionList extensions;

    CreateTestExtensions(1, num_extensions, &extensions, &update_url,
                         ManifestLocation::kInternal);

    for (int i = 0; i < num_extensions; ++i) {
      const std::string& id = extensions[i]->id();
      EXPECT_CALL(helper.delegate(), GetPingDataForExtension(id, _));

      helper.downloader().AddPendingExtension(ExtensionDownloaderTask(
          id, ManifestURL::GetUpdateURL(extensions[i].get()),
          extensions[i]->location(), false, 0, fetch_priority,
          extensions[i]->version(), extensions[i]->GetType(), std::string()));
    }

    // Get the headers our loader was asked to fetch.
    base::RunLoop loop;
    net::HttpRequestHeaders last_request_headers;
    helper.test_url_loader_factory().SetInterceptor(base::BindLambdaForTesting(
        [&](const network::ResourceRequest& request) {
          last_request_headers = request.headers;
          loop.Quit();
        }));

    helper.downloader().StartAllPending(nullptr);
    EXPECT_TRUE(helper.downloader().HasActiveManifestRequestForTesting());

    loop.Run();

    // Make sure that extensions that update from the gallery ignore any
    // update URL data.
    const ManifestFetchData& fetch =
        *helper.downloader().manifests_queue_.active_request();
    const std::string& fetcher_url = fetch.full_url().spec();
    std::string::size_type x = fetcher_url.find("x=");
    EXPECT_NE(std::string::npos, x);
    std::string::size_type ap = fetcher_url.find("ap%3D", x);
    EXPECT_EQ(std::string::npos, ap);

    net::HttpRequestHeaders fetch_headers;
    std::swap(fetch_headers, last_request_headers);
    EXPECT_EQ(should_include_traffic_management_headers,
              fetch_headers.HasHeader(
                  ExtensionDownloader::kUpdateInteractivityHeader));
    EXPECT_EQ(should_include_traffic_management_headers,
              fetch_headers.HasHeader(ExtensionDownloader::kUpdateAppIdHeader));
    EXPECT_EQ(
        should_include_traffic_management_headers,
        fetch_headers.HasHeader(ExtensionDownloader::kUpdateUpdaterHeader));

    if (should_include_traffic_management_headers) {
      std::string interactivity_value =
          fetch_headers
              .GetHeader(ExtensionDownloader::kUpdateInteractivityHeader)
              .value_or(std::string());

      std::string expected_interactivity_value =
          fetch_priority == DownloadFetchPriority::kForeground ? "fg" : "bg";
      EXPECT_EQ(expected_interactivity_value, interactivity_value);

      std::string appid_value =
          fetch_headers.GetHeader(ExtensionDownloader::kUpdateAppIdHeader)
              .value_or(std::string());
      if (num_extensions > 1) {
        for (int i = 0; i < num_extensions; ++i) {
          EXPECT_TRUE(
              testing::IsSubstring("", "", extensions[i]->id(), appid_value));
        }
      } else {
        EXPECT_EQ(extensions[0]->id(), appid_value);
      }

      std::string updater_value =
          fetch_headers.GetHeader(ExtensionDownloader::kUpdateUpdaterHeader)
              .value_or(std::string());
      const std::string expected_updater_value = base::StringPrintf(
          "%s-%s", UpdateQueryParams::GetProdIdString(UpdateQueryParams::CRX),
          UpdateQueryParams::GetProdVersion().c_str());
      EXPECT_EQ(expected_updater_value, updater_value);
    }
  }

  void TestInstallSource() {
    const std::string id(32, 'a');
    const std::string version = "1.0";
    const std::string install_source = "instally";

    // Make sure that an installsource= appears in the x= parameter.
    std::unique_ptr<ManifestFetchData> fetch_data(
        CreateManifestFetchData(GURL("http://localhost/foo")));
    fetch_data->AddExtension(
        id, version, ExtensionDownloaderTestHelper::GetTestPingData(),
        ExtensionDownloaderTestHelper::kEmptyUpdateUrlData, install_source,
        ManifestLocation::kInternal, DownloadFetchPriority::kBackground);
    std::map<std::string, std::string> params;
    VerifyQueryAndExtractParameters(fetch_data->full_url().GetQuery(), &params);
    EXPECT_EQ(id, params["id"]);
    EXPECT_EQ(version, params["v"]);
    EXPECT_EQ(install_source, params["installsource"]);
  }

  void TestInstallLocation() {
    const std::string id(32, 'a');
    const std::string version = "1.0";
    const std::string install_location = "external";

    // Make sure that installedby= appears in the x= parameter.
    std::unique_ptr<ManifestFetchData> fetch_data(
        CreateManifestFetchData(GURL("http://localhost/foo")));
    fetch_data->AddExtension(
        id, version, ExtensionDownloaderTestHelper::GetTestPingData(),
        ExtensionDownloaderTestHelper::kEmptyUpdateUrlData, std::string(),
        ManifestLocation::kExternalPrefDownload,
        DownloadFetchPriority::kBackground);
    std::map<std::string, std::string> params;
    VerifyQueryAndExtractParameters(fetch_data->full_url().GetQuery(), &params);
    EXPECT_EQ(id, params["id"]);
    EXPECT_EQ(version, params["v"]);
    EXPECT_EQ(install_location, params["installedby"]);
  }

  void TestDetermineUpdates() {
    ExtensionDownloaderTestHelper helper;

    GURL kUpdateURL("http://localhost/foo");
    std::unique_ptr<ManifestFetchData> fetch_data(
        CreateManifestFetchData(kUpdateURL));

    // Check passing an empty list of parse results to DetermineUpdates
    UpdateManifestResults updates;
    std::vector<std::pair<ExtensionDownloaderTask, UpdateManifestResult*>>
        updateable;
    std::vector<std::pair<ExtensionDownloaderTask, DownloadFailure>> failures;
    helper.downloader().DetermineUpdates(fetch_data->TakeAssociatedTasks(),
                                         updates, &updateable, &failures);
    EXPECT_TRUE(updateable.empty());
    EXPECT_TRUE(failures.empty());

    // Create two updates - expect that DetermineUpdates will return the first
    // one (v1.0 installed, v1.1 available) but not the second one (both
    // installed and available at v2.0).
    const std::string id1 = crx_file::id_util::GenerateId("1");
    const std::string id2 = crx_file::id_util::GenerateId("2");
    AddExtensionToFetchDataForTesting(fetch_data.get(), id1, "1.0.0.0",
                                      kUpdateURL);
    AddParseResult(id1, "1.1", "http://localhost/e1_1.1.crx", &updates);
    AddExtensionToFetchDataForTesting(fetch_data.get(), id2, "2.0.0.0",
                                      kUpdateURL);
    AddParseResult(id2, "2.0.0.0", "http://localhost/e2_2.0.crx", &updates);

    EXPECT_CALL(helper.delegate(), IsExtensionPending(_))
        .WillRepeatedly(Return(false));
    EXPECT_CALL(helper.delegate(), GetExtensionExistingVersion(id1, _))
        .WillOnce(DoAll(SetArgPointee<1>("1.0.0.0"), Return(true)));
    EXPECT_CALL(helper.delegate(), GetExtensionExistingVersion(id2, _))
        .WillOnce(DoAll(SetArgPointee<1>("2.0.0.0"), Return(true)));

    updateable.clear();
    failures.clear();
    helper.downloader().DetermineUpdates(fetch_data->TakeAssociatedTasks(),
                                         updates, &updateable, &failures);
    ASSERT_EQ(1u, failures.size());
    EXPECT_EQ(id2, failures[0].first.id);
    EXPECT_EQ(ExtensionDownloaderDelegate::Error::NO_UPDATE_AVAILABLE,
              failures[0].second.error);
    ASSERT_EQ(1u, updateable.size());
    EXPECT_EQ("1.1", updateable[0].second->version);
  }

  void TestDetermineUpdatesError() {
    ExtensionDownloaderTestHelper helper;
    MockExtensionDownloaderDelegate& delegate = helper.delegate();

    GURL kUpdateURL("http://localhost/foo");
    std::unique_ptr<ManifestFetchData> fetch_data(
        CreateManifestFetchData(kUpdateURL));
    UpdateManifestResults updates;

    // id1 => updatable (current version (1.1) is older than update version).
    // id2 => non_updateable (current version (2.0.0.0) is the same as update
    //        version).
    // id3 => non_updateable (manifest update version is empty).
    // id4 => errors (|updates| doesn't contain id4).
    // id5 => errors (the extension is not currently installed).
    // id6 => errors (manifest update version is invalid).
    const std::string id1 = crx_file::id_util::GenerateId("1");
    const std::string id2 = crx_file::id_util::GenerateId("2");
    const std::string id3 = crx_file::id_util::GenerateId("3");
    const std::string id4 = crx_file::id_util::GenerateId("4");
    const std::string id5 = crx_file::id_util::GenerateId("5");
    const std::string id6 = crx_file::id_util::GenerateId("6");

    AddExtensionToFetchDataForTesting(fetch_data.get(), id1, "1.0.0.0",
                                      kUpdateURL);
    AddParseResult(id1, "1.1", "http://localhost/e1_1.1.crx", &updates);

    AddExtensionToFetchDataForTesting(fetch_data.get(), id2, "2.0.0.0",
                                      kUpdateURL);
    AddParseResult(id2, "2.0.0.0", "http://localhost/e2_2.0.crx", &updates);

    // Empty update version in manifest.
    AddExtensionToFetchDataForTesting(fetch_data.get(), id3, "0.0.0.0",
                                      kUpdateURL);
    AddParseResult(id3, "", "http://localhost/e3_3.0.crx", &updates);

    AddExtensionToFetchDataForTesting(fetch_data.get(), id4, "0.0.0.0",
                                      kUpdateURL);

    AddExtensionToFetchDataForTesting(fetch_data.get(), id5, "0.0.0.0",
                                      kUpdateURL);
    AddParseResult(id5, "5.0.0.0", "http://localhost/e5_5.0.crx", &updates);

    // Invalid update version in manifest.
    AddExtensionToFetchDataForTesting(fetch_data.get(), id6, "0.0.0.0",
                                      kUpdateURL);
    AddParseResult(id6, "invalid_version", "http://localhost/e6_6.0.crx",
                   &updates);

    EXPECT_CALL(delegate, IsExtensionPending(_)).WillRepeatedly(Return(false));
    EXPECT_CALL(delegate, GetExtensionExistingVersion(id1, _))
        .WillOnce(DoAll(SetArgPointee<1>("1.0.0.0"), Return(true)));
    EXPECT_CALL(delegate, GetExtensionExistingVersion(id2, _))
        .WillOnce(DoAll(SetArgPointee<1>("2.0.0.0"), Return(true)));
    EXPECT_CALL(delegate, GetExtensionExistingVersion(id3, _))
        .WillOnce(DoAll(SetArgPointee<1>("0.0.0.0"), Return(true)));
    EXPECT_CALL(delegate, GetExtensionExistingVersion(id5, _))
        .WillOnce(DoAll(SetArgPointee<1>("0.0.0.0"), Return(false)));
    EXPECT_CALL(delegate, GetExtensionExistingVersion(id6, _))
        .WillOnce(DoAll(SetArgPointee<1>("0.0.0.0"), Return(true)));

    std::vector<std::pair<ExtensionDownloaderTask, UpdateManifestResult*>>
        updateable;
    std::vector<std::pair<ExtensionDownloaderTask, DownloadFailure>> failures;
    helper.downloader().DetermineUpdates(fetch_data->TakeAssociatedTasks(),
                                         updates, &updateable, &failures);
    std::vector<ExtensionId> ids_not_updateable({id2, id3});
    for (const auto& id : ids_not_updateable) {
      const auto* failure = GetFailureWithId(failures, id);
      ASSERT_TRUE(failure);
      EXPECT_EQ(ExtensionDownloaderDelegate::Error::NO_UPDATE_AVAILABLE,
                failure->error);
    }
    std::vector<ExtensionId> ids_with_error({id4, id5, id6});
    for (const auto& id : ids_with_error) {
      const auto* failure = GetFailureWithId(failures, id);
      ASSERT_TRUE(failure);
      EXPECT_EQ(ExtensionDownloaderDelegate::Error::MANIFEST_INVALID,
                failure->error);
    }
    EXPECT_EQ(5u, failures.size());
    ASSERT_EQ(1u, updateable.size());
    EXPECT_EQ("1.1", updateable[0].second->version);
  }

  void TestDetermineUpdatesPending() {
    // Create a set of test extensions
    ExtensionDownloaderTestHelper helper;
    TestDownloaderFactory factory(helper.url_loader_factory());
    PendingExtensionManager* pending_extension_manager =
        PendingExtensionManager::Get(profile());
    SetupPendingExtensionManagerForTest(3, GURL(), pending_extension_manager);

    MockExtensionDownloaderDelegate& delegate = helper.delegate();

    GURL kUpdateURL("http://localhost/foo");
    std::unique_ptr<ManifestFetchData> fetch_data(
        CreateManifestFetchData(kUpdateURL));
    UpdateManifestResults updates;

    std::list<std::string> ids_for_update_check =
        pending_extension_manager->GetPendingIdsForUpdateCheck();

    for (const std::string& id : ids_for_update_check) {
      AddExtensionToFetchDataForTesting(fetch_data.get(), id, "1.0.0.0",
                                        kUpdateURL);
      AddParseResult(id, "1.1", "http://localhost/e1_1.1.crx", &updates);
    }

    // The delegate will tell the downloader that all the extensions are
    // pending.
    EXPECT_CALL(delegate, IsExtensionPending(_)).WillRepeatedly(Return(true));

    std::vector<std::pair<ExtensionDownloaderTask, UpdateManifestResult*>>
        updateable;
    std::vector<std::pair<ExtensionDownloaderTask, DownloadFailure>> failures;
    helper.downloader().DetermineUpdates(fetch_data->TakeAssociatedTasks(),
                                         updates, &updateable, &failures);
    // All the apps should be updateable.
    EXPECT_EQ(3u, updateable.size());
    EXPECT_TRUE(failures.empty());
  }

  void TestDetermineUpdatesDuplicates() {
    base::HistogramTester histogram_tester;
    ExtensionDownloaderTestHelper helper;
    MockExtensionDownloaderDelegate& delegate = helper.delegate();

    const std::string id1 = crx_file::id_util::GenerateId("1");
    const std::string id2 = crx_file::id_util::GenerateId("2");
    const std::string id3 = crx_file::id_util::GenerateId("3");
    const std::string id4 = crx_file::id_util::GenerateId("4");
    const std::string id5 = crx_file::id_util::GenerateId("5");
    const std::string id6 = crx_file::id_util::GenerateId("6");
    const std::string id7 = crx_file::id_util::GenerateId("7");

    GURL kUpdateURL("http://localhost/foo");
    std::unique_ptr<ManifestFetchData> fetch_data(
        CreateManifestFetchData(kUpdateURL));
    AddExtensionToFetchDataForTesting(fetch_data.get(), id1, "1.1.0.0",
                                      kUpdateURL);
    AddExtensionToFetchDataForTesting(fetch_data.get(), id2, "1.2.0.0",
                                      kUpdateURL);
    AddExtensionToFetchDataForTesting(fetch_data.get(), id3, "1.3.0.0",
                                      kUpdateURL);
    AddExtensionToFetchDataForTesting(fetch_data.get(), id4, "1.4.0.0",
                                      kUpdateURL);
    AddExtensionToFetchDataForTesting(fetch_data.get(), id5, "1.5.0.0",
                                      kUpdateURL);
    AddExtensionToFetchDataForTesting(fetch_data.get(), id6, "1.6.0.0",
                                      kUpdateURL);
    AddExtensionToFetchDataForTesting(fetch_data.get(), id7, "1.7.0.0",
                                      kUpdateURL);

    UpdateManifestResults updates;
    AddParseResult(id1, "1.1.0.0", "http://localhost/e1_1.1.crx", &updates);
    AddParseResult(id2, "1.2.0.a", "http://localhost/e2_1.1.crx", &updates);
    AddParseResult(id3, "1.3.1.0", "http://localhost/e3_1.1.crx", &updates);
    AddParseResult(id4, "1.4.0.0", "http://localhost/e4_1.1.crx", &updates);
    AddParseResult(id4, "1.4.0.a", "http://localhost/e4_1.1.crx", &updates);
    AddParseResult(id5, "1.5.0.a", "http://localhost/e5_1.1.crx", &updates);
    AddParseResult(id5, "1.5.0.b", "http://localhost/e5_1.1.crx", &updates);
    AddParseResult(id6, "1.6.0.a", "http://localhost/e6_1.1.crx", &updates);
    AddParseResult(id6, "1.6.0.0", "http://localhost/e6_1.1.crx", &updates);
    AddParseResult(id6, "1.6.1.0", "http://localhost/e6_1.1.crx", &updates);
    AddParseResult(id6, "1.6.2.0", "http://localhost/e6_1.1.crx", &updates);

    EXPECT_CALL(delegate, IsExtensionPending(_)).WillRepeatedly(Return(false));
    EXPECT_CALL(delegate, GetExtensionExistingVersion(id1, _))
        .WillOnce(DoAll(SetArgPointee<1>("1.1.0.0"), Return(true)));
    EXPECT_CALL(delegate, GetExtensionExistingVersion(id2, _))
        .WillOnce(DoAll(SetArgPointee<1>("1.2.0.0"), Return(true)));
    EXPECT_CALL(delegate, GetExtensionExistingVersion(id3, _))
        .WillOnce(DoAll(SetArgPointee<1>("1.3.0.0"), Return(true)));
    EXPECT_CALL(delegate, GetExtensionExistingVersion(id4, _))
        .WillOnce(DoAll(SetArgPointee<1>("1.4.0.0"), Return(true)));
    EXPECT_CALL(delegate, GetExtensionExistingVersion(id5, _))
        .WillOnce(DoAll(SetArgPointee<1>("1.5.0.0"), Return(true)));
    EXPECT_CALL(delegate, GetExtensionExistingVersion(id6, _))
        .WillOnce(DoAll(SetArgPointee<1>("1.6.0.0"), Return(true)));

    std::vector<std::pair<ExtensionDownloaderTask, UpdateManifestResult*>>
        updateable;
    std::vector<std::pair<ExtensionDownloaderTask, DownloadFailure>> failures;
    helper.downloader().DetermineUpdates(fetch_data->TakeAssociatedTasks(),
                                         updates, &updateable, &failures);
    std::vector<ExtensionId> ids_not_updateable({id1, id4});
    for (const auto& id : ids_not_updateable) {
      const auto* failure = GetFailureWithId(failures, id);
      ASSERT_TRUE(failure);
      EXPECT_EQ(ExtensionDownloaderDelegate::Error::NO_UPDATE_AVAILABLE,
                failure->error);
    }
    std::vector<ExtensionId> ids_with_error({id2, id5, id7});
    for (const auto& id : ids_with_error) {
      const auto* failure = GetFailureWithId(failures, id);
      ASSERT_TRUE(failure);
      EXPECT_EQ(ExtensionDownloaderDelegate::Error::MANIFEST_INVALID,
                failure->error);
    }
    EXPECT_EQ(5u, failures.size());
    ASSERT_EQ(2u, updateable.size());
    EXPECT_EQ("1.3.1.0", updateable[0].second->version);
    EXPECT_EQ("1.6.1.0", updateable[1].second->version);
  }

  void TestMultipleManifestDownloading() {
    ExtensionDownloaderTestHelper helper;
    MockExtensionDownloaderDelegate& delegate = helper.delegate();
    helper.downloader().manifests_queue_.set_backoff_policy(kNoBackoffPolicy);

    GURL kUpdateUrl("http://localhost/manifest1");

    std::unique_ptr<ManifestFetchData> fetch1(
        CreateManifestFetchData(kUpdateUrl));
    std::unique_ptr<ManifestFetchData> fetch2(
        CreateManifestFetchData(kUpdateUrl));
    std::unique_ptr<ManifestFetchData> fetch3(
        CreateManifestFetchData(kUpdateUrl));
    std::unique_ptr<ManifestFetchData> fetch4(
        CreateManifestFetchData(kUpdateUrl));
    DownloadPingData zero_days(/*rollcall=*/0, /*active=*/0, /*enabled=*/true,
                               /*disable_reasons=*/{});
    AddExtensionToFetchDataForTesting(fetch1.get(), "1111", "1.0", kUpdateUrl,
                                      zero_days);
    AddExtensionToFetchDataForTesting(fetch2.get(), "2222", "2.0", kUpdateUrl,
                                      zero_days);
    AddExtensionToFetchDataForTesting(fetch3.get(), "3333", "3.0", kUpdateUrl,
                                      zero_days);
    AddExtensionToFetchDataForTesting(fetch4.get(), "4444", "4.0", kUpdateUrl,
                                      zero_days);

    // This will start the first fetcher and queue the others. The next in queue
    // is started as each fetcher receives its response. Note that the fetchers
    // don't necessarily run in the order that they are started from here.
    GURL fetch1_url = fetch1->full_url();
    GURL fetch2_url = fetch2->full_url();
    GURL fetch3_url = fetch3->full_url();
    GURL fetch4_url = fetch4->full_url();

    // fetch1_url
    {
      helper.StartUpdateCheck(std::move(fetch1));
      RunUntilIdle();
      helper.test_url_loader_factory().AddResponse(fetch1_url.spec(), "",
                                                   net::HTTP_BAD_REQUEST);
      EXPECT_CALL(
          delegate,
          OnExtensionDownloadFailed(
              "1111", ExtensionDownloaderDelegate::Error::MANIFEST_FETCH_FAILED,
              _, _, _))
          .WillOnce(InvokeWithoutArgs(&delegate,
                                      &MockExtensionDownloaderDelegate::Quit));
      delegate.Wait();
      Mock::VerifyAndClearExpectations(&delegate);
      fetch1_url = GURL();

      RunUntilIdle();
    }

    // fetch2_url
    {
      helper.StartUpdateCheck(std::move(fetch2));
      RunUntilIdle();
      const std::string kInvalidXml = "invalid xml";
      helper.test_url_loader_factory().AddResponse(fetch2_url.spec(),
                                                   kInvalidXml, net::HTTP_OK);
      EXPECT_CALL(
          delegate,
          OnExtensionDownloadFailed(
              "2222", ExtensionDownloaderDelegate::Error::MANIFEST_INVALID, _,
              _, _))
          .WillOnce(InvokeWithoutArgs(&delegate,
                                      &MockExtensionDownloaderDelegate::Quit));
      delegate.Wait();
      Mock::VerifyAndClearExpectations(&delegate);
      fetch2_url = GURL();

      RunUntilIdle();
    }

    // fetch3_url
    {
      helper.StartUpdateCheck(std::move(fetch3));
      RunUntilIdle();
      const std::string kNoUpdate = CreateUpdateManifest(
          {UpdateManifestItem("3333")
               .version("3.0.0.0")
               .prodversionmin("3.0.0.0")
               .codebase("http://example.com/extension_3.0.0.0.crx")});
      helper.test_url_loader_factory().AddResponse(fetch3_url.spec(), kNoUpdate,
                                                   net::HTTP_OK);
      // The third fetcher doesn't have an update available.
      EXPECT_CALL(delegate, IsExtensionPending("3333")).WillOnce(Return(false));
      EXPECT_CALL(delegate, GetExtensionExistingVersion("3333", _))
          .WillOnce(DoAll(SetArgPointee<1>("3.0.0.0"), Return(true)));
      EXPECT_CALL(
          delegate,
          OnExtensionDownloadFailed(
              "3333", ExtensionDownloaderDelegate::Error::NO_UPDATE_AVAILABLE,
              _, _, _))
          .WillOnce(InvokeWithoutArgs(&delegate,
                                      &MockExtensionDownloaderDelegate::Quit));
      delegate.Wait();
      Mock::VerifyAndClearExpectations(&delegate);
      fetch3_url = GURL();

      RunUntilIdle();
    }

    // fetch4_url
    {
      helper.StartUpdateCheck(std::move(fetch4));
      RunUntilIdle();
      // The last fetcher has an update.
      const std::string kUpdateAvailable = CreateUpdateManifest(
          {UpdateManifestItem("4444")
               .version("4.0.42.0")
               .prodversionmin("4.0.42.0")
               .codebase("http://example.com/extension_1.2.3.4.crx")});
      helper.test_url_loader_factory().AddResponse(
          fetch4_url.spec(), kUpdateAvailable, net::HTTP_OK);
      EXPECT_CALL(delegate, IsExtensionPending("4444")).WillOnce(Return(false));
      EXPECT_CALL(delegate, GetExtensionExistingVersion("4444", _))
          .WillOnce(DoAll(SetArgPointee<1>("4.0.0.0"), Return(true)));

      // Verify that the downloader decided to update this extension.
      EXPECT_CALL(delegate,
                  OnExtensionUpdateFound("4444", _, base::Version("4.0.42.0")))
          .WillOnce([&delegate]() { delegate.Quit(); });
      delegate.Wait();
      Mock::VerifyAndClearExpectations(&delegate);

      fetch4_url = GURL();
    }
    if (helper.downloader().HasActiveManifestRequestForTesting())
      ADD_FAILURE() << "Unexpected load";
  }

  void TestManifestRetryDownloading() {
    ExtensionDownloaderTestHelper helper;
    MockExtensionDownloaderDelegate& delegate = helper.delegate();
    helper.downloader().manifests_queue_.set_backoff_policy(kNoBackoffPolicy);

    GURL kUpdateUrl("http://localhost/manifest1");

    std::unique_ptr<ManifestFetchData> fetch(
        CreateManifestFetchData(kUpdateUrl));
    DownloadPingData zero_days(/*rollcall=*/0, /*active=*/0, /*enabled=*/true,
                               /*disable_reasons=*/{});
    fetch->AddExtension("1111", "1.0", &zero_days,
                        ExtensionDownloaderTestHelper::kEmptyUpdateUrlData,
                        std::string(), ManifestLocation::kInternal,
                        DownloadFetchPriority::kBackground);

    // This will start the first fetcher.
    helper.StartUpdateCheck(std::move(fetch));
    RunUntilIdle();

    // ExtensionDownloader should retry kMaxRetries times and then fail.
    EXPECT_CALL(
        delegate,
        OnExtensionDownloadFailed(
            "1111", ExtensionDownloaderDelegate::Error::MANIFEST_FETCH_FAILED,
            _, _, _));
    helper.test_url_loader_factory().SetInterceptor(base::BindLambdaForTesting(
        [&](const network::ResourceRequest& request) {
          EXPECT_TRUE(request.load_flags == kExpectedLoadFlags);
          EXPECT_EQ(network::mojom::CredentialsMode::kInclude,
                    request.credentials_mode);
        }));
    for (int i = 0; i <= ExtensionDownloader::kMaxRetries; ++i) {
      // All fetches will fail.
      auto* request = helper.GetPendingRequest(0);
      // Code 5xx causes ExtensionDownloader to retry.
      helper.test_url_loader_factory().SimulateResponseForPendingRequest(
          request->request.url, network::URLLoaderCompletionStatus(net::OK),
          network::CreateURLResponseHead(net::HTTP_INTERNAL_SERVER_ERROR), "");
      RunUntilIdle();
    }
    Mock::VerifyAndClearExpectations(&delegate);

    // For response codes that are not in the 5xx range ExtensionDownloader
    // should not retry.
    fetch.reset(CreateManifestFetchData(kUpdateUrl));
    fetch->AddExtension("1111", "1.0", &zero_days,
                        ExtensionDownloaderTestHelper::kEmptyUpdateUrlData,
                        std::string(), ManifestLocation::kInternal,
                        DownloadFetchPriority::kBackground);

    // This will start the first fetcher.
    helper.StartUpdateCheck(std::move(fetch));
    RunUntilIdle();

    EXPECT_CALL(
        delegate,
        OnExtensionDownloadFailed(
            "1111", ExtensionDownloaderDelegate::Error::MANIFEST_FETCH_FAILED,
            _, _, _));

    // The first fetch will fail, and require retrying.
    {
      auto* request = helper.GetPendingRequest(0);
      helper.test_url_loader_factory().SimulateResponseForPendingRequest(
          request->request.url, network::URLLoaderCompletionStatus(net::OK),
          network::CreateURLResponseHead(net::HTTP_INTERNAL_SERVER_ERROR), "");
    }
    RunUntilIdle();

    // The second fetch will fail with response 400 and should not cause
    // ExtensionDownloader to retry.
    {
      auto* request = helper.GetPendingRequest(0);
      helper.test_url_loader_factory().SimulateResponseForPendingRequest(
          request->request.url, network::URLLoaderCompletionStatus(net::OK),
          network::CreateURLResponseHead(net::HTTP_BAD_REQUEST), "");
    }
    RunUntilIdle();

    Mock::VerifyAndClearExpectations(&delegate);
  }

  void TestManifestCredentialsNonWebstore() {
    ExtensionDownloaderTestHelper helper;
    helper.downloader().manifests_queue_.set_backoff_policy(kNoBackoffPolicy);

    GURL kUpdateUrl("http://localhost/manifest1");

    std::unique_ptr<ManifestFetchData> fetch(
        CreateManifestFetchData(kUpdateUrl));
    DownloadPingData zero_days(/*rollcall=*/0, /*active=*/0, /*enabled=*/true,
                               /*disable_reasons=*/{});
    fetch->AddExtension("1111", "1.0", &zero_days,
                        ExtensionDownloaderTestHelper::kEmptyUpdateUrlData,
                        std::string(), ManifestLocation::kInternal,
                        DownloadFetchPriority::kBackground);

    helper.StartUpdateCheck(std::move(fetch));
    RunUntilIdle();

    helper.test_url_loader_factory().SetInterceptor(base::BindLambdaForTesting(
        [&](const network::ResourceRequest& request) {
          EXPECT_EQ(network::mojom::CredentialsMode::kInclude,
                    request.credentials_mode);
        }));
    auto* request = helper.GetPendingRequest(0);
    helper.test_url_loader_factory().SimulateResponseForPendingRequest(
        request->request.url, network::URLLoaderCompletionStatus(net::OK),
        network::CreateURLResponseHead(net::HTTP_INTERNAL_SERVER_ERROR), "");
    RunUntilIdle();
  }

  void TestManifestCredentialsWebstore() {
    ExtensionDownloaderTestHelper helper;
    helper.downloader().manifests_queue_.set_backoff_policy(kNoBackoffPolicy);

    GURL kUpdateUrl(extension_urls::kChromeWebstoreUpdateURL);

    std::unique_ptr<ManifestFetchData> fetch(
        CreateManifestFetchData(kUpdateUrl));
    DownloadPingData zero_days(/*rollcall=*/0, /*active=*/0, /*enabled=*/true,
                               /*disable_reasons=*/{});
    fetch->AddExtension("1111", "1.0", &zero_days,
                        ExtensionDownloaderTestHelper::kEmptyUpdateUrlData,
                        std::string(), ManifestLocation::kInternal,
                        DownloadFetchPriority::kBackground);

    helper.StartUpdateCheck(std::move(fetch));
    RunUntilIdle();

    helper.test_url_loader_factory().SetInterceptor(base::BindLambdaForTesting(
        [&](const network::ResourceRequest& request) {
          EXPECT_EQ(network::mojom::CredentialsMode::kOmit,
                    request.credentials_mode);
        }));
    auto* request = helper.GetPendingRequest(0);
    helper.test_url_loader_factory().SimulateResponseForPendingRequest(
        request->request.url, network::URLLoaderCompletionStatus(net::OK),
        network::CreateURLResponseHead(net::HTTP_INTERNAL_SERVER_ERROR), "");
    RunUntilIdle();
  }

  // Checks that the manifest is fetched with a priority of |net::MEDIUM| (which
  // maps to |TaskPriority::USER_BLOCKING| for the task runner) when the active
  // request's |fetch_priority| is in the FOREGROUND.
  void TestManifestFetchPriority(DownloadFetchPriority fetch_priority) {
    ExtensionDownloaderTestHelper helper;
    helper.downloader().manifests_queue_.set_backoff_policy(kNoBackoffPolicy);
    GURL test_url("http://localhost/manifest1");
    std::unique_ptr<ManifestFetchData> fetch(
        CreateManifestFetchData(test_url));
    DownloadPingData zero_days(/*rollcall=*/0, /*active=*/0, /*enabled=*/true,
                               /*disable_reasons=*/{});

    fetch->AddExtension("1111", "1.0", &zero_days,
                        ExtensionDownloaderTestHelper::kEmptyUpdateUrlData,
                        std::string(), ManifestLocation::kInternal,
                        fetch_priority);

    helper.StartUpdateCheck(std::move(fetch));
    RunUntilIdle();

    auto* request = helper.GetPendingRequest(0);
    helper.test_url_loader_factory().SimulateResponseForPendingRequest(
        request->request.url, network::URLLoaderCompletionStatus(net::OK),
        network::CreateURLResponseHead(net::HTTP_INTERNAL_SERVER_ERROR), "");
    RunUntilIdle();

    if (fetch_priority == DownloadFetchPriority::kForeground) {
      EXPECT_EQ(net::MEDIUM, request->request.priority);
    } else {
      EXPECT_EQ(net::IDLE, request->request.priority);
    }
  }

  // Checks that the crx of a given extension is downloaded with a priority of
  // |net::MEDIUM| (maps to |TaskPriority::USER_BLOCKING| for the task runner)
  // when the active request's |fetch_priority| is in the FOREGROUND.
  void TestSingleExtensionDownloadingPriority(
      DownloadFetchPriority fetch_priority) {
    ExtensionUpdater::ScopedSkipScheduledCheckForTest skip_scheduled_checks;
    ExtensionDownloaderTestHelper helper;
    TestDownloaderFactory factory(helper.url_loader_factory());
    TestCrxInstallerFactory crx_installer_factory;
    ExtensionUpdater updater(profile());
    updater.InitAndEnable(extension_prefs(), pref_service(), kUpdateFrequency,
                          nullptr, factory.GetDownloaderFactory());
    updater.set_crx_installer_factory_for_test(&crx_installer_factory);
    MockExtensionDownloaderDelegate downloader_delegate;
    downloader_delegate.DelegateTo(&updater);
    factory.OverrideDownloaderDelegate(&downloader_delegate);
    updater.Start();
    updater.EnsureDownloaderCreated();
    updater.downloader_->extensions_queue_.set_backoff_policy(kNoBackoffPolicy);

    GURL test_url("http://localhost/extension.crx");
    const std::string id(32, 'a');
    std::string hash;
    CRXFileInfo crx_file_info;
    base::Version version("0.0.1");
    ExtensionDownloaderTask task = CreateDownloaderTask(id);
    task.fetch_priority = fetch_priority;
    std::unique_ptr<ExtensionDownloader::ExtensionFetch> fetch =
        std::make_unique<ExtensionDownloader::ExtensionFetch>(
            std::move(task), test_url, hash, version.GetString(),
            fetch_priority);

    updater.downloader_->FetchUpdatedExtension(std::move(fetch), std::nullopt);

    auto* request = helper.GetPendingRequest(0);
    if (fetch_priority == DownloadFetchPriority::kForeground) {
      EXPECT_EQ(net::MEDIUM, request->request.priority);
    } else {
      EXPECT_EQ(net::IDLE, request->request.priority);
    }
  }

  void TestSingleExtensionDownloading(bool pending, bool retry, bool fail) {
    ExtensionUpdater::ScopedSkipScheduledCheckForTest skip_scheduled_checks;
    ExtensionDownloaderTestHelper helper;
    TestDownloaderFactory factory(helper.url_loader_factory());
    TestCrxInstallerFactory crx_installer_factory;
    ExtensionUpdater updater(profile());
    updater.InitAndEnable(extension_prefs(), pref_service(), kUpdateFrequency,
                          nullptr, factory.GetDownloaderFactory());
    updater.set_crx_installer_factory_for_test(&crx_installer_factory);
    MockExtensionDownloaderDelegate downloader_delegate;
    downloader_delegate.DelegateTo(&updater);
    factory.OverrideDownloaderDelegate(&downloader_delegate);
    updater.Start();
    updater.EnsureDownloaderCreated();
    updater.downloader_->extensions_queue_.set_backoff_policy(kNoBackoffPolicy);

    GURL test_url("http://localhost/extension.crx");

    const std::string id(32, 'a');
    std::string hash;
    CRXFileInfo crx_file_info;
    base::Version version("0.0.1");
    std::set<int> requests;
    requests.insert(0);
    std::unique_ptr<ExtensionDownloader::ExtensionFetch> fetch =
        std::make_unique<ExtensionDownloader::ExtensionFetch>(
            CreateDownloaderTask(id), test_url, hash, version.GetString(),
            DownloadFetchPriority::kBackground);
    updater.downloader_->FetchUpdatedExtension(std::move(fetch), std::nullopt);

    if (pending) {
      const bool kIsFromSync = true;
      const bool kMarkAcknowledged = false;
      const bool kRemoteInstall = false;
      PendingExtensionManager* pending_extension_manager =
          PendingExtensionManager::Get(profile());
      pending_extension_manager->AddForTesting(PendingExtensionInfo(
          id, std::string(), test_url, version, &ShouldAlwaysInstall,
          kIsFromSync, ManifestLocation::kInternal, Extension::NO_FLAGS,
          kMarkAcknowledged, kRemoteInstall));
    }

    if (retry) {
      EXPECT_CALL(downloader_delegate, OnExtensionDownloadRetryForTests())
          .WillOnce(DoAll(
              InvokeWithoutArgs(&downloader_delegate,
                                &MockExtensionDownloaderDelegate::Quit),
              InvokeWithoutArgs(&helper, &ExtensionDownloaderTestHelper::
                                             ClearURLLoaderFactoryResponses)));
      helper.test_url_loader_factory().AddResponse(
          test_url.spec(), "", net::HTTP_INTERNAL_SERVER_ERROR);
      downloader_delegate.Wait();
      EXPECT_TRUE(updater.downloader_->extension_loader_);
    }

    if (fail) {
      EXPECT_CALL(downloader_delegate,
                  OnExtensionDownloadFailed(id, _, _, requests, _))
          .WillOnce(DoAll(
              InvokeWithoutArgs(&downloader_delegate,
                                &MockExtensionDownloaderDelegate::Quit),
              InvokeWithoutArgs(&helper, &ExtensionDownloaderTestHelper::
                                             ClearURLLoaderFactoryResponses)));
      helper.test_url_loader_factory().AddResponse(
          test_url.spec(), "Any content. It is irrelevant.",
          net::HTTP_NOT_FOUND);
      downloader_delegate.Wait();
    } else {
      EXPECT_TRUE(updater.downloader_->extension_loader_);
      EXPECT_CALL(downloader_delegate,
                  OnExtensionDownloadFinished_(_, _, _, _, requests, _))
          .WillOnce(
              DoAll(testing::SaveArg<0>(&crx_file_info),
                    InvokeWithoutArgs(&downloader_delegate,
                                      &MockExtensionDownloaderDelegate::Quit)));
      helper.test_url_loader_factory().AddResponse(
          test_url.spec(), "Any content. It is irrelevant.");
      downloader_delegate.Wait();
      EXPECT_EQ(version, crx_file_info.expected_version);
    }

    if (fail) {
      // Don't expect any extension to have been installed.
      EXPECT_TRUE(crx_installer_factory.crx_extension_id().empty());
    } else {
      // Expect that ExtensionUpdater asked the mock extensions service to
      // install a file with the test data for the right id.
      EXPECT_EQ(id, crx_file_info.extension_id);
      base::FilePath tmpfile_path = crx_file_info.path;
      EXPECT_FALSE(tmpfile_path.empty());
    }
  }

  // Helper to create a new test file of zeros.
  void CreateFile(const base::FilePath& file,
                  size_t size,
                  const base::Time& timestamp) {
    const std::string data(size, 0);
    EXPECT_TRUE(base::WriteFile(file, data));
    EXPECT_TRUE(base::TouchFile(file, timestamp, timestamp));
  }

#if BUILDFLAG(IS_CHROMEOS)
  // This tests the condition when the entry for the crx file is already
  // present in the cache but the crx file is itself corrupted. In this case,
  // after detecting the corruption of the crx file, it's entry should be
  // removed from the cache and re-downloaded from the link in the update
  // manifest.
  void TestCacheCorruption() {
    const char kTestExtensionId[] = "test_app";
    const std::string version = "1.1";
    const std::string hash = "abcd";
    ExtensionDownloaderTestHelper helper;
    TestDownloaderFactory factory(helper.url_loader_factory());

    // Set update manifest fetch data and result.
    GURL kUpdateURL("http://localhost/foo");
    std::unique_ptr<ManifestFetchData> fetch(
        CreateManifestFetchData(kUpdateURL));
    AddExtensionToFetchDataForTesting(fetch.get(), kTestExtensionId, "1.0",
                                      kUpdateURL);
    const std::string manifest = CreateUpdateManifest(
        {UpdateManifestItem(kTestExtensionId)
             .version(version)
             .hash(hash)
             .codebase("http://example.com/extension_1.2.3.4.crx")
             .prodversionmin("1.1")});
    helper.test_url_loader_factory().AddResponse(fetch->full_url().spec(),
                                                 manifest, net::HTTP_OK);

    // We need crx installer to install the crx file and also for mock extension
    // service. CrxInstallers require a real ExtensionService.  Create one on
    // the testing profile.  Any action the CrxInstallers take is on the testing
    // profile's extension service, not on our mock |service|.
    TestingProfile profile;
    // TODO(crbug.com/396722906): Delete this when CrxInstaller no longer has
    // dependencies on ExtensionService.
    static_cast<TestExtensionSystem*>(ExtensionSystem::Get(&profile))
        ->CreateExtensionService(base::CommandLine::ForCurrentProcess(),
                                 base::FilePath(), false);
    scoped_refptr<MockCrxInstaller> mock_installer =
        base::MakeRefCounted<MockCrxInstaller>(&profile);

    // Do nothing when called the first time, by ExtensionUpdater
    // But do the real action when called later on by this test code.
    EXPECT_CALL(*mock_installer, InstallCrxFile(_))
        .WillOnce(Return())
        .WillOnce([&mock_installer](const CRXFileInfo& info) {
          return mock_installer->CrxInstaller::InstallCrxFile(info);
        });
    // Just let the real CrxInstaller implementation have the callback.
    EXPECT_CALL(*mock_installer, AddInstallerCallback(_))
        .WillOnce([&](CrxInstaller::InstallerResultCallback callback) {
          mock_installer->CrxInstaller::AddInstallerCallback(
              std::move(callback));
        });

    mock_installer->set_expected_id(kTestExtensionId);
    mock_installer->set_expected_hash(hash);

    // Create mock extension service for test. We need this mock service so that
    // the extension updater process can be intercepted before the installer
    // which is then called explicitly.
    TestCrxInstallerFactory crx_installer_factory;
    crx_installer_factory.AddFakeCrxInstaller(kTestExtensionId, mock_installer);

    ExtensionUpdater updater(this->profile());
    updater.InitAndEnable(extension_prefs(), pref_service(), kUpdateFrequency,
                          nullptr, factory.GetDownloaderFactory());
    updater.set_crx_installer_factory_for_test(&crx_installer_factory);
    MockExtensionDownloaderDelegate& downloader_delegate = helper.delegate();
    downloader_delegate.DelegateTo(&updater);
    factory.OverrideDownloaderDelegate(&downloader_delegate);
    updater.Start();

    // Create and initialize local cache.
    const base::Time now = base::Time::Now();
    base::ScopedTempDir cache_dir;
    ASSERT_TRUE(cache_dir.CreateUniqueTempDir());
    const base::FilePath cache_path = cache_dir.GetPath();
    CreateFile(cache_path.Append(LocalExtensionCache::kCacheReadyFlagFileName),
               0, now);

    ExtensionCacheImpl test_extension_cache(
        std::make_unique<ChromeOSExtensionCacheDelegate>(cache_path));
    base::RunLoop cache_init_run_loop;
    test_extension_cache.Start(cache_init_run_loop.QuitClosure());
    cache_init_run_loop.Run();

    // Create crx file in a temp directory.
    base::ScopedTempDir tmp_dir;
    ASSERT_TRUE(tmp_dir.CreateUniqueTempDir());
    const base::FilePath tmp_path = tmp_dir.GetPath();
    const base::FilePath filename =
        tmp_path.Append(LocalExtensionCache::ExtensionFileName(
            kTestExtensionId, version, "" /* hash */));
    // Create a small file of zeroes, e.g. 100 bytes size.
    CreateFile(filename, 100, now - base::Seconds(3));

    // Add crx file entry in the cache.
    base::RunLoop put_extension_run_loop;
    test_extension_cache.AllowCaching("test_app");
    test_extension_cache.PutExtension(
        kTestExtensionId, "" /* expected hash*/, filename, version,
        base::BindLambdaForTesting(
            [&put_extension_run_loop](const base::FilePath& file_path,
                                      bool file_ownership_passed) {
              put_extension_run_loop.Quit();
            }));
    put_extension_run_loop.Run();

    // Set cache in extension downloader.
    helper.downloader().StartAllPending(&test_extension_cache);

    EXPECT_CALL(downloader_delegate, IsExtensionPending(kTestExtensionId))
        .WillOnce(Return(true));
    // Download the update manifest for the extension, find the same extension
    // version in the cache, start installing the cached crx file which fails
    // due to unpacker error and is hence, removed from the cache and
    // re-downlaoded for installation.
    testing::Sequence sequence;
    EXPECT_CALL(downloader_delegate,
                OnExtensionDownloadStageChanged(
                    kTestExtensionId,
                    ExtensionDownloaderDelegate::Stage::QUEUED_FOR_MANIFEST))
        .Times(testing::AnyNumber());
    EXPECT_CALL(downloader_delegate,
                OnExtensionDownloadStageChanged(
                    kTestExtensionId,
                    ExtensionDownloaderDelegate::Stage::DOWNLOADING_MANIFEST))
        .InSequence(sequence);
    EXPECT_CALL(downloader_delegate,
                OnExtensionDownloadStageChanged(
                    kTestExtensionId,
                    ExtensionDownloaderDelegate::Stage::PARSING_MANIFEST))
        .InSequence(sequence);
    EXPECT_CALL(downloader_delegate,
                OnExtensionDownloadStageChanged(
                    kTestExtensionId,
                    ExtensionDownloaderDelegate::Stage::MANIFEST_LOADED))
        .InSequence(sequence);
    EXPECT_CALL(downloader_delegate,
                OnExtensionDownloadCacheStatusRetrieved(
                    kTestExtensionId,
                    ExtensionDownloaderDelegate::CacheStatus::CACHE_HIT))
        .InSequence(sequence);
    EXPECT_CALL(
        downloader_delegate,
        OnExtensionDownloadStageChanged(
            kTestExtensionId, ExtensionDownloaderDelegate::Stage::FINISHED))
        .InSequence(sequence);
    EXPECT_CALL(downloader_delegate,
                OnExtensionDownloadStageChanged(
                    kTestExtensionId,
                    ExtensionDownloaderDelegate::Stage::DOWNLOADING_CRX))
        .InSequence(sequence);

    helper.StartUpdateCheck(std::move(fetch));

    content::RunAllTasksUntilIdle();

    LoadErrorReporter::Init(false);

    updater.SetExtensionCacheForTesting(&test_extension_cache);
    CRXFileInfo crx_info(filename, GetTestVerifierFormat());
    crx_info.extension_id = kTestExtensionId;
    crx_info.expected_hash = hash;

    // This time call the real InstallCrxFile implementation (see expectation
    // set above for mock_installer).
    mock_installer->InstallCrxFile(crx_info);

    content::RunAllTasksUntilIdle();

    testing::Mock::VerifyAndClearExpectations(&downloader_delegate);
  }
#endif

  // Update a single extension in an environment where the download request
  // initially responds with a 403 status. If |identity_provider| is not NULL,
  // this will first expect a request which includes an Authorization header
  // with an OAuth2 bearer token; otherwise, or if OAuth2 failure is simulated,
  // this expects the downloader to fall back onto cookie-based credentials.
  void TestProtectedDownload(
      const std::string& url_prefix,
      bool enable_oauth2,
      bool succeed_with_oauth2,
      int valid_authuser,
      int max_authuser) {
    ExtensionDownloaderTestHelper helper;
    TestDownloaderFactory factory(helper.url_loader_factory());
    TestCrxInstallerFactory crx_installer_factory;
    const ExtensionDownloader::Factory& downloader_factory =
        enable_oauth2 ? factory.GetAuthenticatedDownloaderFactory()
                      : factory.GetDownloaderFactory();
    ExtensionUpdater updater(profile());
    updater.InitAndEnable(extension_prefs(), pref_service(), kUpdateFrequency,
                          nullptr, downloader_factory);
    updater.set_crx_installer_factory_for_test(&crx_installer_factory);

    MockExtensionDownloaderDelegate downloader_delegate;
    downloader_delegate.DelegateTo(&updater);
    factory.OverrideDownloaderDelegate(&downloader_delegate);

    updater.Start();
    updater.EnsureDownloaderCreated();
    updater.downloader_->extensions_queue_.set_backoff_policy(kNoBackoffPolicy);

    GURL test_url(base::StringPrintf("%s/extension.crx", url_prefix.c_str()));

    const std::string id(32, 'a');
    std::string hash;
    base::Version version("0.0.1");
    std::unique_ptr<ExtensionDownloader::ExtensionFetch> extension_fetch =
        std::make_unique<ExtensionDownloader::ExtensionFetch>(
            CreateDownloaderTask(id), test_url, hash, version.GetString(),
            DownloadFetchPriority::kBackground);
    updater.downloader_->FetchUpdatedExtension(std::move(extension_fetch),
                                               std::nullopt);

    EXPECT_EQ(
        kExpectedLoadFlags,
        updater.downloader_->last_extension_loader_load_flags_for_testing_);

    // Fake a 403 response.
    EXPECT_CALL(downloader_delegate, OnExtensionDownloadRetryForTests())
        .WillOnce(DoAll(
            InvokeWithoutArgs(&downloader_delegate,
                              &MockExtensionDownloaderDelegate::Quit),
            InvokeWithoutArgs(&helper, &ExtensionDownloaderTestHelper::
                                           ClearURLLoaderFactoryResponses)));
    helper.test_url_loader_factory().AddResponse(test_url.spec(), "",
                                                 net::HTTP_FORBIDDEN);
    downloader_delegate.Wait();

    // Only call out to WaitForAccessTokenRequest(...) method below if
    // HTTPS is in use in a google domain and oauth is explicitly enabled.
    // Otherwise, test will await an access token request that have not
    // (and will not) happen.
    //
    // Note that in case the condition below isn't satisfied, the download
    // proceeds normally, but the request does not carry an 'Authorization'
    // HTTP header.
    if (enable_oauth2 && test_url.DomainIs("google.com") &&
        test_url.SchemeIsCryptographic()) {
      factory.identity_test_env()
          ->WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
              factory.account_id(), kFakeOAuth2Token, base::Time::Now());
    }

    bool using_oauth2 = false;
    int expected_load_flags = kExpectedLoadFlags;

    // Verify that the fetch has had its credentials properly incremented.
    EXPECT_TRUE(updater.downloader_->extension_loader_);
    net::HttpRequestHeaders fetch_headers =
        updater.downloader_
            ->last_extension_loader_resource_request_headers_for_testing_;
    // If the download URL is not https, no credentials should be provided.
    if (!test_url.SchemeIsCryptographic()) {
      // No cookies.
      EXPECT_EQ(
          kExpectedLoadFlags,
          updater.downloader_->last_extension_loader_load_flags_for_testing_);
      // No Authorization header.
      EXPECT_FALSE(
          fetch_headers.HasHeader(net::HttpRequestHeaders::kAuthorization));
      expected_load_flags = kExpectedLoadFlags;
    } else {
      // HTTPS is in use, so credentials are allowed.
      if (enable_oauth2 && test_url.DomainIs("google.com")) {
        // If an IdentityProvider is present and the URL is a google.com
        // URL, the fetcher should be in OAuth2 mode after the intitial
        // challenge.
        EXPECT_TRUE(fetch_headers.HasHeader(
            net::HttpRequestHeaders::kAuthorization));
        std::string expected_header_value = base::StringPrintf("Bearer %s",
            kFakeOAuth2Token);
        std::string actual_header_value =
            fetch_headers.GetHeader(net::HttpRequestHeaders::kAuthorization)
                .value_or(std::string());
        EXPECT_EQ(expected_header_value, actual_header_value);
        using_oauth2 = true;
      } else {
        // No IdentityProvider (or no google.com), so expect cookies instead of
        // an Authorization header.
        EXPECT_FALSE(fetch_headers.HasHeader(
            net::HttpRequestHeaders::kAuthorization));
        EXPECT_EQ(
            kExpectedLoadFlagsForDownloadWithCookies,
            updater.downloader_->last_extension_loader_load_flags_for_testing_);
        expected_load_flags = kExpectedLoadFlagsForDownloadWithCookies;
      }
    }

    bool success = false;
    if (using_oauth2) {
      if (succeed_with_oauth2) {
        success = true;
      } else {
        // Simulate OAuth2 failure and ensure that we fall back on cookies.
        EXPECT_CALL(downloader_delegate, OnExtensionDownloadRetryForTests())
            .WillOnce(
                DoAll(InvokeWithoutArgs(&downloader_delegate,
                                        &MockExtensionDownloaderDelegate::Quit),
                      InvokeWithoutArgs(&helper,
                                        &ExtensionDownloaderTestHelper::
                                            ClearURLLoaderFactoryResponses)));
        helper.test_url_loader_factory().AddResponse(test_url.spec(), "",
                                                     net::HTTP_FORBIDDEN);
        downloader_delegate.Wait();

        const ExtensionDownloader::ExtensionFetch& fetch =
            *updater.downloader_->extensions_queue_.active_request();
        EXPECT_EQ(0, GetAuthUserQueryValue(fetch.url));
        EXPECT_EQ(ExtensionDownloader::ExtensionFetch::CREDENTIALS_COOKIES,
                  fetch.credentials);

        EXPECT_TRUE(updater.downloader_->extension_loader_);
        fetch_headers =
            updater.downloader_
                ->last_extension_loader_resource_request_headers_for_testing_;
        EXPECT_FALSE(
            fetch_headers.HasHeader(net::HttpRequestHeaders::kAuthorization));
        EXPECT_EQ(
            kExpectedLoadFlagsForDownloadWithCookies,
            updater.downloader_->last_extension_loader_load_flags_for_testing_);
        expected_load_flags = kExpectedLoadFlagsForDownloadWithCookies;
      }
    }

    if (!success) {
      // Not yet ready to simulate a successful fetch. At this point we begin
      // simulating cookie-based authentication with increasing values of
      // authuser (starting from 0.)
      int user_index = 0;
      for (; user_index <= max_authuser; ++user_index) {
        const ExtensionDownloader::ExtensionFetch& fetch =
            *updater.downloader_->extensions_queue_.active_request();
        EXPECT_EQ(user_index, GetAuthUserQueryValue(fetch.url));
        if (user_index == valid_authuser) {
          success = true;
          break;
        }
        // Simulate an authorization failure which should elicit an increment
        // of the authuser value.
        EXPECT_TRUE(updater.downloader_->extension_loader_);
        EXPECT_EQ(
            expected_load_flags,
            updater.downloader_->last_extension_loader_load_flags_for_testing_);
        EXPECT_CALL(downloader_delegate, OnExtensionDownloadRetryForTests())
            .WillOnce(
                DoAll(InvokeWithoutArgs(&downloader_delegate,
                                        &MockExtensionDownloaderDelegate::Quit),
                      InvokeWithoutArgs(&helper,
                                        &ExtensionDownloaderTestHelper::
                                            ClearURLLoaderFactoryResponses)));
        helper.test_url_loader_factory().AddResponse(
            fetch.url.spec(), "whatever", net::HTTP_FORBIDDEN);
        downloader_delegate.Wait();
      }

      // Simulate exhaustion of all available authusers.
      if (!success && user_index > max_authuser) {
        const ExtensionDownloader::ExtensionFetch& fetch =
            *updater.downloader_->extensions_queue_.active_request();
        EXPECT_TRUE(updater.downloader_->extension_loader_);
        helper.test_url_loader_factory().AddResponse(
            fetch.url.spec(), std::string(), net::HTTP_UNAUTHORIZED);
        EXPECT_CALL(downloader_delegate,
                    OnExtensionDownloadFailed(_, _, _, _, _))
            .WillOnce(InvokeWithoutArgs(
                &downloader_delegate, &MockExtensionDownloaderDelegate::Quit));
        downloader_delegate.Wait();
      }
    }

    // Simulate successful authorization with a 200 response.
    if (success) {
      EXPECT_TRUE(updater.downloader_->extension_loader_);
      const ExtensionDownloader::ExtensionFetch& fetch =
          *updater.downloader_->extensions_queue_.active_request();

      CRXFileInfo crx_file_info;
      EXPECT_CALL(downloader_delegate,
                  OnExtensionDownloadFinished_(_, _, _, _, _, _))
          .WillOnce(
              DoAll(testing::SaveArg<0>(&crx_file_info),
                    InvokeWithoutArgs(&downloader_delegate,
                                      &MockExtensionDownloaderDelegate::Quit)));
      helper.test_url_loader_factory().AddResponse(fetch.url.spec(),
                                                   "whatever");
      downloader_delegate.Wait();

      // Verify installation would proceed as normal.
      EXPECT_EQ(id, crx_file_info.extension_id);
      base::FilePath tmpfile_path = crx_file_info.path;
      EXPECT_FALSE(tmpfile_path.empty());
    }
  }

  // Two extensions are updated.  If |updates_start_running| is true, the
  // mock extensions service has CreateUpdateInstaller(...) return the
  // fake CrxInstallers created by the test.  Otherwise, CreateUpdateInstaller()
  // returns nullptr, signaling install failures.
  void TestMultipleExtensionDownloading(bool updates_start_running) {
    ExtensionDownloaderTestHelper helper;
    TestDownloaderFactory factory(helper.url_loader_factory());
    TestCrxInstallerFactory crx_installer_factory;
    ExtensionUpdater updater(profile());
    updater.InitAndEnable(extension_prefs(), pref_service(), kUpdateFrequency,
                          nullptr, factory.GetDownloaderFactory());
    updater.set_crx_installer_factory_for_test(&crx_installer_factory);
    updater.Start();
    updater.EnsureDownloaderCreated();
    updater.downloader_->extensions_queue_.set_backoff_policy(kNoBackoffPolicy);

    EXPECT_THAT(GetRunningInstallIds(updater), testing::IsEmpty());

    GURL url1("http://localhost/extension1.crx");
    GURL url2("http://localhost/extension2.crx");

    const std::string id1(32, 'a');
    const std::string id2(32, 'b');

    std::string hash1;
    std::string hash2;

    std::string version1 = "0.1";
    std::string version2 = "0.1";

    // Start two fetches
    std::unique_ptr<ExtensionDownloader::ExtensionFetch> fetch1 =
        std::make_unique<ExtensionDownloader::ExtensionFetch>(
            CreateDownloaderTask(id1), url1, hash1, version1,
            DownloadFetchPriority::kBackground);
    std::unique_ptr<ExtensionDownloader::ExtensionFetch> fetch2 =
        std::make_unique<ExtensionDownloader::ExtensionFetch>(
            CreateDownloaderTask(id2), url2, hash2, version2,
            DownloadFetchPriority::kBackground);
    updater.downloader_->FetchUpdatedExtension(std::move(fetch1),
                                               std::optional<std::string>());
    updater.downloader_->FetchUpdatedExtension(std::move(fetch2),
                                               std::optional<std::string>());

    // Make the first fetch complete.
    EXPECT_TRUE(updater.downloader_->extension_loader_);
    EXPECT_EQ(
        kExpectedLoadFlags,
        updater.downloader_->last_extension_loader_load_flags_for_testing_);

    // We need some CrxInstallers, and CrxInstallers require a real
    // ExtensionService.  Create one on the testing profile.  Any action
    // the CrxInstallers take is on the testing profile's extension
    // service, not on our mock |service|.  This allows us to fake
    // the CrxInstaller actions we want.
    TestingProfile profile;
    // TODO(crbug.com/396722906): Delete this when CrxInstaller no longer has
    // dependencies on ExtensionService.
    static_cast<TestExtensionSystem*>(ExtensionSystem::Get(&profile))
        ->CreateExtensionService(base::CommandLine::ForCurrentProcess(),
                                 base::FilePath(), false);

    scoped_refptr<FakeCrxInstaller> fake_crx1 =
        base::MakeRefCounted<FakeCrxInstaller>(&profile);
    scoped_refptr<FakeCrxInstaller> fake_crx2 =
        base::MakeRefCounted<FakeCrxInstaller>(&profile);

    if (updates_start_running) {
      // Add mock CrxInstaller to be returned by
      // delegate.CreateUpdateInstaller().
      crx_installer_factory.AddFakeCrxInstaller(id1, fake_crx1);
      crx_installer_factory.AddFakeCrxInstaller(id2, fake_crx2);
    } else {
      // If we don't add mock CRX installers, the mock delegate will just return
      // nullptr, meaning a failure.
    }

    helper.test_url_loader_factory().AddResponse(
        url1.spec(), "Any content. This is irrelevant.", net::HTTP_OK);
    content::RunAllTasksUntilIdle();

    // Expect that the delegate was asked to do an install with the right data.
    base::FilePath tmpfile_path = crx_installer_factory.crx_install_path();
    EXPECT_FALSE(tmpfile_path.empty());
    EXPECT_EQ(id1, crx_installer_factory.crx_extension_id());
    RunUntilIdle();

    // Make sure the second fetch finished and asked the service to do an
    // update.
    EXPECT_TRUE(updater.downloader_->extension_loader_);
    EXPECT_EQ(
        kExpectedLoadFlags,
        updater.downloader_->last_extension_loader_load_flags_for_testing_);

    helper.test_url_loader_factory().AddResponse(
        url2.spec(), "Any other content. This is irrelevant.", net::HTTP_OK);
    content::RunAllTasksUntilIdle();

    if (updates_start_running) {
      // Both installations should have launched in parallel.
      EXPECT_THAT(GetRunningInstallIds(updater),
                  testing::UnorderedElementsAre(id1, id2));

      // Fake install notice.  This should end the first installation.
      fake_crx1->RunInstallerCallbacks(CrxInstallError(
          CrxInstallErrorType::OTHER, CrxInstallErrorDetail::NONE));
      content::RunAllTasksUntilIdle();
      EXPECT_THAT(GetRunningInstallIds(updater),
                  testing::UnorderedElementsAre(id2));

      fake_crx2->RunInstallerCallbacks(CrxInstallError(
          CrxInstallErrorType::OTHER, CrxInstallErrorDetail::NONE));
      content::RunAllTasksUntilIdle();
    }
    EXPECT_THAT(GetRunningInstallIds(updater), testing::IsEmpty());
  }

  void TestGalleryRequestsWithBrand(bool use_organic_brand_code) {
    google_brand::BrandForTesting brand_for_testing(
        use_organic_brand_code ? "GGLS" : "TEST");

    // We want to test a variety of combinations of expected ping conditions for
    // rollcall and active pings.
    auto ping_cases = std::to_array<int>({
        ManifestFetchData::kNeverPinged,
        0,
        1,
        5,
    });

    for (size_t i = 0; i < std::size(ping_cases); i++) {
      for (size_t j = 0; j < std::size(ping_cases); j++) {
        for (size_t k = 0; k < 2; k++) {
          int rollcall_ping_days = ping_cases[i];
          int active_ping_days = ping_cases[j];
          // Skip cases where rollcall_ping_days == -1, but
          // active_ping_days > 0, because rollcall_ping_days == -1 means the
          // app was just installed and this is the first update check after
          // installation.
          if (rollcall_ping_days == ManifestFetchData::kNeverPinged &&
              active_ping_days > 0)
            continue;

          bool active_bit = k > 0;
          TestGalleryRequests(rollcall_ping_days, active_ping_days, active_bit,
                              !use_organic_brand_code);
          ASSERT_FALSE(HasFailure()) <<
            " rollcall_ping_days=" << ping_cases[i] <<
            " active_ping_days=" << ping_cases[j] <<
            " active_bit=" << active_bit;
        }
      }
    }
  }

  // Test requests to both a Google server and a non-google server. This allows
  // us to test various combinations of installed (ie roll call) and active
  // (ie app launch) ping scenarios. The invariant is that each type of ping
  // value should be present at most once per day, and can be calculated based
  // on the delta between now and the last ping time (or in the case of active
  // pings, that delta plus whether the app has been active).
  void TestGalleryRequests(int rollcall_ping_days,
                           int active_ping_days,
                           bool active_bit,
                           bool expect_brand_code) {
    // Set up 2 mock extensions, one with a google.com update url and one
    // without.
    prefs_ = std::make_unique<TestExtensionPrefs>(
        base::SingleThreadTaskRunner::GetCurrentDefault(),
        std::make_unique<TestingProfile>());
    ExtensionDownloaderTestHelper helper;
    TestDownloaderFactory factory(helper.url_loader_factory());
    TestCrxInstallerFactory crx_installer_factory;
    ExtensionList tmp;
    GURL url1("http://clients2.google.com/service/update2/crx");
    GURL url2("http://www.somewebsite.com");
    CreateTestExtensions(1, 1, &tmp, &url1.possibly_invalid_spec(),
                         ManifestLocation::kInternal);
    CreateTestExtensions(2, 1, &tmp, &url2.possibly_invalid_spec(),
                         ManifestLocation::kInternal);
    EXPECT_EQ(2u, tmp.size());
    SetExtensions(tmp, ExtensionList());

    ExtensionPrefs* prefs = extension_prefs();
    const std::string& id = tmp[0]->id();
    Time now = Time::Now();
    if (rollcall_ping_days == 0) {
      prefs->SetLastPingDay(id, now - base::Seconds(15));
    } else if (rollcall_ping_days > 0) {
      Time last_ping_day =
          now - base::Days(rollcall_ping_days) - base::Seconds(15);
      prefs->SetLastPingDay(id, last_ping_day);
    }

    // Store a value for the last day we sent an active ping.
    if (active_ping_days == 0) {
      prefs->SetLastActivePingDay(id, now - base::Seconds(15));
    } else if (active_ping_days > 0) {
      Time last_active_ping_day =
          now - base::Days(active_ping_days) - base::Seconds(15);
      prefs->SetLastActivePingDay(id, last_active_ping_day);
    }
    if (active_bit)
      prefs->SetActiveBit(id, true);

    ExtensionUpdater updater(profile());
    updater.InitAndEnable(extension_prefs(), pref_service(), kUpdateFrequency,
                          nullptr, factory.GetDownloaderFactory());
    updater.set_crx_installer_factory_for_test(&crx_installer_factory);
    updater.Start();
    updater.CheckNow(ExtensionUpdater::CheckParams());

    // Make the updater do manifest fetching, and note the urls it tries to
    // fetch.
    std::vector<GURL> fetched_urls;
    ASSERT_TRUE(updater.downloader_->HasActiveManifestRequestForTesting());
    const ManifestFetchData& fetch =
        *updater.downloader_->manifests_queue_.active_request();
    fetched_urls.push_back(fetch.full_url());
    helper.test_url_loader_factory().AddResponse(
        fetched_urls[0].spec(), std::string(), net::HTTP_INTERNAL_SERVER_ERROR);
    RunUntilIdle();

    const ManifestFetchData& fetch2 =
        *updater.downloader_->manifests_queue_.active_request();
    fetched_urls.push_back(fetch2.full_url());

    // The urls could have been fetched in either order, so use the host to
    // tell them apart and note the query each used.
    GURL url1_fetch_url;
    GURL url2_fetch_url;
    std::string url1_query;
    std::string url2_query;
    if (fetched_urls[0].GetHost() == url1.GetHost()) {
      url1_fetch_url = fetched_urls[0];
      url2_fetch_url = fetched_urls[1];

      url1_query = fetched_urls[0].GetQuery();
      url2_query = fetched_urls[1].GetQuery();
    } else if (fetched_urls[0].GetHost() == url2.GetHost()) {
      url1_fetch_url = fetched_urls[1];
      url2_fetch_url = fetched_urls[0];
      url1_query = fetched_urls[1].GetQuery();
      url2_query = fetched_urls[0].GetQuery();
    } else {
      NOTREACHED();
    }

    std::map<std::string, ParamsMap> url1_ping_data =
        GetPingDataFromURL(url1_fetch_url);
    ParamsMap url1_params = ParamsMap();
    if (!url1_ping_data.empty() && base::Contains(url1_ping_data, id))
      url1_params = url1_ping_data[id];

    // First make sure the non-google query had no ping parameter.
    EXPECT_TRUE(GetPingDataFromURL(url2_fetch_url).empty());

    // Now make sure the google query had the correct ping parameter.
    bool did_rollcall = false;
    if (rollcall_ping_days != 0) {
      ASSERT_TRUE(base::Contains(url1_params, "r"));
      ASSERT_EQ(1u, url1_params["r"].size());
      EXPECT_EQ(base::NumberToString(rollcall_ping_days),
                *url1_params["r"].begin());
      did_rollcall = true;
    }
    if (active_bit && active_ping_days != 0 && did_rollcall) {
      ASSERT_TRUE(base::Contains(url1_params, "a"));
      ASSERT_EQ(1u, url1_params["a"].size());
      EXPECT_EQ(base::NumberToString(active_ping_days),
                *url1_params["a"].begin());
    }

    // Make sure the non-google query has no brand parameter.
    const std::string brand_string = "brand%3D";
    EXPECT_TRUE(url2_query.find(brand_string) == std::string::npos);

#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
    // Make sure the google query has a brand parameter, but only if the
    // brand is non-organic.
    if (expect_brand_code) {
      EXPECT_TRUE(url1_query.find(brand_string) != std::string::npos);
    } else {
      EXPECT_TRUE(url1_query.find(brand_string) == std::string::npos);
    }
#else
    // Chromium builds never add the brand to the parameter, even for google
    // queries.
    EXPECT_TRUE(url1_query.find(brand_string) == std::string::npos);
#endif

    RunUntilIdle();
  }

  // This makes sure that the extension updater properly stores the results
  // of a <daystart> tag from a manifest fetch in one of two cases: 1) This is
  // the first time we fetched the extension, or 2) We sent a ping value of
  // >= 1 day for the extension.
  void TestHandleManifestResults() {
    ExtensionDownloaderTestHelper helper;
    TestDownloaderFactory factory(helper.url_loader_factory());
    TestCrxInstallerFactory crx_installer_factory;
    GURL update_url("http://www.google.com/manifest");
    ExtensionList tmp;
    CreateTestExtensions(1, 1, &tmp, &update_url.spec(),
                         ManifestLocation::kInternal);
    SetExtensions(tmp, ExtensionList());

    ExtensionUpdater updater(profile());
    updater.InitAndEnable(extension_prefs(), pref_service(), kUpdateFrequency,
                          nullptr, factory.GetDownloaderFactory());
    updater.set_crx_installer_factory_for_test(&crx_installer_factory);
    updater.Start();
    updater.EnsureDownloaderCreated();

    std::unique_ptr<ManifestFetchData> fetch_data(
        CreateManifestFetchData(update_url));
    const Extension* extension = tmp[0].get();
    AddExtensionToFetchDataForTesting(fetch_data.get(), extension->id(),
                                      extension->VersionString(), update_url);
    auto results = std::make_unique<UpdateManifestResults>();
    constexpr int kDaystartElapsedSeconds = 750;
    results->daystart_elapsed_seconds = kDaystartElapsedSeconds;

    updater.downloader_->HandleManifestResults(std::move(fetch_data),
                                               std::move(results),
                                               /*error=*/std::nullopt);
    Time last_ping_day = extension_prefs()->LastPingDay(extension->id());
    EXPECT_FALSE(last_ping_day.is_null());
    int64_t seconds_diff = (Time::Now() - last_ping_day).InSeconds();
    EXPECT_LT(seconds_diff - kDaystartElapsedSeconds, 5);
  }

  void TestManifestAddExtension(DownloadFetchPriority data_priority,
                                DownloadFetchPriority extension_priority,
                                DownloadFetchPriority expected_priority) {
    const std::string id(32, 'a');
    const std::string version = "1.0";

    std::unique_ptr<ManifestFetchData> fetch_data(
        CreateManifestFetchData(GURL("http://localhost/foo"), data_priority));
    ASSERT_TRUE(fetch_data->AddExtension(
        id, version, ExtensionDownloaderTestHelper::GetTestPingData(),
        std::string(), std::string(), ManifestLocation::kInternal,
        extension_priority));
    ASSERT_EQ(expected_priority, fetch_data->fetch_priority());
  }

  void TestManifestMerge(DownloadFetchPriority data_priority,
                         DownloadFetchPriority other_priority,
                         DownloadFetchPriority expected_priority) {
    std::unique_ptr<ManifestFetchData> fetch_data(
        CreateManifestFetchData(GURL("http://localhost/foo"), data_priority));

    std::unique_ptr<ManifestFetchData> fetch_other(
        CreateManifestFetchData(GURL("http://localhost/foo"), other_priority));

    fetch_data->Merge(std::move(fetch_other));
    ASSERT_EQ(expected_priority, fetch_data->fetch_priority());
  }

 protected:
  std::unique_ptr<TestExtensionPrefs> prefs_;
  content::BrowserTaskEnvironment task_environment_;

  ManifestFetchData* CreateManifestFetchData(
      const GURL& update_url,
      DownloadFetchPriority fetch_priority) {
    return new ManifestFetchData(update_url, 0, "",
                                 UpdateQueryParams::Get(UpdateQueryParams::CRX),
                                 ManifestFetchData::PING, fetch_priority);
  }

  ManifestFetchData* CreateManifestFetchData(const GURL& update_url) {
    return CreateManifestFetchData(update_url,
                                   DownloadFetchPriority::kBackground);
  }

 private:
  content::InProcessUtilityThreadHelper in_process_utility_thread_helper_;

#if BUILDFLAG(IS_CHROMEOS)
  ash::ScopedCrosSettingsTestHelper cros_settings_test_helper_;
  user_manager::ScopedUserManager user_manager_{
      std::make_unique<user_manager::UserManagerImpl>(
          std::make_unique<ash::UserManagerDelegateImpl>(),
          TestingBrowserProcess::GetGlobal()->local_state(),
          ash::CrosSettings::Get())};
#endif

  StubExtensionRegistrarDelegate stub_extension_registrar_delegate_;
};

// Because we test some private methods of ExtensionUpdater, it's easier for the
// actual test code to live in ExtensionUpdaterTest methods instead of TEST_F
// subclasses where friendship with ExtensionUpdater is not inherited.

TEST_F(ExtensionUpdaterTest, TestExtensionUpdateCheckRequests) {
  TestExtensionUpdateCheckRequests(false);
}

TEST_F(ExtensionUpdaterTest, TestExtensionUpdateCheckRequestsPending) {
  TestExtensionUpdateCheckRequests(true);
}

TEST_F(ExtensionUpdaterTest, TestUpdateUrlData) {
  TestUpdateUrlDataEmpty();
  TestUpdateUrlDataSimple();
  TestUpdateUrlDataCompound();
  std::string gallery_url_spec = extension_urls::GetWebstoreUpdateUrl().spec();
  TestUpdateUrlDataFromUrl(gallery_url_spec, DownloadFetchPriority::kBackground,
                           1, true);
  TestUpdateUrlDataFromUrl(gallery_url_spec, DownloadFetchPriority::kForeground,
                           1, true);
  TestUpdateUrlDataFromUrl(gallery_url_spec, DownloadFetchPriority::kBackground,
                           2, true);
  TestUpdateUrlDataFromUrl(gallery_url_spec, DownloadFetchPriority::kForeground,
                           4, true);
  TestUpdateUrlDataFromUrl("http://example.com/update",
                           DownloadFetchPriority::kForeground, 4, false);
}

TEST_F(ExtensionUpdaterTest, TestInstallSource) {
  TestInstallSource();
}

TEST_F(ExtensionUpdaterTest, TestInstallLocation) {
  TestInstallLocation();
}

TEST_F(ExtensionUpdaterTest, TestDetermineUpdates) {
  TestDetermineUpdates();
}

TEST_F(ExtensionUpdaterTest, TestDetermineUpdatesPending) {
  TestDetermineUpdatesPending();
}

TEST_F(ExtensionUpdaterTest, TestDetermineUpdatesDuplicates) {
  TestDetermineUpdatesDuplicates();
}

TEST_F(ExtensionUpdaterTest, TestDetermineUpdatesError) {
  TestDetermineUpdatesError();
}

TEST_F(ExtensionUpdaterTest, TestMultipleManifestDownloading) {
  TestMultipleManifestDownloading();
}

TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloading) {
  TestSingleExtensionDownloading(false, false, false);
}

TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingPending) {
  TestSingleExtensionDownloading(true, false, false);
}

TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingWithRetry) {
  TestSingleExtensionDownloading(false, true, false);
}

TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingPendingWithRetry) {
  TestSingleExtensionDownloading(true, true, false);
}

TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingFailure) {
  TestSingleExtensionDownloading(false, false, true);
}

TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingFailureWithRetry) {
  TestSingleExtensionDownloading(false, true, true);
}

TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingFailurePending) {
  TestSingleExtensionDownloading(true, false, true);
}

#if BUILDFLAG(IS_CHROMEOS)
TEST_F(ExtensionUpdaterTest, TestCacheCorruptionCrxDownload) {
  TestCacheCorruption();
}
#endif

TEST_F(ExtensionUpdaterTest, ProtectedDownloadCookieAuth) {
  TestProtectedDownload(
      "https://chrome.google.com/webstore/download",
      false, false,  // No OAuth2 support
      0, 0);
}

TEST_F(ExtensionUpdaterTest, ProtectedDownloadCookieFailure) {
  TestProtectedDownload(
      "https://chrome.google.com/webstore/download",
      false, false,  // No OAuth2 support
      0, -1);  // max_authuser=-1 simulates no valid authuser value.
}

TEST_F(ExtensionUpdaterTest, ProtectedDownloadWithNonDefaultAuthUser1) {
  TestProtectedDownload("https://google.com", false, false, 1, 1);
}

TEST_F(ExtensionUpdaterTest, ProtectedDownloadWithNonDefaultAuthUser2) {
  TestProtectedDownload("https://google.com", false, false, 2, 2);
}

TEST_F(ExtensionUpdaterTest, ProtectedDownloadAuthUserExhaustionFailure) {
  TestProtectedDownload("https://google.com", false, false, 2, 5);
}

TEST_F(ExtensionUpdaterTest, ProtectedDownloadWithOAuth2Token) {
  TestProtectedDownload(
      "https://google.com",
      true, true,
      0, -1);
}

TEST_F(ExtensionUpdaterTest, ProtectedDownloadWithOAuth2Failure) {
  TestProtectedDownload(
      "https://google.com",
      true, false,
      0, -1);
}

TEST_F(ExtensionUpdaterTest, ProtectedDownloadNoOAuth2WithNonGoogleDomain) {
  TestProtectedDownload(
      "https://not-google.com",
      true, true,
      0, -1);
}

TEST_F(ExtensionUpdaterTest, ProtectedDownloadFailWithoutHTTPS) {
  TestProtectedDownload(
      "http://google.com",
      true, true,
      0, 0);
}

TEST_F(ExtensionUpdaterTest, TestMultipleExtensionDownloadingUpdatesFail) {
  TestMultipleExtensionDownloading(false);
}
TEST_F(ExtensionUpdaterTest, TestMultipleExtensionDownloadingUpdatesSucceed) {
  TestMultipleExtensionDownloading(true);
}

TEST_F(ExtensionUpdaterTest, TestManifestRetryDownloading) {
  TestManifestRetryDownloading();
}

TEST_F(ExtensionUpdaterTest, DISABLED_TestGalleryRequestsWithOrganicBrand) {
  TestGalleryRequestsWithBrand(true);
}

TEST_F(ExtensionUpdaterTest, DISABLED_TestGalleryRequestsWithNonOrganicBrand) {
  TestGalleryRequestsWithBrand(false);
}

TEST_F(ExtensionUpdaterTest, TestHandleManifestResults) {
  TestHandleManifestResults();
}

TEST_F(ExtensionUpdaterTest, TestNonAutoUpdateableLocations) {
  ExtensionDownloaderTestHelper helper;
  TestDownloaderFactory factory(helper.url_loader_factory());
  TestCrxInstallerFactory crx_installer_factory;
  ExtensionUpdater updater(profile());
  updater.InitAndEnable(extension_prefs(), pref_service(), kUpdateFrequency,
                        nullptr, factory.GetDownloaderFactory());
  updater.set_crx_installer_factory_for_test(&crx_installer_factory);
  MockExtensionDownloaderDelegate downloader_delegate;
  factory.OverrideDownloaderDelegate(&downloader_delegate);

  // Non-internal non-external extensions should be rejected.
  ExtensionList extensions;
  CreateTestExtensions(1, 1, &extensions, nullptr,
                       ManifestLocation::kInvalidLocation);
  ASSERT_EQ(1u, extensions.size());
  // The test will fail with unexpected calls if the delegate's methods are
  // invoked for the extension.
  SetExtensions(extensions, ExtensionList());
  updater.Start();
  updater.CheckNow(ExtensionUpdater::CheckParams());
}

TEST_F(ExtensionUpdaterTest, TestUpdatingDisabledExtensions) {
  ExtensionDownloaderTestHelper helper;
  TestDownloaderFactory factory(helper.url_loader_factory());
  TestCrxInstallerFactory crx_installer_factory;
  ExtensionUpdater updater(profile());
  updater.InitAndEnable(extension_prefs(), pref_service(), kUpdateFrequency,
                        nullptr, factory.GetDownloaderFactory());
  updater.set_crx_installer_factory_for_test(&crx_installer_factory);
  NiceMock<MockUpdateService> update_service;
  OverrideUpdateService(&updater, &update_service);

  // Non-internal non-external extensions should be rejected.
  ExtensionList enabled_extensions;
  ExtensionList disabled_extensions;
  CreateTestExtensions(1, 1, &enabled_extensions, nullptr,
                       ManifestLocation::kInternal);
  CreateTestExtensions(2, 1, &disabled_extensions, nullptr,
                       ManifestLocation::kInternal);
  ASSERT_EQ(1u, enabled_extensions.size());
  ASSERT_EQ(1u, disabled_extensions.size());

  // We expect that both enabled and disabled extensions are auto-updated.
  EXPECT_CALL(update_service,
              StartUpdateCheck(
                  ::testing::Field(&ExtensionUpdateCheckParams::update_info,
                                   ::testing::SizeIs(2)),
                  _, _));

  SetExtensions(enabled_extensions, disabled_extensions);
  updater.Start();
  updater.CheckNow(ExtensionUpdater::CheckParams());
}

// crbug.com/1098540: Tests that removely disabled extensions that are part of
// the blocklisted extensions are still receive updates.
TEST_F(ExtensionUpdaterTest, TestUpdatingRemotelyDisabledExtensions) {
  ExtensionDownloaderTestHelper helper;
  TestDownloaderFactory factory(helper.url_loader_factory());
  TestCrxInstallerFactory crx_installer_factory;
  ExtensionUpdater updater(profile());
  updater.InitAndEnable(extension_prefs(), pref_service(), kUpdateFrequency,
                        nullptr, factory.GetDownloaderFactory());
  updater.set_crx_installer_factory_for_test(&crx_installer_factory);
  NiceMock<MockUpdateService> update_service;
  OverrideUpdateService(&updater, &update_service);

  ExtensionList enabled_extensions;
  ExtensionList blocklisted_extensions;
  CreateTestExtensions(1, 1, &enabled_extensions, nullptr,
                       ManifestLocation::kInternal);
  CreateTestExtensions(2, 1, &blocklisted_extensions, nullptr,
                       ManifestLocation::kInternal);
  CreateTestExtensions(3, 1, &blocklisted_extensions, nullptr,
                       ManifestLocation::kInternal);
  ASSERT_EQ(1u, enabled_extensions.size());
  ASSERT_EQ(2u, blocklisted_extensions.size());
  const std::string& remotely_blocklisted_id = blocklisted_extensions[0]->id();
  blocklist_prefs::SetSafeBrowsingExtensionBlocklistState(
      remotely_blocklisted_id, BitMapBlocklistState::BLOCKLISTED_MALWARE,
      extension_prefs());
  blocklist_prefs::AddOmahaBlocklistState(
      remotely_blocklisted_id, BitMapBlocklistState::BLOCKLISTED_MALWARE,
      extension_prefs());

  // We expect that both enabled and remotely blocklisted extensions are
  // auto-updated.
  EXPECT_CALL(update_service,
              StartUpdateCheck(
                  ::testing::Field(&ExtensionUpdateCheckParams::update_info,
                                   ::testing::SizeIs(2)),
                  _, _));

  SetExtensions(enabled_extensions, ExtensionList(), blocklisted_extensions);
  updater.Start();
  updater.CheckNow(ExtensionUpdater::CheckParams());
}

TEST_F(ExtensionUpdaterTest, TestPendingInstall) {
  // Add an extension as a pending update with a higher version number.
  base::Value::Dict manifest;
  manifest.Set(manifest_keys::kKey, kExtensionManifestKey);
  manifest.Set(manifest_keys::kName, "Fake extension");
  manifest.Set(manifest_keys::kVersion, "1.0.0.1");
  manifest.Set(manifest_keys::kManifestVersion, 2);
  manifest.Set(manifest_keys::kDifferentialFingerprint, "fingerprint");
  scoped_refptr<Extension> pending_update =
      prefs_->AddExtensionWithManifest(manifest, ManifestLocation::kInternal);
  DelayedInstallManager::Get(profile())->Insert(pending_update);

  ExtensionDownloaderTestHelper helper;
  TestDownloaderFactory factory(helper.url_loader_factory());
  TestCrxInstallerFactory crx_installer_factory;
  ExtensionUpdater updater(profile());
  updater.InitAndEnable(extension_prefs(), pref_service(), kUpdateFrequency,
                        nullptr, factory.GetDownloaderFactory());
  updater.set_crx_installer_factory_for_test(&crx_installer_factory);
  NiceMock<MockUpdateService> update_service;
  OverrideUpdateService(&updater, &update_service);

  ExtensionList enabled_extensions;
  std::string extension_key(kExtensionManifestKey);
  CreateTestExtensions(1, 1, &enabled_extensions, nullptr,
                       ManifestLocation::kInternal, extension_key);
  ASSERT_EQ(1u, enabled_extensions.size());
  ASSERT_EQ(enabled_extensions[0]->VersionString(), "1.0.0.0");

  // When StartUpdateCheck is called, we expect the pending version is used.
  EXPECT_CALL(
      update_service,
      StartUpdateCheck(
          ::testing::Field(
              &ExtensionUpdateCheckParams::update_info,
              ::testing::ElementsAre(::testing::Pair(
                  enabled_extensions[0]->id(),
                  ::testing::FieldsAre(
                      "", false, ::testing::Optional(std::string("1.0.0.1")),
                      ::testing::Optional(std::string("fingerprint")))))),
          _, _));

  SetExtensions(enabled_extensions, ExtensionList());
  updater.Start();
  updater.CheckNow(ExtensionUpdater::CheckParams());
}

TEST_F(ExtensionUpdaterTest, TestManifestFetchesBuilderAddExtension) {
  auto helper = std::make_unique<ExtensionDownloaderTestHelper>();
  EXPECT_EQ(0u, ManifestFetchersCount(&helper->downloader()));

  // First, verify that adding valid extensions does invoke the callbacks on
  // the delegate.
  std::string id = crx_file::id_util::GenerateId("foo");
  EXPECT_CALL(helper->delegate(), GetPingDataForExtension(id, _))
      .WillOnce(Return(false));
  EXPECT_TRUE(helper->downloader().AddPendingExtension(
      CreateDownloaderTask(id, GURL("http://example.com/update"))));
  helper->downloader().StartAllPending(nullptr);
  Mock::VerifyAndClearExpectations(&helper->delegate());
  EXPECT_EQ(1u, ManifestFetchersCount(&helper->downloader()));

  // Extensions with invalid update URLs should be rejected.
  id = crx_file::id_util::GenerateId("foo2");
  EXPECT_FALSE(helper->downloader().AddPendingExtension(
      CreateDownloaderTask(id, GURL("http:google.com:foo"))));
  helper->downloader().StartAllPending(nullptr);
  EXPECT_EQ(1u, ManifestFetchersCount(&helper->downloader()));

  // Extensions with empty IDs should be rejected.
  EXPECT_FALSE(helper->downloader().AddPendingExtension(
      CreateDownloaderTask(std::string(), GURL())));
  helper->downloader().StartAllPending(nullptr);
  EXPECT_EQ(1u, ManifestFetchersCount(&helper->downloader()));

  // TODO(akalin): Test that extensions with empty update URLs
  // converted from user scripts are rejected.

  // Reset the ExtensionDownloader so that it drops the current fetcher.
  helper = std::make_unique<ExtensionDownloaderTestHelper>();
  EXPECT_EQ(0u, ManifestFetchersCount(&helper->downloader()));

  // Extensions with empty update URLs should have a default one
  // filled in.
  id = crx_file::id_util::GenerateId("foo3");
  EXPECT_CALL(helper->delegate(), GetPingDataForExtension(id, _))
      .WillOnce(Return(false));
  EXPECT_TRUE(helper->downloader().AddPendingExtension(
      CreateDownloaderTask(id, GURL())));
  helper->downloader().StartAllPending(nullptr);
  EXPECT_EQ(1u, ManifestFetchersCount(&helper->downloader()));

  RunUntilIdle();
  auto* request = &(*helper->test_url_loader_factory().pending_requests())[0];
  ASSERT_TRUE(request);
  EXPECT_FALSE(request->request.url.is_empty());
}

TEST_F(ExtensionUpdaterTest, TestAddPendingExtensionWithVersion) {
  constexpr char kVersion[] = "1.2.3.4";
  auto helper = std::make_unique<ExtensionDownloaderTestHelper>();
  EXPECT_EQ(0u, ManifestFetchersCount(&helper->downloader()));

  {
    // First, verify that adding valid extensions does invoke the callbacks on
    // the delegate.
    ExtensionId id = crx_file::id_util::GenerateId("foo");
    EXPECT_CALL(helper->delegate(), GetPingDataForExtension(id, _))
        .WillOnce(Return(false));
    ExtensionDownloaderTask task =
        CreateDownloaderTask(id, GURL("http://example.com/update"));
    task.version = base::Version(kVersion);
    EXPECT_TRUE(helper->downloader().AddPendingExtension(std::move(task)));
    helper->downloader().StartAllPending(nullptr);
    Mock::VerifyAndClearExpectations(&helper->delegate());
    EXPECT_EQ(1u, ManifestFetchersCount(&helper->downloader()));
  }

  {
    // Extensions with invalid update URLs should be rejected.
    ExtensionId id = crx_file::id_util::GenerateId("foo2");
    ExtensionDownloaderTask task =
        CreateDownloaderTask(id, GURL("http:google.com:foo"));
    task.version = base::Version(kVersion);
    EXPECT_FALSE(helper->downloader().AddPendingExtension(std::move(task)));
    helper->downloader().StartAllPending(nullptr);
    EXPECT_EQ(1u, ManifestFetchersCount(&helper->downloader()));
  }

  {
    // Extensions with empty IDs should be rejected.
    ExtensionDownloaderTask task = CreateDownloaderTask(std::string(), GURL());
    task.version = base::Version(kVersion);
    EXPECT_FALSE(helper->downloader().AddPendingExtension(std::move(task)));
    helper->downloader().StartAllPending(nullptr);
    EXPECT_EQ(1u, ManifestFetchersCount(&helper->downloader()));
  }

  // Reset the ExtensionDownloader so that it drops the current fetcher.
  helper = std::make_unique<ExtensionDownloaderTestHelper>();
  EXPECT_EQ(0u, ManifestFetchersCount(&helper->downloader()));

  {
    // Extensions with empty update URLs should have a default one
    // filled in.
    ExtensionId id = crx_file::id_util::GenerateId("foo3");
    EXPECT_CALL(helper->delegate(), GetPingDataForExtension(id, _))
        .WillOnce(Return(false));
    ExtensionDownloaderTask task = CreateDownloaderTask(id, GURL());
    task.version = base::Version(kVersion);
    EXPECT_TRUE(helper->downloader().AddPendingExtension(std::move(task)));
    helper->downloader().StartAllPending(nullptr);
    EXPECT_EQ(1u, ManifestFetchersCount(&helper->downloader()));
  }

  RunUntilIdle();
  auto* request = &(*helper->test_url_loader_factory().pending_requests())[0];
  ASSERT_TRUE(request);
  EXPECT_FALSE(request->request.url.is_empty());
  EXPECT_THAT(request->request.url.possibly_invalid_spec(),
              testing::HasSubstr(kVersion));
}

TEST_F(ExtensionUpdaterTest, TestStartUpdateCheckMemory) {
  ExtensionDownloaderTestHelper helper;

  StartUpdateCheck(&helper.downloader(),
                   CreateManifestFetchData(GURL("http://localhost/foo")));
  // This should delete the newly-created ManifestFetchData.
  StartUpdateCheck(&helper.downloader(),
                   CreateManifestFetchData(GURL("http://localhost/foo")));
  // This should add into |manifests_pending_|.
  StartUpdateCheck(&helper.downloader(),
                   CreateManifestFetchData(GURL("http://www.google.com")));
  // The dtor of |downloader| should delete the pending fetchers.
}

TEST_F(ExtensionUpdaterTest, TestCheckSoon) {
  ExtensionDownloaderTestHelper helper;
  TestDownloaderFactory factory(helper.url_loader_factory());
  TestCrxInstallerFactory crx_installer_factory;
  ExtensionUpdater updater(profile());
  updater.InitAndEnable(extension_prefs(), pref_service(), kUpdateFrequency,
                        nullptr, factory.GetDownloaderFactory());
  updater.set_crx_installer_factory_for_test(&crx_installer_factory);
  EXPECT_FALSE(updater.WillCheckSoon());
  updater.Start();
  EXPECT_TRUE(updater.WillCheckSoon());
  RunUntilIdle();
  EXPECT_FALSE(updater.WillCheckSoon());
  updater.CheckSoon();
  EXPECT_TRUE(updater.WillCheckSoon());
  updater.CheckSoon();
  EXPECT_TRUE(updater.WillCheckSoon());
  RunUntilIdle();
  EXPECT_FALSE(updater.WillCheckSoon());
  updater.CheckSoon();
  EXPECT_TRUE(updater.WillCheckSoon());
  updater.Stop();
  EXPECT_FALSE(updater.WillCheckSoon());
}

TEST_F(ExtensionUpdaterTest, TestUninstallWhileUpdateCheck) {
  ExtensionDownloaderTestHelper helper;
  TestDownloaderFactory factory(helper.url_loader_factory());
  TestCrxInstallerFactory crx_installer_factory;
  ExtensionList tmp;
  CreateTestExtensions(1, 1, &tmp, nullptr, ManifestLocation::kInternal);
  SetExtensions(tmp, ExtensionList());

  ASSERT_EQ(1u, tmp.size());
  ExtensionId id = tmp.front()->id();
  ExtensionRegistry* registry = ExtensionRegistry::Get(profile());
  ASSERT_TRUE(registry->enabled_extensions().GetByID(id));

  ExtensionUpdater updater(profile());
  updater.InitAndEnable(extension_prefs(), pref_service(), kUpdateFrequency,
                        nullptr, factory.GetDownloaderFactory());
  updater.set_crx_installer_factory_for_test(&crx_installer_factory);
  ExtensionUpdater::CheckParams params;
  params.ids = {id};
  updater.Start();
  updater.CheckNow(std::move(params));

  SetExtensions(ExtensionList(), ExtensionList());
  ASSERT_FALSE(registry->enabled_extensions().GetByID(id));

  // RunUntilIdle is needed to make sure that the UpdateService instance that
  // runs the extension update process has a chance to exit gracefully; without
  // it, the test would crash.
  RunUntilIdle();
}

TEST_F(ExtensionUpdaterTest, TestManifestFetchDataAddExtension) {
  TestManifestAddExtension(DownloadFetchPriority::kBackground,
                           DownloadFetchPriority::kBackground,
                           DownloadFetchPriority::kBackground);

  TestManifestAddExtension(DownloadFetchPriority::kBackground,
                           DownloadFetchPriority::kForeground,
                           DownloadFetchPriority::kForeground);

  TestManifestAddExtension(DownloadFetchPriority::kForeground,
                           DownloadFetchPriority::kBackground,
                           DownloadFetchPriority::kForeground);

  TestManifestAddExtension(DownloadFetchPriority::kForeground,
                           DownloadFetchPriority::kForeground,
                           DownloadFetchPriority::kForeground);
}

TEST_F(ExtensionUpdaterTest, TestManifestFetchDataMerge) {
  TestManifestMerge(DownloadFetchPriority::kBackground,
                    DownloadFetchPriority::kBackground,
                    DownloadFetchPriority::kBackground);

  TestManifestMerge(DownloadFetchPriority::kBackground,
                    DownloadFetchPriority::kForeground,
                    DownloadFetchPriority::kForeground);

  TestManifestMerge(DownloadFetchPriority::kForeground,
                    DownloadFetchPriority::kBackground,
                    DownloadFetchPriority::kForeground);

  TestManifestMerge(DownloadFetchPriority::kForeground,
                    DownloadFetchPriority::kForeground,
                    DownloadFetchPriority::kForeground);
}

TEST_F(ExtensionUpdaterTest, TestManifestFetchCredentials) {
  TestManifestCredentialsWebstore();
  TestManifestCredentialsNonWebstore();
}

TEST_F(ExtensionUpdaterTest, TestManifestFetchPriority) {
  TestManifestFetchPriority(DownloadFetchPriority::kBackground);
  TestManifestFetchPriority(DownloadFetchPriority::kForeground);
}

TEST_F(ExtensionUpdaterTest, TestExtensionPriority) {
  TestSingleExtensionDownloadingPriority(DownloadFetchPriority::kBackground);
  TestSingleExtensionDownloadingPriority(DownloadFetchPriority::kForeground);
}

TEST_F(ExtensionUpdaterTest, TestProfileDestruction) {
  ExtensionUpdater updater(profile());
  // Create an active ProfileManager, and do NOT make it the owner of profile().
  // This causes ScopedProfileKeepAlive::TryAcquire() to fail.
  auto testing_profile_manager = std::make_unique<TestingProfileManager>(
      TestingBrowserProcess::GetGlobal());
  ASSERT_TRUE(testing_profile_manager->SetUp());

  ExtensionDownloaderTestHelper helper;
  TestDownloaderFactory factory(helper.url_loader_factory());
  // Verify that CheckNow() doesn't do anything in this state.
  updater.SetUpdatingStartedCallbackForTesting(base::BindLambdaForTesting(
      [&]() { ADD_FAILURE() << "Updating should not have started."; }));
  updater.InitAndEnable(extension_prefs(), pref_service(), kUpdateFrequency,
                        nullptr, factory.GetDownloaderFactory());
  updater.Start();
  updater.CheckNow(ExtensionUpdater::CheckParams());
  base::RunLoop().RunUntilIdle();
}

class CanUseUpdateServiceTest : public ExtensionUpdaterTest {
 public:
  CanUseUpdateServiceTest() = default;
  ~CanUseUpdateServiceTest() override = default;

  void SetUp() override {
    ExtensionUpdaterTest::SetUp();

    factory_ = std::make_unique<TestDownloaderFactory>(
        downloader_test_helper_.url_loader_factory());
    crx_installer_factory_ = std::make_unique<TestCrxInstallerFactory>();
    updater_ = std::make_unique<ExtensionUpdater>(profile());
    updater_->InitAndEnable(extension_prefs(), pref_service(), kUpdateFrequency,
                            nullptr, factory_->GetDownloaderFactory());
    updater_->set_crx_installer_factory_for_test(crx_installer_factory_.get());

    store_extension_ =
        ExtensionBuilder("store_extension")
            .SetManifestKey(
                "update_url",
                extension_urls::GetDefaultWebstoreUpdateUrl().spec())
            .Build();
    offstore_extension_ =
        ExtensionBuilder("offstore_extension")
            .SetManifestKey("update_url", "http://localhost/test/updates.xml")
            .Build();
    emptyurl_extension_ = ExtensionBuilder("emptyurl_extension").Build();
    userscript_extension_ =
        ExtensionBuilder("userscript_extension")
            .SetManifestKey("converted_from_user_script", true)
            .Build();

    ASSERT_TRUE(store_extension_.get());
    auto* registry = ExtensionRegistry::Get(profile());
    ASSERT_TRUE(registry->AddEnabled(store_extension_));
    ASSERT_TRUE(offstore_extension_.get());
    ASSERT_TRUE(registry->AddEnabled(offstore_extension_));
    ASSERT_TRUE(emptyurl_extension_.get());
    ASSERT_TRUE(registry->AddEnabled(emptyurl_extension_));
    ASSERT_TRUE(userscript_extension_.get());
    ASSERT_TRUE(registry->AddEnabled(userscript_extension_));
  }

  void TearDown() override {
    // Avoid dangling pointers.
    updater_->set_crx_installer_factory_for_test(nullptr);
    updater_.reset();
    crx_installer_factory_.reset();
    factory_.reset();
    ExtensionUpdaterTest::TearDown();
  }

 protected:
  ExtensionUpdater* updater() { return updater_.get(); }

  ExtensionUpdater::ScopedSkipScheduledCheckForTest skip_scheduled_checks_;
  ExtensionDownloaderTestHelper downloader_test_helper_;
  std::unique_ptr<TestDownloaderFactory> factory_;
  std::unique_ptr<TestCrxInstallerFactory> crx_installer_factory_;
  std::unique_ptr<ExtensionUpdater> updater_;

  scoped_refptr<const Extension> store_extension_;
  scoped_refptr<const Extension> offstore_extension_;
  scoped_refptr<const Extension> emptyurl_extension_;
  scoped_refptr<const Extension> userscript_extension_;
};

class UpdateServiceCanUpdateFeatureEnabledNonDefaultUpdateUrl
    : public CanUseUpdateServiceTest {
 public:
  void SetUp() override {
    CanUseUpdateServiceTest::SetUp();

    // Change the webstore update url.
    auto* command_line = base::CommandLine::ForCurrentProcess();
    // Note: |offstore_extension_|'s update url is the same.
    command_line->AppendSwitchASCII("apps-gallery-update-url",
                                    "http://localhost/test2/updates.xml");
    ExtensionsClient::Get()->InitializeWebStoreUrls(
        base::CommandLine::ForCurrentProcess());
  }
};

TEST_F(CanUseUpdateServiceTest, TestDefaults) {
  // Update service can only update webstore extensions when enabled.
  EXPECT_TRUE(CanUseUpdateService(updater(), store_extension_->id()));
  // ... and extensions with empty update URL.
  EXPECT_TRUE(CanUseUpdateService(updater(), emptyurl_extension_->id()));
  // It can't update off-store extensions.
  EXPECT_FALSE(CanUseUpdateService(updater(), offstore_extension_->id()));
  // ... or extensions with empty update URL converted from user script.
  EXPECT_FALSE(CanUseUpdateService(updater(), userscript_extension_->id()));
  // ... or extensions that don't exist.
  EXPECT_FALSE(CanUseUpdateService(updater(), std::string(32, 'a')));
  // ... or extensions with empty ID (is it possible?).
  EXPECT_FALSE(CanUseUpdateService(updater(), ""));
}

TEST_F(UpdateServiceCanUpdateFeatureEnabledNonDefaultUpdateUrl,
       CanUseUpdateServiceFeatureEnabledNonDefaultUpdateUrl) {
  // Update service can update extensions when the default webstore update url
  // is changed.
  EXPECT_FALSE(CanUseUpdateService(updater(), store_extension_->id()));
  EXPECT_TRUE(CanUseUpdateService(updater(), emptyurl_extension_->id()));
  EXPECT_FALSE(CanUseUpdateService(updater(), offstore_extension_->id()));
  EXPECT_FALSE(CanUseUpdateService(updater(), userscript_extension_->id()));
  EXPECT_FALSE(CanUseUpdateService(updater(), std::string(32, 'a')));
  EXPECT_FALSE(CanUseUpdateService(updater(), ""));
}

// TODO(asargent) - (http://crbug.com/12780) add tests for:
// -prodversionmin (shouldn't update if browser version too old)
// -manifests & updates arriving out of order / interleaved
// -malformed update url (empty, file://, has query, has a # fragment, etc.)
// -An extension gets uninstalled while updates are in progress (so it doesn't
//  "come back from the dead")
// -An extension gets manually updated to v3 while we're downloading v2 (ie
//  you don't get downgraded accidentally)
// -An update manifest mentions multiple updates

}  // namespace extensions
