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

#include <memory>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

#include "base/containers/contains.h"
#include "base/functional/callback.h"
#include "base/strings/strcat.h"
#include "base/strings/string_split.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "base/time/time.h"
#include "net/base/features.h"
#include "net/cookies/cookie_constants.h"
#include "net/cookies/cookie_options.h"
#include "net/cookies/cookie_util.h"
#include "net/first_party_sets/same_party_context.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "url/origin.h"

namespace net {

namespace {

struct RequestCookieParsingTest {
  std::string str;
  base::StringPairs parsed;
  // Used for malformed cookies where the parsed-then-serialized string does not
  // match the original string.
  std::string serialized;
};

void CheckParse(const std::string& str,
                const base::StringPairs& parsed_expected) {
  cookie_util::ParsedRequestCookies parsed;
  cookie_util::ParseRequestCookieLine(str, &parsed);
  EXPECT_EQ(parsed_expected, parsed);
}

void CheckSerialize(const base::StringPairs& parsed,
                    const std::string& str_expected) {
  EXPECT_EQ(str_expected, cookie_util::SerializeRequestCookieLine(parsed));
}

TEST(CookieUtilTest, TestDomainIsHostOnly) {
  const struct {
    const char* str;
    const bool is_host_only;
  } tests[] = {{"", true}, {"www.foo.com", true}, {".foo.com", false}};

  for (const auto& test : tests) {
    EXPECT_EQ(test.is_host_only, cookie_util::DomainIsHostOnly(test.str));
  }
}

// A cookie domain containing non-ASCII characters is not allowed, even if it
// matches the domain from the URL.
TEST(CookieUtilTest, GetCookieDomainWithString_NonASCII) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeature(features::kCookieDomainRejectNonASCII);

  CookieInclusionStatus status;
  std::string result;
  EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
      GURL("http://éxample.com"), "éxample.com", status, &result));
  EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
      {CookieInclusionStatus::EXCLUDE_DOMAIN_NON_ASCII}));
}

// An empty domain string results in the domain from the URL.
TEST(CookieUtilTest, GetCookieDomainWithString_Empty) {
  CookieInclusionStatus status;
  std::string result;
  EXPECT_TRUE(cookie_util::GetCookieDomainWithString(GURL("http://example.com"),
                                                     "", status, &result));
  EXPECT_TRUE(status.IsInclude());
  EXPECT_EQ(result, "example.com");
}

// A cookie domain string equal to the URL host, when that is an IP, results in
// the IP.
TEST(CookieUtilTest, GetCookieDomainWithString_IP) {
  CookieInclusionStatus status;
  std::string result;
  EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
      GURL("http://192.0.2.3"), "192.0.2.3", status, &result));
  EXPECT_TRUE(status.IsInclude());
  EXPECT_EQ(result, "192.0.2.3");
}

// A cookie domain string equal to a dot prefixed to the URL host, when that is
// an IP, results in the IP, without the dot.
TEST(CookieUtilTest, GetCookieDomainWithString_DotIP) {
  CookieInclusionStatus status;
  std::string result;
  EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
      GURL("http://192.0.2.3"), ".192.0.2.3", status, &result));
  EXPECT_TRUE(status.IsInclude());
  EXPECT_EQ(result, "192.0.2.3");
}

// A cookie domain string containing %-encoding is not allowed.
TEST(CookieUtilTest, GetCookieDomainWithString_PercentEncoded) {
  CookieInclusionStatus status;
  std::string result;
  EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
      GURL("http://a.test"), "a%2Etest", status, &result));
  EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
}

// A cookie domain string that cannot be canonicalized is not allowed.
TEST(CookieUtilTest, GetCookieDomainWithString_UnCanonicalizable) {
  CookieInclusionStatus status;
  std::string result;
  EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
      GURL("http://a.test"), "a^test", status, &result));
  EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
}

// A cookie domain that is an eTLD but matches the URL results in a host cookie
// domain.
TEST(CookieUtilTest, GetCookieDomainWithString_ETldMatchesUrl) {
  CookieInclusionStatus status;
  std::string result;
  EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
      GURL("http://gov.uk"), "gov.uk", status, &result));
  EXPECT_TRUE(status.IsInclude());
  EXPECT_EQ(result, "gov.uk");
}

// A cookie domain that is an eTLD but matches the URL results in a host cookie
// domain, even if it is given with a dot prefix.
TEST(CookieUtilTest, GetCookieDomainWithString_ETldMatchesUrl_DotPrefix) {
  CookieInclusionStatus status;
  std::string result;
  EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
      GURL("http://gov.uk"), ".gov.uk", status, &result));
  EXPECT_TRUE(status.IsInclude());
  EXPECT_EQ(result, "gov.uk");
}

// A cookie domain that is an eTLD but matches the URL results in a host cookie
// domain, even if its capitalization is non-canonical.
TEST(CookieUtilTest, GetCookieDomainWithString_ETldMatchesUrl_NonCanonical) {
  CookieInclusionStatus status;
  std::string result;
  EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
      GURL("http://gov.uk"), "GoV.Uk", status, &result));
  EXPECT_TRUE(status.IsInclude());
  EXPECT_EQ(result, "gov.uk");
}

// A cookie domain that is an eTLD but does not match the URL is not allowed.
TEST(CookieUtilTest, GetCookieDomainWithString_ETldDifferentUrl) {
  CookieInclusionStatus status;
  std::string result;
  EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
      GURL("http://nhs.gov.uk"), "gov.uk", status, &result));
  EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
}

// A cookie domain with a different eTLD+1 ("organization-identifying host")
// from the URL is not allowed.
TEST(CookieUtilTest, GetCookieDomainWithString_DifferentOrgHost) {
  CookieInclusionStatus status;
  std::string result;
  EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
      GURL("http://portal.globex.com"), "portal.initech.com", status, &result));
  EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
}

// A cookie domain that matches the URL results in a domain cookie domain.
TEST(CookieUtilTest, GetCookieDomainWithString_MatchesUrl) {
  CookieInclusionStatus status;
  std::string result;
  EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
      GURL("http://globex.com"), "globex.com", status, &result));
  EXPECT_TRUE(status.IsInclude());
  EXPECT_EQ(result, ".globex.com");
}

// A cookie domain that matches the URL but has a `.` prefix results in a domain
// cookie domain.
TEST(CookieUtilTest, GetCookieDomainWithString_MatchesUrlWithDot) {
  CookieInclusionStatus status;
  std::string result;
  EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
      GURL("http://globex.com"), ".globex.com", status, &result));
  EXPECT_TRUE(status.IsInclude());
  EXPECT_EQ(result, ".globex.com");
}

// A cookie domain that is a subdomain of the URL host is not allowed.
TEST(CookieUtilTest, GetCookieDomainWithString_Subdomain) {
  CookieInclusionStatus status;
  std::string result;
  EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
      GURL("http://globex.com"), "mail.globex.com", status, &result));
  EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
}

// A URL that is a subdomain of the cookie domain results in a domain cookie.
TEST(CookieUtilTest, GetCookieDomainWithString_UrlSubdomain) {
  CookieInclusionStatus status;
  std::string result;
  EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
      GURL("http://mail.globex.com"), "globex.com", status, &result));
  EXPECT_TRUE(status.IsInclude());
  EXPECT_EQ(result, ".globex.com");
}

// A URL of which the cookie domain is a substring, but not a dotted suffix,
// is not allowed.
TEST(CookieUtilTest, GetCookieDomainWithString_SubstringButUrlNotSubdomain) {
  CookieInclusionStatus status;
  std::string result;
  EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
      GURL("http://myglobex.com"), "globex.com", status, &result));
  EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
}

// A URL which has a different subdomain of the eTLD+1 than the cookie domain is
// not allowed, regardless of which hostname is longer.
TEST(CookieUtilTest, GetCookieDomainWithString_DifferentSubdomain) {
  CookieInclusionStatus status;
  std::string result;
  EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
      GURL("http://l.globex.com"), "portal.globex.com", status, &result));
  EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
  EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
      GURL("http://portal.globex.com"), "l.globex.com", status, &result));
  EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
}

// A URL without a host can set a "host" cookie with no cookie domain.
TEST(CookieUtilTest, GetCookieDomainWithString_NoUrlHost) {
  CookieInclusionStatus status;
  std::string result;
  EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
      GURL("file:///C:/bar.html"), "", status, &result));
  EXPECT_EQ(result, "");
}

// A URL with two trailing dots (which is an invalid hostname per
// rfc6265bis-11#5.1.2 and will cause GetDomainAndRegistry to return an empty
// string) is not allowed.
TEST(CookieUtilTest, GetCookieDomainWithString_TrailingDots) {
  CookieInclusionStatus status;
  std::string result;
  EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
      GURL("http://foo.com../"), "foo.com..", status, &result));
  EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
}

// A "normal" URL does not match with a cookie containing two trailing dots (or
// just one).
TEST(CookieUtilTest,
     GetCookieDomainWithString_TrailingDots_NotMatchingUrlHost) {
  CookieInclusionStatus status;
  std::string result;
  EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
      GURL("http://foo.com/"), ".foo.com..", status, &result));
  EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
  EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
      GURL("http://foo.com/"), ".foo.com.", status, &result));
  EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
}

// A URL containing an IP address is allowed, if that IP matches the cookie
// domain.
TEST(CookieUtilTest, GetCookieDomainWithString_UrlHostIP) {
  CookieInclusionStatus status;
  std::string result;
  EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
      GURL("http://192.0.2.3/"), "192.0.2.3", status, &result));
  EXPECT_EQ(result, "192.0.2.3");
}

// A cookie domain with a dot-prefixed IP is allowed, if the IP matches
// the URL, but is transformed to a host cookie domain.
TEST(CookieUtilTest, GetCookieDomainWithString_UrlHostIP_DomainCookie) {
  CookieInclusionStatus status;
  std::string result;
  EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
      GURL("http://192.0.2.3/"), ".192.0.2.3", status, &result));
  EXPECT_EQ(result, "192.0.2.3");  // No dot.
}

// A URL containing a TLD that is unknown as a registry is allowed, if it
// matches the cookie domain.
TEST(CookieUtilTest, GetCookieDomainWithString_UnknownRegistry) {
  CookieInclusionStatus status;
  std::string result;
  EXPECT_TRUE(cookie_util::GetCookieDomainWithString(GURL("http://bar/"), "bar",
                                                     status, &result));
  EXPECT_EQ(result, "bar");
}

TEST(CookieUtilTest, TestCookieDateParsing) {
  const struct {
    const char* str;
    const bool valid;
    const double epoch;
  } tests[] = {
      {"Sat, 15-Apr-17 21:01:22 GMT", true, 1492290082},
      {"Thu, 19-Apr-2007 16:00:00 GMT", true, 1176998400},
      {"Wed, 25 Apr 2007 21:02:13 GMT", true, 1177534933},
      {"Thu, 19/Apr\\2007 16:00:00 GMT", true, 1176998400},
      {"Fri, 1 Jan 2010 01:01:50 GMT", true, 1262307710},
      {"Wednesday, 1-Jan-2003 00:00:00 GMT", true, 1041379200},
      {", 1-Jan-2003 00:00:00 GMT", true, 1041379200},
      {" 1-Jan-2003 00:00:00 GMT", true, 1041379200},
      {"1-Jan-2003 00:00:00 GMT", true, 1041379200},
      {"Wed,18-Apr-07 22:50:12 GMT", true, 1176936612},
      {"WillyWonka  , 18-Apr-07 22:50:12 GMT", true, 1176936612},
      {"WillyWonka  , 18-Apr-07 22:50:12", true, 1176936612},
      {"WillyWonka  ,  18-apr-07   22:50:12", true, 1176936612},
      {"Mon, 18-Apr-1977 22:50:13 GMT", true, 230251813},
      {"Mon, 18-Apr-77 22:50:13 GMT", true, 230251813},
      // If the cookie came in with the expiration quoted (which in terms of
      // the RFC you shouldn't do), we will get string quoted.  Bug 1261605.
      {"\"Sat, 15-Apr-17\\\"21:01:22\\\"GMT\"", true, 1492290082},
      // Test with full month names and partial names.
      {"Partyday, 18- April-07 22:50:12", true, 1176936612},
      {"Partyday, 18 - Apri-07 22:50:12", true, 1176936612},
      {"Wednes, 1-Januar-2003 00:00:00 GMT", true, 1041379200},
      // Test that we always take GMT even with other time zones or bogus
      // values.  The RFC says everything should be GMT, and in the worst case
      // we are 24 hours off because of zone issues.
      {"Sat, 15-Apr-17 21:01:22", true, 1492290082},
      {"Sat, 15-Apr-17 21:01:22 GMT-2", true, 1492290082},
      {"Sat, 15-Apr-17 21:01:22 GMT BLAH", true, 1492290082},
      {"Sat, 15-Apr-17 21:01:22 GMT-0400", true, 1492290082},
      {"Sat, 15-Apr-17 21:01:22 GMT-0400 (EDT)", true, 1492290082},
      {"Sat, 15-Apr-17 21:01:22 DST", true, 1492290082},
      {"Sat, 15-Apr-17 21:01:22 -0400", true, 1492290082},
      {"Sat, 15-Apr-17 21:01:22 (hello there)", true, 1492290082},
      // Test that if we encounter multiple : fields, that we take the first
      // that correctly parses.
      {"Sat, 15-Apr-17 21:01:22 11:22:33", true, 1492290082},
      {"Sat, 15-Apr-17 ::00 21:01:22", true, 1492290082},
      {"Sat, 15-Apr-17 boink:z 21:01:22", true, 1492290082},
      // We take the first, which in this case is invalid.
      {"Sat, 15-Apr-17 91:22:33 21:01:22", false, 0},
      // amazon.com formats their cookie expiration like this.
      {"Thu Apr 18 22:50:12 2007 GMT", true, 1176936612},
      // Test that hh:mm:ss can occur anywhere.
      {"22:50:12 Thu Apr 18 2007 GMT", true, 1176936612},
      {"Thu 22:50:12 Apr 18 2007 GMT", true, 1176936612},
      {"Thu Apr 22:50:12 18 2007 GMT", true, 1176936612},
      {"Thu Apr 18 22:50:12 2007 GMT", true, 1176936612},
      {"Thu Apr 18 2007 22:50:12 GMT", true, 1176936612},
      {"Thu Apr 18 2007 GMT 22:50:12", true, 1176936612},
      // Test that the day and year can be anywhere if they are unambigious.
      {"Sat, 15-Apr-17 21:01:22 GMT", true, 1492290082},
      {"15-Sat, Apr-17 21:01:22 GMT", true, 1492290082},
      {"15-Sat, Apr 21:01:22 GMT 17", true, 1492290082},
      {"15-Sat, Apr 21:01:22 GMT 2017", true, 1492290082},
      {"15 Apr 21:01:22 2017", true, 1492290082},
      {"15 17 Apr 21:01:22", true, 1492290082},
      {"Apr 15 17 21:01:22", true, 1492290082},
      {"Apr 15 21:01:22 17", true, 1492290082},
      {"2017 April 15 21:01:22", true, 1492290082},
      {"15 April 2017 21:01:22", true, 1492290082},
      // Test two-digit abbreviated year numbers.
      {"1-Jan-71 00:00:00 GMT" /* 1971 */, true, 31536000},
      {"1-Jan-70 00:00:00 GMT" /* 1970 */, true, 0},
      {"1-Jan-69 00:00:00 GMT" /* 2069 */, true, 3124224000},
      {"1-Jan-68 00:00:00 GMT" /* 2068 */, true, 3092601600},
      // Some invalid dates
      {"98 April 17 21:01:22", false, 0},
      {"Thu, 012-Aug-2008 20:49:07 GMT", false, 0},
      {"Thu, 12-Aug-9999999999 20:49:07 GMT", false, 0},
      {"Thu, 999999999999-Aug-2007 20:49:07 GMT", false, 0},
      {"Thu, 12-Aug-2007 20:61:99999999999 GMT", false, 0},
      {"IAintNoDateFool", false, 0},
      {"1600 April 33 21:01:22", false, 0},
      {"1970 April 33 21:01:22", false, 0},
      {"Thu, 33-Aug-31841 20:49:07 GMT", false, 0},
  };

  base::Time parsed_time;
  for (const auto& test : tests) {
    parsed_time = cookie_util::ParseCookieExpirationTime(test.str);
    if (!test.valid) {
      EXPECT_TRUE(parsed_time.is_null()) << test.str;
      continue;
    }
    EXPECT_TRUE(!parsed_time.is_null()) << test.str;
    EXPECT_EQ(test.epoch, parsed_time.ToDoubleT()) << test.str;
  }
}

// Tests parsing dates that are beyond 2038. 32-bit (non-Mac) POSIX systems are
// incapable of doing this, however the expectation is for cookie parsing to
// succeed anyway (and return the minimum value Time::FromUTCExploded() can
// parse on the current platform). Also checks a date outside the limit on
// Windows, which is year 30827.
TEST(CookieUtilTest, ParseCookieExpirationTimeBeyond2038) {
  const char* kTests[] = {
      "Thu, 12-Aug-31841 20:49:07 GMT", "2039 April 15 21:01:22",
      "2039 April 15 21:01:22",         "2038 April 15 21:01:22",
      "15 April 69 21:01:22",           "15 April 68, 21:01:22",
  };

  for (auto* test : kTests) {
    base::Time parsed_time = cookie_util::ParseCookieExpirationTime(test);
    EXPECT_FALSE(parsed_time.is_null());

    // It should either have an exact value, or be base::Time::Max(). For
    // simplicity just check that it is greater than an arbitray date.
    base::Time almost_jan_2038 = base::Time::UnixEpoch() + base::Days(365 * 68);
    EXPECT_LT(almost_jan_2038, parsed_time);
  }
}

// Tests parsing dates that are prior to (or around) 1970. Non-Mac POSIX systems
// are incapable of doing this, however the expectation is for cookie parsing to
// succeed anyway (and return a minimal base::Time).
TEST(CookieUtilTest, ParseCookieExpirationTimeBefore1970) {
  const char* kTests[] = {
      // Times around the Unix epoch.
      "1970 Jan 1 00:00:00",
      "1969 March 3 21:01:22",
      // Two digit year abbreviations.
      "1-Jan-70 00:00:00",
      "Jan 1, 70 00:00:00",
      // Times around the Windows epoch.
      "1601 Jan 1 00:00:00",
      "1600 April 15 21:01:22",
      // Times around kExplodedMinYear on Mac.
      "1902 Jan 1 00:00:00",
      "1901 Jan 1 00:00:00",
  };

  for (auto* test : kTests) {
    base::Time parsed_time = cookie_util::ParseCookieExpirationTime(test);
    EXPECT_FALSE(parsed_time.is_null()) << test;

    // It should either have an exact value, or should be base::Time(1)
    // For simplicity just check that it is less than the unix epoch.
    EXPECT_LE(parsed_time, base::Time::UnixEpoch()) << test;
  }
}

TEST(CookieUtilTest, TestRequestCookieParsing) {
  std::vector<RequestCookieParsingTest> tests;

  // Simple case.
  tests.emplace_back();
  tests.back().str = "key=value";
  tests.back().parsed.emplace_back(std::string("key"), std::string("value"));
  // Multiple key/value pairs.
  tests.emplace_back();
  tests.back().str = "key1=value1; key2=value2";
  tests.back().parsed.emplace_back(std::string("key1"), std::string("value1"));
  tests.back().parsed.emplace_back(std::string("key2"), std::string("value2"));
  // Empty value.
  tests.emplace_back();
  tests.back().str = "key=; otherkey=1234";
  tests.back().parsed.emplace_back(std::string("key"), std::string());
  tests.back().parsed.emplace_back(std::string("otherkey"),
                                   std::string("1234"));
  // Special characters (including equals signs) in value.
  tests.emplace_back();
  tests.back().str = "key=; a2=s=(./&t=:&u=a#$; a3=+~";
  tests.back().parsed.emplace_back(std::string("key"), std::string());
  tests.back().parsed.emplace_back(std::string("a2"),
                                   std::string("s=(./&t=:&u=a#$"));
  tests.back().parsed.emplace_back(std::string("a3"), std::string("+~"));
  // Quoted value.
  tests.emplace_back();
  tests.back().str = "key=\"abcdef\"; otherkey=1234";
  tests.back().parsed.emplace_back(std::string("key"),
                                   std::string("\"abcdef\""));
  tests.back().parsed.emplace_back(std::string("otherkey"),
                                   std::string("1234"));

  for (size_t i = 0; i < tests.size(); i++) {
    SCOPED_TRACE(testing::Message() << "Test " << i);
    CheckParse(tests[i].str, tests[i].parsed);
    CheckSerialize(tests[i].parsed, tests[i].str);
  }
}

TEST(CookieUtilTest, TestRequestCookieParsing_Malformed) {
  std::vector<RequestCookieParsingTest> tests;

  // Missing equal sign.
  tests.emplace_back();
  tests.back().str = "key";
  tests.back().parsed.emplace_back(std::string("key"), std::string());
  tests.back().serialized = "key=";

  // Quoted value with unclosed quote.
  tests.emplace_back();
  tests.back().str = "key=\"abcdef";

  // Quoted value with unclosed quote followed by regular value.
  tests.emplace_back();
  tests.back().str = "key=\"abcdef; otherkey=1234";

  // Quoted value with unclosed quote followed by another quoted value.
  tests.emplace_back();
  tests.back().str = "key=\"abcdef; otherkey=\"1234\"";
  tests.back().parsed.emplace_back(std::string("key"),
                                   std::string("\"abcdef; otherkey=\""));
  tests.back().parsed.emplace_back(std::string("234\""), std::string());
  tests.back().serialized = "key=\"abcdef; otherkey=\"; 234\"=";

  // Regular value followed by quoted value with unclosed quote.
  tests.emplace_back();
  tests.back().str = "key=abcdef; otherkey=\"1234";
  tests.back().parsed.emplace_back(std::string("key"), std::string("abcdef"));
  tests.back().serialized = "key=abcdef";

  for (size_t i = 0; i < tests.size(); i++) {
    SCOPED_TRACE(testing::Message() << "Test " << i);
    CheckParse(tests[i].str, tests[i].parsed);
    CheckSerialize(tests[i].parsed, tests[i].serialized);
  }
}

TEST(CookieUtilTest, CookieDomainAndPathToURL) {
  struct {
    std::string domain;
    std::string path;
    bool is_https;
    std::string expected_url;
  } kTests[]{
      {"a.com", "/", true, "https://a.com/"},
      {"a.com", "/", false, "http://a.com/"},
      {".a.com", "/", true, "https://a.com/"},
      {".a.com", "/", false, "http://a.com/"},
      {"b.a.com", "/", true, "https://b.a.com/"},
      {"b.a.com", "/", false, "http://b.a.com/"},
      {"a.com", "/example/path", true, "https://a.com/example/path"},
      {".a.com", "/example/path", false, "http://a.com/example/path"},
      {"b.a.com", "/example/path", true, "https://b.a.com/example/path"},
      {".b.a.com", "/example/path", false, "http://b.a.com/example/path"},
  };

  for (auto& test : kTests) {
    GURL url1 = cookie_util::CookieDomainAndPathToURL(test.domain, test.path,
                                                      test.is_https);
    GURL url2 = cookie_util::CookieDomainAndPathToURL(
        test.domain, test.path, std::string(test.is_https ? "https" : "http"));
    // Test both overloads for equality.
    EXPECT_EQ(url1, url2);
    EXPECT_EQ(url1, GURL(test.expected_url));
  }
}

TEST(CookieUtilTest, SimulatedCookieSource) {
  GURL secure_url("https://b.a.com");
  GURL insecure_url("http://b.a.com");

  struct {
    std::string cookie;
    std::string source_scheme;
    std::string expected_simulated_source;
  } kTests[]{
      {"cookie=foo", "http", "http://b.a.com/"},
      {"cookie=foo", "https", "https://b.a.com/"},
      {"cookie=foo", "wss", "wss://b.a.com/"},
      {"cookie=foo", "file", "file://b.a.com/"},
      {"cookie=foo; Domain=b.a.com", "https", "https://b.a.com/"},
      {"cookie=foo; Domain=a.com", "https", "https://a.com/"},
      {"cookie=foo; Domain=.b.a.com", "https", "https://b.a.com/"},
      {"cookie=foo; Domain=.a.com", "https", "https://a.com/"},
      {"cookie=foo; Path=/", "https", "https://b.a.com/"},
      {"cookie=foo; Path=/bar", "https", "https://b.a.com/bar"},
      {"cookie=foo; Domain=b.a.com; Path=/", "https", "https://b.a.com/"},
      {"cookie=foo; Domain=b.a.com; Path=/bar", "https", "https://b.a.com/bar"},
      {"cookie=foo; Domain=a.com; Path=/", "https", "https://a.com/"},
      {"cookie=foo; Domain=a.com; Path=/bar", "https", "https://a.com/bar"},
  };

  for (const auto& test : kTests) {
    std::vector<std::unique_ptr<CanonicalCookie>> cookies;
    // It shouldn't depend on the cookie's secureness or actual source scheme.
    cookies.push_back(
        CanonicalCookie::Create(insecure_url, test.cookie, base::Time::Now(),
                                absl::nullopt /* server_time */,
                                absl::nullopt /* cookie_partition_key */));
    cookies.push_back(
        CanonicalCookie::Create(secure_url, test.cookie, base::Time::Now(),
                                absl::nullopt /* server_time */,
                                absl::nullopt /* cookie_partition_key */));
    cookies.push_back(CanonicalCookie::Create(
        secure_url, test.cookie + "; Secure", base::Time::Now(),
        absl::nullopt /* server_time */,
        absl::nullopt /* cookie_partition_key */));
    for (const auto& cookie : cookies) {
      GURL simulated_source =
          cookie_util::SimulatedCookieSource(*cookie, test.source_scheme);
      EXPECT_EQ(GURL(test.expected_simulated_source), simulated_source);
    }
  }
}

TEST(CookieUtilTest, TestGetEffectiveDomain) {
  // Note: registry_controlled_domains::GetDomainAndRegistry is tested in its
  // own unittests.
  EXPECT_EQ("example.com",
            cookie_util::GetEffectiveDomain("http", "www.example.com"));
  EXPECT_EQ("example.com",
            cookie_util::GetEffectiveDomain("https", "www.example.com"));
  EXPECT_EQ("example.com",
            cookie_util::GetEffectiveDomain("ws", "www.example.com"));
  EXPECT_EQ("example.com",
            cookie_util::GetEffectiveDomain("wss", "www.example.com"));
  EXPECT_EQ("www.example.com",
            cookie_util::GetEffectiveDomain("ftp", "www.example.com"));
}

TEST(CookieUtilTest, TestIsDomainMatch) {
  EXPECT_TRUE(cookie_util::IsDomainMatch("example.com", "example.com"));
  EXPECT_FALSE(cookie_util::IsDomainMatch("www.example.com", "example.com"));

  EXPECT_TRUE(cookie_util::IsDomainMatch(".example.com", "example.com"));
  EXPECT_TRUE(cookie_util::IsDomainMatch(".example.com", "www.example.com"));
  EXPECT_FALSE(cookie_util::IsDomainMatch(".www.example.com", "example.com"));

  EXPECT_FALSE(cookie_util::IsDomainMatch("example.com", "example.de"));
  EXPECT_FALSE(cookie_util::IsDomainMatch(".example.com", "example.de"));
  EXPECT_FALSE(cookie_util::IsDomainMatch(".example.de", "example.de.vu"));
}

TEST(CookieUtilTest, TestIsOnPath) {
  EXPECT_TRUE(cookie_util::IsOnPath("/", "/"));
  EXPECT_TRUE(cookie_util::IsOnPath("/", "/test"));
  EXPECT_TRUE(cookie_util::IsOnPath("/", "/test/bar.html"));

  // Test the empty string edge case.
  EXPECT_FALSE(cookie_util::IsOnPath("/", std::string()));

  EXPECT_FALSE(cookie_util::IsOnPath("/test", "/"));

  EXPECT_TRUE(cookie_util::IsOnPath("/test", "/test"));
  EXPECT_FALSE(cookie_util::IsOnPath("/test", "/testtest/"));

  EXPECT_TRUE(cookie_util::IsOnPath("/test", "/test/bar.html"));
  EXPECT_TRUE(cookie_util::IsOnPath("/test", "/test/sample/bar.html"));
}

TEST(CookieUtilTest, TestIsOnPathCaseSensitive) {
  EXPECT_TRUE(cookie_util::IsOnPath("/test", "/test"));
  EXPECT_FALSE(cookie_util::IsOnPath("/test", "/TEST"));
  EXPECT_FALSE(cookie_util::IsOnPath("/TEST", "/test"));
}

using ::testing::AllOf;
using SameSiteCookieContext = CookieOptions::SameSiteCookieContext;
using ContextType = CookieOptions::SameSiteCookieContext::ContextType;
using ContextRedirectTypeBug1221316 = CookieOptions::SameSiteCookieContext::
    ContextMetadata::ContextRedirectTypeBug1221316;
using HttpMethod =
    CookieOptions::SameSiteCookieContext::ContextMetadata::HttpMethod;

MATCHER_P2(ContextTypeIsWithSchemefulMode, context_type, schemeful, "") {
  return context_type == (schemeful ? arg.schemeful_context() : arg.context());
}

// Checks for the expected metadata related to context downgrades from
// cross-site redirects.
MATCHER_P5(CrossSiteRedirectMetadataCorrectWithSchemefulMode,
           method,
           context_type_without_chain,
           context_type_with_chain,
           redirect_type_with_chain,
           schemeful,
           "") {
  using ContextDowngradeType = CookieOptions::SameSiteCookieContext::
      ContextMetadata::ContextDowngradeType;

  const auto& metadata = schemeful ? arg.schemeful_metadata() : arg.metadata();

  if (metadata.redirect_type_bug_1221316 != redirect_type_with_chain)
    return false;

  // http_method_bug_1221316 is only set when there is a context downgrade.
  if (metadata.cross_site_redirect_downgrade !=
          ContextDowngradeType::kNoDowngrade &&
      metadata.http_method_bug_1221316 != method) {
    return false;
  }

  switch (metadata.cross_site_redirect_downgrade) {
    case ContextDowngradeType::kNoDowngrade:
      return context_type_without_chain == context_type_with_chain;
    case ContextDowngradeType::kStrictToLax:
      return context_type_without_chain == ContextType::SAME_SITE_STRICT &&
             (context_type_with_chain == ContextType::SAME_SITE_LAX ||
              context_type_with_chain ==
                  ContextType::SAME_SITE_LAX_METHOD_UNSAFE);
    case ContextDowngradeType::kStrictToCross:
      return context_type_without_chain == ContextType::SAME_SITE_STRICT &&
             context_type_with_chain == ContextType::CROSS_SITE;
    case ContextDowngradeType::kLaxToCross:
      return (context_type_without_chain == ContextType::SAME_SITE_LAX ||
              context_type_without_chain ==
                  ContextType::SAME_SITE_LAX_METHOD_UNSAFE) &&
             context_type_with_chain == ContextType::CROSS_SITE;
  }
}

std::string UrlChainToString(const std::vector<GURL>& url_chain) {
  std::string s;
  for (const GURL& url : url_chain) {
    base::StrAppend(&s, {" ", url.spec()});
  }
  return s;
}

// Tests for the various ComputeSameSiteContextFor*() functions. The first
// boolean test param is whether the results of the computations are evaluated
// schemefully. The second boolean param is whether SameSite considers redirect
// chains.
class CookieUtilComputeSameSiteContextTest
    : public ::testing::TestWithParam<std::tuple<bool, bool>> {
 public:
  CookieUtilComputeSameSiteContextTest() {
    if (DoesSameSiteConsiderRedirectChain()) {
      feature_list_.InitAndEnableFeature(
          features::kCookieSameSiteConsidersRedirectChain);
    } else {
      // No need to explicitly disable the redirect chain feature because it
      // is disabled by default.
      feature_list_.Init();
    }
  }
  ~CookieUtilComputeSameSiteContextTest() override = default;

  bool IsSchemeful() const { return std::get<0>(GetParam()); }

  bool DoesSameSiteConsiderRedirectChain() const {
    return std::get<1>(GetParam());
  }

  // Returns the proper gtest matcher to use for the schemeless/schemeful mode.
  auto ContextTypeIs(ContextType context_type) const {
    return ContextTypeIsWithSchemefulMode(context_type, IsSchemeful());
  }

  auto CrossSiteRedirectMetadataCorrect(
      HttpMethod method,
      ContextType context_type_without_chain,
      ContextType context_type_with_chain,
      ContextRedirectTypeBug1221316 redirect_type_with_chain) const {
    return CrossSiteRedirectMetadataCorrectWithSchemefulMode(
        method, context_type_without_chain, context_type_with_chain,
        redirect_type_with_chain, IsSchemeful());
  }

  // The following methods return the sets of URLs/SiteForCookies/initiators/URL
  // chains that are same-site or cross-site with respect to kSiteUrl.

  std::vector<GURL> GetAllUrls() const {
    return {kSiteUrl,
            kSiteUrlWithPath,
            kSecureSiteUrl,
            kCrossSiteUrl,
            kSecureCrossSiteUrl,
            kSubdomainUrl,
            kSecureSubdomainUrl,
            kWsUrl,
            kWssUrl};
  }

  std::vector<GURL> GetSameSiteUrls() const {
    // Same-site-same-scheme URLs are always same-site. (ws counts as
    // same-scheme with http.)
    std::vector<GURL> same_site_urls{kSiteUrl, kSiteUrlWithPath, kSubdomainUrl,
                                     kWsUrl};
    // If schemeless, the cross-scheme URLs are also same-site.
    if (!IsSchemeful()) {
      same_site_urls.push_back(kSecureSiteUrl);
      same_site_urls.push_back(kSecureSubdomainUrl);
      same_site_urls.push_back(kWssUrl);
    }
    return same_site_urls;
  }

  std::vector<GURL> GetCrossSiteUrls() const {
    std::vector<GURL> cross_site_urls;
    std::vector<GURL> same_site_urls = GetSameSiteUrls();
    for (const GURL& url : GetAllUrls()) {
      if (!base::Contains(same_site_urls, url))
        cross_site_urls.push_back(url);
    }
    return cross_site_urls;
  }

  std::vector<SiteForCookies> GetAllSitesForCookies() const {
    return {kNullSiteForCookies, kSiteForCookies, kSecureSiteForCookies,
            kCrossSiteForCookies, kSecureCrossSiteForCookies};
  }

  std::vector<SiteForCookies> GetSameSiteSitesForCookies() const {
    std::vector<SiteForCookies> same_site_sfc = {kSiteForCookies};
    // If schemeless, the cross-scheme SFC is also same-site.
    if (!IsSchemeful())
      same_site_sfc.push_back(kSecureSiteForCookies);
    return same_site_sfc;
  }

  std::vector<SiteForCookies> GetCrossSiteSitesForCookies() const {
    std::vector<SiteForCookies> cross_site_sfc;
    std::vector<SiteForCookies> same_site_sfc = GetSameSiteSitesForCookies();
    for (const SiteForCookies& sfc : GetAllSitesForCookies()) {
      if (!base::Contains(same_site_sfc, sfc.RepresentativeUrl(),
                          &SiteForCookies::RepresentativeUrl)) {
        cross_site_sfc.push_back(sfc);
      }
    }
    return cross_site_sfc;
  }

  std::vector<absl::optional<url::Origin>> GetAllInitiators() const {
    return {kBrowserInitiated,   kOpaqueInitiator,
            kSiteInitiator,      kSecureSiteInitiator,
            kCrossSiteInitiator, kSecureCrossSiteInitiator,
            kSubdomainInitiator, kSecureSubdomainInitiator,
            kUnrelatedInitiator};
  }

  std::vector<absl::optional<url::Origin>> GetSameSiteInitiators() const {
    std::vector<absl::optional<url::Origin>> same_site_initiators{
        kBrowserInitiated, kSiteInitiator, kSubdomainInitiator};
    // If schemeless, the cross-scheme origins are also same-site.
    if (!IsSchemeful()) {
      same_site_initiators.push_back(kSecureSiteInitiator);
      same_site_initiators.push_back(kSecureSubdomainInitiator);
    }
    return same_site_initiators;
  }

  std::vector<absl::optional<url::Origin>> GetCrossSiteInitiators() const {
    std::vector<absl::optional<url::Origin>> cross_site_initiators;
    std::vector<absl::optional<url::Origin>> same_site_initiators =
        GetSameSiteInitiators();
    for (const absl::optional<url::Origin>& initiator : GetAllInitiators()) {
      if (!base::Contains(same_site_initiators, initiator))
        cross_site_initiators.push_back(initiator);
    }
    return cross_site_initiators;
  }

  // Returns an assortment of redirect chains that end in `url` as the
  // current request URL, and are completely same-site. `url` is expected to be
  // same-site to kSiteUrl.
  std::vector<std::vector<GURL>> GetSameSiteUrlChains(const GURL& url) const {
    std::vector<std::vector<GURL>> same_site_url_chains;
    for (const GURL& same_site_url : GetSameSiteUrls()) {
      same_site_url_chains.push_back({same_site_url, url});
      for (const GURL& other_same_site_url : GetSameSiteUrls()) {
        same_site_url_chains.push_back(
            {other_same_site_url, same_site_url, url});
      }
    }
    return same_site_url_chains;
  }

  // Returns an assortment of redirect chains that end in `url` as the
  // current request URL, and are cross-site. `url` is expected to be same-site
  // to kSiteUrl.
  std::vector<std::vector<GURL>> GetCrossSiteUrlChains(const GURL& url) const {
    std::vector<std::vector<GURL>> cross_site_url_chains;
    for (const GURL& cross_site_url : GetCrossSiteUrls()) {
      cross_site_url_chains.push_back({cross_site_url, url});
      for (const GURL& same_site_url : GetSameSiteUrls()) {
        cross_site_url_chains.push_back({cross_site_url, same_site_url, url});
        cross_site_url_chains.push_back({same_site_url, cross_site_url, url});
      }
    }
    return cross_site_url_chains;
  }

  // Computes possible values of is_main_frame_navigation that are consistent
  // with the DCHECKs.
  bool CanBeMainFrameNavigation(const GURL& url,
                                const SiteForCookies& site_for_cookies) const {
    return (site_for_cookies.IsNull() ||
            site_for_cookies.IsFirstPartyWithSchemefulMode(url, true)) &&
           !url.SchemeIsWSOrWSS();
  }

  std::vector<bool> IsMainFrameNavigationPossibleValues(
      const GURL& url,
      const SiteForCookies& site_for_cookies) const {
    return CanBeMainFrameNavigation(url, site_for_cookies)
               ? std::vector<bool>{false, true}
               : std::vector<bool>{false};
  }

  // Request URL.
  const GURL kSiteUrl{"http://example.test/"};
  const GURL kSiteUrlWithPath{"http://example.test/path"};
  const GURL kSecureSiteUrl{"https://example.test/"};
  const GURL kCrossSiteUrl{"http://notexample.test/"};
  const GURL kSecureCrossSiteUrl{"https://notexample.test/"};
  const GURL kSubdomainUrl{"http://subdomain.example.test/"};
  const GURL kSecureSubdomainUrl{"https://subdomain.example.test/"};
  const GURL kWsUrl{"ws://example.test/"};
  const GURL kWssUrl{"wss://example.test/"};
  // Site for cookies.
  const SiteForCookies kNullSiteForCookies;
  const SiteForCookies kSiteForCookies = SiteForCookies::FromUrl(kSiteUrl);
  const SiteForCookies kSecureSiteForCookies =
      SiteForCookies::FromUrl(kSecureSiteUrl);
  const SiteForCookies kCrossSiteForCookies =
      SiteForCookies::FromUrl(kCrossSiteUrl);
  const SiteForCookies kSecureCrossSiteForCookies =
      SiteForCookies::FromUrl(kSecureCrossSiteUrl);
  // Initiator origin.
  const absl::optional<url::Origin> kBrowserInitiated = absl::nullopt;
  const absl::optional<url::Origin> kOpaqueInitiator =
      absl::make_optional(url::Origin());
  const absl::optional<url::Origin> kSiteInitiator =
      absl::make_optional(url::Origin::Create(kSiteUrl));
  const absl::optional<url::Origin> kSecureSiteInitiator =
      absl::make_optional(url::Origin::Create(kSecureSiteUrl));
  const absl::optional<url::Origin> kCrossSiteInitiator =
      absl::make_optional(url::Origin::Create(kCrossSiteUrl));
  const absl::optional<url::Origin> kSecureCrossSiteInitiator =
      absl::make_optional(url::Origin::Create(kSecureCrossSiteUrl));
  const absl::optional<url::Origin> kSubdomainInitiator =
      absl::make_optional(url::Origin::Create(kSubdomainUrl));
  const absl::optional<url::Origin> kSecureSubdomainInitiator =
      absl::make_optional(url::Origin::Create(kSecureSubdomainUrl));
  const absl::optional<url::Origin> kUnrelatedInitiator =
      absl::make_optional(url::Origin::Create(GURL("https://unrelated.test/")));

 protected:
  base::test::ScopedFeatureList feature_list_;
};

TEST_P(CookieUtilComputeSameSiteContextTest, UrlAndSiteForCookiesCrossSite) {
  // If the SiteForCookies and URL are cross-site, then the context is always
  // cross-site.
  for (const GURL& url : GetSameSiteUrls()) {
    for (const SiteForCookies& site_for_cookies :
         GetCrossSiteSitesForCookies()) {
      for (const absl::optional<url::Origin>& initiator : GetAllInitiators()) {
        for (const std::string& method : {"GET", "POST", "PUT", "HEAD"}) {
          EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
                          url, site_for_cookies, initiator,
                          false /* force_ignore_site_for_cookies */),
                      ContextTypeIs(ContextType::CROSS_SITE));
          EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptSet(
                          url, site_for_cookies,
                          false /* force_ignore_site_for_cookies */),
                      ContextTypeIs(ContextType::CROSS_SITE));
          for (bool is_main_frame_navigation :
               IsMainFrameNavigationPossibleValues(url, site_for_cookies)) {
            EXPECT_THAT(cookie_util::ComputeSameSiteContextForRequest(
                            method, {url}, site_for_cookies, initiator,
                            is_main_frame_navigation,
                            false /* force_ignore_site_for_cookies */),
                        ContextTypeIs(ContextType::CROSS_SITE));
            EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
                            {url}, site_for_cookies, initiator,
                            is_main_frame_navigation,
                            false /* force_ignore_site_for_cookies */),
                        ContextTypeIs(ContextType::CROSS_SITE));
            // If the current request URL is cross-site to the site-for-cookies,
            // the request context is always cross-site even if the URL chain
            // contains members that are same-site to the site-for-cookies.
            EXPECT_THAT(
                cookie_util::ComputeSameSiteContextForRequest(
                    method, {site_for_cookies.RepresentativeUrl(), url},
                    site_for_cookies, initiator, is_main_frame_navigation,
                    false /* force_ignore_site_for_cookies */),
                ContextTypeIs(ContextType::CROSS_SITE));
            EXPECT_THAT(
                cookie_util::ComputeSameSiteContextForResponse(
                    {site_for_cookies.RepresentativeUrl(), url},
                    site_for_cookies, initiator, is_main_frame_navigation,
                    false /* force_ignore_site_for_cookies */),
                ContextTypeIs(ContextType::CROSS_SITE));
          }
          EXPECT_THAT(cookie_util::ComputeSameSiteContextForSubresource(
                          url, site_for_cookies,
                          false /* force_ignore_site_for_cookies */),
                      ContextTypeIs(ContextType::CROSS_SITE));
        }
      }
    }
  }
}

TEST_P(CookieUtilComputeSameSiteContextTest, SiteForCookiesNotSchemefullySame) {
  // If the SiteForCookies is not schemefully_same, even if its value is
  // schemefully same-site, the schemeful context type will be cross-site.
  if (!IsSchemeful())
    return;

  std::vector<SiteForCookies> sites_for_cookies = GetAllSitesForCookies();
  for (SiteForCookies& sfc : sites_for_cookies) {
    sfc.SetSchemefullySameForTesting(false);
  }

  for (const GURL& url : GetSameSiteUrls()) {
    for (const SiteForCookies& site_for_cookies : sites_for_cookies) {
      for (const absl::optional<url::Origin>& initiator : GetAllInitiators()) {
        for (const std::string& method : {"GET", "POST", "PUT", "HEAD"}) {
          EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
                          url, site_for_cookies, initiator,
                          false /* force_ignore_site_for_cookies */),
                      ContextTypeIs(ContextType::CROSS_SITE));
          EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptSet(
                          url, site_for_cookies,
                          false /* force_ignore_site_for_cookies */),
                      ContextTypeIs(ContextType::CROSS_SITE));

          // If the site-for-cookies isn't schemefully_same, this cannot be a
          // main frame navigation.
          EXPECT_THAT(cookie_util::ComputeSameSiteContextForRequest(
                          method, {url}, site_for_cookies, initiator,
                          false /* is_main_frame_navigation */,
                          false /* force_ignore_site_for_cookies */),
                      ContextTypeIs(ContextType::CROSS_SITE));
          EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
                          {url}, site_for_cookies, initiator,
                          false /* is_main_frame_navigation */,
                          false /* force_ignore_site_for_cookies */),
                      ContextTypeIs(ContextType::CROSS_SITE));

          EXPECT_THAT(cookie_util::ComputeSameSiteContextForSubresource(
                          url, site_for_cookies,
                          false /* force_ignore_site_for_cookies */),
                      ContextTypeIs(ContextType::CROSS_SITE));
        }
      }
    }
  }
}

TEST_P(CookieUtilComputeSameSiteContextTest, ForScriptGet) {
  for (const GURL& url : GetSameSiteUrls()) {
    // Same-site site-for-cookies.
    // (Cross-site cases covered above in UrlAndSiteForCookiesCrossSite test.)
    for (const SiteForCookies& site_for_cookies :
         GetSameSiteSitesForCookies()) {
      // Cross-site initiator -> it's same-site lax.
      for (const absl::optional<url::Origin>& initiator :
           GetCrossSiteInitiators()) {
        EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
                        url, site_for_cookies, initiator,
                        false /* force_ignore_site_for_cookies */),
                    ContextTypeIs(ContextType::SAME_SITE_LAX));
      }

      // Same-site initiator -> it's same-site strict.
      for (const absl::optional<url::Origin>& initiator :
           GetSameSiteInitiators()) {
        EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
                        url, site_for_cookies, initiator,
                        false /* force_ignore_site_for_cookies */),
                    ContextTypeIs(ContextType::SAME_SITE_STRICT));
      }
    }
  }
}

TEST_P(CookieUtilComputeSameSiteContextTest, ForScriptGet_SchemefulDowngrade) {
  // Some test cases where the context is downgraded when computed schemefully.
  // (Should already be covered above, but just to be explicit.)
  EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_STRICT,
                                  ContextType::SAME_SITE_LAX),
            cookie_util::ComputeSameSiteContextForScriptGet(
                kSiteUrl, kSiteForCookies, kSecureSiteInitiator,
                false /* force_ignore_site_for_cookies */));
  EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_STRICT,
                                  ContextType::SAME_SITE_LAX),
            cookie_util::ComputeSameSiteContextForScriptGet(
                kSecureSiteUrl, kSecureSiteForCookies, kSiteInitiator,
                false /* force_ignore_site_for_cookies */));
  EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_LAX,
                                  ContextType::CROSS_SITE),
            cookie_util::ComputeSameSiteContextForScriptGet(
                kSecureSiteUrl, kSiteForCookies, kCrossSiteInitiator,
                false /* force_ignore_site_for_cookies */));
  EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_LAX,
                                  ContextType::CROSS_SITE),
            cookie_util::ComputeSameSiteContextForScriptGet(
                kSiteUrl, kSecureSiteForCookies, kCrossSiteInitiator,
                false /* force_ignore_site_for_cookies */));
}

TEST_P(CookieUtilComputeSameSiteContextTest, ForScriptGet_WebSocketSchemes) {
  // wss/https and http/ws are considered the same for schemeful purposes.
  EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
                  kWssUrl, kSecureSiteForCookies, kSecureSiteInitiator,
                  false /* force_ignore_site_for_cookies */),
              ContextTypeIs(ContextType::SAME_SITE_STRICT));
  EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
                  kWssUrl, kSecureSiteForCookies, kSecureCrossSiteInitiator,
                  false /* force_ignore_site_for_cookies */),
              ContextTypeIs(ContextType::SAME_SITE_LAX));

  EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
                  kWsUrl, kSiteForCookies, kSiteInitiator,
                  false /* force_ignore_site_for_cookies */),
              ContextTypeIs(ContextType::SAME_SITE_STRICT));
  EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
                  kWsUrl, kSiteForCookies, kCrossSiteInitiator,
                  false /* force_ignore_site_for_cookies */),
              ContextTypeIs(ContextType::SAME_SITE_LAX));
}

// Test cases where the URL chain has 1 member (i.e. no redirects).
TEST_P(CookieUtilComputeSameSiteContextTest, ForRequest) {
  for (const GURL& url : GetSameSiteUrls()) {
    // Same-site site-for-cookies.
    // (Cross-site cases covered above in UrlAndSiteForCookiesCrossSite test.)
    for (const SiteForCookies& site_for_cookies :
         GetSameSiteSitesForCookies()) {
      // Same-Site initiator -> it's same-site strict.
      for (const absl::optional<url::Origin>& initiator :
           GetSameSiteInitiators()) {
        for (const std::string& method : {"GET", "POST", "PUT", "HEAD"}) {
          for (bool is_main_frame_navigation :
               IsMainFrameNavigationPossibleValues(url, site_for_cookies)) {
            EXPECT_THAT(cookie_util::ComputeSameSiteContextForRequest(
                            method, {url}, site_for_cookies, initiator,
                            is_main_frame_navigation,
                            false /* force_ignore_site_for_cookies */),
                        ContextTypeIs(ContextType::SAME_SITE_STRICT));
          }
        }
      }

      // Cross-Site initiator -> it's same-site lax iff the method is safe.
      for (const absl::optional<url::Origin>& initiator :
           GetCrossSiteInitiators()) {
        // For main frame navigations, the context is Lax (or Lax-unsafe).
        for (const std::string& method : {"GET", "HEAD"}) {
          if (!CanBeMainFrameNavigation(url, site_for_cookies))
            break;
          EXPECT_THAT(cookie_util::ComputeSameSiteContextForRequest(
                          method, {url}, site_for_cookies, initiator,
                          true /* is_main_frame_navigation */,
                          false /* force_ignore_site_for_cookies */),
                      ContextTypeIs(ContextType::SAME_SITE_LAX));
        }
        for (const std::string& method : {"POST", "PUT"}) {
          if (!CanBeMainFrameNavigation(url, site_for_cookies))
            break;
          EXPECT_THAT(cookie_util::ComputeSameSiteContextForRequest(
                          method, {url}, site_for_cookies, initiator,
                          true /* is_main_frame_navigation */,
                          false /* force_ignore_site_for_cookies */),
                      ContextTypeIs(ContextType::SAME_SITE_LAX_METHOD_UNSAFE));
        }

        // For non-main-frame-navigation requests, the context should be
        // cross-site.
        for (const std::string& method : {"GET", "POST", "PUT", "HEAD"}) {
          EXPECT_THAT(cookie_util::ComputeSameSiteContextForRequest(
                          method, {url}, site_for_cookies, initiator,
                          false /* is_main_frame_navigation */,
                          false /* force_ignore_site_for_cookies */),
                      ContextTypeIs(ContextType::CROSS_SITE));
        }
      }
    }
  }
}

TEST_P(CookieUtilComputeSameSiteContextTest, ForRequest_SchemefulDowngrade) {
  // Some test cases where the context is downgraded when computed schemefully.
  // (Should already be covered above, but just to be explicit.)

  // Cross-scheme URL and site-for-cookies with (schemelessly) same-site
  // initiator.
  // (The request cannot be a main frame navigation if the site-for-cookies is
  // not schemefully same-site).
  for (const std::string& method : {"GET", "POST"}) {
    EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_STRICT,
                                    ContextType::CROSS_SITE),
              cookie_util::ComputeSameSiteContextForRequest(
                  method, {kSecureSiteUrl}, kSiteForCookies, kSiteInitiator,
                  false /* is_main_frame_navigation */,
                  false /* force_ignore_site_for_cookies */));
    EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_STRICT,
                                    ContextType::CROSS_SITE),
              cookie_util::ComputeSameSiteContextForRequest(
                  method, {kSiteUrl}, kSecureSiteForCookies, kSiteInitiator,
                  false /* is_main_frame_navigation */,
                  false /* force_ignore_site_for_cookies */));
  }

  // Schemefully same-site URL and site-for-cookies with cross-scheme
  // initiator.
  for (bool is_main_frame_navigation : {false, true}) {
    ContextType lax_if_main_frame = is_main_frame_navigation
                                        ? ContextType::SAME_SITE_LAX
                                        : ContextType::CROSS_SITE;
    ContextType lax_unsafe_if_main_frame =
        is_main_frame_navigation ? ContextType::SAME_SITE_LAX_METHOD_UNSAFE
                                 : ContextType::CROSS_SITE;

    EXPECT_EQ(
        SameSiteCookieContext(ContextType::SAME_SITE_STRICT, lax_if_main_frame),
        cookie_util::ComputeSameSiteContextForRequest(
            "GET", {kSecureSiteUrl}, kSecureSiteForCookies, kSiteInitiator,
            is_main_frame_navigation,
            false /* force_ignore_site_for_cookies */));
    EXPECT_EQ(
        SameSiteCookieContext(ContextType::SAME_SITE_STRICT, lax_if_main_frame),
        cookie_util::ComputeSameSiteContextForRequest(
            "GET", {kSiteUrl}, kSiteForCookies, kSecureSiteInitiator,
            is_main_frame_navigation,
            false /* force_ignore_site_for_cookies */));
    EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_STRICT,
                                    lax_unsafe_if_main_frame),
              cookie_util::ComputeSameSiteContextForRequest(
                  "POST", {kSecureSiteUrl}, kSecureSiteForCookies,
                  kSiteInitiator, is_main_frame_navigation,
                  false /* force_ignore_site_for_cookies */));
    EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_STRICT,
                                    lax_unsafe_if_main_frame),
              cookie_util::ComputeSameSiteContextForRequest(
                  "POST", {kSiteUrl}, kSiteForCookies, kSecureSiteInitiator,
                  is_main_frame_navigation,
                  false /* force_ignore_site_for_cookies */));
  }

  // Cross-scheme URL and site-for-cookies with cross-site initiator.
  // (The request cannot be a main frame navigation if the site-for-cookies is
  // not schemefully same-site).
  EXPECT_EQ(SameSiteCookieContext(ContextType::CROSS_SITE),
            cookie_util::ComputeSameSiteContextForRequest(
                "GET", {kSiteUrl}, kSecureSiteForCookies, kCrossSiteInitiator,
                false /* is_main_frame_navigation */,
                false /* force_ignore_site_for_cookies */));
  EXPECT_EQ(SameSiteCookieContext(ContextType::CROSS_SITE),
            cookie_util::ComputeSameSiteContextForRequest(
                "GET", {kSecureSiteUrl}, kSiteForCookies, kCrossSiteInitiator,
                false /* is_main_frame_navigation */,
                false /* force_ignore_site_for_cookies */));
  EXPECT_EQ(SameSiteCookieContext(ContextType::CROSS_SITE),
            cookie_util::ComputeSameSiteContextForRequest(
                "POST", {kSiteUrl}, kSecureSiteForCookies, kCrossSiteInitiator,
                false /* is_main_frame_navigation */,
                false /* force_ignore_site_for_cookies */));
  EXPECT_EQ(SameSiteCookieContext(ContextType::CROSS_SITE),
            cookie_util::ComputeSameSiteContextForRequest(
                "POST", {kSecureSiteUrl}, kSiteForCookies, kCrossSiteInitiator,
                false /* is_main_frame_navigation */,
                false /* force_ignore_site_for_cookies */));
}

TEST_P(CookieUtilComputeSameSiteContextTest, ForRequest_WebSocketSchemes) {
  // wss/https and http/ws are considered the same for schemeful purposes.
  // (ws/wss requests cannot be main frame navigations.)
  EXPECT_THAT(cookie_util::ComputeSameSiteContextForRequest(
                  "GET", {kWssUrl}, kSecureSiteForCookies, kSecureSiteInitiator,
                  false /* is_main_frame_navigation */,
                  false /* force_ignore_site_for_cookies */),
              ContextTypeIs(ContextType::SAME_SITE_STRICT));
  EXPECT_THAT(
      cookie_util::ComputeSameSiteContextForRequest(
          "GET", {kWssUrl}, kSecureSiteForCookies, kSecureCrossSiteInitiator,
          false /* is_main_frame_navigation */,
          false /* force_ignore_site_for_cookies */),
      ContextTypeIs(ContextType::CROSS_SITE));

  EXPECT_THAT(cookie_util::ComputeSameSiteContextForRequest(
                  "GET", {kWsUrl}, kSiteForCookies, kSiteInitiator,
                  false /* is_main_frame_navigation */,
                  false /* force_ignore_site_for_cookies */),
              ContextTypeIs(ContextType::SAME_SITE_STRICT));
  EXPECT_THAT(cookie_util::ComputeSameSiteContextForRequest(
                  "GET", {kWsUrl}, kSiteForCookies, kCrossSiteInitiator,
                  false /* is_main_frame_navigation */,
                  false /* force_ignore_site_for_cookies */),
              ContextTypeIs(ContextType::CROSS_SITE));
}

// Test cases where the URL chain contains multiple members, where the last
// member (current request URL) is same-site to kSiteUrl. (Everything is listed
// as same-site or cross-site relative to kSiteUrl.)
TEST_P(CookieUtilComputeSameSiteContextTest, ForRequest_Redirect) {
  struct {
    std::string method;
    bool url_chain_is_same_site;
    bool site_for_cookies_is_same_site;
    bool initiator_is_same_site;
    // These are the expected context types considering redirect chains:
    ContextType expected_context_type;  // for non-main-frame-nav requests.
    ContextType expected_context_type_for_main_frame_navigation;
    // These are the expected context types not considering redirect chains:
    ContextType expected_context_type_without_chain;
    ContextType expected_context_type_for_main_frame_navigation_without_chain;
    // The expected redirect type (only applicable for chains):
    ContextRedirectTypeBug1221316 expected_redirect_type_with_chain;
  } kTestCases[] = {
      // If the url chain is same-site, then the result is the same with or
      // without considering the redirect chain.
      {"GET", true, true, true, ContextType::SAME_SITE_STRICT,
       ContextType::SAME_SITE_STRICT, ContextType::SAME_SITE_STRICT,
       ContextType::SAME_SITE_STRICT,
       ContextRedirectTypeBug1221316::kAllSameSiteRedirect},
      {"GET", true, true, false, ContextType::CROSS_SITE,
       ContextType::SAME_SITE_LAX, ContextType::CROSS_SITE,
       ContextType::SAME_SITE_LAX,
       ContextRedirectTypeBug1221316::kCrossSiteRedirect},
      {"GET", true, false, true, ContextType::CROSS_SITE,
       ContextType::CROSS_SITE, ContextType::CROSS_SITE,
       ContextType::CROSS_SITE,
       ContextRedirectTypeBug1221316::kCrossSiteRedirect},
      {"GET", true, false, false, ContextType::CROSS_SITE,
       ContextType::CROSS_SITE, ContextType::CROSS_SITE,
       ContextType::CROSS_SITE,
       ContextRedirectTypeBug1221316::kCrossSiteRedirect},
      // If the url chain is cross-site, then the result will differ depending
      // on whether the redirect chain is considered, when the site-for-cookies
      // and initiator are both same-site.
      {"GET", false, true, true, ContextType::CROSS_SITE,
       ContextType::SAME_SITE_LAX, ContextType::SAME_SITE_STRICT,
       ContextType::SAME_SITE_STRICT,
       ContextRedirectTypeBug1221316::kPartialSameSiteRedirect},
      {"GET", false, true, false, ContextType::CROSS_SITE,
       ContextType::SAME_SITE_LAX, ContextType::CROSS_SITE,
       ContextType::SAME_SITE_LAX,
       ContextRedirectTypeBug1221316::kCrossSiteRedirect},
      {"GET", false, false, true, ContextType::CROSS_SITE,
       ContextType::CROSS_SITE, ContextType::CROSS_SITE,
       ContextType::CROSS_SITE,
       ContextRedirectTypeBug1221316::kCrossSiteRedirect},
      {"GET", false, false, false, ContextType::CROSS_SITE,
       ContextType::CROSS_SITE, ContextType::CROSS_SITE,
       ContextType::CROSS_SITE,
       ContextRedirectTypeBug1221316::kCrossSiteRedirect},
      // If the url chain is same-site, then the result is the same with or
      // without considering the redirect chain.
      {"POST", true, true, true, ContextType::SAME_SITE_STRICT,
       ContextType::SAME_SITE_STRICT, ContextType::SAME_SITE_STRICT,
       ContextType::SAME_SITE_STRICT,
       ContextRedirectTypeBug1221316::kAllSameSiteRedirect},
      {"POST", true, true, false, ContextType::CROSS_SITE,
       ContextType::SAME_SITE_LAX_METHOD_UNSAFE, ContextType::CROSS_SITE,
       ContextType::SAME_SITE_LAX_METHOD_UNSAFE,
       ContextRedirectTypeBug1221316::kCrossSiteRedirect},
      {"POST", true, false, true, ContextType::CROSS_SITE,
       ContextType::CROSS_SITE, ContextType::CROSS_SITE,
       ContextType::CROSS_SITE,
       ContextRedirectTypeBug1221316::kCrossSiteRedirect},
      {"POST", true, false, false, ContextType::CROSS_SITE,
       ContextType::CROSS_SITE, ContextType::CROSS_SITE,
       ContextType::CROSS_SITE,
       ContextRedirectTypeBug1221316::kCrossSiteRedirect},
      // If the url chain is cross-site, then the result will differ depending
      // on whether the redirect chain is considered, when the site-for-cookies
      // and initiator are both same-site.
      {"POST", false, true, true, ContextType::CROSS_SITE,
       ContextType::SAME_SITE_LAX_METHOD_UNSAFE, ContextType::SAME_SITE_STRICT,
       ContextType::SAME_SITE_STRICT,
       ContextRedirectTypeBug1221316::kPartialSameSiteRedirect},
      {"POST", false, true, false, ContextType::CROSS_SITE,
       ContextType::SAME_SITE_LAX_METHOD_UNSAFE, ContextType::CROSS_SITE,
       ContextType::SAME_SITE_LAX_METHOD_UNSAFE,
       ContextRedirectTypeBug1221316::kCrossSiteRedirect},
      {"POST", false, false, true, ContextType::CROSS_SITE,
       ContextType::CROSS_SITE, ContextType::CROSS_SITE,
       ContextType::CROSS_SITE,
       ContextRedirectTypeBug1221316::kCrossSiteRedirect},
      {"POST", false, false, false, ContextType::CROSS_SITE,
       ContextType::CROSS_SITE, ContextType::CROSS_SITE,
       ContextType::CROSS_SITE,
       ContextRedirectTypeBug1221316::kCrossSiteRedirect},
  };

  for (const auto& test_case : kTestCases) {
    std::vector<std::vector<GURL>> url_chains =
        test_case.url_chain_is_same_site ? GetSameSiteUrlChains(kSiteUrl)
                                         : GetCrossSiteUrlChains(kSiteUrl);
    std::vector<SiteForCookies> sites_for_cookies =
        test_case.site_for_cookies_is_same_site ? GetSameSiteSitesForCookies()
                                                : GetCrossSiteSitesForCookies();
    std::vector<absl::optional<url::Origin>> initiators =
        test_case.initiator_is_same_site ? GetSameSiteInitiators()
                                         : GetCrossSiteInitiators();
    ContextType expected_context_type =
        DoesSameSiteConsiderRedirectChain()
            ? test_case.expected_context_type
            : test_case.expected_context_type_without_chain;
    ContextType expected_context_type_for_main_frame_navigation =
        DoesSameSiteConsiderRedirectChain()
            ? test_case.expected_context_type_for_main_frame_navigation
            : test_case
                  .expected_context_type_for_main_frame_navigation_without_chain;
    for (const std::vector<GURL>& url_chain : url_chains) {
      for (const SiteForCookies& site_for_cookies : sites_for_cookies) {
        for (const absl::optional<url::Origin>& initiator : initiators) {
          EXPECT_THAT(
              cookie_util::ComputeSameSiteContextForRequest(
                  test_case.method, url_chain, site_for_cookies, initiator,
                  false /* is_main_frame_navigation */,
                  false /* force_ignore_site_for_cookies */),
              AllOf(ContextTypeIs(expected_context_type),
                    CrossSiteRedirectMetadataCorrect(
                        cookie_util::HttpMethodStringToEnum(test_case.method),
                        test_case.expected_context_type_without_chain,
                        test_case.expected_context_type,
                        test_case.expected_redirect_type_with_chain)))
              << UrlChainToString(url_chain) << " "
              << site_for_cookies.ToDebugString() << " "
              << (initiator ? initiator->Serialize() : "nullopt");
          if (!CanBeMainFrameNavigation(url_chain.back(), site_for_cookies))
            continue;
          EXPECT_THAT(
              cookie_util::ComputeSameSiteContextForRequest(
                  test_case.method, url_chain, site_for_cookies, initiator,
                  true /* is_main_frame_navigation */,
                  false /* force_ignore_site_for_cookies */),
              AllOf(
                  ContextTypeIs(
                      expected_context_type_for_main_frame_navigation),
                  CrossSiteRedirectMetadataCorrect(
                      cookie_util::HttpMethodStringToEnum(test_case.method),
                      test_case
                          .expected_context_type_for_main_frame_navigation_without_chain,
                      test_case.expected_context_type_for_main_frame_navigation,
                      test_case.expected_redirect_type_with_chain)))
              << UrlChainToString(url_chain) << " "
              << site_for_cookies.ToDebugString() << " "
              << (initiator ? initiator->Serialize() : "nullopt");
        }
      }
    }
  }
}

TEST_P(CookieUtilComputeSameSiteContextTest, ForScriptSet) {
  for (const GURL& url : GetSameSiteUrls()) {
    for (const SiteForCookies& site_for_cookies :
         GetSameSiteSitesForCookies()) {
      // Same-site site-for-cookies -> it's same-site lax.
      // (Cross-site cases covered above in UrlAndSiteForCookiesCrossSite test.)
      EXPECT_THAT(
          cookie_util::ComputeSameSiteContextForScriptSet(
              url, site_for_cookies, false /* force_ignore_site_for_cookies */),
          ContextTypeIs(ContextType::SAME_SITE_LAX));
    }
  }
}

TEST_P(CookieUtilComputeSameSiteContextTest, ForScriptSet_SchemefulDowngrade) {
  // Some test cases where the context is downgraded when computed schemefully.
  // (Should already be covered above, but just to be explicit.)
  EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_LAX,
                                  ContextType::CROSS_SITE),
            cookie_util::ComputeSameSiteContextForScriptSet(
                kSiteUrl, kSecureSiteForCookies,
                false /* force_ignore_site_for_cookies */));
  EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_LAX,
                                  ContextType::CROSS_SITE),
            cookie_util::ComputeSameSiteContextForScriptSet(
                kSecureSiteUrl, kSiteForCookies,
                false /* force_ignore_site_for_cookies */));
}

TEST_P(CookieUtilComputeSameSiteContextTest, ForScriptSet_WebSocketSchemes) {
  // wss/https and http/ws are considered the same for schemeful purposes.
  EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptSet(
                  kWssUrl, kSecureSiteForCookies,
                  false /* force_ignore_site_for_cookies */),
              ContextTypeIs(ContextType::SAME_SITE_LAX));
  EXPECT_THAT(
      cookie_util::ComputeSameSiteContextForScriptSet(
          kWsUrl, kSiteForCookies, false /* force_ignore_site_for_cookies */),
      ContextTypeIs(ContextType::SAME_SITE_LAX));
}

// Test cases where the URL chain has 1 member (i.e. no redirects).
TEST_P(CookieUtilComputeSameSiteContextTest, ForResponse) {
  for (const GURL& url : GetSameSiteUrls()) {
    // Same-site site-for-cookies.
    // (Cross-site cases covered above in UrlAndSiteForCookiesCrossSite test.)
    for (const SiteForCookies& site_for_cookies :
         GetSameSiteSitesForCookies()) {
      // For main frame navigations, setting all SameSite cookies is allowed
      // regardless of initiator.
      for (const absl::optional<url::Origin>& initiator : GetAllInitiators()) {
        if (!CanBeMainFrameNavigation(url, site_for_cookies))
          break;
        EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
                        {url}, site_for_cookies, initiator,
                        true /* is_main_frame_navigation */,
                        false /* force_ignore_site_for_cookies */),
                    ContextTypeIs(ContextType::SAME_SITE_LAX));
      }

      // For non-main-frame-navigation requests, the context should be lax iff
      // the initiator is same-site, and cross-site otherwise.
      for (const absl::optional<url::Origin>& initiator :
           GetSameSiteInitiators()) {
        EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
                        {url}, site_for_cookies, initiator,
                        false /* is_main_frame_navigation */,
                        false /* force_ignore_site_for_cookies */),
                    ContextTypeIs(ContextType::SAME_SITE_LAX));
      }
      for (const absl::optional<url::Origin>& initiator :
           GetCrossSiteInitiators()) {
        EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
                        {url}, site_for_cookies, initiator,
                        false /* is_main_frame_navigation */,
                        false /* force_ignore_site_for_cookies */),
                    ContextTypeIs(ContextType::CROSS_SITE));
      }
    }
  }
}

TEST_P(CookieUtilComputeSameSiteContextTest, ForResponse_SchemefulDowngrade) {
  // Some test cases where the context is downgraded when computed schemefully.
  // (Should already be covered above, but just to be explicit.)

  // URL and site-for-cookies are cross-scheme.
  // (If the URL and site-for-cookies are not schemefully same-site, this cannot
  // be a main frame navigation.)
  // With same-site initiator:
  EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_LAX,
                                  ContextType::CROSS_SITE),
            cookie_util::ComputeSameSiteContextForResponse(
                {kSiteUrl}, kSecureSiteForCookies, kSiteInitiator,
                false /* is_main_frame_navigation */,
                false /* force_ignore_site_for_cookies */));
  EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_LAX,
                                  ContextType::CROSS_SITE),
            cookie_util::ComputeSameSiteContextForResponse(
                {kSecureSiteUrl}, kSiteForCookies, kSecureSiteInitiator,
                false /* is_main_frame_navigation */,
                false /* force_ignore_site_for_cookies */));
  // With cross-site initiator:
  EXPECT_EQ(SameSiteCookieContext(ContextType::CROSS_SITE),
            cookie_util::ComputeSameSiteContextForResponse(
                {kSiteUrl}, kSecureSiteForCookies, kCrossSiteInitiator,
                false /* is_main_frame_navigation */,
                false /* force_ignore_site_for_cookies */));
  EXPECT_EQ(SameSiteCookieContext(ContextType::CROSS_SITE),
            cookie_util::ComputeSameSiteContextForResponse(
                {kSecureSiteUrl}, kSiteForCookies, kCrossSiteInitiator,
                false /* is_main_frame_navigation */,
                false /* force_ignore_site_for_cookies */));

  // Schemefully same-site URL and site-for-cookies with cross-scheme
  // initiator.
  for (bool is_main_frame_navigation : {false, true}) {
    ContextType lax_if_main_frame = is_main_frame_navigation
                                        ? ContextType::SAME_SITE_LAX
                                        : ContextType::CROSS_SITE;
    EXPECT_EQ(
        SameSiteCookieContext(ContextType::SAME_SITE_LAX, lax_if_main_frame),
        cookie_util::ComputeSameSiteContextForResponse(
            {kSiteUrl}, kSiteForCookies, kSecureSiteInitiator,
            is_main_frame_navigation,
            false /* force_ignore_site_for_cookies */));
    EXPECT_EQ(
        SameSiteCookieContext(ContextType::SAME_SITE_LAX, lax_if_main_frame),
        cookie_util::ComputeSameSiteContextForResponse(
            {kSecureSiteUrl}, kSecureSiteForCookies, kSiteInitiator,
            is_main_frame_navigation,
            false /* force_ignore_site_for_cookies */));
  }
}

TEST_P(CookieUtilComputeSameSiteContextTest, ForResponse_WebSocketSchemes) {
  // wss/https and http/ws are considered the same for schemeful purposes.
  // (ws/wss requests cannot be main frame navigations.)

  // Same-site initiators.
  for (const absl::optional<url::Origin>& initiator : GetSameSiteInitiators()) {
    EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
                    {kWsUrl}, kSiteForCookies, initiator,
                    false /* is_main_frame_navigation */,
                    false /* force_ignore_site_for_cookies */),
                ContextTypeIs(ContextType::SAME_SITE_LAX));
  }
  // Cross-site initiators.
  for (const absl::optional<url::Origin>& initiator :
       GetCrossSiteInitiators()) {
    EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
                    {kWsUrl}, kSiteForCookies, initiator,
                    false /* is_main_frame_navigation */,
                    false /* force_ignore_site_for_cookies */),
                ContextTypeIs(ContextType::CROSS_SITE));
  }
}

// Test cases where the URL chain contains multiple members, where the last
// member (current request URL) is same-site to kSiteUrl. (Everything is listed
// as same-site or cross-site relative to kSiteUrl.)
TEST_P(CookieUtilComputeSameSiteContextTest, ForResponse_Redirect) {
  struct {
    bool url_chain_is_same_site;
    bool site_for_cookies_is_same_site;
    bool initiator_is_same_site;
    // These are the expected context types considering redirect chains:
    ContextType expected_context_type;  // for non-main-frame-nav requests.
    ContextType expected_context_type_for_main_frame_navigation;
    // These are the expected context types not considering redirect chains:
    ContextType expected_context_type_without_chain;
    ContextType expected_context_type_for_main_frame_navigation_without_chain;
    // The expected redirect type (only applicable for chains):
    ContextRedirectTypeBug1221316 expected_redirect_type_with_chain;
  } kTestCases[] = {
      // If the url chain is same-site, then the result is the same with or
      // without considering the redirect chain.
      {true, true, true, ContextType::SAME_SITE_LAX, ContextType::SAME_SITE_LAX,
       ContextType::SAME_SITE_LAX, ContextType::SAME_SITE_LAX,
       ContextRedirectTypeBug1221316::kAllSameSiteRedirect},
      {true, true, false, ContextType::CROSS_SITE, ContextType::SAME_SITE_LAX,
       ContextType::CROSS_SITE, ContextType::SAME_SITE_LAX,
       ContextRedirectTypeBug1221316::kCrossSiteRedirect},
      {true, false, true, ContextType::CROSS_SITE, ContextType::CROSS_SITE,
       ContextType::CROSS_SITE, ContextType::CROSS_SITE,
       ContextRedirectTypeBug1221316::kCrossSiteRedirect},
      {true, false, false, ContextType::CROSS_SITE, ContextType::CROSS_SITE,
       ContextType::CROSS_SITE, ContextType::CROSS_SITE,
       ContextRedirectTypeBug1221316::kCrossSiteRedirect},
      // If the url chain is cross-site, then the result will differ depending
      // on whether the redirect chain is considered, when the site-for-cookies
      // and initiator are both same-site.
      {false, true, true, ContextType::CROSS_SITE, ContextType::SAME_SITE_LAX,
       ContextType::SAME_SITE_LAX, ContextType::SAME_SITE_LAX,
       ContextRedirectTypeBug1221316::kPartialSameSiteRedirect},
      {false, true, false, ContextType::CROSS_SITE, ContextType::SAME_SITE_LAX,
       ContextType::CROSS_SITE, ContextType::SAME_SITE_LAX,
       ContextRedirectTypeBug1221316::kCrossSiteRedirect},
      {false, false, true, ContextType::CROSS_SITE, ContextType::CROSS_SITE,
       ContextType::CROSS_SITE, ContextType::CROSS_SITE,
       ContextRedirectTypeBug1221316::kCrossSiteRedirect},
      {false, false, false, ContextType::CROSS_SITE, ContextType::CROSS_SITE,
       ContextType::CROSS_SITE, ContextType::CROSS_SITE,
       ContextRedirectTypeBug1221316::kCrossSiteRedirect},
  };
  for (const auto& test_case : kTestCases) {
    std::vector<std::vector<GURL>> url_chains =
        test_case.url_chain_is_same_site ? GetSameSiteUrlChains(kSiteUrl)
                                         : GetCrossSiteUrlChains(kSiteUrl);
    std::vector<SiteForCookies> sites_for_cookies =
        test_case.site_for_cookies_is_same_site ? GetSameSiteSitesForCookies()
                                                : GetCrossSiteSitesForCookies();
    std::vector<absl::optional<url::Origin>> initiators =
        test_case.initiator_is_same_site ? GetSameSiteInitiators()
                                         : GetCrossSiteInitiators();
    ContextType expected_context_type =
        DoesSameSiteConsiderRedirectChain()
            ? test_case.expected_context_type
            : test_case.expected_context_type_without_chain;
    ContextType expected_context_type_for_main_frame_navigation =
        DoesSameSiteConsiderRedirectChain()
            ? test_case.expected_context_type_for_main_frame_navigation
            : test_case
                  .expected_context_type_for_main_frame_navigation_without_chain;
    for (const std::vector<GURL>& url_chain : url_chains) {
      for (const SiteForCookies& site_for_cookies : sites_for_cookies) {
        for (const absl::optional<url::Origin>& initiator : initiators) {
          EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
                          url_chain, site_for_cookies, initiator,
                          false /* is_main_frame_navigation */,
                          false /* force_ignore_site_for_cookies */),
                      AllOf(ContextTypeIs(expected_context_type),
                            // The 'method' field is kept empty because it's
                            // only used to check http_method_bug_1221316 which
                            // is always empty for responses.
                            CrossSiteRedirectMetadataCorrect(
                                HttpMethod::kUnset,
                                test_case.expected_context_type_without_chain,
                                test_case.expected_context_type,
                                test_case.expected_redirect_type_with_chain)))
              << UrlChainToString(url_chain) << " "
              << site_for_cookies.ToDebugString() << " "
              << (initiator ? initiator->Serialize() : "nullopt");
          if (!CanBeMainFrameNavigation(url_chain.back(), site_for_cookies))
            continue;
          EXPECT_THAT(
              cookie_util::ComputeSameSiteContextForResponse(
                  url_chain, site_for_cookies, initiator,
                  true /* is_main_frame_navigation */,
                  false /* force_ignore_site_for_cookies */),
              AllOf(
                  ContextTypeIs(
                      expected_context_type_for_main_frame_navigation),
                  CrossSiteRedirectMetadataCorrect(
                      HttpMethod::kUnset,
                      test_case
                          .expected_context_type_for_main_frame_navigation_without_chain,
                      test_case.expected_context_type_for_main_frame_navigation,
                      test_case.expected_redirect_type_with_chain)))
              << UrlChainToString(url_chain) << " "
              << site_for_cookies.ToDebugString() << " "
              << (initiator ? initiator->Serialize() : "nullopt");
        }
      }
    }
  }
}

TEST_P(CookieUtilComputeSameSiteContextTest, ForSubresource) {
  for (const GURL& url : GetSameSiteUrls()) {
    // Same-site site-for-cookies.
    // (Cross-site cases covered above in UrlAndSiteForCookiesCrossSite test.)
    for (const SiteForCookies& site_for_cookies :
         GetSameSiteSitesForCookies()) {
      EXPECT_THAT(
          cookie_util::ComputeSameSiteContextForSubresource(
              url, site_for_cookies, false /* force_ignore_site_for_cookies */),
          ContextTypeIs(ContextType::SAME_SITE_STRICT));
    }
  }
}

TEST_P(CookieUtilComputeSameSiteContextTest,
       ForSubresource_SchemefulDowngrade) {
  // Some test cases where the context is downgraded when computed schemefully.
  // (Should already be covered above, but just to be explicit.)
  EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_STRICT,
                                  ContextType::CROSS_SITE),
            cookie_util::ComputeSameSiteContextForSubresource(
                kSiteUrl, kSecureSiteForCookies,
                false /* force_ignore_site_for_cookies */));
  EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_STRICT,
                                  ContextType::CROSS_SITE),
            cookie_util::ComputeSameSiteContextForSubresource(
                kSecureSiteUrl, kSiteForCookies,
                false /* force_ignore_site_for_cookies */));
}

TEST_P(CookieUtilComputeSameSiteContextTest, ForSubresource_WebSocketSchemes) {
  // wss/https and http/ws are considered the same for schemeful purposes.
  EXPECT_THAT(cookie_util::ComputeSameSiteContextForSubresource(
                  kWssUrl, kSecureSiteForCookies,
                  false /* force_ignore_site_for_cookies */),
              ContextTypeIs(ContextType::SAME_SITE_STRICT));
  EXPECT_THAT(
      cookie_util::ComputeSameSiteContextForSubresource(
          kWsUrl, kSiteForCookies, false /* force_ignore_site_for_cookies */),
      ContextTypeIs(ContextType::SAME_SITE_STRICT));
}

TEST_P(CookieUtilComputeSameSiteContextTest, ForceIgnoreSiteForCookies) {
  // force_ignore_site_for_cookies overrides all checks and returns same-site
  // (STRICT for get or LAX for set).
  for (const GURL& url : GetAllUrls()) {
    for (const SiteForCookies& site_for_cookies : GetAllSitesForCookies()) {
      for (const absl::optional<url::Origin>& initiator : GetAllInitiators()) {
        for (const std::string& method : {"GET", "POST", "PUT", "HEAD"}) {
          EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
                          url, site_for_cookies, initiator,
                          true /* force_ignore_site_for_cookies */),
                      ContextTypeIs(ContextType::SAME_SITE_STRICT));
          EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptSet(
                          url, site_for_cookies,
                          true /* force_ignore_site_for_cookies */),
                      ContextTypeIs(ContextType::SAME_SITE_LAX));
          for (bool is_main_frame_navigation :
               IsMainFrameNavigationPossibleValues(url, site_for_cookies)) {
            EXPECT_THAT(cookie_util::ComputeSameSiteContextForRequest(
                            method, {url}, site_for_cookies, initiator,
                            is_main_frame_navigation,
                            true /* force_ignore_site_for_cookies */),
                        ContextTypeIs(ContextType::SAME_SITE_STRICT));
            EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
                            {url}, site_for_cookies, initiator,
                            is_main_frame_navigation,
                            true /* force_ignore_site_for_cookies */),
                        ContextTypeIs(ContextType::SAME_SITE_LAX));
            EXPECT_THAT(
                cookie_util::ComputeSameSiteContextForRequest(
                    method, {site_for_cookies.RepresentativeUrl(), url},
                    site_for_cookies, initiator, is_main_frame_navigation,
                    true /* force_ignore_site_for_cookies */),
                ContextTypeIs(ContextType::SAME_SITE_STRICT));
            EXPECT_THAT(
                cookie_util::ComputeSameSiteContextForResponse(
                    {site_for_cookies.RepresentativeUrl(), url},
                    site_for_cookies, initiator, is_main_frame_navigation,
                    true /* force_ignore_site_for_cookies */),
                ContextTypeIs(ContextType::SAME_SITE_LAX));
          }
          EXPECT_THAT(cookie_util::ComputeSameSiteContextForSubresource(
                          url, site_for_cookies,
                          true /* force_ignore_site_for_cookies */),
                      ContextTypeIs(ContextType::SAME_SITE_STRICT));
        }
      }
    }
  }
}

INSTANTIATE_TEST_SUITE_P(/* no label */,
                         CookieUtilComputeSameSiteContextTest,
                         ::testing::Combine(::testing::Bool(),
                                            ::testing::Bool()));

TEST(CookieUtilTest, IsCookieAccessResultInclude) {
  EXPECT_FALSE(cookie_util::IsCookieAccessResultInclude(CookieAccessResult(
      CookieInclusionStatus(CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR))));

  EXPECT_TRUE(cookie_util::IsCookieAccessResultInclude(CookieAccessResult()));
}

TEST(CookieUtilTest, GetSamePartyStatus_NotInSet) {
  const bool same_party_attribute_enabled = true;
  CookieOptions options;
  options.set_is_in_nontrivial_first_party_set(false);

  for (bool same_party : {false, true}) {
    for (bool secure : {false, true}) {
      for (bool httponly : {false, true}) {
        for (CookieSameSite same_site : {
                 CookieSameSite::NO_RESTRICTION,
                 CookieSameSite::LAX_MODE,
                 CookieSameSite::STRICT_MODE,
                 CookieSameSite::UNSPECIFIED,
             }) {
          for (SamePartyContext::Type party_context_type : {
                   SamePartyContext::Type::kCrossParty,
                   SamePartyContext::Type::kSameParty,
               }) {
            base::Time now = base::Time::Now();
            std::unique_ptr<CanonicalCookie> cookie =
                CanonicalCookie::CreateUnsafeCookieForTesting(
                    "cookie", "tasty", "example.test", "/", now, now, now, now,
                    secure, httponly, same_site,
                    CookiePriority::COOKIE_PRIORITY_DEFAULT, same_party);

            options.set_same_party_context(
                SamePartyContext(party_context_type));
            EXPECT_EQ(CookieSamePartyStatus::kNoSamePartyEnforcement,
                      cookie_util::GetSamePartyStatus(
                          *cookie, options, same_party_attribute_enabled));
          }
        }
      }
    }
  }
}

TEST(CookieUtilTest, GetSamePartyStatus_FeatureDisabled) {
  const bool same_party_attribute_enabled = false;
  CookieOptions options;
  options.set_is_in_nontrivial_first_party_set(true);

  for (bool same_party : {false, true}) {
    for (bool secure : {false, true}) {
      for (bool httponly : {false, true}) {
        for (CookieSameSite same_site : {
                 CookieSameSite::NO_RESTRICTION,
                 CookieSameSite::LAX_MODE,
                 CookieSameSite::STRICT_MODE,
                 CookieSameSite::UNSPECIFIED,
             }) {
          for (SamePartyContext::Type party_context_type : {
                   SamePartyContext::Type::kCrossParty,
                   SamePartyContext::Type::kSameParty,
               }) {
            base::Time now = base::Time::Now();
            std::unique_ptr<CanonicalCookie> cookie =
                CanonicalCookie::CreateUnsafeCookieForTesting(
                    "cookie", "tasty", "example.test", "/", now, now, now, now,
                    secure, httponly, same_site,
                    CookiePriority::COOKIE_PRIORITY_DEFAULT, same_party);

            options.set_same_party_context(
                SamePartyContext(party_context_type));
            EXPECT_EQ(CookieSamePartyStatus::kNoSamePartyEnforcement,
                      cookie_util::GetSamePartyStatus(
                          *cookie, options, same_party_attribute_enabled));
          }
        }
      }
    }
  }
}

TEST(CookieUtilTest, GetSamePartyStatus_NotSameParty) {
  CookieOptions options;
  options.set_is_in_nontrivial_first_party_set(true);

  for (bool secure : {false, true}) {
    for (bool httponly : {false, true}) {
      for (CookieSameSite same_site : {
               CookieSameSite::NO_RESTRICTION,
               CookieSameSite::LAX_MODE,
               CookieSameSite::STRICT_MODE,
               CookieSameSite::UNSPECIFIED,
           }) {
        for (SamePartyContext::Type party_context_type : {
                 SamePartyContext::Type::kCrossParty,
                 SamePartyContext::Type::kSameParty,
             }) {
          base::Time now = base::Time::Now();
          std::unique_ptr<CanonicalCookie> cookie =
              CanonicalCookie::CreateUnsafeCookieForTesting(
                  "cookie", "tasty", "example.test", "/", now, now, now, now,
                  secure, httponly, same_site,
                  CookiePriority::COOKIE_PRIORITY_DEFAULT,
                  false /* same_party */);

          options.set_same_party_context(SamePartyContext(party_context_type));
          EXPECT_EQ(CookieSamePartyStatus::kNoSamePartyEnforcement,
                    cookie_util::GetSamePartyStatus(
                        *cookie, options,
                        /*same_party_attribute_enabled=*/true));
        }
      }
    }
  }
}

TEST(CookieUtilTest, GetSamePartyStatus_SamePartySemantics) {
  CookieOptions options;
  options.set_is_in_nontrivial_first_party_set(true);

  // Note: some SameParty cookie configurations (e.g. non-Secure cookies) are
  // skipped, because they are invalid.
  for (bool httponly : {false, true}) {
    for (CookieSameSite same_site : {
             CookieSameSite::NO_RESTRICTION,
             CookieSameSite::LAX_MODE,
             CookieSameSite::UNSPECIFIED,
         }) {
      for (CookieOptions::SameSiteCookieContext::ContextType same_site_context :
           {
               CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE,
               CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX,
               CookieOptions::SameSiteCookieContext::ContextType::
                   SAME_SITE_LAX_METHOD_UNSAFE,
               CookieOptions::SameSiteCookieContext::ContextType::
                   SAME_SITE_STRICT,
           }) {
        for (CookieOptions::SameSiteCookieContext::ContextType
                 schemeful_same_site_context :
             {
                 CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE,
                 CookieOptions::SameSiteCookieContext::ContextType::
                     SAME_SITE_LAX,
                 CookieOptions::SameSiteCookieContext::ContextType::
                     SAME_SITE_LAX_METHOD_UNSAFE,
                 CookieOptions::SameSiteCookieContext::ContextType::
                     SAME_SITE_STRICT,
             }) {
          if (same_site_context < schemeful_same_site_context)
            continue;
          options.set_same_site_cookie_context(
              CookieOptions::SameSiteCookieContext(
                  same_site_context, schemeful_same_site_context));

          base::Time now = base::Time::Now();
          std::unique_ptr<CanonicalCookie> cookie =
              CanonicalCookie::CreateUnsafeCookieForTesting(
                  "cookie", "tasty", "example.test", "/", now, now, now, now,
                  true /* secure */, httponly, same_site,
                  CookiePriority::COOKIE_PRIORITY_DEFAULT,
                  true /* same_party */);

          options.set_same_party_context(
              SamePartyContext(SamePartyContext::Type::kCrossParty));
          EXPECT_EQ(CookieSamePartyStatus::kEnforceSamePartyExclude,
                    cookie_util::GetSamePartyStatus(
                        *cookie, options,
                        /*same_party_attribute_enabled=*/true));

          options.set_same_party_context(
              SamePartyContext(SamePartyContext::Type::kSameParty));
          EXPECT_EQ(CookieSamePartyStatus::kEnforceSamePartyInclude,
                    cookie_util::GetSamePartyStatus(
                        *cookie, options,
                        /*same_party_attribute_enabled=*/true));
        }
      }
    }
  }
}

}  // namespace

}  // namespace net
