chromium/chrome/browser/extensions/updater/extension_updater_unittest.cc

// 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.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

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

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

#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/ranges/algorithm.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/extension_sync_data.h"
#include "chrome/browser/extensions/fake_crx_installer.h"
#include "chrome/browser/extensions/mock_crx_installer.h"
#include "chrome/browser/extensions/test_extension_prefs.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/scoped_testing_local_state.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "components/crx_file/id_util.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/disable_reason.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/pref_names.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/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_ASH)
#include "base/files/scoped_temp_dir.h"
#include "chrome/browser/ash/login/users/chrome_user_manager_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 "components/user_manager/scoped_user_manager.h"
#endif

Time;
BrowserThread;
ManifestLocation;
_;
DoAll;
Invoke;
InvokeWithoutArgs;
Mock;
NiceMock;
Return;
SetArgPointee;
UpdateQueryParams;

namespace extensions {

Error;
PingResult;

namespace {

const net::BackoffEntry::Policy kNoBackoffPolicy =;

const char kAuthUserQueryKey[] =;

int kExpectedLoadFlags =;

int kExpectedLoadFlagsForDownloadWithCookies =;

// Fake authentication constants
const char kFakeOAuth2Token[] =;

// Extracts the integer value of the |authuser| query parameter. Returns 0 if
// the parameter is not set.
int GetAuthUserQueryValue(const GURL& url) {}

class MockUpdateService : public UpdateService {};

}  // namespace

// Base class for further specialized test classes.
class MockService : public TestExtensionService {};

bool ShouldInstallExtensionsOnly(const Extension* extension,
                                 content::BrowserContext* context) {}

bool ShouldInstallThemesOnly(const Extension* extension,
                             content::BrowserContext* context) {}

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

// Loads some pending extension records into a pending extension manager.
void SetupPendingExtensionManagerForTest(
    int count,
    const GURL& update_url,
    PendingExtensionManager* pending_extension_manager) {}

class ServiceForManifestTests : public MockService {};

class ServiceForDownloadTests : public MockService {};

static const int kUpdateFrequencySecs =;

// 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) {}

// 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")}}
ParamsMap;
static std::map<std::string, ParamsMap> GetPingDataFromURL(
    const GURL& manifest_url) {}

static void VerifyQueryAndExtractParameters(
    const std::string& query,
    std::map<std::string, std::string>* 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 {};

// 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) {}

TEST_F(ExtensionUpdaterTest, TestExtensionUpdateCheckRequestsPending) {}

TEST_F(ExtensionUpdaterTest, TestUpdateUrlData) {}

TEST_F(ExtensionUpdaterTest, TestInstallSource) {}

TEST_F(ExtensionUpdaterTest, TestInstallLocation) {}

TEST_F(ExtensionUpdaterTest, TestDetermineUpdates) {}

TEST_F(ExtensionUpdaterTest, TestDetermineUpdatesPending) {}

TEST_F(ExtensionUpdaterTest, TestDetermineUpdatesDuplicates) {}

TEST_F(ExtensionUpdaterTest, TestDetermineUpdatesError) {}

TEST_F(ExtensionUpdaterTest, TestMultipleManifestDownloading) {}

TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloading) {}

TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingPending) {}

TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingWithRetry) {}

TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingPendingWithRetry) {}

TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingFailure) {}

TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingFailureWithRetry) {}

TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingFailurePending) {}

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

TEST_F(ExtensionUpdaterTest, ProtectedDownloadCookieAuth) {}

TEST_F(ExtensionUpdaterTest, ProtectedDownloadCookieFailure) {}

TEST_F(ExtensionUpdaterTest, ProtectedDownloadWithNonDefaultAuthUser1) {}

TEST_F(ExtensionUpdaterTest, ProtectedDownloadWithNonDefaultAuthUser2) {}

TEST_F(ExtensionUpdaterTest, ProtectedDownloadAuthUserExhaustionFailure) {}

TEST_F(ExtensionUpdaterTest, ProtectedDownloadWithOAuth2Token) {}

TEST_F(ExtensionUpdaterTest, ProtectedDownloadWithOAuth2Failure) {}

TEST_F(ExtensionUpdaterTest, ProtectedDownloadNoOAuth2WithNonGoogleDomain) {}

TEST_F(ExtensionUpdaterTest, ProtectedDownloadFailWithoutHTTPS) {}

TEST_F(ExtensionUpdaterTest, TestMultipleExtensionDownloadingUpdatesFail) {}
TEST_F(ExtensionUpdaterTest, TestMultipleExtensionDownloadingUpdatesSucceed) {}

TEST_F(ExtensionUpdaterTest, TestManifestRetryDownloading) {}

TEST_F(ExtensionUpdaterTest, DISABLED_TestGalleryRequestsWithOrganicBrand) {}

TEST_F(ExtensionUpdaterTest, DISABLED_TestGalleryRequestsWithNonOrganicBrand) {}

TEST_F(ExtensionUpdaterTest, TestHandleManifestResults) {}

TEST_F(ExtensionUpdaterTest, TestNonAutoUpdateableLocations) {}

TEST_F(ExtensionUpdaterTest, TestUpdatingDisabledExtensions) {}

// crbug.com/1098540: Tests that removely disabled extensions that are part of
// the blocklisted extensions are still receive updates.
TEST_F(ExtensionUpdaterTest, TestUpdatingRemotelyDisabledExtensions) {}

TEST_F(ExtensionUpdaterTest, TestPendingInstall) {}

TEST_F(ExtensionUpdaterTest, TestManifestFetchesBuilderAddExtension) {}

TEST_F(ExtensionUpdaterTest, TestAddPendingExtensionWithVersion) {}

TEST_F(ExtensionUpdaterTest, TestStartUpdateCheckMemory) {}

TEST_F(ExtensionUpdaterTest, TestCheckSoon) {}

TEST_F(ExtensionUpdaterTest, TestUninstallWhileUpdateCheck) {}

TEST_F(ExtensionUpdaterTest, TestManifestFetchDataAddExtension) {}

TEST_F(ExtensionUpdaterTest, TestManifestFetchDataMerge) {}

TEST_F(ExtensionUpdaterTest, TestManifestFetchCredentials) {}

TEST_F(ExtensionUpdaterTest, TestManifestFetchPriority) {}

TEST_F(ExtensionUpdaterTest, TestExtensionPriority) {}

class CanUseUpdateServiceTest : public ExtensionUpdaterTest {};

class UpdateServiceCanUpdateFeatureEnabledNonDefaultUpdateUrl
    : public CanUseUpdateServiceTest {};

TEST_F(CanUseUpdateServiceTest, TestDefaults) {}

TEST_F(UpdateServiceCanUpdateFeatureEnabledNonDefaultUpdateUrl,
       CanUseUpdateServiceFeatureEnabledNonDefaultUpdateUrl) {}

// 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