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

#include "content/browser/service_worker/service_worker_navigation_loader.h"

#include <string>
#include <utility>
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "content/browser/loader/navigation_loader_interceptor.h"
#include "content/browser/service_worker/embedded_worker_test_helper.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_test_utils.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/common/service_worker/service_worker_utils.h"
#include "content/common/single_request_url_loader_factory.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "mojo/public/cpp/system/data_pipe_utils.h"
#include "net/ssl/ssl_info.h"
#include "net/test/cert_test_util.h"
#include "net/test/test_data_directory.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/resource_response.h"
#include "services/network/public/mojom/fetch_api.mojom.h"
#include "services/network/test/test_url_loader_client.h"
#include "storage/browser/blob/blob_data_builder.h"
#include "storage/browser/blob/blob_data_handle.h"
#include "storage/browser/blob/blob_impl.h"
#include "storage/browser/blob/blob_storage_context.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/service_worker/service_worker.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"

namespace content {
namespace service_worker_navigation_loader_unittest {

void ReceiveRequestHandler(
    SingleRequestURLLoaderFactory::RequestHandler* out_handler,
    SingleRequestURLLoaderFactory::RequestHandler handler) {
  *out_handler = std::move(handler);
}

blink::mojom::FetchAPIResponsePtr OkResponse(
    blink::mojom::SerializedBlobPtr blob_body) {
  auto response = blink::mojom::FetchAPIResponse::New();
  response->status_code = 200;
  response->status_text = "OK";
  response->response_type = network::mojom::FetchResponseType::kDefault;
  response->blob = std::move(blob_body);
  if (response->blob) {
    response->headers.emplace("Content-Length",
                              base::NumberToString(response->blob->size));
  }
  return response;
}

blink::mojom::FetchAPIResponsePtr ErrorResponse() {
  auto response = blink::mojom::FetchAPIResponse::New();
  response->status_code = 0;
  response->response_type = network::mojom::FetchResponseType::kDefault;
  response->error = blink::mojom::ServiceWorkerResponseError::kPromiseRejected;
  return response;
}

blink::mojom::FetchAPIResponsePtr RedirectResponse(
    const std::string& redirect_location_header) {
  auto response = blink::mojom::FetchAPIResponse::New();
  response->status_code = 301;
  response->status_text = "Moved Permanently";
  response->response_type = network::mojom::FetchResponseType::kDefault;
  response->headers["Location"] = redirect_location_header;
  return response;
}

// NavigationPreloadLoaderClient mocks the renderer-side URLLoaderClient for the
// navigation preload network request performed by the browser. In production
// code, this is ServiceWorkerContextClient::NavigationPreloadRequest,
// which it forwards the response to FetchEvent#preloadResponse. Here, it
// simulates passing the response to FetchEvent#respondWith.
//
// The navigation preload test is quite involved. The flow of data is:
// 1. ServiceWorkerNavigationLoader asks ServiceWorkerFetchDispatcher to start
//    navigation preload.
// 2. ServiceWorkerFetchDispatcher starts the network request which is mocked
//    by EmbeddedWorkerTestHelper's default network loader factory. The
//    response is sent to
//    ServiceWorkerFetchDispatcher::DelegatingURLLoaderClient.
// 3. DelegatingURLLoaderClient sends the response to the |preload_handle|
//    that was passed to Helper::OnFetchEvent().
// 4. Helper::OnFetchEvent() creates NavigationPreloadLoaderClient, which
//    receives the response.
// 5. NavigationPreloadLoaderClient calls OnFetchEvent()'s callbacks
//    with the response.
// 6. Like all FetchEvent responses, the response is sent to
//    ServiceWorkerNavigationLoader::DidDispatchFetchEvent, and the
//    RequestHandler is returned.
class NavigationPreloadLoaderClient final
    : public network::mojom::URLLoaderClient {
 public:
  NavigationPreloadLoaderClient(
      blink::mojom::FetchEventPreloadHandlePtr preload_handle,
      blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
      blink::mojom::ServiceWorker::DispatchFetchEventCallback finish_callback)
      : url_loader_(std::move(preload_handle->url_loader)),
        binding_(this, std::move(preload_handle->url_loader_client_request)),
        response_callback_(std::move(response_callback)),
        finish_callback_(std::move(finish_callback)) {
    binding_.set_connection_error_handler(
        base::BindOnce(&NavigationPreloadLoaderClient::OnConnectionError,
                       base::Unretained(this)));
  }
  ~NavigationPreloadLoaderClient() override = default;

  // network::mojom::URLLoaderClient implementation
  void OnReceiveResponse(
      const network::ResourceResponseHead& response_head) override {
    response_head_ = response_head;
  }
  void OnStartLoadingResponseBody(
      mojo::ScopedDataPipeConsumerHandle body) override {
    body_ = std::move(body);
    // We could call OnResponseStream() here, but for simplicity, don't do
    // anything until OnComplete().
  }
  void OnComplete(const network::URLLoaderCompletionStatus& status) override {
    blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
    auto stream_handle = blink::mojom::ServiceWorkerStreamHandle::New();
    stream_handle->callback_request = mojo::MakeRequest(&stream_callback);
    stream_handle->stream = std::move(body_);

    // Simulate passing the navigation preload response to
    // FetchEvent#respondWith.
    auto response = blink::mojom::FetchAPIResponse::New();
    response->url_list =
        std::vector<GURL>(response_head_.url_list_via_service_worker);
    response->status_code = response_head_.headers->response_code();
    response->status_text = response_head_.headers->GetStatusText();
    response->response_type = response_head_.response_type;
    response_callback_->OnResponseStream(
        std::move(response), std::move(stream_handle),
        blink::mojom::ServiceWorkerFetchEventTiming::New());
    std::move(finish_callback_)
        .Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED);
    stream_callback->OnCompleted();
    delete this;
  }
  void OnReceiveRedirect(
      const net::RedirectInfo& redirect_info,
      const network::ResourceResponseHead& response_head) override {}
  void OnUploadProgress(int64_t current_position,
                        int64_t total_size,
                        OnUploadProgressCallback ack_callback) override {}
  void OnReceiveCachedMetadata(const std::vector<uint8_t>& data) override {}
  void OnTransferSizeUpdated(int32_t transfer_size_diff) override {}

  void OnConnectionError() { delete this; }

 private:
  network::mojom::URLLoaderPtr url_loader_;
  mojo::Binding<network::mojom::URLLoaderClient> binding_;

  network::ResourceResponseHead response_head_;
  mojo::ScopedDataPipeConsumerHandle body_;

  // Callbacks that complete Helper::OnFetchEvent().
  blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback_;
  blink::mojom::ServiceWorker::DispatchFetchEventCallback finish_callback_;

  DISALLOW_COPY_AND_ASSIGN(NavigationPreloadLoaderClient);
};

// Helper simulates a service worker handling fetch events. The response can be
// customized via RespondWith* functions.
class Helper : public EmbeddedWorkerTestHelper {
 public:
  Helper() : EmbeddedWorkerTestHelper(base::FilePath()) {}
  ~Helper() override = default;

  // Tells this helper to respond to fetch events with the specified blob.
  void RespondWithBlob(blink::mojom::SerializedBlobPtr blob) {
    response_mode_ = ResponseMode::kBlob;
    blob_body_ = std::move(blob);
  }

  // Tells this helper to respond to fetch events with the specified stream.
  void RespondWithStream(
      blink::mojom::ServiceWorkerStreamCallbackRequest callback_request,
      mojo::ScopedDataPipeConsumerHandle consumer_handle) {
    response_mode_ = ResponseMode::kStream;
    stream_handle_ = blink::mojom::ServiceWorkerStreamHandle::New();
    stream_handle_->callback_request = std::move(callback_request);
    stream_handle_->stream = std::move(consumer_handle);
  }

  // Tells this helper to respond to fetch events with network fallback.
  // i.e., simulate the service worker not calling respondWith().
  void RespondWithFallback() {
    response_mode_ = ResponseMode::kFallbackResponse;
  }

  // Tells this helper to respond to fetch events with an error response.
  void RespondWithError() { response_mode_ = ResponseMode::kErrorResponse; }

  // Tells this helper to respond to fetch events with
  // FetchEvent#preloadResponse. See NavigationPreloadLoaderClient's
  // documentation for details.
  void RespondWithNavigationPreloadResponse() {
    response_mode_ = ResponseMode::kNavigationPreloadResponse;
  }

  // Tells this helper to respond to fetch events with the redirect response.
  void RespondWithRedirectResponse(const GURL& new_url) {
    response_mode_ = ResponseMode::kRedirect;
    redirected_url_ = new_url;
  }

  // Tells this helper to simulate failure to dispatch the fetch event to the
  // service worker.
  void FailToDispatchFetchEvent() {
    response_mode_ = ResponseMode::kFailFetchEventDispatch;
  }

  // Tells this helper to simulate "early response", where the respondWith()
  // promise resolves before the waitUntil() promise. In this mode, the
  // helper sets the response mode to "early response", which simulates the
  // promise passed to respondWith() resolving before the waitUntil() promise
  // resolves. In this mode, the helper will respond to fetch events
  // immediately, but will not finish the fetch event until FinishWaitUntil() is
  // called.
  void RespondEarly() { response_mode_ = ResponseMode::kEarlyResponse; }
  void FinishWaitUntil() {
    std::move(finish_callback_)
        .Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED);
    base::RunLoop().RunUntilIdle();
  }

  // Tells this helper to wait for FinishRespondWith() to be called before
  // providing the response to the fetch event.
  void DeferResponse() { response_mode_ = ResponseMode::kDeferredResponse; }
  void FinishRespondWith() {
    response_callback_->OnResponse(
        OkResponse(nullptr /* blob_body */),
        blink::mojom::ServiceWorkerFetchEventTiming::New());
    response_callback_.FlushForTesting();
    std::move(finish_callback_)
        .Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED);
  }

  void ReadRequestBody(std::string* out_string) {
    ASSERT_TRUE(request_body_);
    const std::vector<network::DataElement>* elements =
        request_body_->elements();
    // So far this test expects a single bytes element.
    ASSERT_EQ(1u, elements->size());
    const network::DataElement& element = elements->front();
    ASSERT_EQ(network::DataElement::TYPE_BYTES, element.type());
    *out_string = std::string(element.bytes(), element.length());
  }

  void RunUntilFetchEvent() {
    if (has_received_fetch_event_)
      return;
    base::RunLoop run_loop;
    quit_closure_for_fetch_event_ = run_loop.QuitClosure();
    run_loop.Run();
  }

 protected:
  void OnFetchEvent(
      int embedded_worker_id,
      blink::mojom::FetchAPIRequestPtr request,
      blink::mojom::FetchEventPreloadHandlePtr preload_handle,
      blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
      blink::mojom::ServiceWorker::DispatchFetchEventCallback finish_callback)
      override {
    // Basic checks on DispatchFetchEvent parameters.
    EXPECT_TRUE(request->is_main_resource_load);

    has_received_fetch_event_ = true;
    if (request->body)
      request_body_ = request->body.value();

    switch (response_mode_) {
      case ResponseMode::kDefault:
        EmbeddedWorkerTestHelper::OnFetchEvent(
            embedded_worker_id, std::move(request), std::move(preload_handle),
            std::move(response_callback), std::move(finish_callback));
        break;
      case ResponseMode::kBlob:
        response_callback->OnResponse(
            OkResponse(std::move(blob_body_)),
            blink::mojom::ServiceWorkerFetchEventTiming::New());
        std::move(finish_callback)
            .Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED);
        break;
      case ResponseMode::kStream:
        response_callback->OnResponseStream(
            OkResponse(nullptr /* blob_body */), std::move(stream_handle_),
            blink::mojom::ServiceWorkerFetchEventTiming::New());
        std::move(finish_callback)
            .Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED);
        break;
      case ResponseMode::kFallbackResponse:
        response_callback->OnFallback(
            blink::mojom::ServiceWorkerFetchEventTiming::New());
        std::move(finish_callback)
            .Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED);
        break;
      case ResponseMode::kErrorResponse:
        response_callback->OnResponse(
            ErrorResponse(),
            blink::mojom::ServiceWorkerFetchEventTiming::New());
        std::move(finish_callback)
            .Run(blink::mojom::ServiceWorkerEventStatus::REJECTED);
        break;
      case ResponseMode::kNavigationPreloadResponse:
        // Deletes itself when done.
        new NavigationPreloadLoaderClient(std::move(preload_handle),
                                          std::move(response_callback),
                                          std::move(finish_callback));
        break;
      case ResponseMode::kFailFetchEventDispatch:
        // Simulate failure by stopping the worker before the event finishes.
        // This causes ServiceWorkerVersion::StartRequest() to call its error
        // callback, which triggers ServiceWorkerNavigationLoader's dispatch
        // failed behavior.
        SimulateWorkerStopped(embedded_worker_id);
        // Finish the event by calling |finish_callback|.
        // This is the Mojo callback for
        // blink::mojom::ServiceWorker::DispatchFetchEvent().
        // If this is not called, Mojo will complain. In production code,
        // ServiceWorkerContextClient would call this when it aborts all
        // callbacks after an unexpected stop.
        std::move(finish_callback)
            .Run(blink::mojom::ServiceWorkerEventStatus::ABORTED);
        break;
      case ResponseMode::kDeferredResponse:
        finish_callback_ = std::move(finish_callback);
        response_callback_ = std::move(response_callback);
        // Now the caller must call FinishRespondWith() to finish the event.
        break;
      case ResponseMode::kEarlyResponse:
        finish_callback_ = std::move(finish_callback);
        response_callback->OnResponse(
            OkResponse(nullptr /* blob_body */),
            blink::mojom::ServiceWorkerFetchEventTiming::New());
        // Now the caller must call FinishWaitUntil() to finish the event.
        break;
      case ResponseMode::kRedirect:
        response_callback->OnResponse(
            RedirectResponse(redirected_url_.spec()),
            blink::mojom::ServiceWorkerFetchEventTiming::New());
        std::move(finish_callback)
            .Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED);
        break;
    }

    if (quit_closure_for_fetch_event_)
      std::move(quit_closure_for_fetch_event_).Run();
  }

 private:
  enum class ResponseMode {
    kDefault,
    kBlob,
    kStream,
    kFallbackResponse,
    kErrorResponse,
    kNavigationPreloadResponse,
    kFailFetchEventDispatch,
    kDeferredResponse,
    kEarlyResponse,
    kRedirect
  };

  ResponseMode response_mode_ = ResponseMode::kDefault;
  scoped_refptr<network::ResourceRequestBody> request_body_;

  // For ResponseMode::kBlob.
  blink::mojom::SerializedBlobPtr blob_body_;

  // For ResponseMode::kStream.
  blink::mojom::ServiceWorkerStreamHandlePtr stream_handle_;

  // For ResponseMode::kEarlyResponse and kDeferredResponse.
  blink::mojom::ServiceWorker::DispatchFetchEventCallback finish_callback_;
  blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback_;

  // For ResponseMode::kRedirect.
  GURL redirected_url_;

  bool has_received_fetch_event_ = false;
  base::OnceClosure quit_closure_for_fetch_event_;

  DISALLOW_COPY_AND_ASSIGN(Helper);
};

// Returns typical response info for a resource load that went through a service
// worker.
std::unique_ptr<network::ResourceResponseHead>
CreateResponseInfoFromServiceWorker() {
  auto head = std::make_unique<network::ResourceResponseHead>();
  head->was_fetched_via_service_worker = true;
  head->was_fallback_required_by_service_worker = false;
  head->url_list_via_service_worker = std::vector<GURL>();
  head->response_type = network::mojom::FetchResponseType::kDefault;
  head->is_in_cache_storage = false;
  head->cache_storage_cache_name = std::string();
  head->did_service_worker_navigation_preload = false;
  return head;
}

const char kHistogramMainResourceFetchEvent[] =
    "ServiceWorker.FetchEvent.MainResource.Status";

// ServiceWorkerNavigationLoaderTest is for testing the handling of requests
// by a service worker via ServiceWorkerNavigationLoader.
//
// Of course, no actual service worker runs in the unit test, it is simulated
// via EmbeddedWorkerTestHelper receiving IPC messages from the browser and
// responding as if a service worker is running in the renderer.
//
// ServiceWorkerNavigationLoaderTest is also a
// ServiceWorkerNavigationLoader::Delegate. In production code,
// ServiceWorkerControlleeRequestHandler is the Delegate. So this class also
// basically mocks that part of ServiceWorkerControlleeRequestHandler.
class ServiceWorkerNavigationLoaderTest
    : public testing::Test,
      public ServiceWorkerNavigationLoader::Delegate {
 public:
  ServiceWorkerNavigationLoaderTest()
      : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
  ~ServiceWorkerNavigationLoaderTest() override = default;

  void SetUp() override {
    feature_list_.InitAndEnableFeature(network::features::kNetworkService);
    helper_ = std::make_unique<Helper>();

    // Create an active service worker.
    storage()->LazyInitializeForTest(base::DoNothing());
    base::RunLoop().RunUntilIdle();
    blink::mojom::ServiceWorkerRegistrationOptions options;
    options.scope = GURL("https://example.com/");
    registration_ =
        new ServiceWorkerRegistration(options, storage()->NewRegistrationId(),
                                      helper_->context()->AsWeakPtr());
    version_ = new ServiceWorkerVersion(
        registration_.get(), GURL("https://example.com/service_worker.js"),
        blink::mojom::ScriptType::kClassic, storage()->NewVersionId(),
        helper_->context()->AsWeakPtr());
    std::vector<ServiceWorkerDatabase::ResourceRecord> records;
    records.push_back(WriteToDiskCacheSync(
        storage(), version_->script_url(), storage()->NewResourceId(),
        {} /* headers */, "I'm the body", "I'm the meta data"));
    version_->script_cache_map()->SetResources(records);
    version_->set_fetch_handler_existence(
        ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
    version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
    registration_->SetActiveVersion(version_);

    // Make the registration findable via storage functions.
    registration_->set_last_update_check(base::Time::Now());
    base::Optional<blink::ServiceWorkerStatusCode> status;
    storage()->StoreRegistration(registration_.get(), version_.get(),
                                 CreateReceiverOnCurrentThread(&status));
    base::RunLoop().RunUntilIdle();
    ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
  }

  ServiceWorkerStorage* storage() { return helper_->context()->storage(); }

  // Indicates whether ServiceWorkerNavigationLoader decided to handle a
  // request, i.e., it returned a non-null RequestHandler for the request.
  enum class LoaderResult {
    kHandledRequest,
    kDidNotHandleRequest,
  };

  // Starts a request. Returns whether ServiceWorkerNavigationLoader handled the
  // request. If kHandledRequest was returned, the request is ongoing and the
  // caller can use functions like client_.RunUntilComplete() to wait for
  // completion.
  LoaderResult StartRequest(std::unique_ptr<network::ResourceRequest> request) {
    provider_host_ = CreateProviderHostForWindow(
        -1 /* process_id */, -2 /* provider_id */,
        true /* is_parent_frame_secure */, helper_->context()->AsWeakPtr(),
        &provider_endpoints_);
    // Start a ServiceWorkerNavigationLoader. It should return a
    // RequestHandler.
    SingleRequestURLLoaderFactory::RequestHandler handler;
    loader_ = std::make_unique<ServiceWorkerNavigationLoader>(
        base::BindOnce(&ReceiveRequestHandler, &handler),
        base::BindOnce(&ServiceWorkerNavigationLoaderTest::Fallback,
                       base::Unretained(this)),
        this, *request, provider_host_->AsWeakPtr(),
        base::WrapRefCounted<URLLoaderFactoryGetter>(
            helper_->context()->loader_factory_getter()));
    loader_->ForwardToServiceWorker();
    base::RunLoop().RunUntilIdle();
    if (!handler)
      return LoaderResult::kDidNotHandleRequest;

    // Run the handler. It will load |request.url|.
    std::move(handler).Run(*request, mojo::MakeRequest(&loader_ptr_),
                           client_.CreateInterfacePtr());

    return LoaderResult::kHandledRequest;
  }

  // The |fallback_callback| passed to the ServiceWorkerNavigationLoader in
  // StartRequest().
  void Fallback(bool reset_subresource_loader_params) {
    did_call_fallback_callback_ = true;
    reset_subresource_loader_params_ = reset_subresource_loader_params;
    if (quit_closure_for_fallback_callback_)
      std::move(quit_closure_for_fallback_callback_).Run();
  }

  // Runs until the ServiceWorkerNavigationLoader created in StartRequest()
  // calls the |fallback_callback| given to it. The argument passed to
  // |fallback_callback| is saved in |reset_subresurce_loader_params_|.
  void RunUntilFallbackCallback() {
    if (did_call_fallback_callback_)
      return;
    base::RunLoop run_loop;
    quit_closure_for_fallback_callback_ = run_loop.QuitClosure();
    run_loop.Run();
  }

  void ExpectResponseInfo(const network::ResourceResponseHead& info,
                          const network::ResourceResponseHead& expected_info) {
    EXPECT_EQ(expected_info.was_fetched_via_service_worker,
              info.was_fetched_via_service_worker);
    EXPECT_EQ(expected_info.was_fallback_required_by_service_worker,
              info.was_fallback_required_by_service_worker);
    EXPECT_EQ(expected_info.url_list_via_service_worker,
              info.url_list_via_service_worker);
    EXPECT_EQ(expected_info.response_type, info.response_type);
    EXPECT_FALSE(info.service_worker_start_time.is_null());
    EXPECT_FALSE(info.service_worker_ready_time.is_null());
    EXPECT_LT(info.service_worker_start_time, info.service_worker_ready_time);
    EXPECT_EQ(expected_info.is_in_cache_storage, info.is_in_cache_storage);
    EXPECT_EQ(expected_info.cache_storage_cache_name,
              info.cache_storage_cache_name);
    EXPECT_EQ(expected_info.did_service_worker_navigation_preload,
              info.did_service_worker_navigation_preload);
  }

  std::unique_ptr<network::ResourceRequest> CreateRequest() {
    std::unique_ptr<network::ResourceRequest> request =
        std::make_unique<network::ResourceRequest>();
    request->url = GURL("https://www.example.com/");
    request->method = "GET";
    request->fetch_request_mode = network::mojom::FetchRequestMode::kNavigate;
    request->fetch_credentials_mode =
        network::mojom::FetchCredentialsMode::kInclude;
    request->fetch_redirect_mode = network::mojom::FetchRedirectMode::kManual;
    return request;
  }

 protected:
  // ServiceWorkerNavigationLoader::Delegate -----------------------------------
  void OnPrepareToRestart() override {}

  ServiceWorkerVersion* GetServiceWorkerVersion(
      ServiceWorkerMetrics::URLRequestJobResult* result) override {
    return version_.get();
  }

  bool RequestStillValid(
      ServiceWorkerMetrics::URLRequestJobResult* result) override {
    return true;
  }

  void MainResourceLoadFailed() override {
    was_main_resource_load_failed_called_ = true;
  }

  bool HasWorkInBrowser(ServiceWorkerVersion* version) const {
    return version->HasWorkInBrowser();
  }
  // --------------------------------------------------------------------------

  TestBrowserThreadBundle thread_bundle_;
  std::unique_ptr<Helper> helper_;
  scoped_refptr<ServiceWorkerRegistration> registration_;
  scoped_refptr<ServiceWorkerVersion> version_;
  storage::BlobStorageContext blob_context_;
  network::TestURLLoaderClient client_;
  bool was_main_resource_load_failed_called_ = false;
  std::unique_ptr<ServiceWorkerNavigationLoader> loader_;
  network::mojom::URLLoaderPtr loader_ptr_;
  std::unique_ptr<ServiceWorkerProviderHost> provider_host_;
  ServiceWorkerRemoteProviderEndpoint provider_endpoints_;

  bool did_call_fallback_callback_ = false;
  bool reset_subresource_loader_params_ = false;
  base::OnceClosure quit_closure_for_fallback_callback_;

  base::test::ScopedFeatureList feature_list_;
};

TEST_F(ServiceWorkerNavigationLoaderTest, Basic) {
  base::HistogramTester histogram_tester;

  // Perform the request
  LoaderResult result = StartRequest(CreateRequest());
  EXPECT_EQ(LoaderResult::kHandledRequest, result);
  client_.RunUntilComplete();

  EXPECT_EQ(net::OK, client_.completion_status().error_code);
  const network::ResourceResponseHead& info = client_.response_head();
  EXPECT_EQ(200, info.headers->response_code());
  EXPECT_FALSE(info.load_timing.receive_headers_start.is_null());
  EXPECT_FALSE(info.load_timing.receive_headers_end.is_null());
  EXPECT_LE(info.load_timing.receive_headers_start,
            info.load_timing.receive_headers_end);
  ExpectResponseInfo(info, *CreateResponseInfoFromServiceWorker());

  histogram_tester.ExpectUniqueSample(kHistogramMainResourceFetchEvent,
                                      blink::ServiceWorkerStatusCode::kOk, 1);
  histogram_tester.ExpectTotalCount(
      "ServiceWorker.LoadTiming.MainFrame.MainResource."
      "ResponseReceivedToCompleted2",
      1);
}

TEST_F(ServiceWorkerNavigationLoaderTest, NoActiveWorker) {
  base::HistogramTester histogram_tester;

  // Clear |version_| to make GetServiceWorkerVersion() return null.
  version_ = nullptr;

  // Perform the request.
  LoaderResult result = StartRequest(CreateRequest());
  EXPECT_EQ(LoaderResult::kHandledRequest, result);

  client_.RunUntilComplete();
  EXPECT_EQ(net::ERR_FAILED, client_.completion_status().error_code);

  // No fetch event was dispatched.
  histogram_tester.ExpectTotalCount(kHistogramMainResourceFetchEvent, 0);
  histogram_tester.ExpectTotalCount(
      "ServiceWorker.LoadTiming.MainFrame.MainResource."
      "StartToForwardServiceWorker",
      0);
}

// Test that the request body is passed to the fetch event.
TEST_F(ServiceWorkerNavigationLoaderTest, RequestBody) {
  const std::string kData = "hi this is the request body";

  // Create a request with a body.
  auto request_body = base::MakeRefCounted<network::ResourceRequestBody>();
  request_body->AppendBytes(kData.c_str(), kData.length());
  std::unique_ptr<network::ResourceRequest> request = CreateRequest();
  request->method = "POST";
  request->request_body = request_body;

  // This test doesn't use the response to the fetch event, so just have the
  // service worker do the default simple response.
  StartRequest(std::move(request));
  client_.RunUntilComplete();

  // Verify that the request body was passed to the fetch event.
  std::string body;
  helper_->ReadRequestBody(&body);
  EXPECT_EQ(kData, body);
}

TEST_F(ServiceWorkerNavigationLoaderTest, BlobResponse) {
  base::HistogramTester histogram_tester;

  // Construct the blob to respond with.
  const std::string kResponseBody = "Here is sample text for the blob.";
  auto blob_data = std::make_unique<storage::BlobDataBuilder>("blob-id:myblob");
  blob_data->AppendData(kResponseBody);
  std::unique_ptr<storage::BlobDataHandle> blob_handle =
      blob_context_.AddFinishedBlob(std::move(blob_data));

  auto blob = blink::mojom::SerializedBlob::New();
  blob->uuid = blob_handle->uuid();
  blob->size = blob_handle->size();
  blink::mojom::BlobRequest request = mojo::MakeRequest(&blob->blob);
  storage::BlobImpl::Create(std::move(blob_handle), std::move(request));
  helper_->RespondWithBlob(std::move(blob));

  // Perform the request.
  LoaderResult result = StartRequest(CreateRequest());
  EXPECT_EQ(LoaderResult::kHandledRequest, result);
  client_.RunUntilComplete();

  const network::ResourceResponseHead& info = client_.response_head();
  EXPECT_EQ(200, info.headers->response_code());
  ExpectResponseInfo(info, *CreateResponseInfoFromServiceWorker());
  EXPECT_EQ(33, info.content_length);

  // Test the body.
  std::string body;
  EXPECT_TRUE(client_.response_body().is_valid());
  EXPECT_TRUE(
      mojo::BlockingCopyToString(client_.response_body_release(), &body));
  EXPECT_EQ(kResponseBody, body);
  EXPECT_EQ(net::OK, client_.completion_status().error_code);

  // Test histogram of reading body.
  histogram_tester.ExpectTotalCount(
      "ServiceWorker.LoadTiming.MainFrame.MainResource."
      "ResponseReceivedToCompleted2",
      1);
}

// Tell the helper to respond with a non-existent Blob.
TEST_F(ServiceWorkerNavigationLoaderTest, BrokenBlobResponse) {
  base::HistogramTester histogram_tester;

  const std::string kBrokenUUID = "broken_uuid";

  // Create the broken blob.
  std::unique_ptr<storage::BlobDataHandle> blob_handle =
      blob_context_.AddBrokenBlob(kBrokenUUID, "", "",
                                  storage::BlobStatus::ERR_OUT_OF_MEMORY);
  auto blob = blink::mojom::SerializedBlob::New();
  blob->uuid = kBrokenUUID;
  blink::mojom::BlobRequest request = mojo::MakeRequest(&blob->blob);
  storage::BlobImpl::Create(std::move(blob_handle), std::move(request));
  helper_->RespondWithBlob(std::move(blob));

  // Perform the request.
  LoaderResult result = StartRequest(CreateRequest());
  EXPECT_EQ(LoaderResult::kHandledRequest, result);

  // We should get a valid response once the headers arrive.
  client_.RunUntilResponseReceived();
  const network::ResourceResponseHead& info = client_.response_head();
  EXPECT_EQ(200, info.headers->response_code());
  ExpectResponseInfo(info, *CreateResponseInfoFromServiceWorker());

  // However, since the blob is broken we should get an error while transferring
  // the body.
  client_.RunUntilComplete();
  EXPECT_EQ(net::ERR_OUT_OF_MEMORY, client_.completion_status().error_code);

  // Timing histograms shouldn't be recorded on broken response.
  histogram_tester.ExpectTotalCount(
      "ServiceWorker.LoadTiming.MainFrame.MainResource."
      "StartToForwardServiceWorker",
      0);
  histogram_tester.ExpectTotalCount(
      "ServiceWorker.LoadTiming.MainFrame.MainResource."
      "ResponseReceivedToCompleted2",
      0);
}

TEST_F(ServiceWorkerNavigationLoaderTest, StreamResponse) {
  base::HistogramTester histogram_tester;

  // Construct the Stream to respond with.
  const char kResponseBody[] = "Here is sample text for the Stream.";
  blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
  mojo::DataPipe data_pipe;
  helper_->RespondWithStream(mojo::MakeRequest(&stream_callback),
                             std::move(data_pipe.consumer_handle));

  // Perform the request.
  LoaderResult result = StartRequest(CreateRequest());
  EXPECT_EQ(LoaderResult::kHandledRequest, result);
  client_.RunUntilResponseReceived();

  const network::ResourceResponseHead& info = client_.response_head();
  EXPECT_EQ(200, info.headers->response_code());
  ExpectResponseInfo(info, *CreateResponseInfoFromServiceWorker());

  EXPECT_FALSE(version_->HasNoWork());

  // Write the body stream.
  uint32_t written_bytes = sizeof(kResponseBody) - 1;
  MojoResult mojo_result = data_pipe.producer_handle->WriteData(
      kResponseBody, &written_bytes, MOJO_WRITE_DATA_FLAG_NONE);
  ASSERT_EQ(MOJO_RESULT_OK, mojo_result);
  EXPECT_EQ(sizeof(kResponseBody) - 1, written_bytes);
  stream_callback->OnCompleted();
  data_pipe.producer_handle.reset();

  client_.RunUntilComplete();
  EXPECT_EQ(net::OK, client_.completion_status().error_code);

  // Test the body.
  std::string response;
  EXPECT_TRUE(client_.response_body().is_valid());
  EXPECT_TRUE(
      mojo::BlockingCopyToString(client_.response_body_release(), &response));
  EXPECT_EQ(kResponseBody, response);

  // Test histogram of reading body.
  histogram_tester.ExpectTotalCount(
      "ServiceWorker.LoadTiming.MainFrame.MainResource."
      "ResponseReceivedToCompleted2",
      1);
}

// Test when a stream response body is aborted.
TEST_F(ServiceWorkerNavigationLoaderTest, StreamResponse_Abort) {
  base::HistogramTester histogram_tester;

  // Construct the Stream to respond with.
  const char kResponseBody[] = "Here is sample text for the Stream.";
  blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
  mojo::DataPipe data_pipe;
  helper_->RespondWithStream(mojo::MakeRequest(&stream_callback),
                             std::move(data_pipe.consumer_handle));

  // Perform the request.
  LoaderResult result = StartRequest(CreateRequest());
  EXPECT_EQ(LoaderResult::kHandledRequest, result);
  client_.RunUntilResponseReceived();

  const network::ResourceResponseHead& info = client_.response_head();
  EXPECT_EQ(200, info.headers->response_code());
  ExpectResponseInfo(info, *CreateResponseInfoFromServiceWorker());

  // Start writing the body stream, then abort before finishing.
  uint32_t written_bytes = sizeof(kResponseBody) - 1;
  MojoResult mojo_result = data_pipe.producer_handle->WriteData(
      kResponseBody, &written_bytes, MOJO_WRITE_DATA_FLAG_NONE);
  ASSERT_EQ(MOJO_RESULT_OK, mojo_result);
  EXPECT_EQ(sizeof(kResponseBody) - 1, written_bytes);
  stream_callback->OnAborted();
  data_pipe.producer_handle.reset();

  client_.RunUntilComplete();
  EXPECT_EQ(net::ERR_ABORTED, client_.completion_status().error_code);

  // Test the body.
  std::string response;
  EXPECT_TRUE(client_.response_body().is_valid());
  EXPECT_TRUE(
      mojo::BlockingCopyToString(client_.response_body_release(), &response));
  EXPECT_EQ(kResponseBody, response);

  // Timing histograms shouldn't be recorded on abort.
  histogram_tester.ExpectTotalCount(
      "ServiceWorker.LoadTiming.MainFrame.MainResource."
      "StartToForwardServiceWorker",
      0);
  histogram_tester.ExpectTotalCount(
      "ServiceWorker.LoadTiming.MainFrame.MainResource."
      "ResponseReceivedToCompleted2",
      0);
}

// Test when the loader is cancelled while a stream response is being written.
TEST_F(ServiceWorkerNavigationLoaderTest, StreamResponseAndCancel) {
  base::HistogramTester histogram_tester;

  // Construct the Stream to respond with.
  const char kResponseBody[] = "Here is sample text for the Stream.";
  blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
  mojo::DataPipe data_pipe;
  helper_->RespondWithStream(mojo::MakeRequest(&stream_callback),
                             std::move(data_pipe.consumer_handle));

  // Perform the request.
  LoaderResult result = StartRequest(CreateRequest());
  EXPECT_EQ(LoaderResult::kHandledRequest, result);
  client_.RunUntilResponseReceived();

  const network::ResourceResponseHead& info = client_.response_head();
  EXPECT_EQ(200, info.headers->response_code());
  ExpectResponseInfo(info, *CreateResponseInfoFromServiceWorker());

  // Start writing the body stream, then break the Mojo connection to the loader
  // before finishing.
  uint32_t written_bytes = sizeof(kResponseBody) - 1;
  MojoResult mojo_result = data_pipe.producer_handle->WriteData(
      kResponseBody, &written_bytes, MOJO_WRITE_DATA_FLAG_NONE);
  ASSERT_EQ(MOJO_RESULT_OK, mojo_result);
  EXPECT_EQ(sizeof(kResponseBody) - 1, written_bytes);
  EXPECT_TRUE(data_pipe.producer_handle.is_valid());
  EXPECT_TRUE(HasWorkInBrowser(version_.get()));
  loader_ptr_.reset();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(HasWorkInBrowser(version_.get()));

  // Although ServiceWorkerNavigationLoader resets its URLLoaderClient pointer
  // on connection error, the URLLoaderClient still exists. In this test, it is
  // |client_| which owns the data pipe, so it's still valid to write data to
  // it.
  mojo_result = data_pipe.producer_handle->WriteData(
      kResponseBody, &written_bytes, MOJO_WRITE_DATA_FLAG_NONE);
  // TODO(falken): This should probably be an error.
  EXPECT_EQ(MOJO_RESULT_OK, mojo_result);

  client_.RunUntilComplete();
  EXPECT_FALSE(data_pipe.consumer_handle.is_valid());
  EXPECT_EQ(net::ERR_ABORTED, client_.completion_status().error_code);

  // Timing histograms shouldn't be recorded on cancel.
  histogram_tester.ExpectTotalCount(
      "ServiceWorker.LoadTiming.MainFrame.MainResource."
      "StartToForwardServiceWorker",
      0);
  histogram_tester.ExpectTotalCount(
      "ServiceWorker.LoadTiming.MainFrame.MainResource."
      "ResponseReceivedToCompleted2",
      0);
}

// Test when the service worker responds with network fallback.
// i.e., does not call respondWith().
TEST_F(ServiceWorkerNavigationLoaderTest, FallbackResponse) {
  base::HistogramTester histogram_tester;
  helper_->RespondWithFallback();

  // Perform the request.
  LoaderResult result = StartRequest(CreateRequest());
  EXPECT_EQ(LoaderResult::kHandledRequest, result);

  // The fallback callback should be called.
  RunUntilFallbackCallback();
  EXPECT_FALSE(reset_subresource_loader_params_);
  EXPECT_FALSE(was_main_resource_load_failed_called_);

  // The request should not be handled by the loader, but it shouldn't be a
  // failure.
  EXPECT_FALSE(was_main_resource_load_failed_called_);
  histogram_tester.ExpectUniqueSample(kHistogramMainResourceFetchEvent,
                                      blink::ServiceWorkerStatusCode::kOk, 1);

  // Test histogram of network fallback.
  histogram_tester.ExpectTotalCount(
      "ServiceWorker.LoadTiming.MainFrame.MainResource."
      "FetchHandlerEndToFallbackNetwork",
      1);
}

// Test when the service worker rejects the FetchEvent.
TEST_F(ServiceWorkerNavigationLoaderTest, ErrorResponse) {
  base::HistogramTester histogram_tester;
  helper_->RespondWithError();

  // Perform the request.
  LoaderResult result = StartRequest(CreateRequest());
  EXPECT_EQ(LoaderResult::kHandledRequest, result);

  client_.RunUntilComplete();
  EXPECT_EQ(net::ERR_FAILED, client_.completion_status().error_code);

  // Event dispatch still succeeded.
  histogram_tester.ExpectUniqueSample(kHistogramMainResourceFetchEvent,
                                      blink::ServiceWorkerStatusCode::kOk, 1);
  // Timing UMAs shouldn't be recorded when we receive an error response.
  histogram_tester.ExpectTotalCount(
      "ServiceWorker.LoadTiming.MainFrame.MainResource."
      "StartToForwardServiceWorker",
      0);
}

// Test when dispatching the fetch event to the service worker failed.
TEST_F(ServiceWorkerNavigationLoaderTest, FailFetchDispatch) {
  base::HistogramTester histogram_tester;
  helper_->FailToDispatchFetchEvent();

  // Perform the request.
  LoaderResult result = StartRequest(CreateRequest());
  EXPECT_EQ(LoaderResult::kHandledRequest, result);

  // The fallback callback should be called.
  RunUntilFallbackCallback();
  EXPECT_TRUE(reset_subresource_loader_params_);
  EXPECT_TRUE(was_main_resource_load_failed_called_);

  histogram_tester.ExpectUniqueSample(
      kHistogramMainResourceFetchEvent,
      blink::ServiceWorkerStatusCode::kErrorFailed, 1);
  // Timing UMAs shouldn't be recorded when failed to dispatch an event.
  histogram_tester.ExpectTotalCount(
      "ServiceWorker.LoadTiming.MainFrame.MainResource."
      "StartToForwardServiceWorker",
      0);
}

// Test when the respondWith() promise resolves before the waitUntil() promise
// resolves. The response should be received before the event finishes.
TEST_F(ServiceWorkerNavigationLoaderTest, EarlyResponse) {
  helper_->RespondEarly();

  // Perform the request.
  LoaderResult result = StartRequest(CreateRequest());
  EXPECT_EQ(LoaderResult::kHandledRequest, result);
  client_.RunUntilComplete();

  const network::ResourceResponseHead& info = client_.response_head();
  EXPECT_EQ(200, info.headers->response_code());
  ExpectResponseInfo(info, *CreateResponseInfoFromServiceWorker());

  // Although the response was already received, the event remains outstanding
  // until waitUntil() resolves.
  EXPECT_TRUE(HasWorkInBrowser(version_.get()));
  helper_->FinishWaitUntil();
  EXPECT_FALSE(HasWorkInBrowser(version_.get()));
}

// Test asking the loader to fallback to network. In production code, this
// happens when there is no active service worker for the URL, or it must be
// skipped, etc.
TEST_F(ServiceWorkerNavigationLoaderTest, FallbackToNetwork) {
  base::HistogramTester histogram_tester;

  network::ResourceRequest request;
  request.url = GURL("https://www.example.com/");
  request.method = "GET";
  request.fetch_request_mode = network::mojom::FetchRequestMode::kNavigate;
  request.fetch_credentials_mode =
      network::mojom::FetchCredentialsMode::kInclude;
  request.fetch_redirect_mode = network::mojom::FetchRedirectMode::kManual;

  SingleRequestURLLoaderFactory::RequestHandler handler;
  auto loader = std::make_unique<ServiceWorkerNavigationLoader>(
      base::BindOnce(&ReceiveRequestHandler, &handler),
      base::BindOnce(&ServiceWorkerNavigationLoaderTest::Fallback,
                     base::Unretained(this)),
      this, request, nullptr /* provider_host */,
      base::WrapRefCounted<URLLoaderFactoryGetter>(
          helper_->context()->loader_factory_getter()));
  // Ask the loader to fallback to network. In production code,
  // ServiceWorkerControlleeRequestHandler calls FallbackToNetwork() to do this.
  loader->FallbackToNetwork();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(handler);

  // No fetch event was dispatched.
  histogram_tester.ExpectTotalCount(kHistogramMainResourceFetchEvent, 0);
  histogram_tester.ExpectTotalCount(
      "ServiceWorker.LoadTiming.MainFrame.MainResource."
      "StartToForwardServiceWorker",
      0);
}

// Test responding to the fetch event with the navigation preload response.
TEST_F(ServiceWorkerNavigationLoaderTest, NavigationPreload) {
  registration_->EnableNavigationPreload(true);
  helper_->RespondWithNavigationPreloadResponse();

  // Perform the request
  LoaderResult result = StartRequest(CreateRequest());
  ASSERT_EQ(LoaderResult::kHandledRequest, result);
  client_.RunUntilComplete();

  EXPECT_EQ(net::OK, client_.completion_status().error_code);
  const network::ResourceResponseHead& info = client_.response_head();
  EXPECT_EQ(200, info.headers->response_code());

  std::unique_ptr<network::ResourceResponseHead> expected_info =
      CreateResponseInfoFromServiceWorker();
  expected_info->did_service_worker_navigation_preload = true;
  ExpectResponseInfo(info, *expected_info);

  std::string response;
  EXPECT_TRUE(client_.response_body().is_valid());
  EXPECT_TRUE(
      mojo::BlockingCopyToString(client_.response_body_release(), &response));
  EXPECT_EQ("this body came from the network", response);
}

// Test responding to the fetch event with a redirect response.
TEST_F(ServiceWorkerNavigationLoaderTest, Redirect) {
  base::HistogramTester histogram_tester;
  GURL new_url("https://example.com/redirected");
  helper_->RespondWithRedirectResponse(new_url);

  // Perform the request.
  LoaderResult result = StartRequest(CreateRequest());
  EXPECT_EQ(LoaderResult::kHandledRequest, result);
  client_.RunUntilRedirectReceived();

  const network::ResourceResponseHead& info = client_.response_head();
  EXPECT_EQ(301, info.headers->response_code());
  ExpectResponseInfo(info, *CreateResponseInfoFromServiceWorker());

  const net::RedirectInfo& redirect_info = client_.redirect_info();
  EXPECT_EQ(301, redirect_info.status_code);
  EXPECT_EQ("GET", redirect_info.new_method);
  EXPECT_EQ(new_url, redirect_info.new_url);

  histogram_tester.ExpectUniqueSample(kHistogramMainResourceFetchEvent,
                                      blink::ServiceWorkerStatusCode::kOk, 1);
}

TEST_F(ServiceWorkerNavigationLoaderTest, LifetimeAfterForwardToServiceWorker) {
  LoaderResult result = StartRequest(CreateRequest());
  EXPECT_EQ(LoaderResult::kHandledRequest, result);
  base::WeakPtr<ServiceWorkerNavigationLoader> loader = loader_->AsWeakPtr();
  ASSERT_TRUE(loader);

  client_.RunUntilComplete();
  EXPECT_TRUE(loader);

  // Even after calling DetachedFromRequest(), |loader_| should be alive until
  // the Mojo connection to the loader is disconnected.
  loader_.release()->DetachedFromRequest();
  EXPECT_TRUE(loader);

  // When the interface pointer to |loader_| is disconnected, its weak pointers
  // (|loader|) are invalidated.
  loader_ptr_.reset();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(loader);

  // |loader_| is deleted here. LSan test will alert if it leaks.
}

TEST_F(ServiceWorkerNavigationLoaderTest, LifetimeAfterFallbackToNetwork) {
  network::ResourceRequest request;
  request.url = GURL("https://www.example.com/");
  request.method = "GET";
  request.fetch_request_mode = network::mojom::FetchRequestMode::kNavigate;
  request.fetch_credentials_mode =
      network::mojom::FetchCredentialsMode::kInclude;
  request.fetch_redirect_mode = network::mojom::FetchRedirectMode::kManual;

  SingleRequestURLLoaderFactory::RequestHandler handler;
  auto loader = std::make_unique<ServiceWorkerNavigationLoader>(
      base::BindOnce(&ReceiveRequestHandler, &handler),
      base::BindOnce(&ServiceWorkerNavigationLoaderTest::Fallback,
                     base::Unretained(this)),
      this, request, nullptr /* provider_host */,
      base::WrapRefCounted<URLLoaderFactoryGetter>(
          helper_->context()->loader_factory_getter()));
  base::WeakPtr<ServiceWorkerNavigationLoader> loader_weakptr =
      loader->AsWeakPtr();
  // Ask the loader to fallback to network. In production code,
  // ServiceWorkerControlleeRequestHandler calls FallbackToNetwork() to do this.
  loader->FallbackToNetwork();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(handler);
  EXPECT_TRUE(loader_weakptr);

  // DetachedFromRequest() deletes |loader_|.
  loader.release()->DetachedFromRequest();
  EXPECT_FALSE(loader_weakptr);
}

TEST_F(ServiceWorkerNavigationLoaderTest, ConnectionErrorDuringFetchEvent) {
  helper_->DeferResponse();
  LoaderResult result = StartRequest(CreateRequest());
  EXPECT_EQ(LoaderResult::kHandledRequest, result);

  // Wait for the fetch event to be dispatched.
  helper_->RunUntilFetchEvent();

  // Break the Mojo connection. The loader should return an aborted status.
  loader_ptr_.reset();
  client_.RunUntilComplete();
  EXPECT_EQ(net::ERR_ABORTED, client_.completion_status().error_code);

  // The loader is still alive. Finish the fetch event. It shouldn't crash or
  // call any callbacks on |client_|, which would throw an error.
  helper_->FinishRespondWith();
  // There's no event to wait for, so just pump the message loop and the test
  // passes if there is no error or crash.
  base::RunLoop().RunUntilIdle();
}

TEST_F(ServiceWorkerNavigationLoaderTest, DetachedDuringFetchEvent) {
  LoaderResult result = StartRequest(CreateRequest());
  EXPECT_EQ(LoaderResult::kHandledRequest, result);

  // Detach the loader immediately after it started. This results in
  // DidDispatchFetchEvent() being invoked later with null |delegate_|.
  loader_.release()->DetachedFromRequest();
  client_.RunUntilComplete();
  EXPECT_EQ(net::ERR_ABORTED, client_.completion_status().error_code);
}

}  // namespace service_worker_navigation_loader_unittest
}  // namespace content
