chromium/chrome/browser/extensions/service_worker_registration_apitest.cc

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

#include <memory>
#include <string>

#include "base/files/file_path.h"
#include "base/memory/raw_ptr.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/test_future.h"
#include "base/time/time.h"
#include "base/values.h"
#include "chrome/browser/extensions/chrome_test_extension_loader.h"
#include "chrome/browser/extensions/crx_installer.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/webui_url_constants.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/service_worker_context.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "extensions/browser/background_script_executor.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_util.h"
#include "extensions/browser/process_manager.h"
#include "extensions/browser/script_executor.h"
#include "extensions/browser/script_result_queue.h"
#include "extensions/browser/service_worker/service_worker_task_queue.h"
#include "extensions/browser/service_worker/service_worker_test_utils.h"
#include "extensions/common/extension.h"
#include "extensions/common/manifest_handlers/background_info.h"
#include "extensions/common/mojom/manifest.mojom.h"
#include "extensions/test/extension_background_page_waiter.h"
#include "extensions/test/extension_test_message_listener.h"
#include "extensions/test/result_catcher.h"
#include "extensions/test/test_extension_dir.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

namespace extensions {

TestServiceWorkerTaskQueueObserver;

namespace {

constexpr char kNTPTestExtensionId[] =;

enum class BackgroundType {};

// Convenience method for checking true/false counts of boolean histograms.
void CheckBooleanHistogramCounts(const char* histogram_name,
                                 int true_count,
                                 int false_count,
                                 base::HistogramTester& histogram_tester) {}

// Convenience method for checking counts of blink::ServiceWorkerStatusCode
// emitting histograms.
void CheckStatusCodeHistogramCounts(const char* histogram_name,
                                    blink::ServiceWorkerStatusCode status,
                                    int count,
                                    base::HistogramTester& histogram_tester) {}

GURL new_tab_url() {}

// Allows test to wait for the attempt to register and unregister a worker to
// complete. It does not guarantee (un)registration attempt success.
class ExtensionRegistrationAndUnregistrationWaiter
    : public ServiceWorkerTaskQueue::TestObserver {};

}  // namespace

// Tests related to the registration state of extension background service
// workers.
class ServiceWorkerRegistrationApiTest : public ExtensionApiTest {};

// TODO(devlin): There's overlap with service_worker_apitest.cc in this file,
// and other tests in that file that should go here so that it's less
// monolithic.

// Tests that a service worker registration is properly stored after extension
// installation, both at the content layer and in the cached state in the
// extensions layer.
IN_PROC_BROWSER_TEST_F(ServiceWorkerRegistrationApiTest,
                       ServiceWorkerIsProperlyRegisteredAfterInstallation) {}

// Tests that updating an unpacked extension properly updates the extension's
// service worker.
IN_PROC_BROWSER_TEST_F(ServiceWorkerRegistrationApiTest,
                       UpdatingUnpackedExtensionUpdatesServiceWorker) {}

// Test what happens when installing/loading an extension, but then before the
// install (and worker registration) completes disable the extension (which
// tries to unregister the worker). Observes a failed registration and
// unregistration.
IN_PROC_BROWSER_TEST_F(ServiceWorkerRegistrationApiTest,
                       AttemptInstallAndImmediateDisable) {}

// Tests updating an extension and installing it immediately while it has an
// active new tab page override and a new tab is open.
// Regression test for https://crbug.com/1498035.
IN_PROC_BROWSER_TEST_F(ServiceWorkerRegistrationApiTest,
                       ImmediateUpdateWithNewTabPageOverrideActive) {}

// Tests that updating an unpacked extension properly updates the extension's
// service worker.
IN_PROC_BROWSER_TEST_F(ServiceWorkerRegistrationApiTest,
                       UpdatingPackedExtensionUpdatesServiceWorker) {}

// Tests that the service worker is properly unregistered when the extension is
// disabled or uninstalled.
// TODO(crbug.com/40268625): Flaky on multiple platforms.
IN_PROC_BROWSER_TEST_F(
    ServiceWorkerRegistrationApiTest,
    DISABLED_DisablingOrUninstallingAnExtensionUnregistersTheServiceWorker) {}

// Verifies that a service worker registration associated with an extension's
// manifest cannot be removed via the `chrome.browsingData` API.
// Regression test for https://crbug.com/1392498.
IN_PROC_BROWSER_TEST_F(ServiceWorkerRegistrationApiTest,
                       RegistrationCannotBeRemovedByBrowsingDataAPI) {}

// Tests that modifying local files for an unpacked extension does not result
// in the service worker being seen as "updated" (which would result in a
// "waiting" service worker, violating expectations in the extensions system).
// https://crbug.com/1271154.
IN_PROC_BROWSER_TEST_F(ServiceWorkerRegistrationApiTest,
                       ModifyingLocalFilesForUnpackedExtensions) {}

class ServiceWorkerExtensionUpdateOnBrowserRestartRegistrationApiTest
    : public ServiceWorkerRegistrationApiTest {};

// Tests that updating an extension that overrides the NTP updates successfully
// across browser restart when the updated is delayed until shutdown. This PRE_
// test installs v1, updates to v2, but v2 does not install since v1 is not
// idle. At the end of the test the browser shuts down with the v2 update as a
// delayed install.
IN_PROC_BROWSER_TEST_F(
    ServiceWorkerExtensionUpdateOnBrowserRestartRegistrationApiTest,
    PRE_NTPUpdateAcrossBrowserRestart) {}

// TODO(https://crbug.com/330066242): Flakes on chromeOS.
// ui_test_utils::NavigateToURL() causes: [focus_controller.cc(277)] Check
// failed: rules_->CanFocusWindow(window, nullptr).
#if BUILDFLAG(IS_CHROMEOS)
#define MAYBE_NTPUpdateAcrossBrowserRestart
#else
#define MAYBE_NTPUpdateAcrossBrowserRestart
#endif

// Continues the PRE_ test by testing that upon browser start v2 of the
// extension is installed.
IN_PROC_BROWSER_TEST_F(
    ServiceWorkerExtensionUpdateOnBrowserRestartRegistrationApiTest,
    MAYBE_NTPUpdateAcrossBrowserRestart) {}

// Registration and unregistration metrics tests.

// TODO(crbug.com/346732739): Add tests for extension updates from:
//   * non-sw background to sw background
//   * sw registered manually via web API to sw background
//   * sw background context to sw background context

class ServiceWorkerManifestVersionBrowserTest
    : public ExtensionBrowserTest,
      public testing::WithParamInterface<int> {};

ServiceWorkerRegistrationInstallMetricBrowserTest;

// Tests that installing an extension emits metrics for registering the service
// worker.
IN_PROC_BROWSER_TEST_P(ServiceWorkerRegistrationInstallMetricBrowserTest,
                       ExtensionInstall) {}

// Tracks when a worker is registered in the //content layer.
class ServiceWorkerTaskQueueRegistrationObserver
    : public ServiceWorkerTaskQueue::TestObserver {};

// Tests that uninstalling an extension emits metrics for unregistering the
// service worker.
IN_PROC_BROWSER_TEST_P(ServiceWorkerRegistrationInstallMetricBrowserTest,
                       ExtensionUninstall) {}

ServiceWorkerRegistrationRestartMetricBrowserTest;

// Tests that restarting an extension emits metrics for unregistering and
// registering the service worker.
//
// TODO(crbug.com/349683323): Fix flakiness
IN_PROC_BROWSER_TEST_P(ServiceWorkerRegistrationRestartMetricBrowserTest,
                       DISABLED_ExtensionRestart) {}

class MV2BackgroundsToMV3WorkerRegistrationMetricBrowserTest
    : public ServiceWorkerRegistrationApiTest,
      public testing::WithParamInterface<BackgroundType> {};

// Tests that MV2 extensions of all background types, when updated, emit the
// metrics for previous worker unregistration and new worker registration.
IN_PROC_BROWSER_TEST_P(MV2BackgroundsToMV3WorkerRegistrationMetricBrowserTest,
                       ExtensionUpdate) {}

class WorkerBackgroundToWorkerBackgroundRegistrationMetricTest
    : public ServiceWorkerRegistrationApiTest,
      public testing::WithParamInterface<std::pair<int, int>> {};

// Tests that extensions of either manifest type can update to a worker from a
// previous worker version and emit metrics for unregistering the previous
// worker and registering the new worker version.
IN_PROC_BROWSER_TEST_P(WorkerBackgroundToWorkerBackgroundRegistrationMetricTest,
                       ExtensionUpdate) {}

INSTANTIATE_TEST_SUITE_P();
INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();
INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

}  // namespace extensions