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

#include <atomic>

#include "base/path_service.h"
#include "base/strings/pattern.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "content/browser/renderer_host/back_forward_cache_disable.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/renderer.mojom.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/content_paths.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/resource_load_observer.h"
#include "content/shell/browser/shell.h"
#include "content/test/content_browser_test_utils_internal.h"
#include "net/base/features.h"
#include "net/base/network_isolation_key.h"
#include "net/base/schemeful_site.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/default_handlers.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "net/test/scoped_mutually_exclusive_feature_list.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/frame/fullscreen.mojom.h"
#include "url/gurl.h"

namespace content {
namespace {

class SplitCacheContentBrowserTestBase : public ContentBrowserTest {
 public:
  enum class Context { kMainFrame, kSameOriginFrame, kCrossOriginFrame };

  SplitCacheContentBrowserTestBase() = default;

  SplitCacheContentBrowserTestBase(const SplitCacheContentBrowserTestBase&) =
      delete;
  SplitCacheContentBrowserTestBase& operator=(
      const SplitCacheContentBrowserTestBase&) = delete;

  void SetUp() override {
    RenderWidgetHostImpl::DisableResizeAckCheckForTesting();
    ContentBrowserTest::SetUp();
  }

  void SetUpOnMainThread() override {
    // Setup the server to allow serving separate sites, so we can perform
    // cross-process navigation.
    host_resolver()->AddRule("*", "127.0.0.1");

    embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
        &SplitCacheContentBrowserTestBase::CachedScriptHandler,
        base::Unretained(this)));
    ASSERT_TRUE(embedded_test_server()->Start());
  }

  std::unique_ptr<net::test_server::HttpResponse> CachedScriptHandler(
      const net::test_server::HttpRequest& request) {
    GURL absolute_url = embedded_test_server()->GetURL(request.relative_url);

    // Return a page that redirects to d.com/title1.html.
    if (absolute_url.GetPath() == "/redirect_to_d") {
      auto http_response =
          std::make_unique<net::test_server::BasicHttpResponse>();
      http_response->set_code(net::HTTP_SEE_OTHER);
      http_response->AddCustomHeader(
          "Location",
          embedded_test_server()->GetURL("d.com", "/title1.html").spec());
      return http_response;
    }

    // Return valid cacheable script.
    if (absolute_url.GetPath() == "/script") {
      auto http_response =
          std::make_unique<net::test_server::BasicHttpResponse>();
      http_response->set_code(net::HTTP_OK);
      http_response->set_content("console.log(\"Hello World\");");
      http_response->set_content_type("application/javascript");
      http_response->AddCustomHeader("Cache-Control", "max-age=1000");
      return http_response;
    }

    // A basic cacheable worker that loads 3p.com/script
    if (absolute_url.GetPath() == "/worker.js") {
      auto http_response =
          std::make_unique<net::test_server::BasicHttpResponse>();
      http_response->set_code(net::HTTP_OK);

      GURL resource = GenURL("3p.com", "/script");
      // Self-terminate the worker just after loading the third party
      // script, so that the parent context doesn't need to wait for the
      // worker's termination when cleaning up the test. See
      // https://crbug.com/1104847 for more details.
      std::string content = base::StringPrintf("importScripts('%s');\nclose();",
                                               resource.spec().c_str());

      http_response->set_content(content);
      http_response->set_content_type("application/javascript");
      http_response->AddCustomHeader("Cache-Control", "max-age=100000");
      return http_response;
    }

    // Make the document resource cacheable.
    if (absolute_url.GetPath() == "/title1.html") {
      auto http_response =
          std::make_unique<net::test_server::BasicHttpResponse>();
      http_response->set_code(net::HTTP_OK);
      http_response->AddCustomHeader("Cache-Control", "max-age=100000");
      return http_response;
    }

    // A cacheable worker that loads a nested worker on an origin provided
    // as a query param.
    if (absolute_url.GetPath() == "/embedding_worker.js") {
      auto http_response =
          std::make_unique<net::test_server::BasicHttpResponse>();
      http_response->set_code(net::HTTP_OK);

      GURL resource =
          GenURL(base::StringPrintf("%s.com", absolute_url.GetQuery().c_str()),
                 "/worker.js");

      const char kLoadWorkerScript[] = "let w = new Worker('%s');";
      std::string content =
          base::StringPrintf(kLoadWorkerScript, resource.spec().c_str());

      http_response->set_content(content);
      http_response->set_content_type("application/javascript");
      http_response->AddCustomHeader("Cache-Control", "max-age=100000");
      return http_response;
    }

    return nullptr;
  }

 protected:
  // Creates and loads subframe, waits for load to stop, and then returns
  // subframe from the web contents frame tree.
  RenderFrameHost* CreateSubframe(const GURL& sub_frame) {
    EXPECT_TRUE(ExecJs(shell(), GetSubframeScript(sub_frame)));
    EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));

    return static_cast<WebContentsImpl*>(shell()->web_contents())
        ->GetPrimaryFrameTree()
        .root()
        ->child_at(0)
        ->current_frame_host();
  }

  // Loads 3p.com/script on page |url|, optionally from |sub_frame| if it's
  // valid, and returns whether the script was cached or not.
  bool TestResourceLoad(const GURL& url, const GURL& sub_frame) {
    return TestResourceLoadHelper(url, sub_frame, GURL());
  }

  // Loads 3p.com/script on page |url| from |worker| and returns whether
  // the script was cached or not.
  bool TestResourceLoadFromDedicatedWorker(const GURL& url,
                                           const GURL& worker) {
    DCHECK(worker.is_valid());
    return TestResourceLoadHelper(url, GURL(), worker);
  }

  // Loads 3p.com/script on page |url| from |worker| inside |sub_frame|
  // and returns whether the script was cached or not.
  bool TestResourceLoadFromDedicatedWorkerInIframe(const GURL& url,
                                                   const GURL& sub_frame,
                                                   const GURL& worker) {
    DCHECK(sub_frame.is_valid());
    DCHECK(worker.is_valid());
    return TestResourceLoadHelper(url, sub_frame, worker);
  }

  // Loads 3p.com/script on |popup| opened from page |url| and returns whether
  // the script was cached or not.
  bool TestResourceLoadFromPopup(const GURL& url, const GURL& popup) {
    DCHECK(popup.is_valid());
    return TestResourceLoadHelper(url, popup, GURL(), true);
  }

  // Loads 3p.com/script on page |url|. If |new_frame| is valid, it is loaded
  // from a new frame with that url; otherwise, it is loaded from the main
  // frame. This new frame is a popup if |use_popup|; otherwise, it is a
  // subframe. The load is optionally performed by |worker| if it's valid.
  bool TestResourceLoadHelper(const GURL& url,
                              const GURL& new_frame,
                              const GURL& worker,
                              bool use_popup = false) {
    DCHECK(url.is_valid());

    // Allocate a new process to prevent using the in-memory cache.
    // 1) Prevent the old page from entering the back-forward cache. Otherwise
    //    the old process will be kept alive, because it is still being used.
    // 2) Navigate to a WebUI URL, which uses a new process.
    DisableBFCacheForRFHForTesting(
        shell()->web_contents()->GetPrimaryMainFrame());
    EXPECT_TRUE(NavigateToURL(shell(), GetWebUIURL("blob-internals")));

    // In the case of a redirect, the observed URL will be different from
    // what NavigateToURL(...) expects.
    if (base::StartsWith(url.GetPath(), "/redirect",
                         base::CompareCase::SENSITIVE)) {
      EXPECT_FALSE(NavigateToURL(shell(), url));
    } else {
      EXPECT_TRUE(NavigateToURL(shell(), url));
    }

    RenderFrameHost* host_to_load_resource =
        shell()->web_contents()->GetPrimaryMainFrame();
    RenderFrameHostImpl* main_frame =
        static_cast<RenderFrameHostImpl*>(host_to_load_resource);

    Shell* shell_to_observe = shell();

    if (new_frame.is_valid()) {
      // If there is supposed to be a subframe or popup, create it.
      if (use_popup) {
        shell_to_observe = OpenPopup(main_frame, new_frame, "");
        host_to_load_resource =
            static_cast<WebContentsImpl*>(shell_to_observe->web_contents())
                ->GetPrimaryMainFrame();
      } else {
        host_to_load_resource = CreateSubframe(new_frame);
      }
    }

    // `shell_to_observe` may still contain responses depending on process reuse
    // policies. Clear the in-memory cache in `shell_to_observe` to make sure
    // the following ResourceLoadObserver can observe network requests.
    base::RunLoop loop;
    shell_to_observe->web_contents()
        ->GetPrimaryMainFrame()
        ->GetProcess()
        ->GetRendererInterface()
        ->PurgeResourceCache(loop.QuitClosure());
    loop.Run();
    // Observe network requests.
    ResourceLoadObserver observer(shell_to_observe);

    GURL resource = GenURL("3p.com", "/script");

    // If there is supposed to be a worker to load this resource, create it.
    // Otherwise, load the resource directly.
    if (worker.is_valid()) {
      EXPECT_TRUE(ExecJs(host_to_load_resource, GetWorkerScript(worker)));
    } else {
      EXPECT_TRUE(
          ExecJs(host_to_load_resource, GetLoadResourceScript(resource)));
    }

    observer.WaitForResourceCompletion(resource);

    // Test the network isolation key.
    url::Origin top_frame_origin =
        main_frame->frame_tree_node()->current_origin();

    RenderFrameHostImpl* frame_host =
        static_cast<RenderFrameHostImpl*>(host_to_load_resource);
    url::Origin frame_origin;
    if (new_frame.is_empty()) {
      frame_origin = top_frame_origin;
    } else {
      frame_origin = url::Origin::Create(new_frame);
      if (use_popup && !frame_origin.opaque()) {
        // The popup is in a new WebContents, so its top_frame_origin is also
        // new unless it is blank.
        top_frame_origin = frame_origin;
      } else {
        // Take redirects and initially empty subframes/popups into account.
        frame_origin = frame_host->GetLastCommittedOrigin();
      }
    }

    if (!top_frame_origin.opaque() && !frame_origin.opaque()) {
      EXPECT_EQ(net::NetworkIsolationKey(net::SchemefulSite(top_frame_origin),
                                         net::SchemefulSite(frame_origin)),
                frame_host->GetNetworkIsolationKey());
    } else {
      EXPECT_TRUE(frame_host->GetNetworkIsolationKey().IsTransient());
    }

    return (*observer.GetResource(resource))->was_cached;
  }

  // Navigates to |url| and returns if the navigation resource was fetched from
  // the cache or not.
  bool NavigationResourceCached(const GURL& url,
                                const GURL& sub_frame,
                                bool subframe_navigation_resource_cached) {
    return NavigationResourceCached(url, url, sub_frame,
                                    subframe_navigation_resource_cached);
  }

  // Same as above, but allows explicitly specifying the expected commit URL
  // for the navigation to |url|, in case it differs.
  bool NavigationResourceCached(const GURL& url,
                                const GURL& expected_commit_url,
                                const GURL& sub_frame,
                                bool subframe_navigation_resource_cached) {
    // Do a cross-process navigation to clear the in-memory cache.
    // We assume that we don't start this call from "chrome://blob-internals",
    // as otherwise it won't be a cross-process navigation. We are relying on
    // this navigation to discard the old process.
    EXPECT_TRUE(NavigateToURL(shell(), GetWebUIURL("blob-internals")));

    // Observe network requests.
    ResourceLoadObserver observer(shell());

    EXPECT_TRUE(NavigateToURL(shell(), url, expected_commit_url));

    RenderFrameHostImpl* main_frame = static_cast<RenderFrameHostImpl*>(
        shell()->web_contents()->GetPrimaryMainFrame());

    observer.WaitForResourceCompletion(url);

    if (sub_frame.is_valid()) {
      EXPECT_EQ(1U, main_frame->frame_tree_node()->child_count());
      NavigateFrameToURL(main_frame->frame_tree_node()->child_at(0), sub_frame);
      EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
      observer.WaitForResourceCompletion(sub_frame);
      EXPECT_EQ(subframe_navigation_resource_cached,
                (*observer.GetResource(sub_frame))->was_cached);
    }

    return (*observer.GetResource(url))->was_cached;
  }

  // Loads a dedicated worker script and checks to see whether or not the
  // script was cached.
  bool DedicatedWorkerScriptCached(const GURL& url,
                                   const GURL& sub_frame,
                                   const GURL& worker) {
    DCHECK(url.is_valid());
    DCHECK(worker.is_valid());

    // Do a cross-process navigation to clear the in-memory cache.
    // We assume that we don't start this call from "chrome://blob-internals",
    // as otherwise it won't be a cross-process navigation. We are relying on
    // this navigation to discard the old process.
    EXPECT_TRUE(NavigateToURL(shell(), GetWebUIURL("blob-internals")));

    // Observe network requests.
    ResourceLoadObserver observer(shell());

    EXPECT_TRUE(NavigateToURL(shell(), url));

    RenderFrameHost* host_to_load_resource =
        shell()->web_contents()->GetPrimaryMainFrame();

    // If there is supposed to be a subframe, create it.
    if (sub_frame.is_valid()) {
      host_to_load_resource = CreateSubframe(sub_frame);
    }

    EXPECT_TRUE(ExecJs(host_to_load_resource, GetWorkerScript(worker)));

    observer.WaitForResourceCompletion(GenURL("3p.com", "/script"));
    observer.WaitForResourceCompletion(worker);

    return (*observer.GetResource(worker))->was_cached;
  }

  bool NavigationRedirectCached(const GURL& url, const GURL& redirect_url) {
    // Do a cross-process navigation to clear the in-memory cache.
    // We assume that we don't start this call from "chrome://blob-internals",
    // as otherwise it won't be a cross-process navigation. We are relying on
    // this navigation to discard the old process.
    EXPECT_TRUE(NavigateToURL(shell(), GetWebUIURL("blob-internals")));

    EXPECT_TRUE(NavigateToURL(shell(), url));

    // Observe the redirect.
    ResourceLoadObserver observer(shell());
    EXPECT_TRUE(ExecJs(shell(), GetRedirectScript(redirect_url)));
    WaitForLoadStop(shell()->web_contents());
    observer.WaitForResourceCompletion(redirect_url);

    return (*observer.GetResource(redirect_url))->was_cached;
  }

  // Gets script to create subframe.
  std::string GetSubframeScript(const GURL& sub_frame) {
    const char kLoadIframeScript[] = R"(
        let iframe = document.createElement('iframe');
        iframe.src = $1;
        document.body.appendChild(iframe);
      )";
    return JsReplace(kLoadIframeScript, sub_frame);
  }

  // Gets script to create worker.
  std::string GetWorkerScript(const GURL& worker) {
    const char kLoadWorkerScript[] = "let w = new Worker($1);";
    return JsReplace(kLoadWorkerScript, worker);
  }

  // Gets script to load resource.
  std::string GetLoadResourceScript(const GURL& resource) {
    const char kLoadResourceScript[] = R"(
        let script = document.createElement('script');
        script.src = $1;
        document.body.appendChild(script);
      )";
    return JsReplace(kLoadResourceScript, resource);
  }

  // Gets script to redirect via JavaScript.
  std::string GetRedirectScript(const GURL& location) {
    const char kRedirectScript[] = R"(
        window.location.href = $1;
      )";
    return JsReplace(kRedirectScript, location);
  }

  GURL GenURL(const std::string& host, const std::string& path) {
    return embedded_test_server()->GetURL(host, path);
  }
};

class SplitCacheEnabledContentBrowserTest
    : public SplitCacheContentBrowserTestBase {
 public:
  SplitCacheEnabledContentBrowserTest() {
    split_cache_enabled_feature_list_.InitAndEnableFeature(
        net::features::kSplitCacheByNetworkIsolationKey);
  }

 private:
  base::test::ScopedFeatureList split_cache_enabled_feature_list_;
};

class SplitCacheDisabledContentBrowserTest
    : public SplitCacheContentBrowserTestBase {
 public:
  SplitCacheDisabledContentBrowserTest() {
    split_cache_disabled_feature_list_.InitAndDisableFeature(
        net::features::kSplitCacheByNetworkIsolationKey);
  }

 private:
  base::test::ScopedFeatureList split_cache_disabled_feature_list_;
};

IN_PROC_BROWSER_TEST_F(SplitCacheEnabledContentBrowserTest, MainFrame) {
  // Load a cacheable resource for the first time, and it's not cached.
  EXPECT_FALSE(TestResourceLoad(GenURL("a.com", "/title1.html"), GURL()));

  // The second time, it's cached.
  EXPECT_TRUE(TestResourceLoad(GenURL("a.com", "/title1.html"), GURL()));

  // Now load it from a different site, and the resource isn't cached because
  // the top frame origin is different.
  EXPECT_FALSE(TestResourceLoad(GenURL("b.com", "/title1.html"), GURL()));

  // Now load it from 3p.com, which is same-site to the cacheable
  // resource. Still not supposed to be cached.
  EXPECT_FALSE(TestResourceLoad(GenURL("3p.com", "/title1.html"), GURL()));
}

IN_PROC_BROWSER_TEST_F(SplitCacheEnabledContentBrowserTest, MainFrameRedirect) {
  // Load a cacheable resource for the first time, and it's not cached.
  EXPECT_FALSE(TestResourceLoad(GenURL("a.com", "/title1.html"), GURL()));
  ASSERT_TRUE(TestResourceLoad(GenURL("a.com", "/title1.html"), GURL()));

  // Load it from a a.com/redirect_to_d which redirects to d.com/title1.html and
  // the resource shouldn't be cached because now we're on d.com.
  EXPECT_FALSE(TestResourceLoad(GenURL("a.com", "/redirect_to_d"), GURL()));

  // Navigate to d.com directly. The main resource should be cached due to the
  // earlier navigation.
  EXPECT_TRUE(TestResourceLoad(GenURL("d.com", "/title1.html"), GURL()));
}

IN_PROC_BROWSER_TEST_F(SplitCacheEnabledContentBrowserTest, Subframe) {
  // Load a cacheable resource for the first time, and it's not cached.
  EXPECT_FALSE(TestResourceLoad(GenURL("a.com", "/title1.html"), GURL()));
  ASSERT_TRUE(TestResourceLoad(GenURL("a.com", "/title1.html"), GURL()));

  // Load the resource from a same-origin iframe on a page where it's already
  // cached. It should still be cached.
  EXPECT_TRUE(TestResourceLoad(GenURL("a.com", "/title1.html"),
                               GenURL("a.com", "/title1.html")));

  // Load the resource from a cross-origin iframe on a page where the
  // iframe hasn't been cached previously.
  EXPECT_FALSE(TestResourceLoad(GenURL("a.com", "/title1.html"),
                                GenURL("e.com", "/title1.html")));
  EXPECT_TRUE(TestResourceLoad(GenURL("a.com", "/title1.html"),
                               GenURL("e.com", "/title1.html")));

  // Load the resource from a same-origin iframe on a page where it's not
  // cached. It should not be cached.
  EXPECT_FALSE(TestResourceLoad(GenURL("e.com", "/title1.html"),
                                GenURL("e.com", "/title1.html")));
  EXPECT_TRUE(TestResourceLoad(GenURL("e.com", "/title1.html"),
                               GenURL("e.com", "/title1.html")));

  // Load the resource from a cross-origin iframe where the iframe's origin has
  // seen the object before but the top frame hasn't. It should not be cached.
  EXPECT_FALSE(TestResourceLoad(GenURL("f.com", "/title1.html"),
                                GenURL("a.com", "/title1.html")));
}

IN_PROC_BROWSER_TEST_F(SplitCacheEnabledContentBrowserTest, MainFrameDataUrl) {
  // Load a cacheable resource for the first time, and it's not cached.
  EXPECT_FALSE(TestResourceLoad(GenURL("a.com", "/title1.html"), GURL()));
  ASSERT_TRUE(TestResourceLoad(GenURL("a.com", "/title1.html"), GURL()));

  // Load the resource from a data url which has an opaque origin. It shouldn't
  // be cached.
  GURL data_url("data:text/html,<body>Hello World</body>");
  EXPECT_FALSE(TestResourceLoad(data_url, GURL()));

  // Load the same resource from the same data url, it shouldn't be cached
  // because the origin should be unique.
  EXPECT_FALSE(TestResourceLoad(data_url, GURL()));
}

IN_PROC_BROWSER_TEST_F(SplitCacheEnabledContentBrowserTest,
                       MainFrameAboutBlank) {
  // Load a cacheable resource for the first time, and it's not cached.
  EXPECT_FALSE(TestResourceLoad(GenURL("a.com", "/title1.html"), GURL()));
  ASSERT_TRUE(TestResourceLoad(GenURL("a.com", "/title1.html"), GURL()));

  // Load the resource from a document that points to about:blank.
  GURL blank_url(url::kAboutBlankURL);
  EXPECT_FALSE(TestResourceLoad(blank_url, GURL()));

  // Load the same resource from about:blank url again, it shouldn't be cached
  // because the origin is unique. TODO(crbug.com/40092527) will change this
  // behavior and about:blank main frame pages will inherit the origin of the
  // page that opened it.
  EXPECT_FALSE(TestResourceLoad(blank_url, GURL()));
}

IN_PROC_BROWSER_TEST_F(SplitCacheEnabledContentBrowserTest, SubFrameRedirect) {
  // Load a cacheable resource for the first time, and it's not cached.
  EXPECT_FALSE(TestResourceLoad(GenURL("a.com", "/title1.html"), GURL()));
  ASSERT_TRUE(TestResourceLoad(GenURL("a.com", "/title1.html"), GURL()));

  // Load it from a a.com/redirect_to_d which redirects to d.com/title1.html and
  // the resource shouldn't be cached because now we're on d.com.
  EXPECT_FALSE(TestResourceLoad(GenURL("a.com", "/title1.html"),
                                GenURL("a.com", "/redirect_to_d")));

  // Now load it from the d.com iframe directly. It should be cached.
  EXPECT_TRUE(TestResourceLoad(GenURL("a.com", "/title1.html"),
                               GenURL("d.com", "/title1.html")));
}

IN_PROC_BROWSER_TEST_F(SplitCacheEnabledContentBrowserTest, SubFrameDataUrl) {
  // Load a cacheable resource for the first time, and it's not cached.
  EXPECT_FALSE(TestResourceLoad(GenURL("a.com", "/title1.html"), GURL()));
  ASSERT_TRUE(TestResourceLoad(GenURL("a.com", "/title1.html"), GURL()));

  // Load the resource from a data url which has an opaque origin. It shouldn't
  // be cached.
  GURL data_url("data:text/html,<body>Hello World</body>");
  EXPECT_FALSE(TestResourceLoad(GenURL("a.com", "/title1.html"), data_url));

  // Load the same resource from the same data url. It shouldn't be cached
  // because the cache isn't used for transient origins.
  EXPECT_FALSE(TestResourceLoad(GenURL("a.com", "/title1.html"), data_url));
}

IN_PROC_BROWSER_TEST_F(SplitCacheEnabledContentBrowserTest,
                       SubframeAboutBlank) {
  // Load a cacheable resource for the first time, and it's not cached.
  EXPECT_FALSE(TestResourceLoad(GenURL("a.com", "/title1.html"), GURL()));
  ASSERT_TRUE(TestResourceLoad(GenURL("a.com", "/title1.html"), GURL()));

  // Load the resource from a subframe document that points to about:blank. The
  // resource is cached because the resource load is using the main frame's
  // URLLoaderFactory and main frame's factory has the NIK set to
  // (a.com, a.com) which is already in the cache.
  GURL blank_url(url::kAboutBlankURL);
  EXPECT_TRUE(TestResourceLoad(GenURL("a.com", "/title1.html"), blank_url));

  // Load the resource from a popup window that points to about:blank. The
  // resource is cached because the resource load is using the original main
  // frame's URLLoaderFactory and the original main frame's factory has the NIK
  // set to (a.com, a.com) which is already in the cache.
  EXPECT_TRUE(
      TestResourceLoadFromPopup(GenURL("a.com", "/title1.html"), blank_url));
}

IN_PROC_BROWSER_TEST_F(SplitCacheEnabledContentBrowserTest, Popup) {
  // Load a cacheable resource for the first time, and it's not cached.
  EXPECT_FALSE(TestResourceLoad(GenURL("a.com", "/title1.html"), GURL()));
  ASSERT_TRUE(TestResourceLoad(GenURL("a.com", "/title1.html"), GURL()));

  // Load the resource from a popup window that points to a new origin. The
  // resource is not cached because the resource load is using a NIK set to
  // (g.com, g.com).
  EXPECT_FALSE(TestResourceLoadFromPopup(GenURL("a.com", "/title1.html"),
                                         GenURL("g.com", "/title1.html")));

  // Load a cacheable resource for the first time, and it's not cached.
  EXPECT_FALSE(TestResourceLoad(GenURL("a.foo.com", "/title1.html"), GURL()));

  // The second time, it's cached when accessed with the same eTLD+1.
  EXPECT_TRUE(TestResourceLoad(GenURL("b.foo.com", "/title1.html"), GURL()));

  // Now load it from a different site, and the resource isn't cached.
  EXPECT_FALSE(TestResourceLoad(GenURL("b.com", "/title1.html"), GURL()));

  // Now load it from 3p.com, which is same-site to the cacheable
  // resource. Still not supposed to be cached.
  EXPECT_FALSE(TestResourceLoad(GenURL("3p.com", "/title1.html"), GURL()));

  // Test case with iframe. This should be a cache hit since the network
  // isolation key is (foo.com, foo.com) as in the first case.
  EXPECT_TRUE(TestResourceLoad(GenURL("a.foo.com", "/title1.html"),
                               GenURL("iframe.foo.com", "/title1.html")));
}

IN_PROC_BROWSER_TEST_F(SplitCacheDisabledContentBrowserTest, NonSplitCache) {
  // Load a cacheable resource for the first time, and it's not cached.
  EXPECT_FALSE(TestResourceLoad(GenURL("a.com", "/title1.html"), GURL()));

  // The second time, it's cached.
  EXPECT_TRUE(TestResourceLoad(GenURL("a.com", "/title1.html"), GURL()));

  // Now load it from a different site, and the resource is cached.
  EXPECT_TRUE(TestResourceLoad(GenURL("b.com", "/title1.html"), GURL()));

  // Load it from a cross-origin iframe, and it's still cached.
  EXPECT_TRUE(TestResourceLoad(GenURL("b.com", "/title1.html"),
                               GenURL("c.com", "/title1.html")));
}

IN_PROC_BROWSER_TEST_F(SplitCacheEnabledContentBrowserTest,
                       NavigationResources) {
  // Navigate for the first time, and it's not cached.
  EXPECT_FALSE(
      NavigationResourceCached(GenURL("a.com", "/title1.html"), GURL(), false));

  // The second time, it's cached.
  EXPECT_TRUE(
      NavigationResourceCached(GenURL("a.com", "/title1.html"), GURL(), false));

  // Navigate to a.com/redirect_to_d which redirects to d.com/title1.html.
  EXPECT_FALSE(NavigationResourceCached(GenURL("a.com", "/redirect_to_d"),
                                        GenURL("d.com", "/title1.html"), GURL(),
                                        false));

  // Navigate to d.com directly. The main resource should be cached due to the
  // earlier redirected navigation. Note that the HTTP cache doesn't deem the
  // earlier navigation cross-site (for the purposes of calculating the cache
  // key) since the navigation is browser-initiated.
  EXPECT_TRUE(
      NavigationResourceCached(GenURL("d.com", "/title1.html"), GURL(), false));

  // Navigate to a subframe with the same top frame origin as in an earlier
  // navigation and same url as already navigated to earlier in a main frame
  // navigation.
  // The 'is-subframe-document-resource' boolean prevents this resource from
  // sharing a cache partition with the earlier top-level navigation, even
  // in cases where the initiator is same-origin with the page being loaded.
  EXPECT_FALSE(NavigationResourceCached(
      GenURL("a.com", "/navigation_controller/page_with_iframe.html"),
      GenURL("a.com", "/title1.html"),
      false));

  EXPECT_TRUE(NavigationResourceCached(
      GenURL("a.com", "/navigation_controller/page_with_iframe.html"),
      GenURL("a.com", "/title1.html"), true));

  // Navigate to the same subframe document from a different top frame origin.
  // It should be a cache miss.
  EXPECT_FALSE(NavigationResourceCached(
      GenURL("b.com", "/navigation_controller/page_with_iframe.html"),
      GenURL("a.com", "/title1.html"), false));
}

IN_PROC_BROWSER_TEST_F(SplitCacheEnabledContentBrowserTest,
                       SubframeNavigationResources) {
  // Navigate for the first time, and it's not cached.
  NavigationResourceCached(
      GenURL("a.com", "/navigation_controller/page_with_iframe.html"),
      GenURL("a.com", "/title1.html"), false);

  // The second time it should be a cache hit.
  NavigationResourceCached(
      GenURL("a.com", "/navigation_controller/page_with_iframe.html"),
      GenURL("a.com", "/title1.html"), true);

  // Navigate to the same subframe document from a different top frame origin.
  // It should be a cache miss.
  NavigationResourceCached(
      GenURL("b.com", "/navigation_controller/page_with_iframe.html"),
      GenURL("a.com", "/title1.html"), false);

  // Navigate the subframe to a.com/redirect_to_d which redirects to
  // d.com/title1.html.
  NavigationResourceCached(
      GenURL("a.com", "/navigation_controller/page_with_iframe.html"),
      GenURL("a.com", "/redirect_to_d"), false);

  // Navigate to d.com directly. The resource should be cached due to the
  // earlier redirected navigation.
  NavigationResourceCached(
      GenURL("a.com", "/navigation_controller/page_with_iframe.html"),
      GenURL("d.com", "/title1.html"), true);
}

// Tests that when a subresource URL which is same-site to the fetching frame
// is later used to create a subframe from the same top-level site, it should
// not be a cache hit (crbug.com/1135149).
IN_PROC_BROWSER_TEST_F(SplitCacheEnabledContentBrowserTest,
                       SubframeNavigationResource) {
  // main.com iframes 3p.com which fetches a subresource 3p.com/script with
  // cache key (main.com, 3p.com, 3p.com/script). Then main.com iframes evil.com
  // which iframes 3p.com/script. It should be a cache miss since the first time
  // it was fetched as a subresource and second time as a subframe document
  // resource.

  // Fetch 3p.com/script from a 3p.com iframe, top-level site main.com.
  TestResourceLoad(GenURL("main.com", "/title1.html") /* top-level frame */,
                   GenURL("3p.com", "/title1.html") /* subframe */);

  // Create evil.com iframe inside top-level site main.com.
  NavigationResourceCached(
      GenURL("main.com", "/navigation_controller/page_with_iframe.html"),
      GenURL("evil.com", "/title1.html"), false);
  RenderFrameHostImpl* main_frame = static_cast<RenderFrameHostImpl*>(
      shell()->web_contents()->GetPrimaryMainFrame());
  EXPECT_EQ(1U, main_frame->frame_tree_node()->child_count());

  // Observe network requests.
  ResourceLoadObserver observer(shell());

  // Now iframe 3p.com/script within evil.com.
  GURL subframe_url = GenURL("3p.com", "/script");
  EXPECT_TRUE(ExecJs(main_frame->frame_tree_node()->child_at(0),
                     GetSubframeScript(subframe_url)));
  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
  observer.WaitForResourceCompletion(subframe_url);
  EXPECT_EQ(false, (*observer.GetResource(subframe_url))->was_cached);
}

// Tests that a cross-site navigation to a document that was previously loaded
// via top-level navigation doesn't use the cache, since doing so could enable
// cross-site leaks.
IN_PROC_BROWSER_TEST_F(SplitCacheEnabledContentBrowserTest,
                       CrossSiteNavigation) {
  // Do a top-level navigation to a document to add it to the cache.
  EXPECT_FALSE(
      NavigationResourceCached(GenURL("a.com", "/title1.html"), GURL(), false));

  // Verify that the document did get added to the cache.
  EXPECT_TRUE(
      NavigationResourceCached(GenURL("a.com", "/title1.html"), GURL(), false));

  // Navigate to a cross-site document that performs a client-side redirect to
  // the document visited previously. Ensure that repeating this request results
  // in a cache hit, and then try again with a different initiating site.
  bool evil_com_initiator_first_navigation_result = NavigationRedirectCached(
      GenURL("evil.com", "/title1.html"), GenURL("a.com", "/title1.html"));

  EXPECT_TRUE(NavigationRedirectCached(GenURL("evil.com", "/title1.html"),
                                       GenURL("a.com", "/title1.html")));

  bool evil2_com_initiator_navigation_result = NavigationRedirectCached(
      GenURL("evil2.com", "/title1.html"), GenURL("a.com", "/title1.html"));

  // With the cross-site navigation boolean, the first of these should not be in
  // the cache because it's cross-site, but a subsequent cross-site navigation
  // from a different initiator should result in a cache hit.
  EXPECT_FALSE(evil_com_initiator_first_navigation_result);
  EXPECT_TRUE(evil2_com_initiator_navigation_result);
}

// Tests that a cross-origin but same-site navigation to a document that was
// previously loaded via top-level navigation uses the cache.
IN_PROC_BROWSER_TEST_F(SplitCacheEnabledContentBrowserTest,
                       CrossOriginSameSiteNavigation) {
  // Do a top-level navigation to a document to add it to the cache.
  EXPECT_FALSE(
      NavigationResourceCached(GenURL("a.com", "/title1.html"), GURL(), false));

  // Verify that the document did get added to the cache.
  EXPECT_TRUE(
      NavigationResourceCached(GenURL("a.com", "/title1.html"), GURL(), false));

  // Navigate to a cross-site document that performs a client-side redirect to
  // the document visited previously. Ensure that repeating this request results
  // in a cache hit, and then try again with a different initiating site that is
  // cross-origin but same-site.
  bool a_example_com_initiator_first_navigation_result =
      NavigationRedirectCached(GenURL("a.example.com", "/title1.html"),
                               GenURL("a.com", "/title1.html"));

  EXPECT_TRUE(NavigationRedirectCached(GenURL("a.example.com", "/title1.html"),
                                       GenURL("a.com", "/title1.html")));

  bool b_example_com_initiator_navigation_result = NavigationRedirectCached(
      GenURL("b.example.com", "/title1.html"), GenURL("a.com", "/title1.html"));

  // With the cross-site navigation boolean, the first of these should not be in
  // the cache because it's cross-site, but a subsequent cross-site navigation
  // from a different initiator should result in a cache hit.
  EXPECT_FALSE(a_example_com_initiator_first_navigation_result);
  EXPECT_TRUE(b_example_com_initiator_navigation_result);
}

// This class invokes ComputeHttpCacheSize on the Network Context and
// waits for the callback to be invoked.
class SplitCacheComputeHttpCacheSize {
 public:
  SplitCacheComputeHttpCacheSize() = default;
  ~SplitCacheComputeHttpCacheSize() = default;

  int64_t ComputeHttpCacheSize(BrowserContext* context,
                               base::Time start_time,
                               base::Time end_time) {
    last_computed_cache_size_ = -1;
    auto* network_context =
        context->GetDefaultStoragePartition()->GetNetworkContext();
    network::mojom::NetworkContext::ComputeHttpCacheSizeCallback size_callback =
        base::BindOnce(
            &SplitCacheComputeHttpCacheSize::ComputeCacheSizeCallback,
            base::Unretained(this));

    network_context->ComputeHttpCacheSize(start_time, end_time,
                                          std::move(size_callback));
    runloop_ = std::make_unique<base::RunLoop>();
    runloop_->Run();
    return last_computed_cache_size_;
  }

  void ComputeCacheSizeCallback(bool is_upper_bound, int64_t size) {
    last_computed_cache_size_ = size;
    runloop_->Quit();
  }

  SplitCacheComputeHttpCacheSize(const SplitCacheComputeHttpCacheSize&) =
      delete;
  SplitCacheComputeHttpCacheSize& operator=(
      const SplitCacheComputeHttpCacheSize&) = delete;

 private:
  std::unique_ptr<base::RunLoop> runloop_;
  int64_t last_computed_cache_size_ = -1;
};

// Tests that NotifyExternalCacheHit() has the correct value of
// is_subframe_document_resource by checking that the size of the http cache
// resources accessed after the resource is loaded from the blink cache is the
// same as before that.
// TODO(crbug.com/40164302): Test is flaky on Win.
#if BUILDFLAG(IS_WIN)
#define MAYBE_NotifyExternalCacheHitCheckSubframeBit \
  DISABLED_NotifyExternalCacheHitCheckSubframeBit
#else
#define MAYBE_NotifyExternalCacheHitCheckSubframeBit \
  NotifyExternalCacheHitCheckSubframeBit
#endif
IN_PROC_BROWSER_TEST_F(SplitCacheEnabledContentBrowserTest,
                       MAYBE_NotifyExternalCacheHitCheckSubframeBit) {
  ResourceLoadObserver observer(shell());
  BrowserContext* context = shell()->web_contents()->GetBrowserContext();
  std::unique_ptr<SplitCacheComputeHttpCacheSize> http_cache_size =
      std::make_unique<SplitCacheComputeHttpCacheSize>();

  // Since no resources are loaded yet, Http cache's size will be 0.
  EXPECT_EQ(0, http_cache_size->ComputeHttpCacheSize(context, base::Time(),
                                                     base::Time::Max()));

  // First fetch will populate the cache.
  GURL page_url(
      embedded_test_server()->GetURL("/page_with_cached_subresource.html"));
  EXPECT_TRUE(NavigateToURL(shell(), page_url));

  // Checking the size of resources should be >0 as resources have been loaded.
  int64_t size1 = http_cache_size->ComputeHttpCacheSize(context, base::Time(),
                                                        base::Time::Max());
  EXPECT_GT(size1, 0);
  ASSERT_EQ(2U, observer.resource_load_entries().size());
  EXPECT_TRUE(observer.memory_cached_loaded_urls().empty());
  observer.Reset();

  // Make sure time has moved forward from when the last entry was cached.
  base::Time start = base::Time::Now();
  while (start == base::Time::Now()) {
  }
  base::Time after_first = base::Time::Now();

  // Loading again should serve the request out of the in-memory cache.
  EXPECT_TRUE(NavigateToURL(shell(), page_url));

  ASSERT_EQ(1U, observer.resource_load_entries().size());
  ASSERT_EQ(1U, observer.memory_cached_loaded_urls().size());

  // Loading from the in-memory cache also changes the last accessed time of
  // those resources in the http cache. So if we check the size of resources
  // accessed after the first load till now, it will be the same as before the
  // 2nd navigation.
  int64_t size2 = http_cache_size->ComputeHttpCacheSize(context, after_first,
                                                        base::Time::Max());
  EXPECT_EQ(size1, size2);
}

IN_PROC_BROWSER_TEST_F(SplitCacheEnabledContentBrowserTest, DedicatedWorkers) {
  // Load 3p.com/script from a.com's worker. The first time it's loaded from the
  // network and the second it's cached.
  EXPECT_FALSE(TestResourceLoadFromDedicatedWorker(
      GenURL("a.com", "/title1.html"), GenURL("a.com", "/worker.js")));
  EXPECT_TRUE(TestResourceLoadFromDedicatedWorker(
      GenURL("a.com", "/title1.html"), GenURL("a.com", "/worker.js")));

  // Load 3p.com/script from a worker with a new top-frame origin. Due to split
  // caching it's a cache miss.
  EXPECT_FALSE(TestResourceLoadFromDedicatedWorker(
      GenURL("b.com", "/title1.html"), GenURL("b.com", "/worker.js")));
  EXPECT_TRUE(TestResourceLoadFromDedicatedWorker(
      GenURL("b.com", "/title1.html"), GenURL("b.com", "/worker.js")));

  // Load 3p.com/script from a nested worker with a new top-frame origin. Due to
  // split caching it's a cache miss.
  EXPECT_FALSE(TestResourceLoadFromDedicatedWorker(
      GenURL("c.com", "/title1.html"),
      GenURL("c.com", "/embedding_worker.js?c")));
  EXPECT_TRUE(TestResourceLoadFromDedicatedWorker(
      GenURL("c.com", "/title1.html"),
      GenURL("c.com", "/embedding_worker.js?c")));

  // Load 3p.com/script from a worker with a new top-frame origin and nested in
  // a cross-origin iframe. Due to split caching it's a cache miss.
  EXPECT_FALSE(TestResourceLoadFromDedicatedWorkerInIframe(
      GenURL("d.com", "/title1.html"), GenURL("e.com", "/title1.html"),
      GenURL("e.com", "/worker.js")));
  EXPECT_TRUE(TestResourceLoadFromDedicatedWorkerInIframe(
      GenURL("d.com", "/title1.html"), GenURL("e.com", "/title1.html"),
      GenURL("e.com", "/worker.js")));

  // Load 3p.com/script from a worker with a new top-frame origin and nested in
  // a cross-origin iframe whose URL has previously been loaded.
  EXPECT_FALSE(TestResourceLoadFromDedicatedWorkerInIframe(
      GenURL("f.com", "/title1.html"), GenURL("e.com", "/title1.html"),
      GenURL("e.com", "/worker.js")));
  EXPECT_TRUE(TestResourceLoadFromDedicatedWorkerInIframe(
      GenURL("f.com", "/title1.html"), GenURL("e.com", "/title1.html"),
      GenURL("e.com", "/worker.js")));
}

// https://crbug.com/1218723 started flaking after Field Trial Testing Config
// was enabled for content_browsertests.
IN_PROC_BROWSER_TEST_F(SplitCacheEnabledContentBrowserTest,
                       DISABLED_DedicatedWorkersScripts) {
  // Load a.com's worker. The first time the worker script is loaded from the
  // network and the second it's cached.
  EXPECT_FALSE(DedicatedWorkerScriptCached(
      GenURL("a.com", "/title1.html"), GURL(), GenURL("a.com", "/worker.js")));
  EXPECT_TRUE(DedicatedWorkerScriptCached(
      GenURL("a.com", "/title1.html"), GURL(), GenURL("a.com", "/worker.js")));

  // Load a nested worker with a new top-frame origin. It's a cache miss for
  // the embedding worker the first time, as it hasn't been loaded yet, and
  // then the second time it's cached.
  EXPECT_FALSE(
      DedicatedWorkerScriptCached(GenURL("c.com", "/title1.html"), GURL(),
                                  GenURL("c.com", "/embedding_worker.js?c")));
  EXPECT_TRUE(
      DedicatedWorkerScriptCached(GenURL("c.com", "/title1.html"), GURL(),
                                  GenURL("c.com", "/embedding_worker.js?c")));

  // Load a worker with a new top-frame origin and nested in a cross-origin
  // iframe. It's a cache miss for the worker script the first time, then
  // the second time it's cached.
  EXPECT_FALSE(DedicatedWorkerScriptCached(GenURL("d.com", "/title1.html"),
                                           GenURL("e.com", "/title1.html"),
                                           GenURL("e.com", "/worker.js")));
  EXPECT_TRUE(DedicatedWorkerScriptCached(GenURL("d.com", "/title1.html"),
                                          GenURL("e.com", "/title1.html"),
                                          GenURL("e.com", "/worker.js")));

  // Load a worker with a new top-frame origin and nested in a cross-origin
  // iframe whose URL has previously been loaded. Due to split caching it's a
  // cache miss for the worker script the first time.
  EXPECT_FALSE(DedicatedWorkerScriptCached(GenURL("f.com", "/title1.html"),
                                           GenURL("e.com", "/title1.html"),
                                           GenURL("e.com", "/worker.js")));
  EXPECT_TRUE(DedicatedWorkerScriptCached(GenURL("f.com", "/title1.html"),
                                          GenURL("e.com", "/title1.html"),
                                          GenURL("e.com", "/worker.js")));
}

IN_PROC_BROWSER_TEST_F(SplitCacheDisabledContentBrowserTest, DedicatedWorkers) {
  // Load 3p.com/script from a.com's worker. The first time it's loaded from the
  // network and the second it's cached.
  EXPECT_FALSE(TestResourceLoadFromDedicatedWorker(
      GenURL("a.com", "/title1.html"), GenURL("a.com", "/worker.js")));
  EXPECT_TRUE(TestResourceLoadFromDedicatedWorker(
      GenURL("a.com", "/title1.html"), GenURL("a.com", "/worker.js")));

  // Load 3p.com/script from b.com's worker. The cache isn't split by top-frame
  // origin so the resource is already cached.
  EXPECT_TRUE(TestResourceLoadFromDedicatedWorker(
      GenURL("b.com", "/title1.html"), GenURL("b.com", "/worker.js")));

  // Load 3p.com/script from a nested worker with a new top-frame origin. The
  // cache isn't split by top-frame origin so the resource is already cached.
  EXPECT_TRUE(TestResourceLoadFromDedicatedWorker(
      GenURL("c.com", "/title1.html"),
      GenURL("c.com", "/embedding_worker.js?c")));

  // Load 3p.com/script from a worker with a new top-frame origin and nested in
  // a cross-origin iframe. The cache isn't split by top-frame origin so the
  // resource is already cached.
  EXPECT_TRUE(TestResourceLoadFromDedicatedWorkerInIframe(
      GenURL("d.com", "/title1.html"), GenURL("e.com", "/title1.html"),
      GenURL("e.com", "/worker.js")));
  EXPECT_TRUE(TestResourceLoadFromDedicatedWorkerInIframe(
      GenURL("f.com", "/title1.html"), GenURL("e.com", "/title1.html"),
      GenURL("e.com", "/worker.js")));
}

class SplitCacheByIncludeCredentialsTest : public ContentBrowserTest {
 public:
  SplitCacheByIncludeCredentialsTest()
      : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {
    feature_list_.InitAndEnableFeature(
        net::features::kSplitCacheByIncludeCredentials);
  }

  int cacheable_request_count() const { return cacheable_request_count_; }
  net::EmbeddedTestServer* https_server() { return &https_server_; }
  GURL CacheableUrl() { return https_server()->GetURL("b.test", "/cacheable"); }

  void RequestAnonymous(Shell* shell) {
    EXPECT_TRUE(ExecJs(shell, JsReplace(R"(
      new Promise(resolve => {
        const image = new Image();
        image.src = $1;
        image.crossOrigin = "anonymous";
        image.onload = resolve;
        document.body.appendChild(image);
      });
    )",
                                        CacheableUrl())));
  }

  void RequestUseCredentials(Shell* shell) {
    EXPECT_TRUE(ExecJs(shell, JsReplace(R"(
      new Promise(resolve => {
        const image = new Image();
        image.src = $1;
        image.crossOrigin = "use-credentials";
        image.onload = resolve;
        document.body.appendChild(image);
      });
    )",
                                        CacheableUrl())));
  }

 private:
  void SetUpOnMainThread() final {
    ContentBrowserTest::SetUpOnMainThread();

    cacheable_request_count_ = 0;
    host_resolver()->AddRule("*", "127.0.0.1");
    https_server()->SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES);
    https_server()->RegisterRequestHandler(
        base::BindRepeating(&SplitCacheByIncludeCredentialsTest::RequestHandler,
                            base::Unretained(this)));
    https_server()->ServeFilesFromSourceDirectory(GetTestDataFilePath());
    net::test_server::RegisterDefaultHandlers(https_server());
    SetupCrossSiteRedirector(https_server());
    CHECK(https_server()->Start());
  }

  std::unique_ptr<net::test_server::HttpResponse> RequestHandler(
      const net::test_server::HttpRequest& request) {
    if (request.relative_url == "/cacheable") {
      cacheable_request_count_++;
      auto response = std::make_unique<net::test_server::BasicHttpResponse>();
      response->set_content_type("image/svg+xml");
      response->set_content("<svg xmlns=\"http://www.w3.org/2000/svg\"></svg>");
      response->AddCustomHeader("Cache-Control", "max-age=3600");
      response->AddCustomHeader("Cross-Origin-Resource-Policy", "cross-origin");
      response->AddCustomHeader("Access-Control-Allow-Credentials", "true");
      response->AddCustomHeader(
          "Access-Control-Allow-Origin",
          https_server()->GetOrigin("a.test").Serialize());
      return response;
    }
    return nullptr;
  }

  base::test::ScopedFeatureList feature_list_;
  net::EmbeddedTestServer https_server_;
  // Initialized and read from the UI thread. Written from the |https_server_|.
  std::atomic<int> cacheable_request_count_;
};

// Note: Compared to .DifferentProcess and .DifferentProcessVariant, this test
// emits requests from the same renderer process. This is useful for checking
// the behavior of blink's memory cache instead of the HTTP cache.
IN_PROC_BROWSER_TEST_F(SplitCacheByIncludeCredentialsTest, SameProcess) {
  GURL page_url(https_server()->GetURL("a.test", "/empty.html"));
  EXPECT_TRUE(NavigateToURL(shell(), page_url));
  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));

  EXPECT_EQ(0, cacheable_request_count());

  RequestAnonymous(shell());
  EXPECT_EQ(1, cacheable_request_count());
  RequestAnonymous(shell());
  EXPECT_EQ(1, cacheable_request_count());

  RequestUseCredentials(shell());
  EXPECT_EQ(2, cacheable_request_count());
  RequestUseCredentials(shell());
  EXPECT_EQ(2, cacheable_request_count());

  RequestAnonymous(shell());
  EXPECT_EQ(2, cacheable_request_count());
}

IN_PROC_BROWSER_TEST_F(SplitCacheByIncludeCredentialsTest, SameProcessVariant) {
  GURL page_url(https_server()->GetURL("a.test", "/empty.html"));
  EXPECT_TRUE(NavigateToURL(shell(), page_url));
  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));

  EXPECT_EQ(0, cacheable_request_count());

  RequestUseCredentials(shell());
  EXPECT_EQ(1, cacheable_request_count());
  RequestUseCredentials(shell());
  EXPECT_EQ(1, cacheable_request_count());

  RequestAnonymous(shell());
  EXPECT_EQ(2, cacheable_request_count());
  RequestAnonymous(shell());
  EXPECT_EQ(2, cacheable_request_count());

  RequestUseCredentials(shell());
  EXPECT_EQ(2, cacheable_request_count());
}

// Note: Compared to .SameProcess and .SameProcessVariant, this test emits
// requests from two different renderer process. This is useful for checking the
// behavior of the HTTP cache instead of blink's memory cache.
//
// COOP+COEP are used to get two same-origin documents loaded from different
// renderer process. This avoids interferences from
// SplitCacheByNetworkIsolationKey.
IN_PROC_BROWSER_TEST_F(SplitCacheByIncludeCredentialsTest, DifferentProcess) {
  GURL page_1_url(https_server()->GetURL("a.test", "/empty.html"));
  EXPECT_TRUE(NavigateToURL(shell(), page_1_url));
  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));

  GURL page_2_url =
      https_server()->GetURL("a.test",
                             "/set-header?"
                             "Cross-Origin-Opener-Policy: same-origin&"
                             "Cross-Origin-Embedder-Policy: require-corp");
  ShellAddedObserver shell_observer;
  EXPECT_TRUE(ExecJs(shell(), JsReplace("window.open($1)", page_2_url)));
  Shell* new_shell = shell_observer.GetShell();
  EXPECT_TRUE(WaitForLoadStop(new_shell->web_contents()));

  EXPECT_NE(static_cast<WebContentsImpl*>(shell()->web_contents())
                ->GetPrimaryMainFrame()
                ->GetProcess(),
            static_cast<WebContentsImpl*>(new_shell->web_contents())
                ->GetPrimaryMainFrame()
                ->GetProcess());

  EXPECT_EQ(0, cacheable_request_count());

  RequestAnonymous(shell());
  EXPECT_EQ(1, cacheable_request_count());
  RequestAnonymous(new_shell);
  EXPECT_EQ(1, cacheable_request_count());

  RequestUseCredentials(shell());
  EXPECT_EQ(2, cacheable_request_count());
  RequestUseCredentials(new_shell);
  EXPECT_EQ(2, cacheable_request_count());

  RequestAnonymous(shell());
  EXPECT_EQ(2, cacheable_request_count());
}

IN_PROC_BROWSER_TEST_F(SplitCacheByIncludeCredentialsTest,
                       DifferentProcessVariant) {
  GURL page_1_url(https_server()->GetURL("a.test", "/empty.html"));
  EXPECT_TRUE(NavigateToURL(shell(), page_1_url));
  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));

  GURL page_2_url =
      https_server()->GetURL("a.test",
                             "/set-header?"
                             "Cross-Origin-Opener-Policy: same-origin&"
                             "Cross-Origin-Embedder-Policy: require-corp");
  ShellAddedObserver shell_observer;
  EXPECT_TRUE(ExecJs(shell(), JsReplace("window.open($1)", page_2_url)));
  Shell* new_shell = shell_observer.GetShell();
  EXPECT_TRUE(WaitForLoadStop(new_shell->web_contents()));

  EXPECT_NE(static_cast<WebContentsImpl*>(shell()->web_contents())
                ->GetPrimaryMainFrame()
                ->GetProcess(),
            static_cast<WebContentsImpl*>(new_shell->web_contents())
                ->GetPrimaryMainFrame()
                ->GetProcess());

  EXPECT_EQ(0, cacheable_request_count());

  RequestUseCredentials(shell());
  EXPECT_EQ(1, cacheable_request_count());
  RequestUseCredentials(new_shell);
  EXPECT_EQ(1, cacheable_request_count());

  RequestAnonymous(shell());
  EXPECT_EQ(2, cacheable_request_count());
  RequestAnonymous(new_shell);
  EXPECT_EQ(2, cacheable_request_count());

  RequestUseCredentials(shell());
  EXPECT_EQ(2, cacheable_request_count());
}

}  // namespace
}  // namespace content
