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