// 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_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/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"
#include "third_party/blink/public/mojom/devtools/console_message.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 blink::mojom::AppCacheFrontend {
   public:
    void CacheSelected(int32_t host_id,
                       blink::mojom::AppCacheInfoPtr info) override {}

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

    void ErrorEventRaised(
        const std::vector<int32_t>& host_ids,
        blink::mojom::AppCacheErrorDetailsPtr details) override {}

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

    void LogMessage(int32_t host_id,
                    blink::mojom::ConsoleMessageLevel log_level,
                    const std::string& message) override {}

    void SetSubresourceFactory(
        int32_t 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_ = std::make_unique<AppCacheBackendImpl>(mock_service_.get(),
                                                          kMockProcessId);
    backend_impl_->set_frontend_for_testing(mock_frontend_.get());
    const int kHostId = 1;
    const int kRenderFrameId = 2;
    backend_impl_->RegisterHost(kHostId, kRenderFrameId);
    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, base::DoNothing());
    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
