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

#include <string_view>
#include <tuple>

#include "base/base_paths.h"
#include "base/files/file_util.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/metrics/statistics_recorder.h"
#include "base/path_service.h"
#include "base/strings/strcat.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/task_runner.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_future.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/clear_site_data_utils.h"
#include "content/public/browser/client_certificate_delegate.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/network_service_instance.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_features.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_content_browser_client.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/url_loader_interceptor.h"
#include "content/shell/browser/shell.h"
#include "net/base/hash_value.h"
#include "net/base/schemeful_site.h"
#include "net/base/url_util.h"
#include "net/dns/mock_host_resolver.h"
#include "net/extras/shared_dictionary/shared_dictionary_usage_info.h"
#include "net/shared_dictionary/shared_dictionary_constants.h"
#include "net/shared_dictionary/shared_dictionary_isolation_key.h"
#include "net/ssl/client_cert_identity.h"
#include "net/ssl/client_cert_identity_test_util.h"
#include "net/ssl/client_cert_store.h"
#include "net/ssl/ssl_private_key.h"
#include "net/ssl/ssl_server_config.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/test_data_directory.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include "services/network/public/mojom/network_service.mojom.h"
#include "services/network/public/mojom/shared_dictionary_access_observer.mojom.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/blink/public/common/features.h"

using ::testing::UnorderedElementsAreArray;

namespace content {

namespace {

// The Structured Field sf-binary hash of sha256 of dictionary.
// (content/test/data/shared_dictionary/test.dict and test_dict.html).
constexpr std::string_view kExpectedDictionaryHashBase64 =
    ":U5abz16WDg7b8KS93msLPpOB4Vbef1uRzoORYkJw9BY=:";
constexpr net::SHA256HashValue kExpectedDictionaryHashValue = {
    {0x53, 0x96, 0x9b, 0xcf, 0x5e, 0x96, 0x0e, 0x0e, 0xdb, 0xf0, 0xa4,
     0xbd, 0xde, 0x6b, 0x0b, 0x3e, 0x93, 0x81, 0xe1, 0x56, 0xde, 0x7f,
     0x5b, 0x91, 0xce, 0x83, 0x91, 0x62, 0x42, 0x70, 0xf4, 0x16}};

constexpr std::string_view kUncompressedDataString =
    "test(\"This is uncompressed.\");";
constexpr std::string_view kErrorInvalidHashString =
    "test(\"Invalid dictionary hash.\");";
constexpr std::string_view kErrorNoSharedDictionaryAcceptEncodingString =
    "test(\"dcb or dcz is not set in accept-encoding header.\");";

constexpr std::string_view kCompressedDataOriginalString =
    "test(\"This is compressed test data using a test dictionary\");";

// kBrotliCompressedData is generated using the following commands:
// $ echo "This is a test dictionary." > /tmp/dict
// $ echo -n "test(\"This is compressed test data using a test dictionary\");" \
//     > /tmp/data
// $ echo -en '\xffDCB' > /tmp/out.dcb
// $ openssl dgst -sha256 -binary /tmp/dict >> /tmp/out.dcb
// $ brotli --stdout -D /tmp/dict /tmp/data >> /tmp/out.dcb
// $ xxd -i /tmp/out.dcb
constexpr uint8_t kBrotliCompressedData[] = {
    0xff, 0x44, 0x43, 0x42, 0x53, 0x96, 0x9b, 0xcf, 0x5e, 0x96, 0x0e, 0x0e,
    0xdb, 0xf0, 0xa4, 0xbd, 0xde, 0x6b, 0x0b, 0x3e, 0x93, 0x81, 0xe1, 0x56,
    0xde, 0x7f, 0x5b, 0x91, 0xce, 0x83, 0x91, 0x62, 0x42, 0x70, 0xf4, 0x16,
    0xa1, 0xe0, 0x01, 0x00, 0x64, 0x9c, 0xa4, 0xaa, 0xd7, 0x47, 0xe0, 0x26,
    0x4b, 0x95, 0x91, 0xb4, 0x46, 0x36, 0x09, 0xc9, 0xc7, 0x0e, 0x38, 0xe4,
    0x44, 0xe8, 0x72, 0x0d, 0x3c, 0x6e, 0xab, 0x35, 0x9b, 0x0f, 0x4b, 0xd1,
    0x67, 0x0c, 0xec, 0x7f, 0x9d, 0x1e, 0x99, 0x10, 0xf5, 0x1e, 0x57, 0x2f};
const std::string kBrotliCompressedDataString =
    std::string(reinterpret_cast<const char*>(kBrotliCompressedData),
                sizeof(kBrotliCompressedData));

// kZstdCompressedData is generated using the following commands:
// $ echo "This is a test dictionary." > /tmp/dict
// $ echo -n "test(\"This is compressed test data using a test dictionary\");" \
//     > /tmp/data
// $ echo -en '\x5e\x2a\x4d\x18\x20\x00\x00\x00' > /tmp/out.dcz
// $ openssl dgst -sha256 -binary /tmp/dict >> /tmp/out.dcz
// $ zstd -D /tmp/dict -f -o /tmp/tmp.zstd /tmp/data
// $ cat /tmp/tmp.zstd >> /tmp/out.dcz
// $ xxd -i /tmp/out.dcz
constexpr uint8_t kZstdCompressedData[] = {
    0x5e, 0x2a, 0x4d, 0x18, 0x20, 0x00, 0x00, 0x00, 0x53, 0x96, 0x9b, 0xcf,
    0x5e, 0x96, 0x0e, 0x0e, 0xdb, 0xf0, 0xa4, 0xbd, 0xde, 0x6b, 0x0b, 0x3e,
    0x93, 0x81, 0xe1, 0x56, 0xde, 0x7f, 0x5b, 0x91, 0xce, 0x83, 0x91, 0x62,
    0x42, 0x70, 0xf4, 0x16, 0x28, 0xb5, 0x2f, 0xfd, 0x24, 0x3d, 0x35, 0x01,
    0x00, 0xe0, 0x74, 0x65, 0x73, 0x74, 0x28, 0x22, 0x63, 0x6f, 0x6d, 0x70,
    0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x61, 0x74, 0x61, 0x20, 0x75, 0x73,
    0x69, 0x6e, 0x67, 0x22, 0x29, 0x3b, 0x03, 0x10, 0x05, 0xdf, 0x9f, 0x96,
    0x11, 0x21, 0x8a, 0x48, 0x20, 0xef, 0xeb};
const std::string kZstdCompressedDataString =
    std::string(reinterpret_cast<const char*>(kZstdCompressedData),
                sizeof(kZstdCompressedData));

constexpr std::string_view kUncompressedDataResultString =
    "This is uncompressed.";
constexpr std::string_view kCompressedDataResultString =
    "This is compressed test data using a test dictionary";

constexpr std::string_view kHttpAuthPath = "/shared_dictionary/path/http_auth";
const std::string kTestPath = "/shared_dictionary/path/test";

class SharedDictionaryAccessObserver : public WebContentsObserver {
 public:
  SharedDictionaryAccessObserver(WebContents* web_contents,
                                 base::RepeatingClosure on_accessed_callback)
      : WebContentsObserver(web_contents),
        on_accessed_callback_(std::move(on_accessed_callback)) {}

  const network::mojom::SharedDictionaryAccessDetailsPtr& details() const {
    return details_;
  }

 private:
  // WebContentsObserver overrides:
  void OnSharedDictionaryAccessed(
      NavigationHandle* navigation,
      const network::mojom::SharedDictionaryAccessDetails& details) override {
    details_ = details.Clone();
    on_accessed_callback_.Run();
  }
  void OnSharedDictionaryAccessed(
      RenderFrameHost* rfh,
      const network::mojom::SharedDictionaryAccessDetails& details) override {
    details_ = details.Clone();
    on_accessed_callback_.Run();
  }

  base::RepeatingClosure on_accessed_callback_;
  network::mojom::SharedDictionaryAccessDetailsPtr details_;
};

bool WaitForHistogram(const std::string& histogram_name,
                      std::optional<base::TimeDelta> timeout = std::nullopt) {
  // Need the polling of histogram because ScopedHistogramSampleObserver doesn't
  // support cross process metrics.
  base::Time start_time = base::Time::Now();
  while (!base::StatisticsRecorder::FindHistogram(histogram_name)) {
    content::FetchHistogramsFromChildProcesses();
    base::PlatformThread::Sleep(base::Milliseconds(5));
    if (timeout && base::Time::Now() > start_time + *timeout) {
      return false;
    }
  }
  return true;
}

enum class FeatureState {
  kDisabled,
  kBackendOnly,
  kFullyEnabled,
  kFullyEnabledWithZstd
};

enum class BrowserType { kNormal, kOffTheRecord };
std::string ToString(BrowserType browser_type) {
  switch (browser_type) {
    case BrowserType::kNormal:
      return "Normal";
    case BrowserType::kOffTheRecord:
      return "OffTheRecord";
  }
}

enum class FetchType {
  kLinkRelCompressionDictionary,
  kLinkRelCompressionDictionaryDocumentHeader,
  kLinkRelCompressionDictionarySubresourceHeader,
  kFetchApi,
  kFetchApiWithSameOriginMode,
  kFetchApiWithNoCorsMode,
  kFetchApiFromDedicatedWorker,
  kFetchApiFromSharedWorker,
  kFetchApiFromServiceWorker,
  kIframeNavigation,
};

std::string LinkRelCompressionDictionaryScript(const GURL& dictionary_url) {
  return JsReplace(R"(
              (()=>{
                const link = document.createElement('link');
                link.rel = 'compression-dictionary';
                link.href = $1;
                document.body.appendChild(link);
              })();
            )",
                   dictionary_url);
}

std::string LinkRelCompressionDictionaryDocumentHeaderScript(
    const GURL& dictionary_url) {
  return JsReplace(R"(
              (()=>{
                const iframe = document.createElement('iframe');
                iframe.src = new URL('with_dict_header.html', $1);
                document.body.appendChild(iframe);
              })();
            )",
                   dictionary_url);
}

std::string LinkRelCompressionDictionarySubresourceHeaderScript(
    const GURL& dictionary_url) {
  return JsReplace(R"(
              (()=>{
                fetch(new URL('with_dict_header.html', $1));
              })();
            )",
                   dictionary_url);
}

std::string FetchDictionaryScript(const GURL& dictionary_url) {
  return JsReplace(R"(
          (async () => {
            try {
              await fetch($1);
            } catch (e) {
            }
          })();
        )",
                   dictionary_url);
}

std::string FetchDictionaryWithSameOriginModeScript(
    const GURL& dictionary_url) {
  return JsReplace(R"(
          (async () => {
            try {
              await fetch($1, {mode: 'same-origin'});
            } catch (e) {
            }
          })();
        )",
                   dictionary_url);
}

std::string FetchDictionaryWithNoCorsModeScript(const GURL& dictionary_url) {
  return JsReplace(R"(
          (async () => {
            try {
              await fetch($1, {mode: 'no-cors'});
            } catch (e) {
            }
          })();
        )",
                   dictionary_url);
}

std::string StartTestDedicatedWorkerScript(const GURL& dictionary_url) {
  return JsReplace(R"(
          (async () => {
            const script = '/shared_dictionary/fetch_dictionary.js';
            const worker = new Worker(script);
            worker.postMessage($1);
          })();
        )",
                   dictionary_url);
}

std::string StartTestSharedWorkerScript(const GURL& dictionary_url) {
  return JsReplace(R"(
          (async () => {
            const script =
                new URL(location).searchParams.has('otworker') ?
                  '/shared_dictionary/fetch_dictionary.js?ot=enabled' :
                  '/shared_dictionary/fetch_dictionary.js';
            const worker = new SharedWorker(script);
            worker.port.start();
            worker.port.postMessage($1);
          })();
        )",
                   dictionary_url);
}

std::string RegisterTestServiceWorkerScript(const GURL& dictionary_url) {
  return JsReplace(R"(
          (async () => {
            const script =
                new URL(location).searchParams.has('otworker') ?
                  '/shared_dictionary/fetch_dictionary.js?ot=enabled' :
                  '/shared_dictionary/fetch_dictionary.js';
            const registration = await navigator.serviceWorker.register(
                script,
                {scope: '/shared_dictionary/'});
            registration.installing.postMessage($1);
          })();
        )",
                   dictionary_url);
}

std::string FetchTargetDataScript(const GURL& dictionary_url) {
  return JsReplace(R"(
          (async () => {
            const url = new URL('./path/test' ,$1);
            const response = await fetch(url);
            return response.text();
          })();
        )",
                   dictionary_url);
}

std::string IframeLoadScript(const GURL& url) {
  return JsReplace(R"(
  (async () => {
    const iframe = document.createElement('iframe');
    iframe.src = $1;
    const promise =
        new Promise(resolve => { iframe.addEventListener('load', resolve); });
    document.body.appendChild(iframe);
    await promise;
    try {
      return iframe.contentDocument.body.innerText;
    } catch {
      return 'failed to access iframe';
    }
  })()
                  )",
                   url);
}
std::optional<std::string> GetAvailableDictionary(
    const net::test_server::HttpRequest::HeaderMap& headers) {
      auto it = headers.find("available-dictionary");
      return it == headers.end() ? std::nullopt
                                 : std::make_optional(it->second);
}

bool HasSharedDictionaryAcceptEncoding(
    const net::test_server::HttpRequest::HeaderMap& headers) {
  auto it = headers.find(net::HttpRequestHeaders::kAcceptEncoding);
  if (it == headers.end()) {
    return false;
  }
    return it->second == "dcb, dcz" || base::EndsWith(it->second, ", dcb, dcz");
}

// A dummy ContentBrowserClient for testing HTTP Auth.
class DummyAuthContentBrowserClient
    : public ContentBrowserTestContentBrowserClient {
 public:
  DummyAuthContentBrowserClient() = default;
  ~DummyAuthContentBrowserClient() override = default;
  DummyAuthContentBrowserClient(const DummyAuthContentBrowserClient&) = delete;
  DummyAuthContentBrowserClient& operator=(
      const DummyAuthContentBrowserClient&) = delete;

  // ContentBrowserClient method:
  std::unique_ptr<LoginDelegate> CreateLoginDelegate(
      const net::AuthChallengeInfo& auth_info,
      WebContents* web_contents,
      BrowserContext* browser_context,
      const GlobalRequestID& request_id,
      bool is_request_for_primary_main_frame_navigation,
      bool is_request_for_navigation,
      const GURL& url,
      scoped_refptr<net::HttpResponseHeaders> response_headers,
      bool first_auth_attempt,
      GuestPageHolder* guest,
      LoginDelegate::LoginAuthRequiredCallback auth_required_callback)
      override {
    create_login_delegate_called_ = true;
    base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
        FROM_HERE,
        base::BindOnce(std::move(auth_required_callback),
                       net::AuthCredentials(u"username", u"password")));
    return std::make_unique<LoginDelegate>();
  }

  bool create_login_delegate_called() const {
    return create_login_delegate_called_;
  }

 private:
  bool create_login_delegate_called_ = false;
};

// A dummy ContentBrowserClient for allowing all certificate errors.
class CertificateErrorAllowingContentBrowserClient
    : public ContentBrowserTestContentBrowserClient {
 public:
  CertificateErrorAllowingContentBrowserClient() = default;
  ~CertificateErrorAllowingContentBrowserClient() override = default;
  CertificateErrorAllowingContentBrowserClient(
      const CertificateErrorAllowingContentBrowserClient&) = delete;
  CertificateErrorAllowingContentBrowserClient& operator=(
      const CertificateErrorAllowingContentBrowserClient&) = delete;

  // ContentBrowserClient method:
  void AllowCertificateError(
      WebContents* web_contents,
      int cert_error,
      const net::SSLInfo& ssl_info,
      const GURL& request_url,
      bool is_primary_main_frame_request,
      bool strict_enforcement,
      base::OnceCallback<void(CertificateRequestResultType)> callback)
      override {
    allow_certificate_error_called_ = true;
    std::move(callback).Run(CERTIFICATE_REQUEST_RESULT_TYPE_CONTINUE);
  }

  bool allow_certificate_error_called() const {
    return allow_certificate_error_called_;
  }

 private:
  bool allow_certificate_error_called_ = false;
};

// A dummy ContentBrowserClient for setting client certificate.
class DummyClientCertStoreContentBrowserClient
    : public ContentBrowserTestContentBrowserClient {
 public:
  DummyClientCertStoreContentBrowserClient() = default;
  ~DummyClientCertStoreContentBrowserClient() override = default;
  DummyClientCertStoreContentBrowserClient(
      const DummyClientCertStoreContentBrowserClient&) = delete;
  DummyClientCertStoreContentBrowserClient& operator=(
      const DummyClientCertStoreContentBrowserClient&) = delete;

  // ContentBrowserClient methods:
  std::unique_ptr<net::ClientCertStore> CreateClientCertStore(
      BrowserContext* browser_context) override {
    net::ClientCertIdentityList cert_identity_list;
    {
      base::ScopedAllowBlockingForTesting allow_blocking;
      std::unique_ptr<net::FakeClientCertIdentity> cert_identity =
          net::FakeClientCertIdentity::CreateFromCertAndKeyFiles(
              net::GetTestCertsDirectory(), "client_1.pem", "client_1.pk8");
      EXPECT_TRUE(cert_identity.get());
      cert_identity_list.push_back(std::move(cert_identity));
    }
    return std::make_unique<DummyClientCertStore>(
        std::move(cert_identity_list));
  }
  base::OnceClosure SelectClientCertificate(
      BrowserContext* browser_context,
      int process_id,
      WebContents* web_contents,
      net::SSLCertRequestInfo* cert_request_info,
      net::ClientCertIdentityList client_certs,
      std::unique_ptr<ClientCertificateDelegate> delegate) override {
    select_client_certificate_called_ = true;
    CHECK_EQ(1u, client_certs.size());
    scoped_refptr<net::X509Certificate> cert(client_certs[0]->certificate());
    client_certs[0]->AcquirePrivateKey(base::BindOnce(
        [](std::unique_ptr<ClientCertificateDelegate> delegate,
           scoped_refptr<net::X509Certificate> cert,
           scoped_refptr<net::SSLPrivateKey> key) {
          delegate->ContinueWithCertificate(std::move(cert), std::move(key));
        },
        std::move(delegate), std::move(cert)));
    return base::OnceClosure();
  }

  bool select_client_certificate_called() const {
    return select_client_certificate_called_;
  }

 private:
  class DummyClientCertStore : public net::ClientCertStore {
   public:
    explicit DummyClientCertStore(net::ClientCertIdentityList list)
        : list_(std::move(list)) {}
    ~DummyClientCertStore() override = default;

    // net::ClientCertStore:
    void GetClientCerts(
        scoped_refptr<const net::SSLCertRequestInfo> cert_request_info,
        ClientCertListCallback callback) override {
      std::move(callback).Run(std::move(list_));
    }

   private:
    net::ClientCertIdentityList list_;
  };
  bool select_client_certificate_called_ = false;
};

class SharedDictionaryBrowserTestBase : public ContentBrowserTest {
 public:
  SharedDictionaryBrowserTestBase() = default;

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

 protected:
  int64_t GetTestDataFileSize(const std::string& name) {
    base::FilePath file_path;
    CHECK(base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &file_path));
    {
      base::ScopedAllowBlockingForTesting allow_blocking;
      std::optional<int64_t> size_result = base::GetFileSize(
          file_path.Append(GetTestDataFilePath()).AppendASCII(name));
      CHECK(size_result.has_value());
      return size_result.value();
    }
  }
  std::string GetTestDataFile(const std::string& name) {
    base::FilePath file_path;
    CHECK(base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &file_path));
    std::string contents;
    {
      base::ScopedAllowBlockingForTesting allow_blocking;
      CHECK(base::ReadFileToString(
          file_path.Append(GetTestDataFilePath()).AppendASCII(name),
          &contents));
    }
    return contents;
  }

  void RunWriteDictionaryTestImpl(Shell* shell,
                                  FetchType fetch_type,
                                  const GURL& page_url,
                                  const GURL& dictionary_url,
                                  const std::string& histogram_name,
                                  bool expect_success,
                                  bool navigate_to_page_url = true) {
    if (navigate_to_page_url) {
      EXPECT_TRUE(NavigateToURL(shell, page_url));
    }
    base::RunLoop write_loop;
    auto write_observer = std::make_unique<SharedDictionaryAccessObserver>(
        shell->web_contents(), write_loop.QuitClosure());

    base::HistogramTester histogram_tester;
    std::string script;
    switch (fetch_type) {
      case FetchType::kLinkRelCompressionDictionary:
        script = LinkRelCompressionDictionaryScript(dictionary_url);
        break;
      case FetchType::kLinkRelCompressionDictionaryDocumentHeader:
        script =
            LinkRelCompressionDictionaryDocumentHeaderScript(dictionary_url);
        break;
      case FetchType::kLinkRelCompressionDictionarySubresourceHeader:
        script =
            LinkRelCompressionDictionarySubresourceHeaderScript(dictionary_url);
        break;
      case FetchType::kFetchApi:
        script = FetchDictionaryScript(dictionary_url);
        break;
      case FetchType::kFetchApiWithSameOriginMode:
        script = FetchDictionaryWithSameOriginModeScript(dictionary_url);
        break;
      case FetchType::kFetchApiWithNoCorsMode:
        script = FetchDictionaryWithNoCorsModeScript(dictionary_url);
        break;
      case FetchType::kFetchApiFromDedicatedWorker:
        script = StartTestDedicatedWorkerScript(dictionary_url);
        break;
      case FetchType::kFetchApiFromSharedWorker:
        script = StartTestSharedWorkerScript(dictionary_url);
        break;
      case FetchType::kFetchApiFromServiceWorker:
        script = RegisterTestServiceWorkerScript(dictionary_url);
        break;
      case FetchType::kIframeNavigation:
        script = IframeLoadScript(dictionary_url);
        break;
    }
    EXPECT_TRUE(ExecJs(shell->web_contents()->GetPrimaryMainFrame(), script));
    if (expect_success) {
      write_loop.Run();
      ASSERT_TRUE(write_observer->details());
      EXPECT_EQ(network::mojom::SharedDictionaryAccessDetails::Type::kWrite,
                write_observer->details()->type);
      EXPECT_EQ(dictionary_url, write_observer->details()->url);
      EXPECT_EQ(net::SharedDictionaryIsolationKey(url::Origin::Create(page_url),
                                                  net::SchemefulSite(page_url)),
                write_observer->details()->isolation_key);
      EXPECT_FALSE(write_observer->details()->is_blocked);
    }

    if (!expect_success) {
      EXPECT_FALSE(WaitForHistogram(histogram_name, base::Milliseconds(100)));
      EXPECT_FALSE(write_observer->details());

      EXPECT_EQ(kUncompressedDataString,
                EvalJs(shell->web_contents()->GetPrimaryMainFrame(),
                       FetchTargetDataScript(dictionary_url))
                    .ExtractString());
      return;
    }
    EXPECT_TRUE(WaitForHistogram(histogram_name));
    histogram_tester.ExpectBucketCount(
        histogram_name, GetTestDataFileSize("shared_dictionary/test.dict"),
        /*expected_count=*/1);
    base::RunLoop read_loop;

    auto read_observer = std::make_unique<SharedDictionaryAccessObserver>(
        shell->web_contents(), read_loop.QuitClosure());
    EXPECT_EQ(kCompressedDataOriginalString,
              EvalJs(shell->web_contents()->GetPrimaryMainFrame(),
                     FetchTargetDataScript(dictionary_url))
                  .ExtractString());
    read_loop.Run();
    ASSERT_TRUE(read_observer->details());
    EXPECT_EQ(network::mojom::SharedDictionaryAccessDetails::Type::kRead,
              read_observer->details()->type);
    EXPECT_EQ(dictionary_url.Resolve("path/test"),
              read_observer->details()->url);
    EXPECT_EQ(net::SharedDictionaryIsolationKey(url::Origin::Create(page_url),
                                                net::SchemefulSite(page_url)),
              read_observer->details()->isolation_key);
    EXPECT_FALSE(read_observer->details()->is_blocked);
  }

  void RegisterTestRequestHandler(net::EmbeddedTestServer& server) {
    server.RegisterRequestHandler(
        base::BindRepeating(&SharedDictionaryBrowserTestBase::RequestHandler,
                            base::Unretained(this)));
  }

  std::vector<net::SharedDictionaryUsageInfo> GetSharedDictionaryUsageInfo(
      Shell* shell) {
    base::test::TestFuture<const std::vector<net::SharedDictionaryUsageInfo>&>
        result;
    shell->web_contents()
        ->GetBrowserContext()
        ->GetDefaultStoragePartition()
        ->GetNetworkContext()
        ->GetSharedDictionaryUsageInfo(result.GetCallback());
    return result.Get();
  }

  std::vector<url::Origin> GetOriginsBetween(Shell* shell,
                                             base::Time start_time,
                                             base::Time end_time) {
    base::test::TestFuture<const std::vector<url::Origin>&> result;
    shell->web_contents()
        ->GetBrowserContext()
        ->GetDefaultStoragePartition()
        ->GetNetworkContext()
        ->GetSharedDictionaryOriginsBetween(start_time, end_time,
                                            result.GetCallback());
    return result.Get();
  }

  network::mojom::NetworkContext* GetNetworkContext() {
    return shell()
        ->web_contents()
        ->GetBrowserContext()
        ->GetDefaultStoragePartition()
        ->GetNetworkContext();
  }

 private:
  std::unique_ptr<net::test_server::HttpResponse> RequestHandler(
      const net::test_server::HttpRequest& request) {
    if (!base::StartsWith(request.relative_url, kTestPath)) {
      return nullptr;
    }
    auto response = std::make_unique<net::test_server::BasicHttpResponse>();
    response->set_code(net::HTTP_OK);

    if (request.GetURL().GetQuery() == "html") {
      response->set_content_type("text/html");
    } else {
      response->set_content_type("application/javascript");
    }

    if (request.GetURL().GetQuery() != "no_acao" &&
        request.headers.find("origin") != request.headers.end()) {
      response->AddCustomHeader("Access-Control-Allow-Credentials", "true");
      response->AddCustomHeader("Access-Control-Allow-Origin",
                                request.headers.at("origin"));
    }
    std::optional<std::string> dict_hash =
        GetAvailableDictionary(request.headers);
    if (dict_hash) {
      if (*dict_hash == kExpectedDictionaryHashBase64) {
        if (HasSharedDictionaryAcceptEncoding(request.headers)) {
            response->AddCustomHeader(
                "content-encoding",
                net::shared_dictionary::kSharedZstdContentEncodingName);
            response->set_content(kZstdCompressedDataString);
        } else {
          response->set_content(kErrorNoSharedDictionaryAcceptEncodingString);
        }
      } else {
        response->set_content(kErrorInvalidHashString);
      }
    } else {
      response->set_content(kUncompressedDataString);
    }

    return response;
  }
};

// Tests end to end functionality of "compression dictionary transport" feature
// with fully enabled features.
class SharedDictionaryBrowserTest
    : public SharedDictionaryBrowserTestBase,
      public ::testing::WithParamInterface<BrowserType> {
 public:
  SharedDictionaryBrowserTest() {}
  SharedDictionaryBrowserTest(const SharedDictionaryBrowserTest&) = delete;
  SharedDictionaryBrowserTest& operator=(const SharedDictionaryBrowserTest&) =
      delete;

  // ContentBrowserTest implementation:
  void SetUpOnMainThread() override {
    RegisterTestRequestHandler(*embedded_test_server());
    RegisterRedirectRequestHandler(*embedded_test_server());
    RegisterClearSiteDataRequestHandler(*embedded_test_server());
    RegisterHttpAuthRequestHandler(*embedded_test_server());
    ASSERT_TRUE(embedded_test_server()->Start());

    cross_origin_server_ = std::make_unique<net::EmbeddedTestServer>();
    cross_origin_server()->AddDefaultHandlers(GetTestDataFilePath());
    RegisterTestRequestHandler(*cross_origin_server());
    RegisterRedirectRequestHandler(*cross_origin_server());
    RegisterClearSiteDataRequestHandler(*cross_origin_server());
    ASSERT_TRUE(cross_origin_server()->Start());

    host_resolver()->AddRule("*", "127.0.0.1");
  }
  void TearDownOnMainThread() override { off_the_record_shell_ = nullptr; }

  std::string FetchSameOriginRequest(const GURL& url) {
    return EvalJs(GetTargetShell()->web_contents()->GetPrimaryMainFrame(),
                  JsReplace(R"(
          (async () => {
            try {
              const res = await fetch($1, {mode: 'same-origin'});
              return await res.text();
            } catch {
              return 'failed to fetch';
            }
          })();
        )",
                            url))
        .ExtractString();
  }

  std::string LoadTestScript(const GURL& url) {
    return EvalJs(GetTargetShell()->web_contents()->GetPrimaryMainFrame(),
                  JsReplace(R"(
          (async () => {
            return await new Promise(resolve => {
              window.test = resolve;
              const script = document.createElement('script');
              script.src = $1;
              document.body.appendChild(script);
            });
          })();
        )",
                            url))
        .ExtractString();
  }
  std::string LoadTestScriptWithCrossOriginAnonymous(const GURL& url) {
    return EvalJs(GetTargetShell()->web_contents()->GetPrimaryMainFrame(),
                  JsReplace(R"(
          (async () => {
            return await new Promise(resolve => {
              window.test = resolve;
              const script = document.createElement('script');
              script.src = $1;
              script.addEventListener('error', () => {resolve('load failed');});
              script.crossOrigin = 'anonymous';
              document.body.appendChild(script);
            });
          })();
        )",
                            url))
        .ExtractString();
  }
  std::string LoadTestScriptWithCrossOriginUseCredentials(const GURL& url) {
    return EvalJs(GetTargetShell()->web_contents()->GetPrimaryMainFrame(),
                  JsReplace(R"(
          (async () => {
            return await new Promise(resolve => {
              window.test = resolve;
              const script = document.createElement('script');
              script.src = $1;
              script.addEventListener('error', () => {resolve('load failed');});
              script.crossOrigin = 'use-credentials';
              document.body.appendChild(script);
            });
          })();
        )",
                            url))
        .ExtractString();
  }
  std::string LoadTestIframe(const GURL& url) {
    return EvalJs(GetTargetShell()->web_contents()->GetPrimaryMainFrame(),
                  IframeLoadScript(url))
        .ExtractString();
  }

 protected:
  BrowserType GetBrowserType() const { return GetParam(); }
  net::EmbeddedTestServer* cross_origin_server() const {
    return cross_origin_server_.get();
  }

  Shell* GetTargetShell() {
    if (GetBrowserType() == BrowserType::kNormal) {
      return shell();
    }
    if (!off_the_record_shell_) {
      off_the_record_shell_ = CreateOffTheRecordBrowser();
    }
    return off_the_record_shell_;
  }
  network::mojom::NetworkContext* GetTargetNetworkContext() {
    return GetTargetShell()
        ->web_contents()
        ->GetBrowserContext()
        ->GetDefaultStoragePartition()
        ->GetNetworkContext();
  }

  void RunWriteDictionaryTest(FetchType fetch_type,
                              const GURL& page_url,
                              const GURL& dictionary_url,
                              bool expect_success = true) {
    RunWriteDictionaryTestImpl(
        GetTargetShell(), fetch_type, page_url, dictionary_url,
        GetBrowserType() == BrowserType::kNormal
            ? "Net.SharedDictionaryManagerOnDisk.DictionarySize"
            : "Net.SharedDictionaryWriterInMemory.DictionarySize",
        expect_success);
  }

  GURL GetURL(std::string_view relative_url) const {
    return embedded_test_server()->GetURL(relative_url);
  }
  GURL GetURL(std::string_view hostname, std::string_view relative_url) const {
    return embedded_test_server()->GetURL(hostname, relative_url);
  }
  GURL GetCrossOriginURL(std::string_view relative_url) const {
    return cross_origin_server()->GetURL(relative_url);
  }

  bool HasPreloadedSharedDictionaryInfo() {
    bool result = false;
    base::RunLoop run_loop;
    GetTargetNetworkContext()->HasPreloadedSharedDictionaryInfoForTesting(
        base::BindLambdaForTesting([&](bool value) {
          result = value;
          run_loop.Quit();
        }));
    run_loop.Run();
    return result;
  }

  void SendMemoryPressureToNetworkService() {
    content::GetNetworkService()->OnMemoryPressure(
        base::MEMORY_PRESSURE_LEVEL_CRITICAL);
    // To make sure that OnMemoryPressure has been received by the network
    // service, send a GetNetworkList IPC and wait for the result.
    base::RunLoop run_loop;
    content::GetNetworkService()->GetNetworkList(
        net::INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES,
        base::BindLambdaForTesting(
            [&](const std::optional<net::NetworkInterfaceList>&
                    interface_list) { run_loop.Quit(); }));
    run_loop.Run();
  }

 private:
  void RegisterRedirectRequestHandler(net::EmbeddedTestServer& server) {
    server.RegisterRequestHandler(base::BindRepeating(
        &SharedDictionaryBrowserTest::RedirectRequestHandler,
        base::Unretained(this)));
  }
  std::unique_ptr<net::test_server::HttpResponse> RedirectRequestHandler(
      const net::test_server::HttpRequest& request) {
    if (!base::StartsWith(request.relative_url, "/redirect")) {
      return nullptr;
    }
    auto response = std::make_unique<net::test_server::BasicHttpResponse>();
    response->set_code(net::HTTP_MOVED_PERMANENTLY);
    const std::string location = request.GetURL().GetQuery();
    response->AddCustomHeader("Location", location);
    if (request.headers.find("origin") != request.headers.end()) {
      response->AddCustomHeader("Access-Control-Allow-Credentials", "true");
      response->AddCustomHeader("Access-Control-Allow-Origin",
                                request.headers.at("origin"));
    }
    return response;
  }

  void RegisterClearSiteDataRequestHandler(net::EmbeddedTestServer& server) {
    server.RegisterRequestHandler(base::BindRepeating(
        &SharedDictionaryBrowserTest::ClearSiteDataRequestHandler,
        base::Unretained(this)));
  }
  std::unique_ptr<net::test_server::HttpResponse> ClearSiteDataRequestHandler(
      const net::test_server::HttpRequest& request) {
    if (!base::StartsWith(request.relative_url,
                          "/shared_dictionary/clear_site_data")) {
      return nullptr;
    }
    auto response = std::make_unique<net::test_server::BasicHttpResponse>();
    response->set_code(net::HTTP_OK);

    // We need these Access-Control-Allow-* headers for cross origin tests.
    if (request.headers.find("origin") != request.headers.end()) {
      response->AddCustomHeader("Access-Control-Allow-Credentials", "true");
      response->AddCustomHeader("Access-Control-Allow-Origin",
                                request.headers.at("origin"));
    }

    if (request.GetURL().GetQuery() == "cache") {
      response->AddCustomHeader("Clear-Site-Data", "\"cache\"");
    } else if (request.GetURL().GetQuery() == "cookies") {
      response->AddCustomHeader("Clear-Site-Data", "\"cookies\"");
    } else if (request.GetURL().GetQuery() == "storage") {
      response->AddCustomHeader("Clear-Site-Data", "\"storage\"");
    }
    response->set_content("");
    return response;
  }
  void RegisterHttpAuthRequestHandler(net::EmbeddedTestServer& server) {
    server.RegisterRequestHandler(base::BindRepeating(
        &SharedDictionaryBrowserTest::HttpAuthRequestHandler,
        base::Unretained(this)));
  }
  std::unique_ptr<net::test_server::HttpResponse> HttpAuthRequestHandler(
      const net::test_server::HttpRequest& request) {
    if (!base::StartsWith(request.relative_url, kHttpAuthPath)) {
      return nullptr;
    }
    auto response = std::make_unique<net::test_server::BasicHttpResponse>();
    if (base::Contains(request.headers, "Authorization")) {
      response->set_code(net::HTTP_OK);
      std::optional<std::string> dict_hash =
          GetAvailableDictionary(request.headers);
      if (dict_hash) {
        if (*dict_hash == kExpectedDictionaryHashBase64) {
          if (HasSharedDictionaryAcceptEncoding(request.headers)) {
            response->AddCustomHeader("content-encoding", "dcb");
            response->set_content(kBrotliCompressedDataString);
          } else {
            response->set_content(kErrorNoSharedDictionaryAcceptEncodingString);
          }
        } else {
          response->set_content(kErrorInvalidHashString);
        }
      } else {
        response->set_content(kUncompressedDataString);
      }
    } else {
      response->set_code(net::HTTP_UNAUTHORIZED);
      response->AddCustomHeader("WWW-Authenticate",
                                "Basic realm=\"test realm\"");
    }
    return response;
  }

  raw_ptr<Shell> off_the_record_shell_ = nullptr;
  std::unique_ptr<net::EmbeddedTestServer> cross_origin_server_;
};

INSTANTIATE_TEST_SUITE_P(All,
                         SharedDictionaryBrowserTest,
                         testing::Values(BrowserType::kNormal,
                                         BrowserType::kOffTheRecord),
                         [](const testing::TestParamInfo<BrowserType>& info) {
                           return ToString(info.param);
                         });

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       LinkRelCompressionDictionarySecureContext) {
  // http://127.0.0.1:PORT/ is secure context, so the dictionary should be
  // written.
  RunWriteDictionaryTest(FetchType::kLinkRelCompressionDictionary,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict"));
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       FetchDictionarySecureContext) {
  // http://127.0.0.1:PORT/ is secure context, so the dictionary should be
  // written.
  RunWriteDictionaryTest(FetchType::kFetchApi,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict"));
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       LinkRelCompressionDictionaryDocumentHeader) {
  RunWriteDictionaryTest(FetchType::kLinkRelCompressionDictionaryDocumentHeader,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict"));
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       LinkRelCompressionDictionarySubresourceHeader) {
  RunWriteDictionaryTest(
      FetchType::kLinkRelCompressionDictionarySubresourceHeader,
      GetURL("/shared_dictionary/blank.html"),
      GetURL("/shared_dictionary/test.dict"));
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       FetchDictionaryWithSameOriginMode) {
  RunWriteDictionaryTest(FetchType::kFetchApiWithSameOriginMode,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict"));
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       FetchDictionaryWithNoCorsMode) {
  RunWriteDictionaryTest(FetchType::kFetchApiWithNoCorsMode,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict"));
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       LinkRelCompressionDictionaryInsecureContext) {
  // http://www.test/ is insecure context, so the dictionary should not be
  // written.
  RunWriteDictionaryTest(FetchType::kLinkRelCompressionDictionary,
                         GetURL("www.test", "/shared_dictionary/blank.html"),
                         GetURL("www.test", "/shared_dictionary/test.dict"),
                         /*expect_success=*/false);
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       FetchDictionaryInsecureContext) {
  // http://www.test/ is insecure context, so the dictionary should not be
  // written.
  RunWriteDictionaryTest(FetchType::kFetchApi,
                         GetURL("www.test", "/shared_dictionary/blank.html"),
                         GetURL("www.test", "/shared_dictionary/test.dict"),
                         /*expect_success=*/false);
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       FetchDictionaryFromDedicatedWorker) {
  RunWriteDictionaryTest(FetchType::kFetchApiFromDedicatedWorker,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict"));
}

#if !BUILDFLAG(IS_ANDROID)
// Shared workers are not supported on Android.
IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       FetchDictionaryFromSharedWorker) {
  RunWriteDictionaryTest(FetchType::kFetchApiFromSharedWorker,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict"));
}
#endif  // !BUILDFLAG(IS_ANDROID)

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       FetchDictionaryFromServiceWorker) {
  RunWriteDictionaryTest(FetchType::kFetchApiFromServiceWorker,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict"));
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       FetchDictionaryUingIframeNavigation) {
  RunWriteDictionaryTest(FetchType::kIframeNavigation,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test_dict.html"),
                         /*expect_success=*/false);
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       CrossOriginLinkRelCompressionDictionary) {
  RunWriteDictionaryTest(FetchType::kLinkRelCompressionDictionary,
                         GetURL("/shared_dictionary/blank.html"),
                         GetCrossOriginURL("/shared_dictionary/test.dict"));
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       CrossOriginFetchDictionary) {
  RunWriteDictionaryTest(FetchType::kFetchApi,
                         GetURL("/shared_dictionary/blank.html"),
                         GetCrossOriginURL("/shared_dictionary/test.dict"));
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       FetchCompressedDictionarySecureContext) {
  RunWriteDictionaryTest(FetchType::kFetchApi,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict.gz"));
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       CrossOriginLinkRelCompressionDictionaryWithoutACAO) {
  RunWriteDictionaryTest(
      FetchType::kLinkRelCompressionDictionary,
      GetURL("/shared_dictionary/blank.html"),
      GetCrossOriginURL("/shared_dictionary/test_no_acao.dict"),
      /*expect_success=*/false);
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       CrossOriginFetchDictionaryWithoutACAO) {
  RunWriteDictionaryTest(
      FetchType::kFetchApi, GetURL("/shared_dictionary/blank.html"),
      GetCrossOriginURL("/shared_dictionary/test_no_acao.dict"),
      /*expect_success=*/false);
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       CrossOriginFetchDictionaryWithNoCorsMode) {
  RunWriteDictionaryTest(FetchType::kFetchApiWithNoCorsMode,
                         GetURL("/shared_dictionary/blank.html"),
                         GetCrossOriginURL("/shared_dictionary/test.dict"),
                         /*expect_success=*/false);
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       CrossOriginFetchDictionaryUingIframeNavigation) {
  RunWriteDictionaryTest(FetchType::kIframeNavigation,
                         GetURL("/shared_dictionary/blank.html"),
                         GetCrossOriginURL("/shared_dictionary/test_dict.html"),
                         /*expect_success=*/false);
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       SameOriginModeRequestSameOriginResource) {
  RunWriteDictionaryTest(FetchType::kFetchApi,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict"));

  EXPECT_EQ(kCompressedDataOriginalString,
            FetchSameOriginRequest(GetURL(kTestPath)));
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       NoCorsModeRequestSameOriginResource) {
  RunWriteDictionaryTest(FetchType::kFetchApi,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict"));

  EXPECT_EQ(kCompressedDataResultString,
            LoadTestScript(GetURL(kTestPath + "?1")))
      << "Same origin resource";

  EXPECT_EQ(kCompressedDataResultString,
            LoadTestScript(GURL(GetURL("/redirect?").spec() +
                                GetURL(kTestPath + "?2").spec())))
      << "Redirected from same origin to same origin resource";

  EXPECT_EQ(kUncompressedDataResultString,
            LoadTestScript(GURL(GetCrossOriginURL("/redirect?").spec() +
                                GetURL(kTestPath + "?3").spec())))
      << "Redirected from cross origin to same origin resource";

  EXPECT_EQ(kUncompressedDataResultString,
            LoadTestScript(GURL(GetURL("/redirect?").spec() +
                                GetCrossOriginURL("/redirect?").spec() +
                                GetURL(kTestPath + "?4").spec())))
      << "Redirected from same origin via cross origin to same origin resource";
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       NoCorsModeRequestCrossOriginResource) {
  RunWriteDictionaryTest(FetchType::kFetchApi,
                         GetURL("/shared_dictionary/blank.html"),
                         GetCrossOriginURL("/shared_dictionary/test.dict"));

  EXPECT_EQ(kUncompressedDataResultString,
            LoadTestScript(GetCrossOriginURL(kTestPath + "?1")))
      << "Cross origin resource";

  EXPECT_EQ(kUncompressedDataResultString,
            LoadTestScript(GURL(GetURL("/redirect?").spec() +
                                GetCrossOriginURL(kTestPath + "?2").spec())))
      << "Redirected from same origin to cross origin resource";

  EXPECT_EQ(kUncompressedDataResultString,
            LoadTestScript(GURL(GetCrossOriginURL("/redirect?").spec() +
                                GetCrossOriginURL(kTestPath + "?3").spec())))
      << "Redirected from cross origin to cross origin resource";

  EXPECT_EQ(kUncompressedDataResultString,
            LoadTestScript(GURL(GetCrossOriginURL("/redirect?").spec() +
                                GetURL("/redirect?").spec() +
                                GetCrossOriginURL(kTestPath + "?4").spec())))
      << "Redirected from cross origin via same origin to cross origin "
         "resource";
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       CorsModeRequestSameOriginResource) {
  RunWriteDictionaryTest(FetchType::kFetchApi,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict"));

  EXPECT_EQ(kCompressedDataResultString,
            LoadTestScriptWithCrossOriginAnonymous(GetURL(kTestPath + "?1")))
      << "Same origin resource";
  EXPECT_EQ(kCompressedDataResultString,
            LoadTestScriptWithCrossOriginAnonymous(GURL(
                GetURL("/redirect?").spec() + GetURL(kTestPath + "?2").spec())))
      << "Redirected from same origin to same origin resource";
  EXPECT_EQ(kCompressedDataResultString,
            LoadTestScriptWithCrossOriginAnonymous(
                GURL(GetCrossOriginURL("/redirect?").spec() +
                     GetURL(kTestPath + "?3").spec())))
      << "Redirected from cross origin to same origin resource";
  EXPECT_EQ(
      kCompressedDataResultString,
      LoadTestScriptWithCrossOriginAnonymous(GURL(
          GetURL("/redirect?").spec() + GetCrossOriginURL("/redirect?").spec() +
          GetURL(kTestPath + "?4").spec())))
      << "Redirected from same origin via cross origin to same origin resource";
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       CorModeRequestCrossOriginResource) {
  RunWriteDictionaryTest(FetchType::kFetchApi,
                         GetURL("/shared_dictionary/blank.html"),
                         GetCrossOriginURL("/shared_dictionary/test.dict"));

  EXPECT_EQ(kCompressedDataResultString,
            LoadTestScriptWithCrossOriginAnonymous(
                GetCrossOriginURL(kTestPath + "?1")))
      << "Cross origin resource";
  EXPECT_EQ(kCompressedDataResultString,
            LoadTestScriptWithCrossOriginAnonymous(
                GURL(GetURL("/redirect?").spec() +
                     GetCrossOriginURL(kTestPath + "?2").spec())))
      << "Redirected from same origin to cross origin resource";
  EXPECT_EQ(kCompressedDataResultString,
            LoadTestScriptWithCrossOriginAnonymous(
                GURL(GetCrossOriginURL("/redirect?").spec() +
                     GetCrossOriginURL(kTestPath + "?3").spec())))
      << "Redirected from cross origin to cross origin resource";
  EXPECT_EQ(
      kCompressedDataResultString,
      LoadTestScriptWithCrossOriginAnonymous(GURL(
          GetCrossOriginURL("/redirect?").spec() + GetURL("/redirect?").spec() +
          GetCrossOriginURL(kTestPath + "?4").spec())))
      << "Redirected from cross origin via same origin to cross origin "
         "resource";
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       CorsModeRequestWithCredentialsSameOriginResource) {
  RunWriteDictionaryTest(FetchType::kFetchApi,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict"));

  EXPECT_EQ(
      kCompressedDataResultString,
      LoadTestScriptWithCrossOriginUseCredentials(GetURL(kTestPath + "?1")))
      << "Same origin resource";
  EXPECT_EQ(kCompressedDataResultString,
            LoadTestScriptWithCrossOriginUseCredentials(GURL(
                GetURL("/redirect?").spec() + GetURL(kTestPath + "?2").spec())))
      << "Redirected from same origin to same origin resource";
  EXPECT_EQ(kCompressedDataResultString,
            LoadTestScriptWithCrossOriginUseCredentials(
                GURL(GetCrossOriginURL("/redirect?").spec() +
                     GetURL(kTestPath + "?3").spec())))
      << "Redirected from cross origin to same origin resource";
  EXPECT_EQ(
      kCompressedDataResultString,
      LoadTestScriptWithCrossOriginUseCredentials(GURL(
          GetURL("/redirect?").spec() + GetCrossOriginURL("/redirect?").spec() +
          GetURL(kTestPath + "?4").spec())))
      << "Redirected from same origin via cross origin to same origin resource";
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       CorModeRequestWithCredentialsCrossOriginResource) {
  RunWriteDictionaryTest(FetchType::kFetchApi,
                         GetURL("/shared_dictionary/blank.html"),
                         GetCrossOriginURL("/shared_dictionary/test.dict"));

  EXPECT_EQ(kCompressedDataResultString,
            LoadTestScriptWithCrossOriginUseCredentials(
                GetCrossOriginURL(kTestPath + "?1")))
      << "Cross origin resource";
  EXPECT_EQ(kCompressedDataResultString,
            LoadTestScriptWithCrossOriginUseCredentials(
                GURL(GetURL("/redirect?").spec() +
                     GetCrossOriginURL(kTestPath + "?2").spec())))
      << "Redirected from same origin to cross origin resource";
  EXPECT_EQ(kCompressedDataResultString,
            LoadTestScriptWithCrossOriginUseCredentials(
                GURL(GetCrossOriginURL("/redirect?").spec() +
                     GetCrossOriginURL(kTestPath + "?3").spec())))
      << "Redirected from cross origin to cross origin resource";
  EXPECT_EQ(
      kCompressedDataResultString,
      LoadTestScriptWithCrossOriginUseCredentials(GURL(
          GetCrossOriginURL("/redirect?").spec() + GetURL("/redirect?").spec() +
          GetCrossOriginURL(kTestPath + "?4").spec())))
      << "Redirected from cross origin via same origin to cross origin "
         "resource";
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest, Navigation) {
  RunWriteDictionaryTest(FetchType::kFetchApi,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict"));

  const GURL target_url = GetURL(kTestPath + "?html");

  base::RunLoop loop;
  auto observer = std::make_unique<SharedDictionaryAccessObserver>(
      GetTargetShell()->web_contents(), loop.QuitClosure());
  EXPECT_TRUE(NavigateToURL(GetTargetShell(), target_url));
  loop.Run();

  ASSERT_TRUE(observer->details());
  EXPECT_EQ(network::mojom::SharedDictionaryAccessDetails::Type::kRead,
            observer->details()->type);
  EXPECT_EQ(target_url, observer->details()->url);
  EXPECT_EQ(net::SharedDictionaryIsolationKey(url::Origin::Create(target_url),
                                              net::SchemefulSite(target_url)),
            observer->details()->isolation_key);
  EXPECT_FALSE(observer->details()->is_blocked);

  EXPECT_EQ(kCompressedDataOriginalString,
            EvalJs(GetTargetShell()->web_contents()->GetPrimaryMainFrame(),
                   "document.body.innerText")
                .ExtractString());
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       NavigationAfterSameOriginRedirect) {
  RunWriteDictionaryTest(FetchType::kFetchApi,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict"));

  const GURL target_url = GetURL(kTestPath + "?html");
  const GURL redirect_url =
      GURL(GetURL("/redirect?").spec() + GetURL(kTestPath + "?html").spec());

  base::RunLoop loop;
  auto observer = std::make_unique<SharedDictionaryAccessObserver>(
      GetTargetShell()->web_contents(), loop.QuitClosure());
  EXPECT_TRUE(NavigateToURL(GetTargetShell(), redirect_url, target_url));
  loop.Run();

  ASSERT_TRUE(observer->details());
  EXPECT_EQ(network::mojom::SharedDictionaryAccessDetails::Type::kRead,
            observer->details()->type);
  EXPECT_EQ(target_url, observer->details()->url);
  EXPECT_EQ(net::SharedDictionaryIsolationKey(url::Origin::Create(target_url),
                                              net::SchemefulSite(target_url)),
            observer->details()->isolation_key);
  EXPECT_FALSE(observer->details()->is_blocked);

  EXPECT_EQ(kCompressedDataOriginalString,
            EvalJs(GetTargetShell()->web_contents()->GetPrimaryMainFrame(),
                   "document.body.innerText")
                .ExtractString());
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       NavigationAfterCrossOriginRedirect) {
  RunWriteDictionaryTest(FetchType::kFetchApi,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict"));

  const GURL target_url = GetURL(kTestPath + "?html");
  const GURL redirect_url = GURL(GetCrossOriginURL("/redirect?").spec() +
                                 GetURL(kTestPath + "?html").spec());

  base::RunLoop loop;
  auto observer = std::make_unique<SharedDictionaryAccessObserver>(
      GetTargetShell()->web_contents(), loop.QuitClosure());
  EXPECT_TRUE(NavigateToURL(GetTargetShell(), redirect_url, target_url));
  loop.Run();

  ASSERT_TRUE(observer->details());
  EXPECT_EQ(network::mojom::SharedDictionaryAccessDetails::Type::kRead,
            observer->details()->type);
  EXPECT_EQ(target_url, observer->details()->url);
  EXPECT_EQ(net::SharedDictionaryIsolationKey(url::Origin::Create(target_url),
                                              net::SchemefulSite(target_url)),
            observer->details()->isolation_key);
  EXPECT_FALSE(observer->details()->is_blocked);

  EXPECT_EQ(kCompressedDataOriginalString,
            EvalJs(GetTargetShell()->web_contents()->GetPrimaryMainFrame(),
                   "document.body.innerText")
                .ExtractString());
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest, IframeNavigation) {
  RunWriteDictionaryTest(FetchType::kFetchApi,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict"));

  const GURL target_url = GetURL(kTestPath + "?html");

  base::RunLoop loop;
  auto observer = std::make_unique<SharedDictionaryAccessObserver>(
      GetTargetShell()->web_contents(), loop.QuitClosure());

  EXPECT_EQ(kCompressedDataOriginalString, LoadTestIframe(target_url));
  loop.Run();

  ASSERT_TRUE(observer->details());
  EXPECT_EQ(network::mojom::SharedDictionaryAccessDetails::Type::kRead,
            observer->details()->type);
  EXPECT_EQ(target_url, observer->details()->url);
  EXPECT_EQ(net::SharedDictionaryIsolationKey(url::Origin::Create(target_url),
                                              net::SchemefulSite(target_url)),
            observer->details()->isolation_key);
  EXPECT_FALSE(observer->details()->is_blocked);
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       IframeNavigationAfterSameOriginRedirect) {
  RunWriteDictionaryTest(FetchType::kFetchApi,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict"));

  const GURL target_url = GetURL(kTestPath + "?html");
  const GURL redirect_url =
      GURL(GetURL("/redirect?").spec() + GetURL(kTestPath + "?html").spec());

  base::RunLoop loop;
  auto observer = std::make_unique<SharedDictionaryAccessObserver>(
      GetTargetShell()->web_contents(), loop.QuitClosure());

  EXPECT_EQ(kCompressedDataOriginalString, LoadTestIframe(redirect_url));
  loop.Run();

  ASSERT_TRUE(observer->details());
  EXPECT_EQ(network::mojom::SharedDictionaryAccessDetails::Type::kRead,
            observer->details()->type);
  EXPECT_EQ(target_url, observer->details()->url);
  EXPECT_EQ(net::SharedDictionaryIsolationKey(url::Origin::Create(target_url),
                                              net::SchemefulSite(target_url)),
            observer->details()->isolation_key);
  EXPECT_FALSE(observer->details()->is_blocked);
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       IframeNavigationAfterCrossOriginRedirect) {
  RunWriteDictionaryTest(FetchType::kFetchApi,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict"));

  const GURL target_url = GetURL(kTestPath + "?html");
  const GURL redirect_url = GURL(GetCrossOriginURL("/redirect?").spec() +
                                 GetURL(kTestPath + "?html").spec());

  base::RunLoop loop;
  auto observer = std::make_unique<SharedDictionaryAccessObserver>(
      GetTargetShell()->web_contents(), loop.QuitClosure());

  EXPECT_EQ(kCompressedDataOriginalString, LoadTestIframe(redirect_url));
  loop.Run();

  ASSERT_TRUE(observer->details());
  EXPECT_EQ(network::mojom::SharedDictionaryAccessDetails::Type::kRead,
            observer->details()->type);
  EXPECT_EQ(target_url, observer->details()->url);
  EXPECT_EQ(net::SharedDictionaryIsolationKey(url::Origin::Create(target_url),
                                              net::SchemefulSite(target_url)),
            observer->details()->isolation_key);
  EXPECT_FALSE(observer->details()->is_blocked);
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest, MatchDestEmptyString) {
  Shell* shell = GetTargetShell();
  EXPECT_TRUE(NavigateToURL(shell, GetURL("/shared_dictionary/blank.html")));

  // The response header contains `match-dest=("")` in Use-As-Dictionary header.
  const GURL dictionary_url = GetURL("/shared_dictionary/test.empty_dest.dict");
  EXPECT_TRUE(ExecJs(shell->web_contents()->GetPrimaryMainFrame(),
                     LinkRelCompressionDictionaryScript(dictionary_url)));

  // Wait for the dictionary to be registered.
  EXPECT_TRUE(WaitForHistogram(
      GetBrowserType() == BrowserType::kNormal
          ? "Net.SharedDictionaryManagerOnDisk.DictionarySize"
          : "Net.SharedDictionaryWriterInMemory.DictionarySize"));

  // Check that Chrome uses the dictionary while fetching the resource using
  // Fetch API.
  EXPECT_EQ(kCompressedDataOriginalString,
            EvalJs(shell->web_contents()->GetPrimaryMainFrame(),
                   FetchTargetDataScript(dictionary_url))
                .ExtractString());

  // Check that Chrome doesn't use the dictionary while fetching a script.
  EXPECT_EQ(kUncompressedDataResultString,
            LoadTestScript(GetURL(kTestPath + "?for_script")));
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest, MatchDestScript) {
  Shell* shell = GetTargetShell();
  EXPECT_TRUE(NavigateToURL(shell, GetURL("/shared_dictionary/blank.html")));

  // The response header contains `match-dest=("script")` in Use-As-Dictionary
  // header.
  const GURL dictionary_url =
      GetURL("/shared_dictionary/test.script_dest.dict");
  EXPECT_TRUE(ExecJs(shell->web_contents()->GetPrimaryMainFrame(),
                     LinkRelCompressionDictionaryScript(dictionary_url)));

  // Wait for the dictionary to be registered.
  EXPECT_TRUE(WaitForHistogram(
      GetBrowserType() == BrowserType::kNormal
          ? "Net.SharedDictionaryManagerOnDisk.DictionarySize"
          : "Net.SharedDictionaryWriterInMemory.DictionarySize"));

  // Check that Chrome uses the dictionary while fetching a script.
  EXPECT_EQ(kCompressedDataResultString,
            LoadTestScript(GetURL(kTestPath + "?for_script")));

  // Check that Chrome doesn't use the dictionary while fetching the resource
  // using Fetch API.
  EXPECT_EQ(kUncompressedDataString,
            EvalJs(shell->web_contents()->GetPrimaryMainFrame(),
                   FetchTargetDataScript(dictionary_url))
                .ExtractString());
}

IN_PROC_BROWSER_TEST_P(
    SharedDictionaryBrowserTest,
    GetUsageInfoAndClearSharedDictionaryCacheForIsolationKey) {
  RunWriteDictionaryTest(FetchType::kLinkRelCompressionDictionary,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict"));

  net::SharedDictionaryIsolationKey isolation_key =
      net::SharedDictionaryIsolationKey(url::Origin::Create(GetURL("/")),
                                        net::SchemefulSite(GetURL("/")));

  EXPECT_THAT(GetSharedDictionaryUsageInfo(GetTargetShell()),
              UnorderedElementsAreArray({net::SharedDictionaryUsageInfo{
                  .isolation_key = isolation_key,
                  .total_size_bytes = static_cast<uint64_t>(
                      GetTestDataFileSize("shared_dictionary/test.dict"))}}));
  {
    base::RunLoop loop;
    GetTargetNetworkContext()->ClearSharedDictionaryCacheForIsolationKey(
        isolation_key, loop.QuitClosure());
    loop.Run();
  }
  EXPECT_TRUE(GetSharedDictionaryUsageInfo(GetTargetShell()).empty());
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest, GetTotalSizeAndOrigins) {
  base::Time time1 = base::Time::Now();
  RunWriteDictionaryTest(FetchType::kLinkRelCompressionDictionary,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict"));
  base::Time time2 = base::Time::Now();

  EXPECT_TRUE(
      GetOriginsBetween(GetTargetShell(), time1 - base::Seconds(1), time1)
          .empty());
  EXPECT_THAT(GetOriginsBetween(GetTargetShell(), time1, time2),
              testing::ElementsAreArray({url::Origin::Create(GetURL("/"))}));
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest, GetSharedDictionaryInfo) {
  RunWriteDictionaryTest(FetchType::kLinkRelCompressionDictionary,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict"));

  net::SharedDictionaryIsolationKey isolation_key =
      net::SharedDictionaryIsolationKey(url::Origin::Create(GetURL("/")),
                                        net::SchemefulSite(GetURL("/")));
  {
    base::RunLoop loop;
    GetTargetNetworkContext()->GetSharedDictionaryInfo(
        isolation_key,
        base::BindLambdaForTesting(
            [&](std::vector<network::mojom::SharedDictionaryInfoPtr> result) {
              ASSERT_EQ(1u, result.size());

              EXPECT_EQ("/shared_dictionary/path/*", result[0]->match);
              EXPECT_EQ(GetURL("/shared_dictionary/test.dict"),
                        result[0]->dictionary_url);
              EXPECT_EQ(static_cast<uint64_t>(
                            GetTestDataFileSize("shared_dictionary/test.dict")),
                        result[0]->size);
              EXPECT_EQ(kExpectedDictionaryHashValue, result[0]->hash);
              loop.Quit();
            }));
    loop.Run();
  }
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest, ClearSiteData) {
  RunWriteDictionaryTest(FetchType::kLinkRelCompressionDictionary,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict"));
  base::RunLoop loop;
  content::ClearSiteData(
      GetTargetShell()->web_contents()->GetBrowserContext()->GetWeakPtr(),
      /*storage_partition_config=*/std::nullopt,
      /*origin=*/url::Origin::Create(GetURL("/")),
      content::ClearSiteDataTypeSet::All(),
      /*storage_buckets_to_remove=*/{},
      /*avoid_closing_connections=*/true,
      /*cookie_partition_key=*/std::nullopt,
      /*storage_key=*/std::nullopt,
      /*partitioned_state_allowed_only=*/false,
      /*callback=*/loop.QuitClosure());
  loop.Run();

  EXPECT_TRUE(GetSharedDictionaryUsageInfo(GetTargetShell()).empty());
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       ClearSiteDataNavigationCacheDirective) {
  RunWriteDictionaryTest(FetchType::kLinkRelCompressionDictionary,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict"));
  EXPECT_EQ(1u, GetSharedDictionaryUsageInfo(GetTargetShell()).size());
  EXPECT_TRUE(NavigateToURL(
      GetTargetShell(), GetURL("/shared_dictionary/clear_site_data?cache")));
  // Navigation to a page which HTTP response header contains
  // `Clear-Site-Data: "cache"` should clear the shared dictionary.
  EXPECT_TRUE(GetSharedDictionaryUsageInfo(GetTargetShell()).empty());
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       ClearSiteDataNavigationCookiesDirective) {
  RunWriteDictionaryTest(FetchType::kLinkRelCompressionDictionary,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict"));
  EXPECT_EQ(1u, GetSharedDictionaryUsageInfo(GetTargetShell()).size());
  EXPECT_TRUE(NavigateToURL(
      GetTargetShell(), GetURL("/shared_dictionary/clear_site_data?cookies")));
  // Navigation to a page which HTTP response header contains
  // `Clear-Site-Data: "cookies"` should clear the shared dictionary.
  EXPECT_TRUE(GetSharedDictionaryUsageInfo(GetTargetShell()).empty());
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       ClearSiteDataNavigationStorageDirective) {
  RunWriteDictionaryTest(FetchType::kLinkRelCompressionDictionary,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict"));
  EXPECT_EQ(1u, GetSharedDictionaryUsageInfo(GetTargetShell()).size());
  EXPECT_TRUE(NavigateToURL(
      GetTargetShell(), GetURL("/shared_dictionary/clear_site_data?storage")));
  // Navigation to a page which HTTP response header contains
  // `Clear-Site-Data: "storage"` should NOT clear the shared dictionary.
  EXPECT_EQ(1u, GetSharedDictionaryUsageInfo(GetTargetShell()).size());
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       ClearSiteDataFetchCacheDirective) {
  RunWriteDictionaryTest(FetchType::kLinkRelCompressionDictionary,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict"));
  EXPECT_EQ(1u, GetSharedDictionaryUsageInfo(GetTargetShell()).size());
  EXPECT_TRUE(
      ExecJs(GetTargetShell(),
             JsReplace("fetch($1);",
                       GetURL("/shared_dictionary/clear_site_data?cache"))));
  // Fetching a resource which HTTP response header contains
  // `Clear-Site-Data: "cache"` should clear the shared dictionary.
  EXPECT_TRUE(GetSharedDictionaryUsageInfo(GetTargetShell()).empty());
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       ClearSiteDataFetchCookiesDirective) {
  RunWriteDictionaryTest(FetchType::kLinkRelCompressionDictionary,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict"));
  EXPECT_EQ(1u, GetSharedDictionaryUsageInfo(GetTargetShell()).size());
  EXPECT_TRUE(
      ExecJs(GetTargetShell(),
             JsReplace("fetch($1);",
                       GetURL("/shared_dictionary/clear_site_data?cookies"))));
  // Fetching a resource which HTTP response header contains
  // `Clear-Site-Data: "cookies"` should clear the shared dictionary.
  EXPECT_TRUE(GetSharedDictionaryUsageInfo(GetTargetShell()).empty());
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       ClearSiteDataFetchStorageDirective) {
  RunWriteDictionaryTest(FetchType::kLinkRelCompressionDictionary,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict"));
  EXPECT_EQ(1u, GetSharedDictionaryUsageInfo(GetTargetShell()).size());
  EXPECT_TRUE(
      ExecJs(GetTargetShell(),
             JsReplace("fetch($1);",
                       GetURL("/shared_dictionary/clear_site_data?storage"))));
  // Fetching a resource which HTTP response header contains
  // `Clear-Site-Data: "storage"` should NOT clear the shared dictionary.
  EXPECT_EQ(1u, GetSharedDictionaryUsageInfo(GetTargetShell()).size());
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       ClearSiteDataCrossOriginFetchCacheDirective) {
  RunWriteDictionaryTest(FetchType::kLinkRelCompressionDictionary,
                         GetURL("/shared_dictionary/blank.html"),
                         GetCrossOriginURL("/shared_dictionary/test.dict"));
  EXPECT_EQ(1u, GetSharedDictionaryUsageInfo(GetTargetShell()).size());
  // Setting the credentials flag because Clear-Site-Data header handling works
  // only when credentials flag is set.
  EXPECT_TRUE(ExecJs(
      GetTargetShell(),
      JsReplace(
          "fetch($1, {credentials: 'include'});",
          GetCrossOriginURL("/shared_dictionary/clear_site_data?cache"))));
  // Fetching a cross origin resource which HTTP response header contains
  // `Clear-Site-Data: "cache"` should clear the shared dictionary.
  EXPECT_TRUE(GetSharedDictionaryUsageInfo(GetTargetShell()).empty());
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       ClearSiteDataCrossOriginFetchCookiesDirective) {
  RunWriteDictionaryTest(FetchType::kLinkRelCompressionDictionary,
                         GetURL("/shared_dictionary/blank.html"),
                         GetCrossOriginURL("/shared_dictionary/test.dict"));
  EXPECT_EQ(1u, GetSharedDictionaryUsageInfo(GetTargetShell()).size());
  // Setting the credentials flag because Clear-Site-Data header handling works
  // only when credentials flag is set.
  EXPECT_TRUE(ExecJs(
      GetTargetShell(),
      JsReplace(
          "fetch($1, {credentials: 'include'});",
          GetCrossOriginURL("/shared_dictionary/clear_site_data?cookies"))));
  // Fetching a cross origin resource which HTTP response header contains
  // `Clear-Site-Data: "cookies"` should clear the shared dictionary.
  EXPECT_TRUE(GetSharedDictionaryUsageInfo(GetTargetShell()).empty());
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       ClearSiteDataCrossOriginFetchStorageDirective) {
  RunWriteDictionaryTest(FetchType::kLinkRelCompressionDictionary,
                         GetURL("/shared_dictionary/blank.html"),
                         GetCrossOriginURL("/shared_dictionary/test.dict"));
  EXPECT_EQ(1u, GetSharedDictionaryUsageInfo(GetTargetShell()).size());
  // Setting the credentials flag because Clear-Site-Data header handling works
  // only when credentials flag is set.
  EXPECT_TRUE(ExecJs(
      GetTargetShell(),
      JsReplace(
          "fetch($1, {credentials: 'include'});",
          GetCrossOriginURL("/shared_dictionary/clear_site_data?storage"))));
  // Fetching a cross origin resource which HTTP response header contains
  // `Clear-Site-Data: "storage"` should NOT clear the shared dictionary.
  EXPECT_EQ(1u, GetSharedDictionaryUsageInfo(GetTargetShell()).size());
}

// TODO(crbug.com/40599527): When we support wildcard directive
// `Clear-Site-Data: "*"", add test for it.

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       DictionaryReadCountForNavigation) {
  if (GetBrowserType() == BrowserType::kOffTheRecord) {
    // We want to test the behavior of SharedDictionaryStorageOnDisk.
    return;
  }
  base::HistogramTester histogram_tester;
  EXPECT_TRUE(NavigateToURL(shell(), GetURL("/shared_dictionary/blank.html")));
  const std::string histogram_name =
      "Net.SharedDictionaryStorageOnDisk.MetadataReadTime.Empty";

  EXPECT_TRUE(WaitForHistogram(histogram_name));
  histogram_tester.ExpectTotalCount(histogram_name,
                                    /*expected_count=*/1);
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest, RestartWithAuth) {
  RunWriteDictionaryTest(FetchType::kFetchApi,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict"));

  DummyAuthContentBrowserClient browser_client;

  EXPECT_FALSE(browser_client.create_login_delegate_called());
  ASSERT_TRUE(NavigateToURL(GetTargetShell(), GetURL(kHttpAuthPath)));
  EXPECT_TRUE(browser_client.create_login_delegate_called());
  EXPECT_EQ(kCompressedDataOriginalString,
            EvalJs(GetTargetShell()->web_contents()->GetPrimaryMainFrame(),
                   "document.body.innerText")
                .ExtractString());
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       RestartedAfterCertErrorPageUseSbr) {
  net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
  https_server.ServeFilesFromSourceDirectory(GetTestDataFilePath());
  RegisterTestRequestHandler(https_server);
  ASSERT_TRUE(https_server.Start());
  RunWriteDictionaryTest(FetchType::kFetchApi,
                         https_server.GetURL("/shared_dictionary/blank.html"),
                         https_server.GetURL("/shared_dictionary/test.dict"));

  // Resetting the SSL config of the server to trigger a certificate error.
  ASSERT_TRUE(https_server.ResetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED,
                                          net::SSLServerConfig()));

  CertificateErrorAllowingContentBrowserClient browser_client;
  EXPECT_FALSE(browser_client.allow_certificate_error_called());
  EXPECT_TRUE(NavigateToURL(GetTargetShell(),
                            https_server.GetURL(kTestPath + "?html")));
  EXPECT_TRUE(browser_client.allow_certificate_error_called());

  EXPECT_EQ(kCompressedDataOriginalString,
            EvalJs(GetTargetShell()->web_contents()->GetPrimaryMainFrame(),
                   "document.body.innerText")
                .ExtractString());
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       RestartWithCertificatePageUseSbr) {
  net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
  https_server.ServeFilesFromSourceDirectory(GetTestDataFilePath());
  RegisterTestRequestHandler(https_server);
  ASSERT_TRUE(https_server.Start());
  RunWriteDictionaryTest(FetchType::kFetchApi,
                         https_server.GetURL("/shared_dictionary/blank.html"),
                         https_server.GetURL("/shared_dictionary/test.dict"));

  // Resetting the SSL config of the server to require a client certificate.
  net::SSLServerConfig server_config;
  server_config.client_cert_type = net::SSLServerConfig::REQUIRE_CLIENT_CERT;
  ASSERT_TRUE(https_server.ResetSSLConfig(net::EmbeddedTestServer::CERT_OK,
                                          server_config));

  DummyClientCertStoreContentBrowserClient browser_client;
  EXPECT_FALSE(browser_client.select_client_certificate_called());
  EXPECT_TRUE(NavigateToURL(GetTargetShell(),
                            https_server.GetURL(kTestPath + "?html")));
  EXPECT_TRUE(browser_client.select_client_certificate_called());
  EXPECT_EQ(kCompressedDataOriginalString,
            EvalJs(GetTargetShell()->web_contents()->GetPrimaryMainFrame(),
                   "document.body.innerText")
                .ExtractString());
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       EncodedBodySizeAndDecodedBodySize) {
  RunWriteDictionaryTest(FetchType::kLinkRelCompressionDictionary,
                         GetURL("/shared_dictionary/blank.html"),
                         GetURL("/shared_dictionary/test.dict"));

  EXPECT_EQ(base::StringPrintf("%zu, %zu", kZstdCompressedDataString.size(),
                               kCompressedDataOriginalString.size()),
            EvalJs(GetTargetShell()->web_contents()->GetPrimaryMainFrame(),
                   JsReplace(R"(
          (async () => {
            const targetUrl = $1;
            const promise = new Promise((resolve) => {
              const observer = new PerformanceObserver((list) => {
                list.getEntries().forEach((entry) => {
                  if (entry.name == targetUrl) {
                    resolve(entry);
                  }
                });
              });
              observer.observe({ type: 'resource', buffered: true });
            });
            fetch(targetUrl);
            const entry = await promise;
            return entry.encodedBodySize + ', ' + entry.decodedBodySize;
          })();
        )",
                             GetURL("/shared_dictionary/path/test?")))
                .ExtractString());
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       PreloadSharedDictionaryInfo) {
  mojo::PendingRemote<network::mojom::PreloadedSharedDictionaryInfoHandle>
      preloaded_shared_dictionaries_handle;
  GetTargetNetworkContext()->PreloadSharedDictionaryInfoForDocument(
      {GetURL("/")},
      preloaded_shared_dictionaries_handle.InitWithNewPipeAndPassReceiver());
  EXPECT_TRUE(HasPreloadedSharedDictionaryInfo());
  preloaded_shared_dictionaries_handle.reset();
  EXPECT_FALSE(HasPreloadedSharedDictionaryInfo());
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       DoNotPreloadDictionayUnderMemoryPressure) {
  SendMemoryPressureToNetworkService();
  mojo::PendingRemote<network::mojom::PreloadedSharedDictionaryInfoHandle>
      preloaded_shared_dictionaries_handle;
  GetTargetNetworkContext()->PreloadSharedDictionaryInfoForDocument(
      {GetURL("/")},
      preloaded_shared_dictionaries_handle.InitWithNewPipeAndPassReceiver());
  EXPECT_FALSE(HasPreloadedSharedDictionaryInfo());
}

IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                       PreloadedDictionayDiscardedByMemoryPressure) {
  mojo::PendingRemote<network::mojom::PreloadedSharedDictionaryInfoHandle>
      preloaded_shared_dictionaries_handle;
  GetTargetNetworkContext()->PreloadSharedDictionaryInfoForDocument(
      {GetURL("/")},
      preloaded_shared_dictionaries_handle.InitWithNewPipeAndPassReceiver());
  EXPECT_TRUE(HasPreloadedSharedDictionaryInfo());
  SendMemoryPressureToNetworkService();
  EXPECT_FALSE(HasPreloadedSharedDictionaryInfo());
}

}  // namespace

}  // namespace content
