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

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

#include <stdint.h>

#include <memory>
#include <utility>
#include <vector>

#include "base/callback.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
#include "content/browser/loader/resource_request_info_impl.h"
#include "content/browser/resource_context_impl.h"
#include "content/browser/service_worker/embedded_worker_registry.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_context_wrapper.h"
#include "content/browser/service_worker/service_worker_provider_host.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_response_info.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_types.h"
#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/blob_handle.h"
#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/request_context_type.h"
#include "content/public/common/resource_type.h"
#include "content/public/test/mock_resource_context.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "net/base/io_buffer.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/ssl/ssl_info.h"
#include "net/test/cert_test_util.h"
#include "net/test/test_data_directory.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_job_factory_impl.h"
#include "net/url_request/url_request_test_job.h"
#include "net/url_request/url_request_test_util.h"
#include "services/network/public/cpp/resource_request_body.h"
#include "services/network/public/mojom/request_context_frame_type.mojom.h"
#include "storage/browser/blob/blob_data_builder.h"
#include "storage/browser/blob/blob_storage_context.h"
#include "storage/browser/blob/blob_url_request_job.h"
#include "storage/browser/blob/blob_url_request_job_factory.h"
#include "storage/common/blob_storage/blob_handle.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/service_worker/service_worker_status_code.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_installed_scripts_manager.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"

namespace content {
namespace service_worker_url_request_job_unittest {

const int kProviderID = 100;
const char kTestData[] = "Here is sample text for the blob.";

// A simple ProtocolHandler implementation to create ServiceWorkerURLRequestJob.
//
// MockProtocolHandler is basically a mock of
// ServiceWorkerControlleeRequestHandler. In production code,
// ServiceWorkerControlleeRequestHandler::MaybeCreateJob() is called by
// ServiceWorkerRequestInterceptor, a custom URLRequestInterceptor, but for
// testing it's easier to make the job via ProtocolHandler.
class MockProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
 public:
  MockProtocolHandler(
      base::WeakPtr<ServiceWorkerProviderHost> provider_host,
      const ResourceContext* resource_context,
      base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
      ServiceWorkerURLRequestJob::Delegate* delegate)
      : provider_host_(provider_host),
        resource_context_(resource_context),
        blob_storage_context_(blob_storage_context),
        job_(nullptr),
        delegate_(delegate),
        resource_type_(RESOURCE_TYPE_MAIN_FRAME),
        simulate_navigation_preload_(false) {}

  ~MockProtocolHandler() override = default;

  void set_resource_type(ResourceType type) { resource_type_ = type; }
  void set_simulate_navigation_preload() {
    simulate_navigation_preload_ = true;
  }

  // A simple version of
  // ServiceWorkerControlleeRequestHandler::MaybeCreateJob().
  net::URLRequestJob* MaybeCreateJob(
      net::URLRequest* request,
      net::NetworkDelegate* network_delegate) const override {
    if (job_ && job_->ShouldFallbackToNetwork()) {
      // Simulate fallback to network by constructing a valid response.
      return new net::URLRequestTestJob(request, network_delegate,
                                        net::URLRequestTestJob::test_headers(),
                                        "PASS", true);
    }

    job_ = new ServiceWorkerURLRequestJob(
        request, network_delegate, provider_host_->client_uuid(),
        blob_storage_context_, resource_context_,
        network::mojom::FetchRequestMode::kNoCORS,
        network::mojom::FetchCredentialsMode::kOmit,
        network::mojom::FetchRedirectMode::kFollow,
        std::string() /* integrity */, false /* keepalive */, resource_type_,
        REQUEST_CONTEXT_TYPE_HYPERLINK,
        network::mojom::RequestContextFrameType::kTopLevel,
        scoped_refptr<network::ResourceRequestBody>(), delegate_);
    if (simulate_navigation_preload_) {
      job_->set_simulate_navigation_preload_for_test();
    }
    job_->ForwardToServiceWorker();
    return job_;
  }
  ServiceWorkerURLRequestJob* job() { return job_; }

 private:
  base::WeakPtr<ServiceWorkerProviderHost> provider_host_;
  const ResourceContext* resource_context_;
  base::WeakPtr<storage::BlobStorageContext> blob_storage_context_;
  mutable ServiceWorkerURLRequestJob* job_;
  ServiceWorkerURLRequestJob::Delegate* delegate_;
  ResourceType resource_type_;
  bool simulate_navigation_preload_;
};

// Returns a BlobProtocolHandler that uses |blob_storage_context|. Caller owns
// the memory.
std::unique_ptr<storage::BlobProtocolHandler> CreateMockBlobProtocolHandler(
    storage::BlobStorageContext* blob_storage_context) {
  return std::make_unique<storage::BlobProtocolHandler>(blob_storage_context);
}

base::flat_map<std::string, std::string> MakeHeaders() {
  base::flat_map<std::string, std::string> headers;
  headers["Pineapple"] = "Pen";
  headers["Foo"] = "Bar";
  headers["Set-Cookie"] = "CookieCookieCookie";
  return headers;
}

blink::mojom::FetchAPIResponsePtr MakeOkResponse() {
  auto response = blink::mojom::FetchAPIResponse::New();
  response->status_code = 200;
  response->status_text = "OK";
  response->response_type = network::mojom::FetchResponseType::kDefault;
  return response;
}

void SaveStatusCallback(blink::ServiceWorkerStatusCode* out_status,
                        blink::ServiceWorkerStatusCode status) {
  *out_status = status;
}

// ServiceWorkerURLRequestJobTest is for testing the handling of URL requests by
// a service worker.
//
// To use it, call SetUpWithHelper() in your test. This sets up the service
// worker and the scaffolding to make the worker handle https URLRequests.  (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.) Example:
//
//    auto request = url_request_context_.CreateRequest(
//        GURL("https://example.com/foo.html"), net::DEFAULT_PRIORITY,
//        &url_request_delegate_, TRAFFIC_ANNOTATION_FOR_TESTS);
//    request->set_method("GET");
//    request->Start();
//    base::RunLoop().RunUntilIdle();
//    // Now the request was handled by a ServiceWorkerURLRequestJob.
//
// ServiceWorkerURLRequestJobTest is also a
// ServiceWorkerURLRequestJob::Delegate. In production code,
// ServiceWorkerControlleeRequestHandler is the Delegate (for non-"foreign
// fetch" request interceptions). So this class also basically mocks that part
// of ServiceWorkerControlleeRequestHandler.
class ServiceWorkerURLRequestJobTest
    : public testing::Test,
      public ServiceWorkerURLRequestJob::Delegate {
 public:
  MockProtocolHandler* handler() { return protocol_handler_; }

 protected:
  ServiceWorkerURLRequestJobTest()
      : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
  ~ServiceWorkerURLRequestJobTest() override {}

  void SetUp() override {
    // ServiceWorkerURLRequestJob is a non-S13nServiceWorker specific class
    // and we don't use it when S13nServiceWorker is enabled.
    scoped_feature_list_.InitAndDisableFeature(
        blink::features::kServiceWorkerServicification);
    browser_context_.reset(new TestBrowserContext);
    InitializeResourceContext(browser_context_.get());
  }

  void SetUpWithHelper(std::unique_ptr<EmbeddedWorkerTestHelper> helper) {
    helper_ = std::move(helper);
    helper_->context()->storage()->LazyInitializeForTest(base::DoNothing());
    base::RunLoop().RunUntilIdle();

    // Prepare HTTP response info for the version.
    auto http_info = std::make_unique<net::HttpResponseInfo>();
    http_info->ssl_info.cert =
        net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem");
    EXPECT_TRUE(http_info->ssl_info.is_valid());
    http_info->ssl_info.security_bits = 0x100;
    // SSL3 TLS_DHE_RSA_WITH_AES_256_CBC_SHA
    http_info->ssl_info.connection_status = 0x300039;
    http_info->headers = base::MakeRefCounted<net::HttpResponseHeaders>("");

    // Create a registration and service worker version.
    blink::mojom::ServiceWorkerRegistrationOptions options;
    options.scope = GURL("https://example.com/");
    registration_ = new ServiceWorkerRegistration(
        options, 1L, helper_->context()->AsWeakPtr());
    version_ = new ServiceWorkerVersion(
        registration_.get(), GURL("https://example.com/service_worker.js"), 1L,
        helper_->context()->AsWeakPtr());
    std::vector<ServiceWorkerDatabase::ResourceRecord> records;
    records.push_back(WriteToDiskCacheWithCustomResponseInfoSync(
        helper_->context()->storage(), version_->script_url(), 10,
        std::move(http_info), "I'm the body", "I'm the meta data"));
    version_->script_cache_map()->SetResources(records);
    version_->set_fetch_handler_existence(
        ServiceWorkerVersion::FetchHandlerExistence::EXISTS);

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

    // Create a controlled client.
    std::unique_ptr<ServiceWorkerProviderHost> provider_host =
        CreateProviderHostForWindow(
            helper_->mock_render_process_id(), kProviderID,
            true /* is_parent_frame_secure */, helper_->context()->AsWeakPtr(),
            &remote_endpoint_);
    provider_host_ = provider_host->AsWeakPtr();
    provider_host->SetDocumentUrl(GURL("https://example.com/"));
    registration_->SetActiveVersion(version_);
    provider_host->SetControllerRegistration(
        registration_, false /* notify_controllerchange */);

    // Set up scaffolding for handling URL requests.
    ChromeBlobStorageContext* chrome_blob_storage_context =
        ChromeBlobStorageContext::GetFor(browser_context_.get());
    // Wait for chrome_blob_storage_context to finish initializing.
    base::RunLoop().RunUntilIdle();
    storage::BlobStorageContext* blob_storage_context =
        chrome_blob_storage_context->context();
    url_request_job_factory_.reset(new net::URLRequestJobFactoryImpl);
    std::unique_ptr<MockProtocolHandler> handler(new MockProtocolHandler(
        provider_host->AsWeakPtr(), browser_context_->GetResourceContext(),
        blob_storage_context->AsWeakPtr(), this));
    protocol_handler_ = handler.get();
    url_request_job_factory_->SetProtocolHandler("https", std::move(handler));
    url_request_job_factory_->SetProtocolHandler(
        "blob", CreateMockBlobProtocolHandler(blob_storage_context));
    url_request_context_.set_job_factory(url_request_job_factory_.get());

    helper_->context()->AddProviderHost(std::move(provider_host));
  }

  void TearDown() override {
    version_ = nullptr;
    registration_ = nullptr;
    helper_.reset();
    request_.reset();
  }

  void TestRequestResult(int expected_status_code,
                         const std::string& expected_status_text,
                         const std::string& expected_response,
                         bool expect_valid_ssl) {
    EXPECT_EQ(net::OK, url_request_delegate_.request_status());
    EXPECT_EQ(expected_status_code,
              request_->response_headers()->response_code());
    EXPECT_EQ(expected_status_text,
              request_->response_headers()->GetStatusText());
    EXPECT_EQ(expected_response, url_request_delegate_.data_received());
    const net::SSLInfo& ssl_info = request_->response_info().ssl_info;
    if (expect_valid_ssl) {
      EXPECT_TRUE(ssl_info.is_valid());
      EXPECT_EQ(ssl_info.security_bits, 0x100);
      EXPECT_EQ(ssl_info.connection_status, 0x300039);
    } else {
      EXPECT_FALSE(ssl_info.is_valid());
    }
  }

  void CheckHeaders(const net::HttpResponseHeaders* headers) {
    size_t iter = 0;
    std::string name;
    std::string value;
    EXPECT_TRUE(headers->EnumerateHeaderLines(&iter, &name, &value));
    EXPECT_EQ("Foo", name);
    EXPECT_EQ("Bar", value);
    EXPECT_TRUE(headers->EnumerateHeaderLines(&iter, &name, &value));
    EXPECT_EQ("Pineapple", name);
    EXPECT_EQ("Pen", value);
    EXPECT_TRUE(headers->EnumerateHeaderLines(&iter, &name, &value));
    EXPECT_EQ("Set-Cookie", name);
    EXPECT_EQ("CookieCookieCookie", value);
    EXPECT_FALSE(headers->EnumerateHeaderLines(&iter, &name, &value));
  }

  void TestRequest(int expected_status_code,
                   const std::string& expected_status_text,
                   const std::string& expected_response,
                   bool expect_valid_ssl) {
    request_ = url_request_context_.CreateRequest(
        GURL("https://example.com/foo.html"), net::DEFAULT_PRIORITY,
        &url_request_delegate_, TRAFFIC_ANNOTATION_FOR_TESTS);

    request_->set_method("GET");
    request_->Start();
    base::RunLoop().RunUntilIdle();
    TestRequestResult(expected_status_code, expected_status_text,
                      expected_response, expect_valid_ssl);
  }

  bool HasWork() { return version_->HasWorkInBrowser(); }

  // Runs a request where the active worker starts a request in ACTIVATING state
  // and fails to reach ACTIVATED.
  void RunFailToActivateTest(ResourceType resource_type) {
    protocol_handler_->set_resource_type(resource_type);

    // Start a request with an activating worker.
    version_->SetStatus(ServiceWorkerVersion::ACTIVATING);
    request_ = url_request_context_.CreateRequest(
        GURL("https://example.com/foo.html"), net::DEFAULT_PRIORITY,
        &url_request_delegate_, TRAFFIC_ANNOTATION_FOR_TESTS);
    request_->set_method("GET");
    request_->Start();

    // Proceed until the job starts waiting for the worker to activate.
    base::RunLoop().RunUntilIdle();

    // Simulate another worker kicking out the incumbent worker.  PostTask since
    // it might respond synchronously, and the TestDelegate would complain that
    // the message loop isn't being run.
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE, base::BindOnce(&ServiceWorkerVersion::SetStatus, version_,
                                  ServiceWorkerVersion::REDUNDANT));
    base::RunLoop().RunUntilIdle();
  }

  // Starts a navigation request with navigation preload enabled.
  void SetUpNavigationPreloadTest(ResourceType resource_type) {
    version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
    protocol_handler_->set_resource_type(resource_type);
    protocol_handler_->set_simulate_navigation_preload();
    request_ = url_request_context_.CreateRequest(
        GURL("https://example.com/foo.html"), net::DEFAULT_PRIORITY,
        &url_request_delegate_, TRAFFIC_ANNOTATION_FOR_TESTS);
    ResourceRequestInfo::AllocateForTesting(
        request_.get(), resource_type, browser_context_->GetResourceContext(),
        -1, -1, -1, resource_type == RESOURCE_TYPE_MAIN_FRAME, true, true,
        PREVIEWS_OFF, nullptr);

    request_->set_method("GET");
    request_->Start();
    base::RunLoop().RunUntilIdle();
  }

  // ServiceWorkerURLRequestJob::Delegate -------------------------------------
  void OnPrepareToRestart() override { times_prepare_to_restart_invoked_++; }

  ServiceWorkerVersion* GetServiceWorkerVersion(
      ServiceWorkerMetrics::URLRequestJobResult* result) override {
    if (!provider_host_) {
      *result = ServiceWorkerMetrics::REQUEST_JOB_ERROR_NO_PROVIDER_HOST;
      return nullptr;
    }
    if (!provider_host_->controller()) {
      *result = ServiceWorkerMetrics::REQUEST_JOB_ERROR_NO_ACTIVE_VERSION;
      return nullptr;
    }
    return provider_host_->controller();
  }

  bool RequestStillValid(
      ServiceWorkerMetrics::URLRequestJobResult* result) override {
    if (!provider_host_) {
      *result = ServiceWorkerMetrics::REQUEST_JOB_ERROR_NO_PROVIDER_HOST;
      return false;
    }
    return true;
  }

  void MainResourceLoadFailed() override {
    ASSERT_TRUE(provider_host_);
    // Detach the controller so subresource requests also skip the worker.
    provider_host_->NotifyControllerLost();
  }
  // ---------------------------------------------------------------------------

  // |scoped_feature_list_| must be before |thread_bundle_|.
  // See comments in ServiceWorkerProviderHostTest.
  base::test::ScopedFeatureList scoped_feature_list_;

  TestBrowserThreadBundle thread_bundle_;
  base::SimpleTestTickClock tick_clock_;

  std::unique_ptr<TestBrowserContext> browser_context_;
  std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
  scoped_refptr<ServiceWorkerRegistration> registration_;
  scoped_refptr<ServiceWorkerVersion> version_;

  std::unique_ptr<net::URLRequestJobFactoryImpl> url_request_job_factory_;
  net::URLRequestContext url_request_context_;
  net::TestDelegate url_request_delegate_;
  std::unique_ptr<net::URLRequest> request_;

  int times_prepare_to_restart_invoked_ = 0;
  base::WeakPtr<ServiceWorkerProviderHost> provider_host_;
  ServiceWorkerRemoteProviderEndpoint remote_endpoint_;

  // Not owned.
  // The ProtocolHandler for https requests, which creates a
  // ServiceWorkerURLRequestJob.
  MockProtocolHandler* protocol_handler_;

 private:
  DISALLOW_COPY_AND_ASSIGN(ServiceWorkerURLRequestJobTest);
};

TEST_F(ServiceWorkerURLRequestJobTest, Simple) {
  SetUpWithHelper(std::make_unique<EmbeddedWorkerTestHelper>(base::FilePath()));

  version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
  TestRequest(200, "OK", std::string(), true /* expect_valid_ssl */);

  EXPECT_EQ(0, times_prepare_to_restart_invoked_);
  ServiceWorkerResponseInfo* info =
      ServiceWorkerResponseInfo::ForRequest(request_.get());
  ASSERT_TRUE(info);
  EXPECT_TRUE(info->was_fetched_via_service_worker());
  EXPECT_FALSE(info->was_fallback_required());
  EXPECT_TRUE(info->url_list_via_service_worker().empty());
  EXPECT_EQ(network::mojom::FetchResponseType::kDefault,
            info->response_type_via_service_worker());
  EXPECT_FALSE(info->service_worker_start_time().is_null());
  EXPECT_FALSE(info->service_worker_ready_time().is_null());
  EXPECT_FALSE(info->response_is_in_cache_storage());
  EXPECT_EQ(std::string(), info->response_cache_storage_cache_name());
}

// Helper for controlling when to start a worker and respond to a fetch event.
class DelayHelper : public EmbeddedWorkerTestHelper {
 public:
  DelayHelper(ServiceWorkerURLRequestJobTest* test)
      : EmbeddedWorkerTestHelper(base::FilePath()), test_(test) {}
  ~DelayHelper() override {}

  void CompleteNavigationPreload() {
    test_->handler()->job()->OnNavigationPreloadResponse();
  }

  void CompleteStartWorker() {
    EmbeddedWorkerTestHelper::OnStartWorker(
        embedded_worker_id_, service_worker_version_id_, scope_, script_url_,
        pause_after_download_, std::move(start_worker_request_),
        std::move(controller_request_), std::move(start_worker_instance_host_),
        std::move(provider_info_), std::move(installed_scripts_info_));
  }

  void Respond() {
    response_callback_->OnResponse(MakeOkResponse(), base::Time::Now());
    std::move(finish_callback_)
        .Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
             base::Time::Now());
  }

 protected:
  void OnStartWorker(
      int embedded_worker_id,
      int64_t service_worker_version_id,
      const GURL& scope,
      const GURL& script_url,
      bool pause_after_download,
      mojom::ServiceWorkerRequest service_worker_request,
      mojom::ControllerServiceWorkerRequest controller_request,
      mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
      mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
      blink::mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info)
      override {
    embedded_worker_id_ = embedded_worker_id;
    service_worker_version_id_ = service_worker_version_id;
    scope_ = scope;
    script_url_ = script_url;
    pause_after_download_ = pause_after_download;
    start_worker_request_ = std::move(service_worker_request);
    controller_request_ = std::move(controller_request);
    start_worker_instance_host_ = std::move(instance_host);
    provider_info_ = std::move(provider_info);
    installed_scripts_info_ = std::move(installed_scripts_info);
  }

  void OnFetchEvent(
      int embedded_worker_id,
      const network::ResourceRequest& /* request */,
      blink::mojom::FetchEventPreloadHandlePtr preload_handle,
      blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
      mojom::ServiceWorker::DispatchFetchEventCallback finish_callback)
      override {
    embedded_worker_id_ = embedded_worker_id;
    response_callback_ = std::move(response_callback);
    finish_callback_ = std::move(finish_callback);
    preload_handle_ = std::move(preload_handle);
  }

 private:
  int64_t service_worker_version_id_;
  GURL scope_;
  GURL script_url_;
  bool pause_after_download_;
  mojom::ServiceWorkerRequest start_worker_request_;
  mojom::ControllerServiceWorkerRequest controller_request_;
  mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo
      start_worker_instance_host_;
  mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info_;
  blink::mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info_;
  int embedded_worker_id_ = 0;
  blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback_;
  blink::mojom::FetchEventPreloadHandlePtr preload_handle_;
  mojom::ServiceWorker::DispatchFetchEventCallback finish_callback_;
  ServiceWorkerURLRequestJobTest* test_;
  DISALLOW_COPY_AND_ASSIGN(DelayHelper);
};

TEST_F(ServiceWorkerURLRequestJobTest,
       NavPreloadMetrics_WorkerAlreadyStarted_MainFrame) {
  SetUpWithHelper(std::make_unique<DelayHelper>(this));
  DelayHelper* helper = static_cast<DelayHelper*>(helper_.get());

  // Start the worker before the navigation.
  blink::ServiceWorkerStatusCode status =
      blink::ServiceWorkerStatusCode::kErrorFailed;
  base::HistogramTester histogram_tester;
  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
                        base::BindOnce(&SaveStatusCallback, &status));
  base::RunLoop().RunUntilIdle();
  helper->CompleteStartWorker();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status);

  // Do the navigation.
  SetUpNavigationPreloadTest(RESOURCE_TYPE_MAIN_FRAME);
  helper->CompleteNavigationPreload();
  helper->Respond();
  base::RunLoop().RunUntilIdle();

  histogram_tester.ExpectUniqueSample(
      "ServiceWorker.ActivatedWorkerPreparationForMainFrame.Type_"
      "NavigationPreloadEnabled",
      static_cast<int>(ServiceWorkerMetrics::WorkerPreparationType::RUNNING),
      1);
  histogram_tester.ExpectUniqueSample(
      "ServiceWorker.NavPreload.FinishedFirst_MainFrame", false, 1);
  histogram_tester.ExpectTotalCount(
      "ServiceWorker.NavPreload.FinishedFirst_MainFrame_"
      "StartWorkerExistingProcess",
      0);
}

TEST_F(ServiceWorkerURLRequestJobTest,
       NavPreloadMetrics_WorkerFirst_MainFrame) {
  SetUpWithHelper(std::make_unique<DelayHelper>(this));
  DelayHelper* helper = static_cast<DelayHelper*>(helper_.get());

  base::HistogramTester histogram_tester;
  SetUpNavigationPreloadTest(RESOURCE_TYPE_MAIN_FRAME);

  // Worker finishes first.
  helper->CompleteStartWorker();
  helper->CompleteNavigationPreload();
  helper->Respond();
  base::RunLoop().RunUntilIdle();

  histogram_tester.ExpectUniqueSample(
      "ServiceWorker.ActivatedWorkerPreparationForMainFrame.Type_"
      "NavigationPreloadEnabled",
      static_cast<int>(ServiceWorkerMetrics::WorkerPreparationType::
                           START_IN_EXISTING_READY_PROCESS),
      1);
  histogram_tester.ExpectUniqueSample(
      "ServiceWorker.NavPreload.FinishedFirst_MainFrame", false, 1);
  histogram_tester.ExpectUniqueSample(
      "ServiceWorker.NavPreload.FinishedFirst_MainFrame_WorkerStartOccurred",
      false, 1);
}

TEST_F(ServiceWorkerURLRequestJobTest,
       NavPreloadMetrics_NavPreloadFirst_MainFrame) {
  SetUpWithHelper(std::make_unique<DelayHelper>(this));
  DelayHelper* helper = static_cast<DelayHelper*>(helper_.get());

  base::HistogramTester histogram_tester;
  SetUpNavigationPreloadTest(RESOURCE_TYPE_MAIN_FRAME);

  // Nav preload finishes first.
  helper->CompleteNavigationPreload();
  helper->CompleteStartWorker();
  helper->Respond();
  base::RunLoop().RunUntilIdle();

  histogram_tester.ExpectUniqueSample(
      "ServiceWorker.ActivatedWorkerPreparationForMainFrame.Type_"
      "NavigationPreloadEnabled",
      static_cast<int>(ServiceWorkerMetrics::WorkerPreparationType::
                           START_IN_EXISTING_READY_PROCESS),
      1);
  histogram_tester.ExpectUniqueSample(
      "ServiceWorker.NavPreload.FinishedFirst_MainFrame", true, 1);
  histogram_tester.ExpectUniqueSample(
      "ServiceWorker.NavPreload.FinishedFirst_MainFrame_WorkerStartOccurred",
      true, 1);
}

TEST_F(ServiceWorkerURLRequestJobTest, NavPreloadMetrics_WorkerFirst_SubFrame) {
  SetUpWithHelper(std::make_unique<DelayHelper>(this));
  DelayHelper* helper = static_cast<DelayHelper*>(helper_.get());

  base::HistogramTester histogram_tester;
  SetUpNavigationPreloadTest(RESOURCE_TYPE_SUB_FRAME);

  // Worker finishes first.
  helper->CompleteStartWorker();
  helper->CompleteNavigationPreload();
  helper->Respond();
  base::RunLoop().RunUntilIdle();

  histogram_tester.ExpectTotalCount(
      "ServiceWorker.ActivatedWorkerPreparationForMainFrame.Type_"
      "NavigationPreloadEnabled",
      0);
  histogram_tester.ExpectTotalCount(
      "ServiceWorker.NavPreload.FinishedFirst_MainFrame", 0);
  histogram_tester.ExpectTotalCount(
      "ServiceWorker.NavPreload.FinishedFirst_MainFrame_"
      "StartWorkerExistingProcess",
      0);
}

TEST_F(ServiceWorkerURLRequestJobTest,
       NavPreloadMetrics_NavPreloadFirst_SubFrame) {
  SetUpWithHelper(std::make_unique<DelayHelper>(this));
  DelayHelper* helper = static_cast<DelayHelper*>(helper_.get());

  base::HistogramTester histogram_tester;
  SetUpNavigationPreloadTest(RESOURCE_TYPE_SUB_FRAME);

  // Nav preload finishes first.
  helper->CompleteNavigationPreload();
  helper->CompleteStartWorker();
  helper->Respond();
  base::RunLoop().RunUntilIdle();

  histogram_tester.ExpectTotalCount(
      "ServiceWorker.ActivatedWorkerPreparationForMainFrame.Type_"
      "NavigationPreloadEnabled",
      0);
  histogram_tester.ExpectTotalCount(
      "ServiceWorker.NavPreload.FinishedFirst_MainFrame", 0);
  histogram_tester.ExpectTotalCount(
      "ServiceWorker.NavPreload.FinishedFirst_MainFrame_"
      "StartWorkerExistingProcess",
      0);
}

class ProviderDeleteHelper : public EmbeddedWorkerTestHelper {
 public:
  ProviderDeleteHelper() : EmbeddedWorkerTestHelper(base::FilePath()) {}
  ~ProviderDeleteHelper() override {}

 protected:
  void OnFetchEvent(
      int /* embedded_worker_id */,
      const network::ResourceRequest& /* request */,
      blink::mojom::FetchEventPreloadHandlePtr /* preload_handle */,
      blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
      mojom::ServiceWorker::DispatchFetchEventCallback finish_callback)
      override {
    context()->RemoveProviderHost(mock_render_process_id(), kProviderID);
    response_callback->OnResponse(MakeOkResponse(), base::Time::Now());
    std::move(finish_callback)
        .Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
             base::Time::Now());
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(ProviderDeleteHelper);
};

// Shouldn't crash if the ProviderHost is deleted prior to completion of the
// fetch event.
TEST_F(ServiceWorkerURLRequestJobTest, DeletedProviderHostOnFetchEvent) {
  SetUpWithHelper(std::make_unique<ProviderDeleteHelper>());

  version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
  TestRequest(500, "Service Worker Response Error", std::string(),
              false /* expect_valid_ssl */);

  EXPECT_EQ(0, times_prepare_to_restart_invoked_);
  ServiceWorkerResponseInfo* info =
      ServiceWorkerResponseInfo::ForRequest(request_.get());
  ASSERT_TRUE(info);
  EXPECT_TRUE(info->was_fetched_via_service_worker());
  EXPECT_FALSE(info->was_fallback_required());
  EXPECT_EQ(0u, info->url_list_via_service_worker().size());
  EXPECT_EQ(network::mojom::FetchResponseType::kDefault,
            info->response_type_via_service_worker());
  EXPECT_FALSE(info->service_worker_start_time().is_null());
  EXPECT_FALSE(info->service_worker_ready_time().is_null());
}

TEST_F(ServiceWorkerURLRequestJobTest, DeletedProviderHostBeforeFetchEvent) {
  SetUpWithHelper(std::make_unique<EmbeddedWorkerTestHelper>(base::FilePath()));

  version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
  request_ = url_request_context_.CreateRequest(
      GURL("https://example.com/foo.html"), net::DEFAULT_PRIORITY,
      &url_request_delegate_, TRAFFIC_ANNOTATION_FOR_TESTS);

  request_->set_method("GET");
  request_->Start();
  helper_->context()->RemoveProviderHost(helper_->mock_render_process_id(),
                                         kProviderID);
  base::RunLoop().RunUntilIdle();
  TestRequestResult(500, "Service Worker Response Error", std::string(),
                    false /* expect_valid_ssl */);

  EXPECT_EQ(0, times_prepare_to_restart_invoked_);
  ServiceWorkerResponseInfo* info =
      ServiceWorkerResponseInfo::ForRequest(request_.get());
  ASSERT_TRUE(info);
  EXPECT_TRUE(info->was_fetched_via_service_worker());
  EXPECT_FALSE(info->was_fallback_required());
  EXPECT_EQ(0u, info->url_list_via_service_worker().size());
  EXPECT_EQ(network::mojom::FetchResponseType::kDefault,
            info->response_type_via_service_worker());
  EXPECT_TRUE(info->service_worker_start_time().is_null());
  EXPECT_TRUE(info->service_worker_ready_time().is_null());
}

// Responds to fetch events with a blob.
class BlobResponder : public EmbeddedWorkerTestHelper {
 public:
  BlobResponder(const std::string& blob_uuid, uint64_t blob_size)
      : EmbeddedWorkerTestHelper(base::FilePath()),
        blob_uuid_(blob_uuid),
        blob_size_(blob_size) {}
  ~BlobResponder() override = default;

 protected:
  void OnFetchEvent(
      int /* embedded_worker_id */,
      const network::ResourceRequest& /* request */,
      blink::mojom::FetchEventPreloadHandlePtr /* preload_handle */,
      blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
      mojom::ServiceWorker::DispatchFetchEventCallback finish_callback)
      override {
    blink::mojom::FetchAPIResponsePtr response = MakeOkResponse();
    response->headers = MakeHeaders();
    response->blob = blink::mojom::SerializedBlob::New();
    response->blob->uuid = blob_uuid_;
    response->blob->size = blob_size_;
    // As |response->blob->blob| must have a non-null value to be passed via
    // Mojo, we give it a dummy value.
    auto dummy_request = mojo::MakeRequest(&response->blob->blob);

    response_callback->OnResponse(std::move(response), base::Time::Now());
    std::move(finish_callback)
        .Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
             base::Time::Now());
  }

  std::string blob_uuid_;
  uint64_t blob_size_;

 private:
  DISALLOW_COPY_AND_ASSIGN(BlobResponder);
};

TEST_F(ServiceWorkerURLRequestJobTest, BlobResponse) {
  ChromeBlobStorageContext* blob_storage_context =
      ChromeBlobStorageContext::GetFor(browser_context_.get());
  // Wait for blob_storage_context to finish initializing.
  base::RunLoop().RunUntilIdle();

  std::string expected_response;
  expected_response.reserve((sizeof(kTestData) - 1) * 1024);

  auto blob_data = std::make_unique<storage::BlobDataBuilder>("blob-id:myblob");
  for (int i = 0; i < 1024; ++i) {
    blob_data->AppendData(kTestData);
    expected_response += kTestData;
  }
  std::unique_ptr<storage::BlobDataHandle> blob_handle =
      blob_storage_context->context()->AddFinishedBlob(std::move(blob_data));
  SetUpWithHelper(std::make_unique<BlobResponder>(blob_handle->uuid(),
                                                  expected_response.size()));

  version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
  TestRequest(200, "OK", expected_response, true /* expect_valid_ssl */);
  CheckHeaders(request_->response_headers());

  EXPECT_EQ(0, times_prepare_to_restart_invoked_);
  ServiceWorkerResponseInfo* info =
      ServiceWorkerResponseInfo::ForRequest(request_.get());
  ASSERT_TRUE(info);
  EXPECT_TRUE(info->was_fetched_via_service_worker());
  EXPECT_FALSE(info->was_fallback_required());
  EXPECT_EQ(0u, info->url_list_via_service_worker().size());
  EXPECT_EQ(network::mojom::FetchResponseType::kDefault,
            info->response_type_via_service_worker());
  EXPECT_FALSE(info->service_worker_start_time().is_null());
  EXPECT_FALSE(info->service_worker_ready_time().is_null());
}

TEST_F(ServiceWorkerURLRequestJobTest, NonExistentBlobUUIDResponse) {
  SetUpWithHelper(
      std::make_unique<BlobResponder>("blob-id:nothing-is-here", 0));
  version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
  TestRequest(500, "Service Worker Response Error", std::string(),
              true /* expect_valid_ssl */);

  EXPECT_EQ(0, times_prepare_to_restart_invoked_);
  ServiceWorkerResponseInfo* info =
      ServiceWorkerResponseInfo::ForRequest(request_.get());
  ASSERT_TRUE(info);
  EXPECT_TRUE(info->was_fetched_via_service_worker());
  EXPECT_FALSE(info->was_fallback_required());
  EXPECT_EQ(0u, info->url_list_via_service_worker().size());
  EXPECT_EQ(network::mojom::FetchResponseType::kDefault,
            info->response_type_via_service_worker());
  EXPECT_FALSE(info->service_worker_start_time().is_null());
  EXPECT_FALSE(info->service_worker_ready_time().is_null());
}

// Responds to fetch events with a stream.
class StreamResponder : public EmbeddedWorkerTestHelper {
 public:
  explicit StreamResponder(
      blink::mojom::ServiceWorkerStreamCallbackRequest callback_request,
      mojo::ScopedDataPipeConsumerHandle consumer_handle)
      : EmbeddedWorkerTestHelper(base::FilePath()) {
    EXPECT_TRUE(stream_handle_.is_null());
    stream_handle_ = blink::mojom::ServiceWorkerStreamHandle::New();
    stream_handle_->callback_request = std::move(callback_request);
    stream_handle_->stream = std::move(consumer_handle);
  }
  ~StreamResponder() override {}

 protected:
  void OnFetchEvent(
      int /* embedded_worker_id */,
      const network::ResourceRequest& /* request */,
      blink::mojom::FetchEventPreloadHandlePtr /* preload_handle */,
      blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
      mojom::ServiceWorker::DispatchFetchEventCallback finish_callback)
      override {
    ASSERT_FALSE(stream_handle_.is_null());
    blink::mojom::FetchAPIResponsePtr response = MakeOkResponse();
    response->headers = MakeHeaders();
    response_callback->OnResponseStream(
        std::move(response), std::move(stream_handle_), base::Time::Now());
    std::move(finish_callback)
        .Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
             base::Time::Now());
  }

  blink::mojom::ServiceWorkerStreamHandlePtr stream_handle_;

 private:
  DISALLOW_COPY_AND_ASSIGN(StreamResponder);
};

TEST_F(ServiceWorkerURLRequestJobTest, StreamResponse) {
  blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
  mojo::DataPipe data_pipe;
  SetUpWithHelper(
      std::make_unique<StreamResponder>(mojo::MakeRequest(&stream_callback),
                                        std::move(data_pipe.consumer_handle)));

  version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
  request_ = url_request_context_.CreateRequest(
      GURL("https://example.com/foo.html"), net::DEFAULT_PRIORITY,
      &url_request_delegate_, TRAFFIC_ANNOTATION_FOR_TESTS);
  request_->set_method("GET");
  request_->Start();

  std::string expected_response;
  expected_response.reserve((sizeof(kTestData) - 1) * 1024);
  for (int i = 0; i < 1024; ++i) {
    expected_response += kTestData;
    uint32_t written_bytes = sizeof(kTestData) - 1;
    MojoResult result = data_pipe.producer_handle->WriteData(
        kTestData, &written_bytes, MOJO_WRITE_DATA_FLAG_NONE);
    ASSERT_EQ(MOJO_RESULT_OK, result);
    EXPECT_EQ(sizeof(kTestData) - 1, written_bytes);
  }
  stream_callback->OnCompleted();
  data_pipe.producer_handle.reset();

  EXPECT_FALSE(HasWork());
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(HasWork());
  EXPECT_EQ(net::OK, url_request_delegate_.request_status());
  net::HttpResponseHeaders* headers = request_->response_headers();
  EXPECT_EQ(200, headers->response_code());
  EXPECT_EQ("OK", headers->GetStatusText());
  CheckHeaders(headers);
  EXPECT_EQ(expected_response, url_request_delegate_.data_received());

  EXPECT_EQ(0, times_prepare_to_restart_invoked_);
  ServiceWorkerResponseInfo* info =
      ServiceWorkerResponseInfo::ForRequest(request_.get());
  ASSERT_TRUE(info);
  EXPECT_TRUE(info->was_fetched_via_service_worker());
  EXPECT_FALSE(info->was_fallback_required());
  EXPECT_EQ(0u, info->url_list_via_service_worker().size());
  EXPECT_EQ(network::mojom::FetchResponseType::kDefault,
            info->response_type_via_service_worker());
  EXPECT_FALSE(info->service_worker_start_time().is_null());
  EXPECT_FALSE(info->service_worker_ready_time().is_null());

  request_.reset();
  EXPECT_FALSE(HasWork());
}

TEST_F(ServiceWorkerURLRequestJobTest, StreamResponse_ConsecutiveRead) {
  blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
  mojo::DataPipe data_pipe;
  SetUpWithHelper(
      std::make_unique<StreamResponder>(mojo::MakeRequest(&stream_callback),
                                        std::move(data_pipe.consumer_handle)));

  version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
  request_ = url_request_context_.CreateRequest(
      GURL("https://example.com/foo.html"), net::DEFAULT_PRIORITY,
      &url_request_delegate_, TRAFFIC_ANNOTATION_FOR_TESTS);
  request_->set_method("GET");
  request_->Start();
  std::string expected_response;
  expected_response.reserve((sizeof(kTestData) - 1) * 1024);
  for (int i = 0; i < 1024; ++i) {
    expected_response += kTestData;
    uint32_t written_bytes = sizeof(kTestData) - 1;
    MojoResult result = data_pipe.producer_handle->WriteData(
        kTestData, &written_bytes, MOJO_WRITE_DATA_FLAG_NONE);
    ASSERT_EQ(MOJO_RESULT_OK, result);
    EXPECT_EQ(sizeof(kTestData) - 1, written_bytes);
    base::RunLoop().RunUntilIdle();
    EXPECT_EQ(expected_response, url_request_delegate_.data_received());
  }
  stream_callback->OnCompleted();
  base::RunLoop().RunUntilIdle();

  // IO is still pending since |producer_handle| is not yet reset, but the data
  // should have been received by now.
  EXPECT_EQ(net::ERR_IO_PENDING, url_request_delegate_.request_status());
  EXPECT_EQ(200,
            request_->response_headers()->response_code());
  EXPECT_EQ("OK",
            request_->response_headers()->GetStatusText());
  EXPECT_EQ(expected_response, url_request_delegate_.data_received());

  EXPECT_EQ(0, times_prepare_to_restart_invoked_);
  ServiceWorkerResponseInfo* info =
      ServiceWorkerResponseInfo::ForRequest(request_.get());
  ASSERT_TRUE(info);
  EXPECT_TRUE(info->was_fetched_via_service_worker());
  EXPECT_FALSE(info->was_fallback_required());
  EXPECT_EQ(0u, info->url_list_via_service_worker().size());
  EXPECT_EQ(network::mojom::FetchResponseType::kDefault,
            info->response_type_via_service_worker());
  EXPECT_FALSE(info->service_worker_start_time().is_null());
  EXPECT_FALSE(info->service_worker_ready_time().is_null());
}

TEST_F(ServiceWorkerURLRequestJobTest, StreamResponseAndCancel) {
  blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
  mojo::DataPipe data_pipe;
  SetUpWithHelper(
      std::make_unique<StreamResponder>(mojo::MakeRequest(&stream_callback),
                                        std::move(data_pipe.consumer_handle)));

  version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
  request_ = url_request_context_.CreateRequest(
      GURL("https://example.com/foo.html"), net::DEFAULT_PRIORITY,
      &url_request_delegate_, TRAFFIC_ANNOTATION_FOR_TESTS);
  request_->set_method("GET");
  request_->Start();
  EXPECT_FALSE(HasWork());
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(HasWork());

  for (int i = 0; i < 512; ++i) {
    uint32_t written_bytes = sizeof(kTestData) - 1;
    MojoResult result = data_pipe.producer_handle->WriteData(
        kTestData, &written_bytes, MOJO_WRITE_DATA_FLAG_NONE);
    ASSERT_EQ(MOJO_RESULT_OK, result);
    EXPECT_EQ(sizeof(kTestData) - 1, written_bytes);
  }
  EXPECT_TRUE(data_pipe.producer_handle.is_valid());
  request_->Cancel();
  EXPECT_FALSE(HasWork());

  // Fail to write the data pipe because it's already canceled.
  uint32_t written_bytes = sizeof(kTestData) - 1;
  MojoResult result = data_pipe.producer_handle->WriteData(
      kTestData, &written_bytes, MOJO_WRITE_DATA_FLAG_NONE);
  ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);

  stream_callback->OnAborted();

  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(data_pipe.consumer_handle.is_valid());
  EXPECT_EQ(net::ERR_ABORTED, url_request_delegate_.request_status());

  EXPECT_EQ(0, times_prepare_to_restart_invoked_);
  ServiceWorkerResponseInfo* info =
      ServiceWorkerResponseInfo::ForRequest(request_.get());
  ASSERT_TRUE(info);
  EXPECT_TRUE(info->was_fetched_via_service_worker());
  EXPECT_FALSE(info->was_fallback_required());
  EXPECT_EQ(0u, info->url_list_via_service_worker().size());
  EXPECT_EQ(network::mojom::FetchResponseType::kDefault,
            info->response_type_via_service_worker());
  EXPECT_FALSE(info->service_worker_start_time().is_null());
  EXPECT_FALSE(info->service_worker_ready_time().is_null());
}

TEST_F(ServiceWorkerURLRequestJobTest, StreamResponse_Abort) {
  blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
  mojo::DataPipe data_pipe;
  SetUpWithHelper(
      std::make_unique<StreamResponder>(mojo::MakeRequest(&stream_callback),
                                        std::move(data_pipe.consumer_handle)));

  version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
  request_ = url_request_context_.CreateRequest(
      GURL("https://example.com/foo.html"), net::DEFAULT_PRIORITY,
      &url_request_delegate_, TRAFFIC_ANNOTATION_FOR_TESTS);
  request_->set_method("GET");
  request_->Start();

  std::string expected_response;
  expected_response.reserve((sizeof(kTestData) - 1) * 1024);
  for (int i = 0; i < 1024; ++i) {
    expected_response += kTestData;
    uint32_t written_bytes = sizeof(kTestData) - 1;
    MojoResult result = data_pipe.producer_handle->WriteData(
        kTestData, &written_bytes, MOJO_WRITE_DATA_FLAG_NONE);
    ASSERT_EQ(MOJO_RESULT_OK, result);
    EXPECT_EQ(sizeof(kTestData) - 1, written_bytes);
  }
  stream_callback->OnAborted();
  data_pipe.producer_handle.reset();

  EXPECT_FALSE(HasWork());
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(HasWork());
  EXPECT_EQ(net::ERR_CONNECTION_RESET, url_request_delegate_.request_status());

  net::HttpResponseHeaders* headers = request_->response_headers();
  EXPECT_EQ(200, headers->response_code());
  EXPECT_EQ("OK", headers->GetStatusText());
  CheckHeaders(headers);
  EXPECT_EQ(expected_response, url_request_delegate_.data_received());

  EXPECT_EQ(0, times_prepare_to_restart_invoked_);
  ServiceWorkerResponseInfo* info =
      ServiceWorkerResponseInfo::ForRequest(request_.get());
  ASSERT_TRUE(info);
  EXPECT_TRUE(info->was_fetched_via_service_worker());
  EXPECT_FALSE(info->was_fallback_required());
  EXPECT_EQ(0u, info->url_list_via_service_worker().size());
  EXPECT_EQ(network::mojom::FetchResponseType::kDefault,
            info->response_type_via_service_worker());
  EXPECT_FALSE(info->service_worker_start_time().is_null());
  EXPECT_FALSE(info->service_worker_ready_time().is_null());

  request_.reset();
  EXPECT_FALSE(HasWork());
}

TEST_F(ServiceWorkerURLRequestJobTest, StreamResponse_AbortBeforeData) {
  blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
  mojo::DataPipe data_pipe;
  SetUpWithHelper(
      std::make_unique<StreamResponder>(mojo::MakeRequest(&stream_callback),
                                        std::move(data_pipe.consumer_handle)));

  version_->SetStatus(ServiceWorkerVersion::ACTIVATED);

  request_ = url_request_context_.CreateRequest(
      GURL("https://example.com/foo.html"), net::DEFAULT_PRIORITY,
      &url_request_delegate_, TRAFFIC_ANNOTATION_FOR_TESTS);
  request_->set_method("GET");
  request_->Start();
  base::RunLoop().RunUntilIdle();
  stream_callback->OnAborted();
  base::RunLoop().RunUntilIdle();

  std::string expected_response;
  expected_response.reserve((sizeof(kTestData) - 1) * 1024);
  for (int i = 0; i < 1024; ++i) {
    expected_response += kTestData;
    uint32_t written_bytes = sizeof(kTestData) - 1;
    MojoResult result = data_pipe.producer_handle->WriteData(
        kTestData, &written_bytes, MOJO_WRITE_DATA_FLAG_NONE);
    ASSERT_EQ(MOJO_RESULT_OK, result);
    EXPECT_EQ(sizeof(kTestData) - 1, written_bytes);
    base::RunLoop().RunUntilIdle();
    EXPECT_EQ(expected_response, url_request_delegate_.data_received());
  }

  data_pipe.producer_handle.reset();
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(net::ERR_CONNECTION_RESET, url_request_delegate_.request_status());
  EXPECT_EQ(200,
            request_->response_headers()->response_code());
  EXPECT_EQ("OK",
            request_->response_headers()->GetStatusText());
  EXPECT_EQ(expected_response, url_request_delegate_.data_received());

  EXPECT_EQ(0, times_prepare_to_restart_invoked_);
  ServiceWorkerResponseInfo* info =
      ServiceWorkerResponseInfo::ForRequest(request_.get());
  ASSERT_TRUE(info);
  EXPECT_TRUE(info->was_fetched_via_service_worker());
  EXPECT_FALSE(info->was_fallback_required());
  EXPECT_EQ(0u, info->url_list_via_service_worker().size());
  EXPECT_EQ(network::mojom::FetchResponseType::kDefault,
            info->response_type_via_service_worker());
  EXPECT_FALSE(info->service_worker_start_time().is_null());
  EXPECT_FALSE(info->service_worker_ready_time().is_null());
}

TEST_F(ServiceWorkerURLRequestJobTest, StreamResponse_AbortAfterData) {
  blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
  mojo::DataPipe data_pipe;
  SetUpWithHelper(
      std::make_unique<StreamResponder>(mojo::MakeRequest(&stream_callback),
                                        std::move(data_pipe.consumer_handle)));

  version_->SetStatus(ServiceWorkerVersion::ACTIVATED);

  request_ = url_request_context_.CreateRequest(
      GURL("https://example.com/foo.html"), net::DEFAULT_PRIORITY,
      &url_request_delegate_, TRAFFIC_ANNOTATION_FOR_TESTS);
  request_->set_method("GET");
  request_->Start();
  base::RunLoop().RunUntilIdle();
  data_pipe.producer_handle.reset();
  base::RunLoop().RunUntilIdle();
  stream_callback->OnAborted();
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(net::ERR_CONNECTION_RESET, url_request_delegate_.request_status());
  EXPECT_EQ(200, request_->response_headers()->response_code());
  EXPECT_EQ("OK", request_->response_headers()->GetStatusText());
  EXPECT_EQ("", url_request_delegate_.data_received());

  EXPECT_EQ(0, times_prepare_to_restart_invoked_);
  ServiceWorkerResponseInfo* info =
      ServiceWorkerResponseInfo::ForRequest(request_.get());
  ASSERT_TRUE(info);
  EXPECT_TRUE(info->was_fetched_via_service_worker());
  EXPECT_FALSE(info->was_fallback_required());
  EXPECT_EQ(0u, info->url_list_via_service_worker().size());
  EXPECT_EQ(network::mojom::FetchResponseType::kDefault,
            info->response_type_via_service_worker());
  EXPECT_FALSE(info->service_worker_start_time().is_null());
  EXPECT_FALSE(info->service_worker_ready_time().is_null());
}

TEST_F(ServiceWorkerURLRequestJobTest, StreamResponse_ConsecutiveReadAndAbort) {
  blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
  mojo::DataPipe data_pipe;
  SetUpWithHelper(
      std::make_unique<StreamResponder>(mojo::MakeRequest(&stream_callback),
                                        std::move(data_pipe.consumer_handle)));

  version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
  request_ = url_request_context_.CreateRequest(
      GURL("https://example.com/foo.html"), net::DEFAULT_PRIORITY,
      &url_request_delegate_, TRAFFIC_ANNOTATION_FOR_TESTS);
  request_->set_method("GET");
  request_->Start();
  std::string expected_response;
  expected_response.reserve((sizeof(kTestData) - 1) * 1024);
  for (int i = 0; i < 512; ++i) {
    expected_response += kTestData;
    uint32_t written_bytes = sizeof(kTestData) - 1;
    MojoResult result = data_pipe.producer_handle->WriteData(
        kTestData, &written_bytes, MOJO_WRITE_DATA_FLAG_NONE);
    ASSERT_EQ(MOJO_RESULT_OK, result);
    EXPECT_EQ(sizeof(kTestData) - 1, written_bytes);

    base::RunLoop().RunUntilIdle();

    EXPECT_EQ(expected_response, url_request_delegate_.data_received());
  }
  stream_callback->OnAborted();

  base::RunLoop().RunUntilIdle();

  // IO is still pending since |producer_handle| is not yet reset, but the data
  // should have been received by now.
  EXPECT_EQ(net::ERR_IO_PENDING, url_request_delegate_.request_status());
  EXPECT_EQ(200, request_->response_headers()->response_code());
  EXPECT_EQ("OK", request_->response_headers()->GetStatusText());
  EXPECT_EQ(expected_response, url_request_delegate_.data_received());

  EXPECT_EQ(0, times_prepare_to_restart_invoked_);
  ServiceWorkerResponseInfo* info =
      ServiceWorkerResponseInfo::ForRequest(request_.get());
  ASSERT_TRUE(info);
  EXPECT_TRUE(info->was_fetched_via_service_worker());
  EXPECT_FALSE(info->was_fallback_required());
  EXPECT_EQ(0u, info->url_list_via_service_worker().size());
  EXPECT_EQ(network::mojom::FetchResponseType::kDefault,
            info->response_type_via_service_worker());
  EXPECT_FALSE(info->service_worker_start_time().is_null());
  EXPECT_FALSE(info->service_worker_ready_time().is_null());
}

// Helper to simulate failing to dispatch a fetch event to a worker.
class FailFetchHelper : public EmbeddedWorkerTestHelper {
 public:
  FailFetchHelper() : EmbeddedWorkerTestHelper(base::FilePath()) {}
  ~FailFetchHelper() override {}

 protected:
  void OnFetchEvent(
      int embedded_worker_id,
      const network::ResourceRequest& /* request */,
      blink::mojom::FetchEventPreloadHandlePtr /* preload_handle */,
      blink::mojom::
          ServiceWorkerFetchResponseCallbackPtr /* response_callback */,
      mojom::ServiceWorker::DispatchFetchEventCallback finish_callback)
      override {
    SimulateWorkerStopped(embedded_worker_id);
    std::move(finish_callback)
        .Run(blink::mojom::ServiceWorkerEventStatus::ABORTED,
             base::Time::Now());
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(FailFetchHelper);
};

TEST_F(ServiceWorkerURLRequestJobTest, FailFetchDispatch) {
  SetUpWithHelper(std::make_unique<FailFetchHelper>());

  version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
  request_ = url_request_context_.CreateRequest(
      GURL("https://example.com/foo.html"), net::DEFAULT_PRIORITY,
      &url_request_delegate_, TRAFFIC_ANNOTATION_FOR_TESTS);
  request_->set_method("GET");
  request_->Start();

  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(net::OK, url_request_delegate_.request_status());
  // We should have fallen back to network.
  EXPECT_EQ(200, request_->GetResponseCode());
  EXPECT_EQ("PASS", url_request_delegate_.data_received());
  EXPECT_FALSE(HasWork());
  ServiceWorkerProviderHost* host = helper_->context()->GetProviderHost(
      helper_->mock_render_process_id(), kProviderID);
  ASSERT_TRUE(host);
  EXPECT_EQ(host->controller(), nullptr);

  EXPECT_EQ(1, times_prepare_to_restart_invoked_);
  ServiceWorkerResponseInfo* info =
      ServiceWorkerResponseInfo::ForRequest(request_.get());
  ASSERT_TRUE(info);
  EXPECT_FALSE(info->service_worker_start_time().is_null());
  EXPECT_FALSE(info->service_worker_ready_time().is_null());
}

TEST_F(ServiceWorkerURLRequestJobTest, FailToActivate_MainResource) {
  SetUpWithHelper(std::make_unique<EmbeddedWorkerTestHelper>(base::FilePath()));
  RunFailToActivateTest(RESOURCE_TYPE_MAIN_FRAME);

  // The load should fail and we should have fallen back to network because
  // this is a main resource request.
  EXPECT_EQ(net::OK, url_request_delegate_.request_status());
  EXPECT_EQ(200, request_->GetResponseCode());
  EXPECT_EQ("PASS", url_request_delegate_.data_received());

  // The controller should be reset since the main resource request failed.
  ServiceWorkerProviderHost* host = helper_->context()->GetProviderHost(
      helper_->mock_render_process_id(), kProviderID);
  ASSERT_TRUE(host);
  EXPECT_EQ(host->controller(), nullptr);
}

TEST_F(ServiceWorkerURLRequestJobTest, FailToActivate_Subresource) {
  SetUpWithHelper(std::make_unique<EmbeddedWorkerTestHelper>(base::FilePath()));
  RunFailToActivateTest(RESOURCE_TYPE_IMAGE);

  // The load should fail and we should not fall back to network because
  // this is a subresource request.
  EXPECT_EQ(net::OK, url_request_delegate_.request_status());
  EXPECT_EQ(500, request_->GetResponseCode());
  EXPECT_EQ("Service Worker Response Error",
            request_->response_headers()->GetStatusText());

  // The controller should still be set after a subresource request fails.
  ServiceWorkerProviderHost* host = helper_->context()->GetProviderHost(
      helper_->mock_render_process_id(), kProviderID);
  ASSERT_TRUE(host);
  EXPECT_EQ(host->controller(), version_);
}

class EarlyResponseHelper : public EmbeddedWorkerTestHelper {
 public:
  EarlyResponseHelper() : EmbeddedWorkerTestHelper(base::FilePath()) {}
  ~EarlyResponseHelper() override {}

  void FinishWaitUntil() {
    std::move(finish_callback_)
        .Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
             base::Time::Now());
  }

 protected:
  void OnFetchEvent(
      int /* embedded_worker_id */,
      const network::ResourceRequest& /* request */,
      blink::mojom::FetchEventPreloadHandlePtr /* preload_handle */,
      blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
      mojom::ServiceWorker::DispatchFetchEventCallback finish_callback)
      override {
    finish_callback_ = std::move(finish_callback);
    response_callback->OnResponse(MakeOkResponse(), base::Time::Now());
  }

 private:
  mojom::ServiceWorker::DispatchFetchEventCallback finish_callback_;
  DISALLOW_COPY_AND_ASSIGN(EarlyResponseHelper);
};

// This simulates the case when a response is returned and the fetch event is
// still in flight.
TEST_F(ServiceWorkerURLRequestJobTest, EarlyResponse) {
  SetUpWithHelper(std::make_unique<EarlyResponseHelper>());
  EarlyResponseHelper* helper =
      static_cast<EarlyResponseHelper*>(helper_.get());

  version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
  TestRequest(200, "OK", std::string(), true /* expect_valid_ssl */);

  EXPECT_EQ(0, times_prepare_to_restart_invoked_);
  ServiceWorkerResponseInfo* info =
      ServiceWorkerResponseInfo::ForRequest(request_.get());
  ASSERT_TRUE(info);
  EXPECT_TRUE(info->was_fetched_via_service_worker());
  EXPECT_FALSE(info->was_fallback_required());
  EXPECT_EQ(0u, info->url_list_via_service_worker().size());
  EXPECT_EQ(network::mojom::FetchResponseType::kDefault,
            info->response_type_via_service_worker());
  EXPECT_FALSE(info->service_worker_start_time().is_null());
  EXPECT_FALSE(info->service_worker_ready_time().is_null());
  EXPECT_FALSE(info->response_is_in_cache_storage());
  EXPECT_EQ(std::string(), info->response_cache_storage_cache_name());

  EXPECT_TRUE(version_->HasWorkInBrowser());
  helper->FinishWaitUntil();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(version_->HasWorkInBrowser());
}

// Test cancelling the URLRequest while the fetch event is in flight.
TEST_F(ServiceWorkerURLRequestJobTest, CancelRequest) {
  SetUpWithHelper(std::make_unique<DelayHelper>(this));
  DelayHelper* helper = static_cast<DelayHelper*>(helper_.get());

  // Start the URL request. The job will be waiting for the
  // worker to respond to the fetch event.
  version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
  request_ = url_request_context_.CreateRequest(
      GURL("https://example.com/foo.html"), net::DEFAULT_PRIORITY,
      &url_request_delegate_, TRAFFIC_ANNOTATION_FOR_TESTS);
  request_->set_method("GET");
  request_->Start();
  base::RunLoop().RunUntilIdle();
  helper->CompleteStartWorker();
  base::RunLoop().RunUntilIdle();

  // Cancel the URL request.
  request_->Cancel();
  base::RunLoop().RunUntilIdle();

  // Respond to the fetch event.
  EXPECT_TRUE(version_->HasWorkInBrowser());
  helper->Respond();
  base::RunLoop().RunUntilIdle();

  // The fetch event request should no longer be in-flight.
  EXPECT_FALSE(version_->HasWorkInBrowser());
}

// TODO(kinuko): Add more tests with different response data and also for
// FallbackToNetwork case.

}  // namespace service_worker_url_request_job_unittest
}  // namespace content
