// Copyright 2018 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.

#ifndef NET_COOKIES_COOKIE_STORE_CHANGE_UNITTEST_H
#define NET_COOKIES_COOKIE_STORE_CHANGE_UNITTEST_H

#include "base/bind.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_change_dispatcher_test_helpers.h"
#include "net/cookies/cookie_store.h"
#include "net/cookies/cookie_store_unittest.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

namespace net {

namespace {

using CookieChange = std::pair<CanonicalCookie, CookieChangeCause>;

// Used to sort CookieChanges when testing stores without exact change ordering.
//
// The ordering relation must match the order in which the tests below issue
// cookie calls. Changes to this method should be tested by running the tests
// below with CookieMonsterTestTraits::has_exact_change_ordering set to both
// true and false.
bool CookieChangeLessThan(const CookieChange& lhs, const CookieChange& rhs) {
  if (lhs.first.Name() != rhs.first.Name())
    return lhs.first.Name() < rhs.first.Name();

  if (lhs.first.Value() != rhs.first.Value())
    return lhs.first.Value() < rhs.first.Value();

  if (lhs.first.Domain() != rhs.first.Domain())
    return lhs.first.Domain() < rhs.first.Domain();

  return lhs.second < rhs.second;
}

}  // namespace

// Google Test supports at most 50 tests per typed case, so the tests here are
// broken up into multiple cases.
template <class CookieStoreTestTraits>
class CookieStoreChangeTestBase
    : public CookieStoreTest<CookieStoreTestTraits> {
 protected:
  using CookieStoreTest<CookieStoreTestTraits>::FindAndDeleteCookie;

  // Drains all pending tasks on the run loop(s) involved in the test.
  void DeliverChangeNotifications() {
    CookieStoreTestTraits::DeliverChangeNotifications();
  }

  bool FindAndDeleteCookie(CookieStore* cs,
                           const std::string& domain,
                           const std::string& name,
                           const std::string& path) {
    for (auto& cookie : this->GetAllCookies(cs)) {
      if (cookie.Domain() == domain && cookie.Name() == name &&
          cookie.Path() == path) {
        return this->DeleteCanonicalCookie(cs, cookie);
      }
    }

    return false;
  }

  // Could be static, but it's actually easier to have it be a member function.
  ::testing::AssertionResult MatchesCause(CookieChangeCause expected_cause,
                                          CookieChangeCause actual_cause) {
    if (!CookieChangeCauseIsDeletion(expected_cause) ||
        CookieStoreTestTraits::has_exact_change_cause) {
      if (expected_cause == actual_cause)
        return ::testing::AssertionSuccess();
      return ::testing::AssertionFailure()
             << "expected " << expected_cause << " got " << actual_cause;
    }
    if (CookieChangeCauseIsDeletion(actual_cause))
      return ::testing::AssertionSuccess();
    return ::testing::AssertionFailure()
           << "expected a deletion cause, got " << actual_cause;
  }

  static void OnCookieChange(std::vector<CookieChange>* changes,
                             const CanonicalCookie& cookie,
                             CookieChangeCause cause) {
    CookieChange notification(cookie, cause);

    if (CookieStoreTestTraits::has_exact_change_ordering) {
      changes->push_back(notification);
    } else {
      // Assumes the vector is sorted before the insertion. If true, the vector
      // will remain sorted.
      changes->insert(std::upper_bound(changes->begin(), changes->end(),
                                       notification, CookieChangeLessThan),
                      notification);
    }
  }
};

template <class CookieStoreTestTraits>
class CookieStoreChangeGlobalTest
    : public CookieStoreChangeTestBase<CookieStoreTestTraits> {};
TYPED_TEST_CASE_P(CookieStoreChangeGlobalTest);

template <class CookieStoreTestTraits>
class CookieStoreChangeUrlTest
    : public CookieStoreChangeTestBase<CookieStoreTestTraits> {};
TYPED_TEST_CASE_P(CookieStoreChangeUrlTest);

template <class CookieStoreTestTraits>
class CookieStoreChangeNamedTest
    : public CookieStoreChangeTestBase<CookieStoreTestTraits> {};
TYPED_TEST_CASE_P(CookieStoreChangeNamedTest);

TYPED_TEST_P(CookieStoreChangeGlobalTest, NoCookie) {
  if (!TypeParam::supports_global_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();
  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
          &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
          base::Unretained(&cookie_changes)));
  this->DeliverChangeNotifications();
  EXPECT_EQ(0u, cookie_changes.size());
}

TYPED_TEST_P(CookieStoreChangeGlobalTest, InitialCookie) {
  if (!TypeParam::supports_global_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();
  std::vector<CookieChange> cookie_changes;
  this->SetCookie(cs, this->http_www_foo_.url(), "A=B");
  this->DeliverChangeNotifications();
  std::unique_ptr<CookieChangeSubscription> subscription(
      cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
          &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
          base::Unretained(&cookie_changes))));
  this->DeliverChangeNotifications();
  EXPECT_EQ(0u, cookie_changes.size());
}

TYPED_TEST_P(CookieStoreChangeGlobalTest, InsertOne) {
  if (!TypeParam::supports_global_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();
  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
          &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
          base::Unretained(&cookie_changes)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes.size());

  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
  this->DeliverChangeNotifications();

  ASSERT_EQ(1u, cookie_changes.size());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[0].second));
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
  EXPECT_EQ("A", cookie_changes[0].first.Name());
  EXPECT_EQ("B", cookie_changes[0].first.Value());
}

TYPED_TEST_P(CookieStoreChangeGlobalTest, InsertMany) {
  if (!TypeParam::supports_global_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();
  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
          &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
          base::Unretained(&cookie_changes)));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "E=F"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "G=H"));
  this->DeliverChangeNotifications();

  // Check that the cookie changes are dispatched before calling GetCookies.
  // This is not an ASSERT because the following expectations produce useful
  // debugging information if they fail.
  EXPECT_EQ(4u, cookie_changes.size());
  EXPECT_EQ("A=B; C=D; E=F", this->GetCookies(cs, this->http_www_foo_.url()));
  EXPECT_EQ("G=H", this->GetCookies(cs, this->http_bar_com_.url()));

  ASSERT_LE(1u, cookie_changes.size());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[0].second));
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
  EXPECT_EQ("A", cookie_changes[0].first.Name());
  EXPECT_EQ("B", cookie_changes[0].first.Value());

  ASSERT_LE(2u, cookie_changes.size());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[1].second));
  EXPECT_EQ("C", cookie_changes[1].first.Name());
  EXPECT_EQ("D", cookie_changes[1].first.Value());

  ASSERT_LE(3u, cookie_changes.size());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[2].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[2].second));
  EXPECT_EQ("E", cookie_changes[2].first.Name());
  EXPECT_EQ("F", cookie_changes[2].first.Value());

  ASSERT_LE(4u, cookie_changes.size());
  EXPECT_EQ(this->http_bar_com_.url().host(), cookie_changes[3].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[3].second));
  EXPECT_EQ("G", cookie_changes[3].first.Name());
  EXPECT_EQ("H", cookie_changes[3].first.Value());

  EXPECT_EQ(4u, cookie_changes.size());
}

TYPED_TEST_P(CookieStoreChangeGlobalTest, DeleteOne) {
  if (!TypeParam::supports_global_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();
  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
          &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
          base::Unretained(&cookie_changes)));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
  this->DeliverChangeNotifications();
  EXPECT_EQ(1u, cookie_changes.size());
  cookie_changes.clear();

  EXPECT_TRUE(
      this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "A"));
  this->DeliverChangeNotifications();

  ASSERT_EQ(1u, cookie_changes.size());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::EXPLICIT,
                                 cookie_changes[0].second));
  EXPECT_EQ("A", cookie_changes[0].first.Name());
  EXPECT_EQ("B", cookie_changes[0].first.Value());
}

TYPED_TEST_P(CookieStoreChangeGlobalTest, DeleteTwo) {
  if (!TypeParam::supports_global_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();
  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
          &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
          base::Unretained(&cookie_changes)));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "E=F"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "G=H"));
  this->DeliverChangeNotifications();
  EXPECT_EQ(4u, cookie_changes.size());
  cookie_changes.clear();

  EXPECT_TRUE(
      this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "C"));
  EXPECT_TRUE(
      this->FindAndDeleteCookie(cs, this->http_bar_com_.url().host(), "G"));
  this->DeliverChangeNotifications();

  // Check that the cookie changes are dispatched before calling GetCookies.
  // This is not an ASSERT because the following expectations produce useful
  // debugging information if they fail.
  EXPECT_EQ(2u, cookie_changes.size());
  EXPECT_EQ("A=B; E=F", this->GetCookies(cs, this->http_www_foo_.url()));
  EXPECT_EQ("", this->GetCookies(cs, this->http_bar_com_.url()));

  ASSERT_LE(1u, cookie_changes.size());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::EXPLICIT,
                                 cookie_changes[0].second));
  EXPECT_EQ("C", cookie_changes[0].first.Name());
  EXPECT_EQ("D", cookie_changes[0].first.Value());

  ASSERT_EQ(2u, cookie_changes.size());
  EXPECT_EQ(this->http_bar_com_.url().host(), cookie_changes[1].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::EXPLICIT,
                                 cookie_changes[1].second));
  EXPECT_EQ("G", cookie_changes[1].first.Name());
  EXPECT_EQ("H", cookie_changes[1].first.Value());
}

TYPED_TEST_P(CookieStoreChangeGlobalTest, Overwrite) {
  if (!TypeParam::supports_global_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();
  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
          &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
          base::Unretained(&cookie_changes)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes.size());

  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
  this->DeliverChangeNotifications();
  ASSERT_EQ(1u, cookie_changes.size());
  cookie_changes.clear();

  // Replacing an existing cookie is actually a two-phase delete + set
  // operation, so we get an extra notification.
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=C"));
  this->DeliverChangeNotifications();

  ASSERT_LE(1u, cookie_changes.size());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
                                 cookie_changes[0].second));
  EXPECT_EQ("A", cookie_changes[0].first.Name());
  EXPECT_EQ("B", cookie_changes[0].first.Value());

  ASSERT_LE(2u, cookie_changes.size());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[1].second));
  EXPECT_EQ("A", cookie_changes[1].first.Name());
  EXPECT_EQ("C", cookie_changes[1].first.Value());

  EXPECT_EQ(2u, cookie_changes.size());
}

TYPED_TEST_P(CookieStoreChangeGlobalTest, OverwriteWithHttpOnly) {
  if (!TypeParam::supports_global_cookie_tracking)
    return;

  // Insert a cookie "A" for path "/path1"
  CookieStore* cs = this->GetCookieStore();
  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
          &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
          base::Unretained(&cookie_changes)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes.size());

  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "A=B; path=/path1"));
  this->DeliverChangeNotifications();
  ASSERT_EQ(1u, cookie_changes.size());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[0].second));
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
  EXPECT_EQ("A", cookie_changes[0].first.Name());
  EXPECT_EQ("B", cookie_changes[0].first.Value());
  EXPECT_FALSE(cookie_changes[0].first.IsHttpOnly());
  cookie_changes.clear();

  // Insert a cookie "A" for path "/path1", that is httponly. This should
  // overwrite the non-http-only version.
  CookieOptions allow_httponly;
  allow_httponly.set_include_httponly();
  EXPECT_TRUE(this->SetCookieWithOptions(cs, this->http_www_foo_.url(),
                                         "A=C; path=/path1; httponly",
                                         allow_httponly));
  this->DeliverChangeNotifications();

  ASSERT_LE(1u, cookie_changes.size());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
                                 cookie_changes[0].second));
  EXPECT_EQ("A", cookie_changes[0].first.Name());
  EXPECT_EQ("B", cookie_changes[0].first.Value());
  EXPECT_FALSE(cookie_changes[0].first.IsHttpOnly());

  ASSERT_LE(2u, cookie_changes.size());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[1].second));
  EXPECT_EQ("A", cookie_changes[1].first.Name());
  EXPECT_EQ("C", cookie_changes[1].first.Value());
  EXPECT_TRUE(cookie_changes[1].first.IsHttpOnly());

  EXPECT_EQ(2u, cookie_changes.size());
}

TYPED_TEST_P(CookieStoreChangeGlobalTest, Deregister) {
  if (!TypeParam::supports_global_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();

  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
          &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
          base::Unretained(&cookie_changes)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes.size());

  // Insert a cookie and make sure it is seen.
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
  this->DeliverChangeNotifications();
  ASSERT_EQ(1u, cookie_changes.size());
  EXPECT_EQ("A", cookie_changes[0].first.Name());
  EXPECT_EQ("B", cookie_changes[0].first.Value());
  cookie_changes.clear();

  // De-register the subscription.
  subscription.reset();

  // Insert a second cookie and make sure that it's not visible.
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
  this->DeliverChangeNotifications();

  EXPECT_EQ(0u, cookie_changes.size());
}

TYPED_TEST_P(CookieStoreChangeGlobalTest, DeregisterMultiple) {
  if (!TypeParam::supports_global_cookie_tracking ||
      !TypeParam::supports_multiple_tracking_callbacks)
    return;

  CookieStore* cs = this->GetCookieStore();

  // Register two subscriptions.
  std::vector<CookieChange> cookie_changes_1;
  std::unique_ptr<CookieChangeSubscription> subscription1 =
      cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
          &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
          base::Unretained(&cookie_changes_1)));

  std::vector<CookieChange> cookie_changes_2;
  std::unique_ptr<CookieChangeSubscription> subscription2 =
      cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
          &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
          base::Unretained(&cookie_changes_2)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes_1.size());
  ASSERT_EQ(0u, cookie_changes_2.size());

  // Insert a cookie and make sure it's seen.
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
  this->DeliverChangeNotifications();
  ASSERT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ("A", cookie_changes_1[0].first.Name());
  EXPECT_EQ("B", cookie_changes_1[0].first.Value());
  cookie_changes_1.clear();

  ASSERT_EQ(1u, cookie_changes_2.size());
  EXPECT_EQ("A", cookie_changes_2[0].first.Name());
  EXPECT_EQ("B", cookie_changes_2[0].first.Value());
  cookie_changes_2.clear();

  // De-register the second subscription.
  subscription2.reset();

  // Insert a second cookie and make sure that it's only visible in one
  // change array.
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
  this->DeliverChangeNotifications();
  ASSERT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ("C", cookie_changes_1[0].first.Name());
  EXPECT_EQ("D", cookie_changes_1[0].first.Value());
  cookie_changes_1.clear();

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

// Confirm that a listener does not receive notifications for changes that
// happened right before the subscription was established.
TYPED_TEST_P(CookieStoreChangeGlobalTest, DispatchRace) {
  if (!TypeParam::supports_global_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();

  // This cookie insertion should not be seen.
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
  // DeliverChangeNotifications() must NOT be called before the subscription is
  // established.

  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
          &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
          base::Unretained(&cookie_changes)));

  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
  this->DeliverChangeNotifications();

  EXPECT_LE(1u, cookie_changes.size());
  EXPECT_EQ("C", cookie_changes[0].first.Name());
  EXPECT_EQ("D", cookie_changes[0].first.Value());

  ASSERT_EQ(1u, cookie_changes.size());
}

// Confirm that deregistering a subscription blocks the notification if the
// deregistration happened after the change but before the notification was
// received.
TYPED_TEST_P(CookieStoreChangeGlobalTest, DeregisterRace) {
  if (!TypeParam::supports_global_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();

  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
          &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
          base::Unretained(&cookie_changes)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes.size());

  // Insert a cookie and make sure it's seen.
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
  this->DeliverChangeNotifications();
  ASSERT_EQ(1u, cookie_changes.size());
  EXPECT_EQ("A", cookie_changes[0].first.Name());
  EXPECT_EQ("B", cookie_changes[0].first.Value());
  cookie_changes.clear();

  // Insert a cookie, confirm it is not seen, deregister the subscription, run
  // until idle, and confirm the cookie is still not seen.
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));

  // Note that by the API contract it's perfectly valid to have received the
  // notification immediately, i.e. synchronously with the cookie change. In
  // that case, there's nothing to test.
  if (1u == cookie_changes.size())
    return;

  // A task was posted by the SetCookie() above, but has not yet arrived. If it
  // arrived before the subscription is destroyed, callback execution would be
  // valid. Destroy the subscription so as to lose the race and make sure the
  // task posted arrives after the subscription was destroyed.
  subscription.reset();
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes.size());
}

TYPED_TEST_P(CookieStoreChangeGlobalTest, DeregisterRaceMultiple) {
  if (!TypeParam::supports_global_cookie_tracking ||
      !TypeParam::supports_multiple_tracking_callbacks)
    return;

  CookieStore* cs = this->GetCookieStore();

  // Register two subscriptions.
  std::vector<CookieChange> cookie_changes_1, cookie_changes_2;
  std::unique_ptr<CookieChangeSubscription> subscription1 =
      cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
          &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
          base::Unretained(&cookie_changes_1)));
  std::unique_ptr<CookieChangeSubscription> subscription2 =
      cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
          &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
          base::Unretained(&cookie_changes_2)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes_1.size());
  ASSERT_EQ(0u, cookie_changes_2.size());

  // Insert a cookie and make sure it's seen.
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
  this->DeliverChangeNotifications();

  ASSERT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ("A", cookie_changes_1[0].first.Name());
  EXPECT_EQ("B", cookie_changes_1[0].first.Value());
  cookie_changes_1.clear();

  ASSERT_EQ(1u, cookie_changes_2.size());
  EXPECT_EQ("A", cookie_changes_2[0].first.Name());
  EXPECT_EQ("B", cookie_changes_2[0].first.Value());
  cookie_changes_2.clear();

  // Insert a cookie, confirm it is not seen, deregister a subscription, run
  // until idle, and confirm the cookie is still not seen.
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));

  // Note that by the API contract it's perfectly valid to have received the
  // notification immediately, i.e. synchronously with the cookie change. In
  // that case, there's nothing to test.
  if (1u == cookie_changes_2.size())
    return;

  // A task was posted by the SetCookie() above, but has not yet arrived. If it
  // arrived before the subscription is destroyed, callback execution would be
  // valid. Destroy one of the subscriptions so as to lose the race and make
  // sure the task posted arrives after the subscription was destroyed.
  subscription2.reset();
  this->DeliverChangeNotifications();
  ASSERT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ("C", cookie_changes_1[0].first.Name());
  EXPECT_EQ("D", cookie_changes_1[0].first.Value());

  // No late notification was received.
  ASSERT_EQ(0u, cookie_changes_2.size());
}

TYPED_TEST_P(CookieStoreChangeGlobalTest, MultipleSubscriptions) {
  if (!TypeParam::supports_global_cookie_tracking ||
      !TypeParam::supports_multiple_tracking_callbacks)
    return;

  CookieStore* cs = this->GetCookieStore();

  std::vector<CookieChange> cookie_changes_1, cookie_changes_2;
  std::unique_ptr<CookieChangeSubscription> subscription1 =
      cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
          &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
          base::Unretained(&cookie_changes_1)));
  std::unique_ptr<CookieChangeSubscription> subscription2 =
      cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
          &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
          base::Unretained(&cookie_changes_2)));
  this->DeliverChangeNotifications();

  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
  this->DeliverChangeNotifications();

  ASSERT_EQ(1U, cookie_changes_1.size());
  EXPECT_EQ("A", cookie_changes_1[0].first.Name());
  EXPECT_EQ("B", cookie_changes_1[0].first.Value());

  ASSERT_EQ(1U, cookie_changes_2.size());
  EXPECT_EQ("A", cookie_changes_2[0].first.Name());
  EXPECT_EQ("B", cookie_changes_2[0].first.Value());
}

TYPED_TEST_P(CookieStoreChangeUrlTest, NoCookie) {
  if (!TypeParam::supports_url_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();
  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForUrl(
          this->http_www_foo_.url(),
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes)));
  this->DeliverChangeNotifications();
  EXPECT_EQ(0u, cookie_changes.size());
}

TYPED_TEST_P(CookieStoreChangeUrlTest, InitialCookie) {
  if (!TypeParam::supports_url_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();
  std::vector<CookieChange> cookie_changes;
  this->SetCookie(cs, this->http_www_foo_.url(), "A=B");
  this->DeliverChangeNotifications();
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForUrl(
          this->http_www_foo_.url(),
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes)));
  this->DeliverChangeNotifications();
  EXPECT_EQ(0u, cookie_changes.size());
}

TYPED_TEST_P(CookieStoreChangeUrlTest, InsertOne) {
  if (!TypeParam::supports_url_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();
  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForUrl(
          this->http_www_foo_.url(),
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes.size());

  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
  this->DeliverChangeNotifications();
  ASSERT_EQ(1u, cookie_changes.size());

  EXPECT_EQ("A", cookie_changes[0].first.Name());
  EXPECT_EQ("B", cookie_changes[0].first.Value());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[0].second));
}

TYPED_TEST_P(CookieStoreChangeUrlTest, InsertMany) {
  if (!TypeParam::supports_url_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();
  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForUrl(
          this->http_www_foo_.url(),
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes)));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "E=F"));
  this->DeliverChangeNotifications();

  ASSERT_LE(1u, cookie_changes.size());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[0].second));
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
  EXPECT_EQ("A", cookie_changes[0].first.Name());
  EXPECT_EQ("B", cookie_changes[0].first.Value());

  ASSERT_LE(2u, cookie_changes.size());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[1].second));
  EXPECT_EQ("C", cookie_changes[1].first.Name());
  EXPECT_EQ("D", cookie_changes[1].first.Value());

  ASSERT_LE(3u, cookie_changes.size());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[2].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[2].second));
  EXPECT_EQ("E", cookie_changes[2].first.Name());
  EXPECT_EQ("F", cookie_changes[2].first.Value());

  EXPECT_EQ(3u, cookie_changes.size());
}

TYPED_TEST_P(CookieStoreChangeUrlTest, InsertFiltering) {
  if (!TypeParam::supports_url_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();
  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForUrl(
          this->www_foo_foo_.url(),
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes.size());

  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B; path=/"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "C=D; path=/"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "E=F; path=/bar"));
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "G=H; path=/foo/bar"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "I=J; path=/foo"));
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "K=L; domain=foo.com"));
  this->DeliverChangeNotifications();

  ASSERT_LE(1u, cookie_changes.size());
  EXPECT_EQ("A", cookie_changes[0].first.Name());
  EXPECT_EQ("B", cookie_changes[0].first.Value());
  EXPECT_EQ("/", cookie_changes[0].first.Path());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[0].second));

  ASSERT_LE(2u, cookie_changes.size());
  EXPECT_EQ("I", cookie_changes[1].first.Name());
  EXPECT_EQ("J", cookie_changes[1].first.Value());
  EXPECT_EQ("/foo", cookie_changes[1].first.Path());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[1].second));

  ASSERT_LE(3u, cookie_changes.size());
  EXPECT_EQ("K", cookie_changes[2].first.Name());
  EXPECT_EQ("L", cookie_changes[2].first.Value());
  EXPECT_EQ("/", cookie_changes[2].first.Path());
  EXPECT_EQ(".foo.com", cookie_changes[2].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[2].second));

  EXPECT_EQ(3u, cookie_changes.size());
}

TYPED_TEST_P(CookieStoreChangeUrlTest, DeleteOne) {
  if (!TypeParam::supports_url_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();
  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForUrl(
          this->http_www_foo_.url(),
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes)));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
  this->DeliverChangeNotifications();
  EXPECT_EQ(1u, cookie_changes.size());
  cookie_changes.clear();

  EXPECT_TRUE(
      this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "A"));
  this->DeliverChangeNotifications();

  ASSERT_EQ(1u, cookie_changes.size());
  EXPECT_EQ("A", cookie_changes[0].first.Name());
  EXPECT_EQ("B", cookie_changes[0].first.Value());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
  ASSERT_TRUE(this->MatchesCause(CookieChangeCause::EXPLICIT,
                                 cookie_changes[0].second));
}

TYPED_TEST_P(CookieStoreChangeUrlTest, DeleteTwo) {
  if (!TypeParam::supports_url_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();
  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForUrl(
          this->http_www_foo_.url(),
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes)));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "E=F"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "G=H"));
  this->DeliverChangeNotifications();
  EXPECT_EQ(4u, cookie_changes.size());
  cookie_changes.clear();

  EXPECT_TRUE(
      this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "C"));
  EXPECT_TRUE(
      this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "G"));
  this->DeliverChangeNotifications();

  // Check that the cookie changes are dispatched before calling GetCookies.
  // This is not an ASSERT because the following expectations produce useful
  // debugging information if they fail.
  EXPECT_EQ(2u, cookie_changes.size());
  EXPECT_EQ("A=B; E=F", this->GetCookies(cs, this->http_www_foo_.url()));

  ASSERT_LE(1u, cookie_changes.size());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::EXPLICIT,
                                 cookie_changes[0].second));
  EXPECT_EQ("C", cookie_changes[0].first.Name());
  EXPECT_EQ("D", cookie_changes[0].first.Value());

  ASSERT_EQ(2u, cookie_changes.size());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::EXPLICIT,
                                 cookie_changes[1].second));
  EXPECT_EQ("G", cookie_changes[1].first.Name());
  EXPECT_EQ("H", cookie_changes[1].first.Value());
}

TYPED_TEST_P(CookieStoreChangeUrlTest, DeleteFiltering) {
  if (!TypeParam::supports_url_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();
  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForUrl(
          this->www_foo_foo_.url(),
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes)));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B; path=/"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "C=D; path=/"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "E=F; path=/bar"));
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "G=H; path=/foo/bar"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "I=J; path=/foo"));
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "K=L; domain=foo.com"));
  this->DeliverChangeNotifications();
  EXPECT_EQ(3u, cookie_changes.size());
  cookie_changes.clear();

  EXPECT_TRUE(
      this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "A"));
  EXPECT_TRUE(
      this->FindAndDeleteCookie(cs, this->http_bar_com_.url().host(), "C"));
  EXPECT_TRUE(
      this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "E"));
  EXPECT_TRUE(
      this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "G"));
  EXPECT_TRUE(
      this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "I"));
  EXPECT_TRUE(this->FindAndDeleteCookie(cs, ".foo.com", "K"));
  this->DeliverChangeNotifications();

  ASSERT_LE(1u, cookie_changes.size());
  EXPECT_EQ("A", cookie_changes[0].first.Name());
  EXPECT_EQ("B", cookie_changes[0].first.Value());
  EXPECT_EQ("/", cookie_changes[0].first.Path());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::EXPLICIT,
                                 cookie_changes[0].second));

  ASSERT_LE(2u, cookie_changes.size());
  EXPECT_EQ("I", cookie_changes[1].first.Name());
  EXPECT_EQ("J", cookie_changes[1].first.Value());
  EXPECT_EQ("/foo", cookie_changes[1].first.Path());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::EXPLICIT,
                                 cookie_changes[1].second));

  ASSERT_LE(3u, cookie_changes.size());
  EXPECT_EQ("K", cookie_changes[2].first.Name());
  EXPECT_EQ("L", cookie_changes[2].first.Value());
  EXPECT_EQ("/", cookie_changes[2].first.Path());
  EXPECT_EQ(".foo.com", cookie_changes[2].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::EXPLICIT,
                                 cookie_changes[2].second));

  EXPECT_EQ(3u, cookie_changes.size());
}

TYPED_TEST_P(CookieStoreChangeUrlTest, Overwrite) {
  if (!TypeParam::supports_url_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();
  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForUrl(
          this->http_www_foo_.url(),
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes.size());

  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
  this->DeliverChangeNotifications();
  ASSERT_EQ(1u, cookie_changes.size());
  cookie_changes.clear();

  // Replacing an existing cookie is actually a two-phase delete + set
  // operation, so we get an extra notification.
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=C"));
  this->DeliverChangeNotifications();

  ASSERT_LE(1u, cookie_changes.size());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
                                 cookie_changes[0].second));
  EXPECT_EQ("A", cookie_changes[0].first.Name());
  EXPECT_EQ("B", cookie_changes[0].first.Value());

  ASSERT_LE(2u, cookie_changes.size());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[1].second));
  EXPECT_EQ("A", cookie_changes[1].first.Name());
  EXPECT_EQ("C", cookie_changes[1].first.Value());

  EXPECT_EQ(2u, cookie_changes.size());
}

TYPED_TEST_P(CookieStoreChangeUrlTest, OverwriteFiltering) {
  if (!TypeParam::supports_url_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();
  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForUrl(
          this->www_foo_foo_.url(),
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes.size());

  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B; path=/"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "C=D; path=/"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "E=F; path=/bar"));
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "G=H; path=/foo/bar"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "I=J; path=/foo"));
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "K=L; domain=foo.com"));
  this->DeliverChangeNotifications();
  EXPECT_EQ(3u, cookie_changes.size());
  cookie_changes.clear();

  // Replacing an existing cookie is actually a two-phase delete + set
  // operation, so we get two notifications per overwrite.
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=b; path=/"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "C=d; path=/"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "E=f; path=/bar"));
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "G=h; path=/foo/bar"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "I=j; path=/foo"));
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "K=l; domain=foo.com"));
  this->DeliverChangeNotifications();

  ASSERT_LE(1u, cookie_changes.size());
  EXPECT_EQ("A", cookie_changes[0].first.Name());
  EXPECT_EQ("B", cookie_changes[0].first.Value());
  EXPECT_EQ("/", cookie_changes[0].first.Path());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
                                 cookie_changes[0].second));

  ASSERT_LE(2u, cookie_changes.size());
  EXPECT_EQ("A", cookie_changes[1].first.Name());
  EXPECT_EQ("b", cookie_changes[1].first.Value());
  EXPECT_EQ("/", cookie_changes[1].first.Path());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
  EXPECT_EQ(CookieChangeCause::INSERTED, cookie_changes[1].second);
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[1].second));

  ASSERT_LE(3u, cookie_changes.size());
  EXPECT_EQ("I", cookie_changes[2].first.Name());
  EXPECT_EQ("J", cookie_changes[2].first.Value());
  EXPECT_EQ("/foo", cookie_changes[2].first.Path());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[2].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
                                 cookie_changes[2].second));

  ASSERT_LE(4u, cookie_changes.size());
  EXPECT_EQ("I", cookie_changes[3].first.Name());
  EXPECT_EQ("j", cookie_changes[3].first.Value());
  EXPECT_EQ("/foo", cookie_changes[3].first.Path());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[3].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[3].second));

  ASSERT_LE(5u, cookie_changes.size());
  EXPECT_EQ("K", cookie_changes[4].first.Name());
  EXPECT_EQ("L", cookie_changes[4].first.Value());
  EXPECT_EQ("/", cookie_changes[4].first.Path());
  EXPECT_EQ(".foo.com", cookie_changes[4].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
                                 cookie_changes[4].second));

  ASSERT_LE(6u, cookie_changes.size());
  EXPECT_EQ("K", cookie_changes[5].first.Name());
  EXPECT_EQ("l", cookie_changes[5].first.Value());
  EXPECT_EQ("/", cookie_changes[5].first.Path());
  EXPECT_EQ(".foo.com", cookie_changes[5].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[5].second));

  EXPECT_EQ(6u, cookie_changes.size());
}

TYPED_TEST_P(CookieStoreChangeUrlTest, OverwriteWithHttpOnly) {
  if (!TypeParam::supports_url_cookie_tracking)
    return;

  // Insert a cookie "A" for path "/foo".
  CookieStore* cs = this->GetCookieStore();
  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForUrl(
          this->www_foo_foo_.url(),
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes.size());

  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B; path=/foo"));
  this->DeliverChangeNotifications();
  ASSERT_EQ(1u, cookie_changes.size());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[0].second));
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
  EXPECT_EQ("A", cookie_changes[0].first.Name());
  EXPECT_EQ("B", cookie_changes[0].first.Value());
  EXPECT_FALSE(cookie_changes[0].first.IsHttpOnly());
  cookie_changes.clear();

  // Insert a cookie "A" for path "/foo", that is httponly. This should
  // overwrite the non-http-only version.
  CookieOptions allow_httponly;
  allow_httponly.set_include_httponly();
  EXPECT_TRUE(this->SetCookieWithOptions(cs, this->http_www_foo_.url(),
                                         "A=C; path=/foo; httponly",
                                         allow_httponly));
  this->DeliverChangeNotifications();

  ASSERT_LE(1u, cookie_changes.size());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
                                 cookie_changes[0].second));
  EXPECT_EQ("A", cookie_changes[0].first.Name());
  EXPECT_EQ("B", cookie_changes[0].first.Value());
  EXPECT_FALSE(cookie_changes[0].first.IsHttpOnly());

  ASSERT_LE(2u, cookie_changes.size());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[1].second));
  EXPECT_EQ("A", cookie_changes[1].first.Name());
  EXPECT_EQ("C", cookie_changes[1].first.Value());
  EXPECT_TRUE(cookie_changes[1].first.IsHttpOnly());

  EXPECT_EQ(2u, cookie_changes.size());
}

TYPED_TEST_P(CookieStoreChangeUrlTest, Deregister) {
  if (!TypeParam::supports_url_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();

  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForUrl(
          this->http_www_foo_.url(),
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes.size());

  // Insert a cookie and make sure it is seen.
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
  this->DeliverChangeNotifications();
  ASSERT_EQ(1u, cookie_changes.size());
  EXPECT_EQ("A", cookie_changes[0].first.Name());
  EXPECT_EQ("B", cookie_changes[0].first.Value());
  cookie_changes.clear();

  // De-register the subscription.
  subscription.reset();

  // Insert a second cookie and make sure it's not visible.
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
  this->DeliverChangeNotifications();

  EXPECT_EQ(0u, cookie_changes.size());
}

TYPED_TEST_P(CookieStoreChangeUrlTest, DeregisterMultiple) {
  if (!TypeParam::supports_url_cookie_tracking ||
      !TypeParam::supports_multiple_tracking_callbacks)
    return;

  CookieStore* cs = this->GetCookieStore();

  // Register two subscriptions.
  std::vector<CookieChange> cookie_changes_1, cookie_changes_2;
  std::unique_ptr<CookieChangeSubscription> subscription1 =
      cs->GetChangeDispatcher().AddCallbackForUrl(
          this->http_www_foo_.url(),
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_1)));
  std::unique_ptr<CookieChangeSubscription> subscription2 =
      cs->GetChangeDispatcher().AddCallbackForUrl(
          this->http_www_foo_.url(),
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_2)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes_1.size());
  ASSERT_EQ(0u, cookie_changes_2.size());

  // Insert a cookie and make sure it's seen.
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
  this->DeliverChangeNotifications();
  ASSERT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ("A", cookie_changes_1[0].first.Name());
  EXPECT_EQ("B", cookie_changes_1[0].first.Value());
  cookie_changes_1.clear();

  ASSERT_EQ(1u, cookie_changes_2.size());
  EXPECT_EQ("A", cookie_changes_2[0].first.Name());
  EXPECT_EQ("B", cookie_changes_2[0].first.Value());
  cookie_changes_2.clear();

  // De-register the second registration.
  subscription2.reset();

  // Insert a second cookie and make sure that it's only visible in one
  // change array.
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
  this->DeliverChangeNotifications();
  ASSERT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ("C", cookie_changes_1[0].first.Name());
  EXPECT_EQ("D", cookie_changes_1[0].first.Value());

  EXPECT_EQ(0u, cookie_changes_2.size());
}

// Confirm that a listener does not receive notifications for changes that
// happened right before the subscription was established.
TYPED_TEST_P(CookieStoreChangeUrlTest, DispatchRace) {
  if (!TypeParam::supports_url_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();

  // This cookie insertion should not be seen.
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
  // DeliverChangeNotifications() must NOT be called before the subscription is
  // established.

  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForUrl(
          this->http_www_foo_.url(),
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes)));

  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
  this->DeliverChangeNotifications();

  EXPECT_LE(1u, cookie_changes.size());
  EXPECT_EQ("C", cookie_changes[0].first.Name());
  EXPECT_EQ("D", cookie_changes[0].first.Value());

  ASSERT_EQ(1u, cookie_changes.size());
}

// Confirm that deregistering a subscription blocks the notification if the
// deregistration happened after the change but before the notification was
// received.
TYPED_TEST_P(CookieStoreChangeUrlTest, DeregisterRace) {
  if (!TypeParam::supports_url_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();

  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForUrl(
          this->http_www_foo_.url(),
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes.size());

  // Insert a cookie and make sure it's seen.
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
  this->DeliverChangeNotifications();
  ASSERT_EQ(1u, cookie_changes.size());
  EXPECT_EQ("A", cookie_changes[0].first.Name());
  EXPECT_EQ("B", cookie_changes[0].first.Value());
  cookie_changes.clear();

  // Insert a cookie, confirm it is not seen, deregister the subscription, run
  // until idle, and confirm the cookie is still not seen.
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));

  // Note that by the API contract it's perfectly valid to have received the
  // notification immediately, i.e. synchronously with the cookie change. In
  // that case, there's nothing to test.
  if (1u == cookie_changes.size())
    return;

  // A task was posted by the SetCookie() above, but has not yet arrived. If it
  // arrived before the subscription is destroyed, callback execution would be
  // valid. Destroy the subscription so as to lose the race and make sure the
  // task posted arrives after the subscription was destroyed.
  subscription.reset();
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes.size());
}

TYPED_TEST_P(CookieStoreChangeUrlTest, DeregisterRaceMultiple) {
  if (!TypeParam::supports_url_cookie_tracking ||
      !TypeParam::supports_multiple_tracking_callbacks)
    return;

  CookieStore* cs = this->GetCookieStore();

  // Register two subscriptions.
  std::vector<CookieChange> cookie_changes_1, cookie_changes_2;
  std::unique_ptr<CookieChangeSubscription> subscription1 =
      cs->GetChangeDispatcher().AddCallbackForUrl(
          this->http_www_foo_.url(),
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_1)));
  std::unique_ptr<CookieChangeSubscription> subscription2 =
      cs->GetChangeDispatcher().AddCallbackForUrl(
          this->http_www_foo_.url(),
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_2)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes_1.size());
  ASSERT_EQ(0u, cookie_changes_2.size());

  // Insert a cookie and make sure it's seen.
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
  this->DeliverChangeNotifications();

  ASSERT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ("A", cookie_changes_1[0].first.Name());
  EXPECT_EQ("B", cookie_changes_1[0].first.Value());
  cookie_changes_1.clear();

  ASSERT_EQ(1u, cookie_changes_2.size());
  EXPECT_EQ("A", cookie_changes_2[0].first.Name());
  EXPECT_EQ("B", cookie_changes_2[0].first.Value());
  cookie_changes_2.clear();

  // Insert a cookie, confirm it is not seen, deregister a subscription, run
  // until idle, and confirm the cookie is still not seen.
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));

  // Note that by the API contract it's perfectly valid to have received the
  // notification immediately, i.e. synchronously with the cookie change. In
  // that case, there's nothing to test.
  if (1u == cookie_changes_2.size())
    return;

  // A task was posted by the SetCookie() above, but has not yet arrived. If it
  // arrived before the subscription is destroyed, callback execution would be
  // valid. Destroy one of the subscriptions so as to lose the race and make
  // sure the task posted arrives after the subscription was destroyed.
  subscription2.reset();
  this->DeliverChangeNotifications();
  ASSERT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ("C", cookie_changes_1[0].first.Name());
  EXPECT_EQ("D", cookie_changes_1[0].first.Value());

  // No late notification was received.
  ASSERT_EQ(0u, cookie_changes_2.size());
}

TYPED_TEST_P(CookieStoreChangeUrlTest, DifferentSubscriptionsDisjoint) {
  if (!TypeParam::supports_url_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();

  std::vector<CookieChange> cookie_changes_1, cookie_changes_2;
  std::unique_ptr<CookieChangeSubscription> subscription1 =
      cs->GetChangeDispatcher().AddCallbackForUrl(
          this->http_www_foo_.url(),
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_1)));
  std::unique_ptr<CookieChangeSubscription> subscription2 =
      cs->GetChangeDispatcher().AddCallbackForUrl(
          this->http_bar_com_.url(),
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_2)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes_1.size());
  ASSERT_EQ(0u, cookie_changes_2.size());

  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
  this->DeliverChangeNotifications();
  EXPECT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ(0u, cookie_changes_2.size());

  EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "C=D"));
  this->DeliverChangeNotifications();

  ASSERT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ("A", cookie_changes_1[0].first.Name());
  EXPECT_EQ("B", cookie_changes_1[0].first.Value());
  EXPECT_EQ(this->http_www_foo_.url().host(),
            cookie_changes_1[0].first.Domain());

  ASSERT_EQ(1u, cookie_changes_2.size());
  EXPECT_EQ("C", cookie_changes_2[0].first.Name());
  EXPECT_EQ("D", cookie_changes_2[0].first.Value());
  EXPECT_EQ(this->http_bar_com_.url().host(),
            cookie_changes_2[0].first.Domain());
}

TYPED_TEST_P(CookieStoreChangeUrlTest, DifferentSubscriptionsDomains) {
  if (!TypeParam::supports_url_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();

  std::vector<CookieChange> cookie_changes_1, cookie_changes_2;
  std::unique_ptr<CookieChangeSubscription> subscription1 =
      cs->GetChangeDispatcher().AddCallbackForUrl(
          this->http_www_foo_.url(),
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_1)));
  std::unique_ptr<CookieChangeSubscription> subscription2 =
      cs->GetChangeDispatcher().AddCallbackForUrl(
          this->http_bar_com_.url(),
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_2)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes_1.size());
  ASSERT_EQ(0u, cookie_changes_2.size());

  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
  this->DeliverChangeNotifications();
  EXPECT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ(0u, cookie_changes_2.size());

  EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "C=D"));
  this->DeliverChangeNotifications();

  ASSERT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ("A", cookie_changes_1[0].first.Name());
  EXPECT_EQ("B", cookie_changes_1[0].first.Value());
  EXPECT_EQ(this->http_www_foo_.url().host(),
            cookie_changes_1[0].first.Domain());

  ASSERT_EQ(1u, cookie_changes_2.size());
  EXPECT_EQ("C", cookie_changes_2[0].first.Name());
  EXPECT_EQ("D", cookie_changes_2[0].first.Value());
  EXPECT_EQ(this->http_bar_com_.url().host(),
            cookie_changes_2[0].first.Domain());
}

TYPED_TEST_P(CookieStoreChangeUrlTest, DifferentSubscriptionsPaths) {
  if (!TypeParam::supports_url_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();

  std::vector<CookieChange> cookie_changes_1, cookie_changes_2;
  std::unique_ptr<CookieChangeSubscription> subscription1 =
      cs->GetChangeDispatcher().AddCallbackForUrl(
          this->http_www_foo_.url(),
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_1)));
  std::unique_ptr<CookieChangeSubscription> subscription2 =
      cs->GetChangeDispatcher().AddCallbackForUrl(
          this->www_foo_foo_.url(),
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_2)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes_1.size());
  ASSERT_EQ(0u, cookie_changes_2.size());

  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
  this->DeliverChangeNotifications();
  EXPECT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ(1u, cookie_changes_2.size());

  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D; path=/foo"));
  this->DeliverChangeNotifications();

  ASSERT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ("A", cookie_changes_1[0].first.Name());
  EXPECT_EQ("B", cookie_changes_1[0].first.Value());
  EXPECT_EQ("/", cookie_changes_1[0].first.Path());
  EXPECT_EQ(this->http_www_foo_.url().host(),
            cookie_changes_1[0].first.Domain());

  ASSERT_LE(1u, cookie_changes_2.size());
  EXPECT_EQ("A", cookie_changes_2[0].first.Name());
  EXPECT_EQ("B", cookie_changes_2[0].first.Value());
  EXPECT_EQ("/", cookie_changes_2[0].first.Path());
  EXPECT_EQ(this->http_www_foo_.url().host(),
            cookie_changes_2[0].first.Domain());

  ASSERT_LE(2u, cookie_changes_2.size());
  EXPECT_EQ("C", cookie_changes_2[1].first.Name());
  EXPECT_EQ("D", cookie_changes_2[1].first.Value());
  EXPECT_EQ("/foo", cookie_changes_2[1].first.Path());
  EXPECT_EQ(this->http_www_foo_.url().host(),
            cookie_changes_2[1].first.Domain());

  EXPECT_EQ(2u, cookie_changes_2.size());
}

TYPED_TEST_P(CookieStoreChangeUrlTest, DifferentSubscriptionsFiltering) {
  if (!TypeParam::supports_url_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();

  std::vector<CookieChange> cookie_changes_1, cookie_changes_2;
  std::vector<CookieChange> cookie_changes_3;
  std::unique_ptr<CookieChangeSubscription> subscription1 =
      cs->GetChangeDispatcher().AddCallbackForUrl(
          this->http_www_foo_.url(),
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_1)));
  std::unique_ptr<CookieChangeSubscription> subscription2 =
      cs->GetChangeDispatcher().AddCallbackForUrl(
          this->http_bar_com_.url(),
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_2)));
  std::unique_ptr<CookieChangeSubscription> subscription3 =
      cs->GetChangeDispatcher().AddCallbackForUrl(
          this->www_foo_foo_.url(),
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_3)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes_1.size());
  ASSERT_EQ(0u, cookie_changes_2.size());
  EXPECT_EQ(0u, cookie_changes_3.size());

  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
  this->DeliverChangeNotifications();
  EXPECT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ(0u, cookie_changes_2.size());
  EXPECT_EQ(1u, cookie_changes_3.size());

  EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "C=D"));
  this->DeliverChangeNotifications();
  EXPECT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ(1u, cookie_changes_2.size());
  EXPECT_EQ(1u, cookie_changes_3.size());

  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "E=F; path=/foo"));
  this->DeliverChangeNotifications();

  ASSERT_LE(1u, cookie_changes_1.size());
  EXPECT_EQ("A", cookie_changes_1[0].first.Name());
  EXPECT_EQ("B", cookie_changes_1[0].first.Value());
  EXPECT_EQ(this->http_www_foo_.url().host(),
            cookie_changes_1[0].first.Domain());
  EXPECT_EQ(1u, cookie_changes_1.size());

  ASSERT_LE(1u, cookie_changes_2.size());
  EXPECT_EQ("C", cookie_changes_2[0].first.Name());
  EXPECT_EQ("D", cookie_changes_2[0].first.Value());
  EXPECT_EQ(this->http_bar_com_.url().host(),
            cookie_changes_2[0].first.Domain());
  EXPECT_EQ(1u, cookie_changes_2.size());

  ASSERT_LE(1u, cookie_changes_3.size());
  EXPECT_EQ("A", cookie_changes_3[0].first.Name());
  EXPECT_EQ("B", cookie_changes_3[0].first.Value());
  EXPECT_EQ("/", cookie_changes_3[0].first.Path());
  EXPECT_EQ(this->http_www_foo_.url().host(),
            cookie_changes_3[0].first.Domain());

  ASSERT_LE(2u, cookie_changes_3.size());
  EXPECT_EQ("E", cookie_changes_3[1].first.Name());
  EXPECT_EQ("F", cookie_changes_3[1].first.Value());
  EXPECT_EQ("/foo", cookie_changes_3[1].first.Path());
  EXPECT_EQ(this->http_www_foo_.url().host(),
            cookie_changes_3[1].first.Domain());

  EXPECT_EQ(2u, cookie_changes_3.size());
}

TYPED_TEST_P(CookieStoreChangeUrlTest, MultipleSubscriptions) {
  if (!TypeParam::supports_url_cookie_tracking ||
      !TypeParam::supports_multiple_tracking_callbacks)
    return;

  CookieStore* cs = this->GetCookieStore();

  std::vector<CookieChange> cookie_changes_1, cookie_changes_2;
  std::unique_ptr<CookieChangeSubscription> subscription1 =
      cs->GetChangeDispatcher().AddCallbackForUrl(
          this->http_www_foo_.url(),
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_1)));
  std::unique_ptr<CookieChangeSubscription> subscription2 =
      cs->GetChangeDispatcher().AddCallbackForUrl(
          this->http_www_foo_.url(),
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_2)));
  this->DeliverChangeNotifications();

  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
  this->DeliverChangeNotifications();

  ASSERT_EQ(1U, cookie_changes_1.size());
  EXPECT_EQ("A", cookie_changes_1[0].first.Name());
  EXPECT_EQ("B", cookie_changes_1[0].first.Value());

  ASSERT_EQ(1U, cookie_changes_2.size());
  EXPECT_EQ("A", cookie_changes_2[0].first.Name());
  EXPECT_EQ("B", cookie_changes_2[0].first.Value());
}

TYPED_TEST_P(CookieStoreChangeNamedTest, NoCookie) {
  if (!TypeParam::supports_named_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();
  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->http_www_foo_.url(), "abc",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes)));
  this->DeliverChangeNotifications();
  EXPECT_EQ(0u, cookie_changes.size());
}

TYPED_TEST_P(CookieStoreChangeNamedTest, InitialCookie) {
  if (!TypeParam::supports_named_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();
  std::vector<CookieChange> cookie_changes;
  this->SetCookie(cs, this->http_www_foo_.url(), "abc=def");
  this->DeliverChangeNotifications();
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->http_www_foo_.url(), "abc",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes)));
  this->DeliverChangeNotifications();
  EXPECT_EQ(0u, cookie_changes.size());
}

TYPED_TEST_P(CookieStoreChangeNamedTest, InsertOne) {
  if (!TypeParam::supports_named_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();
  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->http_www_foo_.url(), "abc",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes.size());

  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
  this->DeliverChangeNotifications();
  ASSERT_EQ(1u, cookie_changes.size());

  EXPECT_EQ("abc", cookie_changes[0].first.Name());
  EXPECT_EQ("def", cookie_changes[0].first.Value());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[0].second));
}

TYPED_TEST_P(CookieStoreChangeNamedTest, InsertTwo) {
  if (!TypeParam::supports_named_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();
  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->www_foo_foo_.url(), "abc",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes.size());

  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "abc=hij; path=/foo"));
  this->DeliverChangeNotifications();

  ASSERT_LE(1u, cookie_changes.size());
  EXPECT_EQ("abc", cookie_changes[0].first.Name());
  EXPECT_EQ("def", cookie_changes[0].first.Value());
  EXPECT_EQ("/", cookie_changes[0].first.Path());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[0].second));

  ASSERT_LE(2u, cookie_changes.size());
  EXPECT_EQ("abc", cookie_changes[1].first.Name());
  EXPECT_EQ("hij", cookie_changes[1].first.Value());
  EXPECT_EQ("/foo", cookie_changes[1].first.Path());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[1].second));

  EXPECT_EQ(2u, cookie_changes.size());
}

TYPED_TEST_P(CookieStoreChangeNamedTest, InsertFiltering) {
  if (!TypeParam::supports_named_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();
  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->www_foo_foo_.url(), "abc",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes.size());

  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "abc=def; path=/"));
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_bar_com_.url(), "abc=ghi; path=/"));
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "abc=jkl; path=/bar"));
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "abc=mno; path=/foo/bar"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "xyz=zyx"));
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "abc=pqr; path=/foo"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
                              "abc=stu; domain=foo.com"));
  this->DeliverChangeNotifications();

  ASSERT_LE(1u, cookie_changes.size());
  EXPECT_EQ("abc", cookie_changes[0].first.Name());
  EXPECT_EQ("def", cookie_changes[0].first.Value());
  EXPECT_EQ("/", cookie_changes[0].first.Path());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[0].second));

  ASSERT_LE(2u, cookie_changes.size());
  EXPECT_EQ("abc", cookie_changes[1].first.Name());
  EXPECT_EQ("pqr", cookie_changes[1].first.Value());
  EXPECT_EQ("/foo", cookie_changes[1].first.Path());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[1].second));

  ASSERT_LE(3u, cookie_changes.size());
  EXPECT_EQ("abc", cookie_changes[2].first.Name());
  EXPECT_EQ("stu", cookie_changes[2].first.Value());
  EXPECT_EQ("/", cookie_changes[2].first.Path());
  EXPECT_EQ(".foo.com", cookie_changes[2].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[2].second));

  EXPECT_EQ(3u, cookie_changes.size());
}

TYPED_TEST_P(CookieStoreChangeNamedTest, DeleteOne) {
  if (!TypeParam::supports_named_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();
  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->http_www_foo_.url(), "abc",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes)));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
  this->DeliverChangeNotifications();
  EXPECT_EQ(1u, cookie_changes.size());
  cookie_changes.clear();

  EXPECT_TRUE(
      this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "abc"));
  this->DeliverChangeNotifications();

  ASSERT_EQ(1u, cookie_changes.size());
  EXPECT_EQ("abc", cookie_changes[0].first.Name());
  EXPECT_EQ("def", cookie_changes[0].first.Value());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::EXPLICIT,
                                 cookie_changes[0].second));
}

TYPED_TEST_P(CookieStoreChangeNamedTest, DeleteTwo) {
  if (!TypeParam::supports_named_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();
  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->www_foo_foo_.url(), "abc",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes)));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "abc=hij; path=/foo"));
  this->DeliverChangeNotifications();
  EXPECT_EQ(2u, cookie_changes.size());
  cookie_changes.clear();

  EXPECT_TRUE(this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(),
                                        "abc", "/"));
  EXPECT_TRUE(this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(),
                                        "abc", "/foo"));
  this->DeliverChangeNotifications();

  ASSERT_LE(1u, cookie_changes.size());
  EXPECT_EQ("abc", cookie_changes[0].first.Name());
  EXPECT_EQ("def", cookie_changes[0].first.Value());
  EXPECT_EQ("/", cookie_changes[0].first.Path());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::EXPLICIT,
                                 cookie_changes[0].second));

  ASSERT_EQ(2u, cookie_changes.size());
  EXPECT_EQ("abc", cookie_changes[1].first.Name());
  EXPECT_EQ("hij", cookie_changes[1].first.Value());
  EXPECT_EQ("/foo", cookie_changes[1].first.Path());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::EXPLICIT,
                                 cookie_changes[1].second));
}

TYPED_TEST_P(CookieStoreChangeNamedTest, DeleteFiltering) {
  if (!TypeParam::supports_named_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();
  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->www_foo_foo_.url(), "abc",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes)));
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "xyz=zyx; path=/"));
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_bar_com_.url(), "abc=def; path=/"));
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "abc=hij; path=/foo/bar"));
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "abc=mno; path=/foo"));
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "abc=pqr; path=/"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
                              "abc=stu; domain=foo.com"));
  this->DeliverChangeNotifications();
  EXPECT_EQ(3u, cookie_changes.size());
  cookie_changes.clear();

  EXPECT_TRUE(
      this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "xyz"));
  EXPECT_TRUE(
      this->FindAndDeleteCookie(cs, this->http_bar_com_.url().host(), "abc"));
  EXPECT_TRUE(this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(),
                                        "abc", "/foo/bar"));
  EXPECT_TRUE(this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(),
                                        "abc", "/foo"));
  EXPECT_TRUE(this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(),
                                        "abc", "/"));
  EXPECT_TRUE(this->FindAndDeleteCookie(cs, ".foo.com", "abc", "/"));
  this->DeliverChangeNotifications();

  ASSERT_LE(1u, cookie_changes.size());
  EXPECT_EQ("abc", cookie_changes[0].first.Name());
  EXPECT_EQ("mno", cookie_changes[0].first.Value());
  EXPECT_EQ("/foo", cookie_changes[0].first.Path());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::EXPLICIT,
                                 cookie_changes[0].second));

  ASSERT_LE(2u, cookie_changes.size());
  EXPECT_EQ("abc", cookie_changes[1].first.Name());
  EXPECT_EQ("pqr", cookie_changes[1].first.Value());
  EXPECT_EQ("/", cookie_changes[1].first.Path());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::EXPLICIT,
                                 cookie_changes[1].second));

  ASSERT_LE(3u, cookie_changes.size());
  EXPECT_EQ("abc", cookie_changes[2].first.Name());
  EXPECT_EQ("stu", cookie_changes[2].first.Value());
  EXPECT_EQ("/", cookie_changes[2].first.Path());
  EXPECT_EQ(".foo.com", cookie_changes[2].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::EXPLICIT,
                                 cookie_changes[2].second));

  EXPECT_EQ(3u, cookie_changes.size());
}

TYPED_TEST_P(CookieStoreChangeNamedTest, Overwrite) {
  if (!TypeParam::supports_named_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();
  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->http_www_foo_.url(), "abc",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes.size());

  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
  this->DeliverChangeNotifications();
  EXPECT_EQ(1u, cookie_changes.size());
  cookie_changes.clear();

  // Replacing an existing cookie is actually a two-phase delete + set
  // operation, so we get an extra notification.
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=ghi"));
  this->DeliverChangeNotifications();

  EXPECT_LE(1u, cookie_changes.size());
  EXPECT_EQ("abc", cookie_changes[0].first.Name());
  EXPECT_EQ("def", cookie_changes[0].first.Value());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
                                 cookie_changes[0].second));

  EXPECT_LE(2u, cookie_changes.size());
  EXPECT_EQ("abc", cookie_changes[1].first.Name());
  EXPECT_EQ("ghi", cookie_changes[1].first.Value());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[1].second));

  EXPECT_EQ(2u, cookie_changes.size());
}

TYPED_TEST_P(CookieStoreChangeNamedTest, OverwriteFiltering) {
  if (!TypeParam::supports_named_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();
  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->www_foo_foo_.url(), "abc",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes.size());

  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "xyz=zyx1; path=/"));
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_bar_com_.url(), "abc=def1; path=/"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
                              "abc=hij1; path=/foo/bar"));
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "abc=mno1; path=/foo"));
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "abc=pqr1; path=/"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
                              "abc=stu1; domain=foo.com"));
  this->DeliverChangeNotifications();
  EXPECT_EQ(3u, cookie_changes.size());
  cookie_changes.clear();

  // Replacing an existing cookie is actually a two-phase delete + set
  // operation, so we get two notifications per overwrite.
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "xyz=zyx2; path=/"));
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_bar_com_.url(), "abc=def2; path=/"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
                              "abc=hij2; path=/foo/bar"));
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "abc=mno2; path=/foo"));
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "abc=pqr2; path=/"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
                              "abc=stu2; domain=foo.com"));
  this->DeliverChangeNotifications();

  ASSERT_LE(1u, cookie_changes.size());
  EXPECT_EQ("abc", cookie_changes[0].first.Name());
  EXPECT_EQ("mno1", cookie_changes[0].first.Value());
  EXPECT_EQ("/foo", cookie_changes[0].first.Path());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
                                 cookie_changes[0].second));

  ASSERT_LE(2u, cookie_changes.size());
  EXPECT_EQ("abc", cookie_changes[1].first.Name());
  EXPECT_EQ("mno2", cookie_changes[1].first.Value());
  EXPECT_EQ("/foo", cookie_changes[1].first.Path());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[1].second));

  ASSERT_LE(3u, cookie_changes.size());
  EXPECT_EQ("abc", cookie_changes[2].first.Name());
  EXPECT_EQ("pqr1", cookie_changes[2].first.Value());
  EXPECT_EQ("/", cookie_changes[2].first.Path());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[2].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
                                 cookie_changes[2].second));

  ASSERT_LE(4u, cookie_changes.size());
  EXPECT_EQ("abc", cookie_changes[3].first.Name());
  EXPECT_EQ("pqr2", cookie_changes[3].first.Value());
  EXPECT_EQ("/", cookie_changes[3].first.Path());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[3].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[3].second));

  ASSERT_LE(5u, cookie_changes.size());
  EXPECT_EQ("abc", cookie_changes[4].first.Name());
  EXPECT_EQ("stu1", cookie_changes[4].first.Value());
  EXPECT_EQ("/", cookie_changes[4].first.Path());
  EXPECT_EQ(".foo.com", cookie_changes[4].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
                                 cookie_changes[4].second));

  ASSERT_LE(6u, cookie_changes.size());
  EXPECT_EQ("abc", cookie_changes[5].first.Name());
  EXPECT_EQ("stu2", cookie_changes[5].first.Value());
  EXPECT_EQ("/", cookie_changes[5].first.Path());
  EXPECT_EQ(".foo.com", cookie_changes[5].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[5].second));

  EXPECT_EQ(6u, cookie_changes.size());
}

TYPED_TEST_P(CookieStoreChangeNamedTest, OverwriteWithHttpOnly) {
  if (!TypeParam::supports_named_cookie_tracking)
    return;

  // Insert a cookie "abc" for path "/foo".
  CookieStore* cs = this->GetCookieStore();
  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->www_foo_foo_.url(), "abc",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes.size());

  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "abc=def; path=/foo"));
  this->DeliverChangeNotifications();
  ASSERT_EQ(1u, cookie_changes.size());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[0].second));
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
  EXPECT_EQ("abc", cookie_changes[0].first.Name());
  EXPECT_EQ("def", cookie_changes[0].first.Value());
  EXPECT_FALSE(cookie_changes[0].first.IsHttpOnly());
  cookie_changes.clear();

  // Insert a cookie "a" for path "/foo", that is httponly. This should
  // overwrite the non-http-only version.
  CookieOptions allow_httponly;
  allow_httponly.set_include_httponly();
  EXPECT_TRUE(this->SetCookieWithOptions(cs, this->http_www_foo_.url(),
                                         "abc=hij; path=/foo; httponly",
                                         allow_httponly));
  this->DeliverChangeNotifications();

  ASSERT_LE(1u, cookie_changes.size());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
                                 cookie_changes[0].second));
  EXPECT_EQ("abc", cookie_changes[0].first.Name());
  EXPECT_EQ("def", cookie_changes[0].first.Value());
  EXPECT_FALSE(cookie_changes[0].first.IsHttpOnly());

  ASSERT_LE(2u, cookie_changes.size());
  EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
  EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
                                 cookie_changes[1].second));
  EXPECT_EQ("abc", cookie_changes[1].first.Name());
  EXPECT_EQ("hij", cookie_changes[1].first.Value());
  EXPECT_TRUE(cookie_changes[1].first.IsHttpOnly());

  EXPECT_EQ(2u, cookie_changes.size());
}

TYPED_TEST_P(CookieStoreChangeNamedTest, Deregister) {
  if (!TypeParam::supports_named_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();

  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->www_foo_foo_.url(), "abc",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes.size());

  // Insert a cookie and make sure it is seen.
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "abc=def; path=/foo"));
  this->DeliverChangeNotifications();
  ASSERT_EQ(1u, cookie_changes.size());
  EXPECT_EQ("abc", cookie_changes[0].first.Name());
  EXPECT_EQ("def", cookie_changes[0].first.Value());
  EXPECT_EQ("/foo", cookie_changes[0].first.Path());
  cookie_changes.clear();

  // De-register the subscription.
  subscription.reset();

  // Insert a second cookie and make sure it's not visible.
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "abc=hij; path=/"));
  this->DeliverChangeNotifications();

  EXPECT_EQ(0u, cookie_changes.size());
}

TYPED_TEST_P(CookieStoreChangeNamedTest, DeregisterMultiple) {
  if (!TypeParam::supports_named_cookie_tracking ||
      !TypeParam::supports_multiple_tracking_callbacks)
    return;

  CookieStore* cs = this->GetCookieStore();

  // Register two subscriptions.
  std::vector<CookieChange> cookie_changes_1, cookie_changes_2;
  std::unique_ptr<CookieChangeSubscription> subscription1 =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->www_foo_foo_.url(), "abc",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_1)));
  std::unique_ptr<CookieChangeSubscription> subscription2 =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->www_foo_foo_.url(), "abc",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_2)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes_1.size());
  ASSERT_EQ(0u, cookie_changes_2.size());

  // Insert a cookie and make sure it's seen.
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "abc=def; path=/foo"));
  this->DeliverChangeNotifications();
  ASSERT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ("abc", cookie_changes_1[0].first.Name());
  EXPECT_EQ("def", cookie_changes_1[0].first.Value());
  EXPECT_EQ("/foo", cookie_changes_1[0].first.Path());
  cookie_changes_1.clear();

  ASSERT_EQ(1u, cookie_changes_2.size());
  EXPECT_EQ("abc", cookie_changes_2[0].first.Name());
  EXPECT_EQ("def", cookie_changes_2[0].first.Value());
  EXPECT_EQ("/foo", cookie_changes_2[0].first.Path());
  cookie_changes_2.clear();

  // De-register the second registration.
  subscription2.reset();

  // Insert a second cookie and make sure that it's only visible in one
  // change array.
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "abc=hij; path=/"));
  this->DeliverChangeNotifications();
  ASSERT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ("abc", cookie_changes_1[0].first.Name());
  EXPECT_EQ("hij", cookie_changes_1[0].first.Value());
  EXPECT_EQ("/", cookie_changes_1[0].first.Path());

  EXPECT_EQ(0u, cookie_changes_2.size());
}

// Confirm that a listener does not receive notifications for changes that
// happened right before the subscription was established.
TYPED_TEST_P(CookieStoreChangeNamedTest, DispatchRace) {
  if (!TypeParam::supports_named_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();

  // This cookie insertion should not be seen.
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "abc=def; path=/foo"));
  // DeliverChangeNotifications() must NOT be called before the subscription is
  // established.

  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->www_foo_foo_.url(), "abc",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes)));

  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "abc=hij; path=/"));
  this->DeliverChangeNotifications();

  EXPECT_LE(1u, cookie_changes.size());
  EXPECT_EQ("abc", cookie_changes[0].first.Name());
  EXPECT_EQ("hij", cookie_changes[0].first.Value());
  EXPECT_EQ("/", cookie_changes[0].first.Path());

  ASSERT_EQ(1u, cookie_changes.size());
}

// Confirm that deregistering a subscription blocks the notification if the
// deregistration happened after the change but before the notification was
// received.
TYPED_TEST_P(CookieStoreChangeNamedTest, DeregisterRace) {
  if (!TypeParam::supports_named_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();

  std::vector<CookieChange> cookie_changes;
  std::unique_ptr<CookieChangeSubscription> subscription =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->www_foo_foo_.url(), "abc",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes.size());

  // Insert a cookie and make sure it's seen.
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "abc=def; path=/foo"));
  this->DeliverChangeNotifications();
  ASSERT_EQ(1u, cookie_changes.size());
  EXPECT_EQ("abc", cookie_changes[0].first.Name());
  EXPECT_EQ("def", cookie_changes[0].first.Value());
  EXPECT_EQ("/foo", cookie_changes[0].first.Path());
  cookie_changes.clear();

  // Insert a cookie, confirm it is not seen, deregister the subscription, run
  // until idle, and confirm the cookie is still not seen.
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "abc=hij; path=/"));

  // Note that by the API contract it's perfectly valid to have received the
  // notification immediately, i.e. synchronously with the cookie change. In
  // that case, there's nothing to test.
  if (1u == cookie_changes.size())
    return;

  // A task was posted by the SetCookie() above, but has not yet arrived. If it
  // arrived before the subscription is destroyed, callback execution would be
  // valid. Destroy the subscription so as to lose the race and make sure the
  // task posted arrives after the subscription was destroyed.
  subscription.reset();
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes.size());
}

TYPED_TEST_P(CookieStoreChangeNamedTest, DeregisterRaceMultiple) {
  if (!TypeParam::supports_named_cookie_tracking ||
      !TypeParam::supports_multiple_tracking_callbacks)
    return;

  CookieStore* cs = this->GetCookieStore();

  std::vector<CookieChange> cookie_changes_1, cookie_changes_2;
  std::unique_ptr<CookieChangeSubscription> subscription1 =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->www_foo_foo_.url(), "abc",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_1)));
  std::unique_ptr<CookieChangeSubscription> subscription2 =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->www_foo_foo_.url(), "abc",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_2)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes_1.size());
  ASSERT_EQ(0u, cookie_changes_2.size());

  // Insert a cookie and make sure it's seen.
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "abc=def; path=/foo"));
  this->DeliverChangeNotifications();

  ASSERT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ("abc", cookie_changes_1[0].first.Name());
  EXPECT_EQ("def", cookie_changes_1[0].first.Value());
  EXPECT_EQ("/foo", cookie_changes_1[0].first.Path());
  cookie_changes_1.clear();

  ASSERT_EQ(1u, cookie_changes_2.size());
  EXPECT_EQ("abc", cookie_changes_2[0].first.Name());
  EXPECT_EQ("def", cookie_changes_2[0].first.Value());
  EXPECT_EQ("/foo", cookie_changes_2[0].first.Path());
  cookie_changes_2.clear();

  // Insert a cookie, confirm it is not seen, deregister a subscription, run
  // until idle, and confirm the cookie is still not seen.
  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "abc=hij; path=/"));

  // Note that by the API contract it's perfectly valid to have received the
  // notification immediately, i.e. synchronously with the cookie change. In
  // that case, there's nothing to test.
  if (1u == cookie_changes_2.size())
    return;

  // A task was posted by the SetCookie() above, but has not yet arrived. If it
  // arrived before the subscription is destroyed, callback execution would be
  // valid. Destroy one of the subscriptions so as to lose the race and make
  // sure the task posted arrives after the subscription was destroyed.
  subscription2.reset();
  this->DeliverChangeNotifications();
  ASSERT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ("abc", cookie_changes_1[0].first.Name());
  EXPECT_EQ("hij", cookie_changes_1[0].first.Value());
  EXPECT_EQ("/", cookie_changes_1[0].first.Path());

  // No late notification was received.
  ASSERT_EQ(0u, cookie_changes_2.size());
}

TYPED_TEST_P(CookieStoreChangeNamedTest, DifferentSubscriptionsDisjoint) {
  if (!TypeParam::supports_named_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();

  std::vector<CookieChange> cookie_changes_1, cookie_changes_2;
  std::unique_ptr<CookieChangeSubscription> subscription1 =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->http_www_foo_.url(), "abc",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_1)));
  std::unique_ptr<CookieChangeSubscription> subscription2 =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->http_bar_com_.url(), "ghi",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_2)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes_1.size());
  ASSERT_EQ(0u, cookie_changes_2.size());

  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
  this->DeliverChangeNotifications();
  EXPECT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ(0u, cookie_changes_2.size());

  EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "ghi=jkl"));
  this->DeliverChangeNotifications();

  ASSERT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ("abc", cookie_changes_1[0].first.Name());
  EXPECT_EQ("def", cookie_changes_1[0].first.Value());
  EXPECT_EQ(this->http_www_foo_.url().host(),
            cookie_changes_1[0].first.Domain());

  ASSERT_EQ(1u, cookie_changes_2.size());
  EXPECT_EQ("ghi", cookie_changes_2[0].first.Name());
  EXPECT_EQ("jkl", cookie_changes_2[0].first.Value());
  EXPECT_EQ(this->http_bar_com_.url().host(),
            cookie_changes_2[0].first.Domain());
}

TYPED_TEST_P(CookieStoreChangeNamedTest, DifferentSubscriptionsDomains) {
  if (!TypeParam::supports_named_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();

  std::vector<CookieChange> cookie_changes_1, cookie_changes_2;
  std::unique_ptr<CookieChangeSubscription> subscription1 =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->http_www_foo_.url(), "abc",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_1)));
  std::unique_ptr<CookieChangeSubscription> subscription2 =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->http_bar_com_.url(), "abc",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_2)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes_1.size());
  ASSERT_EQ(0u, cookie_changes_2.size());

  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
  this->DeliverChangeNotifications();
  EXPECT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ(0u, cookie_changes_2.size());

  EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "abc=ghi"));
  this->DeliverChangeNotifications();

  ASSERT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ("abc", cookie_changes_1[0].first.Name());
  EXPECT_EQ("def", cookie_changes_1[0].first.Value());
  EXPECT_EQ(this->http_www_foo_.url().host(),
            cookie_changes_1[0].first.Domain());

  ASSERT_EQ(1u, cookie_changes_2.size());
  EXPECT_EQ("abc", cookie_changes_2[0].first.Name());
  EXPECT_EQ("ghi", cookie_changes_2[0].first.Value());
  EXPECT_EQ(this->http_bar_com_.url().host(),
            cookie_changes_2[0].first.Domain());
}

TYPED_TEST_P(CookieStoreChangeNamedTest, DifferentSubscriptionsNames) {
  if (!TypeParam::supports_named_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();

  std::vector<CookieChange> cookie_changes_1, cookie_changes_2;
  std::unique_ptr<CookieChangeSubscription> subscription1 =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->http_www_foo_.url(), "abc",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_1)));
  std::unique_ptr<CookieChangeSubscription> subscription2 =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->http_www_foo_.url(), "ghi",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_2)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes_1.size());
  ASSERT_EQ(0u, cookie_changes_2.size());

  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
  this->DeliverChangeNotifications();
  EXPECT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ(0u, cookie_changes_2.size());

  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "ghi=jkl"));
  this->DeliverChangeNotifications();

  ASSERT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ("abc", cookie_changes_1[0].first.Name());
  EXPECT_EQ("def", cookie_changes_1[0].first.Value());
  EXPECT_EQ(this->http_www_foo_.url().host(),
            cookie_changes_1[0].first.Domain());

  ASSERT_EQ(1u, cookie_changes_2.size());
  EXPECT_EQ("ghi", cookie_changes_2[0].first.Name());
  EXPECT_EQ("jkl", cookie_changes_2[0].first.Value());
  EXPECT_EQ(this->http_www_foo_.url().host(),
            cookie_changes_2[0].first.Domain());
}

TYPED_TEST_P(CookieStoreChangeNamedTest, DifferentSubscriptionsPaths) {
  if (!TypeParam::supports_named_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();

  std::vector<CookieChange> cookie_changes_1, cookie_changes_2;
  std::unique_ptr<CookieChangeSubscription> subscription1 =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->http_www_foo_.url(), "abc",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_1)));
  std::unique_ptr<CookieChangeSubscription> subscription2 =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->www_foo_foo_.url(), "abc",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_2)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes_1.size());
  ASSERT_EQ(0u, cookie_changes_2.size());

  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
  this->DeliverChangeNotifications();
  EXPECT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ(1u, cookie_changes_2.size());

  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "abc=ghi; path=/foo"));
  this->DeliverChangeNotifications();

  ASSERT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ("abc", cookie_changes_1[0].first.Name());
  EXPECT_EQ("def", cookie_changes_1[0].first.Value());
  EXPECT_EQ("/", cookie_changes_1[0].first.Path());
  EXPECT_EQ(this->http_www_foo_.url().host(),
            cookie_changes_1[0].first.Domain());

  ASSERT_LE(1u, cookie_changes_2.size());
  EXPECT_EQ("abc", cookie_changes_2[0].first.Name());
  EXPECT_EQ("def", cookie_changes_2[0].first.Value());
  EXPECT_EQ("/", cookie_changes_2[0].first.Path());
  EXPECT_EQ(this->http_www_foo_.url().host(),
            cookie_changes_2[0].first.Domain());

  ASSERT_LE(2u, cookie_changes_2.size());
  EXPECT_EQ("abc", cookie_changes_2[1].first.Name());
  EXPECT_EQ("ghi", cookie_changes_2[1].first.Value());
  EXPECT_EQ("/foo", cookie_changes_2[1].first.Path());
  EXPECT_EQ(this->http_www_foo_.url().host(),
            cookie_changes_2[1].first.Domain());

  EXPECT_EQ(2u, cookie_changes_2.size());
}

TYPED_TEST_P(CookieStoreChangeNamedTest, DifferentSubscriptionsFiltering) {
  if (!TypeParam::supports_named_cookie_tracking)
    return;

  CookieStore* cs = this->GetCookieStore();

  std::vector<CookieChange> cookie_changes_1, cookie_changes_2;
  std::vector<CookieChange> cookie_changes_3, cookie_changes_4;
  std::unique_ptr<CookieChangeSubscription> subscription1 =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->http_www_foo_.url(), "abc",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_1)));
  std::unique_ptr<CookieChangeSubscription> subscription2 =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->http_www_foo_.url(), "hij",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_2)));
  std::unique_ptr<CookieChangeSubscription> subscription3 =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->http_bar_com_.url(), "abc",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_3)));
  std::unique_ptr<CookieChangeSubscription> subscription4 =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->www_foo_foo_.url(), "abc",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_4)));
  this->DeliverChangeNotifications();
  ASSERT_EQ(0u, cookie_changes_1.size());
  ASSERT_EQ(0u, cookie_changes_2.size());
  EXPECT_EQ(0u, cookie_changes_3.size());
  EXPECT_EQ(0u, cookie_changes_4.size());

  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
  this->DeliverChangeNotifications();
  EXPECT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ(0u, cookie_changes_2.size());
  EXPECT_EQ(0u, cookie_changes_3.size());
  EXPECT_EQ(1u, cookie_changes_4.size());

  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "xyz=zyx"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "hij=mno"));
  this->DeliverChangeNotifications();
  EXPECT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ(1u, cookie_changes_2.size());
  EXPECT_EQ(0u, cookie_changes_3.size());
  EXPECT_EQ(1u, cookie_changes_4.size());

  EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "hij=pqr"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "xyz=zyx"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "abc=stu"));
  this->DeliverChangeNotifications();
  EXPECT_EQ(1u, cookie_changes_1.size());
  EXPECT_EQ(1u, cookie_changes_2.size());
  EXPECT_EQ(1u, cookie_changes_3.size());
  EXPECT_EQ(1u, cookie_changes_4.size());

  EXPECT_TRUE(
      this->SetCookie(cs, this->http_www_foo_.url(), "abc=vwx; path=/foo"));
  this->DeliverChangeNotifications();

  ASSERT_LE(1u, cookie_changes_1.size());
  EXPECT_EQ("abc", cookie_changes_1[0].first.Name());
  EXPECT_EQ("def", cookie_changes_1[0].first.Value());
  EXPECT_EQ(this->http_www_foo_.url().host(),
            cookie_changes_1[0].first.Domain());
  EXPECT_EQ(1u, cookie_changes_1.size());

  ASSERT_LE(1u, cookie_changes_2.size());
  EXPECT_EQ("hij", cookie_changes_2[0].first.Name());
  EXPECT_EQ("mno", cookie_changes_2[0].first.Value());
  EXPECT_EQ(this->http_www_foo_.url().host(),
            cookie_changes_2[0].first.Domain());
  EXPECT_EQ(1u, cookie_changes_2.size());

  ASSERT_LE(1u, cookie_changes_3.size());
  EXPECT_EQ("abc", cookie_changes_3[0].first.Name());
  EXPECT_EQ("stu", cookie_changes_3[0].first.Value());
  EXPECT_EQ(this->http_bar_com_.url().host(),
            cookie_changes_3[0].first.Domain());
  EXPECT_EQ(1u, cookie_changes_3.size());

  ASSERT_LE(1u, cookie_changes_4.size());
  EXPECT_EQ("abc", cookie_changes_4[0].first.Name());
  EXPECT_EQ("def", cookie_changes_4[0].first.Value());
  EXPECT_EQ("/", cookie_changes_4[0].first.Path());
  EXPECT_EQ(this->http_www_foo_.url().host(),
            cookie_changes_4[0].first.Domain());

  ASSERT_LE(2u, cookie_changes_4.size());
  EXPECT_EQ("abc", cookie_changes_4[1].first.Name());
  EXPECT_EQ("vwx", cookie_changes_4[1].first.Value());
  EXPECT_EQ("/foo", cookie_changes_4[1].first.Path());
  EXPECT_EQ(this->http_www_foo_.url().host(),
            cookie_changes_4[1].first.Domain());

  EXPECT_EQ(2u, cookie_changes_4.size());
}

TYPED_TEST_P(CookieStoreChangeNamedTest, MultipleSubscriptions) {
  if (!TypeParam::supports_named_cookie_tracking ||
      !TypeParam::supports_multiple_tracking_callbacks)
    return;

  CookieStore* cs = this->GetCookieStore();

  std::vector<CookieChange> cookie_changes_1, cookie_changes_2;
  std::unique_ptr<CookieChangeSubscription> subscription1 =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->http_www_foo_.url(), "abc",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_1)));
  std::unique_ptr<CookieChangeSubscription> subscription2 =
      cs->GetChangeDispatcher().AddCallbackForCookie(
          this->http_www_foo_.url(), "abc",
          base::BindRepeating(
              &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
              base::Unretained(&cookie_changes_2)));
  this->DeliverChangeNotifications();

  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "xyz=zyx"));
  EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
  this->DeliverChangeNotifications();

  ASSERT_EQ(1U, cookie_changes_1.size());
  EXPECT_EQ("abc", cookie_changes_1[0].first.Name());
  EXPECT_EQ("def", cookie_changes_1[0].first.Value());
  cookie_changes_1.clear();

  ASSERT_EQ(1U, cookie_changes_2.size());
  EXPECT_EQ("abc", cookie_changes_2[0].first.Name());
  EXPECT_EQ("def", cookie_changes_2[0].first.Value());
  cookie_changes_2.clear();
}

REGISTER_TYPED_TEST_CASE_P(CookieStoreChangeGlobalTest,
                           NoCookie,
                           InitialCookie,
                           InsertOne,
                           InsertMany,
                           DeleteOne,
                           DeleteTwo,
                           Overwrite,
                           OverwriteWithHttpOnly,
                           Deregister,
                           DeregisterMultiple,
                           DispatchRace,
                           DeregisterRace,
                           DeregisterRaceMultiple,
                           MultipleSubscriptions);

REGISTER_TYPED_TEST_CASE_P(CookieStoreChangeUrlTest,
                           NoCookie,
                           InitialCookie,
                           InsertOne,
                           InsertMany,
                           InsertFiltering,
                           DeleteOne,
                           DeleteTwo,
                           DeleteFiltering,
                           Overwrite,
                           OverwriteFiltering,
                           OverwriteWithHttpOnly,
                           Deregister,
                           DeregisterMultiple,
                           DispatchRace,
                           DeregisterRace,
                           DeregisterRaceMultiple,
                           DifferentSubscriptionsDisjoint,
                           DifferentSubscriptionsDomains,
                           DifferentSubscriptionsPaths,
                           DifferentSubscriptionsFiltering,
                           MultipleSubscriptions);

REGISTER_TYPED_TEST_CASE_P(CookieStoreChangeNamedTest,
                           NoCookie,
                           InitialCookie,
                           InsertOne,
                           InsertTwo,
                           InsertFiltering,
                           DeleteOne,
                           DeleteTwo,
                           DeleteFiltering,
                           Overwrite,
                           OverwriteFiltering,
                           OverwriteWithHttpOnly,
                           Deregister,
                           DeregisterMultiple,
                           DispatchRace,
                           DeregisterRace,
                           DeregisterRaceMultiple,
                           DifferentSubscriptionsDisjoint,
                           DifferentSubscriptionsDomains,
                           DifferentSubscriptionsNames,
                           DifferentSubscriptionsPaths,
                           DifferentSubscriptionsFiltering,
                           MultipleSubscriptions);

}  // namespace net

#endif  // NET_COOKIES_COOKIE_STORE_CHANGE_UNITTEST_H
