// 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/appcache/appcache_request_handler.h"

#include <stdint.h>

#include <string>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/containers/stack.h"
#include "base/location.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/waitable_event.h"
#include "base/task/post_task.h"
#include "base/test/scoped_feature_list.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/browser/appcache/appcache.h"
#include "content/browser/appcache/appcache_backend_impl.h"
#include "content/browser/appcache/appcache_frontend.h"
#include "content/browser/appcache/appcache_job.h"
#include "content/browser/appcache/appcache_url_loader_job.h"
#include "content/browser/appcache/appcache_url_loader_request.h"
#include "content/browser/appcache/appcache_url_request.h"
#include "content/browser/appcache/appcache_url_request_job.h"
#include "content/browser/appcache/mock_appcache_policy.h"
#include "content/browser/appcache/mock_appcache_service.h"
#include "content/common/appcache_interfaces.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "net/base/net_errors.h"
#include "net/base/request_priority.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_util.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_error_job.h"
#include "net/url_request/url_request_job_factory.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/resource_request.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/appcache/appcache.mojom.h"
#include "third_party/blink/public/mojom/appcache/appcache_info.mojom.h"

namespace content {

static const int kMockProcessId = 1;

// Controls whether we instantiate the URLRequest based AppCache handler or
// the URLLoader based one.
enum RequestHandlerType {
  URLREQUEST,
  URLLOADER,
};

// TODO(michaeln/ananta)
// Build on the abstractions provided by the request and the job classes to
// provide mock request and job classes to the AppCacheRequestHandler class
// which would make it testable. It would also allow us to avoid the URLRequest
// and URLLoader semantics in the test cases here,
class AppCacheRequestHandlerTest
    : public testing::TestWithParam<RequestHandlerType> {
 public:
  class MockFrontend : public AppCacheFrontend {
   public:
    void OnCacheSelected(int host_id,
                         const blink::mojom::AppCacheInfo& info) override {}

    void OnStatusChanged(const std::vector<int>& host_ids,
                         blink::mojom::AppCacheStatus status) override {}

    void OnEventRaised(const std::vector<int>& host_ids,
                       blink::mojom::AppCacheEventID event_id) override {}

    void OnErrorEventRaised(
        const std::vector<int>& host_ids,
        const blink::mojom::AppCacheErrorDetails& details) override {}

    void OnProgressEventRaised(const std::vector<int>& host_ids,
                               const GURL& url,
                               int num_total,
                               int num_complete) override {}

    void OnLogMessage(int host_id,
                      AppCacheLogLevel log_level,
                      const std::string& message) override {}

    void OnContentBlocked(int host_id, const GURL& manifest_url) override {}

    void OnSetSubresourceFactory(
        int host_id,
        network::mojom::URLLoaderFactoryPtr url_loader_factory) override {}
  };

  // Helper callback to run a test on our io_thread. The io_thread is spun up
  // once and reused for all tests.
  template <class Method>
  void MethodWrapper(Method method) {
    SetUpTest();
    (this->*method)();
  }

  // Subclasses to simulate particular responses so test cases can
  // exercise fallback code paths.

  class MockURLRequestDelegate : public net::URLRequest::Delegate {
   public:
    MockURLRequestDelegate() : request_status_(1) {}

    void OnResponseStarted(net::URLRequest* request, int net_error) override {
      DCHECK_NE(net::ERR_IO_PENDING, net_error);
      request_status_ = net_error;
    }

    void OnReadCompleted(net::URLRequest* request, int bytes_read) override {
      DCHECK_NE(net::ERR_IO_PENDING, bytes_read);
      if (bytes_read >= 0)
        request_status_ = net::OK;
      else
        request_status_ = bytes_read;
    }

    int request_status() const { return request_status_; }

   private:
    int request_status_;
  };

  class MockURLRequestJob : public net::URLRequestJob {
   public:
    MockURLRequestJob(net::URLRequest* request,
                      net::NetworkDelegate* network_delegate,
                      const net::HttpResponseInfo& info)
        : net::URLRequestJob(request, network_delegate),
          has_response_info_(true),
          response_info_(info) {}

    ~MockURLRequestJob() override {}

   protected:
    void Start() override { NotifyHeadersComplete(); }
    void GetResponseInfo(net::HttpResponseInfo* info) override {
      if (!has_response_info_)
        return;
      *info = response_info_;
    }

   private:
    bool has_response_info_;
    net::HttpResponseInfo response_info_;
  };

  class MockURLRequestJobFactory : public net::URLRequestJobFactory {
   public:
    MockURLRequestJobFactory() {}

    ~MockURLRequestJobFactory() override { DCHECK(!request_job_); }

    void SetJob(std::unique_ptr<net::URLRequestJob> job) {
      request_job_ = std::move(job);
    }

    net::URLRequestJob* MaybeCreateJobWithProtocolHandler(
        const std::string& scheme,
        net::URLRequest* request,
        net::NetworkDelegate* network_delegate) const override {
      if (request_job_)
        return request_job_.release();

      // Some of these tests trigger UpdateJobs which start URLRequests.
      // We short circuit those be returning error jobs.
      return new net::URLRequestErrorJob(request, network_delegate,
                                         net::ERR_INTERNET_DISCONNECTED);
    }

    net::URLRequestJob* MaybeInterceptRedirect(
        net::URLRequest* request,
        net::NetworkDelegate* network_delegate,
        const GURL& location) const override {
      return nullptr;
    }

    net::URLRequestJob* MaybeInterceptResponse(
        net::URLRequest* request,
        net::NetworkDelegate* network_delegate) const override {
      return nullptr;
    }

    bool IsHandledProtocol(const std::string& scheme) const override {
      return scheme == "http";
    };

    bool IsSafeRedirectTarget(const GURL& location) const override {
      return false;
    }

   private:
    mutable std::unique_ptr<net::URLRequestJob> request_job_;
  };

  static void SetUpTestCase() {
    thread_bundle_.reset(
        new TestBrowserThreadBundle(TestBrowserThreadBundle::REAL_IO_THREAD));
    io_task_runner_ =
        base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO});
  }

  static void TearDownTestCase() {
    thread_bundle_.reset();
    io_task_runner_ = nullptr;
  }

  // Test harness --------------------------------------------------

  AppCacheRequestHandlerTest()
      : host_(nullptr), request_(nullptr), request_handler_type_(GetParam()) {
    AppCacheRequestHandler::SetRunningInTests(true);
    if (request_handler_type_ == URLLOADER)
      feature_list_.InitAndEnableFeature(network::features::kNetworkService);
  }

  ~AppCacheRequestHandlerTest() {
    AppCacheRequestHandler::SetRunningInTests(false);
  }

  template <class Method>
  void RunTestOnIOThread(Method method) {
    test_finished_event_.reset(new base::WaitableEvent(
        base::WaitableEvent::ResetPolicy::AUTOMATIC,
        base::WaitableEvent::InitialState::NOT_SIGNALED));
    io_task_runner_->PostTask(
        FROM_HERE,
        base::BindOnce(&AppCacheRequestHandlerTest::MethodWrapper<Method>,
                       base::Unretained(this), method));
    test_finished_event_->Wait();
  }

  void SetUpTest() {
    DCHECK(io_task_runner_->BelongsToCurrentThread());
    mock_service_.reset(new MockAppCacheService);
    // Initializes URLRequestContext on the IO thread.
    empty_context_.reset(new net::URLRequestContext);
    mock_service_->set_request_context(empty_context_.get());
    mock_policy_.reset(new MockAppCachePolicy);
    mock_service_->set_appcache_policy(mock_policy_.get());
    mock_frontend_.reset(new MockFrontend);
    backend_impl_.reset(new AppCacheBackendImpl);
    backend_impl_->Initialize(mock_service_.get(), mock_frontend_.get(),
                              kMockProcessId);
    const int kHostId = 1;
    backend_impl_->RegisterHost(kHostId);
    host_ = backend_impl_->GetHost(kHostId);
    job_factory_.reset(new MockURLRequestJobFactory());
    empty_context_->set_job_factory(job_factory_.get());
  }

  void TearDownTest() {
    DCHECK(io_task_runner_->BelongsToCurrentThread());
    appcache_url_request_job_.reset();
    if (appcache_url_loader_job_)
      appcache_url_loader_job_->DeleteIfNeeded();
    appcache_url_loader_job_.reset();
    handler_.reset();
    request_ = nullptr;
    url_request_.reset();
    backend_impl_.reset();
    mock_frontend_.reset();
    mock_service_.reset();
    mock_policy_.reset();
    job_factory_.reset();
    empty_context_.reset();
    host_ = nullptr;
  }

  void TestFinished() {
    // We unwind the stack prior to finishing up to let stack
    // based objects get deleted.
    DCHECK(io_task_runner_->BelongsToCurrentThread());
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE,
        base::BindOnce(&AppCacheRequestHandlerTest::TestFinishedUnwound,
                       base::Unretained(this)));
  }

  void TestFinishedUnwound() {
    TearDownTest();
    test_finished_event_->Signal();
  }

  void PushNextTask(base::OnceClosure task) {
    task_stack_.push(std::move(task));
  }

  void ScheduleNextTask() {
    DCHECK(io_task_runner_->BelongsToCurrentThread());
    if (task_stack_.empty()) {
      TestFinished();
      return;
    }
    base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
                                                  std::move(task_stack_.top()));
    task_stack_.pop();
  }

  void SetAppCacheJob(AppCacheJob* job) {
    appcache_url_request_job_.reset();
    if (appcache_url_loader_job_)
      appcache_url_loader_job_->DeleteIfNeeded();
    appcache_url_loader_job_ = nullptr;
    if (!job)
      return;
    if (request_handler_type_ == URLREQUEST)
      appcache_url_request_job_.reset(job->AsURLRequestJob());
    else
      appcache_url_loader_job_ = job->AsURLLoaderJob()->GetDerivedWeakPtr();
  }

  AppCacheJob* job() {
    if (request_handler_type_ == URLREQUEST)
      return appcache_url_request_job_.get();
    else
      return appcache_url_loader_job_.get();
  }

  // MainResource_Miss --------------------------------------------------

  void MainResource_Miss() {
    PushNextTask(
        base::BindOnce(&AppCacheRequestHandlerTest::Verify_MainResource_Miss,
                       base::Unretained(this)));

    EXPECT_TRUE(CreateRequestAndHandler(GURL("http://blah"), host_,
                                        RESOURCE_TYPE_MAIN_FRAME));
    EXPECT_TRUE(handler_.get());

    SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
    EXPECT_TRUE(job());
    EXPECT_TRUE(job()->IsWaiting());

    // We have to wait for completion of storage->FindResponseForMainRequest.
    ScheduleNextTask();
  }

  void Verify_MainResource_Miss() {
    EXPECT_FALSE(job()->IsWaiting());
    EXPECT_TRUE(job()->IsDeliveringNetworkResponse());

    int64_t cache_id = blink::mojom::kAppCacheNoCacheId;
    GURL manifest_url;
    handler_->GetExtraResponseInfo(&cache_id, &manifest_url);
    EXPECT_EQ(blink::mojom::kAppCacheNoCacheId, cache_id);
    EXPECT_EQ(GURL(), manifest_url);
    EXPECT_EQ(0, handler_->found_group_id_);

    SetAppCacheJob(handler_->MaybeLoadFallbackForRedirect(
        nullptr, GURL("http://blah/redirect")));
    EXPECT_FALSE(job());
    SetAppCacheJob(handler_->MaybeLoadFallbackForResponse(nullptr));
    EXPECT_FALSE(job());

    EXPECT_TRUE(host_->preferred_manifest_url().is_empty());

    TestFinished();
  }

  // MainResource_Hit --------------------------------------------------

  void MainResource_Hit() {
    PushNextTask(
        base::BindOnce(&AppCacheRequestHandlerTest::Verify_MainResource_Hit,
                       base::Unretained(this)));

    EXPECT_TRUE(CreateRequestAndHandler(GURL("http://blah"), host_,
                                        RESOURCE_TYPE_MAIN_FRAME));
    EXPECT_TRUE(handler_.get());

    mock_storage()->SimulateFindMainResource(
        AppCacheEntry(AppCacheEntry::EXPLICIT, 1),
        GURL(), AppCacheEntry(),
        1, 2, GURL("http://blah/manifest/"));

    SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
    EXPECT_TRUE(job());
    EXPECT_TRUE(job()->IsWaiting());

    // We have to wait for completion of storage->FindResponseForMainRequest.
    ScheduleNextTask();
  }

  void Verify_MainResource_Hit() {
    EXPECT_FALSE(job()->IsWaiting());
    EXPECT_TRUE(job()->IsDeliveringAppCacheResponse());

    int64_t cache_id = blink::mojom::kAppCacheNoCacheId;
    GURL manifest_url;
    handler_->GetExtraResponseInfo(&cache_id, &manifest_url);
    EXPECT_EQ(1, cache_id);
    EXPECT_EQ(GURL("http://blah/manifest/"), manifest_url);
    EXPECT_EQ(2, handler_->found_group_id_);

    SetAppCacheJob(handler_->MaybeLoadFallbackForResponse(nullptr));
    EXPECT_FALSE(job());

    EXPECT_EQ(GURL("http://blah/manifest/"),
              host_->preferred_manifest_url());

    TestFinished();
  }

  // MainResource_Fallback --------------------------------------------------

  void MainResource_Fallback() {
    PushNextTask(base::BindOnce(
        &AppCacheRequestHandlerTest::Verify_MainResource_Fallback,
        base::Unretained(this)));

    EXPECT_TRUE(CreateRequestAndHandler(GURL("http://blah"), host_,
                                        RESOURCE_TYPE_MAIN_FRAME));
    EXPECT_TRUE(handler_.get());

    mock_storage()->SimulateFindMainResource(
        AppCacheEntry(),
        GURL("http://blah/fallbackurl"),
        AppCacheEntry(AppCacheEntry::EXPLICIT, 1),
        1, 2, GURL("http://blah/manifest/"));

    SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
    EXPECT_TRUE(job());
    EXPECT_TRUE(job()->IsWaiting());

    // We have to wait for completion of storage->FindResponseForMainRequest.
    ScheduleNextTask();
  }

  void SimulateResponseCode(int response_code) {
    net::HttpResponseInfo info;
    std::string headers =
        base::StringPrintf("HTTP/1.1 %i Muffin\r\n\r\n", response_code);
    info.headers = new net::HttpResponseHeaders(
        net::HttpUtil::AssembleRawHeaders(headers.c_str(), headers.length()));

    if (request_handler_type_ == URLREQUEST) {
      job_factory_->SetJob(std::make_unique<MockURLRequestJob>(
          url_request_.get(), nullptr, info));
      request_->AsURLRequest()->GetURLRequest()->Start();
      // All our simulation needs to satisfy are the DCHECK's for the request
      // status and the response code.
      DCHECK_EQ(net::OK, delegate_.request_status());
    } else {
      network::ResourceResponseHead response;
      response.headers = info.headers;
      request_->AsURLLoaderRequest()->set_response(response);
    }
    DCHECK_EQ(response_code, request_->GetResponseCode());
  }

  void SimulateResponseInfo(const net::HttpResponseInfo& info) {
    if (request_handler_type_ == URLREQUEST) {
      job_factory_->SetJob(std::make_unique<MockURLRequestJob>(
          url_request_.get(), nullptr, info));
      request_->AsURLRequest()->GetURLRequest()->Start();
    } else {
      network::ResourceResponseHead response;
      response.headers = info.headers;
      request_->AsURLLoaderRequest()->set_response(response);
    }
  }

  void Verify_MainResource_Fallback() {
    EXPECT_FALSE(job()->IsWaiting());
    EXPECT_TRUE(job()->IsDeliveringNetworkResponse());

    // The handler expects to the job to tell it that the request is going to
    // be restarted before it sees the next request.
    if (request_handler_type_ == URLREQUEST) {
      handler_->OnPrepareToRestartURLRequest();

      // When the request is restarted, the existing job is dropped so a
      // real network job gets created. We expect NULL here which will cause
      // the net library to create a real job.
      SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
      EXPECT_FALSE(job());
    }

    // Simulate an http error of the real network job.
    SimulateResponseCode(500);

    SetAppCacheJob(handler_->MaybeLoadFallbackForResponse(nullptr));
    EXPECT_TRUE(job());
    EXPECT_TRUE(job()->IsDeliveringAppCacheResponse());

    int64_t cache_id = blink::mojom::kAppCacheNoCacheId;
    GURL manifest_url;
    handler_->GetExtraResponseInfo(&cache_id, &manifest_url);
    EXPECT_EQ(1, cache_id);
    EXPECT_EQ(GURL("http://blah/manifest/"), manifest_url);
    EXPECT_TRUE(host_->main_resource_was_namespace_entry_);
    EXPECT_EQ(GURL("http://blah/fallbackurl"), host_->namespace_entry_url_);

    EXPECT_EQ(GURL("http://blah/manifest/"),
              host_->preferred_manifest_url());

    TestFinished();
  }

  // MainResource_FallbackOverride --------------------------------------------

  void MainResource_FallbackOverride() {
    PushNextTask(base::BindOnce(
        &AppCacheRequestHandlerTest::Verify_MainResource_FallbackOverride,
        base::Unretained(this)));

    EXPECT_TRUE(CreateRequestAndHandler(GURL("http://blah/fallback-override"),
                                        host_, RESOURCE_TYPE_MAIN_FRAME));
    EXPECT_TRUE(handler_.get());

    mock_storage()->SimulateFindMainResource(
        AppCacheEntry(),
        GURL("http://blah/fallbackurl"),
        AppCacheEntry(AppCacheEntry::EXPLICIT, 1),
        1, 2, GURL("http://blah/manifest/"));

    SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
    EXPECT_TRUE(job());
    EXPECT_TRUE(job()->IsWaiting());

    // We have to wait for completion of storage->FindResponseForMainRequest.
    ScheduleNextTask();
  }

  void Verify_MainResource_FallbackOverride() {
    EXPECT_FALSE(job()->IsWaiting());
    EXPECT_TRUE(job()->IsDeliveringNetworkResponse());

    // The handler expects to the job to tell it that the request is going to
    // be restarted before it sees the next request.
    if (request_handler_type_ == URLREQUEST) {
      handler_->OnPrepareToRestartURLRequest();

      // When the request is restarted, the existing job is dropped so a
      // real network job gets created. We expect NULL here which will cause
      // the net library to create a real job.
      SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
      EXPECT_FALSE(job());
    }

    // Simulate an http error of the real network job, but with custom
    // headers that override the fallback behavior.
    const char kOverrideHeaders[] =
        "HTTP/1.1 404 BOO HOO\0"
        "x-chromium-appcache-fallback-override: disallow-fallback\0"
        "\0";
    net::HttpResponseInfo info;
    info.headers = new net::HttpResponseHeaders(
        std::string(kOverrideHeaders, base::size(kOverrideHeaders)));
    SimulateResponseInfo(info);

    SetAppCacheJob(handler_->MaybeLoadFallbackForResponse(nullptr));
    EXPECT_FALSE(job());

    // GetExtraResponseInfo should return no information.
    int64_t cache_id = blink::mojom::kAppCacheNoCacheId;
    GURL manifest_url;
    handler_->GetExtraResponseInfo(&cache_id, &manifest_url);
    EXPECT_EQ(blink::mojom::kAppCacheNoCacheId, cache_id);
    EXPECT_TRUE(manifest_url.is_empty());

    TestFinished();
  }

  // SubResource_Miss_WithNoCacheSelected ----------------------------------

  void SubResource_Miss_WithNoCacheSelected() {
    EXPECT_TRUE(CreateRequestAndHandler(GURL("http://blah/"), host_,
                                        RESOURCE_TYPE_SUB_RESOURCE));
    // We avoid creating handler when possible, sub-resource requests are not
    // subject to retrieval from an appcache when there's no associated cache.
    EXPECT_FALSE(handler_.get());

    TestFinished();
  }

  // SubResource_Miss_WithCacheSelected ----------------------------------

  void SubResource_Miss_WithCacheSelected() {
    // A sub-resource load where the resource is not in an appcache, or
    // in a network or fallback namespace, should result in a failed request.
    host_->AssociateCompleteCache(MakeNewCache());

    EXPECT_TRUE(CreateRequestAndHandler(GURL("http://blah/"), host_,
                                        RESOURCE_TYPE_SUB_RESOURCE));
    EXPECT_TRUE(handler_.get());

    SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
    EXPECT_TRUE(job());
    EXPECT_TRUE(job()->IsDeliveringErrorResponse());

    SetAppCacheJob(handler_->MaybeLoadFallbackForRedirect(
        nullptr, GURL("http://blah/redirect")));
    EXPECT_FALSE(job());
    SetAppCacheJob(handler_->MaybeLoadFallbackForResponse(nullptr));
    EXPECT_FALSE(job());

    TestFinished();
  }

  // SubResource_Miss_WithWaitForCacheSelection -----------------------------

  void SubResource_Miss_WithWaitForCacheSelection() {
    // Precondition, the host is waiting on cache selection.
    scoped_refptr<AppCache> cache(MakeNewCache());
    host_->pending_selected_cache_id_ = cache->cache_id();
    host_->set_preferred_manifest_url(cache->owning_group()->manifest_url());

    EXPECT_TRUE(CreateRequestAndHandler(GURL("http://blah/"), host_,
                                        RESOURCE_TYPE_SUB_RESOURCE));
    EXPECT_TRUE(handler_.get());
    SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
    EXPECT_TRUE(job());
    EXPECT_TRUE(job()->IsWaiting());

    host_->FinishCacheSelection(cache.get(), nullptr);
    EXPECT_FALSE(job()->IsWaiting());
    EXPECT_TRUE(job()->IsDeliveringErrorResponse());

    SetAppCacheJob(handler_->MaybeLoadFallbackForRedirect(
        nullptr, GURL("http://blah/redirect")));
    EXPECT_FALSE(job());
    SetAppCacheJob(handler_->MaybeLoadFallbackForResponse(nullptr));
    EXPECT_FALSE(job());

    TestFinished();
  }

  // SubResource_Hit -----------------------------

  void SubResource_Hit() {
    host_->AssociateCompleteCache(MakeNewCache());

    mock_storage()->SimulateFindSubResource(
        AppCacheEntry(AppCacheEntry::EXPLICIT, 1), AppCacheEntry(), false);

    EXPECT_TRUE(CreateRequestAndHandler(GURL("http://blah/"), host_,
                                        RESOURCE_TYPE_SUB_RESOURCE));
    EXPECT_TRUE(handler_.get());
    SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
    EXPECT_TRUE(job());
    EXPECT_TRUE(job()->IsDeliveringAppCacheResponse());

    SetAppCacheJob(handler_->MaybeLoadFallbackForRedirect(
        nullptr, GURL("http://blah/redirect")));
    EXPECT_FALSE(job());
    SetAppCacheJob(handler_->MaybeLoadFallbackForResponse(nullptr));
    EXPECT_FALSE(job());

    TestFinished();
  }

  // SubResource_RedirectFallback -----------------------------

  void SubResource_RedirectFallback() {
    // Redirects to resources in the a different origin are subject to
    // fallback namespaces.
    host_->AssociateCompleteCache(MakeNewCache());

    mock_storage()->SimulateFindSubResource(
        AppCacheEntry(), AppCacheEntry(AppCacheEntry::EXPLICIT, 1), false);

    EXPECT_TRUE(CreateRequestAndHandler(GURL("http://blah/"), host_,
                                        RESOURCE_TYPE_SUB_RESOURCE));
    EXPECT_TRUE(handler_.get());
    SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
    EXPECT_FALSE(job());

    SetAppCacheJob(handler_->MaybeLoadFallbackForRedirect(
        nullptr, GURL("http://not_blah/redirect")));
    EXPECT_TRUE(job());
    EXPECT_TRUE(job()->IsDeliveringAppCacheResponse());

    SetAppCacheJob(handler_->MaybeLoadFallbackForResponse(nullptr));
    EXPECT_FALSE(job());

    TestFinished();
  }

  // SubResource_NoRedirectFallback -----------------------------

  void SubResource_NoRedirectFallback() {
    // Redirects to resources in the same-origin are not subject to
    // fallback namespaces.
    host_->AssociateCompleteCache(MakeNewCache());

    mock_storage()->SimulateFindSubResource(
        AppCacheEntry(), AppCacheEntry(AppCacheEntry::EXPLICIT, 1), false);

    EXPECT_TRUE(CreateRequestAndHandler(GURL("http://blah/"), host_,
                                        RESOURCE_TYPE_SUB_RESOURCE));
    EXPECT_TRUE(handler_.get());
    SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
    EXPECT_FALSE(job());

    SetAppCacheJob(handler_->MaybeLoadFallbackForRedirect(
        nullptr, GURL("http://blah/redirect")));
    EXPECT_FALSE(job());

    SimulateResponseCode(200);
    SetAppCacheJob(handler_->MaybeLoadFallbackForResponse(nullptr));
    EXPECT_FALSE(job());

    TestFinished();
  }

  // SubResource_Network -----------------------------

  void SubResource_Network() {
    // A sub-resource load where the resource is in a network namespace,
    // should result in the system using a 'real' job to do the network
    // retrieval.
    host_->AssociateCompleteCache(MakeNewCache());

    mock_storage()->SimulateFindSubResource(
        AppCacheEntry(), AppCacheEntry(), true);

    EXPECT_TRUE(CreateRequestAndHandler(GURL("http://blah/"), host_,
                                        RESOURCE_TYPE_SUB_RESOURCE));
    EXPECT_TRUE(handler_.get());
    SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
    EXPECT_FALSE(job());

    SetAppCacheJob(handler_->MaybeLoadFallbackForRedirect(
        nullptr, GURL("http://blah/redirect")));
    EXPECT_FALSE(job());
    SetAppCacheJob(handler_->MaybeLoadFallbackForResponse(nullptr));
    EXPECT_FALSE(job());

    TestFinished();
  }

  // DestroyedHost -----------------------------

  void DestroyedHost() {
    host_->AssociateCompleteCache(MakeNewCache());

    mock_storage()->SimulateFindSubResource(
        AppCacheEntry(AppCacheEntry::EXPLICIT, 1), AppCacheEntry(), false);

    EXPECT_TRUE(CreateRequestAndHandler(GURL("http://blah/"), host_,
                                        RESOURCE_TYPE_SUB_RESOURCE));
    EXPECT_TRUE(handler_.get());

    backend_impl_->UnregisterHost(1);
    host_ = nullptr;

    EXPECT_FALSE(handler_->MaybeLoadResource(nullptr));
    EXPECT_FALSE(handler_->MaybeLoadFallbackForRedirect(
        nullptr, GURL("http://blah/redirect")));
    EXPECT_FALSE(handler_->MaybeLoadFallbackForResponse(nullptr));

    TestFinished();
  }

  // DestroyedHostWithWaitingJob -----------------------------

  void DestroyedHostWithWaitingJob() {
    // Precondition, the host is waiting on cache selection.
    host_->pending_selected_cache_id_ = 1;

    EXPECT_TRUE(CreateRequestAndHandler(GURL("http://blah/"), host_,
                                        RESOURCE_TYPE_SUB_RESOURCE));
    EXPECT_TRUE(handler_.get());

    SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
    EXPECT_TRUE(job());
    EXPECT_TRUE(job()->IsWaiting());

    backend_impl_->UnregisterHost(1);
    host_ = nullptr;

    if (request_handler_type_ == URLREQUEST) {
      EXPECT_TRUE(appcache_url_request_job_->has_been_killed());
    }
    EXPECT_FALSE(handler_->MaybeLoadResource(nullptr));
    EXPECT_FALSE(handler_->MaybeLoadFallbackForRedirect(
        nullptr, GURL("http://blah/redirect")));
    EXPECT_FALSE(handler_->MaybeLoadFallbackForResponse(nullptr));

    TestFinished();
  }

  // DestroyedService -----------------------------

  void DestroyedService() {
    host_->AssociateCompleteCache(MakeNewCache());

    mock_storage()->SimulateFindSubResource(
        AppCacheEntry(AppCacheEntry::EXPLICIT, 1), AppCacheEntry(), false);

    EXPECT_TRUE(CreateRequestAndHandler(GURL("http://blah/"), host_,
                                        RESOURCE_TYPE_SUB_RESOURCE));
    EXPECT_TRUE(handler_.get());
    SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
    EXPECT_TRUE(job());

    backend_impl_.reset();
    mock_frontend_.reset();
    mock_service_.reset();
    mock_policy_.reset();
    host_ = nullptr;

    if (request_handler_type_ == URLREQUEST) {
      EXPECT_TRUE(appcache_url_request_job_->has_been_killed());
    }
    EXPECT_FALSE(handler_->MaybeLoadResource(nullptr));
    EXPECT_FALSE(handler_->MaybeLoadFallbackForRedirect(
        nullptr, GURL("http://blah/redirect")));
    EXPECT_FALSE(handler_->MaybeLoadFallbackForResponse(nullptr));

    TestFinished();
  }

  // UnsupportedScheme -----------------------------

  void UnsupportedScheme() {
    // Precondition, the host is waiting on cache selection.
    host_->pending_selected_cache_id_ = 1;

    EXPECT_TRUE(CreateRequestAndHandler(GURL("ftp://blah/"), host_,
                                        RESOURCE_TYPE_SUB_RESOURCE));
    EXPECT_TRUE(handler_.get());  // we could redirect to http (conceivably)

    EXPECT_FALSE(handler_->MaybeLoadResource(nullptr));
    EXPECT_FALSE(handler_->MaybeLoadFallbackForRedirect(
        nullptr, GURL("ftp://blah/redirect")));
    EXPECT_FALSE(handler_->MaybeLoadFallbackForResponse(nullptr));

    TestFinished();
  }

  // CanceledRequest -----------------------------

  void CanceledRequest() {
    EXPECT_TRUE(CreateRequestAndHandler(GURL("http://blah/"), host_,
                                        RESOURCE_TYPE_MAIN_FRAME));
    EXPECT_TRUE(handler_.get());

    SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
    EXPECT_TRUE(job());
    EXPECT_TRUE(job()->IsWaiting());
    EXPECT_FALSE(job()->IsStarted());

    base::WeakPtr<AppCacheJob> weak_job = job()->GetWeakPtr();

    // TODO(ananta/michaeln)
    // Rewrite this test for URLLoader.
    if (request_handler_type_ == URLREQUEST) {
      job_factory_->SetJob(std::move(appcache_url_request_job_));

      request_->AsURLRequest()->GetURLRequest()->Start();
      ASSERT_TRUE(weak_job);
      EXPECT_TRUE(weak_job->IsStarted());

      request_->AsURLRequest()->GetURLRequest()->Cancel();
      ASSERT_FALSE(weak_job);
    }

    EXPECT_FALSE(handler_->MaybeLoadFallbackForResponse(nullptr));

    TestFinished();
  }

  // MainResource_Blocked --------------------------------------------------

  void MainResource_Blocked() {
    PushNextTask(
        base::BindOnce(&AppCacheRequestHandlerTest::Verify_MainResource_Blocked,
                       base::Unretained(this)));

    EXPECT_TRUE(CreateRequestAndHandler(GURL("http://blah/"), host_,
                                        RESOURCE_TYPE_MAIN_FRAME));
    EXPECT_TRUE(handler_.get());

    mock_policy_->can_load_return_value_ = false;
    mock_storage()->SimulateFindMainResource(
        AppCacheEntry(AppCacheEntry::EXPLICIT, 1),
        GURL(), AppCacheEntry(),
        1, 2, GURL("http://blah/manifest/"));

    SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
    EXPECT_TRUE(job());
    EXPECT_TRUE(job()->IsWaiting());

    // We have to wait for completion of storage->FindResponseForMainRequest.
    ScheduleNextTask();
  }

  void Verify_MainResource_Blocked() {
    EXPECT_FALSE(job()->IsWaiting());
    EXPECT_FALSE(job()->IsDeliveringAppCacheResponse());

    EXPECT_EQ(0, handler_->found_cache_id_);
    EXPECT_EQ(0, handler_->found_group_id_);
    EXPECT_TRUE(handler_->found_manifest_url_.is_empty());
    EXPECT_TRUE(host_->preferred_manifest_url().is_empty());
    EXPECT_TRUE(host_->main_resource_blocked_);
    EXPECT_EQ(host_->blocked_manifest_url_, "http://blah/manifest/");

    TestFinished();
  }

  // Test case helpers --------------------------------------------------

  AppCache* MakeNewCache() {
    AppCache* cache = new AppCache(
        mock_storage(), mock_storage()->NewCacheId());
    cache->set_complete(true);
    AppCacheGroup* group = new AppCacheGroup(
        mock_storage(), GURL("http://blah/manifest"),
        mock_storage()->NewGroupId());
    group->AddCache(cache);
    return cache;
  }

  MockAppCacheStorage* mock_storage() {
    return reinterpret_cast<MockAppCacheStorage*>(mock_service_->storage());
  }

  bool CreateRequestAndHandler(const GURL& url,
                               AppCacheHost* host,
                               ResourceType resource_type) {
    if (request_handler_type_ == URLREQUEST) {
      url_request_ = empty_context_->CreateRequest(
          url, net::DEFAULT_PRIORITY, &delegate_, TRAFFIC_ANNOTATION_FOR_TESTS);

      std::unique_ptr<AppCacheRequest> request =
          AppCacheURLRequest::Create(url_request_.get());
      request_ = request.get();
      handler_ =
          host->CreateRequestHandler(std::move(request), resource_type, false);
      return true;
    } else if (request_handler_type_ == URLLOADER) {
      network::ResourceRequest resource_request;
      resource_request.url = url;
      resource_request.method = "GET";
      std::unique_ptr<AppCacheRequest> request =
          AppCacheURLLoaderRequest::Create(resource_request);
      request_ = request.get();
      handler_ =
          host->CreateRequestHandler(std::move(request), resource_type, false);
      return true;
    }
    return false;
  }

  // Data members --------------------------------------------------

  std::unique_ptr<base::WaitableEvent> test_finished_event_;
  base::stack<base::OnceClosure> task_stack_;
  std::unique_ptr<MockAppCacheService> mock_service_;
  std::unique_ptr<AppCacheBackendImpl> backend_impl_;
  std::unique_ptr<MockFrontend> mock_frontend_;
  std::unique_ptr<MockAppCachePolicy> mock_policy_;
  AppCacheHost* host_;
  std::unique_ptr<net::URLRequestContext> empty_context_;
  std::unique_ptr<MockURLRequestJobFactory> job_factory_;
  MockURLRequestDelegate delegate_;
  AppCacheRequest* request_;
  std::unique_ptr<net::URLRequest> url_request_;
  std::unique_ptr<AppCacheRequestHandler> handler_;
  std::unique_ptr<AppCacheURLRequestJob> appcache_url_request_job_;
  base::WeakPtr<AppCacheURLLoaderJob> appcache_url_loader_job_;

  static std::unique_ptr<TestBrowserThreadBundle> thread_bundle_;
  static scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;

  RequestHandlerType request_handler_type_;
  base::test::ScopedFeatureList feature_list_;
};

// static
std::unique_ptr<TestBrowserThreadBundle>
    AppCacheRequestHandlerTest::thread_bundle_;
scoped_refptr<base::SingleThreadTaskRunner>
    AppCacheRequestHandlerTest::io_task_runner_;

TEST_P(AppCacheRequestHandlerTest, MainResource_Miss) {
  RunTestOnIOThread(&AppCacheRequestHandlerTest::MainResource_Miss);
}

TEST_P(AppCacheRequestHandlerTest, MainResource_Hit) {
  RunTestOnIOThread(&AppCacheRequestHandlerTest::MainResource_Hit);
}

TEST_P(AppCacheRequestHandlerTest, MainResource_Fallback) {
  RunTestOnIOThread(&AppCacheRequestHandlerTest::MainResource_Fallback);
}

TEST_P(AppCacheRequestHandlerTest, MainResource_FallbackOverride) {
  RunTestOnIOThread(
      &AppCacheRequestHandlerTest::MainResource_FallbackOverride);
}

TEST_P(AppCacheRequestHandlerTest, SubResource_Miss_WithNoCacheSelected) {
  RunTestOnIOThread(
      &AppCacheRequestHandlerTest::SubResource_Miss_WithNoCacheSelected);
}

TEST_P(AppCacheRequestHandlerTest, SubResource_Miss_WithCacheSelected) {
  RunTestOnIOThread(
      &AppCacheRequestHandlerTest::SubResource_Miss_WithCacheSelected);
}

TEST_P(AppCacheRequestHandlerTest, SubResource_Miss_WithWaitForCacheSelection) {
  RunTestOnIOThread(
      &AppCacheRequestHandlerTest::SubResource_Miss_WithWaitForCacheSelection);
}

TEST_P(AppCacheRequestHandlerTest, SubResource_Hit) {
  RunTestOnIOThread(&AppCacheRequestHandlerTest::SubResource_Hit);
}

TEST_P(AppCacheRequestHandlerTest, SubResource_RedirectFallback) {
  RunTestOnIOThread(&AppCacheRequestHandlerTest::SubResource_RedirectFallback);
}

TEST_P(AppCacheRequestHandlerTest, SubResource_NoRedirectFallback) {
  RunTestOnIOThread(
    &AppCacheRequestHandlerTest::SubResource_NoRedirectFallback);
}

TEST_P(AppCacheRequestHandlerTest, SubResource_Network) {
  RunTestOnIOThread(&AppCacheRequestHandlerTest::SubResource_Network);
}

TEST_P(AppCacheRequestHandlerTest, DestroyedHost) {
  RunTestOnIOThread(&AppCacheRequestHandlerTest::DestroyedHost);
}

TEST_P(AppCacheRequestHandlerTest, DestroyedHostWithWaitingJob) {
  RunTestOnIOThread(&AppCacheRequestHandlerTest::DestroyedHostWithWaitingJob);
}

TEST_P(AppCacheRequestHandlerTest, DestroyedService) {
  RunTestOnIOThread(&AppCacheRequestHandlerTest::DestroyedService);
}

TEST_P(AppCacheRequestHandlerTest, UnsupportedScheme) {
  RunTestOnIOThread(&AppCacheRequestHandlerTest::UnsupportedScheme);
}

TEST_P(AppCacheRequestHandlerTest, CanceledRequest) {
  RunTestOnIOThread(&AppCacheRequestHandlerTest::CanceledRequest);
}

TEST_P(AppCacheRequestHandlerTest, MainResource_Blocked) {
  RunTestOnIOThread(&AppCacheRequestHandlerTest::MainResource_Blocked);
}

INSTANTIATE_TEST_CASE_P(,
                        AppCacheRequestHandlerTest,
                        ::testing::Values(URLREQUEST, URLLOADER));

}  // namespace content
