// 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 <array>

// Tests common functionality used by the Chrome Extensions Cookies API
// implementation.

#include <stddef.h>

#include <memory>
#include <optional>
#include <utility>
#include <vector>

#include "base/test/gtest_util.h"
#include "base/values.h"
#include "chrome/browser/extensions/api/cookies/cookies_helpers.h"
#include "chrome/common/extensions/api/cookies.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/test/browser_task_environment.h"
#include "extensions/buildflags/buildflags.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_constants.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

static_assert(BUILDFLAG(ENABLE_EXTENSIONS_CORE));

using extensions::api::cookies::Cookie;
using extensions::api::cookies::CookieStore;

namespace GetAll = extensions::api::cookies::GetAll;

namespace extensions {

constexpr char kDomainKey[] = "domain";

namespace {

struct DomainMatchCase {
  const char* filter;
  const char* domain;
  const bool matches;
};

}  // namespace

class ExtensionCookiesTest : public testing::Test {
 private:
  content::BrowserTaskEnvironment task_environment_;
};

TEST_F(ExtensionCookiesTest, StoreIdProfileConversion) {
  TestingProfile::Builder profile_builder;
  std::unique_ptr<TestingProfile> profile = profile_builder.Build();
  // Trigger early creation of off-the-record profile.
  EXPECT_TRUE(profile->GetPrimaryOTRProfile(/*create_if_needed=*/true));

  EXPECT_EQ(std::string("0"),
            cookies_helpers::GetStoreIdFromProfile(profile.get()));
  EXPECT_EQ(profile.get(),
            cookies_helpers::ChooseProfileFromStoreId(
                "0", profile.get(), true));
  EXPECT_EQ(profile.get(),
            cookies_helpers::ChooseProfileFromStoreId(
                "0", profile.get(), false));
  EXPECT_EQ(
      profile->GetPrimaryOTRProfile(/*create_if_needed=*/true),
      cookies_helpers::ChooseProfileFromStoreId("1", profile.get(), true));
  EXPECT_EQ(nullptr, cookies_helpers::ChooseProfileFromStoreId(
                         "1", profile.get(), false));

  EXPECT_EQ(std::string("1"),
            cookies_helpers::GetStoreIdFromProfile(
                profile->GetPrimaryOTRProfile(/*create_if_needed=*/true)));
  EXPECT_EQ(
      nullptr,
      cookies_helpers::ChooseProfileFromStoreId(
          "0", profile->GetPrimaryOTRProfile(/*create_if_needed=*/true), true));
  EXPECT_EQ(nullptr,
            cookies_helpers::ChooseProfileFromStoreId(
                "0", profile->GetPrimaryOTRProfile(/*create_if_needed=*/true),
                false));
  EXPECT_EQ(
      profile->GetPrimaryOTRProfile(/*create_if_needed=*/true),
      cookies_helpers::ChooseProfileFromStoreId(
          "1", profile->GetPrimaryOTRProfile(/*create_if_needed=*/true), true));
  EXPECT_EQ(profile->GetPrimaryOTRProfile(/*create_if_needed=*/true),
            cookies_helpers::ChooseProfileFromStoreId(
                "1", profile->GetPrimaryOTRProfile(/*create_if_needed=*/true),
                false));
}

TEST_F(ExtensionCookiesTest, ExtensionTypeCreation) {
  std::unique_ptr<net::CanonicalCookie> canonical_cookie1 =
      net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "ABC", "DEF", "www.example.com", "/", base::Time(), base::Time(),
          base::Time(), base::Time(), false, false,
          net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_DEFAULT);
  ASSERT_NE(nullptr, canonical_cookie1.get());
  Cookie cookie1 =
      cookies_helpers::CreateCookie(*canonical_cookie1, "some cookie store");
  EXPECT_EQ("ABC", cookie1.name);
  EXPECT_EQ("DEF", cookie1.value);
  EXPECT_EQ("www.example.com", cookie1.domain);
  EXPECT_TRUE(cookie1.host_only);
  EXPECT_EQ("/", cookie1.path);
  EXPECT_FALSE(cookie1.secure);
  EXPECT_FALSE(cookie1.http_only);
  EXPECT_EQ(api::cookies::SameSiteStatus::kNoRestriction, cookie1.same_site);
  EXPECT_TRUE(cookie1.session);
  EXPECT_FALSE(cookie1.expiration_date);
  EXPECT_EQ("some cookie store", cookie1.store_id);

  std::unique_ptr<net::CanonicalCookie> canonical_cookie2 =
      net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "ABC", "DEF", ".example.com", "/", base::Time(),
          base::Time::FromSecondsSinceUnixEpoch(10000), base::Time(),
          base::Time(), false, false, net::CookieSameSite::STRICT_MODE,
          net::COOKIE_PRIORITY_DEFAULT);
  ASSERT_NE(nullptr, canonical_cookie2.get());
  Cookie cookie2 =
      cookies_helpers::CreateCookie(*canonical_cookie2, "some cookie store");
  EXPECT_FALSE(cookie2.host_only);
  EXPECT_FALSE(cookie2.session);
  EXPECT_EQ(api::cookies::SameSiteStatus::kStrict, cookie2.same_site);
  ASSERT_TRUE(cookie2.expiration_date);
  EXPECT_EQ(10000, *cookie2.expiration_date);

  TestingProfile profile;
  base::Value::List tab_ids_list;
  std::vector<int> tab_ids;
  CookieStore cookie_store =
      cookies_helpers::CreateCookieStore(&profile, std::move(tab_ids_list));
  EXPECT_EQ("0", cookie_store.id);
  EXPECT_EQ(tab_ids, cookie_store.tab_ids);
}

TEST_F(ExtensionCookiesTest, GetURLFromCanonicalCookie) {
  std::unique_ptr<net::CanonicalCookie> cookie1 =
      net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "ABC", "DEF", ".example.com", "/", base::Time(), base::Time(),
          base::Time(), base::Time(), false, false,
          net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_DEFAULT);
  ASSERT_NE(nullptr, cookie1.get());
  EXPECT_EQ("http://example.com/",
            cookies_helpers::GetURLFromCanonicalCookie(*cookie1).spec());

  std::unique_ptr<net::CanonicalCookie> cookie2 =
      net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "ABC", "DEF", ".helloworld.com", "/", base::Time(), base::Time(),
          base::Time(), base::Time(), true, false,
          net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_DEFAULT);
  ASSERT_NE(nullptr, cookie2.get());
  EXPECT_EQ("https://helloworld.com/",
            cookies_helpers::GetURLFromCanonicalCookie(*cookie2).spec());
}

TEST_F(ExtensionCookiesTest, EmptyDictionary) {
  base::Value::Dict dict;
  auto details = GetAll::Params::Details::FromValue(dict);
  ASSERT_TRUE(details);
  cookies_helpers::MatchFilter filter(&details.value());
  net::CanonicalCookie cookie;
  EXPECT_TRUE(filter.MatchesCookie(cookie));
}

TEST_F(ExtensionCookiesTest, DomainMatching) {
  constexpr static const auto tests = std::to_array<DomainMatchCase>({
      {"bar.com", "bar.com", true},
      {".bar.com", "bar.com", true},
      {"bar.com", "food.bar.com", true},
      {"bar.com", "bar.foo.com", false},
      {".bar.com", ".foo.bar.com", true},
      {".bar.com", "baz.foo.bar.com", true},
      {"foo.bar.com", ".bar.com", false},
  });

  for (size_t i = 0; i < std::size(tests); ++i) {
    // Build up the Params struct.
    base::Value::List args;
    base::Value::Dict dict;
    dict.Set(kDomainKey, tests[i].filter);
    args.Append(std::move(dict));
    std::optional<GetAll::Params> params = GetAll::Params::Create(args);

    cookies_helpers::MatchFilter filter(&params->details);
    std::unique_ptr<net::CanonicalCookie> cookie =
        net::CanonicalCookie::CreateUnsafeCookieForTesting(
            "name", std::string(), tests[i].domain, "/", base::Time(),
            base::Time(), base::Time(), base::Time(), false, false,
            net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_DEFAULT);
    ASSERT_NE(nullptr, cookie.get());
    EXPECT_EQ(tests[i].matches, filter.MatchesCookie(*cookie)) << " test " << i;
  }
}

TEST_F(ExtensionCookiesTest, DecodeUTF8WithErrorHandling) {
  std::unique_ptr<net::CanonicalCookie> canonical_cookie(
      net::CanonicalCookie::CreateForTesting(
          GURL("http://test.com"), "=011Q255bNX_1!yd\203e+;path=/path\203",
          base::Time::Now()));
  ASSERT_NE(nullptr, canonical_cookie.get());
  Cookie cookie =
      cookies_helpers::CreateCookie(*canonical_cookie, "some cookie store");
  EXPECT_EQ(std::string("011Q255bNX_1!yd\xEF\xBF\xBD"
                        "e+"),
            cookie.value);
  EXPECT_EQ(std::string(), cookie.path);
}

TEST_F(ExtensionCookiesTest, PartitionKeySerialization) {
  std::string top_level_site = "https://toplevelsite.com";
  std::optional<extensions::api::cookies::CookiePartitionKey>
      partition_key_for_nonce_and_regular =
          extensions::api::cookies::CookiePartitionKey();
  std::optional<extensions::api::cookies::CookiePartitionKey>
      partition_key_for_opaque = extensions::api::cookies::CookiePartitionKey();
  partition_key_for_nonce_and_regular->top_level_site = top_level_site;
  partition_key_for_opaque->top_level_site = "";

  // Partition key to confirm crbug.com/1522601 is addressed.
  std::optional<extensions::api::cookies::CookiePartitionKey>
      partition_key_with_no_top_level_site_set =
          extensions::api::cookies::CookiePartitionKey();

  // Make a CanonicalCookie with a opaque top_level_site or nonce in partition
  // key.
  auto cookie = net::CanonicalCookie::CreateUnsafeCookieForTesting(
      "__Host-A", "B", "x.y", "/", base::Time(), base::Time(), base::Time(),
      base::Time(), /*secure=*/true,
      /*httponly=*/false, net::CookieSameSite::UNSPECIFIED,
      net::COOKIE_PRIORITY_LOW,
      net::CookiePartitionKey::FromURLForTesting(GURL(top_level_site)));
  EXPECT_TRUE(cookie->IsPartitioned());
  EXPECT_FALSE(net::CookiePartitionKey::HasNonce(cookie->PartitionKey()));
  EXPECT_TRUE(cookie->PartitionKey()->IsSerializeable());

  // Make a CanonicalCookie with a opaque partition key.
  auto opaque_cookie = net::CanonicalCookie::CreateUnsafeCookieForTesting(
      "__Host-A", "B", "x.y", "/", base::Time(), base::Time(), base::Time(),
      base::Time(), /*secure=*/true,
      /*httponly=*/false, net::CookieSameSite::UNSPECIFIED,
      net::COOKIE_PRIORITY_LOW,
      net::CookiePartitionKey::FromURLForTesting(GURL()));

  EXPECT_TRUE(opaque_cookie->IsPartitioned());
  EXPECT_FALSE(opaque_cookie->PartitionKey()->IsSerializeable());

  // Make a CanonicalCookie with an nonce partition key.
  auto nonce_cookie = net::CanonicalCookie::CreateUnsafeCookieForTesting(
      "__Host-A", "B", "x.y", "/", base::Time(), base::Time(), base::Time(),
      base::Time(), /*secure=*/true,
      /*httponly=*/false, net::CookieSameSite::UNSPECIFIED,
      net::COOKIE_PRIORITY_LOW,
      net::CookiePartitionKey::FromURLForTesting(
          GURL("https://toplevelsite.com"),
          net::CookiePartitionKey::AncestorChainBit::kCrossSite,
          base::UnguessableToken::Create()));

  EXPECT_TRUE(nonce_cookie->IsPartitioned());
  EXPECT_TRUE(net::CookiePartitionKey::HasNonce(nonce_cookie->PartitionKey()));
  EXPECT_FALSE(nonce_cookie->PartitionKey()->IsSerializeable());

  // Confirm that to be matchable, the partition key
  // must be serializable.
  EXPECT_TRUE(
      cookies_helpers::CanonicalCookiePartitionKeyMatchesApiCookiePartitionKey(
          partition_key_for_nonce_and_regular, *cookie->PartitionKey()));
  EXPECT_FALSE(
      cookies_helpers::CanonicalCookiePartitionKeyMatchesApiCookiePartitionKey(
          partition_key_for_nonce_and_regular, *nonce_cookie->PartitionKey()));
  EXPECT_FALSE(
      cookies_helpers::CanonicalCookiePartitionKeyMatchesApiCookiePartitionKey(
          partition_key_for_opaque, *opaque_cookie->PartitionKey()));
  EXPECT_FALSE(
      cookies_helpers::CanonicalCookiePartitionKeyMatchesApiCookiePartitionKey(
          partition_key_with_no_top_level_site_set, *cookie->PartitionKey()));
  EXPECT_FALSE(
      cookies_helpers::CanonicalCookiePartitionKeyMatchesApiCookiePartitionKey(
          partition_key_with_no_top_level_site_set,
          *nonce_cookie->PartitionKey()));
  EXPECT_FALSE(
      cookies_helpers::CanonicalCookiePartitionKeyMatchesApiCookiePartitionKey(
          partition_key_with_no_top_level_site_set,
          *opaque_cookie->PartitionKey()));

  // Confirm that a CanonicalCookie with serializable partition key
  // can be used to create a cookie.
  auto api_cookie = cookies_helpers::CreateCookie(*cookie, "0");
  EXPECT_TRUE(api_cookie.partition_key);

  // Confirm that a CanonicalCookie with a non-serializable partition key
  // dies when a cookie is attempted to be created.
  EXPECT_CHECK_DEATH(cookies_helpers::CreateCookie(*nonce_cookie, "0"));
  EXPECT_CHECK_DEATH(cookies_helpers::CreateCookie(*opaque_cookie, "0"));
}

}  // namespace extensions
