• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef NET_COOKIES_COOKIE_STORE_CHANGE_UNITTEST_H_
6 #define NET_COOKIES_COOKIE_STORE_CHANGE_UNITTEST_H_
7 
8 #include "base/functional/bind.h"
9 #include "net/cookies/canonical_cookie.h"
10 #include "net/cookies/cookie_change_dispatcher_test_helpers.h"
11 #include "net/cookies/cookie_constants.h"
12 #include "net/cookies/cookie_store.h"
13 #include "net/cookies/cookie_store_unittest.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "url/gurl.h"
16 
17 namespace net {
18 
19 namespace {
20 
21 // Used to sort CookieChanges when testing stores without exact change ordering.
22 //
23 // The ordering relation must match the order in which the tests below issue
24 // cookie calls. Changes to this method should be tested by running the tests
25 // below with CookieMonsterTestTraits::has_exact_change_ordering set to both
26 // true and false.
CookieChangeLessThan(const CookieChangeInfo & lhs,const CookieChangeInfo & rhs)27 bool CookieChangeLessThan(const CookieChangeInfo& lhs,
28                           const CookieChangeInfo& rhs) {
29   if (lhs.cookie.Name() != rhs.cookie.Name())
30     return lhs.cookie.Name() < rhs.cookie.Name();
31 
32   if (lhs.cookie.Value() != rhs.cookie.Value())
33     return lhs.cookie.Value() < rhs.cookie.Value();
34 
35   if (lhs.cookie.Domain() != rhs.cookie.Domain())
36     return lhs.cookie.Domain() < rhs.cookie.Domain();
37 
38   return lhs.cause < rhs.cause;
39 }
40 
41 }  // namespace
42 
43 // Google Test supports at most 50 tests per typed case, so the tests here are
44 // broken up into multiple cases.
45 template <class CookieStoreTestTraits>
46 class CookieStoreChangeTestBase
47     : public CookieStoreTest<CookieStoreTestTraits> {
48  protected:
49   using CookieStoreTest<CookieStoreTestTraits>::FindAndDeleteCookie;
50 
51   // Drains all pending tasks on the run loop(s) involved in the test.
DeliverChangeNotifications()52   void DeliverChangeNotifications() {
53     CookieStoreTestTraits::DeliverChangeNotifications();
54   }
55 
FindAndDeleteCookie(CookieStore * cs,const std::string & domain,const std::string & name,const std::string & path)56   bool FindAndDeleteCookie(CookieStore* cs,
57                            const std::string& domain,
58                            const std::string& name,
59                            const std::string& path) {
60     for (auto& cookie : this->GetAllCookies(cs)) {
61       if (cookie.Domain() == domain && cookie.Name() == name &&
62           cookie.Path() == path) {
63         return this->DeleteCanonicalCookie(cs, cookie);
64       }
65     }
66 
67     return false;
68   }
69 
70   // Could be static, but it's actually easier to have it be a member function.
MatchesCause(CookieChangeCause expected_cause,CookieChangeCause actual_cause)71   ::testing::AssertionResult MatchesCause(CookieChangeCause expected_cause,
72                                           CookieChangeCause actual_cause) {
73     if (!CookieChangeCauseIsDeletion(expected_cause) ||
74         CookieStoreTestTraits::has_exact_change_cause) {
75       if (expected_cause == actual_cause)
76         return ::testing::AssertionSuccess();
77       return ::testing::AssertionFailure()
78              << "expected " << expected_cause << " got " << actual_cause;
79     }
80     if (CookieChangeCauseIsDeletion(actual_cause))
81       return ::testing::AssertionSuccess();
82     return ::testing::AssertionFailure()
83            << "expected a deletion cause, got " << actual_cause;
84   }
85 
IsExpectedAccessSemantics(net::CookieAccessSemantics expected_semantics,net::CookieAccessSemantics actual_semantics)86   bool IsExpectedAccessSemantics(net::CookieAccessSemantics expected_semantics,
87                                  net::CookieAccessSemantics actual_semantics) {
88     if (CookieStoreTestTraits::supports_cookie_access_semantics)
89       return expected_semantics == actual_semantics;
90     return actual_semantics == net::CookieAccessSemantics::UNKNOWN;
91   }
92 
OnCookieChange(std::vector<CookieChangeInfo> * changes,const CookieChangeInfo & notification)93   static void OnCookieChange(std::vector<CookieChangeInfo>* changes,
94                              const CookieChangeInfo& notification) {
95     if (CookieStoreTestTraits::has_exact_change_ordering) {
96       changes->push_back(notification);
97     } else {
98       // Assumes the vector is sorted before the insertion. If true, the vector
99       // will remain sorted.
100       changes->insert(std::upper_bound(changes->begin(), changes->end(),
101                                        notification, CookieChangeLessThan),
102                       notification);
103     }
104   }
105 };
106 
107 template <class CookieStoreTestTraits>
108 class CookieStoreChangeGlobalTest
109     : public CookieStoreChangeTestBase<CookieStoreTestTraits> {};
110 TYPED_TEST_SUITE_P(CookieStoreChangeGlobalTest);
111 
112 template <class CookieStoreTestTraits>
113 class CookieStoreChangeUrlTest
114     : public CookieStoreChangeTestBase<CookieStoreTestTraits> {};
115 TYPED_TEST_SUITE_P(CookieStoreChangeUrlTest);
116 
117 template <class CookieStoreTestTraits>
118 class CookieStoreChangeNamedTest
119     : public CookieStoreChangeTestBase<CookieStoreTestTraits> {};
120 TYPED_TEST_SUITE_P(CookieStoreChangeNamedTest);
121 
TYPED_TEST_P(CookieStoreChangeGlobalTest,NoCookie)122 TYPED_TEST_P(CookieStoreChangeGlobalTest, NoCookie) {
123   if (!TypeParam::supports_global_cookie_tracking)
124     return;
125 
126   CookieStore* cs = this->GetCookieStore();
127   std::vector<CookieChangeInfo> cookie_changes;
128   std::unique_ptr<CookieChangeSubscription> subscription =
129       cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
130           &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
131           base::Unretained(&cookie_changes)));
132   this->DeliverChangeNotifications();
133   EXPECT_EQ(0u, cookie_changes.size());
134 }
135 
TYPED_TEST_P(CookieStoreChangeGlobalTest,InitialCookie)136 TYPED_TEST_P(CookieStoreChangeGlobalTest, InitialCookie) {
137   if (!TypeParam::supports_global_cookie_tracking)
138     return;
139 
140   CookieStore* cs = this->GetCookieStore();
141   std::vector<CookieChangeInfo> cookie_changes;
142   this->SetCookie(cs, this->http_www_foo_.url(), "A=B");
143   this->DeliverChangeNotifications();
144   std::unique_ptr<CookieChangeSubscription> subscription(
145       cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
146           &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
147           base::Unretained(&cookie_changes))));
148   this->DeliverChangeNotifications();
149   EXPECT_EQ(0u, cookie_changes.size());
150 }
151 
TYPED_TEST_P(CookieStoreChangeGlobalTest,InsertOne)152 TYPED_TEST_P(CookieStoreChangeGlobalTest, InsertOne) {
153   if (!TypeParam::supports_global_cookie_tracking)
154     return;
155 
156   CookieStore* cs = this->GetCookieStore();
157   std::vector<CookieChangeInfo> cookie_changes;
158   std::unique_ptr<CookieChangeSubscription> subscription =
159       cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
160           &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
161           base::Unretained(&cookie_changes)));
162   this->DeliverChangeNotifications();
163   ASSERT_EQ(0u, cookie_changes.size());
164 
165   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
166   this->DeliverChangeNotifications();
167 
168   ASSERT_EQ(1u, cookie_changes.size());
169   EXPECT_TRUE(
170       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[0].cause));
171   EXPECT_EQ(this->http_www_foo_.url().host(),
172             cookie_changes[0].cookie.Domain());
173   EXPECT_EQ("A", cookie_changes[0].cookie.Name());
174   EXPECT_EQ("B", cookie_changes[0].cookie.Value());
175 }
176 
TYPED_TEST_P(CookieStoreChangeGlobalTest,InsertMany)177 TYPED_TEST_P(CookieStoreChangeGlobalTest, InsertMany) {
178   if (!TypeParam::supports_global_cookie_tracking)
179     return;
180 
181   CookieStore* cs = this->GetCookieStore();
182   std::vector<CookieChangeInfo> cookie_changes;
183   std::unique_ptr<CookieChangeSubscription> subscription =
184       cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
185           &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
186           base::Unretained(&cookie_changes)));
187   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
188   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
189   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "E=F"));
190   EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "G=H"));
191   this->DeliverChangeNotifications();
192 
193   // Check that the cookie changes are dispatched before calling GetCookies.
194   // This is not an ASSERT because the following expectations produce useful
195   // debugging information if they fail.
196   EXPECT_EQ(4u, cookie_changes.size());
197   EXPECT_EQ("A=B; C=D; E=F", this->GetCookies(cs, this->http_www_foo_.url()));
198   EXPECT_EQ("G=H", this->GetCookies(cs, this->http_bar_com_.url()));
199 
200   ASSERT_LE(1u, cookie_changes.size());
201   EXPECT_TRUE(
202       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[0].cause));
203   EXPECT_EQ(this->http_www_foo_.url().host(),
204             cookie_changes[0].cookie.Domain());
205   EXPECT_EQ("A", cookie_changes[0].cookie.Name());
206   EXPECT_EQ("B", cookie_changes[0].cookie.Value());
207 
208   ASSERT_LE(2u, cookie_changes.size());
209   EXPECT_EQ(this->http_www_foo_.url().host(),
210             cookie_changes[1].cookie.Domain());
211   EXPECT_TRUE(
212       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[1].cause));
213   EXPECT_EQ("C", cookie_changes[1].cookie.Name());
214   EXPECT_EQ("D", cookie_changes[1].cookie.Value());
215 
216   ASSERT_LE(3u, cookie_changes.size());
217   EXPECT_EQ(this->http_www_foo_.url().host(),
218             cookie_changes[2].cookie.Domain());
219   EXPECT_TRUE(
220       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[2].cause));
221   EXPECT_EQ("E", cookie_changes[2].cookie.Name());
222   EXPECT_EQ("F", cookie_changes[2].cookie.Value());
223 
224   ASSERT_LE(4u, cookie_changes.size());
225   EXPECT_EQ(this->http_bar_com_.url().host(),
226             cookie_changes[3].cookie.Domain());
227   EXPECT_TRUE(
228       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[3].cause));
229   EXPECT_EQ("G", cookie_changes[3].cookie.Name());
230   EXPECT_EQ("H", cookie_changes[3].cookie.Value());
231 
232   EXPECT_EQ(4u, cookie_changes.size());
233 }
234 
TYPED_TEST_P(CookieStoreChangeGlobalTest,DeleteOne)235 TYPED_TEST_P(CookieStoreChangeGlobalTest, DeleteOne) {
236   if (!TypeParam::supports_global_cookie_tracking)
237     return;
238 
239   CookieStore* cs = this->GetCookieStore();
240   std::vector<CookieChangeInfo> cookie_changes;
241   std::unique_ptr<CookieChangeSubscription> subscription =
242       cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
243           &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
244           base::Unretained(&cookie_changes)));
245   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
246   this->DeliverChangeNotifications();
247   EXPECT_EQ(1u, cookie_changes.size());
248   cookie_changes.clear();
249 
250   EXPECT_TRUE(
251       this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "A"));
252   this->DeliverChangeNotifications();
253 
254   ASSERT_EQ(1u, cookie_changes.size());
255   EXPECT_EQ(this->http_www_foo_.url().host(),
256             cookie_changes[0].cookie.Domain());
257   EXPECT_TRUE(
258       this->MatchesCause(CookieChangeCause::EXPLICIT, cookie_changes[0].cause));
259   EXPECT_EQ("A", cookie_changes[0].cookie.Name());
260   EXPECT_EQ("B", cookie_changes[0].cookie.Value());
261 }
262 
TYPED_TEST_P(CookieStoreChangeGlobalTest,DeleteTwo)263 TYPED_TEST_P(CookieStoreChangeGlobalTest, DeleteTwo) {
264   if (!TypeParam::supports_global_cookie_tracking)
265     return;
266 
267   CookieStore* cs = this->GetCookieStore();
268   std::vector<CookieChangeInfo> cookie_changes;
269   std::unique_ptr<CookieChangeSubscription> subscription =
270       cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
271           &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
272           base::Unretained(&cookie_changes)));
273   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
274   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
275   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "E=F"));
276   EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "G=H"));
277   this->DeliverChangeNotifications();
278   EXPECT_EQ(4u, cookie_changes.size());
279   cookie_changes.clear();
280 
281   EXPECT_TRUE(
282       this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "C"));
283   EXPECT_TRUE(
284       this->FindAndDeleteCookie(cs, this->http_bar_com_.url().host(), "G"));
285   this->DeliverChangeNotifications();
286 
287   // Check that the cookie changes are dispatched before calling GetCookies.
288   // This is not an ASSERT because the following expectations produce useful
289   // debugging information if they fail.
290   EXPECT_EQ(2u, cookie_changes.size());
291   EXPECT_EQ("A=B; E=F", this->GetCookies(cs, this->http_www_foo_.url()));
292   EXPECT_EQ("", this->GetCookies(cs, this->http_bar_com_.url()));
293 
294   ASSERT_LE(1u, cookie_changes.size());
295   EXPECT_EQ(this->http_www_foo_.url().host(),
296             cookie_changes[0].cookie.Domain());
297   EXPECT_TRUE(
298       this->MatchesCause(CookieChangeCause::EXPLICIT, cookie_changes[0].cause));
299   EXPECT_EQ("C", cookie_changes[0].cookie.Name());
300   EXPECT_EQ("D", cookie_changes[0].cookie.Value());
301 
302   ASSERT_EQ(2u, cookie_changes.size());
303   EXPECT_EQ(this->http_bar_com_.url().host(),
304             cookie_changes[1].cookie.Domain());
305   EXPECT_TRUE(
306       this->MatchesCause(CookieChangeCause::EXPLICIT, cookie_changes[1].cause));
307   EXPECT_EQ("G", cookie_changes[1].cookie.Name());
308   EXPECT_EQ("H", cookie_changes[1].cookie.Value());
309 }
310 
TYPED_TEST_P(CookieStoreChangeGlobalTest,Overwrite)311 TYPED_TEST_P(CookieStoreChangeGlobalTest, Overwrite) {
312   if (!TypeParam::supports_global_cookie_tracking)
313     return;
314 
315   CookieStore* cs = this->GetCookieStore();
316   std::vector<CookieChangeInfo> cookie_changes;
317   std::unique_ptr<CookieChangeSubscription> subscription =
318       cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
319           &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
320           base::Unretained(&cookie_changes)));
321   this->DeliverChangeNotifications();
322   ASSERT_EQ(0u, cookie_changes.size());
323 
324   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
325   this->DeliverChangeNotifications();
326   ASSERT_EQ(1u, cookie_changes.size());
327   cookie_changes.clear();
328 
329   // Replacing an existing cookie is actually a two-phase delete + set
330   // operation, so we get an extra notification.
331   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=C"));
332   this->DeliverChangeNotifications();
333 
334   ASSERT_LE(1u, cookie_changes.size());
335   EXPECT_EQ(this->http_www_foo_.url().host(),
336             cookie_changes[0].cookie.Domain());
337   EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
338                                  cookie_changes[0].cause));
339   EXPECT_EQ("A", cookie_changes[0].cookie.Name());
340   EXPECT_EQ("B", cookie_changes[0].cookie.Value());
341 
342   ASSERT_LE(2u, cookie_changes.size());
343   EXPECT_EQ(this->http_www_foo_.url().host(),
344             cookie_changes[1].cookie.Domain());
345   EXPECT_TRUE(
346       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[1].cause));
347   EXPECT_EQ("A", cookie_changes[1].cookie.Name());
348   EXPECT_EQ("C", cookie_changes[1].cookie.Value());
349 
350   EXPECT_EQ(2u, cookie_changes.size());
351 }
352 
TYPED_TEST_P(CookieStoreChangeGlobalTest,OverwriteWithHttpOnly)353 TYPED_TEST_P(CookieStoreChangeGlobalTest, OverwriteWithHttpOnly) {
354   if (!TypeParam::supports_global_cookie_tracking)
355     return;
356 
357   // Insert a cookie "A" for path "/path1"
358   CookieStore* cs = this->GetCookieStore();
359   std::vector<CookieChangeInfo> cookie_changes;
360   std::unique_ptr<CookieChangeSubscription> subscription =
361       cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
362           &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
363           base::Unretained(&cookie_changes)));
364   this->DeliverChangeNotifications();
365   ASSERT_EQ(0u, cookie_changes.size());
366 
367   EXPECT_TRUE(
368       this->SetCookie(cs, this->http_www_foo_.url(), "A=B; path=/path1"));
369   this->DeliverChangeNotifications();
370   ASSERT_EQ(1u, cookie_changes.size());
371   EXPECT_TRUE(
372       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[0].cause));
373   EXPECT_EQ(this->http_www_foo_.url().host(),
374             cookie_changes[0].cookie.Domain());
375   EXPECT_EQ("A", cookie_changes[0].cookie.Name());
376   EXPECT_EQ("B", cookie_changes[0].cookie.Value());
377   EXPECT_FALSE(cookie_changes[0].cookie.IsHttpOnly());
378   cookie_changes.clear();
379 
380   // Insert a cookie "A" for path "/path1", that is httponly. This should
381   // overwrite the non-http-only version.
382   CookieOptions allow_httponly;
383   allow_httponly.set_include_httponly();
384   allow_httponly.set_same_site_cookie_context(
385       net::CookieOptions::SameSiteCookieContext::MakeInclusive());
386 
387   EXPECT_TRUE(this->CreateAndSetCookie(cs, this->http_www_foo_.url(),
388                                        "A=C; path=/path1; httponly",
389                                        allow_httponly));
390   this->DeliverChangeNotifications();
391 
392   ASSERT_LE(1u, cookie_changes.size());
393   EXPECT_EQ(this->http_www_foo_.url().host(),
394             cookie_changes[0].cookie.Domain());
395   EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
396                                  cookie_changes[0].cause));
397   EXPECT_EQ("A", cookie_changes[0].cookie.Name());
398   EXPECT_EQ("B", cookie_changes[0].cookie.Value());
399   EXPECT_FALSE(cookie_changes[0].cookie.IsHttpOnly());
400 
401   ASSERT_LE(2u, cookie_changes.size());
402   EXPECT_EQ(this->http_www_foo_.url().host(),
403             cookie_changes[1].cookie.Domain());
404   EXPECT_TRUE(
405       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[1].cause));
406   EXPECT_EQ("A", cookie_changes[1].cookie.Name());
407   EXPECT_EQ("C", cookie_changes[1].cookie.Value());
408   EXPECT_TRUE(cookie_changes[1].cookie.IsHttpOnly());
409 
410   EXPECT_EQ(2u, cookie_changes.size());
411 }
412 
TYPED_TEST_P(CookieStoreChangeGlobalTest,Deregister)413 TYPED_TEST_P(CookieStoreChangeGlobalTest, Deregister) {
414   if (!TypeParam::supports_global_cookie_tracking)
415     return;
416 
417   CookieStore* cs = this->GetCookieStore();
418 
419   std::vector<CookieChangeInfo> cookie_changes;
420   std::unique_ptr<CookieChangeSubscription> subscription =
421       cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
422           &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
423           base::Unretained(&cookie_changes)));
424   this->DeliverChangeNotifications();
425   ASSERT_EQ(0u, cookie_changes.size());
426 
427   // Insert a cookie and make sure it is seen.
428   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
429   this->DeliverChangeNotifications();
430   ASSERT_EQ(1u, cookie_changes.size());
431   EXPECT_EQ("A", cookie_changes[0].cookie.Name());
432   EXPECT_EQ("B", cookie_changes[0].cookie.Value());
433   cookie_changes.clear();
434 
435   // De-register the subscription.
436   subscription.reset();
437 
438   // Insert a second cookie and make sure that it's not visible.
439   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
440   this->DeliverChangeNotifications();
441 
442   EXPECT_EQ(0u, cookie_changes.size());
443 }
444 
TYPED_TEST_P(CookieStoreChangeGlobalTest,DeregisterMultiple)445 TYPED_TEST_P(CookieStoreChangeGlobalTest, DeregisterMultiple) {
446   if (!TypeParam::supports_global_cookie_tracking ||
447       !TypeParam::supports_multiple_tracking_callbacks)
448     return;
449 
450   CookieStore* cs = this->GetCookieStore();
451 
452   // Register two subscriptions.
453   std::vector<CookieChangeInfo> cookie_changes_1;
454   std::unique_ptr<CookieChangeSubscription> subscription1 =
455       cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
456           &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
457           base::Unretained(&cookie_changes_1)));
458 
459   std::vector<CookieChangeInfo> cookie_changes_2;
460   std::unique_ptr<CookieChangeSubscription> subscription2 =
461       cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
462           &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
463           base::Unretained(&cookie_changes_2)));
464   this->DeliverChangeNotifications();
465   ASSERT_EQ(0u, cookie_changes_1.size());
466   ASSERT_EQ(0u, cookie_changes_2.size());
467 
468   // Insert a cookie and make sure it's seen.
469   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
470   this->DeliverChangeNotifications();
471   ASSERT_EQ(1u, cookie_changes_1.size());
472   EXPECT_EQ("A", cookie_changes_1[0].cookie.Name());
473   EXPECT_EQ("B", cookie_changes_1[0].cookie.Value());
474   cookie_changes_1.clear();
475 
476   ASSERT_EQ(1u, cookie_changes_2.size());
477   EXPECT_EQ("A", cookie_changes_2[0].cookie.Name());
478   EXPECT_EQ("B", cookie_changes_2[0].cookie.Value());
479   cookie_changes_2.clear();
480 
481   // De-register the second subscription.
482   subscription2.reset();
483 
484   // Insert a second cookie and make sure that it's only visible in one
485   // change array.
486   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
487   this->DeliverChangeNotifications();
488   ASSERT_EQ(1u, cookie_changes_1.size());
489   EXPECT_EQ("C", cookie_changes_1[0].cookie.Name());
490   EXPECT_EQ("D", cookie_changes_1[0].cookie.Value());
491   cookie_changes_1.clear();
492 
493   ASSERT_EQ(0u, cookie_changes_2.size());
494 }
495 
496 // Confirm that a listener does not receive notifications for changes that
497 // happened right before the subscription was established.
TYPED_TEST_P(CookieStoreChangeGlobalTest,DispatchRace)498 TYPED_TEST_P(CookieStoreChangeGlobalTest, DispatchRace) {
499   if (!TypeParam::supports_global_cookie_tracking)
500     return;
501 
502   CookieStore* cs = this->GetCookieStore();
503 
504   // This cookie insertion should not be seen.
505   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
506   // DeliverChangeNotifications() must NOT be called before the subscription is
507   // established.
508 
509   std::vector<CookieChangeInfo> cookie_changes;
510   std::unique_ptr<CookieChangeSubscription> subscription =
511       cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
512           &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
513           base::Unretained(&cookie_changes)));
514 
515   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
516   this->DeliverChangeNotifications();
517 
518   EXPECT_LE(1u, cookie_changes.size());
519   EXPECT_EQ("C", cookie_changes[0].cookie.Name());
520   EXPECT_EQ("D", cookie_changes[0].cookie.Value());
521 
522   ASSERT_EQ(1u, cookie_changes.size());
523 }
524 
525 // Confirm that deregistering a subscription blocks the notification if the
526 // deregistration happened after the change but before the notification was
527 // received.
TYPED_TEST_P(CookieStoreChangeGlobalTest,DeregisterRace)528 TYPED_TEST_P(CookieStoreChangeGlobalTest, DeregisterRace) {
529   if (!TypeParam::supports_global_cookie_tracking)
530     return;
531 
532   CookieStore* cs = this->GetCookieStore();
533 
534   std::vector<CookieChangeInfo> cookie_changes;
535   std::unique_ptr<CookieChangeSubscription> subscription =
536       cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
537           &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
538           base::Unretained(&cookie_changes)));
539   this->DeliverChangeNotifications();
540   ASSERT_EQ(0u, cookie_changes.size());
541 
542   // Insert a cookie and make sure it's seen.
543   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
544   this->DeliverChangeNotifications();
545   ASSERT_EQ(1u, cookie_changes.size());
546   EXPECT_EQ("A", cookie_changes[0].cookie.Name());
547   EXPECT_EQ("B", cookie_changes[0].cookie.Value());
548   cookie_changes.clear();
549 
550   // Insert a cookie, confirm it is not seen, deregister the subscription, run
551   // until idle, and confirm the cookie is still not seen.
552   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
553 
554   // Note that by the API contract it's perfectly valid to have received the
555   // notification immediately, i.e. synchronously with the cookie change. In
556   // that case, there's nothing to test.
557   if (1u == cookie_changes.size())
558     return;
559 
560   // A task was posted by the SetCookie() above, but has not yet arrived. If it
561   // arrived before the subscription is destroyed, callback execution would be
562   // valid. Destroy the subscription so as to lose the race and make sure the
563   // task posted arrives after the subscription was destroyed.
564   subscription.reset();
565   this->DeliverChangeNotifications();
566   ASSERT_EQ(0u, cookie_changes.size());
567 }
568 
TYPED_TEST_P(CookieStoreChangeGlobalTest,DeregisterRaceMultiple)569 TYPED_TEST_P(CookieStoreChangeGlobalTest, DeregisterRaceMultiple) {
570   if (!TypeParam::supports_global_cookie_tracking ||
571       !TypeParam::supports_multiple_tracking_callbacks)
572     return;
573 
574   CookieStore* cs = this->GetCookieStore();
575 
576   // Register two subscriptions.
577   std::vector<CookieChangeInfo> cookie_changes_1, cookie_changes_2;
578   std::unique_ptr<CookieChangeSubscription> subscription1 =
579       cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
580           &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
581           base::Unretained(&cookie_changes_1)));
582   std::unique_ptr<CookieChangeSubscription> subscription2 =
583       cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
584           &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
585           base::Unretained(&cookie_changes_2)));
586   this->DeliverChangeNotifications();
587   ASSERT_EQ(0u, cookie_changes_1.size());
588   ASSERT_EQ(0u, cookie_changes_2.size());
589 
590   // Insert a cookie and make sure it's seen.
591   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
592   this->DeliverChangeNotifications();
593 
594   ASSERT_EQ(1u, cookie_changes_1.size());
595   EXPECT_EQ("A", cookie_changes_1[0].cookie.Name());
596   EXPECT_EQ("B", cookie_changes_1[0].cookie.Value());
597   cookie_changes_1.clear();
598 
599   ASSERT_EQ(1u, cookie_changes_2.size());
600   EXPECT_EQ("A", cookie_changes_2[0].cookie.Name());
601   EXPECT_EQ("B", cookie_changes_2[0].cookie.Value());
602   cookie_changes_2.clear();
603 
604   // Insert a cookie, confirm it is not seen, deregister a subscription, run
605   // until idle, and confirm the cookie is still not seen.
606   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
607 
608   // Note that by the API contract it's perfectly valid to have received the
609   // notification immediately, i.e. synchronously with the cookie change. In
610   // that case, there's nothing to test.
611   if (1u == cookie_changes_2.size())
612     return;
613 
614   // A task was posted by the SetCookie() above, but has not yet arrived. If it
615   // arrived before the subscription is destroyed, callback execution would be
616   // valid. Destroy one of the subscriptions so as to lose the race and make
617   // sure the task posted arrives after the subscription was destroyed.
618   subscription2.reset();
619   this->DeliverChangeNotifications();
620   ASSERT_EQ(1u, cookie_changes_1.size());
621   EXPECT_EQ("C", cookie_changes_1[0].cookie.Name());
622   EXPECT_EQ("D", cookie_changes_1[0].cookie.Value());
623 
624   // No late notification was received.
625   ASSERT_EQ(0u, cookie_changes_2.size());
626 }
627 
TYPED_TEST_P(CookieStoreChangeGlobalTest,MultipleSubscriptions)628 TYPED_TEST_P(CookieStoreChangeGlobalTest, MultipleSubscriptions) {
629   if (!TypeParam::supports_global_cookie_tracking ||
630       !TypeParam::supports_multiple_tracking_callbacks)
631     return;
632 
633   CookieStore* cs = this->GetCookieStore();
634 
635   std::vector<CookieChangeInfo> cookie_changes_1, cookie_changes_2;
636   std::unique_ptr<CookieChangeSubscription> subscription1 =
637       cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
638           &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
639           base::Unretained(&cookie_changes_1)));
640   std::unique_ptr<CookieChangeSubscription> subscription2 =
641       cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
642           &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
643           base::Unretained(&cookie_changes_2)));
644   this->DeliverChangeNotifications();
645 
646   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
647   this->DeliverChangeNotifications();
648 
649   ASSERT_EQ(1U, cookie_changes_1.size());
650   EXPECT_EQ("A", cookie_changes_1[0].cookie.Name());
651   EXPECT_EQ("B", cookie_changes_1[0].cookie.Value());
652 
653   ASSERT_EQ(1U, cookie_changes_2.size());
654   EXPECT_EQ("A", cookie_changes_2[0].cookie.Name());
655   EXPECT_EQ("B", cookie_changes_2[0].cookie.Value());
656 }
657 
TYPED_TEST_P(CookieStoreChangeGlobalTest,ChangeIncludesCookieAccessSemantics)658 TYPED_TEST_P(CookieStoreChangeGlobalTest, ChangeIncludesCookieAccessSemantics) {
659   if (!TypeParam::supports_global_cookie_tracking)
660     return;
661 
662   CookieStore* cs = this->GetCookieStore();
663   // if !supports_cookie_access_semantics, the delegate will be stored but will
664   // not be used.
665   auto access_delegate = std::make_unique<TestCookieAccessDelegate>();
666   access_delegate->SetExpectationForCookieDomain("domain1.test",
667                                                  CookieAccessSemantics::LEGACY);
668   access_delegate->SetExpectationForCookieDomain(
669       "domain2.test", CookieAccessSemantics::NONLEGACY);
670   access_delegate->SetExpectationForCookieDomain(
671       "domain3.test", CookieAccessSemantics::UNKNOWN);
672   cs->SetCookieAccessDelegate(std::move(access_delegate));
673 
674   std::vector<CookieChangeInfo> cookie_changes;
675   std::unique_ptr<CookieChangeSubscription> subscription =
676       cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
677           &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
678           base::Unretained(&cookie_changes)));
679 
680   this->CreateAndSetCookie(cs, GURL("http://domain1.test"), "cookie=1",
681                            CookieOptions::MakeAllInclusive());
682   this->CreateAndSetCookie(cs, GURL("http://domain2.test"), "cookie=1",
683                            CookieOptions::MakeAllInclusive());
684   this->CreateAndSetCookie(cs, GURL("http://domain3.test"), "cookie=1",
685                            CookieOptions::MakeAllInclusive());
686   this->CreateAndSetCookie(cs, GURL("http://domain4.test"), "cookie=1",
687                            CookieOptions::MakeAllInclusive());
688   this->DeliverChangeNotifications();
689 
690   ASSERT_EQ(4u, cookie_changes.size());
691 
692   EXPECT_EQ("domain1.test", cookie_changes[0].cookie.Domain());
693   EXPECT_TRUE(this->IsExpectedAccessSemantics(
694       CookieAccessSemantics::LEGACY,
695       cookie_changes[0].access_result.access_semantics));
696   EXPECT_EQ("domain2.test", cookie_changes[1].cookie.Domain());
697   EXPECT_TRUE(this->IsExpectedAccessSemantics(
698       CookieAccessSemantics::NONLEGACY,
699       cookie_changes[1].access_result.access_semantics));
700   EXPECT_EQ("domain3.test", cookie_changes[2].cookie.Domain());
701   EXPECT_TRUE(this->IsExpectedAccessSemantics(
702       CookieAccessSemantics::UNKNOWN,
703       cookie_changes[2].access_result.access_semantics));
704   EXPECT_EQ("domain4.test", cookie_changes[3].cookie.Domain());
705   EXPECT_TRUE(this->IsExpectedAccessSemantics(
706       CookieAccessSemantics::UNKNOWN,
707       cookie_changes[3].access_result.access_semantics));
708 }
709 
TYPED_TEST_P(CookieStoreChangeGlobalTest,PartitionedCookies)710 TYPED_TEST_P(CookieStoreChangeGlobalTest, PartitionedCookies) {
711   if (!TypeParam::supports_named_cookie_tracking ||
712       !TypeParam::supports_partitioned_cookies) {
713     return;
714   }
715 
716   CookieStore* cs = this->GetCookieStore();
717 
718   // Test that all partitioned cookies are visible to global change listeners.
719   std::vector<CookieChangeInfo> all_cookie_changes;
720   std::unique_ptr<CookieChangeSubscription> global_subscription =
721       cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
722           &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
723           base::Unretained(&all_cookie_changes)));
724   // Set two cookies in two separate partitions, one with nonce.
725   this->CreateAndSetCookie(
726       cs, GURL("https://www.example2.com"),
727       "__Host-a=1; Secure; Path=/; Partitioned",
728       CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */,
729       absl::nullopt /* system_time */,
730       CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com")));
731   this->CreateAndSetCookie(
732       cs, GURL("https://www.example2.com"),
733       "__Host-a=2; Secure; Path=/; Partitioned; Max-Age=7200",
734       CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */,
735       absl::nullopt /* system_time */,
736       CookiePartitionKey::FromURLForTesting(GURL("https://www.bar.com"),
737                                             base::UnguessableToken::Create()));
738   this->DeliverChangeNotifications();
739   ASSERT_EQ(2u, all_cookie_changes.size());
740 }
741 
TYPED_TEST_P(CookieStoreChangeUrlTest,NoCookie)742 TYPED_TEST_P(CookieStoreChangeUrlTest, NoCookie) {
743   if (!TypeParam::supports_url_cookie_tracking)
744     return;
745 
746   CookieStore* cs = this->GetCookieStore();
747   std::vector<CookieChangeInfo> cookie_changes;
748   std::unique_ptr<CookieChangeSubscription> subscription =
749       cs->GetChangeDispatcher().AddCallbackForUrl(
750           this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
751           base::BindRepeating(
752               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
753               base::Unretained(&cookie_changes)));
754   this->DeliverChangeNotifications();
755   EXPECT_EQ(0u, cookie_changes.size());
756 }
757 
TYPED_TEST_P(CookieStoreChangeUrlTest,InitialCookie)758 TYPED_TEST_P(CookieStoreChangeUrlTest, InitialCookie) {
759   if (!TypeParam::supports_url_cookie_tracking)
760     return;
761 
762   CookieStore* cs = this->GetCookieStore();
763   std::vector<CookieChangeInfo> cookie_changes;
764   this->SetCookie(cs, this->http_www_foo_.url(), "A=B");
765   this->DeliverChangeNotifications();
766   std::unique_ptr<CookieChangeSubscription> subscription =
767       cs->GetChangeDispatcher().AddCallbackForUrl(
768           this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
769           base::BindRepeating(
770               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
771               base::Unretained(&cookie_changes)));
772   this->DeliverChangeNotifications();
773   EXPECT_EQ(0u, cookie_changes.size());
774 }
775 
TYPED_TEST_P(CookieStoreChangeUrlTest,InsertOne)776 TYPED_TEST_P(CookieStoreChangeUrlTest, InsertOne) {
777   if (!TypeParam::supports_url_cookie_tracking)
778     return;
779 
780   CookieStore* cs = this->GetCookieStore();
781   std::vector<CookieChangeInfo> cookie_changes;
782   std::unique_ptr<CookieChangeSubscription> subscription =
783       cs->GetChangeDispatcher().AddCallbackForUrl(
784           this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
785           base::BindRepeating(
786               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
787               base::Unretained(&cookie_changes)));
788   this->DeliverChangeNotifications();
789   ASSERT_EQ(0u, cookie_changes.size());
790 
791   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
792   this->DeliverChangeNotifications();
793   ASSERT_EQ(1u, cookie_changes.size());
794 
795   EXPECT_EQ("A", cookie_changes[0].cookie.Name());
796   EXPECT_EQ("B", cookie_changes[0].cookie.Value());
797   EXPECT_EQ(this->http_www_foo_.url().host(),
798             cookie_changes[0].cookie.Domain());
799   EXPECT_TRUE(
800       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[0].cause));
801 }
802 
TYPED_TEST_P(CookieStoreChangeUrlTest,InsertMany)803 TYPED_TEST_P(CookieStoreChangeUrlTest, InsertMany) {
804   if (!TypeParam::supports_url_cookie_tracking)
805     return;
806 
807   CookieStore* cs = this->GetCookieStore();
808   std::vector<CookieChangeInfo> cookie_changes;
809   std::unique_ptr<CookieChangeSubscription> subscription =
810       cs->GetChangeDispatcher().AddCallbackForUrl(
811           this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
812           base::BindRepeating(
813               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
814               base::Unretained(&cookie_changes)));
815   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
816   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
817   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "E=F"));
818   this->DeliverChangeNotifications();
819 
820   ASSERT_LE(1u, cookie_changes.size());
821   EXPECT_TRUE(
822       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[0].cause));
823   EXPECT_EQ(this->http_www_foo_.url().host(),
824             cookie_changes[0].cookie.Domain());
825   EXPECT_EQ("A", cookie_changes[0].cookie.Name());
826   EXPECT_EQ("B", cookie_changes[0].cookie.Value());
827 
828   ASSERT_LE(2u, cookie_changes.size());
829   EXPECT_EQ(this->http_www_foo_.url().host(),
830             cookie_changes[1].cookie.Domain());
831   EXPECT_TRUE(
832       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[1].cause));
833   EXPECT_EQ("C", cookie_changes[1].cookie.Name());
834   EXPECT_EQ("D", cookie_changes[1].cookie.Value());
835 
836   ASSERT_LE(3u, cookie_changes.size());
837   EXPECT_EQ(this->http_www_foo_.url().host(),
838             cookie_changes[2].cookie.Domain());
839   EXPECT_TRUE(
840       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[2].cause));
841   EXPECT_EQ("E", cookie_changes[2].cookie.Name());
842   EXPECT_EQ("F", cookie_changes[2].cookie.Value());
843 
844   EXPECT_EQ(3u, cookie_changes.size());
845 }
846 
TYPED_TEST_P(CookieStoreChangeUrlTest,InsertFiltering)847 TYPED_TEST_P(CookieStoreChangeUrlTest, InsertFiltering) {
848   if (!TypeParam::supports_url_cookie_tracking)
849     return;
850 
851   CookieStore* cs = this->GetCookieStore();
852   std::vector<CookieChangeInfo> cookie_changes;
853   std::unique_ptr<CookieChangeSubscription> subscription =
854       cs->GetChangeDispatcher().AddCallbackForUrl(
855           this->www_foo_foo_.url(), absl::nullopt /* cookie_partition_key */,
856           base::BindRepeating(
857               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
858               base::Unretained(&cookie_changes)));
859   this->DeliverChangeNotifications();
860   ASSERT_EQ(0u, cookie_changes.size());
861 
862   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B; path=/"));
863   EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "C=D; path=/"));
864   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "E=F; path=/bar"));
865   EXPECT_TRUE(
866       this->SetCookie(cs, this->http_www_foo_.url(), "G=H; path=/foo/bar"));
867   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "I=J; path=/foo"));
868   EXPECT_TRUE(
869       this->SetCookie(cs, this->http_www_foo_.url(), "K=L; domain=foo.com"));
870   this->DeliverChangeNotifications();
871 
872   ASSERT_LE(1u, cookie_changes.size());
873   EXPECT_EQ("A", cookie_changes[0].cookie.Name());
874   EXPECT_EQ("B", cookie_changes[0].cookie.Value());
875   EXPECT_EQ("/", cookie_changes[0].cookie.Path());
876   EXPECT_EQ(this->http_www_foo_.url().host(),
877             cookie_changes[0].cookie.Domain());
878   EXPECT_TRUE(
879       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[0].cause));
880 
881   ASSERT_LE(2u, cookie_changes.size());
882   EXPECT_EQ("I", cookie_changes[1].cookie.Name());
883   EXPECT_EQ("J", cookie_changes[1].cookie.Value());
884   EXPECT_EQ("/foo", cookie_changes[1].cookie.Path());
885   EXPECT_EQ(this->http_www_foo_.url().host(),
886             cookie_changes[1].cookie.Domain());
887   EXPECT_TRUE(
888       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[1].cause));
889 
890   ASSERT_LE(3u, cookie_changes.size());
891   EXPECT_EQ("K", cookie_changes[2].cookie.Name());
892   EXPECT_EQ("L", cookie_changes[2].cookie.Value());
893   EXPECT_EQ("/", cookie_changes[2].cookie.Path());
894   EXPECT_EQ(".foo.com", cookie_changes[2].cookie.Domain());
895   EXPECT_TRUE(
896       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[2].cause));
897 
898   EXPECT_EQ(3u, cookie_changes.size());
899 }
900 
TYPED_TEST_P(CookieStoreChangeUrlTest,DeleteOne)901 TYPED_TEST_P(CookieStoreChangeUrlTest, DeleteOne) {
902   if (!TypeParam::supports_url_cookie_tracking)
903     return;
904 
905   CookieStore* cs = this->GetCookieStore();
906   std::vector<CookieChangeInfo> cookie_changes;
907   std::unique_ptr<CookieChangeSubscription> subscription =
908       cs->GetChangeDispatcher().AddCallbackForUrl(
909           this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
910           base::BindRepeating(
911               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
912               base::Unretained(&cookie_changes)));
913   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
914   this->DeliverChangeNotifications();
915   EXPECT_EQ(1u, cookie_changes.size());
916   cookie_changes.clear();
917 
918   EXPECT_TRUE(
919       this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "A"));
920   this->DeliverChangeNotifications();
921 
922   ASSERT_EQ(1u, cookie_changes.size());
923   EXPECT_EQ("A", cookie_changes[0].cookie.Name());
924   EXPECT_EQ("B", cookie_changes[0].cookie.Value());
925   EXPECT_EQ(this->http_www_foo_.url().host(),
926             cookie_changes[0].cookie.Domain());
927   ASSERT_TRUE(
928       this->MatchesCause(CookieChangeCause::EXPLICIT, cookie_changes[0].cause));
929 }
930 
TYPED_TEST_P(CookieStoreChangeUrlTest,DeleteTwo)931 TYPED_TEST_P(CookieStoreChangeUrlTest, DeleteTwo) {
932   if (!TypeParam::supports_url_cookie_tracking)
933     return;
934 
935   CookieStore* cs = this->GetCookieStore();
936   std::vector<CookieChangeInfo> cookie_changes;
937   std::unique_ptr<CookieChangeSubscription> subscription =
938       cs->GetChangeDispatcher().AddCallbackForUrl(
939           this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
940           base::BindRepeating(
941               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
942               base::Unretained(&cookie_changes)));
943   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
944   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
945   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "E=F"));
946   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "G=H"));
947   this->DeliverChangeNotifications();
948   EXPECT_EQ(4u, cookie_changes.size());
949   cookie_changes.clear();
950 
951   EXPECT_TRUE(
952       this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "C"));
953   EXPECT_TRUE(
954       this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "G"));
955   this->DeliverChangeNotifications();
956 
957   // Check that the cookie changes are dispatched before calling GetCookies.
958   // This is not an ASSERT because the following expectations produce useful
959   // debugging information if they fail.
960   EXPECT_EQ(2u, cookie_changes.size());
961   EXPECT_EQ("A=B; E=F", this->GetCookies(cs, this->http_www_foo_.url()));
962 
963   ASSERT_LE(1u, cookie_changes.size());
964   EXPECT_EQ(this->http_www_foo_.url().host(),
965             cookie_changes[0].cookie.Domain());
966   EXPECT_TRUE(
967       this->MatchesCause(CookieChangeCause::EXPLICIT, cookie_changes[0].cause));
968   EXPECT_EQ("C", cookie_changes[0].cookie.Name());
969   EXPECT_EQ("D", cookie_changes[0].cookie.Value());
970 
971   ASSERT_EQ(2u, cookie_changes.size());
972   EXPECT_EQ(this->http_www_foo_.url().host(),
973             cookie_changes[1].cookie.Domain());
974   EXPECT_TRUE(
975       this->MatchesCause(CookieChangeCause::EXPLICIT, cookie_changes[1].cause));
976   EXPECT_EQ("G", cookie_changes[1].cookie.Name());
977   EXPECT_EQ("H", cookie_changes[1].cookie.Value());
978 }
979 
TYPED_TEST_P(CookieStoreChangeUrlTest,DeleteFiltering)980 TYPED_TEST_P(CookieStoreChangeUrlTest, DeleteFiltering) {
981   if (!TypeParam::supports_url_cookie_tracking)
982     return;
983 
984   CookieStore* cs = this->GetCookieStore();
985   std::vector<CookieChangeInfo> cookie_changes;
986   std::unique_ptr<CookieChangeSubscription> subscription =
987       cs->GetChangeDispatcher().AddCallbackForUrl(
988           this->www_foo_foo_.url(), absl::nullopt /* cookie_partition_key */,
989           base::BindRepeating(
990               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
991               base::Unretained(&cookie_changes)));
992   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B; path=/"));
993   EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "C=D; path=/"));
994   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "E=F; path=/bar"));
995   EXPECT_TRUE(
996       this->SetCookie(cs, this->http_www_foo_.url(), "G=H; path=/foo/bar"));
997   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "I=J; path=/foo"));
998   EXPECT_TRUE(
999       this->SetCookie(cs, this->http_www_foo_.url(), "K=L; domain=foo.com"));
1000   this->DeliverChangeNotifications();
1001   EXPECT_EQ(3u, cookie_changes.size());
1002   cookie_changes.clear();
1003 
1004   EXPECT_TRUE(
1005       this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "A"));
1006   EXPECT_TRUE(
1007       this->FindAndDeleteCookie(cs, this->http_bar_com_.url().host(), "C"));
1008   EXPECT_TRUE(
1009       this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "E"));
1010   EXPECT_TRUE(
1011       this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "G"));
1012   EXPECT_TRUE(
1013       this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "I"));
1014   EXPECT_TRUE(this->FindAndDeleteCookie(cs, ".foo.com", "K"));
1015   this->DeliverChangeNotifications();
1016 
1017   ASSERT_LE(1u, cookie_changes.size());
1018   EXPECT_EQ("A", cookie_changes[0].cookie.Name());
1019   EXPECT_EQ("B", cookie_changes[0].cookie.Value());
1020   EXPECT_EQ("/", cookie_changes[0].cookie.Path());
1021   EXPECT_EQ(this->http_www_foo_.url().host(),
1022             cookie_changes[0].cookie.Domain());
1023   EXPECT_TRUE(
1024       this->MatchesCause(CookieChangeCause::EXPLICIT, cookie_changes[0].cause));
1025 
1026   ASSERT_LE(2u, cookie_changes.size());
1027   EXPECT_EQ("I", cookie_changes[1].cookie.Name());
1028   EXPECT_EQ("J", cookie_changes[1].cookie.Value());
1029   EXPECT_EQ("/foo", cookie_changes[1].cookie.Path());
1030   EXPECT_EQ(this->http_www_foo_.url().host(),
1031             cookie_changes[1].cookie.Domain());
1032   EXPECT_TRUE(
1033       this->MatchesCause(CookieChangeCause::EXPLICIT, cookie_changes[1].cause));
1034 
1035   ASSERT_LE(3u, cookie_changes.size());
1036   EXPECT_EQ("K", cookie_changes[2].cookie.Name());
1037   EXPECT_EQ("L", cookie_changes[2].cookie.Value());
1038   EXPECT_EQ("/", cookie_changes[2].cookie.Path());
1039   EXPECT_EQ(".foo.com", cookie_changes[2].cookie.Domain());
1040   EXPECT_TRUE(
1041       this->MatchesCause(CookieChangeCause::EXPLICIT, cookie_changes[2].cause));
1042 
1043   EXPECT_EQ(3u, cookie_changes.size());
1044 }
1045 
TYPED_TEST_P(CookieStoreChangeUrlTest,Overwrite)1046 TYPED_TEST_P(CookieStoreChangeUrlTest, Overwrite) {
1047   if (!TypeParam::supports_url_cookie_tracking)
1048     return;
1049 
1050   CookieStore* cs = this->GetCookieStore();
1051   std::vector<CookieChangeInfo> cookie_changes;
1052   std::unique_ptr<CookieChangeSubscription> subscription =
1053       cs->GetChangeDispatcher().AddCallbackForUrl(
1054           this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
1055           base::BindRepeating(
1056               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
1057               base::Unretained(&cookie_changes)));
1058   this->DeliverChangeNotifications();
1059   ASSERT_EQ(0u, cookie_changes.size());
1060 
1061   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
1062   this->DeliverChangeNotifications();
1063   ASSERT_EQ(1u, cookie_changes.size());
1064   cookie_changes.clear();
1065 
1066   // Replacing an existing cookie is actually a two-phase delete + set
1067   // operation, so we get an extra notification.
1068   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=C"));
1069   this->DeliverChangeNotifications();
1070 
1071   ASSERT_LE(1u, cookie_changes.size());
1072   EXPECT_EQ(this->http_www_foo_.url().host(),
1073             cookie_changes[0].cookie.Domain());
1074   EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
1075                                  cookie_changes[0].cause));
1076   EXPECT_EQ("A", cookie_changes[0].cookie.Name());
1077   EXPECT_EQ("B", cookie_changes[0].cookie.Value());
1078 
1079   ASSERT_LE(2u, cookie_changes.size());
1080   EXPECT_EQ(this->http_www_foo_.url().host(),
1081             cookie_changes[1].cookie.Domain());
1082   EXPECT_TRUE(
1083       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[1].cause));
1084   EXPECT_EQ("A", cookie_changes[1].cookie.Name());
1085   EXPECT_EQ("C", cookie_changes[1].cookie.Value());
1086 
1087   EXPECT_EQ(2u, cookie_changes.size());
1088 }
1089 
TYPED_TEST_P(CookieStoreChangeUrlTest,OverwriteFiltering)1090 TYPED_TEST_P(CookieStoreChangeUrlTest, OverwriteFiltering) {
1091   if (!TypeParam::supports_url_cookie_tracking)
1092     return;
1093 
1094   CookieStore* cs = this->GetCookieStore();
1095   std::vector<CookieChangeInfo> cookie_changes;
1096   std::unique_ptr<CookieChangeSubscription> subscription =
1097       cs->GetChangeDispatcher().AddCallbackForUrl(
1098           this->www_foo_foo_.url(), absl::nullopt /* cookie_partition_key */,
1099           base::BindRepeating(
1100               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
1101               base::Unretained(&cookie_changes)));
1102   this->DeliverChangeNotifications();
1103   ASSERT_EQ(0u, cookie_changes.size());
1104 
1105   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B; path=/"));
1106   EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "C=D; path=/"));
1107   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "E=F; path=/bar"));
1108   EXPECT_TRUE(
1109       this->SetCookie(cs, this->http_www_foo_.url(), "G=H; path=/foo/bar"));
1110   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "I=J; path=/foo"));
1111   EXPECT_TRUE(
1112       this->SetCookie(cs, this->http_www_foo_.url(), "K=L; domain=foo.com"));
1113   this->DeliverChangeNotifications();
1114   EXPECT_EQ(3u, cookie_changes.size());
1115   cookie_changes.clear();
1116 
1117   // Replacing an existing cookie is actually a two-phase delete + set
1118   // operation, so we get two notifications per overwrite.
1119   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=b; path=/"));
1120   EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "C=d; path=/"));
1121   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "E=f; path=/bar"));
1122   EXPECT_TRUE(
1123       this->SetCookie(cs, this->http_www_foo_.url(), "G=h; path=/foo/bar"));
1124   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "I=j; path=/foo"));
1125   EXPECT_TRUE(
1126       this->SetCookie(cs, this->http_www_foo_.url(), "K=l; domain=foo.com"));
1127   this->DeliverChangeNotifications();
1128 
1129   ASSERT_LE(1u, cookie_changes.size());
1130   EXPECT_EQ("A", cookie_changes[0].cookie.Name());
1131   EXPECT_EQ("B", cookie_changes[0].cookie.Value());
1132   EXPECT_EQ("/", cookie_changes[0].cookie.Path());
1133   EXPECT_EQ(this->http_www_foo_.url().host(),
1134             cookie_changes[0].cookie.Domain());
1135   EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
1136                                  cookie_changes[0].cause));
1137 
1138   ASSERT_LE(2u, cookie_changes.size());
1139   EXPECT_EQ("A", cookie_changes[1].cookie.Name());
1140   EXPECT_EQ("b", cookie_changes[1].cookie.Value());
1141   EXPECT_EQ("/", cookie_changes[1].cookie.Path());
1142   EXPECT_EQ(this->http_www_foo_.url().host(),
1143             cookie_changes[1].cookie.Domain());
1144   EXPECT_EQ(CookieChangeCause::INSERTED, cookie_changes[1].cause);
1145   EXPECT_TRUE(
1146       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[1].cause));
1147 
1148   ASSERT_LE(3u, cookie_changes.size());
1149   EXPECT_EQ("I", cookie_changes[2].cookie.Name());
1150   EXPECT_EQ("J", cookie_changes[2].cookie.Value());
1151   EXPECT_EQ("/foo", cookie_changes[2].cookie.Path());
1152   EXPECT_EQ(this->http_www_foo_.url().host(),
1153             cookie_changes[2].cookie.Domain());
1154   EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
1155                                  cookie_changes[2].cause));
1156 
1157   ASSERT_LE(4u, cookie_changes.size());
1158   EXPECT_EQ("I", cookie_changes[3].cookie.Name());
1159   EXPECT_EQ("j", cookie_changes[3].cookie.Value());
1160   EXPECT_EQ("/foo", cookie_changes[3].cookie.Path());
1161   EXPECT_EQ(this->http_www_foo_.url().host(),
1162             cookie_changes[3].cookie.Domain());
1163   EXPECT_TRUE(
1164       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[3].cause));
1165 
1166   ASSERT_LE(5u, cookie_changes.size());
1167   EXPECT_EQ("K", cookie_changes[4].cookie.Name());
1168   EXPECT_EQ("L", cookie_changes[4].cookie.Value());
1169   EXPECT_EQ("/", cookie_changes[4].cookie.Path());
1170   EXPECT_EQ(".foo.com", cookie_changes[4].cookie.Domain());
1171   EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
1172                                  cookie_changes[4].cause));
1173 
1174   ASSERT_LE(6u, cookie_changes.size());
1175   EXPECT_EQ("K", cookie_changes[5].cookie.Name());
1176   EXPECT_EQ("l", cookie_changes[5].cookie.Value());
1177   EXPECT_EQ("/", cookie_changes[5].cookie.Path());
1178   EXPECT_EQ(".foo.com", cookie_changes[5].cookie.Domain());
1179   EXPECT_TRUE(
1180       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[5].cause));
1181 
1182   EXPECT_EQ(6u, cookie_changes.size());
1183 }
1184 
TYPED_TEST_P(CookieStoreChangeUrlTest,OverwriteWithHttpOnly)1185 TYPED_TEST_P(CookieStoreChangeUrlTest, OverwriteWithHttpOnly) {
1186   if (!TypeParam::supports_url_cookie_tracking)
1187     return;
1188 
1189   // Insert a cookie "A" for path "/foo".
1190   CookieStore* cs = this->GetCookieStore();
1191   std::vector<CookieChangeInfo> cookie_changes;
1192   std::unique_ptr<CookieChangeSubscription> subscription =
1193       cs->GetChangeDispatcher().AddCallbackForUrl(
1194           this->www_foo_foo_.url(), absl::nullopt /* cookie_partition_key */,
1195           base::BindRepeating(
1196               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
1197               base::Unretained(&cookie_changes)));
1198   this->DeliverChangeNotifications();
1199   ASSERT_EQ(0u, cookie_changes.size());
1200 
1201   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B; path=/foo"));
1202   this->DeliverChangeNotifications();
1203   ASSERT_EQ(1u, cookie_changes.size());
1204   EXPECT_TRUE(
1205       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[0].cause));
1206   EXPECT_EQ(this->http_www_foo_.url().host(),
1207             cookie_changes[0].cookie.Domain());
1208   EXPECT_EQ("A", cookie_changes[0].cookie.Name());
1209   EXPECT_EQ("B", cookie_changes[0].cookie.Value());
1210   EXPECT_FALSE(cookie_changes[0].cookie.IsHttpOnly());
1211   cookie_changes.clear();
1212 
1213   // Insert a cookie "A" for path "/foo", that is httponly. This should
1214   // overwrite the non-http-only version.
1215   CookieOptions allow_httponly;
1216   allow_httponly.set_include_httponly();
1217   allow_httponly.set_same_site_cookie_context(
1218       net::CookieOptions::SameSiteCookieContext::MakeInclusive());
1219 
1220   EXPECT_TRUE(this->CreateAndSetCookie(cs, this->http_www_foo_.url(),
1221                                        "A=C; path=/foo; httponly",
1222                                        allow_httponly));
1223   this->DeliverChangeNotifications();
1224 
1225   ASSERT_LE(1u, cookie_changes.size());
1226   EXPECT_EQ(this->http_www_foo_.url().host(),
1227             cookie_changes[0].cookie.Domain());
1228   EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
1229                                  cookie_changes[0].cause));
1230   EXPECT_EQ("A", cookie_changes[0].cookie.Name());
1231   EXPECT_EQ("B", cookie_changes[0].cookie.Value());
1232   EXPECT_FALSE(cookie_changes[0].cookie.IsHttpOnly());
1233 
1234   ASSERT_LE(2u, cookie_changes.size());
1235   EXPECT_EQ(this->http_www_foo_.url().host(),
1236             cookie_changes[1].cookie.Domain());
1237   EXPECT_TRUE(
1238       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[1].cause));
1239   EXPECT_EQ("A", cookie_changes[1].cookie.Name());
1240   EXPECT_EQ("C", cookie_changes[1].cookie.Value());
1241   EXPECT_TRUE(cookie_changes[1].cookie.IsHttpOnly());
1242 
1243   EXPECT_EQ(2u, cookie_changes.size());
1244 }
1245 
TYPED_TEST_P(CookieStoreChangeUrlTest,Deregister)1246 TYPED_TEST_P(CookieStoreChangeUrlTest, Deregister) {
1247   if (!TypeParam::supports_url_cookie_tracking)
1248     return;
1249 
1250   CookieStore* cs = this->GetCookieStore();
1251 
1252   std::vector<CookieChangeInfo> cookie_changes;
1253   std::unique_ptr<CookieChangeSubscription> subscription =
1254       cs->GetChangeDispatcher().AddCallbackForUrl(
1255           this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
1256           base::BindRepeating(
1257               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
1258               base::Unretained(&cookie_changes)));
1259   this->DeliverChangeNotifications();
1260   ASSERT_EQ(0u, cookie_changes.size());
1261 
1262   // Insert a cookie and make sure it is seen.
1263   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
1264   this->DeliverChangeNotifications();
1265   ASSERT_EQ(1u, cookie_changes.size());
1266   EXPECT_EQ("A", cookie_changes[0].cookie.Name());
1267   EXPECT_EQ("B", cookie_changes[0].cookie.Value());
1268   cookie_changes.clear();
1269 
1270   // De-register the subscription.
1271   subscription.reset();
1272 
1273   // Insert a second cookie and make sure it's not visible.
1274   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
1275   this->DeliverChangeNotifications();
1276 
1277   EXPECT_EQ(0u, cookie_changes.size());
1278 }
1279 
TYPED_TEST_P(CookieStoreChangeUrlTest,DeregisterMultiple)1280 TYPED_TEST_P(CookieStoreChangeUrlTest, DeregisterMultiple) {
1281   if (!TypeParam::supports_url_cookie_tracking ||
1282       !TypeParam::supports_multiple_tracking_callbacks)
1283     return;
1284 
1285   CookieStore* cs = this->GetCookieStore();
1286 
1287   // Register two subscriptions.
1288   std::vector<CookieChangeInfo> cookie_changes_1, cookie_changes_2;
1289   std::unique_ptr<CookieChangeSubscription> subscription1 =
1290       cs->GetChangeDispatcher().AddCallbackForUrl(
1291           this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
1292           base::BindRepeating(
1293               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
1294               base::Unretained(&cookie_changes_1)));
1295   std::unique_ptr<CookieChangeSubscription> subscription2 =
1296       cs->GetChangeDispatcher().AddCallbackForUrl(
1297           this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
1298           base::BindRepeating(
1299               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
1300               base::Unretained(&cookie_changes_2)));
1301   this->DeliverChangeNotifications();
1302   ASSERT_EQ(0u, cookie_changes_1.size());
1303   ASSERT_EQ(0u, cookie_changes_2.size());
1304 
1305   // Insert a cookie and make sure it's seen.
1306   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
1307   this->DeliverChangeNotifications();
1308   ASSERT_EQ(1u, cookie_changes_1.size());
1309   EXPECT_EQ("A", cookie_changes_1[0].cookie.Name());
1310   EXPECT_EQ("B", cookie_changes_1[0].cookie.Value());
1311   cookie_changes_1.clear();
1312 
1313   ASSERT_EQ(1u, cookie_changes_2.size());
1314   EXPECT_EQ("A", cookie_changes_2[0].cookie.Name());
1315   EXPECT_EQ("B", cookie_changes_2[0].cookie.Value());
1316   cookie_changes_2.clear();
1317 
1318   // De-register the second registration.
1319   subscription2.reset();
1320 
1321   // Insert a second cookie and make sure that it's only visible in one
1322   // change array.
1323   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
1324   this->DeliverChangeNotifications();
1325   ASSERT_EQ(1u, cookie_changes_1.size());
1326   EXPECT_EQ("C", cookie_changes_1[0].cookie.Name());
1327   EXPECT_EQ("D", cookie_changes_1[0].cookie.Value());
1328 
1329   EXPECT_EQ(0u, cookie_changes_2.size());
1330 }
1331 
1332 // Confirm that a listener does not receive notifications for changes that
1333 // happened right before the subscription was established.
TYPED_TEST_P(CookieStoreChangeUrlTest,DispatchRace)1334 TYPED_TEST_P(CookieStoreChangeUrlTest, DispatchRace) {
1335   if (!TypeParam::supports_url_cookie_tracking)
1336     return;
1337 
1338   CookieStore* cs = this->GetCookieStore();
1339 
1340   // This cookie insertion should not be seen.
1341   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
1342   // DeliverChangeNotifications() must NOT be called before the subscription is
1343   // established.
1344 
1345   std::vector<CookieChangeInfo> cookie_changes;
1346   std::unique_ptr<CookieChangeSubscription> subscription =
1347       cs->GetChangeDispatcher().AddCallbackForUrl(
1348           this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
1349           base::BindRepeating(
1350               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
1351               base::Unretained(&cookie_changes)));
1352 
1353   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
1354   this->DeliverChangeNotifications();
1355 
1356   EXPECT_LE(1u, cookie_changes.size());
1357   EXPECT_EQ("C", cookie_changes[0].cookie.Name());
1358   EXPECT_EQ("D", cookie_changes[0].cookie.Value());
1359 
1360   ASSERT_EQ(1u, cookie_changes.size());
1361 }
1362 
1363 // Confirm that deregistering a subscription blocks the notification if the
1364 // deregistration happened after the change but before the notification was
1365 // received.
TYPED_TEST_P(CookieStoreChangeUrlTest,DeregisterRace)1366 TYPED_TEST_P(CookieStoreChangeUrlTest, DeregisterRace) {
1367   if (!TypeParam::supports_url_cookie_tracking)
1368     return;
1369 
1370   CookieStore* cs = this->GetCookieStore();
1371 
1372   std::vector<CookieChangeInfo> cookie_changes;
1373   std::unique_ptr<CookieChangeSubscription> subscription =
1374       cs->GetChangeDispatcher().AddCallbackForUrl(
1375           this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
1376           base::BindRepeating(
1377               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
1378               base::Unretained(&cookie_changes)));
1379   this->DeliverChangeNotifications();
1380   ASSERT_EQ(0u, cookie_changes.size());
1381 
1382   // Insert a cookie and make sure it's seen.
1383   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
1384   this->DeliverChangeNotifications();
1385   ASSERT_EQ(1u, cookie_changes.size());
1386   EXPECT_EQ("A", cookie_changes[0].cookie.Name());
1387   EXPECT_EQ("B", cookie_changes[0].cookie.Value());
1388   cookie_changes.clear();
1389 
1390   // Insert a cookie, confirm it is not seen, deregister the subscription, run
1391   // until idle, and confirm the cookie is still not seen.
1392   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
1393 
1394   // Note that by the API contract it's perfectly valid to have received the
1395   // notification immediately, i.e. synchronously with the cookie change. In
1396   // that case, there's nothing to test.
1397   if (1u == cookie_changes.size())
1398     return;
1399 
1400   // A task was posted by the SetCookie() above, but has not yet arrived. If it
1401   // arrived before the subscription is destroyed, callback execution would be
1402   // valid. Destroy the subscription so as to lose the race and make sure the
1403   // task posted arrives after the subscription was destroyed.
1404   subscription.reset();
1405   this->DeliverChangeNotifications();
1406   ASSERT_EQ(0u, cookie_changes.size());
1407 }
1408 
TYPED_TEST_P(CookieStoreChangeUrlTest,DeregisterRaceMultiple)1409 TYPED_TEST_P(CookieStoreChangeUrlTest, DeregisterRaceMultiple) {
1410   if (!TypeParam::supports_url_cookie_tracking ||
1411       !TypeParam::supports_multiple_tracking_callbacks)
1412     return;
1413 
1414   CookieStore* cs = this->GetCookieStore();
1415 
1416   // Register two subscriptions.
1417   std::vector<CookieChangeInfo> cookie_changes_1, cookie_changes_2;
1418   std::unique_ptr<CookieChangeSubscription> subscription1 =
1419       cs->GetChangeDispatcher().AddCallbackForUrl(
1420           this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
1421           base::BindRepeating(
1422               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
1423               base::Unretained(&cookie_changes_1)));
1424   std::unique_ptr<CookieChangeSubscription> subscription2 =
1425       cs->GetChangeDispatcher().AddCallbackForUrl(
1426           this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
1427           base::BindRepeating(
1428               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
1429               base::Unretained(&cookie_changes_2)));
1430   this->DeliverChangeNotifications();
1431   ASSERT_EQ(0u, cookie_changes_1.size());
1432   ASSERT_EQ(0u, cookie_changes_2.size());
1433 
1434   // Insert a cookie and make sure it's seen.
1435   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
1436   this->DeliverChangeNotifications();
1437 
1438   ASSERT_EQ(1u, cookie_changes_1.size());
1439   EXPECT_EQ("A", cookie_changes_1[0].cookie.Name());
1440   EXPECT_EQ("B", cookie_changes_1[0].cookie.Value());
1441   cookie_changes_1.clear();
1442 
1443   ASSERT_EQ(1u, cookie_changes_2.size());
1444   EXPECT_EQ("A", cookie_changes_2[0].cookie.Name());
1445   EXPECT_EQ("B", cookie_changes_2[0].cookie.Value());
1446   cookie_changes_2.clear();
1447 
1448   // Insert a cookie, confirm it is not seen, deregister a subscription, run
1449   // until idle, and confirm the cookie is still not seen.
1450   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
1451 
1452   // Note that by the API contract it's perfectly valid to have received the
1453   // notification immediately, i.e. synchronously with the cookie change. In
1454   // that case, there's nothing to test.
1455   if (1u == cookie_changes_2.size())
1456     return;
1457 
1458   // A task was posted by the SetCookie() above, but has not yet arrived. If it
1459   // arrived before the subscription is destroyed, callback execution would be
1460   // valid. Destroy one of the subscriptions so as to lose the race and make
1461   // sure the task posted arrives after the subscription was destroyed.
1462   subscription2.reset();
1463   this->DeliverChangeNotifications();
1464   ASSERT_EQ(1u, cookie_changes_1.size());
1465   EXPECT_EQ("C", cookie_changes_1[0].cookie.Name());
1466   EXPECT_EQ("D", cookie_changes_1[0].cookie.Value());
1467 
1468   // No late notification was received.
1469   ASSERT_EQ(0u, cookie_changes_2.size());
1470 }
1471 
TYPED_TEST_P(CookieStoreChangeUrlTest,DifferentSubscriptionsDisjoint)1472 TYPED_TEST_P(CookieStoreChangeUrlTest, DifferentSubscriptionsDisjoint) {
1473   if (!TypeParam::supports_url_cookie_tracking)
1474     return;
1475 
1476   CookieStore* cs = this->GetCookieStore();
1477 
1478   std::vector<CookieChangeInfo> cookie_changes_1, cookie_changes_2;
1479   std::unique_ptr<CookieChangeSubscription> subscription1 =
1480       cs->GetChangeDispatcher().AddCallbackForUrl(
1481           this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
1482           base::BindRepeating(
1483               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
1484               base::Unretained(&cookie_changes_1)));
1485   std::unique_ptr<CookieChangeSubscription> subscription2 =
1486       cs->GetChangeDispatcher().AddCallbackForUrl(
1487           this->http_bar_com_.url(), absl::nullopt /* cookie_partition_key */,
1488           base::BindRepeating(
1489               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
1490               base::Unretained(&cookie_changes_2)));
1491   this->DeliverChangeNotifications();
1492   ASSERT_EQ(0u, cookie_changes_1.size());
1493   ASSERT_EQ(0u, cookie_changes_2.size());
1494 
1495   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
1496   this->DeliverChangeNotifications();
1497   EXPECT_EQ(1u, cookie_changes_1.size());
1498   EXPECT_EQ(0u, cookie_changes_2.size());
1499 
1500   EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "C=D"));
1501   this->DeliverChangeNotifications();
1502 
1503   ASSERT_EQ(1u, cookie_changes_1.size());
1504   EXPECT_EQ("A", cookie_changes_1[0].cookie.Name());
1505   EXPECT_EQ("B", cookie_changes_1[0].cookie.Value());
1506   EXPECT_EQ(this->http_www_foo_.url().host(),
1507             cookie_changes_1[0].cookie.Domain());
1508 
1509   ASSERT_EQ(1u, cookie_changes_2.size());
1510   EXPECT_EQ("C", cookie_changes_2[0].cookie.Name());
1511   EXPECT_EQ("D", cookie_changes_2[0].cookie.Value());
1512   EXPECT_EQ(this->http_bar_com_.url().host(),
1513             cookie_changes_2[0].cookie.Domain());
1514 }
1515 
TYPED_TEST_P(CookieStoreChangeUrlTest,DifferentSubscriptionsDomains)1516 TYPED_TEST_P(CookieStoreChangeUrlTest, DifferentSubscriptionsDomains) {
1517   if (!TypeParam::supports_url_cookie_tracking)
1518     return;
1519 
1520   CookieStore* cs = this->GetCookieStore();
1521 
1522   std::vector<CookieChangeInfo> cookie_changes_1, cookie_changes_2;
1523   std::unique_ptr<CookieChangeSubscription> subscription1 =
1524       cs->GetChangeDispatcher().AddCallbackForUrl(
1525           this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
1526           base::BindRepeating(
1527               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
1528               base::Unretained(&cookie_changes_1)));
1529   std::unique_ptr<CookieChangeSubscription> subscription2 =
1530       cs->GetChangeDispatcher().AddCallbackForUrl(
1531           this->http_bar_com_.url(), absl::nullopt /* cookie_partition_key */,
1532           base::BindRepeating(
1533               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
1534               base::Unretained(&cookie_changes_2)));
1535   this->DeliverChangeNotifications();
1536   ASSERT_EQ(0u, cookie_changes_1.size());
1537   ASSERT_EQ(0u, cookie_changes_2.size());
1538 
1539   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
1540   this->DeliverChangeNotifications();
1541   EXPECT_EQ(1u, cookie_changes_1.size());
1542   EXPECT_EQ(0u, cookie_changes_2.size());
1543 
1544   EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "C=D"));
1545   this->DeliverChangeNotifications();
1546 
1547   ASSERT_EQ(1u, cookie_changes_1.size());
1548   EXPECT_EQ("A", cookie_changes_1[0].cookie.Name());
1549   EXPECT_EQ("B", cookie_changes_1[0].cookie.Value());
1550   EXPECT_EQ(this->http_www_foo_.url().host(),
1551             cookie_changes_1[0].cookie.Domain());
1552 
1553   ASSERT_EQ(1u, cookie_changes_2.size());
1554   EXPECT_EQ("C", cookie_changes_2[0].cookie.Name());
1555   EXPECT_EQ("D", cookie_changes_2[0].cookie.Value());
1556   EXPECT_EQ(this->http_bar_com_.url().host(),
1557             cookie_changes_2[0].cookie.Domain());
1558 }
1559 
TYPED_TEST_P(CookieStoreChangeUrlTest,DifferentSubscriptionsPaths)1560 TYPED_TEST_P(CookieStoreChangeUrlTest, DifferentSubscriptionsPaths) {
1561   if (!TypeParam::supports_url_cookie_tracking)
1562     return;
1563 
1564   CookieStore* cs = this->GetCookieStore();
1565 
1566   std::vector<CookieChangeInfo> cookie_changes_1, cookie_changes_2;
1567   std::unique_ptr<CookieChangeSubscription> subscription1 =
1568       cs->GetChangeDispatcher().AddCallbackForUrl(
1569           this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
1570           base::BindRepeating(
1571               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
1572               base::Unretained(&cookie_changes_1)));
1573   std::unique_ptr<CookieChangeSubscription> subscription2 =
1574       cs->GetChangeDispatcher().AddCallbackForUrl(
1575           this->www_foo_foo_.url(), absl::nullopt /* cookie_partition_key */,
1576           base::BindRepeating(
1577               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
1578               base::Unretained(&cookie_changes_2)));
1579   this->DeliverChangeNotifications();
1580   ASSERT_EQ(0u, cookie_changes_1.size());
1581   ASSERT_EQ(0u, cookie_changes_2.size());
1582 
1583   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
1584   this->DeliverChangeNotifications();
1585   EXPECT_EQ(1u, cookie_changes_1.size());
1586   EXPECT_EQ(1u, cookie_changes_2.size());
1587 
1588   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D; path=/foo"));
1589   this->DeliverChangeNotifications();
1590 
1591   ASSERT_EQ(1u, cookie_changes_1.size());
1592   EXPECT_EQ("A", cookie_changes_1[0].cookie.Name());
1593   EXPECT_EQ("B", cookie_changes_1[0].cookie.Value());
1594   EXPECT_EQ("/", cookie_changes_1[0].cookie.Path());
1595   EXPECT_EQ(this->http_www_foo_.url().host(),
1596             cookie_changes_1[0].cookie.Domain());
1597 
1598   ASSERT_LE(1u, cookie_changes_2.size());
1599   EXPECT_EQ("A", cookie_changes_2[0].cookie.Name());
1600   EXPECT_EQ("B", cookie_changes_2[0].cookie.Value());
1601   EXPECT_EQ("/", cookie_changes_2[0].cookie.Path());
1602   EXPECT_EQ(this->http_www_foo_.url().host(),
1603             cookie_changes_2[0].cookie.Domain());
1604 
1605   ASSERT_LE(2u, cookie_changes_2.size());
1606   EXPECT_EQ("C", cookie_changes_2[1].cookie.Name());
1607   EXPECT_EQ("D", cookie_changes_2[1].cookie.Value());
1608   EXPECT_EQ("/foo", cookie_changes_2[1].cookie.Path());
1609   EXPECT_EQ(this->http_www_foo_.url().host(),
1610             cookie_changes_2[1].cookie.Domain());
1611 
1612   EXPECT_EQ(2u, cookie_changes_2.size());
1613 }
1614 
TYPED_TEST_P(CookieStoreChangeUrlTest,DifferentSubscriptionsFiltering)1615 TYPED_TEST_P(CookieStoreChangeUrlTest, DifferentSubscriptionsFiltering) {
1616   if (!TypeParam::supports_url_cookie_tracking)
1617     return;
1618 
1619   CookieStore* cs = this->GetCookieStore();
1620 
1621   std::vector<CookieChangeInfo> cookie_changes_1, cookie_changes_2;
1622   std::vector<CookieChangeInfo> cookie_changes_3;
1623   std::unique_ptr<CookieChangeSubscription> subscription1 =
1624       cs->GetChangeDispatcher().AddCallbackForUrl(
1625           this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
1626           base::BindRepeating(
1627               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
1628               base::Unretained(&cookie_changes_1)));
1629   std::unique_ptr<CookieChangeSubscription> subscription2 =
1630       cs->GetChangeDispatcher().AddCallbackForUrl(
1631           this->http_bar_com_.url(), absl::nullopt /* cookie_partition_key */,
1632           base::BindRepeating(
1633               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
1634               base::Unretained(&cookie_changes_2)));
1635   std::unique_ptr<CookieChangeSubscription> subscription3 =
1636       cs->GetChangeDispatcher().AddCallbackForUrl(
1637           this->www_foo_foo_.url(), absl::nullopt /* cookie_partition_key */,
1638           base::BindRepeating(
1639               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
1640               base::Unretained(&cookie_changes_3)));
1641   this->DeliverChangeNotifications();
1642   ASSERT_EQ(0u, cookie_changes_1.size());
1643   ASSERT_EQ(0u, cookie_changes_2.size());
1644   EXPECT_EQ(0u, cookie_changes_3.size());
1645 
1646   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
1647   this->DeliverChangeNotifications();
1648   EXPECT_EQ(1u, cookie_changes_1.size());
1649   EXPECT_EQ(0u, cookie_changes_2.size());
1650   EXPECT_EQ(1u, cookie_changes_3.size());
1651 
1652   EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "C=D"));
1653   this->DeliverChangeNotifications();
1654   EXPECT_EQ(1u, cookie_changes_1.size());
1655   EXPECT_EQ(1u, cookie_changes_2.size());
1656   EXPECT_EQ(1u, cookie_changes_3.size());
1657 
1658   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "E=F; path=/foo"));
1659   this->DeliverChangeNotifications();
1660 
1661   ASSERT_LE(1u, cookie_changes_1.size());
1662   EXPECT_EQ("A", cookie_changes_1[0].cookie.Name());
1663   EXPECT_EQ("B", cookie_changes_1[0].cookie.Value());
1664   EXPECT_EQ(this->http_www_foo_.url().host(),
1665             cookie_changes_1[0].cookie.Domain());
1666   EXPECT_EQ(1u, cookie_changes_1.size());
1667 
1668   ASSERT_LE(1u, cookie_changes_2.size());
1669   EXPECT_EQ("C", cookie_changes_2[0].cookie.Name());
1670   EXPECT_EQ("D", cookie_changes_2[0].cookie.Value());
1671   EXPECT_EQ(this->http_bar_com_.url().host(),
1672             cookie_changes_2[0].cookie.Domain());
1673   EXPECT_EQ(1u, cookie_changes_2.size());
1674 
1675   ASSERT_LE(1u, cookie_changes_3.size());
1676   EXPECT_EQ("A", cookie_changes_3[0].cookie.Name());
1677   EXPECT_EQ("B", cookie_changes_3[0].cookie.Value());
1678   EXPECT_EQ("/", cookie_changes_3[0].cookie.Path());
1679   EXPECT_EQ(this->http_www_foo_.url().host(),
1680             cookie_changes_3[0].cookie.Domain());
1681 
1682   ASSERT_LE(2u, cookie_changes_3.size());
1683   EXPECT_EQ("E", cookie_changes_3[1].cookie.Name());
1684   EXPECT_EQ("F", cookie_changes_3[1].cookie.Value());
1685   EXPECT_EQ("/foo", cookie_changes_3[1].cookie.Path());
1686   EXPECT_EQ(this->http_www_foo_.url().host(),
1687             cookie_changes_3[1].cookie.Domain());
1688 
1689   EXPECT_EQ(2u, cookie_changes_3.size());
1690 }
1691 
TYPED_TEST_P(CookieStoreChangeUrlTest,MultipleSubscriptions)1692 TYPED_TEST_P(CookieStoreChangeUrlTest, MultipleSubscriptions) {
1693   if (!TypeParam::supports_url_cookie_tracking ||
1694       !TypeParam::supports_multiple_tracking_callbacks)
1695     return;
1696 
1697   CookieStore* cs = this->GetCookieStore();
1698 
1699   std::vector<CookieChangeInfo> cookie_changes_1, cookie_changes_2;
1700   std::unique_ptr<CookieChangeSubscription> subscription1 =
1701       cs->GetChangeDispatcher().AddCallbackForUrl(
1702           this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
1703           base::BindRepeating(
1704               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
1705               base::Unretained(&cookie_changes_1)));
1706   std::unique_ptr<CookieChangeSubscription> subscription2 =
1707       cs->GetChangeDispatcher().AddCallbackForUrl(
1708           this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
1709           base::BindRepeating(
1710               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
1711               base::Unretained(&cookie_changes_2)));
1712   this->DeliverChangeNotifications();
1713 
1714   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
1715   this->DeliverChangeNotifications();
1716 
1717   ASSERT_EQ(1U, cookie_changes_1.size());
1718   EXPECT_EQ("A", cookie_changes_1[0].cookie.Name());
1719   EXPECT_EQ("B", cookie_changes_1[0].cookie.Value());
1720 
1721   ASSERT_EQ(1U, cookie_changes_2.size());
1722   EXPECT_EQ("A", cookie_changes_2[0].cookie.Name());
1723   EXPECT_EQ("B", cookie_changes_2[0].cookie.Value());
1724 }
1725 
TYPED_TEST_P(CookieStoreChangeUrlTest,ChangeIncludesCookieAccessSemantics)1726 TYPED_TEST_P(CookieStoreChangeUrlTest, ChangeIncludesCookieAccessSemantics) {
1727   if (!TypeParam::supports_url_cookie_tracking)
1728     return;
1729 
1730   CookieStore* cs = this->GetCookieStore();
1731   // if !supports_cookie_access_semantics, the delegate will be stored but will
1732   // not be used.
1733   auto access_delegate = std::make_unique<TestCookieAccessDelegate>();
1734   access_delegate->SetExpectationForCookieDomain("domain1.test",
1735                                                  CookieAccessSemantics::LEGACY);
1736   cs->SetCookieAccessDelegate(std::move(access_delegate));
1737 
1738   std::vector<CookieChangeInfo> cookie_changes;
1739   std::unique_ptr<CookieChangeSubscription> subscription =
1740       cs->GetChangeDispatcher().AddCallbackForUrl(
1741           GURL("http://domain1.test"), absl::nullopt /* cookie_partition_key */,
1742           base::BindRepeating(
1743               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
1744               base::Unretained(&cookie_changes)));
1745 
1746   this->CreateAndSetCookie(cs, GURL("http://domain1.test"), "cookie=1",
1747                            CookieOptions::MakeAllInclusive());
1748   this->DeliverChangeNotifications();
1749 
1750   ASSERT_EQ(1u, cookie_changes.size());
1751 
1752   EXPECT_EQ("domain1.test", cookie_changes[0].cookie.Domain());
1753   EXPECT_TRUE(this->IsExpectedAccessSemantics(
1754       CookieAccessSemantics::LEGACY,
1755       cookie_changes[0].access_result.access_semantics));
1756 }
1757 
TYPED_TEST_P(CookieStoreChangeUrlTest,PartitionedCookies)1758 TYPED_TEST_P(CookieStoreChangeUrlTest, PartitionedCookies) {
1759   if (!TypeParam::supports_url_cookie_tracking ||
1760       !TypeParam::supports_partitioned_cookies)
1761     return;
1762 
1763   CookieStore* cs = this->GetCookieStore();
1764   std::vector<CookieChangeInfo> cookie_changes;
1765   std::unique_ptr<CookieChangeSubscription> subscription =
1766       cs->GetChangeDispatcher().AddCallbackForUrl(
1767           GURL("https://www.example.com/"),
1768           CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com")),
1769           base::BindRepeating(
1770               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
1771               base::Unretained(&cookie_changes)));
1772 
1773   // Unpartitioned cookie
1774   this->CreateAndSetCookie(cs, GURL("https://www.example.com/"),
1775                            "__Host-a=1; Secure; Path=/",
1776                            CookieOptions::MakeAllInclusive());
1777   // Partitioned cookie with the same partition key
1778   this->CreateAndSetCookie(
1779       cs, GURL("https://www.example.com/"),
1780       "__Host-b=2; Secure; Path=/; Partitioned",
1781       CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */,
1782       absl::nullopt /* system_time */,
1783       CookiePartitionKey::FromURLForTesting(GURL("https://sub.foo.com")));
1784   // Partitioned cookie with a different partition key
1785   this->CreateAndSetCookie(
1786       cs, GURL("https://www.example.com"),
1787       "__Host-c=3; Secure; Path=/; Partitioned",
1788       CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */,
1789       absl::nullopt /* system_time */,
1790       CookiePartitionKey::FromURLForTesting(GURL("https://www.bar.com")));
1791   this->DeliverChangeNotifications();
1792 
1793   ASSERT_EQ(2u, cookie_changes.size());
1794   EXPECT_FALSE(cookie_changes[0].cookie.IsPartitioned());
1795   EXPECT_EQ("__Host-a", cookie_changes[0].cookie.Name());
1796   EXPECT_TRUE(cookie_changes[1].cookie.IsPartitioned());
1797   EXPECT_EQ(CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com")),
1798             cookie_changes[1].cookie.PartitionKey().value());
1799   EXPECT_EQ("__Host-b", cookie_changes[1].cookie.Name());
1800 
1801   // Test that when the partition key parameter is nullopt that all Partitioned
1802   // cookies do not emit events.
1803 
1804   std::vector<CookieChangeInfo> other_cookie_changes;
1805   std::unique_ptr<CookieChangeSubscription> other_subscription =
1806       cs->GetChangeDispatcher().AddCallbackForUrl(
1807           GURL("https://www.example.com/"),
1808           absl::nullopt /* cookie_partition_key */,
1809           base::BindRepeating(
1810               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
1811               base::Unretained(&other_cookie_changes)));
1812   // Update Max-Age: None -> 7200
1813   this->CreateAndSetCookie(
1814       cs, GURL("https://www.example.com"),
1815       "__Host-b=2; Secure; Path=/; Partitioned; Max-Age=7200",
1816       CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */,
1817       absl::nullopt /* system_time */,
1818       CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com")));
1819   this->DeliverChangeNotifications();
1820   ASSERT_EQ(0u, other_cookie_changes.size());
1821   // Check that the other listener was invoked.
1822   ASSERT_LT(2u, cookie_changes.size());
1823 }
1824 
TYPED_TEST_P(CookieStoreChangeUrlTest,PartitionedCookies_WithNonce)1825 TYPED_TEST_P(CookieStoreChangeUrlTest, PartitionedCookies_WithNonce) {
1826   if (!TypeParam::supports_named_cookie_tracking ||
1827       !TypeParam::supports_partitioned_cookies) {
1828     return;
1829   }
1830 
1831   CookieStore* cs = this->GetCookieStore();
1832   base::UnguessableToken nonce = base::UnguessableToken::Create();
1833 
1834   std::vector<CookieChangeInfo> cookie_changes;
1835   std::unique_ptr<CookieChangeSubscription> subscription =
1836       cs->GetChangeDispatcher().AddCallbackForUrl(
1837           GURL("https://www.example.com"),
1838           CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com"),
1839                                                 nonce),
1840           base::BindRepeating(
1841               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
1842               base::Unretained(&cookie_changes)));
1843 
1844   // Should not see changes to an unpartitioned cookie.
1845   this->CreateAndSetCookie(cs, GURL("https://www.example.com"),
1846                            "__Host-a=1; Secure; Path=/",
1847                            CookieOptions::MakeAllInclusive());
1848   this->DeliverChangeNotifications();
1849   ASSERT_EQ(0u, cookie_changes.size());
1850 
1851   // Set partitioned cookie without nonce. Should not see the change.
1852   this->CreateAndSetCookie(
1853       cs, GURL("https://www.example.com"),
1854       "__Host-a=2; Secure; Path=/; Partitioned",
1855       CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */,
1856       absl::nullopt /* system_time */,
1857       CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com")));
1858   this->DeliverChangeNotifications();
1859   ASSERT_EQ(0u, cookie_changes.size());
1860 
1861   // Set partitioned cookie with nonce.
1862   this->CreateAndSetCookie(cs, GURL("https://www.example.com"),
1863                            "__Host-a=3; Secure; Path=/; Partitioned",
1864                            CookieOptions::MakeAllInclusive(),
1865                            absl::nullopt /* server_time */,
1866                            absl::nullopt /* system_time */,
1867                            CookiePartitionKey::FromURLForTesting(
1868                                GURL("https://www.foo.com"), nonce));
1869   this->DeliverChangeNotifications();
1870   ASSERT_EQ(1u, cookie_changes.size());
1871 }
1872 
TYPED_TEST_P(CookieStoreChangeNamedTest,NoCookie)1873 TYPED_TEST_P(CookieStoreChangeNamedTest, NoCookie) {
1874   if (!TypeParam::supports_named_cookie_tracking)
1875     return;
1876 
1877   CookieStore* cs = this->GetCookieStore();
1878   std::vector<CookieChangeInfo> cookie_changes;
1879   std::unique_ptr<CookieChangeSubscription> subscription =
1880       cs->GetChangeDispatcher().AddCallbackForCookie(
1881           this->http_www_foo_.url(), "abc",
1882           absl::nullopt /* cookie_partition_key */,
1883           base::BindRepeating(
1884               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
1885               base::Unretained(&cookie_changes)));
1886   this->DeliverChangeNotifications();
1887   EXPECT_EQ(0u, cookie_changes.size());
1888 }
1889 
TYPED_TEST_P(CookieStoreChangeNamedTest,InitialCookie)1890 TYPED_TEST_P(CookieStoreChangeNamedTest, InitialCookie) {
1891   if (!TypeParam::supports_named_cookie_tracking)
1892     return;
1893 
1894   CookieStore* cs = this->GetCookieStore();
1895   std::vector<CookieChangeInfo> cookie_changes;
1896   this->SetCookie(cs, this->http_www_foo_.url(), "abc=def");
1897   this->DeliverChangeNotifications();
1898   std::unique_ptr<CookieChangeSubscription> subscription =
1899       cs->GetChangeDispatcher().AddCallbackForCookie(
1900           this->http_www_foo_.url(), "abc",
1901           absl::nullopt /* cookie_partition_key */,
1902           base::BindRepeating(
1903               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
1904               base::Unretained(&cookie_changes)));
1905   this->DeliverChangeNotifications();
1906   EXPECT_EQ(0u, cookie_changes.size());
1907 }
1908 
TYPED_TEST_P(CookieStoreChangeNamedTest,InsertOne)1909 TYPED_TEST_P(CookieStoreChangeNamedTest, InsertOne) {
1910   if (!TypeParam::supports_named_cookie_tracking)
1911     return;
1912 
1913   CookieStore* cs = this->GetCookieStore();
1914   std::vector<CookieChangeInfo> cookie_changes;
1915   std::unique_ptr<CookieChangeSubscription> subscription =
1916       cs->GetChangeDispatcher().AddCallbackForCookie(
1917           this->http_www_foo_.url(), "abc",
1918           absl::nullopt /* cookie_partition_key */,
1919           base::BindRepeating(
1920               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
1921               base::Unretained(&cookie_changes)));
1922   this->DeliverChangeNotifications();
1923   ASSERT_EQ(0u, cookie_changes.size());
1924 
1925   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
1926   this->DeliverChangeNotifications();
1927   ASSERT_EQ(1u, cookie_changes.size());
1928 
1929   EXPECT_EQ("abc", cookie_changes[0].cookie.Name());
1930   EXPECT_EQ("def", cookie_changes[0].cookie.Value());
1931   EXPECT_EQ(this->http_www_foo_.url().host(),
1932             cookie_changes[0].cookie.Domain());
1933   EXPECT_TRUE(
1934       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[0].cause));
1935 }
1936 
TYPED_TEST_P(CookieStoreChangeNamedTest,InsertTwo)1937 TYPED_TEST_P(CookieStoreChangeNamedTest, InsertTwo) {
1938   if (!TypeParam::supports_named_cookie_tracking)
1939     return;
1940 
1941   CookieStore* cs = this->GetCookieStore();
1942   std::vector<CookieChangeInfo> cookie_changes;
1943   std::unique_ptr<CookieChangeSubscription> subscription =
1944       cs->GetChangeDispatcher().AddCallbackForCookie(
1945           this->www_foo_foo_.url(), "abc",
1946           absl::nullopt /* cookie_partition_key */,
1947           base::BindRepeating(
1948               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
1949               base::Unretained(&cookie_changes)));
1950   this->DeliverChangeNotifications();
1951   ASSERT_EQ(0u, cookie_changes.size());
1952 
1953   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
1954   EXPECT_TRUE(
1955       this->SetCookie(cs, this->http_www_foo_.url(), "abc=hij; path=/foo"));
1956   this->DeliverChangeNotifications();
1957 
1958   ASSERT_LE(1u, cookie_changes.size());
1959   EXPECT_EQ("abc", cookie_changes[0].cookie.Name());
1960   EXPECT_EQ("def", cookie_changes[0].cookie.Value());
1961   EXPECT_EQ("/", cookie_changes[0].cookie.Path());
1962   EXPECT_EQ(this->http_www_foo_.url().host(),
1963             cookie_changes[0].cookie.Domain());
1964   EXPECT_TRUE(
1965       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[0].cause));
1966 
1967   ASSERT_LE(2u, cookie_changes.size());
1968   EXPECT_EQ("abc", cookie_changes[1].cookie.Name());
1969   EXPECT_EQ("hij", cookie_changes[1].cookie.Value());
1970   EXPECT_EQ("/foo", cookie_changes[1].cookie.Path());
1971   EXPECT_EQ(this->http_www_foo_.url().host(),
1972             cookie_changes[1].cookie.Domain());
1973   EXPECT_TRUE(
1974       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[1].cause));
1975 
1976   EXPECT_EQ(2u, cookie_changes.size());
1977 }
1978 
TYPED_TEST_P(CookieStoreChangeNamedTest,InsertFiltering)1979 TYPED_TEST_P(CookieStoreChangeNamedTest, InsertFiltering) {
1980   if (!TypeParam::supports_named_cookie_tracking)
1981     return;
1982 
1983   CookieStore* cs = this->GetCookieStore();
1984   std::vector<CookieChangeInfo> cookie_changes;
1985   std::unique_ptr<CookieChangeSubscription> subscription =
1986       cs->GetChangeDispatcher().AddCallbackForCookie(
1987           this->www_foo_foo_.url(), "abc",
1988           absl::nullopt /* cookie_partition_key */,
1989           base::BindRepeating(
1990               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
1991               base::Unretained(&cookie_changes)));
1992   this->DeliverChangeNotifications();
1993   ASSERT_EQ(0u, cookie_changes.size());
1994 
1995   EXPECT_TRUE(
1996       this->SetCookie(cs, this->http_www_foo_.url(), "abc=def; path=/"));
1997   EXPECT_TRUE(
1998       this->SetCookie(cs, this->http_bar_com_.url(), "abc=ghi; path=/"));
1999   EXPECT_TRUE(
2000       this->SetCookie(cs, this->http_www_foo_.url(), "abc=jkl; path=/bar"));
2001   EXPECT_TRUE(
2002       this->SetCookie(cs, this->http_www_foo_.url(), "abc=mno; path=/foo/bar"));
2003   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "xyz=zyx"));
2004   EXPECT_TRUE(
2005       this->SetCookie(cs, this->http_www_foo_.url(), "abc=pqr; path=/foo"));
2006   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
2007                               "abc=stu; domain=foo.com"));
2008   this->DeliverChangeNotifications();
2009 
2010   ASSERT_LE(1u, cookie_changes.size());
2011   EXPECT_EQ("abc", cookie_changes[0].cookie.Name());
2012   EXPECT_EQ("def", cookie_changes[0].cookie.Value());
2013   EXPECT_EQ("/", cookie_changes[0].cookie.Path());
2014   EXPECT_EQ(this->http_www_foo_.url().host(),
2015             cookie_changes[0].cookie.Domain());
2016   EXPECT_TRUE(
2017       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[0].cause));
2018 
2019   ASSERT_LE(2u, cookie_changes.size());
2020   EXPECT_EQ("abc", cookie_changes[1].cookie.Name());
2021   EXPECT_EQ("pqr", cookie_changes[1].cookie.Value());
2022   EXPECT_EQ("/foo", cookie_changes[1].cookie.Path());
2023   EXPECT_EQ(this->http_www_foo_.url().host(),
2024             cookie_changes[1].cookie.Domain());
2025   EXPECT_TRUE(
2026       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[1].cause));
2027 
2028   ASSERT_LE(3u, cookie_changes.size());
2029   EXPECT_EQ("abc", cookie_changes[2].cookie.Name());
2030   EXPECT_EQ("stu", cookie_changes[2].cookie.Value());
2031   EXPECT_EQ("/", cookie_changes[2].cookie.Path());
2032   EXPECT_EQ(".foo.com", cookie_changes[2].cookie.Domain());
2033   EXPECT_TRUE(
2034       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[2].cause));
2035 
2036   EXPECT_EQ(3u, cookie_changes.size());
2037 }
2038 
TYPED_TEST_P(CookieStoreChangeNamedTest,DeleteOne)2039 TYPED_TEST_P(CookieStoreChangeNamedTest, DeleteOne) {
2040   if (!TypeParam::supports_named_cookie_tracking)
2041     return;
2042 
2043   CookieStore* cs = this->GetCookieStore();
2044   std::vector<CookieChangeInfo> cookie_changes;
2045   std::unique_ptr<CookieChangeSubscription> subscription =
2046       cs->GetChangeDispatcher().AddCallbackForCookie(
2047           this->http_www_foo_.url(), "abc",
2048           absl::nullopt /* cookie_partition_key */,
2049           base::BindRepeating(
2050               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
2051               base::Unretained(&cookie_changes)));
2052   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
2053   this->DeliverChangeNotifications();
2054   EXPECT_EQ(1u, cookie_changes.size());
2055   cookie_changes.clear();
2056 
2057   EXPECT_TRUE(
2058       this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "abc"));
2059   this->DeliverChangeNotifications();
2060 
2061   ASSERT_EQ(1u, cookie_changes.size());
2062   EXPECT_EQ("abc", cookie_changes[0].cookie.Name());
2063   EXPECT_EQ("def", cookie_changes[0].cookie.Value());
2064   EXPECT_EQ(this->http_www_foo_.url().host(),
2065             cookie_changes[0].cookie.Domain());
2066   EXPECT_TRUE(
2067       this->MatchesCause(CookieChangeCause::EXPLICIT, cookie_changes[0].cause));
2068 }
2069 
TYPED_TEST_P(CookieStoreChangeNamedTest,DeleteTwo)2070 TYPED_TEST_P(CookieStoreChangeNamedTest, DeleteTwo) {
2071   if (!TypeParam::supports_named_cookie_tracking)
2072     return;
2073 
2074   CookieStore* cs = this->GetCookieStore();
2075   std::vector<CookieChangeInfo> cookie_changes;
2076   std::unique_ptr<CookieChangeSubscription> subscription =
2077       cs->GetChangeDispatcher().AddCallbackForCookie(
2078           this->www_foo_foo_.url(), "abc",
2079           absl::nullopt /* cookie_partition_key */,
2080           base::BindRepeating(
2081               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
2082               base::Unretained(&cookie_changes)));
2083   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
2084   EXPECT_TRUE(
2085       this->SetCookie(cs, this->http_www_foo_.url(), "abc=hij; path=/foo"));
2086   this->DeliverChangeNotifications();
2087   EXPECT_EQ(2u, cookie_changes.size());
2088   cookie_changes.clear();
2089 
2090   EXPECT_TRUE(this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(),
2091                                         "abc", "/"));
2092   EXPECT_TRUE(this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(),
2093                                         "abc", "/foo"));
2094   this->DeliverChangeNotifications();
2095 
2096   ASSERT_LE(1u, cookie_changes.size());
2097   EXPECT_EQ("abc", cookie_changes[0].cookie.Name());
2098   EXPECT_EQ("def", cookie_changes[0].cookie.Value());
2099   EXPECT_EQ("/", cookie_changes[0].cookie.Path());
2100   EXPECT_EQ(this->http_www_foo_.url().host(),
2101             cookie_changes[0].cookie.Domain());
2102   EXPECT_TRUE(
2103       this->MatchesCause(CookieChangeCause::EXPLICIT, cookie_changes[0].cause));
2104 
2105   ASSERT_EQ(2u, cookie_changes.size());
2106   EXPECT_EQ("abc", cookie_changes[1].cookie.Name());
2107   EXPECT_EQ("hij", cookie_changes[1].cookie.Value());
2108   EXPECT_EQ("/foo", cookie_changes[1].cookie.Path());
2109   EXPECT_EQ(this->http_www_foo_.url().host(),
2110             cookie_changes[1].cookie.Domain());
2111   EXPECT_TRUE(
2112       this->MatchesCause(CookieChangeCause::EXPLICIT, cookie_changes[1].cause));
2113 }
2114 
TYPED_TEST_P(CookieStoreChangeNamedTest,DeleteFiltering)2115 TYPED_TEST_P(CookieStoreChangeNamedTest, DeleteFiltering) {
2116   if (!TypeParam::supports_named_cookie_tracking)
2117     return;
2118 
2119   CookieStore* cs = this->GetCookieStore();
2120   std::vector<CookieChangeInfo> cookie_changes;
2121   std::unique_ptr<CookieChangeSubscription> subscription =
2122       cs->GetChangeDispatcher().AddCallbackForCookie(
2123           this->www_foo_foo_.url(), "abc",
2124           absl::nullopt /* cookie_partition_key */,
2125           base::BindRepeating(
2126               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
2127               base::Unretained(&cookie_changes)));
2128   EXPECT_TRUE(
2129       this->SetCookie(cs, this->http_www_foo_.url(), "xyz=zyx; path=/"));
2130   EXPECT_TRUE(
2131       this->SetCookie(cs, this->http_bar_com_.url(), "abc=def; path=/"));
2132   EXPECT_TRUE(
2133       this->SetCookie(cs, this->http_www_foo_.url(), "abc=hij; path=/foo/bar"));
2134   EXPECT_TRUE(
2135       this->SetCookie(cs, this->http_www_foo_.url(), "abc=mno; path=/foo"));
2136   EXPECT_TRUE(
2137       this->SetCookie(cs, this->http_www_foo_.url(), "abc=pqr; path=/"));
2138   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
2139                               "abc=stu; domain=foo.com"));
2140   this->DeliverChangeNotifications();
2141   EXPECT_EQ(3u, cookie_changes.size());
2142   cookie_changes.clear();
2143 
2144   EXPECT_TRUE(
2145       this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "xyz"));
2146   EXPECT_TRUE(
2147       this->FindAndDeleteCookie(cs, this->http_bar_com_.url().host(), "abc"));
2148   EXPECT_TRUE(this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(),
2149                                         "abc", "/foo/bar"));
2150   EXPECT_TRUE(this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(),
2151                                         "abc", "/foo"));
2152   EXPECT_TRUE(this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(),
2153                                         "abc", "/"));
2154   EXPECT_TRUE(this->FindAndDeleteCookie(cs, ".foo.com", "abc", "/"));
2155   this->DeliverChangeNotifications();
2156 
2157   ASSERT_LE(1u, cookie_changes.size());
2158   EXPECT_EQ("abc", cookie_changes[0].cookie.Name());
2159   EXPECT_EQ("mno", cookie_changes[0].cookie.Value());
2160   EXPECT_EQ("/foo", cookie_changes[0].cookie.Path());
2161   EXPECT_EQ(this->http_www_foo_.url().host(),
2162             cookie_changes[0].cookie.Domain());
2163   EXPECT_TRUE(
2164       this->MatchesCause(CookieChangeCause::EXPLICIT, cookie_changes[0].cause));
2165 
2166   ASSERT_LE(2u, cookie_changes.size());
2167   EXPECT_EQ("abc", cookie_changes[1].cookie.Name());
2168   EXPECT_EQ("pqr", cookie_changes[1].cookie.Value());
2169   EXPECT_EQ("/", cookie_changes[1].cookie.Path());
2170   EXPECT_EQ(this->http_www_foo_.url().host(),
2171             cookie_changes[1].cookie.Domain());
2172   EXPECT_TRUE(
2173       this->MatchesCause(CookieChangeCause::EXPLICIT, cookie_changes[1].cause));
2174 
2175   ASSERT_LE(3u, cookie_changes.size());
2176   EXPECT_EQ("abc", cookie_changes[2].cookie.Name());
2177   EXPECT_EQ("stu", cookie_changes[2].cookie.Value());
2178   EXPECT_EQ("/", cookie_changes[2].cookie.Path());
2179   EXPECT_EQ(".foo.com", cookie_changes[2].cookie.Domain());
2180   EXPECT_TRUE(
2181       this->MatchesCause(CookieChangeCause::EXPLICIT, cookie_changes[2].cause));
2182 
2183   EXPECT_EQ(3u, cookie_changes.size());
2184 }
2185 
TYPED_TEST_P(CookieStoreChangeNamedTest,Overwrite)2186 TYPED_TEST_P(CookieStoreChangeNamedTest, Overwrite) {
2187   if (!TypeParam::supports_named_cookie_tracking)
2188     return;
2189 
2190   CookieStore* cs = this->GetCookieStore();
2191   std::vector<CookieChangeInfo> cookie_changes;
2192   std::unique_ptr<CookieChangeSubscription> subscription =
2193       cs->GetChangeDispatcher().AddCallbackForCookie(
2194           this->http_www_foo_.url(), "abc",
2195           absl::nullopt /* cookie_partition_key */,
2196           base::BindRepeating(
2197               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
2198               base::Unretained(&cookie_changes)));
2199   this->DeliverChangeNotifications();
2200   ASSERT_EQ(0u, cookie_changes.size());
2201 
2202   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
2203   this->DeliverChangeNotifications();
2204   EXPECT_EQ(1u, cookie_changes.size());
2205   cookie_changes.clear();
2206 
2207   // Replacing an existing cookie is actually a two-phase delete + set
2208   // operation, so we get an extra notification.
2209   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=ghi"));
2210   this->DeliverChangeNotifications();
2211 
2212   EXPECT_LE(1u, cookie_changes.size());
2213   EXPECT_EQ("abc", cookie_changes[0].cookie.Name());
2214   EXPECT_EQ("def", cookie_changes[0].cookie.Value());
2215   EXPECT_EQ(this->http_www_foo_.url().host(),
2216             cookie_changes[0].cookie.Domain());
2217   EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
2218                                  cookie_changes[0].cause));
2219 
2220   EXPECT_LE(2u, cookie_changes.size());
2221   EXPECT_EQ("abc", cookie_changes[1].cookie.Name());
2222   EXPECT_EQ("ghi", cookie_changes[1].cookie.Value());
2223   EXPECT_EQ(this->http_www_foo_.url().host(),
2224             cookie_changes[1].cookie.Domain());
2225   EXPECT_TRUE(
2226       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[1].cause));
2227 
2228   EXPECT_EQ(2u, cookie_changes.size());
2229 }
2230 
TYPED_TEST_P(CookieStoreChangeNamedTest,OverwriteFiltering)2231 TYPED_TEST_P(CookieStoreChangeNamedTest, OverwriteFiltering) {
2232   if (!TypeParam::supports_named_cookie_tracking)
2233     return;
2234 
2235   CookieStore* cs = this->GetCookieStore();
2236   std::vector<CookieChangeInfo> cookie_changes;
2237   std::unique_ptr<CookieChangeSubscription> subscription =
2238       cs->GetChangeDispatcher().AddCallbackForCookie(
2239           this->www_foo_foo_.url(), "abc",
2240           absl::nullopt /* cookie_partition_key */,
2241           base::BindRepeating(
2242               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
2243               base::Unretained(&cookie_changes)));
2244   this->DeliverChangeNotifications();
2245   ASSERT_EQ(0u, cookie_changes.size());
2246 
2247   EXPECT_TRUE(
2248       this->SetCookie(cs, this->http_www_foo_.url(), "xyz=zyx1; path=/"));
2249   EXPECT_TRUE(
2250       this->SetCookie(cs, this->http_bar_com_.url(), "abc=def1; path=/"));
2251   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
2252                               "abc=hij1; path=/foo/bar"));
2253   EXPECT_TRUE(
2254       this->SetCookie(cs, this->http_www_foo_.url(), "abc=mno1; path=/foo"));
2255   EXPECT_TRUE(
2256       this->SetCookie(cs, this->http_www_foo_.url(), "abc=pqr1; path=/"));
2257   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
2258                               "abc=stu1; domain=foo.com"));
2259   this->DeliverChangeNotifications();
2260   EXPECT_EQ(3u, cookie_changes.size());
2261   cookie_changes.clear();
2262 
2263   // Replacing an existing cookie is actually a two-phase delete + set
2264   // operation, so we get two notifications per overwrite.
2265   EXPECT_TRUE(
2266       this->SetCookie(cs, this->http_www_foo_.url(), "xyz=zyx2; path=/"));
2267   EXPECT_TRUE(
2268       this->SetCookie(cs, this->http_bar_com_.url(), "abc=def2; path=/"));
2269   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
2270                               "abc=hij2; path=/foo/bar"));
2271   EXPECT_TRUE(
2272       this->SetCookie(cs, this->http_www_foo_.url(), "abc=mno2; path=/foo"));
2273   EXPECT_TRUE(
2274       this->SetCookie(cs, this->http_www_foo_.url(), "abc=pqr2; path=/"));
2275   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
2276                               "abc=stu2; domain=foo.com"));
2277   this->DeliverChangeNotifications();
2278 
2279   ASSERT_LE(1u, cookie_changes.size());
2280   EXPECT_EQ("abc", cookie_changes[0].cookie.Name());
2281   EXPECT_EQ("mno1", cookie_changes[0].cookie.Value());
2282   EXPECT_EQ("/foo", cookie_changes[0].cookie.Path());
2283   EXPECT_EQ(this->http_www_foo_.url().host(),
2284             cookie_changes[0].cookie.Domain());
2285   EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
2286                                  cookie_changes[0].cause));
2287 
2288   ASSERT_LE(2u, cookie_changes.size());
2289   EXPECT_EQ("abc", cookie_changes[1].cookie.Name());
2290   EXPECT_EQ("mno2", cookie_changes[1].cookie.Value());
2291   EXPECT_EQ("/foo", cookie_changes[1].cookie.Path());
2292   EXPECT_EQ(this->http_www_foo_.url().host(),
2293             cookie_changes[1].cookie.Domain());
2294   EXPECT_TRUE(
2295       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[1].cause));
2296 
2297   ASSERT_LE(3u, cookie_changes.size());
2298   EXPECT_EQ("abc", cookie_changes[2].cookie.Name());
2299   EXPECT_EQ("pqr1", cookie_changes[2].cookie.Value());
2300   EXPECT_EQ("/", cookie_changes[2].cookie.Path());
2301   EXPECT_EQ(this->http_www_foo_.url().host(),
2302             cookie_changes[2].cookie.Domain());
2303   EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
2304                                  cookie_changes[2].cause));
2305 
2306   ASSERT_LE(4u, cookie_changes.size());
2307   EXPECT_EQ("abc", cookie_changes[3].cookie.Name());
2308   EXPECT_EQ("pqr2", cookie_changes[3].cookie.Value());
2309   EXPECT_EQ("/", cookie_changes[3].cookie.Path());
2310   EXPECT_EQ(this->http_www_foo_.url().host(),
2311             cookie_changes[3].cookie.Domain());
2312   EXPECT_TRUE(
2313       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[3].cause));
2314 
2315   ASSERT_LE(5u, cookie_changes.size());
2316   EXPECT_EQ("abc", cookie_changes[4].cookie.Name());
2317   EXPECT_EQ("stu1", cookie_changes[4].cookie.Value());
2318   EXPECT_EQ("/", cookie_changes[4].cookie.Path());
2319   EXPECT_EQ(".foo.com", cookie_changes[4].cookie.Domain());
2320   EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
2321                                  cookie_changes[4].cause));
2322 
2323   ASSERT_LE(6u, cookie_changes.size());
2324   EXPECT_EQ("abc", cookie_changes[5].cookie.Name());
2325   EXPECT_EQ("stu2", cookie_changes[5].cookie.Value());
2326   EXPECT_EQ("/", cookie_changes[5].cookie.Path());
2327   EXPECT_EQ(".foo.com", cookie_changes[5].cookie.Domain());
2328   EXPECT_TRUE(
2329       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[5].cause));
2330 
2331   EXPECT_EQ(6u, cookie_changes.size());
2332 }
2333 
TYPED_TEST_P(CookieStoreChangeNamedTest,OverwriteWithHttpOnly)2334 TYPED_TEST_P(CookieStoreChangeNamedTest, OverwriteWithHttpOnly) {
2335   if (!TypeParam::supports_named_cookie_tracking)
2336     return;
2337 
2338   // Insert a cookie "abc" for path "/foo".
2339   CookieStore* cs = this->GetCookieStore();
2340   std::vector<CookieChangeInfo> cookie_changes;
2341   std::unique_ptr<CookieChangeSubscription> subscription =
2342       cs->GetChangeDispatcher().AddCallbackForCookie(
2343           this->www_foo_foo_.url(), "abc",
2344           absl::nullopt /* cookie_partition_key */,
2345           base::BindRepeating(
2346               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
2347               base::Unretained(&cookie_changes)));
2348   this->DeliverChangeNotifications();
2349   ASSERT_EQ(0u, cookie_changes.size());
2350 
2351   EXPECT_TRUE(
2352       this->SetCookie(cs, this->http_www_foo_.url(), "abc=def; path=/foo"));
2353   this->DeliverChangeNotifications();
2354   ASSERT_EQ(1u, cookie_changes.size());
2355   EXPECT_TRUE(
2356       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[0].cause));
2357   EXPECT_EQ(this->http_www_foo_.url().host(),
2358             cookie_changes[0].cookie.Domain());
2359   EXPECT_EQ("abc", cookie_changes[0].cookie.Name());
2360   EXPECT_EQ("def", cookie_changes[0].cookie.Value());
2361   EXPECT_FALSE(cookie_changes[0].cookie.IsHttpOnly());
2362   cookie_changes.clear();
2363 
2364   // Insert a cookie "a" for path "/foo", that is httponly. This should
2365   // overwrite the non-http-only version.
2366   CookieOptions allow_httponly;
2367   allow_httponly.set_include_httponly();
2368   allow_httponly.set_same_site_cookie_context(
2369       net::CookieOptions::SameSiteCookieContext::MakeInclusive());
2370 
2371   EXPECT_TRUE(this->CreateAndSetCookie(cs, this->http_www_foo_.url(),
2372                                        "abc=hij; path=/foo; httponly",
2373                                        allow_httponly));
2374   this->DeliverChangeNotifications();
2375 
2376   ASSERT_LE(1u, cookie_changes.size());
2377   EXPECT_EQ(this->http_www_foo_.url().host(),
2378             cookie_changes[0].cookie.Domain());
2379   EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
2380                                  cookie_changes[0].cause));
2381   EXPECT_EQ("abc", cookie_changes[0].cookie.Name());
2382   EXPECT_EQ("def", cookie_changes[0].cookie.Value());
2383   EXPECT_FALSE(cookie_changes[0].cookie.IsHttpOnly());
2384 
2385   ASSERT_LE(2u, cookie_changes.size());
2386   EXPECT_EQ(this->http_www_foo_.url().host(),
2387             cookie_changes[1].cookie.Domain());
2388   EXPECT_TRUE(
2389       this->MatchesCause(CookieChangeCause::INSERTED, cookie_changes[1].cause));
2390   EXPECT_EQ("abc", cookie_changes[1].cookie.Name());
2391   EXPECT_EQ("hij", cookie_changes[1].cookie.Value());
2392   EXPECT_TRUE(cookie_changes[1].cookie.IsHttpOnly());
2393 
2394   EXPECT_EQ(2u, cookie_changes.size());
2395 }
2396 
TYPED_TEST_P(CookieStoreChangeNamedTest,Deregister)2397 TYPED_TEST_P(CookieStoreChangeNamedTest, Deregister) {
2398   if (!TypeParam::supports_named_cookie_tracking)
2399     return;
2400 
2401   CookieStore* cs = this->GetCookieStore();
2402 
2403   std::vector<CookieChangeInfo> cookie_changes;
2404   std::unique_ptr<CookieChangeSubscription> subscription =
2405       cs->GetChangeDispatcher().AddCallbackForCookie(
2406           this->www_foo_foo_.url(), "abc",
2407           absl::nullopt /* cookie_partition_key */,
2408           base::BindRepeating(
2409               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
2410               base::Unretained(&cookie_changes)));
2411   this->DeliverChangeNotifications();
2412   ASSERT_EQ(0u, cookie_changes.size());
2413 
2414   // Insert a cookie and make sure it is seen.
2415   EXPECT_TRUE(
2416       this->SetCookie(cs, this->http_www_foo_.url(), "abc=def; path=/foo"));
2417   this->DeliverChangeNotifications();
2418   ASSERT_EQ(1u, cookie_changes.size());
2419   EXPECT_EQ("abc", cookie_changes[0].cookie.Name());
2420   EXPECT_EQ("def", cookie_changes[0].cookie.Value());
2421   EXPECT_EQ("/foo", cookie_changes[0].cookie.Path());
2422   cookie_changes.clear();
2423 
2424   // De-register the subscription.
2425   subscription.reset();
2426 
2427   // Insert a second cookie and make sure it's not visible.
2428   EXPECT_TRUE(
2429       this->SetCookie(cs, this->http_www_foo_.url(), "abc=hij; path=/"));
2430   this->DeliverChangeNotifications();
2431 
2432   EXPECT_EQ(0u, cookie_changes.size());
2433 }
2434 
TYPED_TEST_P(CookieStoreChangeNamedTest,DeregisterMultiple)2435 TYPED_TEST_P(CookieStoreChangeNamedTest, DeregisterMultiple) {
2436   if (!TypeParam::supports_named_cookie_tracking ||
2437       !TypeParam::supports_multiple_tracking_callbacks)
2438     return;
2439 
2440   CookieStore* cs = this->GetCookieStore();
2441 
2442   // Register two subscriptions.
2443   std::vector<CookieChangeInfo> cookie_changes_1, cookie_changes_2;
2444   std::unique_ptr<CookieChangeSubscription> subscription1 =
2445       cs->GetChangeDispatcher().AddCallbackForCookie(
2446           this->www_foo_foo_.url(), "abc",
2447           absl::nullopt /* cookie_partition_key */,
2448           base::BindRepeating(
2449               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
2450               base::Unretained(&cookie_changes_1)));
2451   std::unique_ptr<CookieChangeSubscription> subscription2 =
2452       cs->GetChangeDispatcher().AddCallbackForCookie(
2453           this->www_foo_foo_.url(), "abc",
2454           absl::nullopt /* cookie_partition_key */,
2455           base::BindRepeating(
2456               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
2457               base::Unretained(&cookie_changes_2)));
2458   this->DeliverChangeNotifications();
2459   ASSERT_EQ(0u, cookie_changes_1.size());
2460   ASSERT_EQ(0u, cookie_changes_2.size());
2461 
2462   // Insert a cookie and make sure it's seen.
2463   EXPECT_TRUE(
2464       this->SetCookie(cs, this->http_www_foo_.url(), "abc=def; path=/foo"));
2465   this->DeliverChangeNotifications();
2466   ASSERT_EQ(1u, cookie_changes_1.size());
2467   EXPECT_EQ("abc", cookie_changes_1[0].cookie.Name());
2468   EXPECT_EQ("def", cookie_changes_1[0].cookie.Value());
2469   EXPECT_EQ("/foo", cookie_changes_1[0].cookie.Path());
2470   cookie_changes_1.clear();
2471 
2472   ASSERT_EQ(1u, cookie_changes_2.size());
2473   EXPECT_EQ("abc", cookie_changes_2[0].cookie.Name());
2474   EXPECT_EQ("def", cookie_changes_2[0].cookie.Value());
2475   EXPECT_EQ("/foo", cookie_changes_2[0].cookie.Path());
2476   cookie_changes_2.clear();
2477 
2478   // De-register the second registration.
2479   subscription2.reset();
2480 
2481   // Insert a second cookie and make sure that it's only visible in one
2482   // change array.
2483   EXPECT_TRUE(
2484       this->SetCookie(cs, this->http_www_foo_.url(), "abc=hij; path=/"));
2485   this->DeliverChangeNotifications();
2486   ASSERT_EQ(1u, cookie_changes_1.size());
2487   EXPECT_EQ("abc", cookie_changes_1[0].cookie.Name());
2488   EXPECT_EQ("hij", cookie_changes_1[0].cookie.Value());
2489   EXPECT_EQ("/", cookie_changes_1[0].cookie.Path());
2490 
2491   EXPECT_EQ(0u, cookie_changes_2.size());
2492 }
2493 
2494 // Confirm that a listener does not receive notifications for changes that
2495 // happened right before the subscription was established.
TYPED_TEST_P(CookieStoreChangeNamedTest,DispatchRace)2496 TYPED_TEST_P(CookieStoreChangeNamedTest, DispatchRace) {
2497   if (!TypeParam::supports_named_cookie_tracking)
2498     return;
2499 
2500   CookieStore* cs = this->GetCookieStore();
2501 
2502   // This cookie insertion should not be seen.
2503   EXPECT_TRUE(
2504       this->SetCookie(cs, this->http_www_foo_.url(), "abc=def; path=/foo"));
2505   // DeliverChangeNotifications() must NOT be called before the subscription is
2506   // established.
2507 
2508   std::vector<CookieChangeInfo> cookie_changes;
2509   std::unique_ptr<CookieChangeSubscription> subscription =
2510       cs->GetChangeDispatcher().AddCallbackForCookie(
2511           this->www_foo_foo_.url(), "abc",
2512           absl::nullopt /* cookie_partition_key */,
2513           base::BindRepeating(
2514               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
2515               base::Unretained(&cookie_changes)));
2516 
2517   EXPECT_TRUE(
2518       this->SetCookie(cs, this->http_www_foo_.url(), "abc=hij; path=/"));
2519   this->DeliverChangeNotifications();
2520 
2521   EXPECT_LE(1u, cookie_changes.size());
2522   EXPECT_EQ("abc", cookie_changes[0].cookie.Name());
2523   EXPECT_EQ("hij", cookie_changes[0].cookie.Value());
2524   EXPECT_EQ("/", cookie_changes[0].cookie.Path());
2525 
2526   ASSERT_EQ(1u, cookie_changes.size());
2527 }
2528 
2529 // Confirm that deregistering a subscription blocks the notification if the
2530 // deregistration happened after the change but before the notification was
2531 // received.
TYPED_TEST_P(CookieStoreChangeNamedTest,DeregisterRace)2532 TYPED_TEST_P(CookieStoreChangeNamedTest, DeregisterRace) {
2533   if (!TypeParam::supports_named_cookie_tracking)
2534     return;
2535 
2536   CookieStore* cs = this->GetCookieStore();
2537 
2538   std::vector<CookieChangeInfo> cookie_changes;
2539   std::unique_ptr<CookieChangeSubscription> subscription =
2540       cs->GetChangeDispatcher().AddCallbackForCookie(
2541           this->www_foo_foo_.url(), "abc",
2542           absl::nullopt /* cookie_partition_key */,
2543           base::BindRepeating(
2544               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
2545               base::Unretained(&cookie_changes)));
2546   this->DeliverChangeNotifications();
2547   ASSERT_EQ(0u, cookie_changes.size());
2548 
2549   // Insert a cookie and make sure it's seen.
2550   EXPECT_TRUE(
2551       this->SetCookie(cs, this->http_www_foo_.url(), "abc=def; path=/foo"));
2552   this->DeliverChangeNotifications();
2553   ASSERT_EQ(1u, cookie_changes.size());
2554   EXPECT_EQ("abc", cookie_changes[0].cookie.Name());
2555   EXPECT_EQ("def", cookie_changes[0].cookie.Value());
2556   EXPECT_EQ("/foo", cookie_changes[0].cookie.Path());
2557   cookie_changes.clear();
2558 
2559   // Insert a cookie, confirm it is not seen, deregister the subscription, run
2560   // until idle, and confirm the cookie is still not seen.
2561   EXPECT_TRUE(
2562       this->SetCookie(cs, this->http_www_foo_.url(), "abc=hij; path=/"));
2563 
2564   // Note that by the API contract it's perfectly valid to have received the
2565   // notification immediately, i.e. synchronously with the cookie change. In
2566   // that case, there's nothing to test.
2567   if (1u == cookie_changes.size())
2568     return;
2569 
2570   // A task was posted by the SetCookie() above, but has not yet arrived. If it
2571   // arrived before the subscription is destroyed, callback execution would be
2572   // valid. Destroy the subscription so as to lose the race and make sure the
2573   // task posted arrives after the subscription was destroyed.
2574   subscription.reset();
2575   this->DeliverChangeNotifications();
2576   ASSERT_EQ(0u, cookie_changes.size());
2577 }
2578 
TYPED_TEST_P(CookieStoreChangeNamedTest,DeregisterRaceMultiple)2579 TYPED_TEST_P(CookieStoreChangeNamedTest, DeregisterRaceMultiple) {
2580   if (!TypeParam::supports_named_cookie_tracking ||
2581       !TypeParam::supports_multiple_tracking_callbacks)
2582     return;
2583 
2584   CookieStore* cs = this->GetCookieStore();
2585 
2586   std::vector<CookieChangeInfo> cookie_changes_1, cookie_changes_2;
2587   std::unique_ptr<CookieChangeSubscription> subscription1 =
2588       cs->GetChangeDispatcher().AddCallbackForCookie(
2589           this->www_foo_foo_.url(), "abc",
2590           absl::nullopt /* cookie_partition_key */,
2591           base::BindRepeating(
2592               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
2593               base::Unretained(&cookie_changes_1)));
2594   std::unique_ptr<CookieChangeSubscription> subscription2 =
2595       cs->GetChangeDispatcher().AddCallbackForCookie(
2596           this->www_foo_foo_.url(), "abc",
2597           absl::nullopt /* cookie_partition_key */,
2598           base::BindRepeating(
2599               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
2600               base::Unretained(&cookie_changes_2)));
2601   this->DeliverChangeNotifications();
2602   ASSERT_EQ(0u, cookie_changes_1.size());
2603   ASSERT_EQ(0u, cookie_changes_2.size());
2604 
2605   // Insert a cookie and make sure it's seen.
2606   EXPECT_TRUE(
2607       this->SetCookie(cs, this->http_www_foo_.url(), "abc=def; path=/foo"));
2608   this->DeliverChangeNotifications();
2609 
2610   ASSERT_EQ(1u, cookie_changes_1.size());
2611   EXPECT_EQ("abc", cookie_changes_1[0].cookie.Name());
2612   EXPECT_EQ("def", cookie_changes_1[0].cookie.Value());
2613   EXPECT_EQ("/foo", cookie_changes_1[0].cookie.Path());
2614   cookie_changes_1.clear();
2615 
2616   ASSERT_EQ(1u, cookie_changes_2.size());
2617   EXPECT_EQ("abc", cookie_changes_2[0].cookie.Name());
2618   EXPECT_EQ("def", cookie_changes_2[0].cookie.Value());
2619   EXPECT_EQ("/foo", cookie_changes_2[0].cookie.Path());
2620   cookie_changes_2.clear();
2621 
2622   // Insert a cookie, confirm it is not seen, deregister a subscription, run
2623   // until idle, and confirm the cookie is still not seen.
2624   EXPECT_TRUE(
2625       this->SetCookie(cs, this->http_www_foo_.url(), "abc=hij; path=/"));
2626 
2627   // Note that by the API contract it's perfectly valid to have received the
2628   // notification immediately, i.e. synchronously with the cookie change. In
2629   // that case, there's nothing to test.
2630   if (1u == cookie_changes_2.size())
2631     return;
2632 
2633   // A task was posted by the SetCookie() above, but has not yet arrived. If it
2634   // arrived before the subscription is destroyed, callback execution would be
2635   // valid. Destroy one of the subscriptions so as to lose the race and make
2636   // sure the task posted arrives after the subscription was destroyed.
2637   subscription2.reset();
2638   this->DeliverChangeNotifications();
2639   ASSERT_EQ(1u, cookie_changes_1.size());
2640   EXPECT_EQ("abc", cookie_changes_1[0].cookie.Name());
2641   EXPECT_EQ("hij", cookie_changes_1[0].cookie.Value());
2642   EXPECT_EQ("/", cookie_changes_1[0].cookie.Path());
2643 
2644   // No late notification was received.
2645   ASSERT_EQ(0u, cookie_changes_2.size());
2646 }
2647 
TYPED_TEST_P(CookieStoreChangeNamedTest,DifferentSubscriptionsDisjoint)2648 TYPED_TEST_P(CookieStoreChangeNamedTest, DifferentSubscriptionsDisjoint) {
2649   if (!TypeParam::supports_named_cookie_tracking)
2650     return;
2651 
2652   CookieStore* cs = this->GetCookieStore();
2653 
2654   std::vector<CookieChangeInfo> cookie_changes_1, cookie_changes_2;
2655   std::unique_ptr<CookieChangeSubscription> subscription1 =
2656       cs->GetChangeDispatcher().AddCallbackForCookie(
2657           this->http_www_foo_.url(), "abc",
2658           absl::nullopt /* cookie_partition_key */,
2659           base::BindRepeating(
2660               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
2661               base::Unretained(&cookie_changes_1)));
2662   std::unique_ptr<CookieChangeSubscription> subscription2 =
2663       cs->GetChangeDispatcher().AddCallbackForCookie(
2664           this->http_bar_com_.url(), "ghi",
2665           absl::nullopt /* cookie_partition_key */,
2666           base::BindRepeating(
2667               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
2668               base::Unretained(&cookie_changes_2)));
2669   this->DeliverChangeNotifications();
2670   ASSERT_EQ(0u, cookie_changes_1.size());
2671   ASSERT_EQ(0u, cookie_changes_2.size());
2672 
2673   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
2674   this->DeliverChangeNotifications();
2675   EXPECT_EQ(1u, cookie_changes_1.size());
2676   EXPECT_EQ(0u, cookie_changes_2.size());
2677 
2678   EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "ghi=jkl"));
2679   this->DeliverChangeNotifications();
2680 
2681   ASSERT_EQ(1u, cookie_changes_1.size());
2682   EXPECT_EQ("abc", cookie_changes_1[0].cookie.Name());
2683   EXPECT_EQ("def", cookie_changes_1[0].cookie.Value());
2684   EXPECT_EQ(this->http_www_foo_.url().host(),
2685             cookie_changes_1[0].cookie.Domain());
2686 
2687   ASSERT_EQ(1u, cookie_changes_2.size());
2688   EXPECT_EQ("ghi", cookie_changes_2[0].cookie.Name());
2689   EXPECT_EQ("jkl", cookie_changes_2[0].cookie.Value());
2690   EXPECT_EQ(this->http_bar_com_.url().host(),
2691             cookie_changes_2[0].cookie.Domain());
2692 }
2693 
TYPED_TEST_P(CookieStoreChangeNamedTest,DifferentSubscriptionsDomains)2694 TYPED_TEST_P(CookieStoreChangeNamedTest, DifferentSubscriptionsDomains) {
2695   if (!TypeParam::supports_named_cookie_tracking)
2696     return;
2697 
2698   CookieStore* cs = this->GetCookieStore();
2699 
2700   std::vector<CookieChangeInfo> cookie_changes_1, cookie_changes_2;
2701   std::unique_ptr<CookieChangeSubscription> subscription1 =
2702       cs->GetChangeDispatcher().AddCallbackForCookie(
2703           this->http_www_foo_.url(), "abc",
2704           absl::nullopt /* cookie_partition_key */,
2705           base::BindRepeating(
2706               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
2707               base::Unretained(&cookie_changes_1)));
2708   std::unique_ptr<CookieChangeSubscription> subscription2 =
2709       cs->GetChangeDispatcher().AddCallbackForCookie(
2710           this->http_bar_com_.url(), "abc",
2711           absl::nullopt /* cookie_partition_key */,
2712           base::BindRepeating(
2713               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
2714               base::Unretained(&cookie_changes_2)));
2715   this->DeliverChangeNotifications();
2716   ASSERT_EQ(0u, cookie_changes_1.size());
2717   ASSERT_EQ(0u, cookie_changes_2.size());
2718 
2719   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
2720   this->DeliverChangeNotifications();
2721   EXPECT_EQ(1u, cookie_changes_1.size());
2722   EXPECT_EQ(0u, cookie_changes_2.size());
2723 
2724   EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "abc=ghi"));
2725   this->DeliverChangeNotifications();
2726 
2727   ASSERT_EQ(1u, cookie_changes_1.size());
2728   EXPECT_EQ("abc", cookie_changes_1[0].cookie.Name());
2729   EXPECT_EQ("def", cookie_changes_1[0].cookie.Value());
2730   EXPECT_EQ(this->http_www_foo_.url().host(),
2731             cookie_changes_1[0].cookie.Domain());
2732 
2733   ASSERT_EQ(1u, cookie_changes_2.size());
2734   EXPECT_EQ("abc", cookie_changes_2[0].cookie.Name());
2735   EXPECT_EQ("ghi", cookie_changes_2[0].cookie.Value());
2736   EXPECT_EQ(this->http_bar_com_.url().host(),
2737             cookie_changes_2[0].cookie.Domain());
2738 }
2739 
TYPED_TEST_P(CookieStoreChangeNamedTest,DifferentSubscriptionsNames)2740 TYPED_TEST_P(CookieStoreChangeNamedTest, DifferentSubscriptionsNames) {
2741   if (!TypeParam::supports_named_cookie_tracking)
2742     return;
2743 
2744   CookieStore* cs = this->GetCookieStore();
2745 
2746   std::vector<CookieChangeInfo> cookie_changes_1, cookie_changes_2;
2747   std::unique_ptr<CookieChangeSubscription> subscription1 =
2748       cs->GetChangeDispatcher().AddCallbackForCookie(
2749           this->http_www_foo_.url(), "abc",
2750           absl::nullopt /* cookie_partition_key */,
2751           base::BindRepeating(
2752               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
2753               base::Unretained(&cookie_changes_1)));
2754   std::unique_ptr<CookieChangeSubscription> subscription2 =
2755       cs->GetChangeDispatcher().AddCallbackForCookie(
2756           this->http_www_foo_.url(), "ghi",
2757           absl::nullopt /* cookie_partition_key */,
2758           base::BindRepeating(
2759               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
2760               base::Unretained(&cookie_changes_2)));
2761   this->DeliverChangeNotifications();
2762   ASSERT_EQ(0u, cookie_changes_1.size());
2763   ASSERT_EQ(0u, cookie_changes_2.size());
2764 
2765   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
2766   this->DeliverChangeNotifications();
2767   EXPECT_EQ(1u, cookie_changes_1.size());
2768   EXPECT_EQ(0u, cookie_changes_2.size());
2769 
2770   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "ghi=jkl"));
2771   this->DeliverChangeNotifications();
2772 
2773   ASSERT_EQ(1u, cookie_changes_1.size());
2774   EXPECT_EQ("abc", cookie_changes_1[0].cookie.Name());
2775   EXPECT_EQ("def", cookie_changes_1[0].cookie.Value());
2776   EXPECT_EQ(this->http_www_foo_.url().host(),
2777             cookie_changes_1[0].cookie.Domain());
2778 
2779   ASSERT_EQ(1u, cookie_changes_2.size());
2780   EXPECT_EQ("ghi", cookie_changes_2[0].cookie.Name());
2781   EXPECT_EQ("jkl", cookie_changes_2[0].cookie.Value());
2782   EXPECT_EQ(this->http_www_foo_.url().host(),
2783             cookie_changes_2[0].cookie.Domain());
2784 }
2785 
TYPED_TEST_P(CookieStoreChangeNamedTest,DifferentSubscriptionsPaths)2786 TYPED_TEST_P(CookieStoreChangeNamedTest, DifferentSubscriptionsPaths) {
2787   if (!TypeParam::supports_named_cookie_tracking)
2788     return;
2789 
2790   CookieStore* cs = this->GetCookieStore();
2791 
2792   std::vector<CookieChangeInfo> cookie_changes_1, cookie_changes_2;
2793   std::unique_ptr<CookieChangeSubscription> subscription1 =
2794       cs->GetChangeDispatcher().AddCallbackForCookie(
2795           this->http_www_foo_.url(), "abc",
2796           absl::nullopt /* cookie_partition_key */,
2797           base::BindRepeating(
2798               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
2799               base::Unretained(&cookie_changes_1)));
2800   std::unique_ptr<CookieChangeSubscription> subscription2 =
2801       cs->GetChangeDispatcher().AddCallbackForCookie(
2802           this->www_foo_foo_.url(), "abc",
2803           absl::nullopt /* cookie_partition_key */,
2804           base::BindRepeating(
2805               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
2806               base::Unretained(&cookie_changes_2)));
2807   this->DeliverChangeNotifications();
2808   ASSERT_EQ(0u, cookie_changes_1.size());
2809   ASSERT_EQ(0u, cookie_changes_2.size());
2810 
2811   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
2812   this->DeliverChangeNotifications();
2813   EXPECT_EQ(1u, cookie_changes_1.size());
2814   EXPECT_EQ(1u, cookie_changes_2.size());
2815 
2816   EXPECT_TRUE(
2817       this->SetCookie(cs, this->http_www_foo_.url(), "abc=ghi; path=/foo"));
2818   this->DeliverChangeNotifications();
2819 
2820   ASSERT_EQ(1u, cookie_changes_1.size());
2821   EXPECT_EQ("abc", cookie_changes_1[0].cookie.Name());
2822   EXPECT_EQ("def", cookie_changes_1[0].cookie.Value());
2823   EXPECT_EQ("/", cookie_changes_1[0].cookie.Path());
2824   EXPECT_EQ(this->http_www_foo_.url().host(),
2825             cookie_changes_1[0].cookie.Domain());
2826 
2827   ASSERT_LE(1u, cookie_changes_2.size());
2828   EXPECT_EQ("abc", cookie_changes_2[0].cookie.Name());
2829   EXPECT_EQ("def", cookie_changes_2[0].cookie.Value());
2830   EXPECT_EQ("/", cookie_changes_2[0].cookie.Path());
2831   EXPECT_EQ(this->http_www_foo_.url().host(),
2832             cookie_changes_2[0].cookie.Domain());
2833 
2834   ASSERT_LE(2u, cookie_changes_2.size());
2835   EXPECT_EQ("abc", cookie_changes_2[1].cookie.Name());
2836   EXPECT_EQ("ghi", cookie_changes_2[1].cookie.Value());
2837   EXPECT_EQ("/foo", cookie_changes_2[1].cookie.Path());
2838   EXPECT_EQ(this->http_www_foo_.url().host(),
2839             cookie_changes_2[1].cookie.Domain());
2840 
2841   EXPECT_EQ(2u, cookie_changes_2.size());
2842 }
2843 
TYPED_TEST_P(CookieStoreChangeNamedTest,DifferentSubscriptionsFiltering)2844 TYPED_TEST_P(CookieStoreChangeNamedTest, DifferentSubscriptionsFiltering) {
2845   if (!TypeParam::supports_named_cookie_tracking)
2846     return;
2847 
2848   CookieStore* cs = this->GetCookieStore();
2849 
2850   std::vector<CookieChangeInfo> cookie_changes_1, cookie_changes_2;
2851   std::vector<CookieChangeInfo> cookie_changes_3, cookie_changes_4;
2852   std::unique_ptr<CookieChangeSubscription> subscription1 =
2853       cs->GetChangeDispatcher().AddCallbackForCookie(
2854           this->http_www_foo_.url(), "abc",
2855           absl::nullopt /* cookie_partition_key */,
2856           base::BindRepeating(
2857               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
2858               base::Unretained(&cookie_changes_1)));
2859   std::unique_ptr<CookieChangeSubscription> subscription2 =
2860       cs->GetChangeDispatcher().AddCallbackForCookie(
2861           this->http_www_foo_.url(), "hij",
2862           absl::nullopt /* cookie_partition_key */,
2863           base::BindRepeating(
2864               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
2865               base::Unretained(&cookie_changes_2)));
2866   std::unique_ptr<CookieChangeSubscription> subscription3 =
2867       cs->GetChangeDispatcher().AddCallbackForCookie(
2868           this->http_bar_com_.url(), "abc",
2869           absl::nullopt /* cookie_partition_key */,
2870           base::BindRepeating(
2871               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
2872               base::Unretained(&cookie_changes_3)));
2873   std::unique_ptr<CookieChangeSubscription> subscription4 =
2874       cs->GetChangeDispatcher().AddCallbackForCookie(
2875           this->www_foo_foo_.url(), "abc",
2876           absl::nullopt /* cookie_partition_key */,
2877           base::BindRepeating(
2878               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
2879               base::Unretained(&cookie_changes_4)));
2880   this->DeliverChangeNotifications();
2881   ASSERT_EQ(0u, cookie_changes_1.size());
2882   ASSERT_EQ(0u, cookie_changes_2.size());
2883   EXPECT_EQ(0u, cookie_changes_3.size());
2884   EXPECT_EQ(0u, cookie_changes_4.size());
2885 
2886   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
2887   this->DeliverChangeNotifications();
2888   EXPECT_EQ(1u, cookie_changes_1.size());
2889   EXPECT_EQ(0u, cookie_changes_2.size());
2890   EXPECT_EQ(0u, cookie_changes_3.size());
2891   EXPECT_EQ(1u, cookie_changes_4.size());
2892 
2893   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "xyz=zyx"));
2894   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "hij=mno"));
2895   this->DeliverChangeNotifications();
2896   EXPECT_EQ(1u, cookie_changes_1.size());
2897   EXPECT_EQ(1u, cookie_changes_2.size());
2898   EXPECT_EQ(0u, cookie_changes_3.size());
2899   EXPECT_EQ(1u, cookie_changes_4.size());
2900 
2901   EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "hij=pqr"));
2902   EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "xyz=zyx"));
2903   EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "abc=stu"));
2904   this->DeliverChangeNotifications();
2905   EXPECT_EQ(1u, cookie_changes_1.size());
2906   EXPECT_EQ(1u, cookie_changes_2.size());
2907   EXPECT_EQ(1u, cookie_changes_3.size());
2908   EXPECT_EQ(1u, cookie_changes_4.size());
2909 
2910   EXPECT_TRUE(
2911       this->SetCookie(cs, this->http_www_foo_.url(), "abc=vwx; path=/foo"));
2912   this->DeliverChangeNotifications();
2913 
2914   ASSERT_LE(1u, cookie_changes_1.size());
2915   EXPECT_EQ("abc", cookie_changes_1[0].cookie.Name());
2916   EXPECT_EQ("def", cookie_changes_1[0].cookie.Value());
2917   EXPECT_EQ(this->http_www_foo_.url().host(),
2918             cookie_changes_1[0].cookie.Domain());
2919   EXPECT_EQ(1u, cookie_changes_1.size());
2920 
2921   ASSERT_LE(1u, cookie_changes_2.size());
2922   EXPECT_EQ("hij", cookie_changes_2[0].cookie.Name());
2923   EXPECT_EQ("mno", cookie_changes_2[0].cookie.Value());
2924   EXPECT_EQ(this->http_www_foo_.url().host(),
2925             cookie_changes_2[0].cookie.Domain());
2926   EXPECT_EQ(1u, cookie_changes_2.size());
2927 
2928   ASSERT_LE(1u, cookie_changes_3.size());
2929   EXPECT_EQ("abc", cookie_changes_3[0].cookie.Name());
2930   EXPECT_EQ("stu", cookie_changes_3[0].cookie.Value());
2931   EXPECT_EQ(this->http_bar_com_.url().host(),
2932             cookie_changes_3[0].cookie.Domain());
2933   EXPECT_EQ(1u, cookie_changes_3.size());
2934 
2935   ASSERT_LE(1u, cookie_changes_4.size());
2936   EXPECT_EQ("abc", cookie_changes_4[0].cookie.Name());
2937   EXPECT_EQ("def", cookie_changes_4[0].cookie.Value());
2938   EXPECT_EQ("/", cookie_changes_4[0].cookie.Path());
2939   EXPECT_EQ(this->http_www_foo_.url().host(),
2940             cookie_changes_4[0].cookie.Domain());
2941 
2942   ASSERT_LE(2u, cookie_changes_4.size());
2943   EXPECT_EQ("abc", cookie_changes_4[1].cookie.Name());
2944   EXPECT_EQ("vwx", cookie_changes_4[1].cookie.Value());
2945   EXPECT_EQ("/foo", cookie_changes_4[1].cookie.Path());
2946   EXPECT_EQ(this->http_www_foo_.url().host(),
2947             cookie_changes_4[1].cookie.Domain());
2948 
2949   EXPECT_EQ(2u, cookie_changes_4.size());
2950 }
2951 
TYPED_TEST_P(CookieStoreChangeNamedTest,MultipleSubscriptions)2952 TYPED_TEST_P(CookieStoreChangeNamedTest, MultipleSubscriptions) {
2953   if (!TypeParam::supports_named_cookie_tracking ||
2954       !TypeParam::supports_multiple_tracking_callbacks)
2955     return;
2956 
2957   CookieStore* cs = this->GetCookieStore();
2958 
2959   std::vector<CookieChangeInfo> cookie_changes_1, cookie_changes_2;
2960   std::unique_ptr<CookieChangeSubscription> subscription1 =
2961       cs->GetChangeDispatcher().AddCallbackForCookie(
2962           this->http_www_foo_.url(), "abc",
2963           absl::nullopt /* cookie_partition_key */,
2964           base::BindRepeating(
2965               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
2966               base::Unretained(&cookie_changes_1)));
2967   std::unique_ptr<CookieChangeSubscription> subscription2 =
2968       cs->GetChangeDispatcher().AddCallbackForCookie(
2969           this->http_www_foo_.url(), "abc",
2970           absl::nullopt /* cookie_partition_key */,
2971           base::BindRepeating(
2972               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
2973               base::Unretained(&cookie_changes_2)));
2974   this->DeliverChangeNotifications();
2975 
2976   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "xyz=zyx"));
2977   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
2978   this->DeliverChangeNotifications();
2979 
2980   ASSERT_EQ(1U, cookie_changes_1.size());
2981   EXPECT_EQ("abc", cookie_changes_1[0].cookie.Name());
2982   EXPECT_EQ("def", cookie_changes_1[0].cookie.Value());
2983   cookie_changes_1.clear();
2984 
2985   ASSERT_EQ(1U, cookie_changes_2.size());
2986   EXPECT_EQ("abc", cookie_changes_2[0].cookie.Name());
2987   EXPECT_EQ("def", cookie_changes_2[0].cookie.Value());
2988   cookie_changes_2.clear();
2989 }
2990 
TYPED_TEST_P(CookieStoreChangeNamedTest,SubscriptionOutlivesStore)2991 TYPED_TEST_P(CookieStoreChangeNamedTest, SubscriptionOutlivesStore) {
2992   if (!TypeParam::supports_named_cookie_tracking)
2993     return;
2994 
2995   std::vector<CookieChangeInfo> cookie_changes;
2996   std::unique_ptr<CookieChangeSubscription> subscription =
2997       this->GetCookieStore()->GetChangeDispatcher().AddCallbackForCookie(
2998           this->http_www_foo_.url(), "abc",
2999           absl::nullopt /* cookie_partition_key */,
3000           base::BindRepeating(
3001               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
3002               base::Unretained(&cookie_changes)));
3003   this->ResetCookieStore();
3004 
3005   // |subscription| outlives cookie_store - crash should not happen.
3006   subscription.reset();
3007 }
3008 
TYPED_TEST_P(CookieStoreChangeNamedTest,ChangeIncludesCookieAccessSemantics)3009 TYPED_TEST_P(CookieStoreChangeNamedTest, ChangeIncludesCookieAccessSemantics) {
3010   if (!TypeParam::supports_named_cookie_tracking)
3011     return;
3012 
3013   CookieStore* cs = this->GetCookieStore();
3014   // if !supports_cookie_access_semantics, the delegate will be stored but will
3015   // not be used.
3016   auto access_delegate = std::make_unique<TestCookieAccessDelegate>();
3017   access_delegate->SetExpectationForCookieDomain("domain1.test",
3018                                                  CookieAccessSemantics::LEGACY);
3019   cs->SetCookieAccessDelegate(std::move(access_delegate));
3020 
3021   std::vector<CookieChangeInfo> cookie_changes;
3022   std::unique_ptr<CookieChangeSubscription> subscription =
3023       cs->GetChangeDispatcher().AddCallbackForCookie(
3024           GURL("http://domain1.test"), "cookie",
3025           absl::nullopt /* cookie_partition_key */,
3026           base::BindRepeating(
3027               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
3028               base::Unretained(&cookie_changes)));
3029 
3030   this->CreateAndSetCookie(cs, GURL("http://domain1.test"), "cookie=1",
3031                            CookieOptions::MakeAllInclusive());
3032   this->DeliverChangeNotifications();
3033 
3034   ASSERT_EQ(1u, cookie_changes.size());
3035   EXPECT_EQ("domain1.test", cookie_changes[0].cookie.Domain());
3036   EXPECT_EQ("cookie", cookie_changes[0].cookie.Name());
3037   EXPECT_TRUE(this->IsExpectedAccessSemantics(
3038       CookieAccessSemantics::LEGACY,
3039       cookie_changes[0].access_result.access_semantics));
3040 }
3041 
TYPED_TEST_P(CookieStoreChangeNamedTest,PartitionedCookies)3042 TYPED_TEST_P(CookieStoreChangeNamedTest, PartitionedCookies) {
3043   if (!TypeParam::supports_named_cookie_tracking ||
3044       !TypeParam::supports_partitioned_cookies)
3045     return;
3046 
3047   CookieStore* cs = this->GetCookieStore();
3048   std::vector<CookieChangeInfo> cookie_changes;
3049   std::unique_ptr<CookieChangeSubscription> subscription =
3050       cs->GetChangeDispatcher().AddCallbackForCookie(
3051           GURL("https://www.example.com"), "__Host-a",
3052           CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com")),
3053           base::BindRepeating(
3054               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
3055               base::Unretained(&cookie_changes)));
3056 
3057   // Unpartitioned cookie
3058   this->CreateAndSetCookie(cs, GURL("https://www.example.com"),
3059                            "__Host-a=1; Secure; Path=/",
3060                            CookieOptions::MakeAllInclusive());
3061   // Partitioned cookie with the same partition key
3062   this->CreateAndSetCookie(
3063       cs, GURL("https://www.example.com"),
3064       "__Host-a=2; Secure; Path=/; Partitioned",
3065       CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */,
3066       absl::nullopt /* system_time */,
3067       CookiePartitionKey::FromURLForTesting(GURL("https://sub.foo.com")));
3068   // Partitioned cookie with a different partition key
3069   this->CreateAndSetCookie(
3070       cs, GURL("https://www.example.com"),
3071       "__Host-a=3; Secure; Path=/; Partitioned",
3072       CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */,
3073       absl::nullopt /* system_time */,
3074       CookiePartitionKey::FromURLForTesting(GURL("https://www.bar.com")));
3075   this->DeliverChangeNotifications();
3076 
3077   ASSERT_EQ(2u, cookie_changes.size());
3078   EXPECT_FALSE(cookie_changes[0].cookie.IsPartitioned());
3079   EXPECT_EQ("1", cookie_changes[0].cookie.Value());
3080   EXPECT_TRUE(cookie_changes[1].cookie.IsPartitioned());
3081   EXPECT_EQ(CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com")),
3082             cookie_changes[1].cookie.PartitionKey().value());
3083   EXPECT_EQ("2", cookie_changes[1].cookie.Value());
3084 
3085   // Test that when the partition key parameter is nullopt that all Partitioned
3086   // cookies do not emit events.
3087   std::vector<CookieChangeInfo> other_cookie_changes;
3088   std::unique_ptr<CookieChangeSubscription> other_subscription =
3089       cs->GetChangeDispatcher().AddCallbackForCookie(
3090           GURL("https://www.example.com"), "__Host-a",
3091           absl::nullopt /* cookie_partition_key */,
3092           base::BindRepeating(
3093               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
3094               base::Unretained(&other_cookie_changes)));
3095   // Update Max-Age: None -> 7200
3096   this->CreateAndSetCookie(
3097       cs, GURL("https://www.example.com"),
3098       "__Host-a=2; Secure; Path=/; Partitioned; Max-Age=7200",
3099       CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */,
3100       absl::nullopt /* system_time */,
3101       CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com")));
3102   this->DeliverChangeNotifications();
3103   ASSERT_EQ(0u, other_cookie_changes.size());
3104   // Check that the other listener was invoked.
3105   ASSERT_LT(2u, cookie_changes.size());
3106 }
3107 
TYPED_TEST_P(CookieStoreChangeNamedTest,PartitionedCookies_WithNonce)3108 TYPED_TEST_P(CookieStoreChangeNamedTest, PartitionedCookies_WithNonce) {
3109   if (!TypeParam::supports_named_cookie_tracking ||
3110       !TypeParam::supports_partitioned_cookies) {
3111     return;
3112   }
3113 
3114   CookieStore* cs = this->GetCookieStore();
3115   base::UnguessableToken nonce = base::UnguessableToken::Create();
3116 
3117   std::vector<CookieChangeInfo> cookie_changes;
3118   std::unique_ptr<CookieChangeSubscription> subscription =
3119       cs->GetChangeDispatcher().AddCallbackForCookie(
3120           GURL("https://www.example.com"), "__Host-a",
3121           CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com"),
3122                                                 nonce),
3123           base::BindRepeating(
3124               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
3125               base::Unretained(&cookie_changes)));
3126 
3127   // Should not see changes to an unpartitioned cookie.
3128   this->CreateAndSetCookie(cs, GURL("https://www.example.com"),
3129                            "__Host-a=1; Secure; Path=/",
3130                            CookieOptions::MakeAllInclusive());
3131   this->DeliverChangeNotifications();
3132   ASSERT_EQ(0u, cookie_changes.size());
3133 
3134   // Set partitioned cookie without nonce. Should not see the change.
3135   this->CreateAndSetCookie(
3136       cs, GURL("https://www.example.com"),
3137       "__Host-a=2; Secure; Path=/; Partitioned",
3138       CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */,
3139       absl::nullopt /* system_time */,
3140       CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com")));
3141   this->DeliverChangeNotifications();
3142   ASSERT_EQ(0u, cookie_changes.size());
3143 
3144   // Set partitioned cookie with nonce.
3145   this->CreateAndSetCookie(cs, GURL("https://www.example.com"),
3146                            "__Host-a=3; Secure; Path=/; Partitioned",
3147                            CookieOptions::MakeAllInclusive(),
3148                            absl::nullopt /* server_time */,
3149                            absl::nullopt /* system_time */,
3150                            CookiePartitionKey::FromURLForTesting(
3151                                GURL("https://www.foo.com"), nonce));
3152   this->DeliverChangeNotifications();
3153   ASSERT_EQ(1u, cookie_changes.size());
3154 }
3155 
3156 REGISTER_TYPED_TEST_SUITE_P(CookieStoreChangeGlobalTest,
3157                             NoCookie,
3158                             InitialCookie,
3159                             InsertOne,
3160                             InsertMany,
3161                             DeleteOne,
3162                             DeleteTwo,
3163                             Overwrite,
3164                             OverwriteWithHttpOnly,
3165                             Deregister,
3166                             DeregisterMultiple,
3167                             DispatchRace,
3168                             DeregisterRace,
3169                             DeregisterRaceMultiple,
3170                             MultipleSubscriptions,
3171                             ChangeIncludesCookieAccessSemantics,
3172                             PartitionedCookies);
3173 
3174 REGISTER_TYPED_TEST_SUITE_P(CookieStoreChangeUrlTest,
3175                             NoCookie,
3176                             InitialCookie,
3177                             InsertOne,
3178                             InsertMany,
3179                             InsertFiltering,
3180                             DeleteOne,
3181                             DeleteTwo,
3182                             DeleteFiltering,
3183                             Overwrite,
3184                             OverwriteFiltering,
3185                             OverwriteWithHttpOnly,
3186                             Deregister,
3187                             DeregisterMultiple,
3188                             DispatchRace,
3189                             DeregisterRace,
3190                             DeregisterRaceMultiple,
3191                             DifferentSubscriptionsDisjoint,
3192                             DifferentSubscriptionsDomains,
3193                             DifferentSubscriptionsPaths,
3194                             DifferentSubscriptionsFiltering,
3195                             MultipleSubscriptions,
3196                             ChangeIncludesCookieAccessSemantics,
3197                             PartitionedCookies,
3198                             PartitionedCookies_WithNonce);
3199 
3200 REGISTER_TYPED_TEST_SUITE_P(CookieStoreChangeNamedTest,
3201                             NoCookie,
3202                             InitialCookie,
3203                             InsertOne,
3204                             InsertTwo,
3205                             InsertFiltering,
3206                             DeleteOne,
3207                             DeleteTwo,
3208                             DeleteFiltering,
3209                             Overwrite,
3210                             OverwriteFiltering,
3211                             OverwriteWithHttpOnly,
3212                             Deregister,
3213                             DeregisterMultiple,
3214                             DispatchRace,
3215                             DeregisterRace,
3216                             DeregisterRaceMultiple,
3217                             DifferentSubscriptionsDisjoint,
3218                             DifferentSubscriptionsDomains,
3219                             DifferentSubscriptionsNames,
3220                             DifferentSubscriptionsPaths,
3221                             DifferentSubscriptionsFiltering,
3222                             MultipleSubscriptions,
3223                             SubscriptionOutlivesStore,
3224                             ChangeIncludesCookieAccessSemantics,
3225                             PartitionedCookies,
3226                             PartitionedCookies_WithNonce);
3227 
3228 }  // namespace net
3229 
3230 #endif  // NET_COOKIES_COOKIE_STORE_CHANGE_UNITTEST_H_
3231