/*
 * Copyright (c) 2015, Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "core/loader/FrameFetchContext.h"

#include <memory>
#include "core/dom/Document.h"
#include "core/frame/FrameOwner.h"
#include "core/frame/FrameTypes.h"
#include "core/frame/LocalFrameView.h"
#include "core/frame/Settings.h"
#include "core/html/HTMLIFrameElement.h"
#include "core/loader/DocumentLoader.h"
#include "core/loader/EmptyClients.h"
#include "core/loader/SubresourceFilter.h"
#include "core/page/Page.h"
#include "core/testing/DummyPageHolder.h"
#include "platform/loader/fetch/FetchInitiatorInfo.h"
#include "platform/loader/fetch/FetchInitiatorTypeNames.h"
#include "platform/loader/fetch/ResourceLoaderOptions.h"
#include "platform/loader/fetch/ResourceRequest.h"
#include "platform/loader/fetch/ResourceTimingInfo.h"
#include "platform/loader/fetch/UniqueIdentifier.h"
#include "platform/loader/testing/MockResource.h"
#include "platform/weborigin/KURL.h"
#include "platform/weborigin/SecurityViolationReportingPolicy.h"
#include "public/platform/WebAddressSpace.h"
#include "public/platform/WebCachePolicy.h"
#include "public/platform/WebDocumentSubresourceFilter.h"
#include "public/platform/WebInsecureRequestPolicy.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace blink {

using Checkpoint = testing::StrictMock<testing::MockFunction<void(int)>>;

class StubLocalFrameClientWithParent final : public EmptyLocalFrameClient {
 public:
  static StubLocalFrameClientWithParent* Create(Frame* parent) {
    return new StubLocalFrameClientWithParent(parent);
  }

  DEFINE_INLINE_VIRTUAL_TRACE() {
    visitor->Trace(parent_);
    EmptyLocalFrameClient::Trace(visitor);
  }

  Frame* Parent() const override { return parent_.Get(); }

 private:
  explicit StubLocalFrameClientWithParent(Frame* parent) : parent_(parent) {}

  Member<Frame> parent_;
};

class MockLocalFrameClient : public EmptyLocalFrameClient {
 public:
  MockLocalFrameClient() : EmptyLocalFrameClient() {}
  MOCK_METHOD1(DidDisplayContentWithCertificateErrors, void(const KURL&));
  MOCK_METHOD2(DispatchDidLoadResourceFromMemoryCache,
               void(const ResourceRequest&, const ResourceResponse&));
  MOCK_METHOD0(UserAgent, String());
  MOCK_METHOD0(MayUseClientLoFiForImageRequests, bool());
  MOCK_METHOD0(IsClientLoFiActiveForFrame, bool());
};

class FixedPolicySubresourceFilter : public WebDocumentSubresourceFilter {
 public:
  FixedPolicySubresourceFilter(LoadPolicy policy, int* filtered_load_counter)
      : policy_(policy), filtered_load_counter_(filtered_load_counter) {}

  LoadPolicy GetLoadPolicy(const WebURL& resource_url,
                           WebURLRequest::RequestContext) override {
    return policy_;
  }

  LoadPolicy GetLoadPolicyForWebSocketConnect(const WebURL& url) override {
    return policy_;
  }

  void ReportDisallowedLoad() override { ++*filtered_load_counter_; }

  bool ShouldLogToConsole() override { return false; }

 private:
  const LoadPolicy policy_;
  int* filtered_load_counter_;
};

class FrameFetchContextTest : public ::testing::Test {
 protected:
  void SetUp() override {
    dummy_page_holder = DummyPageHolder::Create(IntSize(500, 500));
    dummy_page_holder->GetPage().SetDeviceScaleFactorDeprecated(1.0);
    document = &dummy_page_holder->GetDocument();
    fetch_context =
        static_cast<FrameFetchContext*>(&document->Fetcher()->Context());
    owner = DummyFrameOwner::Create();
    FrameFetchContext::ProvideDocumentToContext(*fetch_context, document.Get());
  }

  void TearDown() override {
    if (child_frame)
      child_frame->Detach(FrameDetachType::kRemove);
  }

  FrameFetchContext* CreateChildFrame() {
    child_client = StubLocalFrameClientWithParent::Create(document->GetFrame());
    child_frame = LocalFrame::Create(
        child_client.Get(), *document->GetFrame()->GetPage(), owner.Get());
    child_frame->SetView(
        LocalFrameView::Create(*child_frame, IntSize(500, 500)));
    child_frame->Init();
    child_document = child_frame->GetDocument();
    FrameFetchContext* child_fetch_context = static_cast<FrameFetchContext*>(
        &child_frame->Loader().GetDocumentLoader()->Fetcher()->Context());
    FrameFetchContext::ProvideDocumentToContext(*child_fetch_context,
                                                child_document.Get());
    return child_fetch_context;
  }

  std::unique_ptr<DummyPageHolder> dummy_page_holder;
  // We don't use the DocumentLoader directly in any tests, but need to keep it
  // around as long as the ResourceFetcher and Document live due to indirect
  // usage.
  Persistent<Document> document;
  Persistent<FrameFetchContext> fetch_context;

  Persistent<StubLocalFrameClientWithParent> child_client;
  Persistent<LocalFrame> child_frame;
  Persistent<Document> child_document;
  Persistent<DummyFrameOwner> owner;
};

class FrameFetchContextSubresourceFilterTest : public FrameFetchContextTest {
 protected:
  void SetUp() override {
    FrameFetchContextTest::SetUp();
    filtered_load_callback_counter_ = 0;
  }

  void TearDown() override {
    document->Loader()->SetSubresourceFilter(nullptr);
    FrameFetchContextTest::TearDown();
  }

  int GetFilteredLoadCallCount() const {
    return filtered_load_callback_counter_;
  }

  void SetFilterPolicy(WebDocumentSubresourceFilter::LoadPolicy policy) {
    document->Loader()->SetSubresourceFilter(SubresourceFilter::Create(
        document->Loader(), WTF::MakeUnique<FixedPolicySubresourceFilter>(
                                policy, &filtered_load_callback_counter_)));
  }

  ResourceRequestBlockedReason CanRequest() {
    return CanRequestInternal(SecurityViolationReportingPolicy::kReport);
  }

  ResourceRequestBlockedReason CanRequestPreload() {
    return CanRequestInternal(
        SecurityViolationReportingPolicy::kSuppressReporting);
  }

 private:
  ResourceRequestBlockedReason CanRequestInternal(
      SecurityViolationReportingPolicy reporting_policy) {
    KURL input_url(kParsedURLString, "http://example.com/");
    ResourceRequest resource_request(input_url);
    resource_request.SetFetchCredentialsMode(
        WebURLRequest::kFetchCredentialsModeOmit);
    ResourceLoaderOptions options;
    return fetch_context->CanRequest(
        Resource::kImage, resource_request, input_url, options,
        reporting_policy, FetchParameters::kUseDefaultOriginRestrictionForType);
  }

  int filtered_load_callback_counter_;
};

// This test class sets up a mock frame loader client.
class FrameFetchContextMockedLocalFrameClientTest
    : public FrameFetchContextTest {
 protected:
  void SetUp() override {
    url = KURL(KURL(), "https://example.test/foo");
    main_resource_url = KURL(KURL(), "https://www.example.test");
    client = new testing::NiceMock<MockLocalFrameClient>();
    dummy_page_holder =
        DummyPageHolder::Create(IntSize(500, 500), nullptr, client);
    dummy_page_holder->GetPage().SetDeviceScaleFactorDeprecated(1.0);
    document = &dummy_page_holder->GetDocument();
    document->SetURL(main_resource_url);
    fetch_context =
        static_cast<FrameFetchContext*>(&document->Fetcher()->Context());
    owner = DummyFrameOwner::Create();
    FrameFetchContext::ProvideDocumentToContext(*fetch_context, document.Get());
  }

  KURL url;
  KURL main_resource_url;

  Persistent<testing::NiceMock<MockLocalFrameClient>> client;
};

class FrameFetchContextModifyRequestTest : public FrameFetchContextTest {
 public:
  FrameFetchContextModifyRequestTest()
      : example_origin(SecurityOrigin::Create(
            KURL(kParsedURLString, "https://example.test/"))),
        secure_origin(SecurityOrigin::Create(
            KURL(kParsedURLString, "https://secureorigin.test/image.png"))) {}

 protected:
  void ExpectUpgrade(const char* input, const char* expected) {
    ExpectUpgrade(input, WebURLRequest::kRequestContextScript,
                  WebURLRequest::kFrameTypeNone, expected);
  }

  void ExpectUpgrade(const char* input,
                     WebURLRequest::RequestContext request_context,
                     WebURLRequest::FrameType frame_type,
                     const char* expected) {
    KURL input_url(kParsedURLString, input);
    KURL expected_url(kParsedURLString, expected);

    ResourceRequest resource_request(input_url);
    resource_request.SetRequestContext(request_context);
    resource_request.SetFrameType(frame_type);

    fetch_context->ModifyRequestForCSP(resource_request);

    EXPECT_EQ(expected_url.GetString(), resource_request.Url().GetString());
    EXPECT_EQ(expected_url.Protocol(), resource_request.Url().Protocol());
    EXPECT_EQ(expected_url.Host(), resource_request.Url().Host());
    EXPECT_EQ(expected_url.Port(), resource_request.Url().Port());
    EXPECT_EQ(expected_url.HasPort(), resource_request.Url().HasPort());
    EXPECT_EQ(expected_url.GetPath(), resource_request.Url().GetPath());
  }

  void ExpectUpgradeInsecureRequestHeader(const char* input,
                                          WebURLRequest::FrameType frame_type,
                                          bool should_prefer) {
    KURL input_url(kParsedURLString, input);

    ResourceRequest resource_request(input_url);
    resource_request.SetRequestContext(WebURLRequest::kRequestContextScript);
    resource_request.SetFrameType(frame_type);

    fetch_context->ModifyRequestForCSP(resource_request);

    EXPECT_EQ(
        should_prefer ? String("1") : String(),
        resource_request.HttpHeaderField(HTTPNames::Upgrade_Insecure_Requests));

    // Calling modifyRequestForCSP more than once shouldn't affect the
    // header.
    if (should_prefer) {
      fetch_context->ModifyRequestForCSP(resource_request);
      EXPECT_EQ("1", resource_request.HttpHeaderField(
                         HTTPNames::Upgrade_Insecure_Requests));
    }
  }

  void ExpectSetRequiredCSPRequestHeader(
      const char* input,
      WebURLRequest::FrameType frame_type,
      const AtomicString& expected_required_csp) {
    KURL input_url(kParsedURLString, input);
    ResourceRequest resource_request(input_url);
    resource_request.SetRequestContext(WebURLRequest::kRequestContextScript);
    resource_request.SetFrameType(frame_type);

    fetch_context->ModifyRequestForCSP(resource_request);

    EXPECT_EQ(expected_required_csp,
              resource_request.HttpHeaderField(HTTPNames::Sec_Required_CSP));
  }

  void SetFrameOwnerBasedOnFrameType(WebURLRequest::FrameType frame_type,
                                     HTMLIFrameElement* iframe,
                                     const AtomicString& potential_value) {
    if (frame_type != WebURLRequest::kFrameTypeNested) {
      document->GetFrame()->SetOwner(nullptr);
      return;
    }

    iframe->setAttribute(HTMLNames::cspAttr, potential_value);
    document->GetFrame()->SetOwner(iframe);
  }

  RefPtr<SecurityOrigin> example_origin;
  RefPtr<SecurityOrigin> secure_origin;
};

TEST_F(FrameFetchContextModifyRequestTest, UpgradeInsecureResourceRequests) {
  struct TestCase {
    const char* original;
    const char* upgraded;
  } tests[] = {
      {"http://example.test/image.png", "https://example.test/image.png"},
      {"http://example.test:80/image.png",
       "https://example.test:443/image.png"},
      {"http://example.test:1212/image.png",
       "https://example.test:1212/image.png"},

      {"https://example.test/image.png", "https://example.test/image.png"},
      {"https://example.test:80/image.png",
       "https://example.test:80/image.png"},
      {"https://example.test:1212/image.png",
       "https://example.test:1212/image.png"},

      {"ftp://example.test/image.png", "ftp://example.test/image.png"},
      {"ftp://example.test:21/image.png", "ftp://example.test:21/image.png"},
      {"ftp://example.test:1212/image.png",
       "ftp://example.test:1212/image.png"},
  };

  FrameFetchContext::ProvideDocumentToContext(*fetch_context, document.Get());
  document->SetInsecureRequestPolicy(kUpgradeInsecureRequests);

  for (const auto& test : tests) {
    document->InsecureNavigationsToUpgrade()->clear();

    // We always upgrade for FrameTypeNone and FrameTypeNested.
    ExpectUpgrade(test.original, WebURLRequest::kRequestContextScript,
                  WebURLRequest::kFrameTypeNone, test.upgraded);
    ExpectUpgrade(test.original, WebURLRequest::kRequestContextScript,
                  WebURLRequest::kFrameTypeNested, test.upgraded);

    // We do not upgrade for FrameTypeTopLevel or FrameTypeAuxiliary...
    ExpectUpgrade(test.original, WebURLRequest::kRequestContextScript,
                  WebURLRequest::kFrameTypeTopLevel, test.original);
    ExpectUpgrade(test.original, WebURLRequest::kRequestContextScript,
                  WebURLRequest::kFrameTypeAuxiliary, test.original);

    // unless the request context is RequestContextForm.
    ExpectUpgrade(test.original, WebURLRequest::kRequestContextForm,
                  WebURLRequest::kFrameTypeTopLevel, test.upgraded);
    ExpectUpgrade(test.original, WebURLRequest::kRequestContextForm,
                  WebURLRequest::kFrameTypeAuxiliary, test.upgraded);

    // Or unless the host of the resource is in the document's
    // InsecureNavigationsSet:
    document->AddInsecureNavigationUpgrade(
        example_origin->Host().Impl()->GetHash());
    ExpectUpgrade(test.original, WebURLRequest::kRequestContextScript,
                  WebURLRequest::kFrameTypeTopLevel, test.upgraded);
    ExpectUpgrade(test.original, WebURLRequest::kRequestContextScript,
                  WebURLRequest::kFrameTypeAuxiliary, test.upgraded);
  }
}

TEST_F(FrameFetchContextModifyRequestTest,
       DoNotUpgradeInsecureResourceRequests) {
  FrameFetchContext::ProvideDocumentToContext(*fetch_context, document.Get());
  document->SetSecurityOrigin(secure_origin);
  document->SetInsecureRequestPolicy(kLeaveInsecureRequestsAlone);

  ExpectUpgrade("http://example.test/image.png",
                "http://example.test/image.png");
  ExpectUpgrade("http://example.test:80/image.png",
                "http://example.test:80/image.png");
  ExpectUpgrade("http://example.test:1212/image.png",
                "http://example.test:1212/image.png");

  ExpectUpgrade("https://example.test/image.png",
                "https://example.test/image.png");
  ExpectUpgrade("https://example.test:80/image.png",
                "https://example.test:80/image.png");
  ExpectUpgrade("https://example.test:1212/image.png",
                "https://example.test:1212/image.png");

  ExpectUpgrade("ftp://example.test/image.png", "ftp://example.test/image.png");
  ExpectUpgrade("ftp://example.test:21/image.png",
                "ftp://example.test:21/image.png");
  ExpectUpgrade("ftp://example.test:1212/image.png",
                "ftp://example.test:1212/image.png");
}

TEST_F(FrameFetchContextModifyRequestTest, SendUpgradeInsecureRequestHeader) {
  struct TestCase {
    const char* to_request;
    WebURLRequest::FrameType frame_type;
    bool should_prefer;
  } tests[] = {
      {"http://example.test/page.html", WebURLRequest::kFrameTypeAuxiliary,
       true},
      {"http://example.test/page.html", WebURLRequest::kFrameTypeNested, true},
      {"http://example.test/page.html", WebURLRequest::kFrameTypeNone, false},
      {"http://example.test/page.html", WebURLRequest::kFrameTypeTopLevel,
       true},
      {"https://example.test/page.html", WebURLRequest::kFrameTypeAuxiliary,
       true},
      {"https://example.test/page.html", WebURLRequest::kFrameTypeNested, true},
      {"https://example.test/page.html", WebURLRequest::kFrameTypeNone, false},
      {"https://example.test/page.html", WebURLRequest::kFrameTypeTopLevel,
       true}};

  // This should work correctly both when the FrameFetchContext has a Document,
  // and when it doesn't (e.g. during main frame navigations), so run through
  // the tests both before and after providing a document to the context.
  for (const auto& test : tests) {
    document->SetInsecureRequestPolicy(kLeaveInsecureRequestsAlone);
    ExpectUpgradeInsecureRequestHeader(test.to_request, test.frame_type,
                                       test.should_prefer);

    document->SetInsecureRequestPolicy(kUpgradeInsecureRequests);
    ExpectUpgradeInsecureRequestHeader(test.to_request, test.frame_type,
                                       test.should_prefer);
  }

  FrameFetchContext::ProvideDocumentToContext(*fetch_context, document.Get());

  for (const auto& test : tests) {
    document->SetInsecureRequestPolicy(kLeaveInsecureRequestsAlone);
    ExpectUpgradeInsecureRequestHeader(test.to_request, test.frame_type,
                                       test.should_prefer);

    document->SetInsecureRequestPolicy(kUpgradeInsecureRequests);
    ExpectUpgradeInsecureRequestHeader(test.to_request, test.frame_type,
                                       test.should_prefer);
  }
}

TEST_F(FrameFetchContextModifyRequestTest, SendRequiredCSPHeader) {
  struct TestCase {
    const char* to_request;
    WebURLRequest::FrameType frame_type;
  } tests[] = {
      {"https://example.test/page.html", WebURLRequest::kFrameTypeAuxiliary},
      {"https://example.test/page.html", WebURLRequest::kFrameTypeNested},
      {"https://example.test/page.html", WebURLRequest::kFrameTypeNone},
      {"https://example.test/page.html", WebURLRequest::kFrameTypeTopLevel}};

  HTMLIFrameElement* iframe = HTMLIFrameElement::Create(*document);
  const AtomicString& required_csp = AtomicString("default-src 'none'");
  const AtomicString& another_required_csp = AtomicString("default-src 'self'");

  for (const auto& test : tests) {
    SetFrameOwnerBasedOnFrameType(test.frame_type, iframe, required_csp);
    ExpectSetRequiredCSPRequestHeader(
        test.to_request, test.frame_type,
        test.frame_type == WebURLRequest::kFrameTypeNested ? required_csp
                                                           : g_null_atom);

    SetFrameOwnerBasedOnFrameType(test.frame_type, iframe,
                                  another_required_csp);
    ExpectSetRequiredCSPRequestHeader(
        test.to_request, test.frame_type,
        test.frame_type == WebURLRequest::kFrameTypeNested
            ? another_required_csp
            : g_null_atom);
  }
}

// Tests that PopulateResourceRequest() checks report-only CSP headers, so that
// any violations are reported before the request is modified.
TEST_F(FrameFetchContextTest, PopulateResourceRequestChecksReportOnlyCSP) {
  ContentSecurityPolicy* policy = document->GetContentSecurityPolicy();
  policy->DidReceiveHeader(
      "upgrade-insecure-requests; script-src https://foo.test",
      kContentSecurityPolicyHeaderTypeEnforce,
      kContentSecurityPolicyHeaderSourceHTTP);
  policy->DidReceiveHeader("script-src https://bar.test",
                           kContentSecurityPolicyHeaderTypeReport,
                           kContentSecurityPolicyHeaderSourceHTTP);
  KURL url(KURL(), "http://baz.test");
  ResourceRequest resource_request(url);
  resource_request.SetRequestContext(WebURLRequest::kRequestContextScript);
  resource_request.SetFetchCredentialsMode(
      WebURLRequest::kFetchCredentialsModeOmit);
  ResourceLoaderOptions options;
  fetch_context->PopulateResourceRequest(
      url, Resource::kScript, ClientHintsPreferences(),
      FetchParameters::ResourceWidth(), options,
      SecurityViolationReportingPolicy::kReport, resource_request);
  EXPECT_EQ(1u, policy->violation_reports_sent_.size());
  // Check that the resource was upgraded to a secure URL.
  EXPECT_EQ(KURL(KURL(), "https://baz.test"), resource_request.Url());
}

class FrameFetchContextHintsTest : public FrameFetchContextTest {
 public:
  FrameFetchContextHintsTest() {}

 protected:
  void ExpectHeader(const char* input,
                    const char* header_name,
                    bool is_present,
                    const char* header_value,
                    float width = 0) {
    ClientHintsPreferences hints_preferences;

    FetchParameters::ResourceWidth resource_width;
    if (width > 0) {
      resource_width.width = width;
      resource_width.is_set = true;
    }

    KURL input_url(kParsedURLString, input);
    ResourceRequest resource_request(input_url);

    fetch_context->AddClientHintsIfNecessary(hints_preferences, resource_width,
                                             resource_request);

    EXPECT_EQ(is_present ? String(header_value) : String(),
              resource_request.HttpHeaderField(header_name));
  }
};

TEST_F(FrameFetchContextHintsTest, MonitorDeviceRAMHints) {
  ExpectHeader("http://www.example.com/1.gif", "device-ram", false, "");
  ClientHintsPreferences preferences;
  preferences.SetShouldSendDeviceRAM(true);
  document->GetClientHintsPreferences().UpdateFrom(preferences);
  MemoryCoordinator::SetPhysicalMemoryMBForTesting(4096);
  ExpectHeader("http://www.example.com/1.gif", "device-ram", true, "4");
  MemoryCoordinator::SetPhysicalMemoryMBForTesting(2048);
  ExpectHeader("http://www.example.com/1.gif", "device-ram", true, "2");
  MemoryCoordinator::SetPhysicalMemoryMBForTesting(64385);
  ExpectHeader("http://www.example.com/1.gif", "device-ram", true, "32");
  MemoryCoordinator::SetPhysicalMemoryMBForTesting(768);
  ExpectHeader("http://www.example.com/1.gif", "device-ram", true, "0.5");
  ExpectHeader("http://www.example.com/1.gif", "DPR", false, "");
  ExpectHeader("http://www.example.com/1.gif", "Width", false, "");
  ExpectHeader("http://www.example.com/1.gif", "Viewport-Width", false, "");
}

TEST_F(FrameFetchContextHintsTest, MonitorDPRHints) {
  ExpectHeader("http://www.example.com/1.gif", "DPR", false, "");
  ClientHintsPreferences preferences;
  preferences.SetShouldSendDPR(true);
  document->GetClientHintsPreferences().UpdateFrom(preferences);
  ExpectHeader("http://www.example.com/1.gif", "DPR", true, "1");
  dummy_page_holder->GetPage().SetDeviceScaleFactorDeprecated(2.5);
  ExpectHeader("http://www.example.com/1.gif", "DPR", true, "2.5");
  ExpectHeader("http://www.example.com/1.gif", "Width", false, "");
  ExpectHeader("http://www.example.com/1.gif", "Viewport-Width", false, "");
}

TEST_F(FrameFetchContextHintsTest, MonitorResourceWidthHints) {
  ExpectHeader("http://www.example.com/1.gif", "Width", false, "");
  ClientHintsPreferences preferences;
  preferences.SetShouldSendResourceWidth(true);
  document->GetClientHintsPreferences().UpdateFrom(preferences);
  ExpectHeader("http://www.example.com/1.gif", "Width", true, "500", 500);
  ExpectHeader("http://www.example.com/1.gif", "Width", true, "667", 666.6666);
  ExpectHeader("http://www.example.com/1.gif", "DPR", false, "");
  dummy_page_holder->GetPage().SetDeviceScaleFactorDeprecated(2.5);
  ExpectHeader("http://www.example.com/1.gif", "Width", true, "1250", 500);
  ExpectHeader("http://www.example.com/1.gif", "Width", true, "1667", 666.6666);
}

TEST_F(FrameFetchContextHintsTest, MonitorViewportWidthHints) {
  ExpectHeader("http://www.example.com/1.gif", "Viewport-Width", false, "");
  ClientHintsPreferences preferences;
  preferences.SetShouldSendViewportWidth(true);
  document->GetClientHintsPreferences().UpdateFrom(preferences);
  ExpectHeader("http://www.example.com/1.gif", "Viewport-Width", true, "500");
  dummy_page_holder->GetFrameView().SetLayoutSizeFixedToFrameSize(false);
  dummy_page_holder->GetFrameView().SetLayoutSize(IntSize(800, 800));
  ExpectHeader("http://www.example.com/1.gif", "Viewport-Width", true, "800");
  ExpectHeader("http://www.example.com/1.gif", "Viewport-Width", true, "800",
               666.6666);
  ExpectHeader("http://www.example.com/1.gif", "DPR", false, "");
}

TEST_F(FrameFetchContextHintsTest, MonitorAllHints) {
  ExpectHeader("http://www.example.com/1.gif", "device-ram", false, "");
  ExpectHeader("http://www.example.com/1.gif", "DPR", false, "");
  ExpectHeader("http://www.example.com/1.gif", "Viewport-Width", false, "");
  ExpectHeader("http://www.example.com/1.gif", "Width", false, "");

  ClientHintsPreferences preferences;
  preferences.SetShouldSendDeviceRAM(true);
  preferences.SetShouldSendDPR(true);
  preferences.SetShouldSendResourceWidth(true);
  preferences.SetShouldSendViewportWidth(true);
  MemoryCoordinator::SetPhysicalMemoryMBForTesting(4096);
  document->GetClientHintsPreferences().UpdateFrom(preferences);
  ExpectHeader("http://www.example.com/1.gif", "device-ram", true, "4");
  ExpectHeader("http://www.example.com/1.gif", "DPR", true, "1");
  ExpectHeader("http://www.example.com/1.gif", "Width", true, "400", 400);
  ExpectHeader("http://www.example.com/1.gif", "Viewport-Width", true, "500");
}

TEST_F(FrameFetchContextHintsTest, ClientHintsDeviceRAM) {
  EXPECT_EQ(0.125, FrameFetchContext::ClientHintsDeviceRAM(128));  // 128MB
  EXPECT_EQ(0.25, FrameFetchContext::ClientHintsDeviceRAM(256));   // 256MB
  EXPECT_EQ(0.25, FrameFetchContext::ClientHintsDeviceRAM(510));   // <512MB
  EXPECT_EQ(0.5, FrameFetchContext::ClientHintsDeviceRAM(512));    // 512MB
  EXPECT_EQ(0.5, FrameFetchContext::ClientHintsDeviceRAM(640));    // 512+128MB
  EXPECT_EQ(0.5, FrameFetchContext::ClientHintsDeviceRAM(768));    // 512+256MB
  EXPECT_EQ(0.5, FrameFetchContext::ClientHintsDeviceRAM(1000));   // <1GB
  EXPECT_EQ(1, FrameFetchContext::ClientHintsDeviceRAM(1024));     // 1GB
  EXPECT_EQ(1, FrameFetchContext::ClientHintsDeviceRAM(1536));     // 1.5GB
  EXPECT_EQ(1, FrameFetchContext::ClientHintsDeviceRAM(2000));     // <2GB
  EXPECT_EQ(2, FrameFetchContext::ClientHintsDeviceRAM(2048));     // 2GB
  EXPECT_EQ(4, FrameFetchContext::ClientHintsDeviceRAM(5120));     // 5GB
  EXPECT_EQ(8, FrameFetchContext::ClientHintsDeviceRAM(8192));     // 8GB
  EXPECT_EQ(16, FrameFetchContext::ClientHintsDeviceRAM(16384));   // 16GB
  EXPECT_EQ(32, FrameFetchContext::ClientHintsDeviceRAM(32768));   // 32GB
  EXPECT_EQ(32, FrameFetchContext::ClientHintsDeviceRAM(64385));   // <64GB
}

TEST_F(FrameFetchContextTest, MainResourceCachePolicy) {
  // Default case
  ResourceRequest request("http://www.example.com");
  EXPECT_EQ(WebCachePolicy::kUseProtocolCachePolicy,
            fetch_context->ResourceRequestCachePolicy(
                request, Resource::kMainResource, FetchParameters::kNoDefer));

  // Post
  ResourceRequest post_request("http://www.example.com");
  post_request.SetHTTPMethod(HTTPNames::POST);
  EXPECT_EQ(
      WebCachePolicy::kValidatingCacheData,
      fetch_context->ResourceRequestCachePolicy(
          post_request, Resource::kMainResource, FetchParameters::kNoDefer));

  // Re-post
  document->Loader()->SetLoadType(kFrameLoadTypeBackForward);
  EXPECT_EQ(
      WebCachePolicy::kReturnCacheDataDontLoad,
      fetch_context->ResourceRequestCachePolicy(
          post_request, Resource::kMainResource, FetchParameters::kNoDefer));

  // FrameLoadTypeReload
  document->Loader()->SetLoadType(kFrameLoadTypeReload);
  EXPECT_EQ(WebCachePolicy::kValidatingCacheData,
            fetch_context->ResourceRequestCachePolicy(
                request, Resource::kMainResource, FetchParameters::kNoDefer));

  // Conditional request
  document->Loader()->SetLoadType(kFrameLoadTypeStandard);
  ResourceRequest conditional("http://www.example.com");
  conditional.SetHTTPHeaderField(HTTPNames::If_Modified_Since, "foo");
  EXPECT_EQ(
      WebCachePolicy::kValidatingCacheData,
      fetch_context->ResourceRequestCachePolicy(
          conditional, Resource::kMainResource, FetchParameters::kNoDefer));

  // FrameLoadTypeReloadBypassingCache
  document->Loader()->SetLoadType(kFrameLoadTypeReloadBypassingCache);
  EXPECT_EQ(WebCachePolicy::kBypassingCache,
            fetch_context->ResourceRequestCachePolicy(
                request, Resource::kMainResource, FetchParameters::kNoDefer));

  // FrameLoadTypeReloadBypassingCache with a conditional request
  document->Loader()->SetLoadType(kFrameLoadTypeReloadBypassingCache);
  EXPECT_EQ(
      WebCachePolicy::kBypassingCache,
      fetch_context->ResourceRequestCachePolicy(
          conditional, Resource::kMainResource, FetchParameters::kNoDefer));

  // FrameLoadTypeReloadBypassingCache with a post request
  document->Loader()->SetLoadType(kFrameLoadTypeReloadBypassingCache);
  EXPECT_EQ(
      WebCachePolicy::kBypassingCache,
      fetch_context->ResourceRequestCachePolicy(
          post_request, Resource::kMainResource, FetchParameters::kNoDefer));

  // Set up a child frame
  FrameFetchContext* child_fetch_context = CreateChildFrame();

  // Child frame as part of back/forward
  document->Loader()->SetLoadType(kFrameLoadTypeBackForward);
  EXPECT_EQ(WebCachePolicy::kReturnCacheDataElseLoad,
            child_fetch_context->ResourceRequestCachePolicy(
                request, Resource::kMainResource, FetchParameters::kNoDefer));

  // Child frame as part of reload
  document->Loader()->SetLoadType(kFrameLoadTypeReload);
  EXPECT_EQ(WebCachePolicy::kUseProtocolCachePolicy,
            child_fetch_context->ResourceRequestCachePolicy(
                request, Resource::kMainResource, FetchParameters::kNoDefer));

  // Child frame as part of reload bypassing cache
  document->Loader()->SetLoadType(kFrameLoadTypeReloadBypassingCache);
  EXPECT_EQ(WebCachePolicy::kBypassingCache,
            child_fetch_context->ResourceRequestCachePolicy(
                request, Resource::kMainResource, FetchParameters::kNoDefer));

  // Per-frame bypassing reload, but parent load type is different.
  // This is not the case users can trigger through user interfaces, but for
  // checking code correctness and consistency.
  document->Loader()->SetLoadType(kFrameLoadTypeReload);
  child_frame->Loader().GetDocumentLoader()->SetLoadType(
      kFrameLoadTypeReloadBypassingCache);
  EXPECT_EQ(WebCachePolicy::kBypassingCache,
            child_fetch_context->ResourceRequestCachePolicy(
                request, Resource::kMainResource, FetchParameters::kNoDefer));
}

TEST_F(FrameFetchContextTest, SubResourceCachePolicy) {
  // Reset load event state: if the load event is finished, we ignore the
  // DocumentLoader load type.
  document->open();
  ASSERT_FALSE(document->LoadEventFinished());

  // Default case
  ResourceRequest request("http://www.example.com/mock");
  EXPECT_EQ(WebCachePolicy::kUseProtocolCachePolicy,
            fetch_context->ResourceRequestCachePolicy(
                request, Resource::kMock, FetchParameters::kNoDefer));

  // FrameLoadTypeReload should not affect sub-resources
  document->Loader()->SetLoadType(kFrameLoadTypeReload);
  EXPECT_EQ(WebCachePolicy::kUseProtocolCachePolicy,
            fetch_context->ResourceRequestCachePolicy(
                request, Resource::kMock, FetchParameters::kNoDefer));

  // Conditional request
  document->Loader()->SetLoadType(kFrameLoadTypeStandard);
  ResourceRequest conditional("http://www.example.com/mock");
  conditional.SetHTTPHeaderField(HTTPNames::If_Modified_Since, "foo");
  EXPECT_EQ(WebCachePolicy::kValidatingCacheData,
            fetch_context->ResourceRequestCachePolicy(
                conditional, Resource::kMock, FetchParameters::kNoDefer));

  // FrameLoadTypeReloadBypassingCache
  document->Loader()->SetLoadType(kFrameLoadTypeReloadBypassingCache);
  EXPECT_EQ(WebCachePolicy::kBypassingCache,
            fetch_context->ResourceRequestCachePolicy(
                request, Resource::kMock, FetchParameters::kNoDefer));

  // FrameLoadTypeReloadBypassingCache with a conditional request
  document->Loader()->SetLoadType(kFrameLoadTypeReloadBypassingCache);
  EXPECT_EQ(WebCachePolicy::kBypassingCache,
            fetch_context->ResourceRequestCachePolicy(
                conditional, Resource::kMock, FetchParameters::kNoDefer));

  // Back/forward navigation
  document->Loader()->SetLoadType(kFrameLoadTypeBackForward);
  EXPECT_EQ(WebCachePolicy::kReturnCacheDataElseLoad,
            fetch_context->ResourceRequestCachePolicy(
                request, Resource::kMock, FetchParameters::kNoDefer));

  // Back/forward navigation with a conditional request
  document->Loader()->SetLoadType(kFrameLoadTypeBackForward);
  EXPECT_EQ(WebCachePolicy::kReturnCacheDataElseLoad,
            fetch_context->ResourceRequestCachePolicy(
                conditional, Resource::kMock, FetchParameters::kNoDefer));
}

TEST_F(FrameFetchContextTest, SetFirstPartyCookieAndRequestorOrigin) {
  struct TestCase {
    const char* document_url;
    bool document_sandboxed;
    const char* requestor_origin;  // "" => null
    WebURLRequest::FrameType frame_type;
    const char* serialized_origin;  // "" => null
  } cases[] = {
      // No document origin => unique request origin
      {"", false, "", WebURLRequest::kFrameTypeNone, "null"},
      {"", true, "", WebURLRequest::kFrameTypeNone, "null"},

      // Document origin => request origin
      {"http://example.test", false, "", WebURLRequest::kFrameTypeNone,
       "http://example.test"},
      {"http://example.test", true, "", WebURLRequest::kFrameTypeNone,
       "http://example.test"},

      // If the request already has a requestor origin, then
      // 'SetFirstPartyCookieAndRequestorOrigin' leaves it alone:
      {"http://example.test", false, "http://not-example.test",
       WebURLRequest::kFrameTypeNone, "http://not-example.test"},
      {"http://example.test", true, "http://not-example.test",
       WebURLRequest::kFrameTypeNone, "http://not-example.test"},
  };

  int index = 0;
  for (const auto& test : cases) {
    SCOPED_TRACE(::testing::Message() << index++ << " " << test.document_url
                                      << " => " << test.serialized_origin);
    // Set up a new document to ensure sandbox flags are cleared:
    dummy_page_holder = DummyPageHolder::Create(IntSize(500, 500));
    dummy_page_holder->GetPage().SetDeviceScaleFactorDeprecated(1.0);
    document = &dummy_page_holder->GetDocument();
    fetch_context =
        static_cast<FrameFetchContext*>(&document->Fetcher()->Context());
    FrameFetchContext::ProvideDocumentToContext(*fetch_context, document.Get());

    // Setup the test:
    document->SetURL(KURL(kParsedURLString, test.document_url));
    document->SetSecurityOrigin(SecurityOrigin::Create(document->Url()));

    if (test.document_sandboxed)
      document->EnforceSandboxFlags(kSandboxOrigin);

    ResourceRequest request("http://example.test/");
    request.SetFrameType(test.frame_type);
    if (strlen(test.requestor_origin) > 0) {
      request.SetRequestorOrigin(SecurityOrigin::Create(
          KURL(kParsedURLString, test.requestor_origin)));
    }

    // Compare the populated |requestorOrigin| against |test.serializedOrigin|
    fetch_context->SetFirstPartyCookieAndRequestorOrigin(request);
    if (strlen(test.serialized_origin) == 0) {
      EXPECT_TRUE(!request.RequestorOrigin());
    } else {
      EXPECT_EQ(String(test.serialized_origin),
                request.RequestorOrigin()->ToString());
    }

    EXPECT_EQ(document->FirstPartyForCookies(), request.FirstPartyForCookies());
  }
}

// Tests if "Save-Data" header is correctly added on the first load and reload.
TEST_F(FrameFetchContextTest, EnableDataSaver) {
  Settings* settings = document->GetFrame()->GetSettings();
  settings->SetDataSaverEnabled(true);
  ResourceRequest resource_request("http://www.example.com");
  fetch_context->AddAdditionalRequestHeaders(resource_request,
                                             kFetchMainResource);
  EXPECT_EQ("on", resource_request.HttpHeaderField("Save-Data"));

  // Subsequent call to addAdditionalRequestHeaders should not append to the
  // save-data header.
  fetch_context->AddAdditionalRequestHeaders(resource_request,
                                             kFetchMainResource);
  EXPECT_EQ("on", resource_request.HttpHeaderField("Save-Data"));
}

// Tests if "Save-Data" header is not added when the data saver is disabled.
TEST_F(FrameFetchContextTest, DisabledDataSaver) {
  ResourceRequest resource_request("http://www.example.com");
  fetch_context->AddAdditionalRequestHeaders(resource_request,
                                             kFetchMainResource);
  EXPECT_EQ(String(), resource_request.HttpHeaderField("Save-Data"));
}

// Tests if reload variants can reflect the current data saver setting.
TEST_F(FrameFetchContextTest, ChangeDataSaverConfig) {
  Settings* settings = document->GetFrame()->GetSettings();
  settings->SetDataSaverEnabled(true);
  ResourceRequest resource_request("http://www.example.com");
  fetch_context->AddAdditionalRequestHeaders(resource_request,
                                             kFetchMainResource);
  EXPECT_EQ("on", resource_request.HttpHeaderField("Save-Data"));

  settings->SetDataSaverEnabled(false);
  document->Loader()->SetLoadType(kFrameLoadTypeReload);
  fetch_context->AddAdditionalRequestHeaders(resource_request,
                                             kFetchMainResource);
  EXPECT_EQ(String(), resource_request.HttpHeaderField("Save-Data"));

  settings->SetDataSaverEnabled(true);
  fetch_context->AddAdditionalRequestHeaders(resource_request,
                                             kFetchMainResource);
  EXPECT_EQ("on", resource_request.HttpHeaderField("Save-Data"));

  settings->SetDataSaverEnabled(false);
  document->Loader()->SetLoadType(kFrameLoadTypeReload);
  fetch_context->AddAdditionalRequestHeaders(resource_request,
                                             kFetchMainResource);
  EXPECT_EQ(String(), resource_request.HttpHeaderField("Save-Data"));
}

// Tests that the embedder gets correct notification when a resource is loaded
// from the memory cache.
TEST_F(FrameFetchContextMockedLocalFrameClientTest,
       DispatchDidLoadResourceFromMemoryCache) {
  ResourceRequest resource_request(url);
  resource_request.SetRequestContext(WebURLRequest::kRequestContextImage);
  resource_request.SetFetchCredentialsMode(
      WebURLRequest::kFetchCredentialsModeOmit);
  Resource* resource = MockResource::Create(resource_request);
  EXPECT_CALL(*client,
              DispatchDidLoadResourceFromMemoryCache(
                  testing::AllOf(
                      testing::Property(&ResourceRequest::Url, url),
                      testing::Property(&ResourceRequest::GetFrameType,
                                        WebURLRequest::kFrameTypeNone),
                      testing::Property(&ResourceRequest::GetRequestContext,
                                        WebURLRequest::kRequestContextImage)),
                  ResourceResponse()));
  fetch_context->DispatchDidLoadResourceFromMemoryCache(
      CreateUniqueIdentifier(), resource_request, resource->GetResponse());
}

// Tests that when a resource with certificate errors is loaded from the memory
// cache, the embedder is notified.
TEST_F(FrameFetchContextMockedLocalFrameClientTest,
       MemoryCacheCertificateError) {
  ResourceRequest resource_request(url);
  resource_request.SetRequestContext(WebURLRequest::kRequestContextImage);
  resource_request.SetFetchCredentialsMode(
      WebURLRequest::kFetchCredentialsModeOmit);
  ResourceResponse response;
  response.SetURL(url);
  response.SetHasMajorCertificateErrors(true);
  Resource* resource = MockResource::Create(resource_request);
  resource->SetResponse(response);
  EXPECT_CALL(*client, DidDisplayContentWithCertificateErrors(url));
  fetch_context->DispatchDidLoadResourceFromMemoryCache(
      CreateUniqueIdentifier(), resource_request, resource->GetResponse());
}

TEST_F(FrameFetchContextSubresourceFilterTest, Filter) {
  SetFilterPolicy(WebDocumentSubresourceFilter::kDisallow);

  EXPECT_EQ(ResourceRequestBlockedReason::kSubresourceFilter, CanRequest());
  EXPECT_EQ(1, GetFilteredLoadCallCount());

  EXPECT_EQ(ResourceRequestBlockedReason::kSubresourceFilter, CanRequest());
  EXPECT_EQ(2, GetFilteredLoadCallCount());

  EXPECT_EQ(ResourceRequestBlockedReason::kSubresourceFilter,
            CanRequestPreload());
  EXPECT_EQ(2, GetFilteredLoadCallCount());

  EXPECT_EQ(ResourceRequestBlockedReason::kSubresourceFilter, CanRequest());
  EXPECT_EQ(3, GetFilteredLoadCallCount());
}

TEST_F(FrameFetchContextSubresourceFilterTest, Allow) {
  SetFilterPolicy(WebDocumentSubresourceFilter::kAllow);

  EXPECT_EQ(ResourceRequestBlockedReason::kNone, CanRequest());
  EXPECT_EQ(0, GetFilteredLoadCallCount());

  EXPECT_EQ(ResourceRequestBlockedReason::kNone, CanRequestPreload());
  EXPECT_EQ(0, GetFilteredLoadCallCount());
}

TEST_F(FrameFetchContextSubresourceFilterTest, WouldDisallow) {
  SetFilterPolicy(WebDocumentSubresourceFilter::kWouldDisallow);

  EXPECT_EQ(ResourceRequestBlockedReason::kNone, CanRequest());
  EXPECT_EQ(0, GetFilteredLoadCallCount());

  EXPECT_EQ(ResourceRequestBlockedReason::kNone, CanRequestPreload());
  EXPECT_EQ(0, GetFilteredLoadCallCount());
}

TEST_F(FrameFetchContextTest, AddAdditionalRequestHeadersWhenDetached) {
  const KURL document_url(KURL(), "https://www2.example.com/fuga/hoge.html");
  const String origin = "https://www2.example.com";
  ResourceRequest request(KURL(KURL(), "https://localhost/"));
  request.SetHTTPMethod("PUT");

  Settings* settings = document->GetFrame()->GetSettings();
  settings->SetDataSaverEnabled(true);
  document->SetSecurityOrigin(SecurityOrigin::Create(KURL(KURL(), origin)));
  document->SetURL(document_url);
  document->SetReferrerPolicy(kReferrerPolicyOrigin);
  document->SetAddressSpace(kWebAddressSpacePublic);

  dummy_page_holder = nullptr;

  EXPECT_FALSE(request.IsExternalRequest());

  fetch_context->AddAdditionalRequestHeaders(request, kFetchSubresource);

  EXPECT_EQ(origin, request.HttpHeaderField(HTTPNames::Origin));
  EXPECT_EQ(String(origin + "/"), request.HttpHeaderField(HTTPNames::Referer));
  EXPECT_EQ(String(), request.HttpHeaderField("Save-Data"));
  EXPECT_TRUE(request.IsExternalRequest());
}

TEST_F(FrameFetchContextTest, ResourceRequestCachePolicyWhenDetached) {
  ResourceRequest request(KURL(KURL(), "https://localhost/"));

  dummy_page_holder = nullptr;

  EXPECT_EQ(WebCachePolicy::kUseProtocolCachePolicy,
            fetch_context->ResourceRequestCachePolicy(
                request, Resource::kRaw, FetchParameters::kNoDefer));
}

TEST_F(FrameFetchContextTest, DispatchDidChangePriorityWhenDetached) {
  dummy_page_holder = nullptr;

  fetch_context->DispatchDidChangeResourcePriority(2, kResourceLoadPriorityLow,
                                                   3);
  // Should not crash.
}

TEST_F(FrameFetchContextMockedLocalFrameClientTest,
       PrepareRequestWhenDetached) {
  Checkpoint checkpoint;

  EXPECT_CALL(checkpoint, Call(1));
  EXPECT_CALL(*client, UserAgent()).WillOnce(testing::Return(String("hi")));
  EXPECT_CALL(checkpoint, Call(2));

  checkpoint.Call(1);
  dummy_page_holder = nullptr;
  checkpoint.Call(2);

  ResourceRequest request(KURL(KURL(), "https://localhost/"));
  fetch_context->PrepareRequest(request,
                                FetchContext::RedirectType::kNotForRedirect);

  EXPECT_EQ("hi", request.HttpHeaderField(HTTPNames::User_Agent));
}

TEST_F(FrameFetchContextTest, DispatchWillSendRequestWhenDetached) {
  ResourceRequest request(KURL(KURL(), "https://www.example.com/"));
  ResourceResponse response;
  FetchInitiatorInfo initiator_info;

  dummy_page_holder = nullptr;

  fetch_context->DispatchWillSendRequest(1, request, response, initiator_info);
  // Should not crash.
}

TEST_F(FrameFetchContextTest,
       DispatchDidLoadResourceFromMemoryCacheWhenDetached) {
  ResourceRequest request(KURL(KURL(), "https://www.example.com/"));
  ResourceResponse response;
  FetchInitiatorInfo initiator_info;

  dummy_page_holder = nullptr;

  fetch_context->DispatchDidLoadResourceFromMemoryCache(8, request, response);
  // Should not crash.
}

TEST_F(FrameFetchContextTest, DispatchDidReceiveResponseWhenDetached) {
  ResourceRequest request(KURL(KURL(), "https://www.example.com/"));
  request.SetFetchCredentialsMode(WebURLRequest::kFetchCredentialsModeOmit);
  Resource* resource = MockResource::Create(request);
  ResourceResponse response;

  dummy_page_holder = nullptr;

  fetch_context->DispatchDidReceiveResponse(
      3, response, WebURLRequest::kFrameTypeTopLevel,
      WebURLRequest::kRequestContextFetch, resource,
      FetchContext::ResourceResponseType::kNotFromMemoryCache);
  // Should not crash.
}

TEST_F(FrameFetchContextTest, DispatchDidReceiveDataWhenDetached) {
  dummy_page_holder = nullptr;

  fetch_context->DispatchDidReceiveData(3, "abcd", 4);
  // Should not crash.
}

TEST_F(FrameFetchContextTest, DispatchDidReceiveEncodedDataWhenDetached) {
  dummy_page_holder = nullptr;

  fetch_context->DispatchDidReceiveEncodedData(8, 9);
  // Should not crash.
}

TEST_F(FrameFetchContextTest, DispatchDidDownloadDataWhenDetached) {
  dummy_page_holder = nullptr;

  fetch_context->DispatchDidDownloadData(4, 7, 9);
  // Should not crash.
}

TEST_F(FrameFetchContextTest, DispatchDidFinishLoadingWhenDetached) {
  dummy_page_holder = nullptr;

  fetch_context->DispatchDidFinishLoading(4, 0.3, 8, 10);
  // Should not crash.
}

TEST_F(FrameFetchContextTest, DispatchDidFailWhenDetached) {
  dummy_page_holder = nullptr;

  fetch_context->DispatchDidFail(8, ResourceError(), 5, false);
  // Should not crash.
}

TEST_F(FrameFetchContextTest, ShouldLoadNewResourceWhenDetached) {
  dummy_page_holder = nullptr;

  EXPECT_TRUE(fetch_context->ShouldLoadNewResource(Resource::kImage));
  EXPECT_TRUE(fetch_context->ShouldLoadNewResource(Resource::kRaw));
  EXPECT_TRUE(fetch_context->ShouldLoadNewResource(Resource::kScript));
  EXPECT_TRUE(fetch_context->ShouldLoadNewResource(Resource::kMainResource));
}

TEST_F(FrameFetchContextTest, RecordLoadingActivityWhenDetached) {
  ResourceRequest request(KURL(KURL(), "https://www.example.com/"));

  dummy_page_holder = nullptr;

  fetch_context->RecordLoadingActivity(4, request, Resource::kRaw,
                                       FetchInitiatorTypeNames::xmlhttprequest);
  // Should not crash.

  fetch_context->RecordLoadingActivity(8, request, Resource::kRaw,
                                       FetchInitiatorTypeNames::document);
  // Should not crash.
}

TEST_F(FrameFetchContextTest, DidLoadResourceWhenDetached) {
  ResourceRequest request(KURL(KURL(), "https://www.example.com/"));
  request.SetFetchCredentialsMode(WebURLRequest::kFetchCredentialsModeOmit);
  Resource* resource = MockResource::Create(request);

  dummy_page_holder = nullptr;

  fetch_context->DidLoadResource(resource);
  // Should not crash.
}

TEST_F(FrameFetchContextTest, AddResourceTimingWhenDetached) {
  RefPtr<ResourceTimingInfo> info =
      ResourceTimingInfo::Create("type", 0.3, false);

  dummy_page_holder = nullptr;

  fetch_context->AddResourceTiming(*info);
  // Should not crash.
}

TEST_F(FrameFetchContextTest, AllowImageWhenDetached) {
  KURL url(KURL(), "https://www.example.com/");

  dummy_page_holder = nullptr;

  EXPECT_TRUE(fetch_context->AllowImage(true, url));
  EXPECT_TRUE(fetch_context->AllowImage(false, url));
}

TEST_F(FrameFetchContextTest, IsControlledByServiceWorkerWhenDetached) {
  dummy_page_holder = nullptr;

  EXPECT_FALSE(fetch_context->IsControlledByServiceWorker());
}

TEST_F(FrameFetchContextTest, IsMainFrameWhenDetached) {
  FetchContext* child_fetch_context = CreateChildFrame();

  EXPECT_TRUE(fetch_context->IsMainFrame());
  EXPECT_FALSE(child_fetch_context->IsMainFrame());

  dummy_page_holder = nullptr;

  EXPECT_TRUE(fetch_context->IsMainFrame());
  EXPECT_FALSE(child_fetch_context->IsMainFrame());
}

TEST_F(FrameFetchContextTest, DefersLoadingWhenDetached) {
  EXPECT_FALSE(fetch_context->DefersLoading());
}

TEST_F(FrameFetchContextTest, IsLoadCompleteWhenDetached_1) {
  document->open();
  EXPECT_FALSE(fetch_context->IsLoadComplete());

  dummy_page_holder = nullptr;

  EXPECT_TRUE(fetch_context->IsLoadComplete());
}

TEST_F(FrameFetchContextTest, IsLoadCompleteWhenDetached_2) {
  EXPECT_TRUE(fetch_context->IsLoadComplete());

  dummy_page_holder = nullptr;

  EXPECT_TRUE(fetch_context->IsLoadComplete());
}

TEST_F(FrameFetchContextTest, PageDismissalEventBeingDispatchedWhenDetached) {
  dummy_page_holder = nullptr;

  EXPECT_FALSE(fetch_context->PageDismissalEventBeingDispatched());
}

TEST_F(FrameFetchContextTest, UpdateTimingInfoForIFrameNavigationWhenDetached) {
  RefPtr<ResourceTimingInfo> info =
      ResourceTimingInfo::Create("type", 0.3, false);

  dummy_page_holder = nullptr;

  fetch_context->UpdateTimingInfoForIFrameNavigation(info.Get());
  // Should not crash.
}

TEST_F(FrameFetchContextTest, SendImagePingWhenDetached) {
  KURL url(KURL(), "https://www.example.com/");

  dummy_page_holder = nullptr;

  fetch_context->SendImagePing(url);
  // Should not crash. Nothing should be sent.
}

TEST_F(FrameFetchContextTest, AddConsoleMessageWhenDetached) {
  dummy_page_holder = nullptr;

  fetch_context->AddConsoleMessage("foobar");
  // Should not crash.
}

TEST_F(FrameFetchContextTest, GetSecurityOriginWhenDetached) {
  RefPtr<SecurityOrigin> origin =
      SecurityOrigin::Create(KURL(KURL(), "https://www.example.com"));
  document->SetSecurityOrigin(origin);

  dummy_page_holder = nullptr;
  EXPECT_EQ(origin.Get(), fetch_context->GetSecurityOrigin());
}

TEST_F(FrameFetchContextTest, PopulateResourceRequestWhenDetached) {
  KURL url(KURL(), "https://www.example.com/");
  ResourceRequest request(url);
  request.SetFetchCredentialsMode(WebURLRequest::kFetchCredentialsModeOmit);

  ClientHintsPreferences client_hints_preferences;
  client_hints_preferences.SetShouldSendDeviceRAM(true);
  client_hints_preferences.SetShouldSendDPR(true);
  client_hints_preferences.SetShouldSendResourceWidth(true);
  client_hints_preferences.SetShouldSendViewportWidth(true);

  FetchParameters::ResourceWidth resource_width;
  ResourceLoaderOptions options;

  document->GetClientHintsPreferences().SetShouldSendDeviceRAM(true);
  document->GetClientHintsPreferences().SetShouldSendDPR(true);
  document->GetClientHintsPreferences().SetShouldSendResourceWidth(true);
  document->GetClientHintsPreferences().SetShouldSendViewportWidth(true);

  dummy_page_holder = nullptr;

  fetch_context->PopulateResourceRequest(
      url, Resource::kRaw, client_hints_preferences, resource_width, options,
      SecurityViolationReportingPolicy::kReport, request);
  // Should not crash.
}

TEST_F(FrameFetchContextTest,
       SetFirstPartyCookieAndRequestorOriginWhenDetached) {
  KURL url(KURL(), "https://www.example.com/hoge/fuga");
  ResourceRequest request(url);
  KURL document_url(KURL(), "https://www2.example.com/foo/bar");
  RefPtr<SecurityOrigin> origin = SecurityOrigin::Create(document_url);

  document->SetSecurityOrigin(origin);
  document->SetURL(document_url);

  dummy_page_holder = nullptr;

  fetch_context->SetFirstPartyCookieAndRequestorOrigin(request);

  EXPECT_EQ(document_url, request.FirstPartyForCookies());
  EXPECT_EQ(origin, request.RequestorOrigin());
}

TEST_F(FrameFetchContextTest, ArchiveWhenDetached) {
  FetchContext* child_fetch_context = CreateChildFrame();

  dummy_page_holder = nullptr;
  child_frame->Detach(FrameDetachType::kRemove);
  child_frame = nullptr;

  EXPECT_EQ(nullptr, child_fetch_context->Archive());
}

// Tests if "Intervention" header is added for frame with Client Lo-Fi enabled.
TEST_F(FrameFetchContextMockedLocalFrameClientTest,
       ClientLoFiInterventionHeader) {
  // Verify header not added if Lo-Fi not active.
  EXPECT_CALL(*client, IsClientLoFiActiveForFrame())
      .WillRepeatedly(testing::Return(false));
  ResourceRequest resource_request("http://www.example.com/style.css");
  fetch_context->AddAdditionalRequestHeaders(resource_request,
                                             kFetchMainResource);
  EXPECT_EQ(g_null_atom, resource_request.HttpHeaderField("Intervention"));

  // Verify header is added if Lo-Fi is active.
  EXPECT_CALL(*client, IsClientLoFiActiveForFrame())
      .WillRepeatedly(testing::Return(true));
  fetch_context->AddAdditionalRequestHeaders(resource_request,
                                             kFetchSubresource);
  EXPECT_EQ(
      "<https://www.chromestatus.com/features/6072546726248448>; "
      "level=\"warning\"",
      resource_request.HttpHeaderField("Intervention"));

  // Verify appended to an existing "Intervention" header value.
  ResourceRequest resource_request2("http://www.example.com/getad.js");
  resource_request2.SetHTTPHeaderField("Intervention",
                                       "<https://otherintervention.org>");
  fetch_context->AddAdditionalRequestHeaders(resource_request2,
                                             kFetchSubresource);
  EXPECT_EQ(
      "<https://otherintervention.org>, "
      "<https://www.chromestatus.com/features/6072546726248448>; "
      "level=\"warning\"",
      resource_request2.HttpHeaderField("Intervention"));
}

}  // namespace blink
