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

#include "services/network/cookie_manager.h"

#include <algorithm>

#include "base/bind.h"
#include "base/cxx17_backports.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "base/strings/strcat.h"
#include "base/task/post_task.h"
#include "base/task/thread_pool.h"
#include "base/task/thread_pool/thread_pool_instance.h"
#include "base/test/bind.h"
#include "base/test/scoped_command_line.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "net/base/features.h"
#include "net/cookies/canonical_cookie_test_helpers.h"
#include "net/cookies/cookie_access_result.h"
#include "net/cookies/cookie_constants.h"
#include "net/cookies/cookie_inclusion_status.h"
#include "net/cookies/cookie_monster.h"
#include "net/cookies/cookie_store.h"
#include "net/cookies/cookie_store_test_callbacks.h"
#include "net/cookies/cookie_store_test_helpers.h"
#include "net/cookies/cookie_util.h"
#include "net/cookies/test_cookie_access_delegate.h"
#include "net/url_request/url_request_context.h"
#include "services/network/cookie_access_delegate_impl.h"
#include "services/network/public/cpp/is_potentially_trustworthy.h"
#include "services/network/public/cpp/network_switches.h"
#include "services/network/public/mojom/cookie_manager.mojom.h"
#include "services/network/session_cleanup_cookie_store.h"
#include "testing/gmock/include/gmock/gmock-matchers.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

// Test infrastructure outline:
//      # Classes
//      * SynchronousMojoCookieWrapper: Takes a mojom::CookieManager at
//        construction; exposes synchronous interfaces that wrap the
//        mojom::CookieManager async interfaces to make testing easier.
//      * CookieChangeListener: Test class implementing the CookieChangeListener
//        interface and recording incoming messages on it.
//      * CookieManagerTest: Test base class.  Automatically sets up
//        a cookie store, a cookie service wrapping it, a mojo pipe
//        connected to the server, and the cookie service implemented
//        by the other end of the pipe.
//
//      # Functions
//      * CompareCanonicalCookies: Comparison function to make it easy to
//        sort cookie list responses from the mojom::CookieManager.
//      * CompareCookiesByValue: As above, but only by value.

namespace network {
namespace {
using base::StrCat;
using testing::IsEmpty;
using testing::UnorderedElementsAre;

using CookieDeletionInfo = net::CookieDeletionInfo;

const base::FilePath::CharType kTestCookiesFilename[] =
    FILE_PATH_LITERAL("Cookies");

constexpr char kCookieDomain[] = "foo_host.com";
constexpr char kCookieURL[] = "http://foo_host.com";
constexpr char kCookieHttpsURL[] = "https://foo_host.com";

// Wraps a mojom::CookieManager in synchronous, blocking calls to make
// it easier to test.
class SynchronousCookieManager {
 public:
  // Caller must guarantee that |*cookie_service| outlives the
  // SynchronousCookieManager.
  explicit SynchronousCookieManager(mojom::CookieManager* cookie_service)
      : cookie_service_(cookie_service), callback_counter_(0) {}

  ~SynchronousCookieManager() = default;

  std::vector<net::CanonicalCookie> GetAllCookies() {
    base::RunLoop run_loop;
    std::vector<net::CanonicalCookie> cookies_out;
    cookie_service_->GetAllCookies(base::BindLambdaForTesting(
        [&run_loop,
         &cookies_out](const std::vector<net::CanonicalCookie>& cookies) {
          cookies_out = cookies;
          run_loop.Quit();
        }));
    run_loop.Run();
    return cookies_out;
  }

  std::vector<net::CanonicalCookie> GetAllCookiesWithAccessSemantics(
      std::vector<net::CookieAccessSemantics>* access_semantics_list_out) {
    base::RunLoop run_loop;
    std::vector<net::CanonicalCookie> cookies_out;
    cookie_service_->GetAllCookiesWithAccessSemantics(
        base::BindLambdaForTesting(
            [&run_loop, &cookies_out, access_semantics_list_out](
                const std::vector<net::CanonicalCookie>& cookies,
                const std::vector<net::CookieAccessSemantics>&
                    access_semantics_list) {
              cookies_out = cookies;
              *access_semantics_list_out = access_semantics_list;
              run_loop.Quit();
            }));
    run_loop.Run();
    return cookies_out;
  }

  std::vector<net::CanonicalCookie> GetCookieList(const GURL& url,
                                                  net::CookieOptions options) {
    base::RunLoop run_loop;
    std::vector<net::CanonicalCookie> cookies_out;
    cookie_service_->GetCookieList(
        url, options,
        base::BindLambdaForTesting(
            [&run_loop, &cookies_out](
                const net::CookieAccessResultList& cookies,
                const net::CookieAccessResultList& excluded_cookies) {
              cookies_out = net::cookie_util::StripAccessResults(cookies);
              run_loop.Quit();
            }));
    run_loop.Run();
    return cookies_out;
  }

  net::CookieAccessResultList GetExcludedCookieList(
      const GURL& url,
      net::CookieOptions options) {
    base::RunLoop run_loop;
    net::CookieAccessResultList cookies_out;
    cookie_service_->GetCookieList(
        url, options,
        base::BindLambdaForTesting(
            [&run_loop, &cookies_out](
                const net::CookieAccessResultList& cookies,
                const net::CookieAccessResultList& excluded_cookies) {
              cookies_out = excluded_cookies;
              run_loop.Quit();
            }));
    run_loop.Run();
    return cookies_out;
  }

  bool SetCanonicalCookie(const net::CanonicalCookie& cookie,
                          std::string source_scheme,
                          bool modify_http_only) {
    base::RunLoop run_loop;
    net::CookieInclusionStatus result_out(
        net::CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR);
    net::CookieOptions options;
    options.set_same_site_cookie_context(
        net::CookieOptions::SameSiteCookieContext::MakeInclusive());
    if (modify_http_only)
      options.set_include_httponly();
    cookie_service_->SetCanonicalCookie(
        cookie, net::cookie_util::SimulatedCookieSource(cookie, source_scheme),
        options,
        base::BindLambdaForTesting(
            [&run_loop, &result_out](net::CookieAccessResult result) {
              result_out = result.status;
              run_loop.Quit();
            }));

    run_loop.Run();
    return result_out.IsInclude();
  }

  net::CookieAccessResult SetCanonicalCookieWithAccessResult(
      const net::CanonicalCookie& cookie,
      std::string source_scheme,
      bool modify_http_only) {
    base::RunLoop run_loop;
    net::CookieOptions options;
    options.set_same_site_cookie_context(
        net::CookieOptions::SameSiteCookieContext::MakeInclusive());
    if (modify_http_only)
      options.set_include_httponly();
    auto result_out = net::CookieAccessResult(net::CookieInclusionStatus(
        net::CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR));
    cookie_service_->SetCanonicalCookie(
        cookie, net::cookie_util::SimulatedCookieSource(cookie, source_scheme),
        options,
        base::BindLambdaForTesting(
            [&run_loop, &result_out](net::CookieAccessResult result) {
              result_out = result;
              run_loop.Quit();
            }));

    run_loop.Run();
    return result_out;
  }

  // TODO(chlily): Clean up these Set*() methods to all use proper source_url.
  net::CookieInclusionStatus SetCanonicalCookieFromUrlWithStatus(
      const net::CanonicalCookie& cookie,
      const GURL& source_url,
      bool modify_http_only) {
    base::RunLoop run_loop;
    net::CookieOptions options;
    options.set_same_site_cookie_context(
        net::CookieOptions::SameSiteCookieContext::MakeInclusive());
    if (modify_http_only)
      options.set_include_httponly();
    net::CookieInclusionStatus result_out(
        net::CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR);
    cookie_service_->SetCanonicalCookie(
        cookie, source_url, options,
        base::BindLambdaForTesting(
            [&run_loop, &result_out](net::CookieAccessResult result) {
              result_out = result.status;
              run_loop.Quit();
            }));

    run_loop.Run();
    return result_out;
  }

  bool DeleteCanonicalCookie(const net::CanonicalCookie& cookie) {
    base::RunLoop run_loop;
    bool result_out;
    cookie_service_->DeleteCanonicalCookie(
        cookie,
        base::BindLambdaForTesting([&run_loop, &result_out](bool result) {
          result_out = result;
          run_loop.Quit();
        }));

    run_loop.Run();
    return result_out;
  }

  uint32_t DeleteCookies(mojom::CookieDeletionFilter filter) {
    base::RunLoop run_loop;
    uint32_t result_out = 0u;
    mojom::CookieDeletionFilterPtr filter_ptr =
        mojom::CookieDeletionFilter::New(filter);

    cookie_service_->DeleteCookies(
        std::move(filter_ptr),
        base::BindLambdaForTesting([&run_loop, &result_out](uint32_t result) {
          result_out = result;
          run_loop.Quit();
        }));

    run_loop.Run();
    return result_out;
  }

  uint32_t DeleteSessionOnlyCookies() {
    base::RunLoop run_loop;
    uint32_t result_out = 0u;

    cookie_service_->DeleteSessionOnlyCookies(
        base::BindLambdaForTesting([&run_loop, &result_out](uint32_t result) {
          result_out = result;
          run_loop.Quit();
        }));

    run_loop.Run();
    return result_out;
  }

  void FlushCookieStore() {
    base::RunLoop run_loop;
    cookie_service_->FlushCookieStore(base::BindLambdaForTesting([&]() {
      ++callback_counter_;
      run_loop.Quit();
    }));
    run_loop.Run();
  }

  void SetStorageAccessGrantSettings() {
    std::vector<ContentSettingPatternSource> settings;
    base::RunLoop run_loop;
    cookie_service_->SetStorageAccessGrantSettings(
        std::move(settings), base::BindLambdaForTesting([&]() {
          ++callback_counter_;
          run_loop.Quit();
        }));
    run_loop.Run();
  }

  uint32_t callback_count() const { return callback_counter_; }

  // No need to wrap Add*Listener and CloneInterface, since their use
  // is purely async.
 private:
  mojom::CookieManager* cookie_service_;
  uint32_t callback_counter_;

  DISALLOW_COPY_AND_ASSIGN(SynchronousCookieManager);
};

class CookieManagerTest : public testing::Test {
 public:
  CookieManagerTest() {
    scoped_feature_list_.Init();
    InitializeCookieService(nullptr, nullptr);
  }

  ~CookieManagerTest() override = default;

  // Tear down the remote service.
  void NukeService() { cookie_service_.reset(); }

  // Set a canonical cookie directly into the store.
  bool SetCanonicalCookie(const net::CanonicalCookie& cookie,
                          std::string source_scheme,
                          bool can_modify_httponly) {
    net::ResultSavingCookieCallback<net::CookieAccessResult> callback;
    net::CookieOptions options;
    options.set_same_site_cookie_context(
        net::CookieOptions::SameSiteCookieContext::MakeInclusive());
    options.set_same_party_cookie_context_type(
        net::CookieOptions::SamePartyCookieContextType::kSameParty);
    options.set_is_in_nontrivial_first_party_set(true);
    if (can_modify_httponly)
      options.set_include_httponly();

    cookie_monster_->SetCanonicalCookieAsync(
        std::make_unique<net::CanonicalCookie>(cookie),
        net::cookie_util::SimulatedCookieSource(cookie, source_scheme), options,
        callback.MakeCallback());
    callback.WaitUntilDone();
    return callback.result().status.IsInclude();
  }

  std::string DumpAllCookies() {
    std::string result = "Cookies in store:\n";
    std::vector<net::CanonicalCookie> cookies =
        service_wrapper()->GetAllCookies();
    for (int i = 0; i < static_cast<int>(cookies.size()); ++i) {
      result += "\t";
      result += cookies[i].DebugString();
      result += "\n";
    }
    return result;
  }

  ContentSettingPatternSource CreateDefaultSetting(ContentSetting setting) {
    return ContentSettingPatternSource(
        ContentSettingsPattern::Wildcard(), ContentSettingsPattern::Wildcard(),
        base::Value(setting), std::string(), false);
  }

  ContentSettingPatternSource CreateSetting(ContentSetting setting,
                                            const std::string& url_str) {
    const GURL url(url_str);
    EXPECT_TRUE(url.is_valid());
    return ContentSettingPatternSource(ContentSettingsPattern::FromURL(url),
                                       ContentSettingsPattern::Wildcard(),
                                       base::Value(setting), std::string(),
                                       false);
  }

  net::CookieStore* cookie_store() { return cookie_monster_.get(); }

  CookieManager* service() const { return cookie_service_.get(); }

  // Return the cookie service at the client end of the mojo pipe.
  mojom::CookieManager* cookie_service_client() {
    return cookie_service_remote_.get();
  }

  // Synchronous wrapper
  SynchronousCookieManager* service_wrapper() { return service_wrapper_.get(); }

  bool connection_error_seen() const { return connection_error_seen_; }

  base::test::ScopedFeatureList& scoped_feature_list() {
    return scoped_feature_list_;
  }

 protected:
  void InitializeCookieService(
      scoped_refptr<net::CookieMonster::PersistentCookieStore> store,
      scoped_refptr<SessionCleanupCookieStore> cleanup_store) {
    if (cookie_service_) {
      // Make sure that data from any previous store is fully saved.
      // |cookie_service_| destroyed first since it may issue some writes to the
      // |cookie_monster_|.
      cookie_service_ = nullptr;
      net::NoResultCookieCallback callback;
      cookie_monster_->FlushStore(callback.MakeCallback());
      callback.WaitUntilDone();
    }
    // Reset |cookie_service_remote_| to allow re-initialize with params
    // for FlushableCookieManagerTest and SessionCleanupCookieManagerTest.
    cookie_service_remote_.reset();

    connection_error_seen_ = false;
    cookie_monster_ = std::make_unique<net::CookieMonster>(
        std::move(store), nullptr /* netlog */);
    url_request_context_ = std::make_unique<net::URLRequestContext>();
    url_request_context_->set_cookie_store(cookie_monster_.get());
    cookie_service_ = std::make_unique<CookieManager>(
        url_request_context_.get(), nullptr /* first_party_sets */,
        std::move(cleanup_store), nullptr);
    cookie_service_->AddReceiver(
        cookie_service_remote_.BindNewPipeAndPassReceiver());
    service_wrapper_ = std::make_unique<SynchronousCookieManager>(
        cookie_service_remote_.get());
    cookie_service_remote_.set_disconnect_handler(base::BindOnce(
        &CookieManagerTest::OnConnectionError, base::Unretained(this)));
  }

  base::ScopedTempDir temp_dir_;
  base::test::TaskEnvironment task_environment_;

 private:
  void OnConnectionError() { connection_error_seen_ = true; }

  bool connection_error_seen_;

  base::test::ScopedFeatureList scoped_feature_list_;
  std::unique_ptr<net::CookieMonster> cookie_monster_;
  std::unique_ptr<net::URLRequestContext> url_request_context_;
  std::unique_ptr<CookieManager> cookie_service_;
  mojo::Remote<mojom::CookieManager> cookie_service_remote_;
  std::unique_ptr<SynchronousCookieManager> service_wrapper_;

  DISALLOW_COPY_AND_ASSIGN(CookieManagerTest);
};

bool CompareCanonicalCookies(const net::CanonicalCookie& c1,
                             const net::CanonicalCookie& c2) {
  return c1.PartialCompare(c2);
}

// Test the GetAllCookies accessor.  Also tests that canonical
// cookies come out of the store unchanged.
TEST_F(CookieManagerTest, GetAllCookies) {
  base::Time before_creation(base::Time::Now());

  // Set some cookies for the test to play with.
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A", "B", kCookieDomain, "/", base::Time(), base::Time(),
          base::Time(),
          /*secure=*/false, /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "C", "D", "foo_host2", "/with/path", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "Secure", "E", kCookieDomain, "/with/path", base::Time(),
          base::Time(), base::Time(), /*secure=*/true,
          /*httponly=*/false, net::CookieSameSite::NO_RESTRICTION,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "HttpOnly", "F", kCookieDomain, "/with/path",
                             base::Time(), base::Time(), base::Time(),
                             /*secure=*/false,
                             /*httponly=*/true, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "SecureSameParty", "G", kCookieDomain, "/with/path", base::Time(),
          base::Time(), base::Time(),
          /*secure=*/true,
          /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/true),
      "https", true));

  base::Time after_creation(base::Time::Now());

  std::vector<net::CanonicalCookie> cookies =
      service_wrapper()->GetAllCookies();

  ASSERT_EQ(5u, cookies.size());
  std::sort(cookies.begin(), cookies.end(), &CompareCanonicalCookies);

  EXPECT_EQ("A", cookies[0].Name());
  EXPECT_EQ("B", cookies[0].Value());
  EXPECT_EQ(kCookieDomain, cookies[0].Domain());
  EXPECT_EQ("/", cookies[0].Path());
  EXPECT_LE(before_creation, cookies[0].CreationDate());
  EXPECT_LE(cookies[0].CreationDate(), after_creation);
  EXPECT_EQ(cookies[0].LastAccessDate(), base::Time());
  EXPECT_EQ(cookies[0].ExpiryDate(), base::Time());
  EXPECT_FALSE(cookies[0].IsPersistent());
  EXPECT_FALSE(cookies[0].IsSecure());
  EXPECT_FALSE(cookies[0].IsHttpOnly());
  EXPECT_EQ(net::CookieSameSite::LAX_MODE, cookies[0].SameSite());
  EXPECT_EQ(net::COOKIE_PRIORITY_MEDIUM, cookies[0].Priority());
  EXPECT_FALSE(cookies[0].IsSameParty());

  EXPECT_EQ("C", cookies[1].Name());
  EXPECT_EQ("D", cookies[1].Value());
  EXPECT_EQ("foo_host2", cookies[1].Domain());
  EXPECT_EQ("/with/path", cookies[1].Path());
  EXPECT_LE(before_creation, cookies[1].CreationDate());
  EXPECT_LE(cookies[1].CreationDate(), after_creation);
  EXPECT_EQ(cookies[1].LastAccessDate(), base::Time());
  EXPECT_EQ(cookies[1].ExpiryDate(), base::Time());
  EXPECT_FALSE(cookies[1].IsPersistent());
  EXPECT_FALSE(cookies[1].IsSecure());
  EXPECT_FALSE(cookies[1].IsHttpOnly());
  EXPECT_EQ(net::CookieSameSite::LAX_MODE, cookies[1].SameSite());
  EXPECT_EQ(net::COOKIE_PRIORITY_MEDIUM, cookies[1].Priority());
  EXPECT_FALSE(cookies[1].IsSameParty());

  EXPECT_EQ("HttpOnly", cookies[2].Name());
  EXPECT_EQ("F", cookies[2].Value());
  EXPECT_EQ(kCookieDomain, cookies[2].Domain());
  EXPECT_EQ("/with/path", cookies[2].Path());
  EXPECT_LE(before_creation, cookies[2].CreationDate());
  EXPECT_LE(cookies[2].CreationDate(), after_creation);
  EXPECT_EQ(cookies[2].LastAccessDate(), base::Time());
  EXPECT_EQ(cookies[2].ExpiryDate(), base::Time());
  EXPECT_FALSE(cookies[2].IsPersistent());
  EXPECT_FALSE(cookies[2].IsSecure());
  EXPECT_TRUE(cookies[2].IsHttpOnly());
  EXPECT_EQ(net::CookieSameSite::LAX_MODE, cookies[2].SameSite());
  EXPECT_EQ(net::COOKIE_PRIORITY_MEDIUM, cookies[2].Priority());
  EXPECT_FALSE(cookies[2].IsSameParty());

  EXPECT_EQ("Secure", cookies[3].Name());
  EXPECT_EQ("E", cookies[3].Value());
  EXPECT_EQ(kCookieDomain, cookies[3].Domain());
  EXPECT_EQ("/with/path", cookies[3].Path());
  EXPECT_LE(before_creation, cookies[3].CreationDate());
  EXPECT_LE(cookies[3].CreationDate(), after_creation);
  EXPECT_EQ(cookies[3].LastAccessDate(), base::Time());
  EXPECT_EQ(cookies[3].ExpiryDate(), base::Time());
  EXPECT_FALSE(cookies[3].IsPersistent());
  EXPECT_TRUE(cookies[3].IsSecure());
  EXPECT_FALSE(cookies[3].IsHttpOnly());
  EXPECT_EQ(net::CookieSameSite::NO_RESTRICTION, cookies[3].SameSite());
  EXPECT_EQ(net::COOKIE_PRIORITY_MEDIUM, cookies[3].Priority());
  EXPECT_FALSE(cookies[3].IsSameParty());

  EXPECT_EQ("SecureSameParty", cookies[4].Name());
  EXPECT_EQ("G", cookies[4].Value());
  EXPECT_EQ(kCookieDomain, cookies[4].Domain());
  EXPECT_EQ("/with/path", cookies[4].Path());
  EXPECT_LE(before_creation, cookies[4].CreationDate());
  EXPECT_LE(cookies[4].CreationDate(), after_creation);
  EXPECT_EQ(cookies[4].LastAccessDate(), base::Time());
  EXPECT_EQ(cookies[4].ExpiryDate(), base::Time());
  EXPECT_FALSE(cookies[4].IsPersistent());
  EXPECT_TRUE(cookies[4].IsSecure());
  EXPECT_FALSE(cookies[4].IsHttpOnly());
  EXPECT_EQ(net::CookieSameSite::LAX_MODE, cookies[4].SameSite());
  EXPECT_EQ(net::COOKIE_PRIORITY_MEDIUM, cookies[4].Priority());
  EXPECT_TRUE(cookies[4].IsSameParty());
}

TEST_F(CookieManagerTest, GetAllCookiesWithAccessSemantics) {
  auto delegate = std::make_unique<net::TestCookieAccessDelegate>();
  delegate->SetExpectationForCookieDomain("domain1.test",
                                          net::CookieAccessSemantics::UNKNOWN);
  delegate->SetExpectationForCookieDomain("domain2.test",
                                          net::CookieAccessSemantics::LEGACY);
  delegate->SetExpectationForCookieDomain(
      ".domainwithdot.test", net::CookieAccessSemantics::NONLEGACY);
  cookie_store()->SetCookieAccessDelegate(std::move(delegate));

  // Set some cookies for the test to play with.
  // TODO(chlily): Because the order of the cookies with respect to the access
  // semantics entries should match up, for the purposes of this test we need
  // the cookies to sort in a predictable order. Since the longest path is
  // first, we can manipulate the path attribute of each cookie set below to get
  // them in the right order. This will have to change if CookieSorter ever
  // starts sorting the cookies differently.

  // UNKNOWN
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A", "B", "domain1.test",
                             "/this/path/is/the/longest/for/sorting/purposes",
                             base::Time(), base::Time(), base::Time(),
                             /*secure=*/true, /*httponly=*/false,
                             net::CookieSameSite::NO_RESTRICTION,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));
  // LEGACY
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "C", "D", "domain2.test", "/with/longer/path",
                             base::Time(), base::Time(), base::Time(),
                             /*secure=*/true, /*httponly=*/false,
                             net::CookieSameSite::NO_RESTRICTION,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));
  // not set (UNKNOWN)
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "HttpOnly", "F", "domain3.test", "/with/path", base::Time(),
          base::Time(), base::Time(), /*secure=*/true,
          /*httponly=*/true, net::CookieSameSite::NO_RESTRICTION,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));
  // NONLEGACY
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "Secure", "E", ".domainwithdot.test", "/", base::Time(), base::Time(),
          base::Time(), /*secure=*/true,
          /*httponly=*/true, net::CookieSameSite::NO_RESTRICTION,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));

  std::vector<net::CookieAccessSemantics> access_semantics_list;
  std::vector<net::CanonicalCookie> cookies =
      service_wrapper()->GetAllCookiesWithAccessSemantics(
          &access_semantics_list);

  ASSERT_EQ(4u, cookies.size());
  EXPECT_EQ(cookies.size(), access_semantics_list.size());
  EXPECT_EQ("domain1.test", cookies[0].Domain());
  EXPECT_EQ("domain2.test", cookies[1].Domain());
  EXPECT_EQ("domain3.test", cookies[2].Domain());
  EXPECT_EQ(".domainwithdot.test", cookies[3].Domain());

  EXPECT_EQ(net::CookieAccessSemantics::UNKNOWN, access_semantics_list[0]);
  EXPECT_EQ(net::CookieAccessSemantics::LEGACY, access_semantics_list[1]);
  EXPECT_EQ(net::CookieAccessSemantics::UNKNOWN, access_semantics_list[2]);
  EXPECT_EQ(net::CookieAccessSemantics::NONLEGACY, access_semantics_list[3]);
}

TEST_F(CookieManagerTest, GetCookieList) {
  // Set some cookies for the test to play with.
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A", "B", kCookieDomain, "/", base::Time(), base::Time(),
          base::Time(),
          /*secure=*/false, /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "C", "D", "foo_host2", "/with/path", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "Secure", "E", kCookieDomain, "/with/path",
                             base::Time(), base::Time(), base::Time(),
                             /*secure=*/true,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "HttpOnly", "F", kCookieDomain, "/with/path",
                             base::Time(), base::Time(), base::Time(),
                             /*secure=*/false,
                             /*httponly=*/true, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));

  // Want the SameSite=lax cookies, but not httponly ones.
  net::CookieOptions options;
  options.set_same_site_cookie_context(
      net::CookieOptions::SameSiteCookieContext::MakeInclusive());
  std::vector<net::CanonicalCookie> cookies = service_wrapper()->GetCookieList(
      GURL("https://foo_host.com/with/path"), options);

  ASSERT_EQ(2u, cookies.size());
  std::sort(cookies.begin(), cookies.end(), &CompareCanonicalCookies);

  EXPECT_EQ("A", cookies[0].Name());
  EXPECT_EQ("B", cookies[0].Value());

  EXPECT_EQ("Secure", cookies[1].Name());
  EXPECT_EQ("E", cookies[1].Value());

  net::CookieOptions excluded_options = options;
  excluded_options.set_return_excluded_cookies();
  net::CookieAccessResultList excluded_cookies =
      service_wrapper()->GetExcludedCookieList(
          GURL("https://foo_host.com/with/path"), excluded_options);

  ASSERT_EQ(1u, excluded_cookies.size());

  EXPECT_EQ("HttpOnly", excluded_cookies[0].cookie.Name());
  EXPECT_EQ("F", excluded_cookies[0].cookie.Value());
  EXPECT_TRUE(excluded_cookies[0]
                  .access_result.status.HasExactlyExclusionReasonsForTesting(
                      {net::CookieInclusionStatus::EXCLUDE_HTTP_ONLY}));
}

TEST_F(CookieManagerTest, GetCookieListHttpOnly) {
  // Create an httponly and a non-httponly cookie.
  bool result;
  result = SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A", "B", kCookieDomain, "/", base::Time(), base::Time(),
          base::Time(),
          /*secure=*/false, /*httponly=*/true, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true);
  ASSERT_TRUE(result);
  result = SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "C", "D", kCookieDomain, "/", base::Time(), base::Time(),
          base::Time(),
          /*secure=*/false, /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true);
  ASSERT_TRUE(result);

  // Retrieve without httponly cookies (default)
  net::CookieOptions options;
  options.set_same_site_cookie_context(
      net::CookieOptions::SameSiteCookieContext::MakeInclusive());

  EXPECT_TRUE(options.exclude_httponly());
  std::vector<net::CanonicalCookie> cookies = service_wrapper()->GetCookieList(
      GURL("https://foo_host.com/with/path"), options);
  ASSERT_EQ(1u, cookies.size());
  EXPECT_EQ("C", cookies[0].Name());

  options.set_return_excluded_cookies();

  net::CookieAccessResultList excluded_cookies =
      service_wrapper()->GetExcludedCookieList(
          GURL("https://foo_host.com/with/path"), options);
  ASSERT_EQ(1u, excluded_cookies.size());
  EXPECT_EQ("A", excluded_cookies[0].cookie.Name());

  // Retrieve with httponly cookies.
  options.set_include_httponly();
  cookies = service_wrapper()->GetCookieList(
      GURL("https://foo_host.com/with/path"), options);
  ASSERT_EQ(2u, cookies.size());
  std::sort(cookies.begin(), cookies.end(), &CompareCanonicalCookies);

  EXPECT_EQ("A", cookies[0].Name());
  EXPECT_EQ("C", cookies[1].Name());
}

TEST_F(CookieManagerTest, GetCookieListSameSite) {
  // Create an unrestricted, a lax, and a strict cookie.
  bool result;
  result =
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A", "B", kCookieDomain, "/", base::Time(),
                             base::Time(), base::Time(),
                             /*secure=*/true, /*httponly=*/false,
                             net::CookieSameSite::NO_RESTRICTION,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true);
  ASSERT_TRUE(result);
  result =
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "C", "D", kCookieDomain, "/", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true);
  ASSERT_TRUE(result);
  result = SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "E", "F", kCookieDomain, "/", base::Time(), base::Time(),
          base::Time(), /*secure=*/false,
          /*httponly=*/false, net::CookieSameSite::STRICT_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true);
  ASSERT_TRUE(result);

  // Retrieve only unrestricted cookies.
  net::CookieOptions options;
  EXPECT_EQ(
      net::CookieOptions::SameSiteCookieContext(
          net::CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE),
      options.same_site_cookie_context());
  std::vector<net::CanonicalCookie> cookies = service_wrapper()->GetCookieList(
      GURL("https://foo_host.com/with/path"), options);
  ASSERT_EQ(1u, cookies.size());
  EXPECT_EQ("A", cookies[0].Name());

  options.set_return_excluded_cookies();

  net::CookieAccessResultList excluded_cookies =
      service_wrapper()->GetExcludedCookieList(
          GURL("https://foo_host.com/with/path"), options);
  ASSERT_EQ(2u, excluded_cookies.size());

  // Retrieve unrestricted and lax cookies.
  options.set_same_site_cookie_context(
      net::CookieOptions::SameSiteCookieContext(
          net::CookieOptions::SameSiteCookieContext::ContextType::
              SAME_SITE_LAX));
  cookies = service_wrapper()->GetCookieList(
      GURL("https://foo_host.com/with/path"), options);
  ASSERT_EQ(2u, cookies.size());
  std::sort(cookies.begin(), cookies.end(), &CompareCanonicalCookies);
  EXPECT_EQ("A", cookies[0].Name());
  EXPECT_EQ("C", cookies[1].Name());

  excluded_cookies = service_wrapper()->GetExcludedCookieList(
      GURL("https://foo_host.com/with/path"), options);
  ASSERT_EQ(1u, excluded_cookies.size());

  // Retrieve everything.
  options.set_same_site_cookie_context(
      net::CookieOptions::SameSiteCookieContext::MakeInclusive());
  cookies = service_wrapper()->GetCookieList(
      GURL("https://foo_host.com/with/path"), options);
  ASSERT_EQ(3u, cookies.size());
  std::sort(cookies.begin(), cookies.end(), &CompareCanonicalCookies);
  EXPECT_EQ("A", cookies[0].Name());
  EXPECT_EQ("C", cookies[1].Name());
  EXPECT_EQ("E", cookies[2].Name());

  excluded_cookies = service_wrapper()->GetExcludedCookieList(
      GURL("https://foo_host.com/with/path"), options);
  ASSERT_EQ(0u, excluded_cookies.size());
}

TEST_F(CookieManagerTest, GetCookieListSameParty) {
  scoped_feature_list().Reset();
  scoped_feature_list().InitAndEnableFeature(net::features::kFirstPartySets);
  // Create SameParty & non-SameParty cookies for each valid SameSite choice.
  // Unspecified:
  ASSERT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "nonSameParty-Unspecified", "A", kCookieDomain, "/", base::Time(),
          base::Time(), base::Time(),
          /*secure=*/true, /*httponly=*/false, net::CookieSameSite::UNSPECIFIED,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));
  ASSERT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "SameParty-Unspecified", "B", kCookieDomain, "/", base::Time(),
          base::Time(), base::Time(), /*secure=*/true,
          /*httponly=*/false, net::CookieSameSite::UNSPECIFIED,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/true),
      "https", true));
  // None:
  ASSERT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "nonSameParty-None", "C", kCookieDomain, "/",
                             base::Time(), base::Time(), base::Time(),
                             /*secure=*/true, /*httponly=*/false,
                             net::CookieSameSite::NO_RESTRICTION,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));
  ASSERT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "SameParty-None", "D", kCookieDomain, "/", base::Time(), base::Time(),
          base::Time(), /*secure=*/true,
          /*httponly=*/false, net::CookieSameSite::NO_RESTRICTION,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/true),
      "https", true));
  // Lax:
  ASSERT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "nonSameParty-Lax", "E", kCookieDomain, "/", base::Time(),
          base::Time(), base::Time(), /*secure=*/true,
          /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));
  ASSERT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "SameParty-Lax", "F", kCookieDomain, "/", base::Time(), base::Time(),
          base::Time(), /*secure=*/true,
          /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/true),
      "https", true));

  const GURL cookie_url("https://foo_host.com/with/path");

  // Verify that sites in a First-Party Set get SameParty semantics.
  {
    net::CookieOptions options;
    options.set_return_excluded_cookies();
    options.set_is_in_nontrivial_first_party_set(true);
    ASSERT_EQ(net::CookieOptions::SamePartyCookieContextType::kCrossParty,
              options.same_party_cookie_context_type());
    ASSERT_EQ(
        net::CookieOptions::SameSiteCookieContext(
            net::CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE),
        options.same_site_cookie_context());

    // Retrieve only unrestricted cookies. SameParty cookies are excluded, and
    // non-SameSite=None cookies are excluded.
    EXPECT_THAT(
        service_wrapper()->GetCookieList(cookie_url, options),
        UnorderedElementsAre(net::MatchesCookieWithName("nonSameParty-None")));

    EXPECT_THAT(
        service_wrapper()->GetExcludedCookieList(cookie_url, options),
        UnorderedElementsAre(
            net::MatchesCookieAccessWithName("SameParty-Unspecified"),
            net::MatchesCookieAccessWithName("SameParty-None"),
            net::MatchesCookieAccessWithName("SameParty-Lax"),
            net::MatchesCookieAccessWithName("nonSameParty-Unspecified"),
            net::MatchesCookieAccessWithName("nonSameParty-Lax")));

    // In a same-party, cross-site context, SameParty cookies should be
    // included, and non-SameParty cookies should be excluded based on SameSite
    // value.
    options.set_same_party_cookie_context_type(
        net::CookieOptions::SamePartyCookieContextType::kSameParty);
    EXPECT_THAT(service_wrapper()->GetCookieList(cookie_url, options),
                UnorderedElementsAre(
                    net::MatchesCookieWithName("SameParty-Unspecified"),
                    net::MatchesCookieWithName("SameParty-None"),
                    net::MatchesCookieWithName("SameParty-Lax"),
                    net::MatchesCookieWithName("nonSameParty-None")));
    EXPECT_THAT(
        service_wrapper()->GetExcludedCookieList(cookie_url, options),
        UnorderedElementsAre(
            net::MatchesCookieAccessWithName("nonSameParty-Unspecified"),
            net::MatchesCookieAccessWithName("nonSameParty-Lax")));

    // In a same-party, same-site context, all cookies should be included.
    options.set_same_site_cookie_context(
        net::CookieOptions::SameSiteCookieContext::MakeInclusive());
    EXPECT_THAT(service_wrapper()->GetCookieList(cookie_url, options),
                UnorderedElementsAre(
                    net::MatchesCookieWithName("SameParty-Unspecified"),
                    net::MatchesCookieWithName("SameParty-None"),
                    net::MatchesCookieWithName("SameParty-Lax"),
                    net::MatchesCookieWithName("nonSameParty-Unspecified"),
                    net::MatchesCookieWithName("nonSameParty-None"),
                    net::MatchesCookieWithName("nonSameParty-Lax")));
    EXPECT_THAT(service_wrapper()->GetExcludedCookieList(cookie_url, options),
                IsEmpty());
  }

  // Now verify that sites not in a First-Party Set ignore SameParty and fall
  // back to SameSite semantics instead.
  {
    net::CookieOptions options;
    options.set_return_excluded_cookies();
    // Default, but set for explicitness.
    options.set_is_in_nontrivial_first_party_set(false);
    ASSERT_EQ(net::CookieOptions::SamePartyCookieContextType::kCrossParty,
              options.same_party_cookie_context_type());
    ASSERT_EQ(
        net::CookieOptions::SameSiteCookieContext(
            net::CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE),
        options.same_site_cookie_context());

    // Cross-party, cross-site.
    EXPECT_THAT(
        service_wrapper()->GetCookieList(cookie_url, options),
        UnorderedElementsAre(net::MatchesCookieWithName("SameParty-None"),
                             net::MatchesCookieWithName("nonSameParty-None")));

    EXPECT_THAT(
        service_wrapper()->GetExcludedCookieList(cookie_url, options),
        UnorderedElementsAre(
            net::MatchesCookieAccessWithName("SameParty-Unspecified"),
            net::MatchesCookieAccessWithName("SameParty-Lax"),
            net::MatchesCookieAccessWithName("nonSameParty-Unspecified"),
            net::MatchesCookieAccessWithName("nonSameParty-Lax")));

    // Same-party, cross-site.
    options.set_same_party_cookie_context_type(
        net::CookieOptions::SamePartyCookieContextType::kSameParty);
    EXPECT_THAT(
        service_wrapper()->GetCookieList(cookie_url, options),
        UnorderedElementsAre(net::MatchesCookieWithName("SameParty-None"),
                             net::MatchesCookieWithName("nonSameParty-None")));
    EXPECT_THAT(
        service_wrapper()->GetExcludedCookieList(cookie_url, options),
        UnorderedElementsAre(
            net::MatchesCookieAccessWithName("SameParty-Unspecified"),
            net::MatchesCookieAccessWithName("SameParty-Lax"),
            net::MatchesCookieAccessWithName("nonSameParty-Unspecified"),
            net::MatchesCookieAccessWithName("nonSameParty-Lax")));

    // Same-party, same-site.
    options.set_same_site_cookie_context(
        net::CookieOptions::SameSiteCookieContext::MakeInclusive());
    EXPECT_THAT(service_wrapper()->GetCookieList(cookie_url, options),
                UnorderedElementsAre(
                    net::MatchesCookieWithName("SameParty-Unspecified"),
                    net::MatchesCookieWithName("SameParty-None"),
                    net::MatchesCookieWithName("SameParty-Lax"),
                    net::MatchesCookieWithName("nonSameParty-Unspecified"),
                    net::MatchesCookieWithName("nonSameParty-None"),
                    net::MatchesCookieWithName("nonSameParty-Lax")));
    EXPECT_THAT(service_wrapper()->GetExcludedCookieList(cookie_url, options),
                IsEmpty());
  }
}

TEST_F(CookieManagerTest, GetCookieListAccessTime) {
  bool result = SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A", "B", kCookieDomain, "/", base::Time(), base::Time(),
          base::Time(),
          /*secure=*/false, /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true);
  ASSERT_TRUE(result);

  // Get the cookie without updating the access time and check
  // the access time is null.
  net::CookieOptions options;
  options.set_same_site_cookie_context(
      net::CookieOptions::SameSiteCookieContext::MakeInclusive());

  options.set_do_not_update_access_time();
  std::vector<net::CanonicalCookie> cookies = service_wrapper()->GetCookieList(
      GURL("https://foo_host.com/with/path"), options);
  ASSERT_EQ(1u, cookies.size());
  EXPECT_EQ("A", cookies[0].Name());
  EXPECT_TRUE(cookies[0].LastAccessDate().is_null());

  // Get the cookie updating the access time and check
  // that it's a valid value.
  base::Time start(base::Time::Now());
  options.set_update_access_time();
  cookies = service_wrapper()->GetCookieList(
      GURL("https://foo_host.com/with/path"), options);
  ASSERT_EQ(1u, cookies.size());
  EXPECT_EQ("A", cookies[0].Name());
  EXPECT_FALSE(cookies[0].LastAccessDate().is_null());
  EXPECT_GE(cookies[0].LastAccessDate(), start);
  EXPECT_LE(cookies[0].LastAccessDate(), base::Time::Now());
}

TEST_F(CookieManagerTest, DeleteCanonicalCookie) {
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A", "B", "foo_host", "/", base::Time(), base::Time(), base::Time(),
          /*secure=*/false, /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));
  std::vector<net::CanonicalCookie> cookies =
      service_wrapper()->GetAllCookies();
  ASSERT_EQ(1U, cookies.size());
  EXPECT_TRUE(service_wrapper()->DeleteCanonicalCookie(cookies[0]));
  EXPECT_EQ(0U, service_wrapper()->GetAllCookies().size());
}

TEST_F(CookieManagerTest, DeleteThroughSet) {
  // Set some cookies for the test to play with.
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A", "B", kCookieDomain, "/", base::Time(), base::Time(),
          base::Time(),
          /*secure=*/false, /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "C", "D", "foo_host2", "/with/path", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "Secure", "E", kCookieDomain, "/with/path",
                             base::Time(), base::Time(), base::Time(),
                             /*secure=*/true,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "HttpOnly", "F", kCookieDomain, "/with/path",
                             base::Time(), base::Time(), base::Time(),
                             /*secure=*/false,
                             /*httponly=*/true, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));

  base::Time yesterday = base::Time::Now() - base::TimeDelta::FromDays(1);
  EXPECT_TRUE(service_wrapper()->SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A", "E", kCookieDomain, "/", base::Time(), yesterday, base::Time(),
          /*secure=*/false, /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "http", false));

  std::vector<net::CanonicalCookie> cookies =
      service_wrapper()->GetAllCookies();

  ASSERT_EQ(3u, cookies.size());
  std::sort(cookies.begin(), cookies.end(), &CompareCanonicalCookies);

  EXPECT_EQ("C", cookies[0].Name());
  EXPECT_EQ("D", cookies[0].Value());

  EXPECT_EQ("HttpOnly", cookies[1].Name());
  EXPECT_EQ("F", cookies[1].Value());

  EXPECT_EQ("Secure", cookies[2].Name());
  EXPECT_EQ("E", cookies[2].Value());
}

TEST_F(CookieManagerTest, ConfirmSecureSetFails) {
  net::CookieAccessResult access_result =
      service_wrapper()->SetCanonicalCookieWithAccessResult(
          *net::CanonicalCookie::CreateUnsafeCookieForTesting(
              "N", "O", kCookieDomain, "/", base::Time(), base::Time(),
              base::Time(),
              /*secure=*/true, /*httponly=*/false,
              net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM,
              /*same_party=*/false),
          "http", false);

  EXPECT_TRUE(access_result.status.HasExactlyExclusionReasonsForTesting(
      {net::CookieInclusionStatus::EXCLUDE_SECURE_ONLY}));
  EXPECT_EQ(access_result.effective_same_site,
            net::CookieEffectiveSameSite::NO_RESTRICTION);
  std::vector<net::CanonicalCookie> cookies =
      service_wrapper()->GetAllCookies();

  ASSERT_EQ(0u, cookies.size());
}

// Test CookieAccessDelegateImpl functionality for allowing Secure cookie access
// from potentially trustworthy origins, even if non-cryptographic.
TEST_F(CookieManagerTest, SecureCookieNonCryptographicPotentiallyTrustworthy) {
  GURL http_localhost_url("http://localhost/path");
  auto http_localhost_cookie = net::CanonicalCookie::Create(
      http_localhost_url, "http_localhost=1; Secure", base::Time::Now(),
      absl::nullopt);

  // Secure cookie can be set from non-cryptographic localhost URL.
  EXPECT_TRUE(service_wrapper()
                  ->SetCanonicalCookieFromUrlWithStatus(
                      *http_localhost_cookie, http_localhost_url,
                      false /* modify_http_only */)
                  .IsInclude());
  // And can be retrieved from such.
  std::vector<net::CanonicalCookie> http_localhost_cookies =
      service_wrapper()->GetCookieList(http_localhost_url,
                                       net::CookieOptions::MakeAllInclusive());
  ASSERT_EQ(1u, http_localhost_cookies.size());
  EXPECT_EQ("http_localhost", http_localhost_cookies[0].Name());
  EXPECT_EQ(net::CookieSourceScheme::kNonSecure,
            http_localhost_cookies[0].SourceScheme());
  EXPECT_TRUE(http_localhost_cookies[0].IsSecure());

  GURL http_other_url("http://other.test/path");
  auto http_other_cookie = net::CanonicalCookie::Create(
      http_other_url, "http_other=1; Secure", base::Time::Now(), absl::nullopt);

  // Secure cookie cannot be set from another non-cryptographic URL if there is
  // no CookieAccessDelegate.
  EXPECT_TRUE(
      service_wrapper()
          ->SetCanonicalCookieFromUrlWithStatus(
              *http_other_cookie, http_other_url, false /* modify_http_only */)
          .HasExactlyExclusionReasonsForTesting(
              {net::CookieInclusionStatus::EXCLUDE_SECURE_ONLY}));

  // Set a CookieAccessDelegateImpl which allows other origins registered
  // as trustworthy to set a Secure cookie.
  auto delegate = std::make_unique<CookieAccessDelegateImpl>(
      mojom::CookieAccessDelegateType::ALWAYS_LEGACY, nullptr);
  cookie_store()->SetCookieAccessDelegate(std::move(delegate));
  base::test::ScopedCommandLine scoped_command_line;
  base::CommandLine* command_line = scoped_command_line.GetProcessCommandLine();
  command_line->AppendSwitchASCII(
      switches::kUnsafelyTreatInsecureOriginAsSecure, "http://other.test");
  SecureOriginAllowlist::GetInstance().ResetForTesting();
  ASSERT_TRUE(IsUrlPotentiallyTrustworthy(http_other_url));

  // Secure cookie can be set from non-cryptographic but potentially trustworthy
  // origin, if CookieAccessDelegate allows it.
  EXPECT_TRUE(
      service_wrapper()
          ->SetCanonicalCookieFromUrlWithStatus(
              *http_other_cookie, http_other_url, false /* modify_http_only */)
          .IsInclude());
  // And can be retrieved from such.
  std::vector<net::CanonicalCookie> http_other_cookies =
      service_wrapper()->GetCookieList(http_other_url,
                                       net::CookieOptions::MakeAllInclusive());
  ASSERT_EQ(1u, http_other_cookies.size());
  EXPECT_EQ("http_other", http_other_cookies[0].Name());
  EXPECT_EQ(net::CookieSourceScheme::kNonSecure,
            http_other_cookies[0].SourceScheme());
  EXPECT_TRUE(http_other_cookies[0].IsSecure());
}

TEST_F(CookieManagerTest, ConfirmHttpOnlySetFails) {
  net::CookieAccessResult access_result =
      service_wrapper()->SetCanonicalCookieWithAccessResult(
          *net::CanonicalCookie::CreateUnsafeCookieForTesting(
              "N", "O", kCookieDomain, "/", base::Time(), base::Time(),
              base::Time(),
              /*secure=*/false, /*httponly=*/true,
              net::CookieSameSite::LAX_MODE, net::COOKIE_PRIORITY_MEDIUM,
              /*same_party=*/false),
          "http", false);

  EXPECT_TRUE(access_result.status.HasExactlyExclusionReasonsForTesting(
      {net::CookieInclusionStatus::EXCLUDE_HTTP_ONLY}));
  EXPECT_EQ(access_result.effective_same_site,
            net::CookieEffectiveSameSite::LAX_MODE);
  std::vector<net::CanonicalCookie> cookies =
      service_wrapper()->GetAllCookies();

  ASSERT_EQ(0u, cookies.size());
}

TEST_F(CookieManagerTest, ConfirmSecureOverwriteFails) {
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "Secure", "F", kCookieDomain, "/with/path",
                             base::Time(), base::Time(), base::Time(),
                             /*secure=*/true,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));

  net::CookieAccessResult access_result =
      service_wrapper()->SetCanonicalCookieWithAccessResult(
          *net::CanonicalCookie::CreateUnsafeCookieForTesting(
              "Secure", "Nope", kCookieDomain, "/with/path", base::Time(),
              base::Time(), base::Time(), /*secure=*/false,
              /*httponly=*/false, net::CookieSameSite::LAX_MODE,
              net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
          "http", false);

  EXPECT_TRUE(access_result.status.HasExactlyExclusionReasonsForTesting(
      {net::CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
  EXPECT_EQ(access_result.effective_same_site,
            net::CookieEffectiveSameSite::LAX_MODE);

  std::vector<net::CanonicalCookie> cookies =
      service_wrapper()->GetAllCookies();
  ASSERT_EQ(1u, cookies.size());
  std::sort(cookies.begin(), cookies.end(), &CompareCanonicalCookies);
  EXPECT_EQ("Secure", cookies[0].Name());
  EXPECT_EQ("F", cookies[0].Value());
}

TEST_F(CookieManagerTest, ConfirmHttpOnlyOverwriteFails) {
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "HttpOnly", "F", kCookieDomain, "/with/path",
                             base::Time(), base::Time(), base::Time(),
                             /*secure=*/false,
                             /*httponly=*/true, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "http", true));

  net::CookieAccessResult access_result =
      service_wrapper()->SetCanonicalCookieWithAccessResult(
          *net::CanonicalCookie::CreateUnsafeCookieForTesting(
              "HttpOnly", "Nope", kCookieDomain, "/with/path", base::Time(),
              base::Time(), base::Time(), /*secure=*/false,
              /*httponly=*/false, net::CookieSameSite::LAX_MODE,
              net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
          "https", false);

  EXPECT_TRUE(access_result.status.HasExactlyExclusionReasonsForTesting(
      {net::CookieInclusionStatus::EXCLUDE_OVERWRITE_HTTP_ONLY}));
  EXPECT_EQ(access_result.effective_same_site,
            net::CookieEffectiveSameSite::LAX_MODE);

  std::vector<net::CanonicalCookie> cookies =
      service_wrapper()->GetAllCookies();
  ASSERT_EQ(1u, cookies.size());
  std::sort(cookies.begin(), cookies.end(), &CompareCanonicalCookies);
  EXPECT_EQ("HttpOnly", cookies[0].Name());
  EXPECT_EQ("F", cookies[0].Value());
}

TEST_F(CookieManagerTest, DeleteEverything) {
  // Set some cookies for the test to play with.
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A", "B", kCookieDomain, "/", base::Time(), base::Time(),
          base::Time(),
          /*secure=*/false, /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "C", "D", "foo_host2", "/with/path", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "Secure", "E", kCookieDomain, "/with/path", base::Time(),
          base::Time(), base::Time(), /*secure=*/true,
          /*httponly=*/false, net::CookieSameSite::NO_RESTRICTION,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "HttpOnly", "F", kCookieDomain, "/with/path",
                             base::Time(), base::Time(), base::Time(),
                             /*secure=*/false,
                             /*httponly=*/true, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));

  mojom::CookieDeletionFilter filter;
  EXPECT_EQ(4u, service_wrapper()->DeleteCookies(filter));

  std::vector<net::CanonicalCookie> cookies =
      service_wrapper()->GetAllCookies();
  ASSERT_EQ(0u, cookies.size());
}

TEST_F(CookieManagerTest, DeleteByTime) {
  base::Time now(base::Time::Now());

  // Create three cookies and delete the middle one.
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A1", "val", kCookieDomain, "/",
          now - base::TimeDelta::FromMinutes(60), base::Time(), base::Time(),
          /*secure=*/false, /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));

  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A2", "val", kCookieDomain, "/",
          now - base::TimeDelta::FromMinutes(120), base::Time(), base::Time(),
          /*secure=*/false, /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));

  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A3", "val", kCookieDomain, "/",
          now - base::TimeDelta::FromMinutes(180), base::Time(), base::Time(),
          /*secure=*/false, /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));

  mojom::CookieDeletionFilter filter;
  filter.created_after_time = now - base::TimeDelta::FromMinutes(150);
  filter.created_before_time = now - base::TimeDelta::FromMinutes(90);
  EXPECT_EQ(1u, service_wrapper()->DeleteCookies(filter));
  std::vector<net::CanonicalCookie> cookies =
      service_wrapper()->GetAllCookies();
  ASSERT_EQ(2u, cookies.size());
  std::sort(cookies.begin(), cookies.end(), &CompareCanonicalCookies);
  EXPECT_EQ("A1", cookies[0].Name());
  EXPECT_EQ("A3", cookies[1].Name());
}

TEST_F(CookieManagerTest, DeleteByExcludingDomains) {
  // Create three cookies and delete the middle one.
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A1", "val", "foo_host1", "/", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));

  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A2", "val", "foo_host2", "/", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));

  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A3", "val", "foo_host3", "/", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));

  mojom::CookieDeletionFilter filter;
  filter.excluding_domains = std::vector<std::string>();
  filter.excluding_domains->push_back("foo_host2");
  EXPECT_EQ(2u, service_wrapper()->DeleteCookies(filter));
  std::vector<net::CanonicalCookie> cookies =
      service_wrapper()->GetAllCookies();
  ASSERT_EQ(1u, cookies.size());
  EXPECT_EQ("A2", cookies[0].Name());
}

TEST_F(CookieManagerTest, DeleteByIncludingDomains) {
  // Create three cookies and delete the middle one.
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A1", "val", "foo_host1", "/", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));

  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A2", "val", "foo_host2", "/", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));

  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A3", "val", "foo_host3", "/", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));

  mojom::CookieDeletionFilter filter;
  filter.including_domains = std::vector<std::string>();
  filter.including_domains->push_back("foo_host1");
  filter.including_domains->push_back("foo_host3");
  EXPECT_EQ(2u, service_wrapper()->DeleteCookies(filter));
  std::vector<net::CanonicalCookie> cookies =
      service_wrapper()->GetAllCookies();
  ASSERT_EQ(1u, cookies.size());
  EXPECT_EQ("A2", cookies[0].Name());
}

// Confirm deletion is based on eTLD+1
TEST_F(CookieManagerTest, DeleteDetails_eTLD) {
  // Two domains on diferent levels of the same eTLD both get deleted.
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A1", "val", "example.com", "/", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A2", "val", "www.example.com", "/", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A3", "val", "www.nonexample.com", "/", base::Time(), base::Time(),
          base::Time(), /*secure=*/false,
          /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));

  mojom::CookieDeletionFilter filter;
  filter.including_domains = std::vector<std::string>();
  filter.including_domains->push_back("example.com");
  EXPECT_EQ(2u, service_wrapper()->DeleteCookies(filter));
  std::vector<net::CanonicalCookie> cookies =
      service_wrapper()->GetAllCookies();
  ASSERT_EQ(1u, cookies.size());
  EXPECT_EQ("A3", cookies[0].Name());
  filter = mojom::CookieDeletionFilter();
  EXPECT_EQ(1u, service_wrapper()->DeleteCookies(filter));

  // Same thing happens on an eTLD+1 which isn't a TLD+1.
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A1", "val", "example.co.uk", "/", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A2", "val", "www.example.co.uk", "/", base::Time(), base::Time(),
          base::Time(), /*secure=*/false,
          /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A3", "val", "www.nonexample.co.uk", "/", base::Time(), base::Time(),
          base::Time(),
          /*secure=*/false, /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));
  filter.including_domains = std::vector<std::string>();
  filter.including_domains->push_back("example.co.uk");
  EXPECT_EQ(2u, service_wrapper()->DeleteCookies(filter));
  cookies = service_wrapper()->GetAllCookies();
  ASSERT_EQ(1u, cookies.size());
  EXPECT_EQ("A3", cookies[0].Name());
  filter = mojom::CookieDeletionFilter();
  EXPECT_EQ(1u, service_wrapper()->DeleteCookies(filter));

  // Deletion of a second level domain that's an eTLD doesn't delete any
  // subdomains.
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A1", "val", "example.co.uk", "/", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A2", "val", "www.example.co.uk", "/", base::Time(), base::Time(),
          base::Time(), /*secure=*/false,
          /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A3", "val", "www.nonexample.co.uk", "/", base::Time(), base::Time(),
          base::Time(),
          /*secure=*/false, /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));
  filter.including_domains = std::vector<std::string>();
  filter.including_domains->push_back("co.uk");
  EXPECT_EQ(0u, service_wrapper()->DeleteCookies(filter));
  cookies = service_wrapper()->GetAllCookies();
  ASSERT_EQ(3u, cookies.size());
  EXPECT_EQ("A1", cookies[0].Name());
  EXPECT_EQ("A2", cookies[1].Name());
  EXPECT_EQ("A3", cookies[2].Name());
}

// Confirm deletion ignores host/domain distinction.
TEST_F(CookieManagerTest, DeleteDetails_HostDomain) {
  // Create four cookies: A host (no leading .) and domain cookie
  // (leading .) for each of two separate domains.  Confirm that the
  // filter deletes both of one domain and leaves the other alone.
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A1", "val", "foo_host.com", "/", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A2", "val", ".foo_host.com", "/", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A3", "val", "bar.host.com", "/", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A4", "val", ".bar.host.com", "/", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));

  mojom::CookieDeletionFilter filter;
  filter.including_domains = std::vector<std::string>();
  filter.including_domains->push_back("foo_host.com");
  EXPECT_EQ(2u, service_wrapper()->DeleteCookies(filter));
  std::vector<net::CanonicalCookie> cookies =
      service_wrapper()->GetAllCookies();
  ASSERT_EQ(2u, cookies.size());
  std::sort(cookies.begin(), cookies.end(), &CompareCanonicalCookies);
  EXPECT_EQ("A3", cookies[0].Name());
  EXPECT_EQ("A4", cookies[1].Name());
}

TEST_F(CookieManagerTest, DeleteDetails_eTLDvsPrivateRegistry) {
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A1", "val", "random.co.uk", "/", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A2", "val", "sub.domain.random.co.uk", "/", base::Time(),
          base::Time(), base::Time(),
          /*secure=*/false, /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A3", "val", "random.com", "/", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A4", "val", "random", "/", base::Time(), base::Time(), base::Time(),
          /*secure=*/false, /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A5", "val", "normal.co.uk", "/", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));

  mojom::CookieDeletionFilter filter;
  filter.including_domains = std::vector<std::string>();
  filter.including_domains->push_back("random.co.uk");
  EXPECT_EQ(2u, service_wrapper()->DeleteCookies(filter));
  std::vector<net::CanonicalCookie> cookies =
      service_wrapper()->GetAllCookies();
  ASSERT_EQ(3u, cookies.size());
  std::sort(cookies.begin(), cookies.end(), &CompareCanonicalCookies);
  EXPECT_EQ("A3", cookies[0].Name());
  EXPECT_EQ("A4", cookies[1].Name());
  EXPECT_EQ("A5", cookies[2].Name());
}

TEST_F(CookieManagerTest, DeleteDetails_PrivateRegistry) {
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A1", "val", "privatedomain", "/", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));

  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          // Will not actually be treated as a private domain as it's under
          // .com.
          "A2", "val", "privatedomain.com", "/", base::Time(), base::Time(),
          base::Time(), /*secure=*/false, /*httponly=*/false,
          net::CookieSameSite::LAX_MODE, net::COOKIE_PRIORITY_MEDIUM,
          /*same_party=*/false),
      "https", true));

  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          // Will not actually be treated as a private domain as it's two
          // level
          "A3", "val", "subdomain.privatedomain", "/", base::Time(),
          base::Time(), base::Time(), /*secure=*/false, /*httponly=*/false,
          net::CookieSameSite::LAX_MODE, net::COOKIE_PRIORITY_MEDIUM,
          /*same_party=*/false),
      "https", true));

  mojom::CookieDeletionFilter filter;
  filter.including_domains = std::vector<std::string>();
  filter.including_domains->push_back("privatedomain");
  EXPECT_EQ(1u, service_wrapper()->DeleteCookies(filter));
  std::vector<net::CanonicalCookie> cookies =
      service_wrapper()->GetAllCookies();
  ASSERT_EQ(2u, cookies.size());
  std::sort(cookies.begin(), cookies.end(), &CompareCanonicalCookies);
  EXPECT_EQ("A2", cookies[0].Name());
  EXPECT_EQ("A3", cookies[1].Name());
}

// Test to probe and make sure the attributes that deletion should ignore
// don't affect the results.
TEST_F(CookieManagerTest, DeleteDetails_IgnoredFields) {
  // Simple deletion filter
  mojom::CookieDeletionFilter filter;
  filter.including_domains = std::vector<std::string>();
  filter.including_domains->push_back("example.com");

  // Set two cookies for each ignored field, one that will be deleted by the
  // above filter, and one that won't, with values unused in other tests
  // for the ignored field.  Secure & httponly are tested in
  // DeleteDetails_Consumer below, and expiration does affect deletion
  // through the persistence distinction.

  // Value
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A01", "RandomValue", "example.com", "/", base::Time(), base::Time(),
          base::Time(),
          /*secure=*/false, /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A02", "RandomValue", "canonical.com", "/", base::Time(),
          base::Time(), base::Time(),
          /*secure=*/false, /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));

  // Path
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A03", "val", "example.com", "/this/is/a/long/path", base::Time(),
          base::Time(), base::Time(),
          /*secure=*/false, /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A04", "val", "canonical.com", "/this/is/a/long/path", base::Time(),
          base::Time(), base::Time(), /*secure=*/false, /*httponly=*/false,
          net::CookieSameSite::LAX_MODE, net::COOKIE_PRIORITY_MEDIUM,
          /*same_party=*/false),
      "https", true));

  // Last_access
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A05", "val", "example.com", "/",
          base::Time::Now() - base::TimeDelta::FromDays(3), base::Time(),
          base::Time::Now() - base::TimeDelta::FromDays(3), /*secure=*/false,
          /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A06", "val", "canonical.com", "/",
          base::Time::Now() - base::TimeDelta::FromDays(3), base::Time(),
          base::Time::Now() - base::TimeDelta::FromDays(3), /*secure=*/false,
          /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));

  // Same_site
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A07", "val", "example.com", "/", base::Time(), base::Time(),
          base::Time(), /*secure=*/false,
          /*httponly=*/false, net::CookieSameSite::STRICT_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A08", "val", "canonical.com", "/", base::Time(), base::Time(),
          base::Time(), /*secure=*/false,
          /*httponly=*/false, net::CookieSameSite::STRICT_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));

  // Priority
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A09", "val", "example.com", "/", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_HIGH, /*same_party=*/false),
                         "https", true));
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A10", "val", "canonical.com", "/", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_HIGH, /*same_party=*/false),
                         "https", true));

  // Use the filter and make sure the result is the expected set.
  EXPECT_EQ(5u, service_wrapper()->DeleteCookies(filter));
  std::vector<net::CanonicalCookie> cookies =
      service_wrapper()->GetAllCookies();
  ASSERT_EQ(5u, cookies.size());
  std::sort(cookies.begin(), cookies.end(), &CompareCanonicalCookies);
  EXPECT_EQ("A02", cookies[0].Name());
  EXPECT_EQ("A04", cookies[1].Name());
  EXPECT_EQ("A06", cookies[2].Name());
  EXPECT_EQ("A08", cookies[3].Name());
  EXPECT_EQ("A10", cookies[4].Name());
}

// A set of tests specified by the only consumer of this interface
// (BrowsingDataFilterBuilderImpl).
TEST_F(CookieManagerTest, DeleteDetails_Consumer) {
  const char* filter_domains[] = {
      "google.com",

      // sp.nom.br is an eTLD, so this is a regular valid registrable domain,
      // just like google.com.
      "website.sp.nom.br",

      // This domain will also not be found in registries, and since it has only
      // one component, it will not be recognized as a valid registrable domain.
      "fileserver",

      // This domain will not be found in registries. It will be assumed that
      // it belongs to an unknown registry, and since it has two components,
      // they will be treated as the second level domain and TLD. Most
      // importantly, it will NOT be treated as a subdomain of "fileserver".
      "second-level-domain.fileserver",

      // IP addresses are supported.
      "192.168.1.1",
  };
  mojom::CookieDeletionFilter test_filter;
  test_filter.including_domains = std::vector<std::string>();
  for (int i = 0; i < static_cast<int>(base::size(filter_domains)); ++i)
    test_filter.including_domains->push_back(filter_domains[i]);

  struct TestCase {
    std::string domain;
    std::string path;
    bool expect_delete;
  } test_cases[] = {
      // We match any URL on the specified domains.
      {"www.google.com", "/foo/bar", true},
      {"www.sub.google.com", "/foo/bar", true},
      {"sub.google.com", "/", true},
      {"www.sub.google.com", "/foo/bar", true},
      {"website.sp.nom.br", "/", true},
      {"www.website.sp.nom.br", "/", true},
      {"192.168.1.1", "/", true},

      // Internal hostnames do not have subdomains.
      {"fileserver", "/", true},
      {"fileserver", "/foo/bar", true},
      {"website.fileserver", "/foo/bar", false},

      // This is a valid registrable domain with the TLD "fileserver", which
      // is unrelated to the internal hostname "fileserver".
      {"second-level-domain.fileserver", "/foo", true},
      {"www.second-level-domain.fileserver", "/index.html", true},

      // Different domains.
      {"www.youtube.com", "/", false},
      {"www.google.net", "/", false},
      {"192.168.1.2", "/", false},

      // Check both a bare eTLD.
      {"sp.nom.br", "/", false},
  };

  mojom::CookieDeletionFilter clear_filter;
  for (int i = 0; i < static_cast<int>(base::size(test_cases)); ++i) {
    TestCase& test_case(test_cases[i]);

    // Clear store.
    service_wrapper()->DeleteCookies(clear_filter);

    // IP addresses and internal hostnames can only be host cookies.
    bool exclude_domain_cookie =
        (GURL("http://" + test_case.domain).HostIsIPAddress() ||
         test_case.domain.find(".") == std::string::npos);

    // Standard cookie
    EXPECT_TRUE(SetCanonicalCookie(
        *net::CanonicalCookie::CreateUnsafeCookieForTesting(
            "A1", "val", test_cases[i].domain, test_cases[i].path, base::Time(),
            base::Time(), base::Time(), /*secure=*/false, /*httponly=*/false,
            net::CookieSameSite::LAX_MODE, net::COOKIE_PRIORITY_MEDIUM,
            /*same_party=*/false),
        "https", true));

    if (!exclude_domain_cookie) {
      // Host cookie
      EXPECT_TRUE(SetCanonicalCookie(
          *net::CanonicalCookie::CreateUnsafeCookieForTesting(
              "A2", "val", "." + test_cases[i].domain, test_cases[i].path,
              base::Time(), base::Time(), base::Time(), /*secure=*/false,
              /*httponly=*/false, net::CookieSameSite::LAX_MODE,
              net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
          "https", true));
    }

    // Httponly cookie
    EXPECT_TRUE(SetCanonicalCookie(
        *net::CanonicalCookie::CreateUnsafeCookieForTesting(
            "A3", "val", test_cases[i].domain, test_cases[i].path, base::Time(),
            base::Time(), base::Time(), /*secure=*/false, /*httponly=*/true,
            net::CookieSameSite::LAX_MODE, net::COOKIE_PRIORITY_MEDIUM,
            /*same_party=*/false),
        "https", true));

    // Httponly and secure cookie
    EXPECT_TRUE(SetCanonicalCookie(
        *net::CanonicalCookie::CreateUnsafeCookieForTesting(
            "A4", "val", test_cases[i].domain, test_cases[i].path, base::Time(),
            base::Time(), base::Time(), /*secure=*/false, /*httponly=*/true,
            net::CookieSameSite::LAX_MODE, net::COOKIE_PRIORITY_MEDIUM,
            /*same_party=*/false),
        "https", true));

    const uint32_t number_cookies = exclude_domain_cookie ? 3u : 4u;
    EXPECT_EQ(number_cookies, service_wrapper()->GetAllCookies().size());
    EXPECT_EQ(test_cases[i].expect_delete ? number_cookies : 0u,
              service_wrapper()->DeleteCookies(test_filter))
        << "Case " << i << " domain " << test_cases[i].domain << " path "
        << test_cases[i].path << " expect "
        << (test_cases[i].expect_delete ? "delete" : "keep");
    EXPECT_EQ(test_cases[i].expect_delete ? 0u : number_cookies,
              service_wrapper()->GetAllCookies().size());
  }
}

TEST_F(CookieManagerTest, DeleteByName) {
  // Create cookies with varying (name, host)
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A1", "val", kCookieDomain, "/", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true /*modify_httponly*/));

  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A1", "val", "bar_host", "/", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true /*modify_httponly*/));

  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A2", "val", kCookieDomain, "/", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true /*modify_httponly*/));

  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A3", "val", "bar_host", "/", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true /*modify_httponly*/));

  mojom::CookieDeletionFilter filter;
  filter.cookie_name = std::string("A1");
  EXPECT_EQ(2u, service_wrapper()->DeleteCookies(filter));

  std::vector<net::CanonicalCookie> cookies =
      service_wrapper()->GetAllCookies();
  ASSERT_EQ(2u, cookies.size());
  std::sort(cookies.begin(), cookies.end(), &CompareCanonicalCookies);
  EXPECT_EQ("A2", cookies[0].Name());
  EXPECT_EQ("A3", cookies[1].Name());
}

TEST_F(CookieManagerTest, DeleteByURL) {
  GURL filter_url("http://www.example.com/path");

  // Cookie that shouldn't be deleted because it's secure.
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A01", "val", "www.example.com", "/path",
                             base::Time(), base::Time(), base::Time(),
                             /*secure=*/true, /*httponly=*/false,
                             net::CookieSameSite::NO_RESTRICTION,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true /*modify_httponly*/));

  // Cookie that should not be deleted because it's a host cookie in a
  // subdomain that doesn't exactly match the passed URL.
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A02", "val", "sub.www.example.com", "/path", base::Time(),
          base::Time(), base::Time(),
          /*secure=*/false, /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true /*modify_httponly*/));

  // Cookie that shouldn't be deleted because the path doesn't match.
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A03", "val", "www.example.com", "/otherpath", base::Time(),
          base::Time(), base::Time(),
          /*secure=*/false, /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true /*modify_httponly*/));

  // Cookie that shouldn't be deleted because the path is more specific
  // than the URL.
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A04", "val", "www.example.com", "/path/path2", base::Time(),
          base::Time(), base::Time(),
          /*secure=*/false, /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true /*modify_httponly*/));

  // Cookie that shouldn't be deleted because it's at a host cookie domain that
  // doesn't exactly match the url's host.
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A05", "val", "example.com", "/path", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true /*modify_httponly*/));

  // Cookie that should not be deleted because it's not a host cookie and
  // has a domain that's more specific than the URL
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A06", "val", ".sub.www.example.com", "/path", base::Time(),
          base::Time(), base::Time(),
          /*secure=*/false, /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true /*modify_httponly*/));

  // Cookie that should be deleted because it's not a host cookie and has a
  // domain that matches the URL
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A07", "val", ".www.example.com", "/path", base::Time(), base::Time(),
          base::Time(),
          /*secure=*/false, /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true /*modify_httponly*/));

  // Cookie that should be deleted because it's not a host cookie and has a
  // domain that domain matches the URL.
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A08", "val", ".example.com", "/path", base::Time(), base::Time(),
          base::Time(), /*secure=*/false,
          /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true /*modify_httponly*/));

  // Cookie that should be deleted because it matches exactly.
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A09", "val", "www.example.com", "/path", base::Time(), base::Time(),
          base::Time(),
          /*secure=*/false, /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true /*modify_httponly*/));

  // Cookie that should be deleted because it applies to a larger set
  // of paths than the URL path.
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A10", "val", "www.example.com", "/", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true /*modify_httponly*/));

  mojom::CookieDeletionFilter filter;
  filter.url = filter_url;
  EXPECT_EQ(4u, service_wrapper()->DeleteCookies(filter));

  std::vector<net::CanonicalCookie> cookies =
      service_wrapper()->GetAllCookies();
  ASSERT_EQ(6u, cookies.size()) << DumpAllCookies();
  std::sort(cookies.begin(), cookies.end(), &CompareCanonicalCookies);
  EXPECT_EQ("A01", cookies[0].Name());
  EXPECT_EQ("A02", cookies[1].Name());
  EXPECT_EQ("A03", cookies[2].Name());
  EXPECT_EQ("A04", cookies[3].Name());
  EXPECT_EQ("A05", cookies[4].Name());
  EXPECT_EQ("A06", cookies[5].Name());
}

TEST_F(CookieManagerTest, DeleteBySessionStatus) {
  base::Time now(base::Time::Now());

  // Create three cookies and delete the middle one.
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A1", "val", kCookieDomain, "/", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));

  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A2", "val", kCookieDomain, "/", base::Time(),
          now + base::TimeDelta::FromDays(1), base::Time(),
          /*secure=*/false, /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));

  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A3", "val", kCookieDomain, "/", base::Time(),
                             base::Time(), base::Time(), /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));

  mojom::CookieDeletionFilter filter;
  filter.session_control =
      mojom::CookieDeletionSessionControl::PERSISTENT_COOKIES;
  EXPECT_EQ(1u, service_wrapper()->DeleteCookies(filter));
  std::vector<net::CanonicalCookie> cookies =
      service_wrapper()->GetAllCookies();
  ASSERT_EQ(2u, cookies.size());
  std::sort(cookies.begin(), cookies.end(), &CompareCanonicalCookies);
  EXPECT_EQ("A1", cookies[0].Name());
  EXPECT_EQ("A3", cookies[1].Name());
}

TEST_F(CookieManagerTest, DeleteByAll) {
  base::Time now(base::Time::Now());

  // Add a lot of cookies, only one of which will be deleted by the filter.
  // Filter will be:
  //    * Between two and four days ago.
  //    * Including domains: no.com and nope.com
  //    * Excluding domains: no.com and yes.com (excluding wins on no.com
  //      because of ANDing)
  //    * Matching a specific URL.
  //    * Persistent cookies.
  // The archetypal cookie (which will be deleted) will satisfy all of
  // these filters (2 days old, nope.com, persistent).
  // Each of the other four cookies will vary in a way that will take it out
  // of being deleted by one of the filter.

  // Cookie name is not included as a filter because the cookies are made
  // unique by name.

  mojom::CookieDeletionFilter filter;
  filter.created_after_time = now - base::TimeDelta::FromDays(4);
  filter.created_before_time = now - base::TimeDelta::FromDays(2);
  filter.including_domains = std::vector<std::string>();
  filter.including_domains->push_back("no.com");
  filter.including_domains->push_back("nope.com");
  filter.excluding_domains = std::vector<std::string>();
  filter.excluding_domains->push_back("no.com");
  filter.excluding_domains->push_back("yes.com");
  filter.url = GURL("http://nope.com/path");
  filter.session_control =
      mojom::CookieDeletionSessionControl::PERSISTENT_COOKIES;

  // Archetypal cookie:
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A1", "val0", "nope.com", "/path", now - base::TimeDelta::FromDays(3),
          now + base::TimeDelta::FromDays(3), base::Time(), /*secure=*/false,
          /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));

  // Too old cookie.
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A2", "val1", "nope.com", "/path", now - base::TimeDelta::FromDays(5),
          now + base::TimeDelta::FromDays(3), base::Time(), /*secure=*/false,
          /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));

  // Too young cookie.
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A3", "val2", "nope.com", "/path", now - base::TimeDelta::FromDays(1),
          now + base::TimeDelta::FromDays(3), base::Time(), /*secure=*/false,
          /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));

  // Not in domains_and_ips_to_delete.
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A4", "val3", "other.com", "/path",
                             now - base::TimeDelta::FromDays(3),
                             now + base::TimeDelta::FromDays(3), base::Time(),
                             /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));

  // In domains_and_ips_to_ignore.
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A5", "val4", "no.com", "/path", now - base::TimeDelta::FromDays(3),
          now + base::TimeDelta::FromDays(3), base::Time(), /*secure=*/false,
          /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));

  // Doesn't match URL (by path).
  EXPECT_TRUE(
      SetCanonicalCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
                             "A6", "val6", "nope.com", "/otherpath",
                             now - base::TimeDelta::FromDays(3),
                             now + base::TimeDelta::FromDays(3), base::Time(),
                             /*secure=*/false,
                             /*httponly=*/false, net::CookieSameSite::LAX_MODE,
                             net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
                         "https", true));

  // Session
  EXPECT_TRUE(SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "A7", "val7", "nope.com", "/path", now - base::TimeDelta::FromDays(3),
          base::Time(), base::Time(), /*secure=*/false, /*httponly=*/false,
          net::CookieSameSite::LAX_MODE, net::COOKIE_PRIORITY_MEDIUM,
          /*same_party=*/false),
      "https", true));

  EXPECT_EQ(1u, service_wrapper()->DeleteCookies(filter));
  std::vector<net::CanonicalCookie> cookies =
      service_wrapper()->GetAllCookies();
  ASSERT_EQ(6u, cookies.size());
  std::sort(cookies.begin(), cookies.end(), &CompareCanonicalCookies);
  EXPECT_EQ("A2", cookies[0].Name());
  EXPECT_EQ("A3", cookies[1].Name());
  EXPECT_EQ("A4", cookies[2].Name());
  EXPECT_EQ("A5", cookies[3].Name());
  EXPECT_EQ("A6", cookies[4].Name());
  EXPECT_EQ("A7", cookies[5].Name());
}

// Receives and records notifications from the mojom::CookieManager.
class CookieChangeListener : public mojom::CookieChangeListener {
 public:
  CookieChangeListener(
      mojo::PendingReceiver<mojom::CookieChangeListener> receiver)
      : run_loop_(nullptr), receiver_(this, std::move(receiver)) {}

  // Blocks until the listener observes a cookie change.
  void WaitForChange() {
    if (!observed_changes_.empty())
      return;
    base::RunLoop loop;
    run_loop_ = &loop;
    loop.Run();
    run_loop_ = nullptr;
  }

  void ClearObservedChanges() { observed_changes_.clear(); }

  const std::vector<net::CookieChangeInfo>& observed_changes() const {
    return observed_changes_;
  }

  // mojom::CookieChangeListener
  void OnCookieChange(const net::CookieChangeInfo& change) override {
    observed_changes_.push_back(change);
    if (run_loop_)
      run_loop_->Quit();
  }

 private:
  std::vector<net::CookieChangeInfo> observed_changes_;

  // Loop to signal on receiving a notification if not null.
  base::RunLoop* run_loop_;

  mojo::Receiver<mojom::CookieChangeListener> receiver_;
};

TEST_F(CookieManagerTest, AddCookieChangeListener) {
  const GURL listener_url("http://www.testing.com/pathele");
  const std::string listener_url_host("www.testing.com");
  const std::string listener_url_domain("testing.com");
  const std::string listener_cookie_name("Cookie_Name");
  ASSERT_EQ(listener_url.host(), listener_url_host);

  mojo::PendingRemote<mojom::CookieChangeListener> listener_remote;
  CookieChangeListener listener(
      listener_remote.InitWithNewPipeAndPassReceiver());

  cookie_service_client()->AddCookieChangeListener(
      listener_url, listener_cookie_name, std::move(listener_remote));

  EXPECT_EQ(0u, listener.observed_changes().size());

  // Set a cookie that doesn't match the above notification request in name
  // and confirm it doesn't produce a notification.
  service_wrapper()->SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "DifferentName", "val", listener_url_host, "/", base::Time(),
          base::Time(), base::Time(),
          /*secure=*/false,
          /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0u, listener.observed_changes().size());

  // Set a cookie that doesn't match the above notification request in url
  // and confirm it doesn't produce a notification.
  service_wrapper()->SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          listener_cookie_name, "val", "www.other.host", "/", base::Time(),
          base::Time(), base::Time(),
          /*secure=*/false,
          /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true);

  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0u, listener.observed_changes().size());

  // Insert a cookie that does match.
  service_wrapper()->SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          listener_cookie_name, "val", listener_url_host, "/", base::Time(),
          base::Time(), base::Time(),
          /*secure=*/false,
          /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true);

  // Expect asynchrony
  EXPECT_EQ(0u, listener.observed_changes().size());

  // Expect to observe a cookie change.
  listener.WaitForChange();
  std::vector<net::CookieChangeInfo> observed_changes =
      listener.observed_changes();
  ASSERT_EQ(1u, observed_changes.size());
  EXPECT_EQ(listener_cookie_name, observed_changes[0].cookie.Name());
  EXPECT_EQ(listener_url_host, observed_changes[0].cookie.Domain());
  EXPECT_EQ(net::CookieChangeCause::INSERTED, observed_changes[0].cause);
  listener.ClearObservedChanges();

  // Delete all cookies matching the domain.  This includes one for which
  // a notification will be generated, and one for which a notification
  // will not be generated.
  mojom::CookieDeletionFilter filter;
  filter.including_domains = std::vector<std::string>();
  filter.including_domains->push_back(listener_url_domain);
  // If this test fails, it may indicate a problem which will lead to
  // no notifications being generated and the test hanging, so assert.
  ASSERT_EQ(2u, service_wrapper()->DeleteCookies(filter));

  // The notification may already have arrived, or it may arrive in the future.
  listener.WaitForChange();
  observed_changes = listener.observed_changes();
  ASSERT_EQ(1u, observed_changes.size());
  EXPECT_EQ(listener_cookie_name, observed_changes[0].cookie.Name());
  EXPECT_EQ(listener_url_host, observed_changes[0].cookie.Domain());
  EXPECT_EQ(net::CookieChangeCause::EXPLICIT, observed_changes[0].cause);
}

TEST_F(CookieManagerTest, AddGlobalChangeListener) {
  const std::string kExampleHost = "www.example.com";
  const std::string kThisHost = "www.this.com";
  const std::string kThisETLDP1 = "this.com";
  const std::string kThatHost = "www.that.com";

  mojo::PendingRemote<mojom::CookieChangeListener> listener_remote;
  CookieChangeListener listener(
      listener_remote.InitWithNewPipeAndPassReceiver());

  cookie_service_client()->AddGlobalChangeListener(std::move(listener_remote));

  EXPECT_EQ(0u, listener.observed_changes().size());

  // Confirm the right change is observed after setting a cookie.
  service_wrapper()->SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "Thing1", "val", kExampleHost, "/", base::Time(), base::Time(),
          base::Time(), /*secure=*/false,
          /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true);

  // Expect asynchrony
  EXPECT_EQ(0u, listener.observed_changes().size());

  base::RunLoop().RunUntilIdle();
  std::vector<net::CookieChangeInfo> observed_changes =
      listener.observed_changes();
  ASSERT_EQ(1u, observed_changes.size());
  EXPECT_EQ("Thing1", observed_changes[0].cookie.Name());
  EXPECT_EQ("val", observed_changes[0].cookie.Value());
  EXPECT_EQ(kExampleHost, observed_changes[0].cookie.Domain());
  EXPECT_EQ("/", observed_changes[0].cookie.Path());
  EXPECT_EQ(net::CookieChangeCause::INSERTED, observed_changes[0].cause);
  listener.ClearObservedChanges();

  // Set two cookies in a row on different domains and confirm they are both
  // signalled.
  service_wrapper()->SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "Thing1", "val", kThisHost, "/", base::Time(), base::Time(),
          base::Time(), /*secure=*/false,
          /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true);
  service_wrapper()->SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "Thing2", "val", kThatHost, "/", base::Time(), base::Time(),
          base::Time(), /*secure=*/false,
          /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true);

  base::RunLoop().RunUntilIdle();
  observed_changes = listener.observed_changes();
  ASSERT_EQ(2u, observed_changes.size());
  EXPECT_EQ("Thing1", observed_changes[0].cookie.Name());
  EXPECT_EQ(net::CookieChangeCause::INSERTED, observed_changes[0].cause);
  EXPECT_EQ("Thing2", observed_changes[1].cookie.Name());
  EXPECT_EQ(net::CookieChangeCause::INSERTED, observed_changes[1].cause);
  listener.ClearObservedChanges();

  // Delete cookies matching one domain; should produce one notification.
  mojom::CookieDeletionFilter filter;
  filter.including_domains = std::vector<std::string>();
  filter.including_domains->push_back(kThisETLDP1);
  // If this test fails, it may indicate a problem which will lead to
  // no notifications being generated and the test hanging, so assert.
  ASSERT_EQ(1u, service_wrapper()->DeleteCookies(filter));

  // The notification may already have arrived, or it may arrive in the future.
  listener.WaitForChange();
  observed_changes = listener.observed_changes();
  ASSERT_EQ(1u, observed_changes.size());
  EXPECT_EQ("Thing1", observed_changes[0].cookie.Name());
  EXPECT_EQ(kThisHost, observed_changes[0].cookie.Domain());
  EXPECT_EQ(net::CookieChangeCause::EXPLICIT, observed_changes[0].cause);
}

// Confirm the service operates properly if a returned notification interface
// is destroyed.
TEST_F(CookieManagerTest, ListenerDestroyed) {
  // Create two identical listeners.
  const GURL listener_url("http://www.testing.com/pathele");
  const std::string listener_url_host("www.testing.com");
  ASSERT_EQ(listener_url.host(), listener_url_host);
  const std::string listener_cookie_name("Cookie_Name");

  mojo::PendingRemote<mojom::CookieChangeListener> listener1_remote;
  auto listener1 = std::make_unique<CookieChangeListener>(
      listener1_remote.InitWithNewPipeAndPassReceiver());
  cookie_service_client()->AddCookieChangeListener(
      listener_url, listener_cookie_name, std::move(listener1_remote));

  mojo::PendingRemote<mojom::CookieChangeListener> listener2_remote;
  auto listener2 = std::make_unique<CookieChangeListener>(
      listener2_remote.InitWithNewPipeAndPassReceiver());
  cookie_service_client()->AddCookieChangeListener(
      listener_url, listener_cookie_name, std::move(listener2_remote));

  // Add a cookie and receive a notification on both interfaces.
  service_wrapper()->SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          listener_cookie_name, "val", listener_url_host, "/", base::Time(),
          base::Time(), base::Time(),
          /*secure=*/false,
          /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true);

  EXPECT_EQ(0u, listener1->observed_changes().size());
  EXPECT_EQ(0u, listener2->observed_changes().size());

  listener1->WaitForChange();
  EXPECT_EQ(1u, listener1->observed_changes().size());
  listener1->ClearObservedChanges();
  listener2->WaitForChange();
  EXPECT_EQ(1u, listener2->observed_changes().size());
  listener2->ClearObservedChanges();
  EXPECT_EQ(2u, service()->GetListenersRegisteredForTesting());

  // Destroy the first listener.
  listener1.reset();

  // Confirm the second interface can still receive notifications.
  mojom::CookieDeletionFilter filter;
  EXPECT_EQ(1u, service_wrapper()->DeleteCookies(filter));

  listener2->WaitForChange();
  EXPECT_EQ(1u, listener2->observed_changes().size());

  EXPECT_EQ(1u, service()->GetListenersRegisteredForTesting());
}

// Confirm we get a connection error notification if the service dies.
TEST_F(CookieManagerTest, ServiceDestructVisible) {
  EXPECT_FALSE(connection_error_seen());
  NukeService();
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(connection_error_seen());
}

// Test service cloning.  Also confirm that the service notices if a client
// dies.
TEST_F(CookieManagerTest, CloningAndClientDestructVisible) {
  EXPECT_EQ(1u, service()->GetClientsBoundForTesting());

  // Clone the interface.
  mojo::Remote<mojom::CookieManager> new_remote;
  cookie_service_client()->CloneInterface(
      new_remote.BindNewPipeAndPassReceiver());

  SynchronousCookieManager new_wrapper(new_remote.get());

  // Set a cookie on the new interface and make sure it's visible on the
  // old one.
  EXPECT_TRUE(new_wrapper.SetCanonicalCookie(
      *net::CanonicalCookie::CreateUnsafeCookieForTesting(
          "X", "Y", "www.other.host", "/", base::Time(), base::Time(),
          base::Time(), /*secure=*/false,
          /*httponly=*/false, net::CookieSameSite::LAX_MODE,
          net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false),
      "https", true));

  std::vector<net::CanonicalCookie> cookies = service_wrapper()->GetCookieList(
      GURL("http://www.other.host/"), net::CookieOptions::MakeAllInclusive());
  ASSERT_EQ(1u, cookies.size());
  EXPECT_EQ("X", cookies[0].Name());
  EXPECT_EQ("Y", cookies[0].Value());

  // After a synchronous round trip through the new client pointer, it
  // should be reflected in the bindings seen on the server.
  EXPECT_EQ(2u, service()->GetClientsBoundForTesting());

  new_remote.reset();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, service()->GetClientsBoundForTesting());
}

TEST_F(CookieManagerTest, BlockThirdPartyCookies) {
  const GURL kThisURL = GURL("http://www.this.com");
  const GURL kThatURL = GURL("http://www.that.com");
  EXPECT_TRUE(service()->cookie_settings().IsFullCookieAccessAllowed(kThisURL,
                                                                     kThatURL));

  // Set block third party cookies to true, cookie should now be blocked.
  cookie_service_client()->BlockThirdPartyCookies(true);
  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(service()->cookie_settings().IsFullCookieAccessAllowed(
      kThisURL, kThatURL));
  EXPECT_TRUE(service()->cookie_settings().IsFullCookieAccessAllowed(kThisURL,
                                                                     kThisURL));

  // Set block third party cookies back to false, cookie should no longer be
  // blocked.
  cookie_service_client()->BlockThirdPartyCookies(false);
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(service()->cookie_settings().IsFullCookieAccessAllowed(kThisURL,
                                                                     kThatURL));
}

// A test class having cookie store with a persistent backing store.
class FlushableCookieManagerTest : public CookieManagerTest {
 public:
  FlushableCookieManagerTest()
      : store_(base::MakeRefCounted<net::FlushablePersistentStore>()) {
    InitializeCookieService(store_, nullptr);
  }

  ~FlushableCookieManagerTest() override {}

  net::FlushablePersistentStore* store() { return store_.get(); }

 private:
  scoped_refptr<net::FlushablePersistentStore> store_;
};

// Tests that the cookie's backing store (if available) gets flush to disk.
TEST_F(FlushableCookieManagerTest, FlushCookieStore) {
  ASSERT_EQ(0, store()->flush_count());
  ASSERT_EQ(0U, service_wrapper()->callback_count());

  // Before initialization, FlushCookieStore() should just run the callback.
  service_wrapper()->FlushCookieStore();

  ASSERT_EQ(0, store()->flush_count());
  ASSERT_EQ(1U, service_wrapper()->callback_count());

  // After initialization, FlushCookieStore() should delegate to the store.
  service_wrapper()->GetAllCookies();  // force init
  service_wrapper()->FlushCookieStore();

  ASSERT_EQ(1, store()->flush_count());
  ASSERT_EQ(2U, service_wrapper()->callback_count());
}

TEST_F(FlushableCookieManagerTest, DeletionFilterToInfo) {
  mojom::CookieDeletionFilterPtr filter_ptr =
      mojom::CookieDeletionFilter::New();

  // First test the default values.
  CookieDeletionInfo delete_info = DeletionFilterToInfo(std::move(filter_ptr));
  EXPECT_TRUE(delete_info.creation_range.start().is_null());
  EXPECT_TRUE(delete_info.creation_range.end().is_null());
  EXPECT_EQ(CookieDeletionInfo::SessionControl::IGNORE_CONTROL,
            delete_info.session_control);
  EXPECT_FALSE(delete_info.host.has_value());
  EXPECT_FALSE(delete_info.name.has_value());
  EXPECT_FALSE(delete_info.url.has_value());
  EXPECT_TRUE(delete_info.domains_and_ips_to_delete.empty());
  EXPECT_TRUE(delete_info.domains_and_ips_to_ignore.empty());
  EXPECT_FALSE(delete_info.value_for_testing.has_value());

  // Then test all with non-default values.
  const double kTestStartEpoch = 1000;
  const double kTestEndEpoch = 10000000;
  filter_ptr = mojom::CookieDeletionFilter::New();
  filter_ptr->created_after_time = base::Time::FromDoubleT(kTestStartEpoch);
  filter_ptr->created_before_time = base::Time::FromDoubleT(kTestEndEpoch);
  filter_ptr->cookie_name = "cookie-name";
  filter_ptr->host_name = "cookie-host";
  filter_ptr->including_domains =
      std::vector<std::string>({"first.com", "second.com", "third.com"});
  filter_ptr->excluding_domains =
      std::vector<std::string>({"ten.com", "twelve.com"});
  filter_ptr->url = GURL("https://www.example.com");
  filter_ptr->session_control =
      mojom::CookieDeletionSessionControl::PERSISTENT_COOKIES;

  delete_info = DeletionFilterToInfo(std::move(filter_ptr));
  EXPECT_EQ(base::Time::FromDoubleT(kTestStartEpoch),
            delete_info.creation_range.start());
  EXPECT_EQ(base::Time::FromDoubleT(kTestEndEpoch),
            delete_info.creation_range.end());

  EXPECT_EQ(CookieDeletionInfo::SessionControl::PERSISTENT_COOKIES,
            delete_info.session_control);
  EXPECT_EQ("cookie-name", delete_info.name.value());
  EXPECT_EQ("cookie-host", delete_info.host.value());
  EXPECT_EQ(GURL("https://www.example.com"), delete_info.url.value());
  EXPECT_EQ(3u, delete_info.domains_and_ips_to_delete.size());
  EXPECT_NE(delete_info.domains_and_ips_to_delete.find("first.com"),
            delete_info.domains_and_ips_to_delete.end());
  EXPECT_NE(delete_info.domains_and_ips_to_delete.find("second.com"),
            delete_info.domains_and_ips_to_delete.end());
  EXPECT_NE(delete_info.domains_and_ips_to_delete.find("third.com"),
            delete_info.domains_and_ips_to_delete.end());
  EXPECT_EQ(2u, delete_info.domains_and_ips_to_ignore.size());
  EXPECT_NE(delete_info.domains_and_ips_to_ignore.find("ten.com"),
            delete_info.domains_and_ips_to_ignore.end());
  EXPECT_NE(delete_info.domains_and_ips_to_ignore.find("twelve.com"),
            delete_info.domains_and_ips_to_ignore.end());
  EXPECT_FALSE(delete_info.value_for_testing.has_value());
}

// A test class having cookie store with a persistent backing store. The cookie
// store can be destroyed and recreated by calling InitializeCookieService
// again.
class SessionCleanupCookieManagerTest : public CookieManagerTest {
 public:
  ~SessionCleanupCookieManagerTest() override {}

 protected:
  void SetUp() override {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    auto store = CreateCookieStore();
    InitializeCookieService(store, store);
  }

  scoped_refptr<SessionCleanupCookieStore> CreateCookieStore() {
    auto sqlite_store = base::MakeRefCounted<net::SQLitePersistentCookieStore>(
        temp_dir_.GetPath().Append(kTestCookiesFilename),
        task_environment_.GetMainThreadTaskRunner(), background_task_runner_,
        true, nullptr);
    return base::MakeRefCounted<SessionCleanupCookieStore>(sqlite_store.get());
  }

  net::CanonicalCookie CreateCookie() { return CreateCookie(kCookieDomain); }

  net::CanonicalCookie CreateCookie(const std::string& domain) {
    base::Time t = base::Time::Now();
    return *net::CanonicalCookie::CreateUnsafeCookieForTesting(
        "A", "B", domain, "/", t, t + base::TimeDelta::FromDays(1),
        base::Time(),
        /*secure=*/false, /*httponly=*/false, net::CookieSameSite::LAX_MODE,
        net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false);
  }

 private:
  const scoped_refptr<base::SequencedTaskRunner> background_task_runner_ =
      base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()});
};

TEST_F(SessionCleanupCookieManagerTest, PersistSessionCookies) {
  EXPECT_TRUE(SetCanonicalCookie(CreateCookie(), "https", true));

  EXPECT_EQ(1u, service_wrapper()->GetAllCookies().size());

  // Re-create the cookie store to make sure cookies are persisted.
  auto store = CreateCookieStore();
  InitializeCookieService(store, store);

  EXPECT_EQ(1u, service_wrapper()->GetAllCookies().size());
}

TEST_F(SessionCleanupCookieManagerTest, DeleteSessionCookiesOnShutdown) {
  EXPECT_TRUE(SetCanonicalCookie(CreateCookie(), "https", true));

  EXPECT_EQ(1u, service_wrapper()->GetAllCookies().size());

  cookie_service_client()->SetContentSettings(
      {CreateSetting(CONTENT_SETTING_SESSION_ONLY, kCookieURL)});
  base::RunLoop().RunUntilIdle();

  auto store = CreateCookieStore();
  InitializeCookieService(store, store);

  EXPECT_EQ(0u, service_wrapper()->GetAllCookies().size());
}

TEST_F(SessionCleanupCookieManagerTest, SettingMustMatchDomainOnShutdown) {
  EXPECT_TRUE(SetCanonicalCookie(CreateCookie(), "https", true));

  EXPECT_EQ(1u, service_wrapper()->GetAllCookies().size());

  cookie_service_client()->SetContentSettings(
      {CreateSetting(CONTENT_SETTING_SESSION_ONLY, "http://other.com")});
  base::RunLoop().RunUntilIdle();

  auto store = CreateCookieStore();
  InitializeCookieService(store, store);

  EXPECT_EQ(1u, service_wrapper()->GetAllCookies().size());
}

TEST_F(SessionCleanupCookieManagerTest, DeleteSessionOnlyCookies) {
  EXPECT_TRUE(SetCanonicalCookie(CreateCookie(), "https", true));

  EXPECT_EQ(1u, service_wrapper()->GetAllCookies().size());

  cookie_service_client()->SetContentSettings(
      {CreateSetting(CONTENT_SETTING_SESSION_ONLY, kCookieURL)});
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(1u, service_wrapper()->DeleteSessionOnlyCookies());
  EXPECT_EQ(0u, service_wrapper()->GetAllCookies().size());
}

TEST_F(SessionCleanupCookieManagerTest, SettingMustMatchDomain) {
  EXPECT_TRUE(SetCanonicalCookie(CreateCookie(), "https", true));

  EXPECT_EQ(1u, service_wrapper()->GetAllCookies().size());

  cookie_service_client()->SetContentSettings(
      {CreateSetting(CONTENT_SETTING_SESSION_ONLY, "http://other.com")});
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(0u, service_wrapper()->DeleteSessionOnlyCookies());
  EXPECT_EQ(1u, service_wrapper()->GetAllCookies().size());

  cookie_service_client()->SetContentSettings(
      {CreateSetting(CONTENT_SETTING_SESSION_ONLY, kCookieURL)});
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(1u, service_wrapper()->DeleteSessionOnlyCookies());
  EXPECT_EQ(0u, service_wrapper()->GetAllCookies().size());
}

TEST_F(SessionCleanupCookieManagerTest, FirstSettingTakesPrecedence) {
  EXPECT_TRUE(SetCanonicalCookie(CreateCookie(), "https", true));

  EXPECT_EQ(1u, service_wrapper()->GetAllCookies().size());

  // If a rule with ALLOW is before a SESSION_ONLY rule, the cookie should not
  // be deleted.
  cookie_service_client()->SetContentSettings(
      {CreateSetting(CONTENT_SETTING_ALLOW, kCookieURL),
       CreateSetting(CONTENT_SETTING_SESSION_ONLY, kCookieURL)});
  base::RunLoop().RunUntilIdle();

  auto store = CreateCookieStore();
  InitializeCookieService(store, store);

  EXPECT_EQ(1u, service_wrapper()->GetAllCookies().size());
}

TEST_F(SessionCleanupCookieManagerTest, ForceKeepSessionState) {
  EXPECT_TRUE(SetCanonicalCookie(CreateCookie(), "https", true));

  EXPECT_EQ(1u, service_wrapper()->GetAllCookies().size());

  cookie_service_client()->SetContentSettings(
      {CreateSetting(CONTENT_SETTING_SESSION_ONLY, kCookieURL)});
  cookie_service_client()->SetForceKeepSessionState();
  base::RunLoop().RunUntilIdle();

  auto store = CreateCookieStore();
  InitializeCookieService(store, store);

  EXPECT_EQ(1u, service_wrapper()->GetAllCookies().size());
}

TEST_F(SessionCleanupCookieManagerTest, HttpCookieAllowedOnHttps) {
  EXPECT_TRUE(SetCanonicalCookie(CreateCookie(StrCat({"www.", kCookieDomain})),
                                 "https", true));

  EXPECT_EQ(1u, service_wrapper()->GetAllCookies().size());

  cookie_service_client()->SetContentSettings({
      CreateSetting(CONTENT_SETTING_ALLOW, kCookieHttpsURL),
      CreateDefaultSetting(CONTENT_SETTING_SESSION_ONLY),
  });
  base::RunLoop().RunUntilIdle();

  auto store = CreateCookieStore();
  InitializeCookieService(store, store);

  EXPECT_EQ(1u, service_wrapper()->GetAllCookies().size());
}

// Each call to SetStorageAccessGrantSettings should run the provided callback
// when complete.
TEST_F(CookieManagerTest, SetStorageAccessGrantSettingsRunsCallback) {
  service_wrapper()->SetStorageAccessGrantSettings();
  ASSERT_EQ(1U, service_wrapper()->callback_count());
}

}  // namespace
}  // namespace network
