xref: /aosp_15_r20/external/cronet/net/cookies/cookie_monster_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "net/cookies/cookie_monster.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include <algorithm>
10*6777b538SAndroid Build Coastguard Worker #include <memory>
11*6777b538SAndroid Build Coastguard Worker #include <optional>
12*6777b538SAndroid Build Coastguard Worker #include <string>
13*6777b538SAndroid Build Coastguard Worker #include <string_view>
14*6777b538SAndroid Build Coastguard Worker #include <utility>
15*6777b538SAndroid Build Coastguard Worker #include <vector>
16*6777b538SAndroid Build Coastguard Worker 
17*6777b538SAndroid Build Coastguard Worker #include "base/containers/queue.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback_helpers.h"
21*6777b538SAndroid Build Coastguard Worker #include "base/location.h"
22*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
23*6777b538SAndroid Build Coastguard Worker #include "base/memory/ref_counted.h"
24*6777b538SAndroid Build Coastguard Worker #include "base/metrics/histogram.h"
25*6777b538SAndroid Build Coastguard Worker #include "base/metrics/histogram_samples.h"
26*6777b538SAndroid Build Coastguard Worker #include "base/ranges/algorithm.h"
27*6777b538SAndroid Build Coastguard Worker #include "base/run_loop.h"
28*6777b538SAndroid Build Coastguard Worker #include "base/strings/strcat.h"
29*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_number_conversions.h"
30*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_split.h"
31*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_tokenizer.h"
32*6777b538SAndroid Build Coastguard Worker #include "base/strings/stringprintf.h"
33*6777b538SAndroid Build Coastguard Worker #include "base/task/single_thread_task_runner.h"
34*6777b538SAndroid Build Coastguard Worker #include "base/test/bind.h"
35*6777b538SAndroid Build Coastguard Worker #include "base/test/metrics/histogram_tester.h"
36*6777b538SAndroid Build Coastguard Worker #include "base/test/mock_callback.h"
37*6777b538SAndroid Build Coastguard Worker #include "base/test/scoped_feature_list.h"
38*6777b538SAndroid Build Coastguard Worker #include "base/test/test_future.h"
39*6777b538SAndroid Build Coastguard Worker #include "base/threading/thread.h"
40*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
41*6777b538SAndroid Build Coastguard Worker #include "cookie_partition_key.h"
42*6777b538SAndroid Build Coastguard Worker #include "net/base/features.h"
43*6777b538SAndroid Build Coastguard Worker #include "net/cookies/canonical_cookie.h"
44*6777b538SAndroid Build Coastguard Worker #include "net/cookies/canonical_cookie_test_helpers.h"
45*6777b538SAndroid Build Coastguard Worker #include "net/cookies/cookie_change_dispatcher.h"
46*6777b538SAndroid Build Coastguard Worker #include "net/cookies/cookie_constants.h"
47*6777b538SAndroid Build Coastguard Worker #include "net/cookies/cookie_inclusion_status.h"
48*6777b538SAndroid Build Coastguard Worker #include "net/cookies/cookie_monster_store_test.h"  // For CookieStore mock
49*6777b538SAndroid Build Coastguard Worker #include "net/cookies/cookie_partition_key.h"
50*6777b538SAndroid Build Coastguard Worker #include "net/cookies/cookie_store.h"
51*6777b538SAndroid Build Coastguard Worker #include "net/cookies/cookie_store_change_unittest.h"
52*6777b538SAndroid Build Coastguard Worker #include "net/cookies/cookie_store_test_callbacks.h"
53*6777b538SAndroid Build Coastguard Worker #include "net/cookies/cookie_store_test_helpers.h"
54*6777b538SAndroid Build Coastguard Worker #include "net/cookies/cookie_store_unittest.h"
55*6777b538SAndroid Build Coastguard Worker #include "net/cookies/cookie_util.h"
56*6777b538SAndroid Build Coastguard Worker #include "net/cookies/parsed_cookie.h"
57*6777b538SAndroid Build Coastguard Worker #include "net/cookies/test_cookie_access_delegate.h"
58*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_with_source.h"
59*6777b538SAndroid Build Coastguard Worker #include "net/log/test_net_log.h"
60*6777b538SAndroid Build Coastguard Worker #include "net/log/test_net_log_util.h"
61*6777b538SAndroid Build Coastguard Worker #include "testing/gmock/include/gmock/gmock-matchers.h"
62*6777b538SAndroid Build Coastguard Worker #include "testing/gmock/include/gmock/gmock.h"
63*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
64*6777b538SAndroid Build Coastguard Worker #include "url/gurl.h"
65*6777b538SAndroid Build Coastguard Worker #include "url/third_party/mozilla/url_parse.h"
66*6777b538SAndroid Build Coastguard Worker #include "url/url_constants.h"
67*6777b538SAndroid Build Coastguard Worker 
68*6777b538SAndroid Build Coastguard Worker namespace net {
69*6777b538SAndroid Build Coastguard Worker 
70*6777b538SAndroid Build Coastguard Worker using base::Time;
71*6777b538SAndroid Build Coastguard Worker using CookieDeletionInfo = net::CookieDeletionInfo;
72*6777b538SAndroid Build Coastguard Worker 
73*6777b538SAndroid Build Coastguard Worker namespace {
74*6777b538SAndroid Build Coastguard Worker 
75*6777b538SAndroid Build Coastguard Worker using testing::ElementsAre;
76*6777b538SAndroid Build Coastguard Worker 
77*6777b538SAndroid Build Coastguard Worker // False means 'less than or equal', so we test both ways for full equal.
78*6777b538SAndroid Build Coastguard Worker MATCHER_P(CookieEquals, expected, "") {
79*6777b538SAndroid Build Coastguard Worker   return !(arg.FullCompare(expected) || expected.FullCompare(arg));
80*6777b538SAndroid Build Coastguard Worker }
81*6777b538SAndroid Build Coastguard Worker 
82*6777b538SAndroid Build Coastguard Worker MATCHER_P2(MatchesCookieNameDomain, name, domain, "") {
83*6777b538SAndroid Build Coastguard Worker   return testing::ExplainMatchResult(
84*6777b538SAndroid Build Coastguard Worker       testing::AllOf(testing::Property(&net::CanonicalCookie::Name, name),
85*6777b538SAndroid Build Coastguard Worker                      testing::Property(&net::CanonicalCookie::Domain, domain)),
86*6777b538SAndroid Build Coastguard Worker       arg, result_listener);
87*6777b538SAndroid Build Coastguard Worker }
88*6777b538SAndroid Build Coastguard Worker 
89*6777b538SAndroid Build Coastguard Worker MATCHER_P4(MatchesCookieNameValueCreationExpiry,
90*6777b538SAndroid Build Coastguard Worker            name,
91*6777b538SAndroid Build Coastguard Worker            value,
92*6777b538SAndroid Build Coastguard Worker            creation,
93*6777b538SAndroid Build Coastguard Worker            expiry,
94*6777b538SAndroid Build Coastguard Worker            "") {
95*6777b538SAndroid Build Coastguard Worker   return testing::ExplainMatchResult(
96*6777b538SAndroid Build Coastguard Worker       testing::AllOf(
97*6777b538SAndroid Build Coastguard Worker           testing::Property(&net::CanonicalCookie::Name, name),
98*6777b538SAndroid Build Coastguard Worker           testing::Property(&net::CanonicalCookie::Value, value),
99*6777b538SAndroid Build Coastguard Worker           testing::Property(&net::CanonicalCookie::CreationDate, creation),
100*6777b538SAndroid Build Coastguard Worker           // We need a margin of error when testing the ExpiryDate as, if
101*6777b538SAndroid Build Coastguard Worker           // clamped, it is set relative to the current time.
102*6777b538SAndroid Build Coastguard Worker           testing::Property(&net::CanonicalCookie::ExpiryDate,
103*6777b538SAndroid Build Coastguard Worker                             testing::Gt(expiry - base::Minutes(1))),
104*6777b538SAndroid Build Coastguard Worker           testing::Property(&net::CanonicalCookie::ExpiryDate,
105*6777b538SAndroid Build Coastguard Worker                             testing::Lt(expiry + base::Minutes(1)))),
106*6777b538SAndroid Build Coastguard Worker       arg, result_listener);
107*6777b538SAndroid Build Coastguard Worker }
108*6777b538SAndroid Build Coastguard Worker 
109*6777b538SAndroid Build Coastguard Worker const char kTopLevelDomainPlus1[] = "http://www.harvard.edu";
110*6777b538SAndroid Build Coastguard Worker const char kTopLevelDomainPlus2[] = "http://www.math.harvard.edu";
111*6777b538SAndroid Build Coastguard Worker const char kTopLevelDomainPlus2Secure[] = "https://www.math.harvard.edu";
112*6777b538SAndroid Build Coastguard Worker const char kTopLevelDomainPlus3[] = "http://www.bourbaki.math.harvard.edu";
113*6777b538SAndroid Build Coastguard Worker const char kOtherDomain[] = "http://www.mit.edu";
114*6777b538SAndroid Build Coastguard Worker 
115*6777b538SAndroid Build Coastguard Worker struct CookieMonsterTestTraits {
Createnet::__anon138ee7670111::CookieMonsterTestTraits116*6777b538SAndroid Build Coastguard Worker   static std::unique_ptr<CookieStore> Create() {
117*6777b538SAndroid Build Coastguard Worker     return std::make_unique<CookieMonster>(nullptr /* store */,
118*6777b538SAndroid Build Coastguard Worker                                            nullptr /* netlog */);
119*6777b538SAndroid Build Coastguard Worker   }
120*6777b538SAndroid Build Coastguard Worker 
DeliverChangeNotificationsnet::__anon138ee7670111::CookieMonsterTestTraits121*6777b538SAndroid Build Coastguard Worker   static void DeliverChangeNotifications() { base::RunLoop().RunUntilIdle(); }
122*6777b538SAndroid Build Coastguard Worker 
123*6777b538SAndroid Build Coastguard Worker   static const bool supports_http_only = true;
124*6777b538SAndroid Build Coastguard Worker   static const bool supports_non_dotted_domains = true;
125*6777b538SAndroid Build Coastguard Worker   static const bool preserves_trailing_dots = true;
126*6777b538SAndroid Build Coastguard Worker   static const bool filters_schemes = true;
127*6777b538SAndroid Build Coastguard Worker   static const bool has_path_prefix_bug = false;
128*6777b538SAndroid Build Coastguard Worker   static const bool forbids_setting_empty_name = false;
129*6777b538SAndroid Build Coastguard Worker   static const bool supports_global_cookie_tracking = true;
130*6777b538SAndroid Build Coastguard Worker   static const bool supports_url_cookie_tracking = true;
131*6777b538SAndroid Build Coastguard Worker   static const bool supports_named_cookie_tracking = true;
132*6777b538SAndroid Build Coastguard Worker   static const bool supports_multiple_tracking_callbacks = true;
133*6777b538SAndroid Build Coastguard Worker   static const bool has_exact_change_cause = true;
134*6777b538SAndroid Build Coastguard Worker   static const bool has_exact_change_ordering = true;
135*6777b538SAndroid Build Coastguard Worker   static const int creation_time_granularity_in_ms = 0;
136*6777b538SAndroid Build Coastguard Worker   static const bool supports_cookie_access_semantics = true;
137*6777b538SAndroid Build Coastguard Worker   static const bool supports_partitioned_cookies = true;
138*6777b538SAndroid Build Coastguard Worker };
139*6777b538SAndroid Build Coastguard Worker 
140*6777b538SAndroid Build Coastguard Worker INSTANTIATE_TYPED_TEST_SUITE_P(CookieMonster,
141*6777b538SAndroid Build Coastguard Worker                                CookieStoreTest,
142*6777b538SAndroid Build Coastguard Worker                                CookieMonsterTestTraits);
143*6777b538SAndroid Build Coastguard Worker INSTANTIATE_TYPED_TEST_SUITE_P(CookieMonster,
144*6777b538SAndroid Build Coastguard Worker                                CookieStoreChangeGlobalTest,
145*6777b538SAndroid Build Coastguard Worker                                CookieMonsterTestTraits);
146*6777b538SAndroid Build Coastguard Worker INSTANTIATE_TYPED_TEST_SUITE_P(CookieMonster,
147*6777b538SAndroid Build Coastguard Worker                                CookieStoreChangeUrlTest,
148*6777b538SAndroid Build Coastguard Worker                                CookieMonsterTestTraits);
149*6777b538SAndroid Build Coastguard Worker INSTANTIATE_TYPED_TEST_SUITE_P(CookieMonster,
150*6777b538SAndroid Build Coastguard Worker                                CookieStoreChangeNamedTest,
151*6777b538SAndroid Build Coastguard Worker                                CookieMonsterTestTraits);
152*6777b538SAndroid Build Coastguard Worker 
153*6777b538SAndroid Build Coastguard Worker template <typename T>
154*6777b538SAndroid Build Coastguard Worker class CookieMonsterTestBase : public CookieStoreTest<T> {
155*6777b538SAndroid Build Coastguard Worker  public:
156*6777b538SAndroid Build Coastguard Worker   using CookieStoreTest<T>::SetCookie;
157*6777b538SAndroid Build Coastguard Worker 
158*6777b538SAndroid Build Coastguard Worker  protected:
159*6777b538SAndroid Build Coastguard Worker   using CookieStoreTest<T>::http_www_foo_;
160*6777b538SAndroid Build Coastguard Worker   using CookieStoreTest<T>::https_www_foo_;
161*6777b538SAndroid Build Coastguard Worker 
GetAllCookiesForURLWithOptions(CookieMonster * cm,const GURL & url,const CookieOptions & options,const CookiePartitionKeyCollection & cookie_partition_key_collection=CookiePartitionKeyCollection ())162*6777b538SAndroid Build Coastguard Worker   CookieList GetAllCookiesForURLWithOptions(
163*6777b538SAndroid Build Coastguard Worker       CookieMonster* cm,
164*6777b538SAndroid Build Coastguard Worker       const GURL& url,
165*6777b538SAndroid Build Coastguard Worker       const CookieOptions& options,
166*6777b538SAndroid Build Coastguard Worker       const CookiePartitionKeyCollection& cookie_partition_key_collection =
167*6777b538SAndroid Build Coastguard Worker           CookiePartitionKeyCollection()) {
168*6777b538SAndroid Build Coastguard Worker     DCHECK(cm);
169*6777b538SAndroid Build Coastguard Worker     GetCookieListCallback callback;
170*6777b538SAndroid Build Coastguard Worker     cm->GetCookieListWithOptionsAsync(
171*6777b538SAndroid Build Coastguard Worker         url, options, cookie_partition_key_collection, callback.MakeCallback());
172*6777b538SAndroid Build Coastguard Worker     callback.WaitUntilDone();
173*6777b538SAndroid Build Coastguard Worker     return callback.cookies();
174*6777b538SAndroid Build Coastguard Worker   }
175*6777b538SAndroid Build Coastguard Worker 
GetAllCookies(CookieMonster * cm)176*6777b538SAndroid Build Coastguard Worker   CookieList GetAllCookies(CookieMonster* cm) {
177*6777b538SAndroid Build Coastguard Worker     DCHECK(cm);
178*6777b538SAndroid Build Coastguard Worker     GetAllCookiesCallback callback;
179*6777b538SAndroid Build Coastguard Worker     cm->GetAllCookiesAsync(callback.MakeCallback());
180*6777b538SAndroid Build Coastguard Worker     callback.WaitUntilDone();
181*6777b538SAndroid Build Coastguard Worker     return callback.cookies();
182*6777b538SAndroid Build Coastguard Worker   }
183*6777b538SAndroid Build Coastguard Worker 
GetExcludedCookiesForURLWithOptions(CookieMonster * cm,const GURL & url,const CookieOptions & options,const CookiePartitionKeyCollection & cookie_partition_key_collection=CookiePartitionKeyCollection ())184*6777b538SAndroid Build Coastguard Worker   CookieAccessResultList GetExcludedCookiesForURLWithOptions(
185*6777b538SAndroid Build Coastguard Worker       CookieMonster* cm,
186*6777b538SAndroid Build Coastguard Worker       const GURL& url,
187*6777b538SAndroid Build Coastguard Worker       const CookieOptions& options,
188*6777b538SAndroid Build Coastguard Worker       const CookiePartitionKeyCollection& cookie_partition_key_collection =
189*6777b538SAndroid Build Coastguard Worker           CookiePartitionKeyCollection()) {
190*6777b538SAndroid Build Coastguard Worker     DCHECK(cm);
191*6777b538SAndroid Build Coastguard Worker     GetCookieListCallback callback;
192*6777b538SAndroid Build Coastguard Worker     cm->GetCookieListWithOptionsAsync(
193*6777b538SAndroid Build Coastguard Worker         url, options, cookie_partition_key_collection, callback.MakeCallback());
194*6777b538SAndroid Build Coastguard Worker     callback.WaitUntilDone();
195*6777b538SAndroid Build Coastguard Worker     return callback.excluded_cookies();
196*6777b538SAndroid Build Coastguard Worker   }
197*6777b538SAndroid Build Coastguard Worker 
SetAllCookies(CookieMonster * cm,const CookieList & list)198*6777b538SAndroid Build Coastguard Worker   bool SetAllCookies(CookieMonster* cm, const CookieList& list) {
199*6777b538SAndroid Build Coastguard Worker     DCHECK(cm);
200*6777b538SAndroid Build Coastguard Worker     ResultSavingCookieCallback<CookieAccessResult> callback;
201*6777b538SAndroid Build Coastguard Worker     cm->SetAllCookiesAsync(list, callback.MakeCallback());
202*6777b538SAndroid Build Coastguard Worker     callback.WaitUntilDone();
203*6777b538SAndroid Build Coastguard Worker     return callback.result().status.IsInclude();
204*6777b538SAndroid Build Coastguard Worker   }
205*6777b538SAndroid Build Coastguard Worker 
SetCookieWithCreationTime(CookieMonster * cm,const GURL & url,const std::string & cookie_line,base::Time creation_time,std::optional<CookiePartitionKey> cookie_partition_key=std::nullopt)206*6777b538SAndroid Build Coastguard Worker   bool SetCookieWithCreationTime(
207*6777b538SAndroid Build Coastguard Worker       CookieMonster* cm,
208*6777b538SAndroid Build Coastguard Worker       const GURL& url,
209*6777b538SAndroid Build Coastguard Worker       const std::string& cookie_line,
210*6777b538SAndroid Build Coastguard Worker       base::Time creation_time,
211*6777b538SAndroid Build Coastguard Worker       std::optional<CookiePartitionKey> cookie_partition_key = std::nullopt) {
212*6777b538SAndroid Build Coastguard Worker     DCHECK(cm);
213*6777b538SAndroid Build Coastguard Worker     DCHECK(!creation_time.is_null());
214*6777b538SAndroid Build Coastguard Worker     ResultSavingCookieCallback<CookieAccessResult> callback;
215*6777b538SAndroid Build Coastguard Worker     cm->SetCanonicalCookieAsync(
216*6777b538SAndroid Build Coastguard Worker         CanonicalCookie::CreateForTesting(url, cookie_line, creation_time,
217*6777b538SAndroid Build Coastguard Worker                                           std::nullopt /* server_time */,
218*6777b538SAndroid Build Coastguard Worker                                           cookie_partition_key),
219*6777b538SAndroid Build Coastguard Worker         url, CookieOptions::MakeAllInclusive(), callback.MakeCallback());
220*6777b538SAndroid Build Coastguard Worker     callback.WaitUntilDone();
221*6777b538SAndroid Build Coastguard Worker     return callback.result().status.IsInclude();
222*6777b538SAndroid Build Coastguard Worker   }
223*6777b538SAndroid Build Coastguard Worker 
DeleteAllCreatedInTimeRange(CookieMonster * cm,const TimeRange & creation_range)224*6777b538SAndroid Build Coastguard Worker   uint32_t DeleteAllCreatedInTimeRange(CookieMonster* cm,
225*6777b538SAndroid Build Coastguard Worker                                        const TimeRange& creation_range) {
226*6777b538SAndroid Build Coastguard Worker     DCHECK(cm);
227*6777b538SAndroid Build Coastguard Worker     ResultSavingCookieCallback<uint32_t> callback;
228*6777b538SAndroid Build Coastguard Worker     cm->DeleteAllCreatedInTimeRangeAsync(creation_range,
229*6777b538SAndroid Build Coastguard Worker                                          callback.MakeCallback());
230*6777b538SAndroid Build Coastguard Worker     callback.WaitUntilDone();
231*6777b538SAndroid Build Coastguard Worker     return callback.result();
232*6777b538SAndroid Build Coastguard Worker   }
233*6777b538SAndroid Build Coastguard Worker 
DeleteAllMatchingInfo(CookieMonster * cm,CookieDeletionInfo delete_info)234*6777b538SAndroid Build Coastguard Worker   uint32_t DeleteAllMatchingInfo(CookieMonster* cm,
235*6777b538SAndroid Build Coastguard Worker                                  CookieDeletionInfo delete_info) {
236*6777b538SAndroid Build Coastguard Worker     DCHECK(cm);
237*6777b538SAndroid Build Coastguard Worker     ResultSavingCookieCallback<uint32_t> callback;
238*6777b538SAndroid Build Coastguard Worker     cm->DeleteAllMatchingInfoAsync(std::move(delete_info),
239*6777b538SAndroid Build Coastguard Worker                                    callback.MakeCallback());
240*6777b538SAndroid Build Coastguard Worker     callback.WaitUntilDone();
241*6777b538SAndroid Build Coastguard Worker     return callback.result();
242*6777b538SAndroid Build Coastguard Worker   }
243*6777b538SAndroid Build Coastguard Worker 
DeleteMatchingCookies(CookieMonster * cm,CookieStore::DeletePredicate predicate)244*6777b538SAndroid Build Coastguard Worker   uint32_t DeleteMatchingCookies(CookieMonster* cm,
245*6777b538SAndroid Build Coastguard Worker                                  CookieStore::DeletePredicate predicate) {
246*6777b538SAndroid Build Coastguard Worker     DCHECK(cm);
247*6777b538SAndroid Build Coastguard Worker     ResultSavingCookieCallback<uint32_t> callback;
248*6777b538SAndroid Build Coastguard Worker     cm->DeleteMatchingCookiesAsync(std::move(predicate),
249*6777b538SAndroid Build Coastguard Worker                                    callback.MakeCallback());
250*6777b538SAndroid Build Coastguard Worker     callback.WaitUntilDone();
251*6777b538SAndroid Build Coastguard Worker     return callback.result();
252*6777b538SAndroid Build Coastguard Worker   }
253*6777b538SAndroid Build Coastguard Worker 
254*6777b538SAndroid Build Coastguard Worker   // Helper for PredicateSeesAllCookies test; repopulates CM with same layout
255*6777b538SAndroid Build Coastguard Worker   // each time. Returns the time which is strictly greater than any creation
256*6777b538SAndroid Build Coastguard Worker   // time which was passed to created cookies.
PopulateCmForPredicateCheck(CookieMonster * cm)257*6777b538SAndroid Build Coastguard Worker   base::Time PopulateCmForPredicateCheck(CookieMonster* cm) {
258*6777b538SAndroid Build Coastguard Worker     std::string url_top_level_domain_plus_1(GURL(kTopLevelDomainPlus1).host());
259*6777b538SAndroid Build Coastguard Worker     std::string url_top_level_domain_plus_2(GURL(kTopLevelDomainPlus2).host());
260*6777b538SAndroid Build Coastguard Worker     std::string url_top_level_domain_plus_3(GURL(kTopLevelDomainPlus3).host());
261*6777b538SAndroid Build Coastguard Worker     std::string url_top_level_domain_secure(
262*6777b538SAndroid Build Coastguard Worker         GURL(kTopLevelDomainPlus2Secure).host());
263*6777b538SAndroid Build Coastguard Worker     std::string url_other(GURL(kOtherDomain).host());
264*6777b538SAndroid Build Coastguard Worker 
265*6777b538SAndroid Build Coastguard Worker     this->DeleteAll(cm);
266*6777b538SAndroid Build Coastguard Worker 
267*6777b538SAndroid Build Coastguard Worker     // Static population for probe:
268*6777b538SAndroid Build Coastguard Worker     //    * Three levels of domain cookie (.b.a, .c.b.a, .d.c.b.a)
269*6777b538SAndroid Build Coastguard Worker     //    * Three levels of host cookie (w.b.a, w.c.b.a, w.d.c.b.a)
270*6777b538SAndroid Build Coastguard Worker     //    * http_only cookie (w.c.b.a)
271*6777b538SAndroid Build Coastguard Worker     //    * same_site cookie (w.c.b.a)
272*6777b538SAndroid Build Coastguard Worker     //    * Two secure cookies (.c.b.a, w.c.b.a)
273*6777b538SAndroid Build Coastguard Worker     //    * Two domain path cookies (.c.b.a/dir1, .c.b.a/dir1/dir2)
274*6777b538SAndroid Build Coastguard Worker     //    * Two host path cookies (w.c.b.a/dir1, w.c.b.a/dir1/dir2)
275*6777b538SAndroid Build Coastguard Worker 
276*6777b538SAndroid Build Coastguard Worker     std::vector<std::unique_ptr<CanonicalCookie>> cookies;
277*6777b538SAndroid Build Coastguard Worker     const base::Time now = base::Time::Now();
278*6777b538SAndroid Build Coastguard Worker 
279*6777b538SAndroid Build Coastguard Worker     // Domain cookies
280*6777b538SAndroid Build Coastguard Worker     cookies.push_back(CanonicalCookie::CreateUnsafeCookieForTesting(
281*6777b538SAndroid Build Coastguard Worker         "dom_1", "A", ".harvard.edu", "/", now, base::Time(), base::Time(),
282*6777b538SAndroid Build Coastguard Worker         base::Time(), false, false, CookieSameSite::LAX_MODE,
283*6777b538SAndroid Build Coastguard Worker         COOKIE_PRIORITY_DEFAULT));
284*6777b538SAndroid Build Coastguard Worker     cookies.push_back(CanonicalCookie::CreateUnsafeCookieForTesting(
285*6777b538SAndroid Build Coastguard Worker         "dom_2", "B", ".math.harvard.edu", "/", now, base::Time(), base::Time(),
286*6777b538SAndroid Build Coastguard Worker         base::Time(), false, false, CookieSameSite::LAX_MODE,
287*6777b538SAndroid Build Coastguard Worker         COOKIE_PRIORITY_DEFAULT));
288*6777b538SAndroid Build Coastguard Worker     cookies.push_back(CanonicalCookie::CreateUnsafeCookieForTesting(
289*6777b538SAndroid Build Coastguard Worker         "dom_3", "C", ".bourbaki.math.harvard.edu", "/", now, base::Time(),
290*6777b538SAndroid Build Coastguard Worker         base::Time(), base::Time(), false, false, CookieSameSite::LAX_MODE,
291*6777b538SAndroid Build Coastguard Worker         COOKIE_PRIORITY_DEFAULT));
292*6777b538SAndroid Build Coastguard Worker 
293*6777b538SAndroid Build Coastguard Worker     // Host cookies
294*6777b538SAndroid Build Coastguard Worker     cookies.push_back(CanonicalCookie::CreateUnsafeCookieForTesting(
295*6777b538SAndroid Build Coastguard Worker         "host_1", "A", url_top_level_domain_plus_1, "/", now, base::Time(),
296*6777b538SAndroid Build Coastguard Worker         base::Time(), base::Time(), false, false, CookieSameSite::LAX_MODE,
297*6777b538SAndroid Build Coastguard Worker         COOKIE_PRIORITY_DEFAULT));
298*6777b538SAndroid Build Coastguard Worker     cookies.push_back(CanonicalCookie::CreateUnsafeCookieForTesting(
299*6777b538SAndroid Build Coastguard Worker         "host_2", "B", url_top_level_domain_plus_2, "/", now, base::Time(),
300*6777b538SAndroid Build Coastguard Worker         base::Time(), base::Time(), false, false, CookieSameSite::LAX_MODE,
301*6777b538SAndroid Build Coastguard Worker         COOKIE_PRIORITY_DEFAULT));
302*6777b538SAndroid Build Coastguard Worker     cookies.push_back(CanonicalCookie::CreateUnsafeCookieForTesting(
303*6777b538SAndroid Build Coastguard Worker         "host_3", "C", url_top_level_domain_plus_3, "/", now, base::Time(),
304*6777b538SAndroid Build Coastguard Worker         base::Time(), base::Time(), false, false, CookieSameSite::LAX_MODE,
305*6777b538SAndroid Build Coastguard Worker         COOKIE_PRIORITY_DEFAULT));
306*6777b538SAndroid Build Coastguard Worker 
307*6777b538SAndroid Build Coastguard Worker     // http_only cookie
308*6777b538SAndroid Build Coastguard Worker     cookies.push_back(CanonicalCookie::CreateUnsafeCookieForTesting(
309*6777b538SAndroid Build Coastguard Worker         "httpo_check", "A", url_top_level_domain_plus_2, "/", now, base::Time(),
310*6777b538SAndroid Build Coastguard Worker         base::Time(), base::Time(), false, true, CookieSameSite::LAX_MODE,
311*6777b538SAndroid Build Coastguard Worker         COOKIE_PRIORITY_DEFAULT));
312*6777b538SAndroid Build Coastguard Worker 
313*6777b538SAndroid Build Coastguard Worker     // same-site cookie
314*6777b538SAndroid Build Coastguard Worker     cookies.push_back(CanonicalCookie::CreateUnsafeCookieForTesting(
315*6777b538SAndroid Build Coastguard Worker         "same_site_check", "A", url_top_level_domain_plus_2, "/", now,
316*6777b538SAndroid Build Coastguard Worker         base::Time(), base::Time(), base::Time(), false, false,
317*6777b538SAndroid Build Coastguard Worker         CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT));
318*6777b538SAndroid Build Coastguard Worker 
319*6777b538SAndroid Build Coastguard Worker     // Secure cookies
320*6777b538SAndroid Build Coastguard Worker     cookies.push_back(CanonicalCookie::CreateUnsafeCookieForTesting(
321*6777b538SAndroid Build Coastguard Worker         "sec_dom", "A", ".math.harvard.edu", "/", now, base::Time(),
322*6777b538SAndroid Build Coastguard Worker         base::Time(), base::Time(), true, false, CookieSameSite::NO_RESTRICTION,
323*6777b538SAndroid Build Coastguard Worker         COOKIE_PRIORITY_DEFAULT));
324*6777b538SAndroid Build Coastguard Worker     cookies.push_back(CanonicalCookie::CreateUnsafeCookieForTesting(
325*6777b538SAndroid Build Coastguard Worker         "sec_host", "B", url_top_level_domain_plus_2, "/", now, base::Time(),
326*6777b538SAndroid Build Coastguard Worker         base::Time(), base::Time(), true, false, CookieSameSite::NO_RESTRICTION,
327*6777b538SAndroid Build Coastguard Worker         COOKIE_PRIORITY_DEFAULT));
328*6777b538SAndroid Build Coastguard Worker 
329*6777b538SAndroid Build Coastguard Worker     // Domain path cookies
330*6777b538SAndroid Build Coastguard Worker     cookies.push_back(CanonicalCookie::CreateUnsafeCookieForTesting(
331*6777b538SAndroid Build Coastguard Worker         "dom_path_1", "A", ".math.harvard.edu", "/dir1", now, base::Time(),
332*6777b538SAndroid Build Coastguard Worker         base::Time(), base::Time(), false, false, CookieSameSite::LAX_MODE,
333*6777b538SAndroid Build Coastguard Worker         COOKIE_PRIORITY_DEFAULT));
334*6777b538SAndroid Build Coastguard Worker     cookies.push_back(CanonicalCookie::CreateUnsafeCookieForTesting(
335*6777b538SAndroid Build Coastguard Worker         "dom_path_2", "B", ".math.harvard.edu", "/dir1/dir2", now, base::Time(),
336*6777b538SAndroid Build Coastguard Worker         base::Time(), base::Time(), false, false, CookieSameSite::LAX_MODE,
337*6777b538SAndroid Build Coastguard Worker         COOKIE_PRIORITY_DEFAULT));
338*6777b538SAndroid Build Coastguard Worker 
339*6777b538SAndroid Build Coastguard Worker     // Host path cookies
340*6777b538SAndroid Build Coastguard Worker     cookies.push_back(CanonicalCookie::CreateUnsafeCookieForTesting(
341*6777b538SAndroid Build Coastguard Worker         "host_path_1", "A", url_top_level_domain_plus_2, "/dir1", now,
342*6777b538SAndroid Build Coastguard Worker         base::Time(), base::Time(), base::Time(), false, false,
343*6777b538SAndroid Build Coastguard Worker         CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT));
344*6777b538SAndroid Build Coastguard Worker     cookies.push_back(CanonicalCookie::CreateUnsafeCookieForTesting(
345*6777b538SAndroid Build Coastguard Worker         "host_path_2", "B", url_top_level_domain_plus_2, "/dir1/dir2", now,
346*6777b538SAndroid Build Coastguard Worker         base::Time(), base::Time(), base::Time(), false, false,
347*6777b538SAndroid Build Coastguard Worker         CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT));
348*6777b538SAndroid Build Coastguard Worker 
349*6777b538SAndroid Build Coastguard Worker     // Partitioned cookies
350*6777b538SAndroid Build Coastguard Worker     cookies.push_back(CanonicalCookie::CreateUnsafeCookieForTesting(
351*6777b538SAndroid Build Coastguard Worker         "__Host-pc_1", "A", url_top_level_domain_secure, "/", now, base::Time(),
352*6777b538SAndroid Build Coastguard Worker         base::Time(), base::Time(), true, false, CookieSameSite::NO_RESTRICTION,
353*6777b538SAndroid Build Coastguard Worker         CookiePriority::COOKIE_PRIORITY_DEFAULT,
354*6777b538SAndroid Build Coastguard Worker         CookiePartitionKey::FromURLForTesting(GURL(kTopLevelDomainPlus1))));
355*6777b538SAndroid Build Coastguard Worker     cookies.push_back(CanonicalCookie::CreateUnsafeCookieForTesting(
356*6777b538SAndroid Build Coastguard Worker         "__Host-pc_2", "B", url_top_level_domain_secure, "/", now, base::Time(),
357*6777b538SAndroid Build Coastguard Worker         base::Time(), base::Time(), true, false, CookieSameSite::NO_RESTRICTION,
358*6777b538SAndroid Build Coastguard Worker         CookiePriority::COOKIE_PRIORITY_DEFAULT,
359*6777b538SAndroid Build Coastguard Worker         CookiePartitionKey::FromURLForTesting(GURL(kTopLevelDomainPlus1))));
360*6777b538SAndroid Build Coastguard Worker 
361*6777b538SAndroid Build Coastguard Worker     for (auto& cookie : cookies) {
362*6777b538SAndroid Build Coastguard Worker       GURL source_url = cookie_util::SimulatedCookieSource(
363*6777b538SAndroid Build Coastguard Worker           *cookie, cookie->SecureAttribute() ? "https" : "http");
364*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(this->SetCanonicalCookie(cm, std::move(cookie), source_url,
365*6777b538SAndroid Build Coastguard Worker                                            true /* modify_httponly */));
366*6777b538SAndroid Build Coastguard Worker     }
367*6777b538SAndroid Build Coastguard Worker 
368*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(cookies.size(), this->GetAllCookies(cm).size());
369*6777b538SAndroid Build Coastguard Worker     return now + base::Milliseconds(100);
370*6777b538SAndroid Build Coastguard Worker   }
371*6777b538SAndroid Build Coastguard Worker 
GetFirstCookieAccessDate(CookieMonster * cm)372*6777b538SAndroid Build Coastguard Worker   Time GetFirstCookieAccessDate(CookieMonster* cm) {
373*6777b538SAndroid Build Coastguard Worker     const CookieList all_cookies(this->GetAllCookies(cm));
374*6777b538SAndroid Build Coastguard Worker     return all_cookies.front().LastAccessDate();
375*6777b538SAndroid Build Coastguard Worker   }
376*6777b538SAndroid Build Coastguard Worker 
FindAndDeleteCookie(CookieMonster * cm,const std::string & domain,const std::string & name)377*6777b538SAndroid Build Coastguard Worker   bool FindAndDeleteCookie(CookieMonster* cm,
378*6777b538SAndroid Build Coastguard Worker                            const std::string& domain,
379*6777b538SAndroid Build Coastguard Worker                            const std::string& name) {
380*6777b538SAndroid Build Coastguard Worker     CookieList cookies = this->GetAllCookies(cm);
381*6777b538SAndroid Build Coastguard Worker     for (auto& cookie : cookies)
382*6777b538SAndroid Build Coastguard Worker       if (cookie.Domain() == domain && cookie.Name() == name)
383*6777b538SAndroid Build Coastguard Worker         return this->DeleteCanonicalCookie(cm, cookie);
384*6777b538SAndroid Build Coastguard Worker     return false;
385*6777b538SAndroid Build Coastguard Worker   }
386*6777b538SAndroid Build Coastguard Worker 
TestHostGarbageCollectHelper()387*6777b538SAndroid Build Coastguard Worker   void TestHostGarbageCollectHelper() {
388*6777b538SAndroid Build Coastguard Worker     int domain_max_cookies = CookieMonster::kDomainMaxCookies;
389*6777b538SAndroid Build Coastguard Worker     int domain_purge_cookies = CookieMonster::kDomainPurgeCookies;
390*6777b538SAndroid Build Coastguard Worker     const int more_than_enough_cookies = domain_max_cookies + 10;
391*6777b538SAndroid Build Coastguard Worker     // Add a bunch of cookies on a single host, should purge them.
392*6777b538SAndroid Build Coastguard Worker     {
393*6777b538SAndroid Build Coastguard Worker       auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
394*6777b538SAndroid Build Coastguard Worker       for (int i = 0; i < more_than_enough_cookies; ++i) {
395*6777b538SAndroid Build Coastguard Worker         std::string cookie = base::StringPrintf("a%03d=b", i);
396*6777b538SAndroid Build Coastguard Worker         EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), cookie));
397*6777b538SAndroid Build Coastguard Worker         std::string cookies = this->GetCookies(cm.get(), http_www_foo_.url());
398*6777b538SAndroid Build Coastguard Worker         // Make sure we find it in the cookies.
399*6777b538SAndroid Build Coastguard Worker         EXPECT_NE(cookies.find(cookie), std::string::npos);
400*6777b538SAndroid Build Coastguard Worker         // Count the number of cookies.
401*6777b538SAndroid Build Coastguard Worker         EXPECT_LE(base::ranges::count(cookies, '='), domain_max_cookies);
402*6777b538SAndroid Build Coastguard Worker       }
403*6777b538SAndroid Build Coastguard Worker     }
404*6777b538SAndroid Build Coastguard Worker 
405*6777b538SAndroid Build Coastguard Worker     // Add a bunch of cookies on multiple hosts within a single eTLD.
406*6777b538SAndroid Build Coastguard Worker     // Should keep at least kDomainMaxCookies - kDomainPurgeCookies
407*6777b538SAndroid Build Coastguard Worker     // between them.  We shouldn't go above kDomainMaxCookies for both together.
408*6777b538SAndroid Build Coastguard Worker     GURL url_google_specific(http_www_foo_.Format("http://www.gmail.%D"));
409*6777b538SAndroid Build Coastguard Worker     {
410*6777b538SAndroid Build Coastguard Worker       auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
411*6777b538SAndroid Build Coastguard Worker       for (int i = 0; i < more_than_enough_cookies; ++i) {
412*6777b538SAndroid Build Coastguard Worker         std::string cookie_general = base::StringPrintf("a%03d=b", i);
413*6777b538SAndroid Build Coastguard Worker         EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), cookie_general));
414*6777b538SAndroid Build Coastguard Worker         std::string cookie_specific = base::StringPrintf("c%03d=b", i);
415*6777b538SAndroid Build Coastguard Worker         EXPECT_TRUE(SetCookie(cm.get(), url_google_specific, cookie_specific));
416*6777b538SAndroid Build Coastguard Worker         std::string cookies_general =
417*6777b538SAndroid Build Coastguard Worker             this->GetCookies(cm.get(), http_www_foo_.url());
418*6777b538SAndroid Build Coastguard Worker         EXPECT_NE(cookies_general.find(cookie_general), std::string::npos);
419*6777b538SAndroid Build Coastguard Worker         std::string cookies_specific =
420*6777b538SAndroid Build Coastguard Worker             this->GetCookies(cm.get(), url_google_specific);
421*6777b538SAndroid Build Coastguard Worker         EXPECT_NE(cookies_specific.find(cookie_specific), std::string::npos);
422*6777b538SAndroid Build Coastguard Worker         EXPECT_LE((base::ranges::count(cookies_general, '=') +
423*6777b538SAndroid Build Coastguard Worker                    base::ranges::count(cookies_specific, '=')),
424*6777b538SAndroid Build Coastguard Worker                   domain_max_cookies);
425*6777b538SAndroid Build Coastguard Worker       }
426*6777b538SAndroid Build Coastguard Worker       // After all this, there should be at least
427*6777b538SAndroid Build Coastguard Worker       // kDomainMaxCookies - kDomainPurgeCookies for both URLs.
428*6777b538SAndroid Build Coastguard Worker       std::string cookies_general =
429*6777b538SAndroid Build Coastguard Worker           this->GetCookies(cm.get(), http_www_foo_.url());
430*6777b538SAndroid Build Coastguard Worker       std::string cookies_specific =
431*6777b538SAndroid Build Coastguard Worker           this->GetCookies(cm.get(), url_google_specific);
432*6777b538SAndroid Build Coastguard Worker       int total_cookies = (base::ranges::count(cookies_general, '=') +
433*6777b538SAndroid Build Coastguard Worker                            base::ranges::count(cookies_specific, '='));
434*6777b538SAndroid Build Coastguard Worker       EXPECT_GE(total_cookies, domain_max_cookies - domain_purge_cookies);
435*6777b538SAndroid Build Coastguard Worker       EXPECT_LE(total_cookies, domain_max_cookies);
436*6777b538SAndroid Build Coastguard Worker     }
437*6777b538SAndroid Build Coastguard Worker 
438*6777b538SAndroid Build Coastguard Worker     // Test histogram for the number of registrable domains affected by domain
439*6777b538SAndroid Build Coastguard Worker     // purge.
440*6777b538SAndroid Build Coastguard Worker     {
441*6777b538SAndroid Build Coastguard Worker       auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
442*6777b538SAndroid Build Coastguard Worker       GURL url;
443*6777b538SAndroid Build Coastguard Worker       for (int domain_num = 0; domain_num < 3; ++domain_num) {
444*6777b538SAndroid Build Coastguard Worker         url = GURL(base::StringPrintf("http://domain%d.test", domain_num));
445*6777b538SAndroid Build Coastguard Worker         for (int i = 0; i < more_than_enough_cookies; ++i) {
446*6777b538SAndroid Build Coastguard Worker           std::string cookie = base::StringPrintf("a%03d=b", i);
447*6777b538SAndroid Build Coastguard Worker           EXPECT_TRUE(SetCookie(cm.get(), url, cookie));
448*6777b538SAndroid Build Coastguard Worker           std::string cookies = this->GetCookies(cm.get(), url);
449*6777b538SAndroid Build Coastguard Worker           // Make sure we find it in the cookies.
450*6777b538SAndroid Build Coastguard Worker           EXPECT_NE(cookies.find(cookie), std::string::npos);
451*6777b538SAndroid Build Coastguard Worker           // Count the number of cookies.
452*6777b538SAndroid Build Coastguard Worker           EXPECT_LE(base::ranges::count(cookies, '='), domain_max_cookies);
453*6777b538SAndroid Build Coastguard Worker         }
454*6777b538SAndroid Build Coastguard Worker       }
455*6777b538SAndroid Build Coastguard Worker 
456*6777b538SAndroid Build Coastguard Worker       // Triggering eviction again for a previously affected registrable domain
457*6777b538SAndroid Build Coastguard Worker       // does not increment the histogram.
458*6777b538SAndroid Build Coastguard Worker       for (int i = 0; i < domain_purge_cookies * 2; ++i) {
459*6777b538SAndroid Build Coastguard Worker         // Add some extra cookies (different names than before).
460*6777b538SAndroid Build Coastguard Worker         std::string cookie = base::StringPrintf("b%03d=b", i);
461*6777b538SAndroid Build Coastguard Worker         EXPECT_TRUE(SetCookie(cm.get(), url, cookie));
462*6777b538SAndroid Build Coastguard Worker         std::string cookies = this->GetCookies(cm.get(), url);
463*6777b538SAndroid Build Coastguard Worker         // Make sure we find it in the cookies.
464*6777b538SAndroid Build Coastguard Worker         EXPECT_NE(cookies.find(cookie), std::string::npos);
465*6777b538SAndroid Build Coastguard Worker         // Count the number of cookies.
466*6777b538SAndroid Build Coastguard Worker         EXPECT_LE(base::ranges::count(cookies, '='), domain_max_cookies);
467*6777b538SAndroid Build Coastguard Worker       }
468*6777b538SAndroid Build Coastguard Worker     }
469*6777b538SAndroid Build Coastguard Worker   }
470*6777b538SAndroid Build Coastguard Worker 
CharToPriority(char ch)471*6777b538SAndroid Build Coastguard Worker   CookiePriority CharToPriority(char ch) {
472*6777b538SAndroid Build Coastguard Worker     switch (ch) {
473*6777b538SAndroid Build Coastguard Worker       case 'L':
474*6777b538SAndroid Build Coastguard Worker         return COOKIE_PRIORITY_LOW;
475*6777b538SAndroid Build Coastguard Worker       case 'M':
476*6777b538SAndroid Build Coastguard Worker         return COOKIE_PRIORITY_MEDIUM;
477*6777b538SAndroid Build Coastguard Worker       case 'H':
478*6777b538SAndroid Build Coastguard Worker         return COOKIE_PRIORITY_HIGH;
479*6777b538SAndroid Build Coastguard Worker     }
480*6777b538SAndroid Build Coastguard Worker     NOTREACHED();
481*6777b538SAndroid Build Coastguard Worker     return COOKIE_PRIORITY_DEFAULT;
482*6777b538SAndroid Build Coastguard Worker   }
483*6777b538SAndroid Build Coastguard Worker 
484*6777b538SAndroid Build Coastguard Worker   // Instantiates a CookieMonster, adds multiple cookies (to http_www_foo_)
485*6777b538SAndroid Build Coastguard Worker   // with priorities specified by |coded_priority_str|, and tests priority-aware
486*6777b538SAndroid Build Coastguard Worker   // domain cookie eviction.
487*6777b538SAndroid Build Coastguard Worker   //
488*6777b538SAndroid Build Coastguard Worker   // Example: |coded_priority_string| of "2MN 3LS MN 4HN" specifies sequential
489*6777b538SAndroid Build Coastguard Worker   // (i.e., from least- to most-recently accessed) insertion of 2
490*6777b538SAndroid Build Coastguard Worker   // medium-priority non-secure cookies, 3 low-priority secure cookies, 1
491*6777b538SAndroid Build Coastguard Worker   // medium-priority non-secure cookie, and 4 high-priority non-secure cookies.
492*6777b538SAndroid Build Coastguard Worker   //
493*6777b538SAndroid Build Coastguard Worker   // Within each priority, only the least-accessed cookies should be evicted.
494*6777b538SAndroid Build Coastguard Worker   // Thus, to describe expected suriving cookies, it suffices to specify the
495*6777b538SAndroid Build Coastguard Worker   // expected population of surviving cookies per priority, i.e.,
496*6777b538SAndroid Build Coastguard Worker   // |expected_low_count|, |expected_medium_count|, and |expected_high_count|.
TestPriorityCookieCase(CookieMonster * cm,const std::string & coded_priority_str,size_t expected_low_count,size_t expected_medium_count,size_t expected_high_count,size_t expected_nonsecure,size_t expected_secure)497*6777b538SAndroid Build Coastguard Worker   void TestPriorityCookieCase(CookieMonster* cm,
498*6777b538SAndroid Build Coastguard Worker                               const std::string& coded_priority_str,
499*6777b538SAndroid Build Coastguard Worker                               size_t expected_low_count,
500*6777b538SAndroid Build Coastguard Worker                               size_t expected_medium_count,
501*6777b538SAndroid Build Coastguard Worker                               size_t expected_high_count,
502*6777b538SAndroid Build Coastguard Worker                               size_t expected_nonsecure,
503*6777b538SAndroid Build Coastguard Worker                               size_t expected_secure) {
504*6777b538SAndroid Build Coastguard Worker     SCOPED_TRACE(coded_priority_str);
505*6777b538SAndroid Build Coastguard Worker     this->DeleteAll(cm);
506*6777b538SAndroid Build Coastguard Worker     int next_cookie_id = 0;
507*6777b538SAndroid Build Coastguard Worker     // A list of cookie IDs, indexed by secure status, then by priority.
508*6777b538SAndroid Build Coastguard Worker     std::vector<int> id_list[2][3];
509*6777b538SAndroid Build Coastguard Worker     // A list of all the cookies stored, along with their properties.
510*6777b538SAndroid Build Coastguard Worker     std::vector<std::pair<bool, CookiePriority>> cookie_data;
511*6777b538SAndroid Build Coastguard Worker 
512*6777b538SAndroid Build Coastguard Worker     // Parse |coded_priority_str| and add cookies.
513*6777b538SAndroid Build Coastguard Worker     for (const std::string& token :
514*6777b538SAndroid Build Coastguard Worker          base::SplitString(coded_priority_str, " ", base::TRIM_WHITESPACE,
515*6777b538SAndroid Build Coastguard Worker                            base::SPLIT_WANT_ALL)) {
516*6777b538SAndroid Build Coastguard Worker       DCHECK(!token.empty());
517*6777b538SAndroid Build Coastguard Worker 
518*6777b538SAndroid Build Coastguard Worker       bool is_secure = token.back() == 'S';
519*6777b538SAndroid Build Coastguard Worker 
520*6777b538SAndroid Build Coastguard Worker       // The second-to-last character is the priority. Grab and discard it.
521*6777b538SAndroid Build Coastguard Worker       CookiePriority priority = CharToPriority(token[token.size() - 2]);
522*6777b538SAndroid Build Coastguard Worker 
523*6777b538SAndroid Build Coastguard Worker       // Discard the security status and priority tokens. The rest of the string
524*6777b538SAndroid Build Coastguard Worker       // (possibly empty) specifies repetition.
525*6777b538SAndroid Build Coastguard Worker       int rep = 1;
526*6777b538SAndroid Build Coastguard Worker       if (!token.empty()) {
527*6777b538SAndroid Build Coastguard Worker         bool result = base::StringToInt(
528*6777b538SAndroid Build Coastguard Worker             base::MakeStringPiece(token.begin(), token.end() - 2), &rep);
529*6777b538SAndroid Build Coastguard Worker         DCHECK(result);
530*6777b538SAndroid Build Coastguard Worker       }
531*6777b538SAndroid Build Coastguard Worker       for (; rep > 0; --rep, ++next_cookie_id) {
532*6777b538SAndroid Build Coastguard Worker         std::string cookie =
533*6777b538SAndroid Build Coastguard Worker             base::StringPrintf("a%d=b;priority=%s;%s", next_cookie_id,
534*6777b538SAndroid Build Coastguard Worker                                CookiePriorityToString(priority).c_str(),
535*6777b538SAndroid Build Coastguard Worker                                is_secure ? "secure" : "");
536*6777b538SAndroid Build Coastguard Worker 
537*6777b538SAndroid Build Coastguard Worker         EXPECT_TRUE(SetCookie(
538*6777b538SAndroid Build Coastguard Worker             cm, is_secure ? https_www_foo_.url() : http_www_foo_.url(),
539*6777b538SAndroid Build Coastguard Worker             cookie));
540*6777b538SAndroid Build Coastguard Worker         cookie_data.emplace_back(is_secure, priority);
541*6777b538SAndroid Build Coastguard Worker         id_list[is_secure][priority].push_back(next_cookie_id);
542*6777b538SAndroid Build Coastguard Worker       }
543*6777b538SAndroid Build Coastguard Worker     }
544*6777b538SAndroid Build Coastguard Worker 
545*6777b538SAndroid Build Coastguard Worker     int num_cookies = static_cast<int>(cookie_data.size());
546*6777b538SAndroid Build Coastguard Worker     // A list of cookie IDs, indexed by secure status, then by priority.
547*6777b538SAndroid Build Coastguard Worker     std::vector<int> surviving_id_list[2][3];
548*6777b538SAndroid Build Coastguard Worker 
549*6777b538SAndroid Build Coastguard Worker     // Parse the list of cookies
550*6777b538SAndroid Build Coastguard Worker     std::string cookie_str = this->GetCookies(cm, https_www_foo_.url());
551*6777b538SAndroid Build Coastguard Worker     // If any part of OBC is active then we also need to query the insecure url
552*6777b538SAndroid Build Coastguard Worker     // and combine the resulting strings.
553*6777b538SAndroid Build Coastguard Worker     if (cookie_util::IsOriginBoundCookiesPartiallyEnabled()) {
554*6777b538SAndroid Build Coastguard Worker       std::string cookie_str_insecure =
555*6777b538SAndroid Build Coastguard Worker           this->GetCookies(cm, http_www_foo_.url());
556*6777b538SAndroid Build Coastguard Worker 
557*6777b538SAndroid Build Coastguard Worker       std::vector<std::string_view> to_be_combined;
558*6777b538SAndroid Build Coastguard Worker       // The cookie strings may be empty, only add them to our vector if
559*6777b538SAndroid Build Coastguard Worker       // they're not. Otherwise we'll get an extra separator added which is bad.
560*6777b538SAndroid Build Coastguard Worker       if (!cookie_str.empty()) {
561*6777b538SAndroid Build Coastguard Worker         to_be_combined.push_back(cookie_str);
562*6777b538SAndroid Build Coastguard Worker       }
563*6777b538SAndroid Build Coastguard Worker       if (!cookie_str_insecure.empty()) {
564*6777b538SAndroid Build Coastguard Worker         to_be_combined.push_back(cookie_str_insecure);
565*6777b538SAndroid Build Coastguard Worker       }
566*6777b538SAndroid Build Coastguard Worker 
567*6777b538SAndroid Build Coastguard Worker       cookie_str = base::JoinString(to_be_combined, /*separator=*/"; ");
568*6777b538SAndroid Build Coastguard Worker     }
569*6777b538SAndroid Build Coastguard Worker 
570*6777b538SAndroid Build Coastguard Worker     size_t num_nonsecure = 0;
571*6777b538SAndroid Build Coastguard Worker     size_t num_secure = 0;
572*6777b538SAndroid Build Coastguard Worker     for (const std::string& token : base::SplitString(
573*6777b538SAndroid Build Coastguard Worker              cookie_str, ";", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
574*6777b538SAndroid Build Coastguard Worker       // Assuming *it is "a#=b", so extract and parse "#" portion.
575*6777b538SAndroid Build Coastguard Worker       int id = -1;
576*6777b538SAndroid Build Coastguard Worker       bool result = base::StringToInt(
577*6777b538SAndroid Build Coastguard Worker           base::MakeStringPiece(token.begin() + 1, token.end() - 2), &id);
578*6777b538SAndroid Build Coastguard Worker       DCHECK(result);
579*6777b538SAndroid Build Coastguard Worker       DCHECK_GE(id, 0);
580*6777b538SAndroid Build Coastguard Worker       DCHECK_LT(id, num_cookies);
581*6777b538SAndroid Build Coastguard Worker       surviving_id_list[cookie_data[id].first][cookie_data[id].second]
582*6777b538SAndroid Build Coastguard Worker           .push_back(id);
583*6777b538SAndroid Build Coastguard Worker       if (cookie_data[id].first)
584*6777b538SAndroid Build Coastguard Worker         num_secure += 1;
585*6777b538SAndroid Build Coastguard Worker       else
586*6777b538SAndroid Build Coastguard Worker         num_nonsecure += 1;
587*6777b538SAndroid Build Coastguard Worker     }
588*6777b538SAndroid Build Coastguard Worker 
589*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(expected_nonsecure, num_nonsecure);
590*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(expected_secure, num_secure);
591*6777b538SAndroid Build Coastguard Worker 
592*6777b538SAndroid Build Coastguard Worker     // Validate each priority.
593*6777b538SAndroid Build Coastguard Worker     size_t expected_count[3] = {expected_low_count, expected_medium_count,
594*6777b538SAndroid Build Coastguard Worker                                 expected_high_count};
595*6777b538SAndroid Build Coastguard Worker     for (int i = 0; i < 3; ++i) {
596*6777b538SAndroid Build Coastguard Worker       size_t num_for_priority =
597*6777b538SAndroid Build Coastguard Worker           surviving_id_list[0][i].size() + surviving_id_list[1][i].size();
598*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(expected_count[i], num_for_priority);
599*6777b538SAndroid Build Coastguard Worker       // Verify that the remaining cookies are the most recent among those
600*6777b538SAndroid Build Coastguard Worker       // with the same priorities.
601*6777b538SAndroid Build Coastguard Worker       if (expected_count[i] == num_for_priority) {
602*6777b538SAndroid Build Coastguard Worker         // Non-secure:
603*6777b538SAndroid Build Coastguard Worker         std::sort(surviving_id_list[0][i].begin(),
604*6777b538SAndroid Build Coastguard Worker                   surviving_id_list[0][i].end());
605*6777b538SAndroid Build Coastguard Worker         EXPECT_TRUE(std::equal(
606*6777b538SAndroid Build Coastguard Worker             surviving_id_list[0][i].begin(), surviving_id_list[0][i].end(),
607*6777b538SAndroid Build Coastguard Worker             id_list[0][i].end() - surviving_id_list[0][i].size()));
608*6777b538SAndroid Build Coastguard Worker 
609*6777b538SAndroid Build Coastguard Worker         // Secure:
610*6777b538SAndroid Build Coastguard Worker         std::sort(surviving_id_list[1][i].begin(),
611*6777b538SAndroid Build Coastguard Worker                   surviving_id_list[1][i].end());
612*6777b538SAndroid Build Coastguard Worker         EXPECT_TRUE(std::equal(
613*6777b538SAndroid Build Coastguard Worker             surviving_id_list[1][i].begin(), surviving_id_list[1][i].end(),
614*6777b538SAndroid Build Coastguard Worker             id_list[1][i].end() - surviving_id_list[1][i].size()));
615*6777b538SAndroid Build Coastguard Worker       }
616*6777b538SAndroid Build Coastguard Worker     }
617*6777b538SAndroid Build Coastguard Worker   }
618*6777b538SAndroid Build Coastguard Worker 
619*6777b538SAndroid Build Coastguard Worker   // Represents a number of cookies to create, if they are Secure cookies, and
620*6777b538SAndroid Build Coastguard Worker   // a url to add them to.
621*6777b538SAndroid Build Coastguard Worker   struct CookiesEntry {
622*6777b538SAndroid Build Coastguard Worker     size_t num_cookies;
623*6777b538SAndroid Build Coastguard Worker     bool is_secure;
624*6777b538SAndroid Build Coastguard Worker   };
625*6777b538SAndroid Build Coastguard Worker   // A number of secure and a number of non-secure alternative hosts to create
626*6777b538SAndroid Build Coastguard Worker   // for testing.
627*6777b538SAndroid Build Coastguard Worker   typedef std::pair<size_t, size_t> AltHosts;
628*6777b538SAndroid Build Coastguard Worker   // Takes an array of CookieEntries which specify the number, type, and order
629*6777b538SAndroid Build Coastguard Worker   // of cookies to create. Cookies are created in the order they appear in
630*6777b538SAndroid Build Coastguard Worker   // cookie_entries. The value of cookie_entries[x].num_cookies specifies how
631*6777b538SAndroid Build Coastguard Worker   // many cookies of that type to create consecutively, while if
632*6777b538SAndroid Build Coastguard Worker   // cookie_entries[x].is_secure is |true|, those cookies will be marked as
633*6777b538SAndroid Build Coastguard Worker   // Secure.
TestSecureCookieEviction(base::span<const CookiesEntry> cookie_entries,size_t expected_secure_cookies,size_t expected_non_secure_cookies,const AltHosts * alt_host_entries)634*6777b538SAndroid Build Coastguard Worker   void TestSecureCookieEviction(base::span<const CookiesEntry> cookie_entries,
635*6777b538SAndroid Build Coastguard Worker                                 size_t expected_secure_cookies,
636*6777b538SAndroid Build Coastguard Worker                                 size_t expected_non_secure_cookies,
637*6777b538SAndroid Build Coastguard Worker                                 const AltHosts* alt_host_entries) {
638*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<CookieMonster> cm;
639*6777b538SAndroid Build Coastguard Worker 
640*6777b538SAndroid Build Coastguard Worker     if (alt_host_entries == nullptr) {
641*6777b538SAndroid Build Coastguard Worker       cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
642*6777b538SAndroid Build Coastguard Worker     } else {
643*6777b538SAndroid Build Coastguard Worker       // When generating all of these cookies on alternate hosts, they need to
644*6777b538SAndroid Build Coastguard Worker       // be all older than the max "safe" date for GC, which is currently 30
645*6777b538SAndroid Build Coastguard Worker       // days, so we set them to 60.
646*6777b538SAndroid Build Coastguard Worker       cm = CreateMonsterFromStoreForGC(
647*6777b538SAndroid Build Coastguard Worker           alt_host_entries->first, alt_host_entries->first,
648*6777b538SAndroid Build Coastguard Worker           alt_host_entries->second, alt_host_entries->second, 60);
649*6777b538SAndroid Build Coastguard Worker     }
650*6777b538SAndroid Build Coastguard Worker 
651*6777b538SAndroid Build Coastguard Worker     int next_cookie_id = 0;
652*6777b538SAndroid Build Coastguard Worker     for (const auto& cookie_entry : cookie_entries) {
653*6777b538SAndroid Build Coastguard Worker       for (size_t j = 0; j < cookie_entry.num_cookies; j++) {
654*6777b538SAndroid Build Coastguard Worker         std::string cookie;
655*6777b538SAndroid Build Coastguard Worker         if (cookie_entry.is_secure)
656*6777b538SAndroid Build Coastguard Worker           cookie = base::StringPrintf("a%d=b; Secure", next_cookie_id);
657*6777b538SAndroid Build Coastguard Worker         else
658*6777b538SAndroid Build Coastguard Worker           cookie = base::StringPrintf("a%d=b", next_cookie_id);
659*6777b538SAndroid Build Coastguard Worker         EXPECT_TRUE(SetCookie(cm.get(), https_www_foo_.url(), cookie));
660*6777b538SAndroid Build Coastguard Worker         ++next_cookie_id;
661*6777b538SAndroid Build Coastguard Worker       }
662*6777b538SAndroid Build Coastguard Worker     }
663*6777b538SAndroid Build Coastguard Worker 
664*6777b538SAndroid Build Coastguard Worker     CookieList cookies = this->GetAllCookies(cm.get());
665*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(expected_secure_cookies + expected_non_secure_cookies,
666*6777b538SAndroid Build Coastguard Worker               cookies.size());
667*6777b538SAndroid Build Coastguard Worker     size_t total_secure_cookies = 0;
668*6777b538SAndroid Build Coastguard Worker     size_t total_non_secure_cookies = 0;
669*6777b538SAndroid Build Coastguard Worker     for (const auto& cookie : cookies) {
670*6777b538SAndroid Build Coastguard Worker       if (cookie.SecureAttribute()) {
671*6777b538SAndroid Build Coastguard Worker         ++total_secure_cookies;
672*6777b538SAndroid Build Coastguard Worker       } else {
673*6777b538SAndroid Build Coastguard Worker         ++total_non_secure_cookies;
674*6777b538SAndroid Build Coastguard Worker       }
675*6777b538SAndroid Build Coastguard Worker     }
676*6777b538SAndroid Build Coastguard Worker 
677*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(expected_secure_cookies, total_secure_cookies);
678*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(expected_non_secure_cookies, total_non_secure_cookies);
679*6777b538SAndroid Build Coastguard Worker   }
680*6777b538SAndroid Build Coastguard Worker 
TestPriorityAwareGarbageCollectHelperNonSecure()681*6777b538SAndroid Build Coastguard Worker   void TestPriorityAwareGarbageCollectHelperNonSecure() {
682*6777b538SAndroid Build Coastguard Worker     // Hard-coding limits in the test, but use DCHECK_EQ to enforce constraint.
683*6777b538SAndroid Build Coastguard Worker     DCHECK_EQ(180U, CookieMonster::kDomainMaxCookies);
684*6777b538SAndroid Build Coastguard Worker     DCHECK_EQ(150U, CookieMonster::kDomainMaxCookies -
685*6777b538SAndroid Build Coastguard Worker                         CookieMonster::kDomainPurgeCookies);
686*6777b538SAndroid Build Coastguard Worker 
687*6777b538SAndroid Build Coastguard Worker     auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
688*6777b538SAndroid Build Coastguard Worker     // Key:
689*6777b538SAndroid Build Coastguard Worker     // Round 1 => LN; round 2 => LS; round 3 => MN.
690*6777b538SAndroid Build Coastguard Worker     // Round 4 => HN; round 5 => MS; round 6 => HS
691*6777b538SAndroid Build Coastguard Worker 
692*6777b538SAndroid Build Coastguard Worker     // Each test case adds 181 cookies, so 31 cookies are evicted.
693*6777b538SAndroid Build Coastguard Worker     // Cookie same priority, repeated for each priority.
694*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "181LN", 150U, 0U, 0U, 150U, 0U);
695*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "181MN", 0U, 150U, 0U, 150U, 0U);
696*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "181HN", 0U, 0U, 150U, 150U, 0U);
697*6777b538SAndroid Build Coastguard Worker 
698*6777b538SAndroid Build Coastguard Worker     // Pairwise scenarios.
699*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round2 => 31M; round 3 => none.
700*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "10HN 171MN", 0U, 140U, 10U, 150U, 0U);
701*6777b538SAndroid Build Coastguard Worker     // Round 1 => 10L; round2 => 21M; round 3 => none.
702*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "141MN 40LN", 30U, 120U, 0U, 150U, 0U);
703*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round2 => 30M; round 3 => 1H.
704*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "101HN 80MN", 0U, 50U, 100U, 150U, 0U);
705*6777b538SAndroid Build Coastguard Worker 
706*6777b538SAndroid Build Coastguard Worker     // For {low, medium} priorities right on quota, different orders.
707*6777b538SAndroid Build Coastguard Worker     // Round 1 => 1L; round 2 => none, round3 => 30H.
708*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "31LN 50MN 100HN", 30U, 50U, 70U, 150U,
709*6777b538SAndroid Build Coastguard Worker                            0U);
710*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round 2 => 1M, round3 => 30H.
711*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "51MN 100HN 30LN", 30U, 50U, 70U, 150U,
712*6777b538SAndroid Build Coastguard Worker                            0U);
713*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round 2 => none; round3 => 31H.
714*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "101HN 50MN 30LN", 30U, 50U, 70U, 150U,
715*6777b538SAndroid Build Coastguard Worker                            0U);
716*6777b538SAndroid Build Coastguard Worker 
717*6777b538SAndroid Build Coastguard Worker     // Round 1 => 10L; round 2 => 10M; round3 => 11H.
718*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "81HN 60MN 40LN", 30U, 50U, 70U, 150U, 0U);
719*6777b538SAndroid Build Coastguard Worker 
720*6777b538SAndroid Build Coastguard Worker     // More complex scenarios.
721*6777b538SAndroid Build Coastguard Worker     // Round 1 => 10L; round 2 => 10M; round 3 => 11H.
722*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "21HN 60MN 40LN 60HN", 30U, 50U, 70U, 150U,
723*6777b538SAndroid Build Coastguard Worker                            0U);
724*6777b538SAndroid Build Coastguard Worker     // Round 1 => 10L; round 2 => 21M; round 3 => 0H.
725*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "11HN 10MN 20LN 110MN 20LN 10HN", 30U, 99U,
726*6777b538SAndroid Build Coastguard Worker                            21U, 150U, 0U);
727*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round 2 => none; round 3 => 31H.
728*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "11LN 10MN 140HN 10MN 10LN", 21U, 20U,
729*6777b538SAndroid Build Coastguard Worker                            109U, 150U, 0U);
730*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round 2 => 21M; round 3 => 10H.
731*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "11MN 10HN 10LN 60MN 90HN", 10U, 50U, 90U,
732*6777b538SAndroid Build Coastguard Worker                            150U, 0U);
733*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round 2 => 31M; round 3 => none.
734*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "11MN 10HN 10LN 90MN 60HN", 10U, 70U, 70U,
735*6777b538SAndroid Build Coastguard Worker                            150U, 0U);
736*6777b538SAndroid Build Coastguard Worker 
737*6777b538SAndroid Build Coastguard Worker     // Round 1 => 20L; round 2 => 0; round 3 => 11H
738*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "50LN 131HN", 30U, 0U, 120U, 150U, 0U);
739*6777b538SAndroid Build Coastguard Worker     // Round 1 => 20L; round 2 => 0; round 3 => 11H
740*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "131HN 50LN", 30U, 0U, 120U, 150U, 0U);
741*6777b538SAndroid Build Coastguard Worker     // Round 1 => 20L; round 2 => none; round 3 => 11H.
742*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "50HN 50LN 81HN", 30U, 0U, 120U, 150U, 0U);
743*6777b538SAndroid Build Coastguard Worker     // Round 1 => 20L; round 2 => none; round 3 => 11H.
744*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "81HN 50LN 50HN", 30U, 0U, 120U, 150U, 0U);
745*6777b538SAndroid Build Coastguard Worker   }
746*6777b538SAndroid Build Coastguard Worker 
TestPriorityAwareGarbageCollectHelperSecure()747*6777b538SAndroid Build Coastguard Worker   void TestPriorityAwareGarbageCollectHelperSecure() {
748*6777b538SAndroid Build Coastguard Worker     // Hard-coding limits in the test, but use DCHECK_EQ to enforce constraint.
749*6777b538SAndroid Build Coastguard Worker     DCHECK_EQ(180U, CookieMonster::kDomainMaxCookies);
750*6777b538SAndroid Build Coastguard Worker     DCHECK_EQ(150U, CookieMonster::kDomainMaxCookies -
751*6777b538SAndroid Build Coastguard Worker                         CookieMonster::kDomainPurgeCookies);
752*6777b538SAndroid Build Coastguard Worker 
753*6777b538SAndroid Build Coastguard Worker     auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
754*6777b538SAndroid Build Coastguard Worker     // Key:
755*6777b538SAndroid Build Coastguard Worker     // Round 1 => LN; round 2 => LS; round 3 => MN.
756*6777b538SAndroid Build Coastguard Worker     // Round 4 => HN; round 5 => MS; round 6 => HS
757*6777b538SAndroid Build Coastguard Worker 
758*6777b538SAndroid Build Coastguard Worker     // Each test case adds 181 cookies, so 31 cookies are evicted.
759*6777b538SAndroid Build Coastguard Worker     // Cookie same priority, repeated for each priority.
760*6777b538SAndroid Build Coastguard Worker     // Round 1 => 31L; round2 => none; round 3 => none.
761*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "181LS", 150U, 0U, 0U, 0U, 150U);
762*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round2 => 31M; round 3 => none.
763*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "181MS", 0U, 150U, 0U, 0U, 150U);
764*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round2 => none; round 3 => 31H.
765*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "181HS", 0U, 0U, 150U, 0U, 150U);
766*6777b538SAndroid Build Coastguard Worker 
767*6777b538SAndroid Build Coastguard Worker     // Pairwise scenarios.
768*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round2 => 31M; round 3 => none.
769*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "10HS 171MS", 0U, 140U, 10U, 0U, 150U);
770*6777b538SAndroid Build Coastguard Worker     // Round 1 => 10L; round2 => 21M; round 3 => none.
771*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "141MS 40LS", 30U, 120U, 0U, 0U, 150U);
772*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round2 => 30M; round 3 => 1H.
773*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "101HS 80MS", 0U, 50U, 100U, 0U, 150U);
774*6777b538SAndroid Build Coastguard Worker 
775*6777b538SAndroid Build Coastguard Worker     // For {low, medium} priorities right on quota, different orders.
776*6777b538SAndroid Build Coastguard Worker     // Round 1 => 1L; round 2 => none, round3 => 30H.
777*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "31LS 50MS 100HS", 30U, 50U, 70U, 0U,
778*6777b538SAndroid Build Coastguard Worker                            150U);
779*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round 2 => 1M, round3 => 30H.
780*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "51MS 100HS 30LS", 30U, 50U, 70U, 0U,
781*6777b538SAndroid Build Coastguard Worker                            150U);
782*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round 2 => none; round3 => 31H.
783*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "101HS 50MS 30LS", 30U, 50U, 70U, 0U,
784*6777b538SAndroid Build Coastguard Worker                            150U);
785*6777b538SAndroid Build Coastguard Worker 
786*6777b538SAndroid Build Coastguard Worker     // Round 1 => 10L; round 2 => 10M; round3 => 11H.
787*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "81HS 60MS 40LS", 30U, 50U, 70U, 0U, 150U);
788*6777b538SAndroid Build Coastguard Worker 
789*6777b538SAndroid Build Coastguard Worker     // More complex scenarios.
790*6777b538SAndroid Build Coastguard Worker     // Round 1 => 10L; round 2 => 10M; round 3 => 11H.
791*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "21HS 60MS 40LS 60HS", 30U, 50U, 70U, 0U,
792*6777b538SAndroid Build Coastguard Worker                            150U);
793*6777b538SAndroid Build Coastguard Worker     // Round 1 => 10L; round 2 => 21M; round 3 => none.
794*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "11HS 10MS 20LS 110MS 20LS 10HS", 30U, 99U,
795*6777b538SAndroid Build Coastguard Worker                            21U, 0U, 150U);
796*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round 2 => none; round 3 => 31H.
797*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "11LS 10MS 140HS 10MS 10LS", 21U, 20U,
798*6777b538SAndroid Build Coastguard Worker                            109U, 0U, 150U);
799*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round 2 => 21M; round 3 => 10H.
800*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "11MS 10HS 10LS 60MS 90HS", 10U, 50U, 90U,
801*6777b538SAndroid Build Coastguard Worker                            0U, 150U);
802*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round 2 => 31M; round 3 => none.
803*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "11MS 10HS 10LS 90MS 60HS", 10U, 70U, 70U,
804*6777b538SAndroid Build Coastguard Worker                            0U, 150U);
805*6777b538SAndroid Build Coastguard Worker   }
806*6777b538SAndroid Build Coastguard Worker 
TestPriorityAwareGarbageCollectHelperMixed()807*6777b538SAndroid Build Coastguard Worker   void TestPriorityAwareGarbageCollectHelperMixed() {
808*6777b538SAndroid Build Coastguard Worker     // Hard-coding limits in the test, but use DCHECK_EQ to enforce constraint.
809*6777b538SAndroid Build Coastguard Worker     DCHECK_EQ(180U, CookieMonster::kDomainMaxCookies);
810*6777b538SAndroid Build Coastguard Worker     DCHECK_EQ(150U, CookieMonster::kDomainMaxCookies -
811*6777b538SAndroid Build Coastguard Worker                         CookieMonster::kDomainPurgeCookies);
812*6777b538SAndroid Build Coastguard Worker 
813*6777b538SAndroid Build Coastguard Worker     auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
814*6777b538SAndroid Build Coastguard Worker     // Key:
815*6777b538SAndroid Build Coastguard Worker     // Round 1 => LN; round 2 => LS; round 3 => MN.
816*6777b538SAndroid Build Coastguard Worker     // Round 4 => HN; round 5 => MS; round 6 => HS
817*6777b538SAndroid Build Coastguard Worker 
818*6777b538SAndroid Build Coastguard Worker     // Each test case adds 180 secure cookies, and some non-secure cookie. The
819*6777b538SAndroid Build Coastguard Worker     // secure cookies take priority, so the non-secure cookie is removed, along
820*6777b538SAndroid Build Coastguard Worker     // with 30 secure cookies. Repeated for each priority, and with the
821*6777b538SAndroid Build Coastguard Worker     // non-secure cookie as older and newer.
822*6777b538SAndroid Build Coastguard Worker     // Round 1 => 1LN; round 2 => 30LS; round 3 => none.
823*6777b538SAndroid Build Coastguard Worker     // Round 4 => none; round 5 => none; round 6 => none.
824*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "1LN 180LS", 150U, 0U, 0U, 0U, 150U);
825*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round 2 => none; round 3 => 1MN.
826*6777b538SAndroid Build Coastguard Worker     // Round 4 => none; round 5 => 30MS; round 6 => none.
827*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "1MN 180MS", 0U, 150U, 0U, 0U, 150U);
828*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round 2 => none; round 3 => none.
829*6777b538SAndroid Build Coastguard Worker     // Round 4 => 1HN; round 5 => none; round 6 => 30HS.
830*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "1HN 180HS", 0U, 0U, 150U, 0U, 150U);
831*6777b538SAndroid Build Coastguard Worker     // Round 1 => 1LN; round 2 => 30LS; round 3 => none.
832*6777b538SAndroid Build Coastguard Worker     // Round 4 => none; round 5 => none; round 6 => none.
833*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "180LS 1LN", 150U, 0U, 0U, 0U, 150U);
834*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round 2 => none; round 3 => 1MN.
835*6777b538SAndroid Build Coastguard Worker     // Round 4 => none; round 5 => 30MS; round 6 => none.
836*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "180MS 1MN", 0U, 150U, 0U, 0U, 150U);
837*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round 2 => none; round 3 => none.
838*6777b538SAndroid Build Coastguard Worker     // Round 4 => 1HN; round 5 => none; round 6 => 30HS.
839*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "180HS 1HN", 0U, 0U, 150U, 0U, 150U);
840*6777b538SAndroid Build Coastguard Worker 
841*6777b538SAndroid Build Coastguard Worker     // Quotas should be correctly maintained when a given priority has both
842*6777b538SAndroid Build Coastguard Worker     // secure and non-secure cookies.
843*6777b538SAndroid Build Coastguard Worker     //
844*6777b538SAndroid Build Coastguard Worker     // Round 1 => 10LN; round 2 => none; round 3 => none.
845*6777b538SAndroid Build Coastguard Worker     // Round 4 => 21HN; round 5 => none; round 6 => none.
846*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "39LN 1LS 141HN", 30U, 0U, 120U, 149U, 1U);
847*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round 2 => none; round 3 => 10MN.
848*6777b538SAndroid Build Coastguard Worker     // Round 4 => none; round 5 => none; round 6 => 21HS.
849*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "29LN 1LS 59MN 1MS 91HS", 30U, 50U, 70U,
850*6777b538SAndroid Build Coastguard Worker                            78U, 72U);
851*6777b538SAndroid Build Coastguard Worker 
852*6777b538SAndroid Build Coastguard Worker     // Low-priority secure cookies are removed before higher priority non-secure
853*6777b538SAndroid Build Coastguard Worker     // cookies.
854*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round 2 => 31LS; round 3 => none.
855*6777b538SAndroid Build Coastguard Worker     // Round 4 => none; round 5 => none; round 6 => none.
856*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "180LS 1MN", 149U, 1U, 0U, 1U, 149U);
857*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round 2 => 31LS; round 3 => none.
858*6777b538SAndroid Build Coastguard Worker     // Round 4 => none; round 5 => none; round 6 => none.
859*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "180LS 1HN", 149U, 0U, 1U, 1U, 149U);
860*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round 2 => 31LS; round 3 => none.
861*6777b538SAndroid Build Coastguard Worker     // Round 4 => none; round 5 => none; round 6 => none.
862*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "1MN 180LS", 149U, 1U, 0U, 1U, 149U);
863*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round 2 => 31LS; round 3 => none.
864*6777b538SAndroid Build Coastguard Worker     // Round 4 => none; round 5 => none; round 6 => none.
865*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "1HN 180LS", 149U, 0U, 1U, 1U, 149U);
866*6777b538SAndroid Build Coastguard Worker 
867*6777b538SAndroid Build Coastguard Worker     // Higher-priority non-secure cookies are removed before any secure cookie
868*6777b538SAndroid Build Coastguard Worker     // with greater than low-priority. Is it true? How about the quota?
869*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round 2 => none; round 3 => none.
870*6777b538SAndroid Build Coastguard Worker     // Round 4 => none; round 5 => 31MS; round 6 => none.
871*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "180MS 1HN", 0U, 149U, 1U, 1U, 149U);
872*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round 2 => none; round 3 => none.
873*6777b538SAndroid Build Coastguard Worker     // Round 4 => none; round 5 => 31MS; round 6 => none.
874*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "1HN 180MS", 0U, 149U, 1U, 1U, 149U);
875*6777b538SAndroid Build Coastguard Worker 
876*6777b538SAndroid Build Coastguard Worker     // Pairwise:
877*6777b538SAndroid Build Coastguard Worker     // Round 1 => 31LN; round 2 => none; round 3 => none.
878*6777b538SAndroid Build Coastguard Worker     // Round 4 => none; round 5 => none; round 6 => none.
879*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "1LS 180LN", 150U, 0U, 0U, 149U, 1U);
880*6777b538SAndroid Build Coastguard Worker     // Round 1 => 31LN; round 2 => none; round 3 => none.
881*6777b538SAndroid Build Coastguard Worker     // Round 4 => none; round 5 => none; round 6 => none.
882*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "100LS 81LN", 150U, 0U, 0U, 50U, 100U);
883*6777b538SAndroid Build Coastguard Worker     // Round 1 => 31LN; round 2 => none; round 3 => none.
884*6777b538SAndroid Build Coastguard Worker     // Round 4 => none; round 5 => none; round 6 => none.
885*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "150LS 31LN", 150U, 0U, 0U, 0U, 150U);
886*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round 2 => none; round 3 => none.
887*6777b538SAndroid Build Coastguard Worker     // Round 4 => 31HN; round 5 => none; round 6 => none.
888*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "1LS 180HN", 1U, 0U, 149U, 149U, 1U);
889*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round 2 => 31LS; round 3 => none.
890*6777b538SAndroid Build Coastguard Worker     // Round 4 => none; round 5 => none; round 6 => none.
891*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "100LS 81HN", 69U, 0U, 81U, 81U, 69U);
892*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round 2 => 31LS; round 3 => none.
893*6777b538SAndroid Build Coastguard Worker     // Round 4 => none; round 5 => none; round 6 => none.
894*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "150LS 31HN", 119U, 0U, 31U, 31U, 119U);
895*6777b538SAndroid Build Coastguard Worker 
896*6777b538SAndroid Build Coastguard Worker     // Quota calculations inside non-secure/secure blocks remain in place:
897*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round 2 => 20LS; round 3 => none.
898*6777b538SAndroid Build Coastguard Worker     // Round 4 => 11HN; round 5 => none; round 6 => none.
899*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "50HN 50LS 81HS", 30U, 0U, 120U, 39U,
900*6777b538SAndroid Build Coastguard Worker                            111U);
901*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round 2 => none; round 3 => 31MN.
902*6777b538SAndroid Build Coastguard Worker     // Round 4 => none; round 5 => none; round 6 => none.
903*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "11MS 10HN 10LS 90MN 60HN", 10U, 70U, 70U,
904*6777b538SAndroid Build Coastguard Worker                            129U, 21U);
905*6777b538SAndroid Build Coastguard Worker     // Round 1 => 31LN; round 2 => none; round 3 => none.
906*6777b538SAndroid Build Coastguard Worker     // Round 4 => none; round 5 => none; round 6 => none.
907*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "40LS 40LN 101HS", 49U, 0U, 101U, 9U,
908*6777b538SAndroid Build Coastguard Worker                            141U);
909*6777b538SAndroid Build Coastguard Worker 
910*6777b538SAndroid Build Coastguard Worker     // Multiple GC rounds end up with consistent behavior:
911*6777b538SAndroid Build Coastguard Worker     // GC is started as soon as there are 181 cookies in the store.
912*6777b538SAndroid Build Coastguard Worker     // On each major round it tries to preserve the quota for each priority.
913*6777b538SAndroid Build Coastguard Worker     // It is not aware about more cookies going in.
914*6777b538SAndroid Build Coastguard Worker     // 1 GC notices there are 181 cookies - 100HS 81LN 0MN
915*6777b538SAndroid Build Coastguard Worker     // Round 1 => 31LN; round 2 => none; round 3 => none.
916*6777b538SAndroid Build Coastguard Worker     // Round 4 => none; round 5 => none; round 6 => none.
917*6777b538SAndroid Build Coastguard Worker     // 2 GC notices there are 181 cookies - 100HS 69LN 12MN
918*6777b538SAndroid Build Coastguard Worker     // Round 1 => 31LN; round 2 => none; round 3 => none.
919*6777b538SAndroid Build Coastguard Worker     // Round 4 => none; round 5 => none; round 6 => none.
920*6777b538SAndroid Build Coastguard Worker     // 3 GC notices there are 181 cookies - 100HS 38LN 43MN
921*6777b538SAndroid Build Coastguard Worker     // Round 1 =>  8LN; round 2 => none; round 3 => none.
922*6777b538SAndroid Build Coastguard Worker     // Round 4 => none; round 5 => none; round 6 => 23HS.
923*6777b538SAndroid Build Coastguard Worker     // 4 GC notcies there are 181 cookies - 77HS 30LN 74MN
924*6777b538SAndroid Build Coastguard Worker     // Round 1 => none; round 2 => none; round 3 => 24MN.
925*6777b538SAndroid Build Coastguard Worker     // Round 4 => none; round 5 => none; round 6 =>  7HS.
926*6777b538SAndroid Build Coastguard Worker     TestPriorityCookieCase(cm.get(), "100HS 100LN 100MN", 30U, 76U, 70U, 106U,
927*6777b538SAndroid Build Coastguard Worker                            70U);
928*6777b538SAndroid Build Coastguard Worker   }
929*6777b538SAndroid Build Coastguard Worker 
930*6777b538SAndroid Build Coastguard Worker   // Function for creating a CM with a number of cookies in it,
931*6777b538SAndroid Build Coastguard Worker   // no store (and hence no ability to affect access time).
CreateMonsterForGC(int num_cookies)932*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<CookieMonster> CreateMonsterForGC(int num_cookies) {
933*6777b538SAndroid Build Coastguard Worker     auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
934*6777b538SAndroid Build Coastguard Worker     base::Time creation_time = base::Time::Now();
935*6777b538SAndroid Build Coastguard Worker     for (int i = 0; i < num_cookies; i++) {
936*6777b538SAndroid Build Coastguard Worker       std::unique_ptr<CanonicalCookie> cc(
937*6777b538SAndroid Build Coastguard Worker           CanonicalCookie::CreateUnsafeCookieForTesting(
938*6777b538SAndroid Build Coastguard Worker               "a", "1", base::StringPrintf("h%05d.izzle", i), /*path=*/"/",
939*6777b538SAndroid Build Coastguard Worker               creation_time, /*=expiration_time=*/base::Time(),
940*6777b538SAndroid Build Coastguard Worker               /*last_access=*/creation_time, /*last_update=*/creation_time,
941*6777b538SAndroid Build Coastguard Worker               /*secure=*/true,
942*6777b538SAndroid Build Coastguard Worker               /*httponly=*/false, CookieSameSite::NO_RESTRICTION,
943*6777b538SAndroid Build Coastguard Worker               COOKIE_PRIORITY_DEFAULT));
944*6777b538SAndroid Build Coastguard Worker       GURL source_url = cookie_util::SimulatedCookieSource(*cc, "https");
945*6777b538SAndroid Build Coastguard Worker       cm->SetCanonicalCookieAsync(std::move(cc), source_url,
946*6777b538SAndroid Build Coastguard Worker                                   CookieOptions::MakeAllInclusive(),
947*6777b538SAndroid Build Coastguard Worker                                   CookieStore::SetCookiesCallback());
948*6777b538SAndroid Build Coastguard Worker     }
949*6777b538SAndroid Build Coastguard Worker     return cm;
950*6777b538SAndroid Build Coastguard Worker   }
951*6777b538SAndroid Build Coastguard Worker 
IsCookieInList(const CanonicalCookie & cookie,const CookieList & list)952*6777b538SAndroid Build Coastguard Worker   bool IsCookieInList(const CanonicalCookie& cookie, const CookieList& list) {
953*6777b538SAndroid Build Coastguard Worker     for (const auto& c : list) {
954*6777b538SAndroid Build Coastguard Worker       if (c.Name() == cookie.Name() && c.Value() == cookie.Value() &&
955*6777b538SAndroid Build Coastguard Worker           c.Domain() == cookie.Domain() && c.Path() == cookie.Path() &&
956*6777b538SAndroid Build Coastguard Worker           c.CreationDate() == cookie.CreationDate() &&
957*6777b538SAndroid Build Coastguard Worker           c.ExpiryDate() == cookie.ExpiryDate() &&
958*6777b538SAndroid Build Coastguard Worker           c.LastAccessDate() == cookie.LastAccessDate() &&
959*6777b538SAndroid Build Coastguard Worker           c.LastUpdateDate() == cookie.LastUpdateDate() &&
960*6777b538SAndroid Build Coastguard Worker           c.SecureAttribute() == cookie.SecureAttribute() &&
961*6777b538SAndroid Build Coastguard Worker           c.IsHttpOnly() == cookie.IsHttpOnly() &&
962*6777b538SAndroid Build Coastguard Worker           c.Priority() == cookie.Priority()) {
963*6777b538SAndroid Build Coastguard Worker         return true;
964*6777b538SAndroid Build Coastguard Worker       }
965*6777b538SAndroid Build Coastguard Worker     }
966*6777b538SAndroid Build Coastguard Worker 
967*6777b538SAndroid Build Coastguard Worker     return false;
968*6777b538SAndroid Build Coastguard Worker   }
969*6777b538SAndroid Build Coastguard Worker   RecordingNetLogObserver net_log_;
970*6777b538SAndroid Build Coastguard Worker };
971*6777b538SAndroid Build Coastguard Worker 
972*6777b538SAndroid Build Coastguard Worker using CookieMonsterTest = CookieMonsterTestBase<CookieMonsterTestTraits>;
973*6777b538SAndroid Build Coastguard Worker 
974*6777b538SAndroid Build Coastguard Worker class CookieMonsterTestGarbageCollectionObc
975*6777b538SAndroid Build Coastguard Worker     : public CookieMonsterTest,
976*6777b538SAndroid Build Coastguard Worker       public testing::WithParamInterface<std::tuple<bool, bool>> {
977*6777b538SAndroid Build Coastguard Worker  public:
CookieMonsterTestGarbageCollectionObc()978*6777b538SAndroid Build Coastguard Worker   CookieMonsterTestGarbageCollectionObc() {
979*6777b538SAndroid Build Coastguard Worker     scoped_feature_list_.InitWithFeatureStates(
980*6777b538SAndroid Build Coastguard Worker         {{net::features::kEnableSchemeBoundCookies, IsSchemeBoundEnabled()},
981*6777b538SAndroid Build Coastguard Worker          {net::features::kEnablePortBoundCookies, IsPortBoundEnabled()}});
982*6777b538SAndroid Build Coastguard Worker   }
983*6777b538SAndroid Build Coastguard Worker 
IsSchemeBoundEnabled() const984*6777b538SAndroid Build Coastguard Worker   bool IsSchemeBoundEnabled() const { return std::get<0>(GetParam()); }
985*6777b538SAndroid Build Coastguard Worker 
IsPortBoundEnabled() const986*6777b538SAndroid Build Coastguard Worker   bool IsPortBoundEnabled() const { return std::get<1>(GetParam()); }
987*6777b538SAndroid Build Coastguard Worker 
988*6777b538SAndroid Build Coastguard Worker  private:
989*6777b538SAndroid Build Coastguard Worker   base::test::ScopedFeatureList scoped_feature_list_;
990*6777b538SAndroid Build Coastguard Worker };
991*6777b538SAndroid Build Coastguard Worker 
992*6777b538SAndroid Build Coastguard Worker using CookieMonsterTestPriorityGarbageCollectionObc =
993*6777b538SAndroid Build Coastguard Worker     CookieMonsterTestGarbageCollectionObc;
994*6777b538SAndroid Build Coastguard Worker 
995*6777b538SAndroid Build Coastguard Worker struct CookiesInputInfo {
996*6777b538SAndroid Build Coastguard Worker   const GURL url;
997*6777b538SAndroid Build Coastguard Worker   const std::string name;
998*6777b538SAndroid Build Coastguard Worker   const std::string value;
999*6777b538SAndroid Build Coastguard Worker   const std::string domain;
1000*6777b538SAndroid Build Coastguard Worker   const std::string path;
1001*6777b538SAndroid Build Coastguard Worker   const base::Time expiration_time;
1002*6777b538SAndroid Build Coastguard Worker   bool secure;
1003*6777b538SAndroid Build Coastguard Worker   bool http_only;
1004*6777b538SAndroid Build Coastguard Worker   CookieSameSite same_site;
1005*6777b538SAndroid Build Coastguard Worker   CookiePriority priority;
1006*6777b538SAndroid Build Coastguard Worker };
1007*6777b538SAndroid Build Coastguard Worker 
1008*6777b538SAndroid Build Coastguard Worker }  // namespace
1009*6777b538SAndroid Build Coastguard Worker 
1010*6777b538SAndroid Build Coastguard Worker // This test suite verifies the task deferral behaviour of the CookieMonster.
1011*6777b538SAndroid Build Coastguard Worker // Specifically, for each asynchronous method, verify that:
1012*6777b538SAndroid Build Coastguard Worker // 1. invoking it on an uninitialized cookie store causes the store to begin
1013*6777b538SAndroid Build Coastguard Worker //    chain-loading its backing data or loading data for a specific domain key
1014*6777b538SAndroid Build Coastguard Worker //    (eTLD+1).
1015*6777b538SAndroid Build Coastguard Worker // 2. The initial invocation does not complete until the loading completes.
1016*6777b538SAndroid Build Coastguard Worker // 3. Invocations after the loading has completed complete immediately.
1017*6777b538SAndroid Build Coastguard Worker class DeferredCookieTaskTest : public CookieMonsterTest {
1018*6777b538SAndroid Build Coastguard Worker  protected:
DeferredCookieTaskTest()1019*6777b538SAndroid Build Coastguard Worker   DeferredCookieTaskTest() {
1020*6777b538SAndroid Build Coastguard Worker     persistent_store_ = base::MakeRefCounted<MockPersistentCookieStore>();
1021*6777b538SAndroid Build Coastguard Worker     persistent_store_->set_store_load_commands(true);
1022*6777b538SAndroid Build Coastguard Worker     cookie_monster_ = std::make_unique<CookieMonster>(persistent_store_.get(),
1023*6777b538SAndroid Build Coastguard Worker                                                       net::NetLog::Get());
1024*6777b538SAndroid Build Coastguard Worker   }
1025*6777b538SAndroid Build Coastguard Worker 
1026*6777b538SAndroid Build Coastguard Worker   // Defines a cookie to be returned from PersistentCookieStore::Load
DeclareLoadedCookie(const GURL & url,const std::string & cookie_line,const base::Time & creation_time)1027*6777b538SAndroid Build Coastguard Worker   void DeclareLoadedCookie(const GURL& url,
1028*6777b538SAndroid Build Coastguard Worker                            const std::string& cookie_line,
1029*6777b538SAndroid Build Coastguard Worker                            const base::Time& creation_time) {
1030*6777b538SAndroid Build Coastguard Worker     AddCookieToList(url, cookie_line, creation_time, &loaded_cookies_);
1031*6777b538SAndroid Build Coastguard Worker   }
1032*6777b538SAndroid Build Coastguard Worker 
ExecuteLoads(CookieStoreCommand::Type type)1033*6777b538SAndroid Build Coastguard Worker   void ExecuteLoads(CookieStoreCommand::Type type) {
1034*6777b538SAndroid Build Coastguard Worker     const auto& commands = persistent_store_->commands();
1035*6777b538SAndroid Build Coastguard Worker     for (size_t i = 0; i < commands.size(); ++i) {
1036*6777b538SAndroid Build Coastguard Worker       // Only the first load command will produce the cookies.
1037*6777b538SAndroid Build Coastguard Worker       if (commands[i].type == type) {
1038*6777b538SAndroid Build Coastguard Worker         persistent_store_->TakeCallbackAt(i).Run(std::move(loaded_cookies_));
1039*6777b538SAndroid Build Coastguard Worker       }
1040*6777b538SAndroid Build Coastguard Worker     }
1041*6777b538SAndroid Build Coastguard Worker   }
1042*6777b538SAndroid Build Coastguard Worker 
CommandSummary(const MockPersistentCookieStore::CommandList & commands)1043*6777b538SAndroid Build Coastguard Worker   std::string CommandSummary(
1044*6777b538SAndroid Build Coastguard Worker       const MockPersistentCookieStore::CommandList& commands) {
1045*6777b538SAndroid Build Coastguard Worker     std::string out;
1046*6777b538SAndroid Build Coastguard Worker     for (const auto& command : commands) {
1047*6777b538SAndroid Build Coastguard Worker       switch (command.type) {
1048*6777b538SAndroid Build Coastguard Worker         case CookieStoreCommand::LOAD:
1049*6777b538SAndroid Build Coastguard Worker           base::StrAppend(&out, {"LOAD; "});
1050*6777b538SAndroid Build Coastguard Worker           break;
1051*6777b538SAndroid Build Coastguard Worker         case CookieStoreCommand::LOAD_COOKIES_FOR_KEY:
1052*6777b538SAndroid Build Coastguard Worker           base::StrAppend(&out, {"LOAD_FOR_KEY:", command.key, "; "});
1053*6777b538SAndroid Build Coastguard Worker           break;
1054*6777b538SAndroid Build Coastguard Worker         case CookieStoreCommand::ADD:
1055*6777b538SAndroid Build Coastguard Worker           base::StrAppend(&out, {"ADD; "});
1056*6777b538SAndroid Build Coastguard Worker           break;
1057*6777b538SAndroid Build Coastguard Worker         case CookieStoreCommand::REMOVE:
1058*6777b538SAndroid Build Coastguard Worker           base::StrAppend(&out, {"REMOVE; "});
1059*6777b538SAndroid Build Coastguard Worker           break;
1060*6777b538SAndroid Build Coastguard Worker       }
1061*6777b538SAndroid Build Coastguard Worker     }
1062*6777b538SAndroid Build Coastguard Worker     return out;
1063*6777b538SAndroid Build Coastguard Worker   }
1064*6777b538SAndroid Build Coastguard Worker 
TakeCommandSummary()1065*6777b538SAndroid Build Coastguard Worker   std::string TakeCommandSummary() {
1066*6777b538SAndroid Build Coastguard Worker     return CommandSummary(persistent_store_->TakeCommands());
1067*6777b538SAndroid Build Coastguard Worker   }
1068*6777b538SAndroid Build Coastguard Worker 
1069*6777b538SAndroid Build Coastguard Worker   // Holds cookies to be returned from PersistentCookieStore::Load or
1070*6777b538SAndroid Build Coastguard Worker   // PersistentCookieStore::LoadCookiesForKey.
1071*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<CanonicalCookie>> loaded_cookies_;
1072*6777b538SAndroid Build Coastguard Worker 
1073*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<CookieMonster> cookie_monster_;
1074*6777b538SAndroid Build Coastguard Worker   scoped_refptr<MockPersistentCookieStore> persistent_store_;
1075*6777b538SAndroid Build Coastguard Worker };
1076*6777b538SAndroid Build Coastguard Worker 
TEST_F(DeferredCookieTaskTest,DeferredGetCookieList)1077*6777b538SAndroid Build Coastguard Worker TEST_F(DeferredCookieTaskTest, DeferredGetCookieList) {
1078*6777b538SAndroid Build Coastguard Worker   DeclareLoadedCookie(http_www_foo_.url(),
1079*6777b538SAndroid Build Coastguard Worker                       "X=1; path=/" + FutureCookieExpirationString(),
1080*6777b538SAndroid Build Coastguard Worker                       Time::Now() + base::Days(3));
1081*6777b538SAndroid Build Coastguard Worker 
1082*6777b538SAndroid Build Coastguard Worker   GetCookieListCallback call1;
1083*6777b538SAndroid Build Coastguard Worker   cookie_monster_->GetCookieListWithOptionsAsync(
1084*6777b538SAndroid Build Coastguard Worker       http_www_foo_.url(), CookieOptions::MakeAllInclusive(),
1085*6777b538SAndroid Build Coastguard Worker       CookiePartitionKeyCollection(), call1.MakeCallback());
1086*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
1087*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(call1.was_run());
1088*6777b538SAndroid Build Coastguard Worker 
1089*6777b538SAndroid Build Coastguard Worker   // Finish the per-key load, not everything-load (which is always initiated).
1090*6777b538SAndroid Build Coastguard Worker   ExecuteLoads(CookieStoreCommand::LOAD_COOKIES_FOR_KEY);
1091*6777b538SAndroid Build Coastguard Worker   call1.WaitUntilDone();
1092*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(call1.cookies(), MatchesCookieLine("X=1"));
1093*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("LOAD; LOAD_FOR_KEY:foo.com; ", TakeCommandSummary());
1094*6777b538SAndroid Build Coastguard Worker 
1095*6777b538SAndroid Build Coastguard Worker   GetCookieListCallback call2;
1096*6777b538SAndroid Build Coastguard Worker   cookie_monster_->GetCookieListWithOptionsAsync(
1097*6777b538SAndroid Build Coastguard Worker       http_www_foo_.url(), CookieOptions::MakeAllInclusive(),
1098*6777b538SAndroid Build Coastguard Worker       CookiePartitionKeyCollection(), call2.MakeCallback());
1099*6777b538SAndroid Build Coastguard Worker   // Already ready, no need for second load.
1100*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(call2.cookies(), MatchesCookieLine("X=1"));
1101*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("", TakeCommandSummary());
1102*6777b538SAndroid Build Coastguard Worker }
1103*6777b538SAndroid Build Coastguard Worker 
TEST_F(DeferredCookieTaskTest,DeferredSetCookie)1104*6777b538SAndroid Build Coastguard Worker TEST_F(DeferredCookieTaskTest, DeferredSetCookie) {
1105*6777b538SAndroid Build Coastguard Worker   // Generate puts to store w/o needing a proper expiration.
1106*6777b538SAndroid Build Coastguard Worker   cookie_monster_->SetPersistSessionCookies(true);
1107*6777b538SAndroid Build Coastguard Worker 
1108*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<CookieAccessResult> call1;
1109*6777b538SAndroid Build Coastguard Worker   cookie_monster_->SetCanonicalCookieAsync(
1110*6777b538SAndroid Build Coastguard Worker       CanonicalCookie::CreateForTesting(http_www_foo_.url(), "A=B",
1111*6777b538SAndroid Build Coastguard Worker                                         base::Time::Now()),
1112*6777b538SAndroid Build Coastguard Worker       http_www_foo_.url(), CookieOptions::MakeAllInclusive(),
1113*6777b538SAndroid Build Coastguard Worker       call1.MakeCallback());
1114*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
1115*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(call1.was_run());
1116*6777b538SAndroid Build Coastguard Worker 
1117*6777b538SAndroid Build Coastguard Worker   ExecuteLoads(CookieStoreCommand::LOAD_COOKIES_FOR_KEY);
1118*6777b538SAndroid Build Coastguard Worker   call1.WaitUntilDone();
1119*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(call1.result().status.IsInclude());
1120*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("LOAD; LOAD_FOR_KEY:foo.com; ADD; ", TakeCommandSummary());
1121*6777b538SAndroid Build Coastguard Worker 
1122*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<CookieAccessResult> call2;
1123*6777b538SAndroid Build Coastguard Worker   cookie_monster_->SetCanonicalCookieAsync(
1124*6777b538SAndroid Build Coastguard Worker       CanonicalCookie::CreateForTesting(http_www_foo_.url(), "X=Y",
1125*6777b538SAndroid Build Coastguard Worker                                         base::Time::Now()),
1126*6777b538SAndroid Build Coastguard Worker       http_www_foo_.url(), CookieOptions::MakeAllInclusive(),
1127*6777b538SAndroid Build Coastguard Worker       call2.MakeCallback());
1128*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(call2.was_run());
1129*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(call2.result().status.IsInclude());
1130*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("ADD; ", TakeCommandSummary());
1131*6777b538SAndroid Build Coastguard Worker }
1132*6777b538SAndroid Build Coastguard Worker 
TEST_F(DeferredCookieTaskTest,DeferredSetAllCookies)1133*6777b538SAndroid Build Coastguard Worker TEST_F(DeferredCookieTaskTest, DeferredSetAllCookies) {
1134*6777b538SAndroid Build Coastguard Worker   // Generate puts to store w/o needing a proper expiration.
1135*6777b538SAndroid Build Coastguard Worker   cookie_monster_->SetPersistSessionCookies(true);
1136*6777b538SAndroid Build Coastguard Worker 
1137*6777b538SAndroid Build Coastguard Worker   CookieList list;
1138*6777b538SAndroid Build Coastguard Worker   list.push_back(*CanonicalCookie::CreateUnsafeCookieForTesting(
1139*6777b538SAndroid Build Coastguard Worker       "A", "B", "." + http_www_foo_.domain(), "/", base::Time::Now(),
1140*6777b538SAndroid Build Coastguard Worker       base::Time(), base::Time(), base::Time(), false, true,
1141*6777b538SAndroid Build Coastguard Worker       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT));
1142*6777b538SAndroid Build Coastguard Worker   list.push_back(*CanonicalCookie::CreateUnsafeCookieForTesting(
1143*6777b538SAndroid Build Coastguard Worker       "C", "D", "." + http_www_foo_.domain(), "/", base::Time::Now(),
1144*6777b538SAndroid Build Coastguard Worker       base::Time(), base::Time(), base::Time(), false, true,
1145*6777b538SAndroid Build Coastguard Worker       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT));
1146*6777b538SAndroid Build Coastguard Worker 
1147*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<CookieAccessResult> call1;
1148*6777b538SAndroid Build Coastguard Worker   cookie_monster_->SetAllCookiesAsync(list, call1.MakeCallback());
1149*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
1150*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(call1.was_run());
1151*6777b538SAndroid Build Coastguard Worker 
1152*6777b538SAndroid Build Coastguard Worker   ExecuteLoads(CookieStoreCommand::LOAD);
1153*6777b538SAndroid Build Coastguard Worker   call1.WaitUntilDone();
1154*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(call1.result().status.IsInclude());
1155*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("LOAD; ADD; ADD; ", TakeCommandSummary());
1156*6777b538SAndroid Build Coastguard Worker 
1157*6777b538SAndroid Build Coastguard Worker   // 2nd set doesn't need to read from store. It erases the old cookies, though.
1158*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<CookieAccessResult> call2;
1159*6777b538SAndroid Build Coastguard Worker   cookie_monster_->SetAllCookiesAsync(list, call2.MakeCallback());
1160*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(call2.was_run());
1161*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(call2.result().status.IsInclude());
1162*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("REMOVE; REMOVE; ADD; ADD; ", TakeCommandSummary());
1163*6777b538SAndroid Build Coastguard Worker }
1164*6777b538SAndroid Build Coastguard Worker 
TEST_F(DeferredCookieTaskTest,DeferredGetAllCookies)1165*6777b538SAndroid Build Coastguard Worker TEST_F(DeferredCookieTaskTest, DeferredGetAllCookies) {
1166*6777b538SAndroid Build Coastguard Worker   DeclareLoadedCookie(http_www_foo_.url(),
1167*6777b538SAndroid Build Coastguard Worker                       "X=1; path=/" + FutureCookieExpirationString(),
1168*6777b538SAndroid Build Coastguard Worker                       Time::Now() + base::Days(3));
1169*6777b538SAndroid Build Coastguard Worker 
1170*6777b538SAndroid Build Coastguard Worker   GetAllCookiesCallback call1;
1171*6777b538SAndroid Build Coastguard Worker   cookie_monster_->GetAllCookiesAsync(call1.MakeCallback());
1172*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
1173*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(call1.was_run());
1174*6777b538SAndroid Build Coastguard Worker 
1175*6777b538SAndroid Build Coastguard Worker   ExecuteLoads(CookieStoreCommand::LOAD);
1176*6777b538SAndroid Build Coastguard Worker   call1.WaitUntilDone();
1177*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(call1.cookies(), MatchesCookieLine("X=1"));
1178*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("LOAD; ", TakeCommandSummary());
1179*6777b538SAndroid Build Coastguard Worker 
1180*6777b538SAndroid Build Coastguard Worker   GetAllCookiesCallback call2;
1181*6777b538SAndroid Build Coastguard Worker   cookie_monster_->GetAllCookiesAsync(call2.MakeCallback());
1182*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(call2.was_run());
1183*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(call2.cookies(), MatchesCookieLine("X=1"));
1184*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("", TakeCommandSummary());
1185*6777b538SAndroid Build Coastguard Worker }
1186*6777b538SAndroid Build Coastguard Worker 
TEST_F(DeferredCookieTaskTest,DeferredGetAllForUrlCookies)1187*6777b538SAndroid Build Coastguard Worker TEST_F(DeferredCookieTaskTest, DeferredGetAllForUrlCookies) {
1188*6777b538SAndroid Build Coastguard Worker   DeclareLoadedCookie(http_www_foo_.url(),
1189*6777b538SAndroid Build Coastguard Worker                       "X=1; path=/" + FutureCookieExpirationString(),
1190*6777b538SAndroid Build Coastguard Worker                       Time::Now() + base::Days(3));
1191*6777b538SAndroid Build Coastguard Worker 
1192*6777b538SAndroid Build Coastguard Worker   GetCookieListCallback call1;
1193*6777b538SAndroid Build Coastguard Worker   cookie_monster_->GetCookieListWithOptionsAsync(
1194*6777b538SAndroid Build Coastguard Worker       http_www_foo_.url(), CookieOptions::MakeAllInclusive(),
1195*6777b538SAndroid Build Coastguard Worker       CookiePartitionKeyCollection(), call1.MakeCallback());
1196*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
1197*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(call1.was_run());
1198*6777b538SAndroid Build Coastguard Worker 
1199*6777b538SAndroid Build Coastguard Worker   ExecuteLoads(CookieStoreCommand::LOAD_COOKIES_FOR_KEY);
1200*6777b538SAndroid Build Coastguard Worker   call1.WaitUntilDone();
1201*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(call1.cookies(), MatchesCookieLine("X=1"));
1202*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("LOAD; LOAD_FOR_KEY:foo.com; ", TakeCommandSummary());
1203*6777b538SAndroid Build Coastguard Worker 
1204*6777b538SAndroid Build Coastguard Worker   GetCookieListCallback call2;
1205*6777b538SAndroid Build Coastguard Worker   cookie_monster_->GetCookieListWithOptionsAsync(
1206*6777b538SAndroid Build Coastguard Worker       http_www_foo_.url(), CookieOptions::MakeAllInclusive(),
1207*6777b538SAndroid Build Coastguard Worker       CookiePartitionKeyCollection(), call2.MakeCallback());
1208*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(call2.was_run());
1209*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(call2.cookies(), MatchesCookieLine("X=1"));
1210*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("", TakeCommandSummary());
1211*6777b538SAndroid Build Coastguard Worker }
1212*6777b538SAndroid Build Coastguard Worker 
TEST_F(DeferredCookieTaskTest,DeferredGetAllForUrlWithOptionsCookies)1213*6777b538SAndroid Build Coastguard Worker TEST_F(DeferredCookieTaskTest, DeferredGetAllForUrlWithOptionsCookies) {
1214*6777b538SAndroid Build Coastguard Worker   DeclareLoadedCookie(http_www_foo_.url(),
1215*6777b538SAndroid Build Coastguard Worker                       "X=1; path=/" + FutureCookieExpirationString(),
1216*6777b538SAndroid Build Coastguard Worker                       Time::Now() + base::Days(3));
1217*6777b538SAndroid Build Coastguard Worker 
1218*6777b538SAndroid Build Coastguard Worker   GetCookieListCallback call1;
1219*6777b538SAndroid Build Coastguard Worker   cookie_monster_->GetCookieListWithOptionsAsync(
1220*6777b538SAndroid Build Coastguard Worker       http_www_foo_.url(), CookieOptions::MakeAllInclusive(),
1221*6777b538SAndroid Build Coastguard Worker       CookiePartitionKeyCollection(), call1.MakeCallback());
1222*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
1223*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(call1.was_run());
1224*6777b538SAndroid Build Coastguard Worker 
1225*6777b538SAndroid Build Coastguard Worker   ExecuteLoads(CookieStoreCommand::LOAD_COOKIES_FOR_KEY);
1226*6777b538SAndroid Build Coastguard Worker   call1.WaitUntilDone();
1227*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(call1.cookies(), MatchesCookieLine("X=1"));
1228*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("LOAD; LOAD_FOR_KEY:foo.com; ", TakeCommandSummary());
1229*6777b538SAndroid Build Coastguard Worker 
1230*6777b538SAndroid Build Coastguard Worker   GetCookieListCallback call2;
1231*6777b538SAndroid Build Coastguard Worker   cookie_monster_->GetCookieListWithOptionsAsync(
1232*6777b538SAndroid Build Coastguard Worker       http_www_foo_.url(), CookieOptions::MakeAllInclusive(),
1233*6777b538SAndroid Build Coastguard Worker       CookiePartitionKeyCollection(), call2.MakeCallback());
1234*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(call2.was_run());
1235*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(call2.cookies(), MatchesCookieLine("X=1"));
1236*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("", TakeCommandSummary());
1237*6777b538SAndroid Build Coastguard Worker }
1238*6777b538SAndroid Build Coastguard Worker 
TEST_F(DeferredCookieTaskTest,DeferredDeleteAllCookies)1239*6777b538SAndroid Build Coastguard Worker TEST_F(DeferredCookieTaskTest, DeferredDeleteAllCookies) {
1240*6777b538SAndroid Build Coastguard Worker   DeclareLoadedCookie(http_www_foo_.url(),
1241*6777b538SAndroid Build Coastguard Worker                       "X=1; path=/" + FutureCookieExpirationString(),
1242*6777b538SAndroid Build Coastguard Worker                       Time::Now() + base::Days(3));
1243*6777b538SAndroid Build Coastguard Worker 
1244*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<uint32_t> call1;
1245*6777b538SAndroid Build Coastguard Worker   cookie_monster_->DeleteAllAsync(call1.MakeCallback());
1246*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
1247*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(call1.was_run());
1248*6777b538SAndroid Build Coastguard Worker 
1249*6777b538SAndroid Build Coastguard Worker   ExecuteLoads(CookieStoreCommand::LOAD);
1250*6777b538SAndroid Build Coastguard Worker   call1.WaitUntilDone();
1251*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, call1.result());
1252*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("LOAD; REMOVE; ", TakeCommandSummary());
1253*6777b538SAndroid Build Coastguard Worker 
1254*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<uint32_t> call2;
1255*6777b538SAndroid Build Coastguard Worker   cookie_monster_->DeleteAllAsync(call2.MakeCallback());
1256*6777b538SAndroid Build Coastguard Worker   // This needs an event loop spin since DeleteAllAsync always reports
1257*6777b538SAndroid Build Coastguard Worker   // asynchronously.
1258*6777b538SAndroid Build Coastguard Worker   call2.WaitUntilDone();
1259*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, call2.result());
1260*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("", TakeCommandSummary());
1261*6777b538SAndroid Build Coastguard Worker }
1262*6777b538SAndroid Build Coastguard Worker 
TEST_F(DeferredCookieTaskTest,DeferredDeleteAllCreatedInTimeRangeCookies)1263*6777b538SAndroid Build Coastguard Worker TEST_F(DeferredCookieTaskTest, DeferredDeleteAllCreatedInTimeRangeCookies) {
1264*6777b538SAndroid Build Coastguard Worker   const TimeRange time_range(base::Time(), base::Time::Now());
1265*6777b538SAndroid Build Coastguard Worker 
1266*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<uint32_t> call1;
1267*6777b538SAndroid Build Coastguard Worker   cookie_monster_->DeleteAllCreatedInTimeRangeAsync(time_range,
1268*6777b538SAndroid Build Coastguard Worker                                                     call1.MakeCallback());
1269*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
1270*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(call1.was_run());
1271*6777b538SAndroid Build Coastguard Worker 
1272*6777b538SAndroid Build Coastguard Worker   ExecuteLoads(CookieStoreCommand::LOAD);
1273*6777b538SAndroid Build Coastguard Worker   call1.WaitUntilDone();
1274*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, call1.result());
1275*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("LOAD; ", TakeCommandSummary());
1276*6777b538SAndroid Build Coastguard Worker 
1277*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<uint32_t> call2;
1278*6777b538SAndroid Build Coastguard Worker   cookie_monster_->DeleteAllCreatedInTimeRangeAsync(time_range,
1279*6777b538SAndroid Build Coastguard Worker                                                     call2.MakeCallback());
1280*6777b538SAndroid Build Coastguard Worker   call2.WaitUntilDone();
1281*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, call2.result());
1282*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("", TakeCommandSummary());
1283*6777b538SAndroid Build Coastguard Worker }
1284*6777b538SAndroid Build Coastguard Worker 
TEST_F(DeferredCookieTaskTest,DeferredDeleteAllWithPredicateCreatedInTimeRangeCookies)1285*6777b538SAndroid Build Coastguard Worker TEST_F(DeferredCookieTaskTest,
1286*6777b538SAndroid Build Coastguard Worker        DeferredDeleteAllWithPredicateCreatedInTimeRangeCookies) {
1287*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<uint32_t> call1;
1288*6777b538SAndroid Build Coastguard Worker   cookie_monster_->DeleteAllMatchingInfoAsync(
1289*6777b538SAndroid Build Coastguard Worker       CookieDeletionInfo(Time(), Time::Now()), call1.MakeCallback());
1290*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
1291*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(call1.was_run());
1292*6777b538SAndroid Build Coastguard Worker 
1293*6777b538SAndroid Build Coastguard Worker   ExecuteLoads(CookieStoreCommand::LOAD);
1294*6777b538SAndroid Build Coastguard Worker   call1.WaitUntilDone();
1295*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, call1.result());
1296*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("LOAD; ", TakeCommandSummary());
1297*6777b538SAndroid Build Coastguard Worker 
1298*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<uint32_t> call2;
1299*6777b538SAndroid Build Coastguard Worker   cookie_monster_->DeleteAllMatchingInfoAsync(
1300*6777b538SAndroid Build Coastguard Worker       CookieDeletionInfo(Time(), Time::Now()), call2.MakeCallback());
1301*6777b538SAndroid Build Coastguard Worker   call2.WaitUntilDone();
1302*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, call2.result());
1303*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("", TakeCommandSummary());
1304*6777b538SAndroid Build Coastguard Worker }
1305*6777b538SAndroid Build Coastguard Worker 
TEST_F(DeferredCookieTaskTest,DeferredDeleteMatchingCookies)1306*6777b538SAndroid Build Coastguard Worker TEST_F(DeferredCookieTaskTest, DeferredDeleteMatchingCookies) {
1307*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<uint32_t> call1;
1308*6777b538SAndroid Build Coastguard Worker   cookie_monster_->DeleteMatchingCookiesAsync(
1309*6777b538SAndroid Build Coastguard Worker       base::BindRepeating(
1310*6777b538SAndroid Build Coastguard Worker           [](const net::CanonicalCookie& cookie) { return true; }),
1311*6777b538SAndroid Build Coastguard Worker       call1.MakeCallback());
1312*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
1313*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(call1.was_run());
1314*6777b538SAndroid Build Coastguard Worker 
1315*6777b538SAndroid Build Coastguard Worker   ExecuteLoads(CookieStoreCommand::LOAD);
1316*6777b538SAndroid Build Coastguard Worker   call1.WaitUntilDone();
1317*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, call1.result());
1318*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("LOAD; ", TakeCommandSummary());
1319*6777b538SAndroid Build Coastguard Worker 
1320*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<uint32_t> call2;
1321*6777b538SAndroid Build Coastguard Worker   cookie_monster_->DeleteMatchingCookiesAsync(
1322*6777b538SAndroid Build Coastguard Worker       base::BindRepeating(
1323*6777b538SAndroid Build Coastguard Worker           [](const net::CanonicalCookie& cookie) { return true; }),
1324*6777b538SAndroid Build Coastguard Worker       call2.MakeCallback());
1325*6777b538SAndroid Build Coastguard Worker   call2.WaitUntilDone();
1326*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, call2.result());
1327*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("", TakeCommandSummary());
1328*6777b538SAndroid Build Coastguard Worker }
1329*6777b538SAndroid Build Coastguard Worker 
TEST_F(DeferredCookieTaskTest,DeferredDeleteCanonicalCookie)1330*6777b538SAndroid Build Coastguard Worker TEST_F(DeferredCookieTaskTest, DeferredDeleteCanonicalCookie) {
1331*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<CanonicalCookie> cookie = BuildCanonicalCookie(
1332*6777b538SAndroid Build Coastguard Worker       http_www_foo_.url(), "X=1; path=/", base::Time::Now());
1333*6777b538SAndroid Build Coastguard Worker 
1334*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<uint32_t> call1;
1335*6777b538SAndroid Build Coastguard Worker   cookie_monster_->DeleteCanonicalCookieAsync(*cookie, call1.MakeCallback());
1336*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
1337*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(call1.was_run());
1338*6777b538SAndroid Build Coastguard Worker 
1339*6777b538SAndroid Build Coastguard Worker   // TODO(morlovich): Fix DeleteCanonicalCookieAsync. This test should pass
1340*6777b538SAndroid Build Coastguard Worker   // when using LOAD_COOKIES_FOR_KEY instead, with that reflected in
1341*6777b538SAndroid Build Coastguard Worker   // TakeCommandSummary() as well.
1342*6777b538SAndroid Build Coastguard Worker   ExecuteLoads(CookieStoreCommand::LOAD);
1343*6777b538SAndroid Build Coastguard Worker   call1.WaitUntilDone();
1344*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, call1.result());
1345*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("LOAD; ", TakeCommandSummary());
1346*6777b538SAndroid Build Coastguard Worker 
1347*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<uint32_t> call2;
1348*6777b538SAndroid Build Coastguard Worker   cookie_monster_->DeleteCanonicalCookieAsync(*cookie, call2.MakeCallback());
1349*6777b538SAndroid Build Coastguard Worker   call2.WaitUntilDone();
1350*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, call2.result());
1351*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("", TakeCommandSummary());
1352*6777b538SAndroid Build Coastguard Worker }
1353*6777b538SAndroid Build Coastguard Worker 
TEST_F(DeferredCookieTaskTest,DeferredDeleteSessionCookies)1354*6777b538SAndroid Build Coastguard Worker TEST_F(DeferredCookieTaskTest, DeferredDeleteSessionCookies) {
1355*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<uint32_t> call1;
1356*6777b538SAndroid Build Coastguard Worker   cookie_monster_->DeleteSessionCookiesAsync(call1.MakeCallback());
1357*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
1358*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(call1.was_run());
1359*6777b538SAndroid Build Coastguard Worker 
1360*6777b538SAndroid Build Coastguard Worker   ExecuteLoads(CookieStoreCommand::LOAD);
1361*6777b538SAndroid Build Coastguard Worker   call1.WaitUntilDone();
1362*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, call1.result());
1363*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("LOAD; ", TakeCommandSummary());
1364*6777b538SAndroid Build Coastguard Worker 
1365*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<uint32_t> call2;
1366*6777b538SAndroid Build Coastguard Worker   cookie_monster_->DeleteSessionCookiesAsync(call2.MakeCallback());
1367*6777b538SAndroid Build Coastguard Worker   call2.WaitUntilDone();
1368*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, call2.result());
1369*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("", TakeCommandSummary());
1370*6777b538SAndroid Build Coastguard Worker }
1371*6777b538SAndroid Build Coastguard Worker 
1372*6777b538SAndroid Build Coastguard Worker // Verify that a series of queued tasks are executed in order upon loading of
1373*6777b538SAndroid Build Coastguard Worker // the backing store and that new tasks received while the queued tasks are
1374*6777b538SAndroid Build Coastguard Worker // being dispatched go to the end of the queue.
TEST_F(DeferredCookieTaskTest,DeferredTaskOrder)1375*6777b538SAndroid Build Coastguard Worker TEST_F(DeferredCookieTaskTest, DeferredTaskOrder) {
1376*6777b538SAndroid Build Coastguard Worker   cookie_monster_->SetPersistSessionCookies(true);
1377*6777b538SAndroid Build Coastguard Worker   DeclareLoadedCookie(http_www_foo_.url(),
1378*6777b538SAndroid Build Coastguard Worker                       "X=1; path=/" + FutureCookieExpirationString(),
1379*6777b538SAndroid Build Coastguard Worker                       Time::Now() + base::Days(3));
1380*6777b538SAndroid Build Coastguard Worker 
1381*6777b538SAndroid Build Coastguard Worker   bool get_cookie_list_callback_was_run = false;
1382*6777b538SAndroid Build Coastguard Worker   GetCookieListCallback get_cookie_list_callback_deferred;
1383*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<CookieAccessResult> set_cookies_callback;
1384*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
1385*6777b538SAndroid Build Coastguard Worker   cookie_monster_->GetCookieListWithOptionsAsync(
1386*6777b538SAndroid Build Coastguard Worker       http_www_foo_.url(), CookieOptions::MakeAllInclusive(),
1387*6777b538SAndroid Build Coastguard Worker       CookiePartitionKeyCollection(),
1388*6777b538SAndroid Build Coastguard Worker       base::BindLambdaForTesting(
1389*6777b538SAndroid Build Coastguard Worker           [&](const CookieAccessResultList& cookies,
1390*6777b538SAndroid Build Coastguard Worker               const CookieAccessResultList& excluded_list) {
1391*6777b538SAndroid Build Coastguard Worker             // This should complete before the set.
1392*6777b538SAndroid Build Coastguard Worker             get_cookie_list_callback_was_run = true;
1393*6777b538SAndroid Build Coastguard Worker             EXPECT_FALSE(set_cookies_callback.was_run());
1394*6777b538SAndroid Build Coastguard Worker             EXPECT_THAT(cookies, MatchesCookieLine("X=1"));
1395*6777b538SAndroid Build Coastguard Worker             // Can't use TakeCommandSummary here since ExecuteLoads is walking
1396*6777b538SAndroid Build Coastguard Worker             // through the data it takes.
1397*6777b538SAndroid Build Coastguard Worker             EXPECT_EQ("LOAD; LOAD_FOR_KEY:foo.com; ",
1398*6777b538SAndroid Build Coastguard Worker                       CommandSummary(persistent_store_->commands()));
1399*6777b538SAndroid Build Coastguard Worker 
1400*6777b538SAndroid Build Coastguard Worker             // Queue up a second get. It should see the result of the set queued
1401*6777b538SAndroid Build Coastguard Worker             // before it.
1402*6777b538SAndroid Build Coastguard Worker             cookie_monster_->GetCookieListWithOptionsAsync(
1403*6777b538SAndroid Build Coastguard Worker                 http_www_foo_.url(), CookieOptions::MakeAllInclusive(),
1404*6777b538SAndroid Build Coastguard Worker                 CookiePartitionKeyCollection(),
1405*6777b538SAndroid Build Coastguard Worker                 get_cookie_list_callback_deferred.MakeCallback());
1406*6777b538SAndroid Build Coastguard Worker 
1407*6777b538SAndroid Build Coastguard Worker             run_loop.Quit();
1408*6777b538SAndroid Build Coastguard Worker           }));
1409*6777b538SAndroid Build Coastguard Worker 
1410*6777b538SAndroid Build Coastguard Worker   cookie_monster_->SetCanonicalCookieAsync(
1411*6777b538SAndroid Build Coastguard Worker       CanonicalCookie::CreateForTesting(http_www_foo_.url(), "A=B",
1412*6777b538SAndroid Build Coastguard Worker                                         base::Time::Now()),
1413*6777b538SAndroid Build Coastguard Worker       http_www_foo_.url(), CookieOptions::MakeAllInclusive(),
1414*6777b538SAndroid Build Coastguard Worker       set_cookies_callback.MakeCallback());
1415*6777b538SAndroid Build Coastguard Worker 
1416*6777b538SAndroid Build Coastguard Worker   // Nothing happened yet, before loads are done.
1417*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
1418*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(get_cookie_list_callback_was_run);
1419*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(set_cookies_callback.was_run());
1420*6777b538SAndroid Build Coastguard Worker 
1421*6777b538SAndroid Build Coastguard Worker   ExecuteLoads(CookieStoreCommand::LOAD_COOKIES_FOR_KEY);
1422*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
1423*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("LOAD; LOAD_FOR_KEY:foo.com; ADD; ", TakeCommandSummary());
1424*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(get_cookie_list_callback_was_run);
1425*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(set_cookies_callback.was_run());
1426*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(set_cookies_callback.result().status.IsInclude());
1427*6777b538SAndroid Build Coastguard Worker 
1428*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(get_cookie_list_callback_deferred.was_run());
1429*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(get_cookie_list_callback_deferred.cookies(),
1430*6777b538SAndroid Build Coastguard Worker               MatchesCookieLine("A=B; X=1"));
1431*6777b538SAndroid Build Coastguard Worker }
1432*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,TestCookieDeleteAll)1433*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, TestCookieDeleteAll) {
1434*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
1435*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
1436*6777b538SAndroid Build Coastguard Worker   CookieOptions options = CookieOptions::MakeAllInclusive();
1437*6777b538SAndroid Build Coastguard Worker 
1438*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), kValidCookieLine));
1439*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("A=B", GetCookies(cm.get(), http_www_foo_.url()));
1440*6777b538SAndroid Build Coastguard Worker 
1441*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookie(cm.get(), http_www_foo_.url(), "C=D; httponly",
1442*6777b538SAndroid Build Coastguard Worker                                  options));
1443*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("A=B; C=D",
1444*6777b538SAndroid Build Coastguard Worker             GetCookiesWithOptions(cm.get(), http_www_foo_.url(), options));
1445*6777b538SAndroid Build Coastguard Worker 
1446*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, DeleteAll(cm.get()));
1447*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("", GetCookiesWithOptions(cm.get(), http_www_foo_.url(), options));
1448*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, store->commands().size());
1449*6777b538SAndroid Build Coastguard Worker 
1450*6777b538SAndroid Build Coastguard Worker   // Create a persistent cookie.
1451*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(),
1452*6777b538SAndroid Build Coastguard Worker                         kValidCookieLine + FutureCookieExpirationString()));
1453*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(1u, store->commands().size());
1454*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[0].type);
1455*6777b538SAndroid Build Coastguard Worker 
1456*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, DeleteAll(cm.get()));  // sync_to_store = true.
1457*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(2u, store->commands().size());
1458*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[1].type);
1459*6777b538SAndroid Build Coastguard Worker 
1460*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("", GetCookiesWithOptions(cm.get(), http_www_foo_.url(), options));
1461*6777b538SAndroid Build Coastguard Worker 
1462*6777b538SAndroid Build Coastguard Worker   // Create a Partitioned cookie.
1463*6777b538SAndroid Build Coastguard Worker   auto cookie_partition_key =
1464*6777b538SAndroid Build Coastguard Worker       CookiePartitionKey::FromURLForTesting(GURL("https://toplevelsite.com"));
1465*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(
1466*6777b538SAndroid Build Coastguard Worker       cm.get(), https_www_foo_.url(),
1467*6777b538SAndroid Build Coastguard Worker       "__Host-" + std::string(kValidCookieLine) + "; partitioned; secure",
1468*6777b538SAndroid Build Coastguard Worker       cookie_partition_key));
1469*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, DeleteAll(cm.get()));
1470*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("", GetCookiesWithOptions(
1471*6777b538SAndroid Build Coastguard Worker                     cm.get(), http_www_foo_.url(), options,
1472*6777b538SAndroid Build Coastguard Worker                     CookiePartitionKeyCollection(cookie_partition_key)));
1473*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, store->commands().size());
1474*6777b538SAndroid Build Coastguard Worker }
1475*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,TestCookieDeleteAllCreatedInTimeRangeTimestamps)1476*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, TestCookieDeleteAllCreatedInTimeRangeTimestamps) {
1477*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
1478*6777b538SAndroid Build Coastguard Worker 
1479*6777b538SAndroid Build Coastguard Worker   Time now = Time::Now();
1480*6777b538SAndroid Build Coastguard Worker 
1481*6777b538SAndroid Build Coastguard Worker   // Nothing has been added so nothing should be deleted.
1482*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, DeleteAllCreatedInTimeRange(
1483*6777b538SAndroid Build Coastguard Worker                     cm.get(), TimeRange(now - base::Days(99), Time())));
1484*6777b538SAndroid Build Coastguard Worker 
1485*6777b538SAndroid Build Coastguard Worker   // Create 5 cookies with different creation dates.
1486*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
1487*6777b538SAndroid Build Coastguard Worker       SetCookieWithCreationTime(cm.get(), http_www_foo_.url(), "T-0=Now", now));
1488*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookieWithCreationTime(cm.get(), http_www_foo_.url(),
1489*6777b538SAndroid Build Coastguard Worker                                         "T-1=Yesterday", now - base::Days(1)));
1490*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookieWithCreationTime(cm.get(), http_www_foo_.url(),
1491*6777b538SAndroid Build Coastguard Worker                                         "T-2=DayBefore", now - base::Days(2)));
1492*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookieWithCreationTime(cm.get(), http_www_foo_.url(),
1493*6777b538SAndroid Build Coastguard Worker                                         "T-3=ThreeDays", now - base::Days(3)));
1494*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookieWithCreationTime(cm.get(), http_www_foo_.url(),
1495*6777b538SAndroid Build Coastguard Worker                                         "T-7=LastWeek", now - base::Days(7)));
1496*6777b538SAndroid Build Coastguard Worker 
1497*6777b538SAndroid Build Coastguard Worker   // Try to delete threedays and the daybefore.
1498*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u,
1499*6777b538SAndroid Build Coastguard Worker             DeleteAllCreatedInTimeRange(
1500*6777b538SAndroid Build Coastguard Worker                 cm.get(), TimeRange(now - base::Days(3), now - base::Days(1))));
1501*6777b538SAndroid Build Coastguard Worker 
1502*6777b538SAndroid Build Coastguard Worker   // Try to delete yesterday, also make sure that delete_end is not
1503*6777b538SAndroid Build Coastguard Worker   // inclusive.
1504*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, DeleteAllCreatedInTimeRange(
1505*6777b538SAndroid Build Coastguard Worker                     cm.get(), TimeRange(now - base::Days(2), now)));
1506*6777b538SAndroid Build Coastguard Worker 
1507*6777b538SAndroid Build Coastguard Worker   // Make sure the delete_begin is inclusive.
1508*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, DeleteAllCreatedInTimeRange(
1509*6777b538SAndroid Build Coastguard Worker                     cm.get(), TimeRange(now - base::Days(7), now)));
1510*6777b538SAndroid Build Coastguard Worker 
1511*6777b538SAndroid Build Coastguard Worker   // Delete the last (now) item.
1512*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, DeleteAllCreatedInTimeRange(cm.get(), TimeRange()));
1513*6777b538SAndroid Build Coastguard Worker 
1514*6777b538SAndroid Build Coastguard Worker   // Really make sure everything is gone.
1515*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, DeleteAll(cm.get()));
1516*6777b538SAndroid Build Coastguard Worker 
1517*6777b538SAndroid Build Coastguard Worker   // Test the same deletion process with partitioned cookies. Partitioned
1518*6777b538SAndroid Build Coastguard Worker   // cookies should behave the same way as unpartitioned cookies here, they are
1519*6777b538SAndroid Build Coastguard Worker   // just stored in a different data structure internally.
1520*6777b538SAndroid Build Coastguard Worker 
1521*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
1522*6777b538SAndroid Build Coastguard Worker       SetCookieWithCreationTime(cm.get(), http_www_foo_.url(), "T-0=Now", now,
1523*6777b538SAndroid Build Coastguard Worker                                 CookiePartitionKey::FromURLForTesting(
1524*6777b538SAndroid Build Coastguard Worker                                     GURL("https://toplevelsite0.com"))));
1525*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookieWithCreationTime(
1526*6777b538SAndroid Build Coastguard Worker       cm.get(), https_www_foo_.url(), "T-1=Yesterday", now - base::Days(1),
1527*6777b538SAndroid Build Coastguard Worker       CookiePartitionKey::FromURLForTesting(
1528*6777b538SAndroid Build Coastguard Worker           GURL("https://toplevelsite1.com"))));
1529*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookieWithCreationTime(
1530*6777b538SAndroid Build Coastguard Worker       cm.get(), http_www_foo_.url(), "T-2=DayBefore", now - base::Days(2),
1531*6777b538SAndroid Build Coastguard Worker       CookiePartitionKey::FromURLForTesting(
1532*6777b538SAndroid Build Coastguard Worker           GURL("https://toplevelsite1.com"))));
1533*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookieWithCreationTime(
1534*6777b538SAndroid Build Coastguard Worker       cm.get(), http_www_foo_.url(), "T-3=ThreeDays", now - base::Days(3),
1535*6777b538SAndroid Build Coastguard Worker       CookiePartitionKey::FromURLForTesting(
1536*6777b538SAndroid Build Coastguard Worker           GURL("https://toplevelsite2.com"))));
1537*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookieWithCreationTime(
1538*6777b538SAndroid Build Coastguard Worker       cm.get(), http_www_foo_.url(), "T-7=LastWeek", now - base::Days(7),
1539*6777b538SAndroid Build Coastguard Worker       CookiePartitionKey::FromURLForTesting(
1540*6777b538SAndroid Build Coastguard Worker           GURL("https://toplevelsite3.com"))));
1541*6777b538SAndroid Build Coastguard Worker 
1542*6777b538SAndroid Build Coastguard Worker   // Try to delete threedays and the daybefore.
1543*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u,
1544*6777b538SAndroid Build Coastguard Worker             DeleteAllCreatedInTimeRange(
1545*6777b538SAndroid Build Coastguard Worker                 cm.get(), TimeRange(now - base::Days(3), now - base::Days(1))));
1546*6777b538SAndroid Build Coastguard Worker 
1547*6777b538SAndroid Build Coastguard Worker   // Try to delete yesterday, also make sure that delete_end is not
1548*6777b538SAndroid Build Coastguard Worker   // inclusive.
1549*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, DeleteAllCreatedInTimeRange(
1550*6777b538SAndroid Build Coastguard Worker                     cm.get(), TimeRange(now - base::Days(2), now)));
1551*6777b538SAndroid Build Coastguard Worker 
1552*6777b538SAndroid Build Coastguard Worker   // Make sure the delete_begin is inclusive.
1553*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, DeleteAllCreatedInTimeRange(
1554*6777b538SAndroid Build Coastguard Worker                     cm.get(), TimeRange(now - base::Days(7), now)));
1555*6777b538SAndroid Build Coastguard Worker 
1556*6777b538SAndroid Build Coastguard Worker   // Delete the last (now) item.
1557*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, DeleteAllCreatedInTimeRange(cm.get(), TimeRange()));
1558*6777b538SAndroid Build Coastguard Worker 
1559*6777b538SAndroid Build Coastguard Worker   // Really make sure everything is gone.
1560*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, DeleteAll(cm.get()));
1561*6777b538SAndroid Build Coastguard Worker }
1562*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,TestCookieDeleteAllCreatedInTimeRangeTimestampsWithInfo)1563*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest,
1564*6777b538SAndroid Build Coastguard Worker        TestCookieDeleteAllCreatedInTimeRangeTimestampsWithInfo) {
1565*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
1566*6777b538SAndroid Build Coastguard Worker 
1567*6777b538SAndroid Build Coastguard Worker   Time now = Time::Now();
1568*6777b538SAndroid Build Coastguard Worker 
1569*6777b538SAndroid Build Coastguard Worker   CanonicalCookie test_cookie;
1570*6777b538SAndroid Build Coastguard Worker 
1571*6777b538SAndroid Build Coastguard Worker   // Nothing has been added so nothing should be deleted.
1572*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u,
1573*6777b538SAndroid Build Coastguard Worker             DeleteAllMatchingInfo(
1574*6777b538SAndroid Build Coastguard Worker                 cm.get(), CookieDeletionInfo(now - base::Days(99), Time())));
1575*6777b538SAndroid Build Coastguard Worker 
1576*6777b538SAndroid Build Coastguard Worker   // Create 5 cookies with different creation dates.
1577*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
1578*6777b538SAndroid Build Coastguard Worker       SetCookieWithCreationTime(cm.get(), http_www_foo_.url(), "T-0=Now", now));
1579*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookieWithCreationTime(cm.get(), http_www_foo_.url(),
1580*6777b538SAndroid Build Coastguard Worker                                         "T-1=Yesterday", now - base::Days(1)));
1581*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookieWithCreationTime(cm.get(), http_www_foo_.url(),
1582*6777b538SAndroid Build Coastguard Worker                                         "T-2=DayBefore", now - base::Days(2)));
1583*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookieWithCreationTime(cm.get(), http_www_foo_.url(),
1584*6777b538SAndroid Build Coastguard Worker                                         "T-3=ThreeDays", now - base::Days(3)));
1585*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookieWithCreationTime(cm.get(), http_www_foo_.url(),
1586*6777b538SAndroid Build Coastguard Worker                                         "T-7=LastWeek", now - base::Days(7)));
1587*6777b538SAndroid Build Coastguard Worker 
1588*6777b538SAndroid Build Coastguard Worker   // Delete threedays and the daybefore.
1589*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, DeleteAllMatchingInfo(cm.get(),
1590*6777b538SAndroid Build Coastguard Worker                                       CookieDeletionInfo(now - base::Days(3),
1591*6777b538SAndroid Build Coastguard Worker                                                          now - base::Days(1))));
1592*6777b538SAndroid Build Coastguard Worker 
1593*6777b538SAndroid Build Coastguard Worker   // Delete yesterday, also make sure that delete_end is not inclusive.
1594*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, DeleteAllMatchingInfo(
1595*6777b538SAndroid Build Coastguard Worker                     cm.get(), CookieDeletionInfo(now - base::Days(2), now)));
1596*6777b538SAndroid Build Coastguard Worker 
1597*6777b538SAndroid Build Coastguard Worker   // Make sure the delete_begin is inclusive.
1598*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, DeleteAllMatchingInfo(
1599*6777b538SAndroid Build Coastguard Worker                     cm.get(), CookieDeletionInfo(now - base::Days(7), now)));
1600*6777b538SAndroid Build Coastguard Worker 
1601*6777b538SAndroid Build Coastguard Worker   // Delete the last (now) item.
1602*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, DeleteAllMatchingInfo(cm.get(), CookieDeletionInfo()));
1603*6777b538SAndroid Build Coastguard Worker 
1604*6777b538SAndroid Build Coastguard Worker   // Really make sure everything is gone.
1605*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, DeleteAll(cm.get()));
1606*6777b538SAndroid Build Coastguard Worker 
1607*6777b538SAndroid Build Coastguard Worker   // Test the same deletion process with partitioned cookies. Partitioned
1608*6777b538SAndroid Build Coastguard Worker   // cookies should behave the same way as unpartitioned cookies here, they are
1609*6777b538SAndroid Build Coastguard Worker   // just stored in a different data structure internally.
1610*6777b538SAndroid Build Coastguard Worker 
1611*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
1612*6777b538SAndroid Build Coastguard Worker       SetCookieWithCreationTime(cm.get(), http_www_foo_.url(), "T-0=Now", now,
1613*6777b538SAndroid Build Coastguard Worker                                 CookiePartitionKey::FromURLForTesting(
1614*6777b538SAndroid Build Coastguard Worker                                     GURL("https://toplevelsite0.com"))));
1615*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookieWithCreationTime(
1616*6777b538SAndroid Build Coastguard Worker       cm.get(), https_www_foo_.url(), "T-1=Yesterday", now - base::Days(1),
1617*6777b538SAndroid Build Coastguard Worker       CookiePartitionKey::FromURLForTesting(
1618*6777b538SAndroid Build Coastguard Worker           GURL("https://toplevelsite1.com"))));
1619*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookieWithCreationTime(
1620*6777b538SAndroid Build Coastguard Worker       cm.get(), http_www_foo_.url(), "T-2=DayBefore", now - base::Days(2),
1621*6777b538SAndroid Build Coastguard Worker       CookiePartitionKey::FromURLForTesting(
1622*6777b538SAndroid Build Coastguard Worker           GURL("https://toplevelsite1.com"))));
1623*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookieWithCreationTime(
1624*6777b538SAndroid Build Coastguard Worker       cm.get(), http_www_foo_.url(), "T-3=ThreeDays", now - base::Days(3),
1625*6777b538SAndroid Build Coastguard Worker       CookiePartitionKey::FromURLForTesting(
1626*6777b538SAndroid Build Coastguard Worker           GURL("https://toplevelsite2.com"))));
1627*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookieWithCreationTime(
1628*6777b538SAndroid Build Coastguard Worker       cm.get(), http_www_foo_.url(), "T-7=LastWeek", now - base::Days(7),
1629*6777b538SAndroid Build Coastguard Worker       CookiePartitionKey::FromURLForTesting(
1630*6777b538SAndroid Build Coastguard Worker           GURL("https://toplevelsite3.com"))));
1631*6777b538SAndroid Build Coastguard Worker 
1632*6777b538SAndroid Build Coastguard Worker   // Delete threedays and the daybefore.
1633*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, DeleteAllMatchingInfo(cm.get(),
1634*6777b538SAndroid Build Coastguard Worker                                       CookieDeletionInfo(now - base::Days(3),
1635*6777b538SAndroid Build Coastguard Worker                                                          now - base::Days(1))));
1636*6777b538SAndroid Build Coastguard Worker 
1637*6777b538SAndroid Build Coastguard Worker   // Delete yesterday, also make sure that delete_end is not inclusive.
1638*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, DeleteAllMatchingInfo(
1639*6777b538SAndroid Build Coastguard Worker                     cm.get(), CookieDeletionInfo(now - base::Days(2), now)));
1640*6777b538SAndroid Build Coastguard Worker 
1641*6777b538SAndroid Build Coastguard Worker   // Make sure the delete_begin is inclusive.
1642*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, DeleteAllMatchingInfo(
1643*6777b538SAndroid Build Coastguard Worker                     cm.get(), CookieDeletionInfo(now - base::Days(7), now)));
1644*6777b538SAndroid Build Coastguard Worker 
1645*6777b538SAndroid Build Coastguard Worker   // Delete the last (now) item.
1646*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, DeleteAllMatchingInfo(cm.get(), CookieDeletionInfo()));
1647*6777b538SAndroid Build Coastguard Worker 
1648*6777b538SAndroid Build Coastguard Worker   // Really make sure everything is gone.
1649*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, DeleteAll(cm.get()));
1650*6777b538SAndroid Build Coastguard Worker }
1651*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,TestCookieDeleteMatchingCookies)1652*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, TestCookieDeleteMatchingCookies) {
1653*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
1654*6777b538SAndroid Build Coastguard Worker   Time now = Time::Now();
1655*6777b538SAndroid Build Coastguard Worker 
1656*6777b538SAndroid Build Coastguard Worker   // Nothing has been added so nothing should be deleted.
1657*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, DeleteMatchingCookies(
1658*6777b538SAndroid Build Coastguard Worker                     cm.get(),
1659*6777b538SAndroid Build Coastguard Worker                     base::BindRepeating([](const net::CanonicalCookie& cookie) {
1660*6777b538SAndroid Build Coastguard Worker                       return true;
1661*6777b538SAndroid Build Coastguard Worker                     })));
1662*6777b538SAndroid Build Coastguard Worker 
1663*6777b538SAndroid Build Coastguard Worker   // Create 5 cookies with different domains and security status.
1664*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookieWithCreationTime(cm.get(), GURL("https://a.com"),
1665*6777b538SAndroid Build Coastguard Worker                                         "a1=1;Secure", now));
1666*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
1667*6777b538SAndroid Build Coastguard Worker       SetCookieWithCreationTime(cm.get(), GURL("https://a.com"), "a2=2", now));
1668*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookieWithCreationTime(cm.get(), GURL("https://b.com"),
1669*6777b538SAndroid Build Coastguard Worker                                         "b1=1;Secure", now));
1670*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
1671*6777b538SAndroid Build Coastguard Worker       SetCookieWithCreationTime(cm.get(), GURL("http://b.com"), "b2=2", now));
1672*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookieWithCreationTime(cm.get(), GURL("https://c.com"),
1673*6777b538SAndroid Build Coastguard Worker                                         "c1=1;Secure", now));
1674*6777b538SAndroid Build Coastguard Worker 
1675*6777b538SAndroid Build Coastguard Worker   // Set a partitioned cookie.
1676*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookieWithCreationTime(
1677*6777b538SAndroid Build Coastguard Worker       cm.get(), GURL("https://d.com"),
1678*6777b538SAndroid Build Coastguard Worker       "__Host-pc=123; path=/; secure; partitioned", now,
1679*6777b538SAndroid Build Coastguard Worker       CookiePartitionKey::FromURLForTesting(GURL("https://e.com"))));
1680*6777b538SAndroid Build Coastguard Worker 
1681*6777b538SAndroid Build Coastguard Worker   // Delete http cookies.
1682*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, DeleteMatchingCookies(
1683*6777b538SAndroid Build Coastguard Worker                     cm.get(),
1684*6777b538SAndroid Build Coastguard Worker                     base::BindRepeating([](const net::CanonicalCookie& cookie) {
1685*6777b538SAndroid Build Coastguard Worker                       return !cookie.SecureAttribute();
1686*6777b538SAndroid Build Coastguard Worker                     })));
1687*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(GetAllCookies(cm.get()),
1688*6777b538SAndroid Build Coastguard Worker               ElementsAre(MatchesCookieNameDomain("a1", "a.com"),
1689*6777b538SAndroid Build Coastguard Worker                           MatchesCookieNameDomain("b1", "b.com"),
1690*6777b538SAndroid Build Coastguard Worker                           MatchesCookieNameDomain("c1", "c.com"),
1691*6777b538SAndroid Build Coastguard Worker                           MatchesCookieNameDomain("__Host-pc", "d.com")));
1692*6777b538SAndroid Build Coastguard Worker 
1693*6777b538SAndroid Build Coastguard Worker   // Delete remaining cookie for a.com.
1694*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, DeleteMatchingCookies(
1695*6777b538SAndroid Build Coastguard Worker                     cm.get(),
1696*6777b538SAndroid Build Coastguard Worker                     base::BindRepeating([](const net::CanonicalCookie& cookie) {
1697*6777b538SAndroid Build Coastguard Worker                       return cookie.Domain() == "a.com";
1698*6777b538SAndroid Build Coastguard Worker                     })));
1699*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(GetAllCookies(cm.get()),
1700*6777b538SAndroid Build Coastguard Worker               ElementsAre(MatchesCookieNameDomain("b1", "b.com"),
1701*6777b538SAndroid Build Coastguard Worker                           MatchesCookieNameDomain("c1", "c.com"),
1702*6777b538SAndroid Build Coastguard Worker                           MatchesCookieNameDomain("__Host-pc", "d.com")));
1703*6777b538SAndroid Build Coastguard Worker 
1704*6777b538SAndroid Build Coastguard Worker   // Delete the partitioned cookie.
1705*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, DeleteMatchingCookies(
1706*6777b538SAndroid Build Coastguard Worker                     cm.get(),
1707*6777b538SAndroid Build Coastguard Worker                     base::BindRepeating([](const net::CanonicalCookie& cookie) {
1708*6777b538SAndroid Build Coastguard Worker                       return cookie.IsPartitioned();
1709*6777b538SAndroid Build Coastguard Worker                     })));
1710*6777b538SAndroid Build Coastguard Worker 
1711*6777b538SAndroid Build Coastguard Worker   // Delete the last two item.
1712*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, DeleteMatchingCookies(
1713*6777b538SAndroid Build Coastguard Worker                     cm.get(),
1714*6777b538SAndroid Build Coastguard Worker                     base::BindRepeating([](const net::CanonicalCookie& cookie) {
1715*6777b538SAndroid Build Coastguard Worker                       return true;
1716*6777b538SAndroid Build Coastguard Worker                     })));
1717*6777b538SAndroid Build Coastguard Worker 
1718*6777b538SAndroid Build Coastguard Worker   // Really make sure everything is gone.
1719*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(GetAllCookies(cm.get()).empty());
1720*6777b538SAndroid Build Coastguard Worker }
1721*6777b538SAndroid Build Coastguard Worker 
1722*6777b538SAndroid Build Coastguard Worker static const base::TimeDelta kLastAccessThreshold = base::Milliseconds(200);
1723*6777b538SAndroid Build Coastguard Worker static const base::TimeDelta kAccessDelay =
1724*6777b538SAndroid Build Coastguard Worker     kLastAccessThreshold + base::Milliseconds(20);
1725*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,TestLastAccess)1726*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, TestLastAccess) {
1727*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, kLastAccessThreshold,
1728*6777b538SAndroid Build Coastguard Worker                                             net::NetLog::Get());
1729*6777b538SAndroid Build Coastguard Worker 
1730*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), "A=B"));
1731*6777b538SAndroid Build Coastguard Worker   const Time last_access_date(GetFirstCookieAccessDate(cm.get()));
1732*6777b538SAndroid Build Coastguard Worker 
1733*6777b538SAndroid Build Coastguard Worker   // Reading the cookie again immediately shouldn't update the access date,
1734*6777b538SAndroid Build Coastguard Worker   // since we're inside the threshold.
1735*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("A=B", GetCookies(cm.get(), http_www_foo_.url()));
1736*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(last_access_date, GetFirstCookieAccessDate(cm.get()));
1737*6777b538SAndroid Build Coastguard Worker 
1738*6777b538SAndroid Build Coastguard Worker   // Reading after a short wait will update the access date, if the cookie
1739*6777b538SAndroid Build Coastguard Worker   // is requested with options that would update the access date. First, test
1740*6777b538SAndroid Build Coastguard Worker   // that the flag's behavior is respected.
1741*6777b538SAndroid Build Coastguard Worker   base::PlatformThread::Sleep(kAccessDelay);
1742*6777b538SAndroid Build Coastguard Worker   CookieOptions options = CookieOptions::MakeAllInclusive();
1743*6777b538SAndroid Build Coastguard Worker   options.set_do_not_update_access_time();
1744*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("A=B",
1745*6777b538SAndroid Build Coastguard Worker             GetCookiesWithOptions(cm.get(), http_www_foo_.url(), options));
1746*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(last_access_date, GetFirstCookieAccessDate(cm.get()));
1747*6777b538SAndroid Build Coastguard Worker 
1748*6777b538SAndroid Build Coastguard Worker   // Getting all cookies for a URL doesn't update the accessed time either.
1749*6777b538SAndroid Build Coastguard Worker   CookieList cookies = GetAllCookiesForURL(cm.get(), http_www_foo_.url());
1750*6777b538SAndroid Build Coastguard Worker   auto it = cookies.begin();
1751*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(it != cookies.end());
1752*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(http_www_foo_.host(), it->Domain());
1753*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("A", it->Name());
1754*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("B", it->Value());
1755*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(last_access_date, GetFirstCookieAccessDate(cm.get()));
1756*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(++it == cookies.end());
1757*6777b538SAndroid Build Coastguard Worker 
1758*6777b538SAndroid Build Coastguard Worker   // If the flag isn't set, the last accessed time should be updated.
1759*6777b538SAndroid Build Coastguard Worker   options.set_update_access_time();
1760*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("A=B",
1761*6777b538SAndroid Build Coastguard Worker             GetCookiesWithOptions(cm.get(), http_www_foo_.url(), options));
1762*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(last_access_date == GetFirstCookieAccessDate(cm.get()));
1763*6777b538SAndroid Build Coastguard Worker }
1764*6777b538SAndroid Build Coastguard Worker 
TEST_P(CookieMonsterTestPriorityGarbageCollectionObc,TestHostGarbageCollection)1765*6777b538SAndroid Build Coastguard Worker TEST_P(CookieMonsterTestPriorityGarbageCollectionObc,
1766*6777b538SAndroid Build Coastguard Worker        TestHostGarbageCollection) {
1767*6777b538SAndroid Build Coastguard Worker   TestHostGarbageCollectHelper();
1768*6777b538SAndroid Build Coastguard Worker }
1769*6777b538SAndroid Build Coastguard Worker 
TEST_P(CookieMonsterTestPriorityGarbageCollectionObc,TestPriorityAwareGarbageCollectionNonSecure)1770*6777b538SAndroid Build Coastguard Worker TEST_P(CookieMonsterTestPriorityGarbageCollectionObc,
1771*6777b538SAndroid Build Coastguard Worker        TestPriorityAwareGarbageCollectionNonSecure) {
1772*6777b538SAndroid Build Coastguard Worker   TestPriorityAwareGarbageCollectHelperNonSecure();
1773*6777b538SAndroid Build Coastguard Worker }
1774*6777b538SAndroid Build Coastguard Worker 
TEST_P(CookieMonsterTestPriorityGarbageCollectionObc,TestPriorityAwareGarbageCollectionSecure)1775*6777b538SAndroid Build Coastguard Worker TEST_P(CookieMonsterTestPriorityGarbageCollectionObc,
1776*6777b538SAndroid Build Coastguard Worker        TestPriorityAwareGarbageCollectionSecure) {
1777*6777b538SAndroid Build Coastguard Worker   TestPriorityAwareGarbageCollectHelperSecure();
1778*6777b538SAndroid Build Coastguard Worker }
1779*6777b538SAndroid Build Coastguard Worker 
TEST_P(CookieMonsterTestPriorityGarbageCollectionObc,TestPriorityAwareGarbageCollectionMixed)1780*6777b538SAndroid Build Coastguard Worker TEST_P(CookieMonsterTestPriorityGarbageCollectionObc,
1781*6777b538SAndroid Build Coastguard Worker        TestPriorityAwareGarbageCollectionMixed) {
1782*6777b538SAndroid Build Coastguard Worker   TestPriorityAwareGarbageCollectHelperMixed();
1783*6777b538SAndroid Build Coastguard Worker }
1784*6777b538SAndroid Build Coastguard Worker 
1785*6777b538SAndroid Build Coastguard Worker // Test that domain cookies are always deleted before host cookies for a given
1786*6777b538SAndroid Build Coastguard Worker // {priority, secureness}. In this case, default priority and secure.
TEST_P(CookieMonsterTestGarbageCollectionObc,DomainCookiesPreferred)1787*6777b538SAndroid Build Coastguard Worker TEST_P(CookieMonsterTestGarbageCollectionObc, DomainCookiesPreferred) {
1788*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(cookie_util::IsOriginBoundCookiesPartiallyEnabled());
1789*6777b538SAndroid Build Coastguard Worker   // This test requires the following values.
1790*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(180U, CookieMonster::kDomainMaxCookies);
1791*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(150U, CookieMonster::kDomainMaxCookies -
1792*6777b538SAndroid Build Coastguard Worker                       CookieMonster::kDomainPurgeCookies);
1793*6777b538SAndroid Build Coastguard Worker 
1794*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
1795*6777b538SAndroid Build Coastguard Worker 
1796*6777b538SAndroid Build Coastguard Worker   // Insert an extra host cookie so that one will need to be deleted;
1797*6777b538SAndroid Build Coastguard Worker   // demonstrating that host cookies will still be deleted if need be but they
1798*6777b538SAndroid Build Coastguard Worker   // aren't preferred.
1799*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < 151; i++) {
1800*6777b538SAndroid Build Coastguard Worker     std::string cookie = "host_" + base::NumberToString(i) + "=foo; Secure";
1801*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(SetCookie(cm.get(), https_www_foo_.url(), cookie));
1802*6777b538SAndroid Build Coastguard Worker   }
1803*6777b538SAndroid Build Coastguard Worker 
1804*6777b538SAndroid Build Coastguard Worker   // By adding the domain cookies after the host cookies they are more recently
1805*6777b538SAndroid Build Coastguard Worker   // accessed, which would normally cause these cookies to be preserved. By
1806*6777b538SAndroid Build Coastguard Worker   // showing that they're still deleted before the host cookies we can
1807*6777b538SAndroid Build Coastguard Worker   // demonstrate that domain cookies are preferred for deletion.
1808*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < 30; i++) {
1809*6777b538SAndroid Build Coastguard Worker     std::string cookie = "domain_" + base::NumberToString(i) +
1810*6777b538SAndroid Build Coastguard Worker                          "=foo; Secure; Domain=" + https_www_foo_.domain();
1811*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(SetCookie(cm.get(), https_www_foo_.url(), cookie));
1812*6777b538SAndroid Build Coastguard Worker   }
1813*6777b538SAndroid Build Coastguard Worker 
1814*6777b538SAndroid Build Coastguard Worker   auto cookie_list = this->GetAllCookiesForURL(cm.get(), https_www_foo_.url());
1815*6777b538SAndroid Build Coastguard Worker 
1816*6777b538SAndroid Build Coastguard Worker   int domain_count = 0;
1817*6777b538SAndroid Build Coastguard Worker   int host_count = 0;
1818*6777b538SAndroid Build Coastguard Worker   for (const auto& cookie : cookie_list) {
1819*6777b538SAndroid Build Coastguard Worker     if (cookie.IsHostCookie()) {
1820*6777b538SAndroid Build Coastguard Worker       host_count++;
1821*6777b538SAndroid Build Coastguard Worker     } else {
1822*6777b538SAndroid Build Coastguard Worker       domain_count++;
1823*6777b538SAndroid Build Coastguard Worker     }
1824*6777b538SAndroid Build Coastguard Worker   }
1825*6777b538SAndroid Build Coastguard Worker 
1826*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(host_count, 150);
1827*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(domain_count, 0);
1828*6777b538SAndroid Build Coastguard Worker }
1829*6777b538SAndroid Build Coastguard Worker 
1830*6777b538SAndroid Build Coastguard Worker // Securely set cookies should always be deleted after non-securely set cookies.
TEST_P(CookieMonsterTestGarbageCollectionObc,SecureCookiesPreferred)1831*6777b538SAndroid Build Coastguard Worker TEST_P(CookieMonsterTestGarbageCollectionObc, SecureCookiesPreferred) {
1832*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(cookie_util::IsOriginBoundCookiesPartiallyEnabled());
1833*6777b538SAndroid Build Coastguard Worker   // This test requires the following values.
1834*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(180U, CookieMonster::kDomainMaxCookies);
1835*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(150U, CookieMonster::kDomainMaxCookies -
1836*6777b538SAndroid Build Coastguard Worker                       CookieMonster::kDomainPurgeCookies);
1837*6777b538SAndroid Build Coastguard Worker 
1838*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
1839*6777b538SAndroid Build Coastguard Worker 
1840*6777b538SAndroid Build Coastguard Worker   // If scheme binding is enabled then the secure url is enough, otherwise we
1841*6777b538SAndroid Build Coastguard Worker   // need to also add "Secure" to the cookie line.
1842*6777b538SAndroid Build Coastguard Worker   std::string secure_attr =
1843*6777b538SAndroid Build Coastguard Worker       cookie_util::IsSchemeBoundCookiesEnabled() ? "" : "; Secure";
1844*6777b538SAndroid Build Coastguard Worker 
1845*6777b538SAndroid Build Coastguard Worker   // These cookies would normally be preferred for deletion because they're 1)
1846*6777b538SAndroid Build Coastguard Worker   // Domain cookies, and 2) they're least recently accessed. But, since they're
1847*6777b538SAndroid Build Coastguard Worker   // securely set they'll be deleted after non-secure cookies.
1848*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < 151; i++) {
1849*6777b538SAndroid Build Coastguard Worker     std::string cookie = "domain_" + base::NumberToString(i) +
1850*6777b538SAndroid Build Coastguard Worker                          "=foo; Domain=" + https_www_foo_.domain() +
1851*6777b538SAndroid Build Coastguard Worker                          secure_attr;
1852*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(SetCookie(cm.get(), https_www_foo_.url(), cookie));
1853*6777b538SAndroid Build Coastguard Worker   }
1854*6777b538SAndroid Build Coastguard Worker 
1855*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < 30; i++) {
1856*6777b538SAndroid Build Coastguard Worker     std::string cookie = "host_" + base::NumberToString(i) + "=foo";
1857*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), cookie));
1858*6777b538SAndroid Build Coastguard Worker   }
1859*6777b538SAndroid Build Coastguard Worker 
1860*6777b538SAndroid Build Coastguard Worker   auto secure_cookie_list =
1861*6777b538SAndroid Build Coastguard Worker       this->GetAllCookiesForURL(cm.get(), https_www_foo_.url());
1862*6777b538SAndroid Build Coastguard Worker   auto insecure_cookie_list =
1863*6777b538SAndroid Build Coastguard Worker       this->GetAllCookiesForURL(cm.get(), http_www_foo_.url());
1864*6777b538SAndroid Build Coastguard Worker 
1865*6777b538SAndroid Build Coastguard Worker   int domain_count = 0;
1866*6777b538SAndroid Build Coastguard Worker   int host_count = 0;
1867*6777b538SAndroid Build Coastguard Worker 
1868*6777b538SAndroid Build Coastguard Worker   for (const auto& cookie : secure_cookie_list) {
1869*6777b538SAndroid Build Coastguard Worker     if (cookie.IsHostCookie()) {
1870*6777b538SAndroid Build Coastguard Worker       host_count++;
1871*6777b538SAndroid Build Coastguard Worker     } else {
1872*6777b538SAndroid Build Coastguard Worker       domain_count++;
1873*6777b538SAndroid Build Coastguard Worker     }
1874*6777b538SAndroid Build Coastguard Worker   }
1875*6777b538SAndroid Build Coastguard Worker 
1876*6777b538SAndroid Build Coastguard Worker   for (const auto& cookie : insecure_cookie_list) {
1877*6777b538SAndroid Build Coastguard Worker     if (cookie.IsHostCookie()) {
1878*6777b538SAndroid Build Coastguard Worker       host_count++;
1879*6777b538SAndroid Build Coastguard Worker     } else {
1880*6777b538SAndroid Build Coastguard Worker       domain_count++;
1881*6777b538SAndroid Build Coastguard Worker     }
1882*6777b538SAndroid Build Coastguard Worker   }
1883*6777b538SAndroid Build Coastguard Worker 
1884*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(host_count, 0);
1885*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(domain_count, 150);
1886*6777b538SAndroid Build Coastguard Worker }
1887*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,TestPartitionedCookiesGarbageCollection_Memory)1888*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, TestPartitionedCookiesGarbageCollection_Memory) {
1889*6777b538SAndroid Build Coastguard Worker   // Limit should be 10 KB.
1890*6777b538SAndroid Build Coastguard Worker   DCHECK_EQ(1024u * 10u, CookieMonster::kPerPartitionDomainMaxCookieBytes);
1891*6777b538SAndroid Build Coastguard Worker 
1892*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
1893*6777b538SAndroid Build Coastguard Worker   auto cookie_partition_key =
1894*6777b538SAndroid Build Coastguard Worker       CookiePartitionKey::FromURLForTesting(GURL("https://toplevelsite1.com"));
1895*6777b538SAndroid Build Coastguard Worker 
1896*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < 41; ++i) {
1897*6777b538SAndroid Build Coastguard Worker     std::string cookie_value((10240 / 40) - (i < 10 ? 1 : 2), '0');
1898*6777b538SAndroid Build Coastguard Worker     std::string cookie =
1899*6777b538SAndroid Build Coastguard Worker         base::StrCat({base::NumberToString(i), "=", cookie_value});
1900*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(SetCookie(cm.get(), https_www_foo_.url(),
1901*6777b538SAndroid Build Coastguard Worker                           cookie + "; secure; path=/; partitioned",
1902*6777b538SAndroid Build Coastguard Worker                           cookie_partition_key))
1903*6777b538SAndroid Build Coastguard Worker         << "Failed to set cookie " << i;
1904*6777b538SAndroid Build Coastguard Worker   }
1905*6777b538SAndroid Build Coastguard Worker 
1906*6777b538SAndroid Build Coastguard Worker   std::string cookies =
1907*6777b538SAndroid Build Coastguard Worker       this->GetCookies(cm.get(), https_www_foo_.url(),
1908*6777b538SAndroid Build Coastguard Worker                        CookiePartitionKeyCollection(cookie_partition_key));
1909*6777b538SAndroid Build Coastguard Worker 
1910*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cookies, CookieStringIs(
1911*6777b538SAndroid Build Coastguard Worker                            testing::Not(testing::Contains(testing::Key("0")))));
1912*6777b538SAndroid Build Coastguard Worker   for (size_t i = 1; i < 41; ++i) {
1913*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(cookies, CookieStringIs(testing::Contains(
1914*6777b538SAndroid Build Coastguard Worker                              testing::Key(base::NumberToString(i)))))
1915*6777b538SAndroid Build Coastguard Worker         << "Failed to find cookie " << i;
1916*6777b538SAndroid Build Coastguard Worker   }
1917*6777b538SAndroid Build Coastguard Worker }
1918*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,TestPartitionedCookiesGarbageCollection_MaxCookies)1919*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, TestPartitionedCookiesGarbageCollection_MaxCookies) {
1920*6777b538SAndroid Build Coastguard Worker   // Partitioned cookies also limit domains to 180 cookies per partition.
1921*6777b538SAndroid Build Coastguard Worker   DCHECK_EQ(180u, CookieMonster::kPerPartitionDomainMaxCookies);
1922*6777b538SAndroid Build Coastguard Worker 
1923*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
1924*6777b538SAndroid Build Coastguard Worker   auto cookie_partition_key =
1925*6777b538SAndroid Build Coastguard Worker       CookiePartitionKey::FromURLForTesting(GURL("https://toplevelsite.com"));
1926*6777b538SAndroid Build Coastguard Worker 
1927*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < 181; ++i) {
1928*6777b538SAndroid Build Coastguard Worker     std::string cookie = base::StrCat({base::NumberToString(i), "=0"});
1929*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(SetCookie(cm.get(), https_www_foo_.url(),
1930*6777b538SAndroid Build Coastguard Worker                           cookie + "; secure; path=/; partitioned",
1931*6777b538SAndroid Build Coastguard Worker                           cookie_partition_key))
1932*6777b538SAndroid Build Coastguard Worker         << "Failed to set cookie " << i;
1933*6777b538SAndroid Build Coastguard Worker   }
1934*6777b538SAndroid Build Coastguard Worker 
1935*6777b538SAndroid Build Coastguard Worker   std::string cookies =
1936*6777b538SAndroid Build Coastguard Worker       this->GetCookies(cm.get(), https_www_foo_.url(),
1937*6777b538SAndroid Build Coastguard Worker                        CookiePartitionKeyCollection(cookie_partition_key));
1938*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cookies, CookieStringIs(
1939*6777b538SAndroid Build Coastguard Worker                            testing::Not(testing::Contains(testing::Key("0")))));
1940*6777b538SAndroid Build Coastguard Worker   for (size_t i = 1; i < 181; ++i) {
1941*6777b538SAndroid Build Coastguard Worker     std::string cookie = base::StrCat({base::NumberToString(i), "=0"});
1942*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(cookies, CookieStringIs(testing::Contains(
1943*6777b538SAndroid Build Coastguard Worker                              testing::Key(base::NumberToString(i)))))
1944*6777b538SAndroid Build Coastguard Worker         << "Failed to find cookie " << i;
1945*6777b538SAndroid Build Coastguard Worker   }
1946*6777b538SAndroid Build Coastguard Worker }
1947*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,SetCookieableSchemes)1948*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, SetCookieableSchemes) {
1949*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
1950*6777b538SAndroid Build Coastguard Worker 
1951*6777b538SAndroid Build Coastguard Worker   auto cm_foo = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
1952*6777b538SAndroid Build Coastguard Worker 
1953*6777b538SAndroid Build Coastguard Worker   // Only cm_foo should allow foo:// cookies.
1954*6777b538SAndroid Build Coastguard Worker   std::vector<std::string> schemes;
1955*6777b538SAndroid Build Coastguard Worker   schemes.push_back("foo");
1956*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<bool> cookie_scheme_callback;
1957*6777b538SAndroid Build Coastguard Worker   cm_foo->SetCookieableSchemes(schemes, cookie_scheme_callback.MakeCallback());
1958*6777b538SAndroid Build Coastguard Worker   cookie_scheme_callback.WaitUntilDone();
1959*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cookie_scheme_callback.result());
1960*6777b538SAndroid Build Coastguard Worker 
1961*6777b538SAndroid Build Coastguard Worker   GURL foo_url("foo://host/path");
1962*6777b538SAndroid Build Coastguard Worker   GURL http_url("http://host/path");
1963*6777b538SAndroid Build Coastguard Worker 
1964*6777b538SAndroid Build Coastguard Worker   base::Time now = base::Time::Now();
1965*6777b538SAndroid Build Coastguard Worker   std::optional<base::Time> server_time = std::nullopt;
1966*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
1967*6777b538SAndroid Build Coastguard Worker       CreateAndSetCookieReturnStatus(cm.get(), http_url, "x=1").IsInclude());
1968*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
1969*6777b538SAndroid Build Coastguard Worker       SetCanonicalCookieReturnAccessResult(
1970*6777b538SAndroid Build Coastguard Worker           cm.get(),
1971*6777b538SAndroid Build Coastguard Worker           CanonicalCookie::CreateForTesting(http_url, "y=1", now, server_time),
1972*6777b538SAndroid Build Coastguard Worker           http_url, false /*modify_httponly*/)
1973*6777b538SAndroid Build Coastguard Worker           .status.IsInclude());
1974*6777b538SAndroid Build Coastguard Worker 
1975*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), foo_url, "x=1")
1976*6777b538SAndroid Build Coastguard Worker                   .HasExactlyExclusionReasonsForTesting(
1977*6777b538SAndroid Build Coastguard Worker                       {CookieInclusionStatus::EXCLUDE_NONCOOKIEABLE_SCHEME}));
1978*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
1979*6777b538SAndroid Build Coastguard Worker       SetCanonicalCookieReturnAccessResult(
1980*6777b538SAndroid Build Coastguard Worker           cm.get(),
1981*6777b538SAndroid Build Coastguard Worker           CanonicalCookie::CreateForTesting(foo_url, "y=1", now, server_time),
1982*6777b538SAndroid Build Coastguard Worker           foo_url, false /*modify_httponly*/)
1983*6777b538SAndroid Build Coastguard Worker           .status.HasExactlyExclusionReasonsForTesting(
1984*6777b538SAndroid Build Coastguard Worker               {CookieInclusionStatus::EXCLUDE_NONCOOKIEABLE_SCHEME}));
1985*6777b538SAndroid Build Coastguard Worker 
1986*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
1987*6777b538SAndroid Build Coastguard Worker       CreateAndSetCookieReturnStatus(cm_foo.get(), foo_url, "x=1").IsInclude());
1988*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
1989*6777b538SAndroid Build Coastguard Worker       SetCanonicalCookieReturnAccessResult(
1990*6777b538SAndroid Build Coastguard Worker           cm_foo.get(),
1991*6777b538SAndroid Build Coastguard Worker           CanonicalCookie::CreateForTesting(foo_url, "y=1", now, server_time),
1992*6777b538SAndroid Build Coastguard Worker           foo_url, false /*modify_httponly*/)
1993*6777b538SAndroid Build Coastguard Worker           .status.IsInclude());
1994*6777b538SAndroid Build Coastguard Worker 
1995*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm_foo.get(), http_url, "x=1")
1996*6777b538SAndroid Build Coastguard Worker                   .HasExactlyExclusionReasonsForTesting(
1997*6777b538SAndroid Build Coastguard Worker                       {CookieInclusionStatus::EXCLUDE_NONCOOKIEABLE_SCHEME}));
1998*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
1999*6777b538SAndroid Build Coastguard Worker       SetCanonicalCookieReturnAccessResult(
2000*6777b538SAndroid Build Coastguard Worker           cm_foo.get(),
2001*6777b538SAndroid Build Coastguard Worker           CanonicalCookie::CreateForTesting(http_url, "y=1", now, server_time),
2002*6777b538SAndroid Build Coastguard Worker           http_url, false /*modify_httponly*/)
2003*6777b538SAndroid Build Coastguard Worker           .status.HasExactlyExclusionReasonsForTesting(
2004*6777b538SAndroid Build Coastguard Worker               {CookieInclusionStatus::EXCLUDE_NONCOOKIEABLE_SCHEME}));
2005*6777b538SAndroid Build Coastguard Worker }
2006*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,SetCookieableSchemes_StoreInitialized)2007*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, SetCookieableSchemes_StoreInitialized) {
2008*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
2009*6777b538SAndroid Build Coastguard Worker   // Initializes the cookie store.
2010*6777b538SAndroid Build Coastguard Worker   this->GetCookies(cm.get(), https_www_foo_.url(),
2011*6777b538SAndroid Build Coastguard Worker                    CookiePartitionKeyCollection());
2012*6777b538SAndroid Build Coastguard Worker 
2013*6777b538SAndroid Build Coastguard Worker   std::vector<std::string> schemes;
2014*6777b538SAndroid Build Coastguard Worker   schemes.push_back("foo");
2015*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<bool> cookie_scheme_callback;
2016*6777b538SAndroid Build Coastguard Worker   cm->SetCookieableSchemes(schemes, cookie_scheme_callback.MakeCallback());
2017*6777b538SAndroid Build Coastguard Worker   cookie_scheme_callback.WaitUntilDone();
2018*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cookie_scheme_callback.result());
2019*6777b538SAndroid Build Coastguard Worker 
2020*6777b538SAndroid Build Coastguard Worker   base::Time now = base::Time::Now();
2021*6777b538SAndroid Build Coastguard Worker   std::optional<base::Time> server_time = std::nullopt;
2022*6777b538SAndroid Build Coastguard Worker   GURL foo_url("foo://host/path");
2023*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
2024*6777b538SAndroid Build Coastguard Worker       SetCanonicalCookieReturnAccessResult(
2025*6777b538SAndroid Build Coastguard Worker           cm.get(),
2026*6777b538SAndroid Build Coastguard Worker           CanonicalCookie::CreateForTesting(foo_url, "y=1", now, server_time),
2027*6777b538SAndroid Build Coastguard Worker           foo_url, false /*modify_httponly*/)
2028*6777b538SAndroid Build Coastguard Worker           .status.HasExactlyExclusionReasonsForTesting(
2029*6777b538SAndroid Build Coastguard Worker               {CookieInclusionStatus::EXCLUDE_NONCOOKIEABLE_SCHEME}));
2030*6777b538SAndroid Build Coastguard Worker }
2031*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,GetAllCookiesForURL)2032*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, GetAllCookiesForURL) {
2033*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, kLastAccessThreshold,
2034*6777b538SAndroid Build Coastguard Worker                                             net::NetLog::Get());
2035*6777b538SAndroid Build Coastguard Worker 
2036*6777b538SAndroid Build Coastguard Worker   // Create an httponly cookie.
2037*6777b538SAndroid Build Coastguard Worker   CookieOptions options = CookieOptions::MakeAllInclusive();
2038*6777b538SAndroid Build Coastguard Worker 
2039*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookie(cm.get(), http_www_foo_.url(), "A=B; httponly",
2040*6777b538SAndroid Build Coastguard Worker                                  options));
2041*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookie(cm.get(), http_www_foo_.url(),
2042*6777b538SAndroid Build Coastguard Worker                                  http_www_foo_.Format("C=D; domain=.%D"),
2043*6777b538SAndroid Build Coastguard Worker                                  options));
2044*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookie(
2045*6777b538SAndroid Build Coastguard Worker       cm.get(), https_www_foo_.url(),
2046*6777b538SAndroid Build Coastguard Worker       http_www_foo_.Format("E=F; domain=.%D; secure"), options));
2047*6777b538SAndroid Build Coastguard Worker 
2048*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookie(cm.get(), http_www_bar_.url(),
2049*6777b538SAndroid Build Coastguard Worker                                  http_www_bar_.Format("G=H; domain=.%D"),
2050*6777b538SAndroid Build Coastguard Worker                                  options));
2051*6777b538SAndroid Build Coastguard Worker 
2052*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookie(
2053*6777b538SAndroid Build Coastguard Worker       cm.get(), https_www_foo_.url(),
2054*6777b538SAndroid Build Coastguard Worker       https_www_foo_.Format("I=J; domain=.%D; secure"), options));
2055*6777b538SAndroid Build Coastguard Worker 
2056*6777b538SAndroid Build Coastguard Worker   // Create partitioned cookies for the same site with some partition key.
2057*6777b538SAndroid Build Coastguard Worker   auto cookie_partition_key1 =
2058*6777b538SAndroid Build Coastguard Worker       CookiePartitionKey::FromURLForTesting(GURL("https://toplevelsite1.com"));
2059*6777b538SAndroid Build Coastguard Worker   auto cookie_partition_key2 =
2060*6777b538SAndroid Build Coastguard Worker       CookiePartitionKey::FromURLForTesting(GURL("https://toplevelsite2.com"));
2061*6777b538SAndroid Build Coastguard Worker   auto cookie_partition_key3 =
2062*6777b538SAndroid Build Coastguard Worker       CookiePartitionKey::FromURLForTesting(GURL("https://toplevelsite3.com"));
2063*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookie(
2064*6777b538SAndroid Build Coastguard Worker       cm.get(), https_www_bar_.url(), "__Host-K=L; secure; path=/; partitioned",
2065*6777b538SAndroid Build Coastguard Worker       options, std::nullopt, std::nullopt, cookie_partition_key1));
2066*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookie(
2067*6777b538SAndroid Build Coastguard Worker       cm.get(), https_www_bar_.url(), "__Host-M=N; secure; path=/; partitioned",
2068*6777b538SAndroid Build Coastguard Worker       options, std::nullopt, std::nullopt, cookie_partition_key2));
2069*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookie(
2070*6777b538SAndroid Build Coastguard Worker       cm.get(), https_www_bar_.url(), "__Host-O=P; secure; path=/; partitioned",
2071*6777b538SAndroid Build Coastguard Worker       options, std::nullopt, std::nullopt, cookie_partition_key3));
2072*6777b538SAndroid Build Coastguard Worker 
2073*6777b538SAndroid Build Coastguard Worker   const Time last_access_date(GetFirstCookieAccessDate(cm.get()));
2074*6777b538SAndroid Build Coastguard Worker 
2075*6777b538SAndroid Build Coastguard Worker   base::PlatformThread::Sleep(kAccessDelay);
2076*6777b538SAndroid Build Coastguard Worker 
2077*6777b538SAndroid Build Coastguard Worker   // Check cookies for url.
2078*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
2079*6777b538SAndroid Build Coastguard Worker       GetAllCookiesForURL(cm.get(), http_www_foo_.url()),
2080*6777b538SAndroid Build Coastguard Worker       ElementsAre(MatchesCookieNameDomain("A", http_www_foo_.host()),
2081*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameDomain("C", http_www_foo_.Format(".%D"))));
2082*6777b538SAndroid Build Coastguard Worker 
2083*6777b538SAndroid Build Coastguard Worker   // Check cookies for url excluding http-only cookies.
2084*6777b538SAndroid Build Coastguard Worker   CookieOptions exclude_httponly = options;
2085*6777b538SAndroid Build Coastguard Worker   exclude_httponly.set_exclude_httponly();
2086*6777b538SAndroid Build Coastguard Worker 
2087*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
2088*6777b538SAndroid Build Coastguard Worker       GetAllCookiesForURLWithOptions(cm.get(), http_www_foo_.url(),
2089*6777b538SAndroid Build Coastguard Worker                                      exclude_httponly),
2090*6777b538SAndroid Build Coastguard Worker       ElementsAre(MatchesCookieNameDomain("C", http_www_foo_.Format(".%D"))));
2091*6777b538SAndroid Build Coastguard Worker 
2092*6777b538SAndroid Build Coastguard Worker   // Test secure cookies.
2093*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
2094*6777b538SAndroid Build Coastguard Worker       GetAllCookiesForURL(cm.get(), https_www_foo_.url()),
2095*6777b538SAndroid Build Coastguard Worker       ElementsAre(MatchesCookieNameDomain("A", http_www_foo_.host()),
2096*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameDomain("C", http_www_foo_.Format(".%D")),
2097*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameDomain("E", http_www_foo_.Format(".%D")),
2098*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameDomain("I", http_www_foo_.Format(".%D"))));
2099*6777b538SAndroid Build Coastguard Worker 
2100*6777b538SAndroid Build Coastguard Worker   // Test reading partitioned cookies for a single partition.
2101*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
2102*6777b538SAndroid Build Coastguard Worker       GetAllCookiesForURL(cm.get(), https_www_bar_.url(),
2103*6777b538SAndroid Build Coastguard Worker                           CookiePartitionKeyCollection(cookie_partition_key1)),
2104*6777b538SAndroid Build Coastguard Worker       ElementsAre(MatchesCookieNameDomain("G", https_www_bar_.Format(".%D")),
2105*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameDomain("__Host-K", https_www_bar_.host())));
2106*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
2107*6777b538SAndroid Build Coastguard Worker       GetAllCookiesForURL(cm.get(), https_www_bar_.url(),
2108*6777b538SAndroid Build Coastguard Worker                           CookiePartitionKeyCollection(cookie_partition_key2)),
2109*6777b538SAndroid Build Coastguard Worker       ElementsAre(MatchesCookieNameDomain("G", https_www_bar_.Format(".%D")),
2110*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameDomain("__Host-M", https_www_bar_.host())));
2111*6777b538SAndroid Build Coastguard Worker 
2112*6777b538SAndroid Build Coastguard Worker   // Test reading partitioned cookies from multiple partitions.
2113*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
2114*6777b538SAndroid Build Coastguard Worker       GetAllCookiesForURL(cm.get(), https_www_bar_.url(),
2115*6777b538SAndroid Build Coastguard Worker                           CookiePartitionKeyCollection(
2116*6777b538SAndroid Build Coastguard Worker                               {cookie_partition_key1, cookie_partition_key2})),
2117*6777b538SAndroid Build Coastguard Worker       ElementsAre(MatchesCookieNameDomain("G", https_www_bar_.Format(".%D")),
2118*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameDomain("__Host-K", https_www_bar_.host()),
2119*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameDomain("__Host-M", https_www_bar_.host())));
2120*6777b538SAndroid Build Coastguard Worker 
2121*6777b538SAndroid Build Coastguard Worker   // Test reading partitioned cookies from every partition.
2122*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
2123*6777b538SAndroid Build Coastguard Worker       GetAllCookiesForURL(cm.get(), https_www_bar_.url(),
2124*6777b538SAndroid Build Coastguard Worker                           CookiePartitionKeyCollection::ContainsAll()),
2125*6777b538SAndroid Build Coastguard Worker       ElementsAre(MatchesCookieNameDomain("G", https_www_bar_.Format(".%D")),
2126*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameDomain("__Host-K", https_www_bar_.host()),
2127*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameDomain("__Host-M", https_www_bar_.host()),
2128*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameDomain("__Host-O", https_www_bar_.host())));
2129*6777b538SAndroid Build Coastguard Worker 
2130*6777b538SAndroid Build Coastguard Worker   // Test excluding partitioned cookies.
2131*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
2132*6777b538SAndroid Build Coastguard Worker       GetAllCookiesForURL(cm.get(), https_www_bar_.url(),
2133*6777b538SAndroid Build Coastguard Worker                           CookiePartitionKeyCollection()),
2134*6777b538SAndroid Build Coastguard Worker       ElementsAre(MatchesCookieNameDomain("G", https_www_bar_.Format(".%D"))));
2135*6777b538SAndroid Build Coastguard Worker 
2136*6777b538SAndroid Build Coastguard Worker   // Reading after a short wait should not update the access date.
2137*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(last_access_date, GetFirstCookieAccessDate(cm.get()));
2138*6777b538SAndroid Build Coastguard Worker }
2139*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,GetExcludedCookiesForURL)2140*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, GetExcludedCookiesForURL) {
2141*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, kLastAccessThreshold,
2142*6777b538SAndroid Build Coastguard Worker                                             net::NetLog::Get());
2143*6777b538SAndroid Build Coastguard Worker 
2144*6777b538SAndroid Build Coastguard Worker   // Create an httponly cookie.
2145*6777b538SAndroid Build Coastguard Worker   CookieOptions options = CookieOptions::MakeAllInclusive();
2146*6777b538SAndroid Build Coastguard Worker 
2147*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookie(cm.get(), http_www_foo_.url(), "A=B; httponly",
2148*6777b538SAndroid Build Coastguard Worker                                  options));
2149*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookie(cm.get(), http_www_foo_.url(),
2150*6777b538SAndroid Build Coastguard Worker                                  http_www_foo_.Format("C=D; domain=.%D"),
2151*6777b538SAndroid Build Coastguard Worker                                  options));
2152*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookie(
2153*6777b538SAndroid Build Coastguard Worker       cm.get(), https_www_foo_.url(),
2154*6777b538SAndroid Build Coastguard Worker       http_www_foo_.Format("E=F; domain=.%D; secure"), options));
2155*6777b538SAndroid Build Coastguard Worker 
2156*6777b538SAndroid Build Coastguard Worker   base::PlatformThread::Sleep(kAccessDelay);
2157*6777b538SAndroid Build Coastguard Worker 
2158*6777b538SAndroid Build Coastguard Worker   // Check that no cookies are sent when option is turned off
2159*6777b538SAndroid Build Coastguard Worker   CookieOptions do_not_return_excluded;
2160*6777b538SAndroid Build Coastguard Worker   do_not_return_excluded.unset_return_excluded_cookies();
2161*6777b538SAndroid Build Coastguard Worker 
2162*6777b538SAndroid Build Coastguard Worker   CookieAccessResultList excluded_cookies = GetExcludedCookiesForURLWithOptions(
2163*6777b538SAndroid Build Coastguard Worker       cm.get(), http_www_foo_.url(), do_not_return_excluded);
2164*6777b538SAndroid Build Coastguard Worker   auto iter = excluded_cookies.begin();
2165*6777b538SAndroid Build Coastguard Worker 
2166*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(excluded_cookies.empty());
2167*6777b538SAndroid Build Coastguard Worker 
2168*6777b538SAndroid Build Coastguard Worker   // Checking that excluded cookies get sent with their statuses with http
2169*6777b538SAndroid Build Coastguard Worker   // request.
2170*6777b538SAndroid Build Coastguard Worker   excluded_cookies = GetExcludedCookiesForURL(cm.get(), http_www_foo_.url(),
2171*6777b538SAndroid Build Coastguard Worker                                               CookiePartitionKeyCollection());
2172*6777b538SAndroid Build Coastguard Worker   iter = excluded_cookies.begin();
2173*6777b538SAndroid Build Coastguard Worker 
2174*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(iter != excluded_cookies.end());
2175*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(http_www_foo_.Format(".%D"), iter->cookie.Domain());
2176*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("E", iter->cookie.Name());
2177*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(iter->access_result.status.HasExactlyExclusionReasonsForTesting(
2178*6777b538SAndroid Build Coastguard Worker       {CookieInclusionStatus::EXCLUDE_SECURE_ONLY}));
2179*6777b538SAndroid Build Coastguard Worker 
2180*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(++iter == excluded_cookies.end());
2181*6777b538SAndroid Build Coastguard Worker 
2182*6777b538SAndroid Build Coastguard Worker   // Checking that excluded cookies get sent with their statuses with http-only.
2183*6777b538SAndroid Build Coastguard Worker   CookieOptions return_excluded;
2184*6777b538SAndroid Build Coastguard Worker   return_excluded.set_return_excluded_cookies();
2185*6777b538SAndroid Build Coastguard Worker   return_excluded.set_exclude_httponly();
2186*6777b538SAndroid Build Coastguard Worker   return_excluded.set_same_site_cookie_context(
2187*6777b538SAndroid Build Coastguard Worker       CookieOptions::SameSiteCookieContext(
2188*6777b538SAndroid Build Coastguard Worker           CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT));
2189*6777b538SAndroid Build Coastguard Worker 
2190*6777b538SAndroid Build Coastguard Worker   excluded_cookies = GetExcludedCookiesForURLWithOptions(
2191*6777b538SAndroid Build Coastguard Worker       cm.get(), http_www_foo_.url(), return_excluded);
2192*6777b538SAndroid Build Coastguard Worker   iter = excluded_cookies.begin();
2193*6777b538SAndroid Build Coastguard Worker 
2194*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(iter != excluded_cookies.end());
2195*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(http_www_foo_.host(), iter->cookie.Domain());
2196*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("A", iter->cookie.Name());
2197*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(iter->access_result.status.HasExactlyExclusionReasonsForTesting(
2198*6777b538SAndroid Build Coastguard Worker       {CookieInclusionStatus::EXCLUDE_HTTP_ONLY}));
2199*6777b538SAndroid Build Coastguard Worker 
2200*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(++iter != excluded_cookies.end());
2201*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(http_www_foo_.Format(".%D"), iter->cookie.Domain());
2202*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("E", iter->cookie.Name());
2203*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(iter->access_result.status.HasExactlyExclusionReasonsForTesting(
2204*6777b538SAndroid Build Coastguard Worker       {CookieInclusionStatus::EXCLUDE_SECURE_ONLY}));
2205*6777b538SAndroid Build Coastguard Worker 
2206*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(++iter == excluded_cookies.end());
2207*6777b538SAndroid Build Coastguard Worker 
2208*6777b538SAndroid Build Coastguard Worker   // Check that no excluded cookies are sent with secure request
2209*6777b538SAndroid Build Coastguard Worker   excluded_cookies = GetExcludedCookiesForURL(cm.get(), https_www_foo_.url(),
2210*6777b538SAndroid Build Coastguard Worker                                               CookiePartitionKeyCollection());
2211*6777b538SAndroid Build Coastguard Worker   iter = excluded_cookies.begin();
2212*6777b538SAndroid Build Coastguard Worker 
2213*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(excluded_cookies.empty());
2214*6777b538SAndroid Build Coastguard Worker }
2215*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,GetAllCookiesForURLPathMatching)2216*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, GetAllCookiesForURLPathMatching) {
2217*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
2218*6777b538SAndroid Build Coastguard Worker 
2219*6777b538SAndroid Build Coastguard Worker   CookieOptions options = CookieOptions::MakeAllInclusive();
2220*6777b538SAndroid Build Coastguard Worker 
2221*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookie(cm.get(), www_foo_foo_.url(),
2222*6777b538SAndroid Build Coastguard Worker                                  "A=B; path=/foo;", options));
2223*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookie(cm.get(), www_foo_bar_.url(),
2224*6777b538SAndroid Build Coastguard Worker                                  "C=D; path=/bar;", options));
2225*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
2226*6777b538SAndroid Build Coastguard Worker       CreateAndSetCookie(cm.get(), http_www_foo_.url(), "E=F;", options));
2227*6777b538SAndroid Build Coastguard Worker 
2228*6777b538SAndroid Build Coastguard Worker   CookieList cookies = GetAllCookiesForURL(cm.get(), www_foo_foo_.url());
2229*6777b538SAndroid Build Coastguard Worker   auto it = cookies.begin();
2230*6777b538SAndroid Build Coastguard Worker 
2231*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(it != cookies.end());
2232*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("A", it->Name());
2233*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("/foo", it->Path());
2234*6777b538SAndroid Build Coastguard Worker 
2235*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(++it != cookies.end());
2236*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("E", it->Name());
2237*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("/", it->Path());
2238*6777b538SAndroid Build Coastguard Worker 
2239*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(++it == cookies.end());
2240*6777b538SAndroid Build Coastguard Worker 
2241*6777b538SAndroid Build Coastguard Worker   cookies = GetAllCookiesForURL(cm.get(), www_foo_bar_.url());
2242*6777b538SAndroid Build Coastguard Worker   it = cookies.begin();
2243*6777b538SAndroid Build Coastguard Worker 
2244*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(it != cookies.end());
2245*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("C", it->Name());
2246*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("/bar", it->Path());
2247*6777b538SAndroid Build Coastguard Worker 
2248*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(++it != cookies.end());
2249*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("E", it->Name());
2250*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("/", it->Path());
2251*6777b538SAndroid Build Coastguard Worker 
2252*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(++it == cookies.end());
2253*6777b538SAndroid Build Coastguard Worker }
2254*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,GetExcludedCookiesForURLPathMatching)2255*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, GetExcludedCookiesForURLPathMatching) {
2256*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
2257*6777b538SAndroid Build Coastguard Worker 
2258*6777b538SAndroid Build Coastguard Worker   CookieOptions options = CookieOptions::MakeAllInclusive();
2259*6777b538SAndroid Build Coastguard Worker 
2260*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookie(cm.get(), www_foo_foo_.url(),
2261*6777b538SAndroid Build Coastguard Worker                                  "A=B; path=/foo;", options));
2262*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookie(cm.get(), www_foo_bar_.url(),
2263*6777b538SAndroid Build Coastguard Worker                                  "C=D; path=/bar;", options));
2264*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
2265*6777b538SAndroid Build Coastguard Worker       CreateAndSetCookie(cm.get(), http_www_foo_.url(), "E=F;", options));
2266*6777b538SAndroid Build Coastguard Worker 
2267*6777b538SAndroid Build Coastguard Worker   CookieAccessResultList excluded_cookies = GetExcludedCookiesForURL(
2268*6777b538SAndroid Build Coastguard Worker       cm.get(), www_foo_foo_.url(), CookiePartitionKeyCollection());
2269*6777b538SAndroid Build Coastguard Worker   auto it = excluded_cookies.begin();
2270*6777b538SAndroid Build Coastguard Worker 
2271*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(it != excluded_cookies.end());
2272*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("C", it->cookie.Name());
2273*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("/bar", it->cookie.Path());
2274*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(it->access_result.status.HasExactlyExclusionReasonsForTesting(
2275*6777b538SAndroid Build Coastguard Worker       {CookieInclusionStatus::EXCLUDE_NOT_ON_PATH}));
2276*6777b538SAndroid Build Coastguard Worker 
2277*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(++it == excluded_cookies.end());
2278*6777b538SAndroid Build Coastguard Worker 
2279*6777b538SAndroid Build Coastguard Worker   excluded_cookies = GetExcludedCookiesForURL(cm.get(), www_foo_bar_.url(),
2280*6777b538SAndroid Build Coastguard Worker                                               CookiePartitionKeyCollection());
2281*6777b538SAndroid Build Coastguard Worker   it = excluded_cookies.begin();
2282*6777b538SAndroid Build Coastguard Worker 
2283*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(it != excluded_cookies.end());
2284*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("A", it->cookie.Name());
2285*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("/foo", it->cookie.Path());
2286*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(it->access_result.status.HasExactlyExclusionReasonsForTesting(
2287*6777b538SAndroid Build Coastguard Worker       {CookieInclusionStatus::EXCLUDE_NOT_ON_PATH}));
2288*6777b538SAndroid Build Coastguard Worker 
2289*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(++it == excluded_cookies.end());
2290*6777b538SAndroid Build Coastguard Worker }
2291*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,CookieSorting)2292*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, CookieSorting) {
2293*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
2294*6777b538SAndroid Build Coastguard Worker 
2295*6777b538SAndroid Build Coastguard Worker   base::Time system_time = base::Time::Now();
2296*6777b538SAndroid Build Coastguard Worker   for (const char* cookie_line :
2297*6777b538SAndroid Build Coastguard Worker        {"B=B1; path=/", "B=B2; path=/foo", "B=B3; path=/foo/bar",
2298*6777b538SAndroid Build Coastguard Worker         "A=A1; path=/", "A=A2; path=/foo", "A=A3; path=/foo/bar"}) {
2299*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(SetCookieWithSystemTime(cm.get(), http_www_foo_.url(),
2300*6777b538SAndroid Build Coastguard Worker                                         cookie_line, system_time));
2301*6777b538SAndroid Build Coastguard Worker     system_time += base::Milliseconds(100);
2302*6777b538SAndroid Build Coastguard Worker   }
2303*6777b538SAndroid Build Coastguard Worker 
2304*6777b538SAndroid Build Coastguard Worker   // Re-set cookie which should not change sort order, as the creation date
2305*6777b538SAndroid Build Coastguard Worker   // will be retained, as per RFC 6265 5.3.11.3.
2306*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookieWithSystemTime(cm.get(), http_www_foo_.url(),
2307*6777b538SAndroid Build Coastguard Worker                                       "B=B3; path=/foo/bar", system_time));
2308*6777b538SAndroid Build Coastguard Worker 
2309*6777b538SAndroid Build Coastguard Worker   CookieList cookies = GetAllCookies(cm.get());
2310*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(6u, cookies.size());
2311*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("B3", cookies[0].Value());
2312*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("A3", cookies[1].Value());
2313*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("B2", cookies[2].Value());
2314*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("A2", cookies[3].Value());
2315*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("B1", cookies[4].Value());
2316*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("A1", cookies[5].Value());
2317*6777b538SAndroid Build Coastguard Worker }
2318*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,InheritCreationDate)2319*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, InheritCreationDate) {
2320*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
2321*6777b538SAndroid Build Coastguard Worker 
2322*6777b538SAndroid Build Coastguard Worker   base::Time the_not_so_distant_past(base::Time::Now() - base::Seconds(1000));
2323*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookieWithCreationTime(cm.get(), http_www_foo_.url(),
2324*6777b538SAndroid Build Coastguard Worker                                         "Name=Value; path=/",
2325*6777b538SAndroid Build Coastguard Worker                                         the_not_so_distant_past));
2326*6777b538SAndroid Build Coastguard Worker 
2327*6777b538SAndroid Build Coastguard Worker   CookieList cookies = GetAllCookies(cm.get());
2328*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(1u, cookies.size());
2329*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(the_not_so_distant_past, cookies[0].CreationDate());
2330*6777b538SAndroid Build Coastguard Worker   base::Time last_update = cookies[0].LastUpdateDate();
2331*6777b538SAndroid Build Coastguard Worker 
2332*6777b538SAndroid Build Coastguard Worker   // Overwrite the cookie with the same value, and verify that the creation date
2333*6777b538SAndroid Build Coastguard Worker   // is inherited. The update date isn't inherited though.
2334*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), "Name=Value; path=/"));
2335*6777b538SAndroid Build Coastguard Worker 
2336*6777b538SAndroid Build Coastguard Worker   cookies = GetAllCookies(cm.get());
2337*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(1u, cookies.size());
2338*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(the_not_so_distant_past, cookies[0].CreationDate());
2339*6777b538SAndroid Build Coastguard Worker   // If this is flakey you many need to manually set the last update time.
2340*6777b538SAndroid Build Coastguard Worker   EXPECT_LT(last_update, cookies[0].LastUpdateDate());
2341*6777b538SAndroid Build Coastguard Worker   last_update = cookies[0].LastUpdateDate();
2342*6777b538SAndroid Build Coastguard Worker 
2343*6777b538SAndroid Build Coastguard Worker   // New value => new creation date.
2344*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
2345*6777b538SAndroid Build Coastguard Worker       SetCookie(cm.get(), http_www_foo_.url(), "Name=NewValue; path=/"));
2346*6777b538SAndroid Build Coastguard Worker 
2347*6777b538SAndroid Build Coastguard Worker   cookies = GetAllCookies(cm.get());
2348*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(1u, cookies.size());
2349*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(the_not_so_distant_past, cookies[0].CreationDate());
2350*6777b538SAndroid Build Coastguard Worker   // If this is flakey you many need to manually set the last update time.
2351*6777b538SAndroid Build Coastguard Worker   EXPECT_LT(last_update, cookies[0].LastUpdateDate());
2352*6777b538SAndroid Build Coastguard Worker }
2353*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,OverwriteSource)2354*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, OverwriteSource) {
2355*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
2356*6777b538SAndroid Build Coastguard Worker 
2357*6777b538SAndroid Build Coastguard Worker   // Set cookie with unknown source.
2358*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), "A=0", std::nullopt,
2359*6777b538SAndroid Build Coastguard Worker                         CookieSourceType::kUnknown));
2360*6777b538SAndroid Build Coastguard Worker   CookieList cookies = GetAllCookies(cm.get());
2361*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(1u, cookies.size());
2362*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("0", cookies[0].Value());
2363*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieSourceType::kUnknown, cookies[0].SourceType());
2364*6777b538SAndroid Build Coastguard Worker 
2365*6777b538SAndroid Build Coastguard Worker   // Overwrite the cookie with the same value and an http source.
2366*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), "A=0", std::nullopt,
2367*6777b538SAndroid Build Coastguard Worker                         CookieSourceType::kHTTP));
2368*6777b538SAndroid Build Coastguard Worker   cookies = GetAllCookies(cm.get());
2369*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(1u, cookies.size());
2370*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("0", cookies[0].Value());
2371*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieSourceType::kHTTP, cookies[0].SourceType());
2372*6777b538SAndroid Build Coastguard Worker 
2373*6777b538SAndroid Build Coastguard Worker   // Overwrite the cookie with a new value and a script source.
2374*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), "A=1", std::nullopt,
2375*6777b538SAndroid Build Coastguard Worker                         CookieSourceType::kScript));
2376*6777b538SAndroid Build Coastguard Worker   cookies = GetAllCookies(cm.get());
2377*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(1u, cookies.size());
2378*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("1", cookies[0].Value());
2379*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieSourceType::kScript, cookies[0].SourceType());
2380*6777b538SAndroid Build Coastguard Worker 
2381*6777b538SAndroid Build Coastguard Worker   // Overwrite the cookie with the same value and an other source.
2382*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), "A=1", std::nullopt,
2383*6777b538SAndroid Build Coastguard Worker                         CookieSourceType::kOther));
2384*6777b538SAndroid Build Coastguard Worker   cookies = GetAllCookies(cm.get());
2385*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(1u, cookies.size());
2386*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("1", cookies[0].Value());
2387*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieSourceType::kOther, cookies[0].SourceType());
2388*6777b538SAndroid Build Coastguard Worker }
2389*6777b538SAndroid Build Coastguard Worker 
2390*6777b538SAndroid Build Coastguard Worker // Check that GetAllCookiesForURL() does not return expired cookies and deletes
2391*6777b538SAndroid Build Coastguard Worker // them.
TEST_F(CookieMonsterTest,DeleteExpiredCookiesOnGet)2392*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, DeleteExpiredCookiesOnGet) {
2393*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
2394*6777b538SAndroid Build Coastguard Worker 
2395*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), "A=B;"));
2396*6777b538SAndroid Build Coastguard Worker 
2397*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), "C=D;"));
2398*6777b538SAndroid Build Coastguard Worker 
2399*6777b538SAndroid Build Coastguard Worker   CookieList cookies = GetAllCookiesForURL(cm.get(), http_www_foo_.url());
2400*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, cookies.size());
2401*6777b538SAndroid Build Coastguard Worker 
2402*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(),
2403*6777b538SAndroid Build Coastguard Worker                         "C=D; expires=Thu, 01-Jan-1970 00:00:00 GMT"));
2404*6777b538SAndroid Build Coastguard Worker 
2405*6777b538SAndroid Build Coastguard Worker   cookies = GetAllCookiesForURL(cm.get(), http_www_foo_.url());
2406*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, cookies.size());
2407*6777b538SAndroid Build Coastguard Worker 
2408*6777b538SAndroid Build Coastguard Worker   // Test partitioned cookies. They should exhibit the same behavior but are
2409*6777b538SAndroid Build Coastguard Worker   // stored in a different data structure internally.
2410*6777b538SAndroid Build Coastguard Worker   auto cookie_partition_key =
2411*6777b538SAndroid Build Coastguard Worker       CookiePartitionKey::FromURLForTesting(GURL("https://toplevelsite.com"));
2412*6777b538SAndroid Build Coastguard Worker 
2413*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), https_www_bar_.url(),
2414*6777b538SAndroid Build Coastguard Worker                         "__Host-A=B; secure; path=/; partitioned",
2415*6777b538SAndroid Build Coastguard Worker                         cookie_partition_key));
2416*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), https_www_bar_.url(),
2417*6777b538SAndroid Build Coastguard Worker                         "__Host-C=D; secure; path=/; partitioned",
2418*6777b538SAndroid Build Coastguard Worker                         cookie_partition_key));
2419*6777b538SAndroid Build Coastguard Worker 
2420*6777b538SAndroid Build Coastguard Worker   cookies =
2421*6777b538SAndroid Build Coastguard Worker       GetAllCookiesForURL(cm.get(), https_www_bar_.url(),
2422*6777b538SAndroid Build Coastguard Worker                           CookiePartitionKeyCollection(cookie_partition_key));
2423*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, cookies.size());
2424*6777b538SAndroid Build Coastguard Worker 
2425*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), https_www_bar_.url(),
2426*6777b538SAndroid Build Coastguard Worker                         "__Host-C=D; secure; path=/; partitioned; expires=Thu, "
2427*6777b538SAndroid Build Coastguard Worker                         "01-Jan-1970 00:00:00 GMT",
2428*6777b538SAndroid Build Coastguard Worker                         cookie_partition_key));
2429*6777b538SAndroid Build Coastguard Worker 
2430*6777b538SAndroid Build Coastguard Worker   cookies =
2431*6777b538SAndroid Build Coastguard Worker       GetAllCookiesForURL(cm.get(), https_www_bar_.url(),
2432*6777b538SAndroid Build Coastguard Worker                           CookiePartitionKeyCollection(cookie_partition_key));
2433*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, cookies.size());
2434*6777b538SAndroid Build Coastguard Worker }
2435*6777b538SAndroid Build Coastguard Worker 
2436*6777b538SAndroid Build Coastguard Worker // Test that cookie expiration works correctly when a cookie expires because
2437*6777b538SAndroid Build Coastguard Worker // time elapses.
TEST_F(CookieMonsterTest,DeleteExpiredCookiesAfterTimeElapsed)2438*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, DeleteExpiredCookiesAfterTimeElapsed) {
2439*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(
2440*6777b538SAndroid Build Coastguard Worker       /*store=*/nullptr, net::NetLog::Get());
2441*6777b538SAndroid Build Coastguard Worker 
2442*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), https_www_bar_.url(),
2443*6777b538SAndroid Build Coastguard Worker                         "__Host-A=B; secure; path=/",
2444*6777b538SAndroid Build Coastguard Worker                         /*cookie_partition_key=*/std::nullopt));
2445*6777b538SAndroid Build Coastguard Worker   // Set a cookie with a Max-Age. Since we only parse integers for this
2446*6777b538SAndroid Build Coastguard Worker   // attribute, 1 second is the minimum allowable time.
2447*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), https_www_bar_.url(),
2448*6777b538SAndroid Build Coastguard Worker                         "__Host-C=D; secure; path=/; max-age=1",
2449*6777b538SAndroid Build Coastguard Worker                         /*cookie_partition_key=*/std::nullopt));
2450*6777b538SAndroid Build Coastguard Worker 
2451*6777b538SAndroid Build Coastguard Worker   CookieList cookies = GetAllCookiesForURL(cm.get(), https_www_bar_.url(),
2452*6777b538SAndroid Build Coastguard Worker                                            CookiePartitionKeyCollection());
2453*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, cookies.size());
2454*6777b538SAndroid Build Coastguard Worker 
2455*6777b538SAndroid Build Coastguard Worker   // Sleep for entire Max-Age of the second cookie.
2456*6777b538SAndroid Build Coastguard Worker   base::PlatformThread::Sleep(base::Seconds(1));
2457*6777b538SAndroid Build Coastguard Worker 
2458*6777b538SAndroid Build Coastguard Worker   cookies = GetAllCookiesForURL(cm.get(), https_www_bar_.url(),
2459*6777b538SAndroid Build Coastguard Worker                                 CookiePartitionKeyCollection());
2460*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, cookies.size());
2461*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("__Host-A", cookies[0].Name());
2462*6777b538SAndroid Build Coastguard Worker }
2463*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,DeleteExpiredPartitionedCookiesAfterTimeElapsed)2464*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, DeleteExpiredPartitionedCookiesAfterTimeElapsed) {
2465*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(
2466*6777b538SAndroid Build Coastguard Worker       /*store=*/nullptr, net::NetLog::Get());
2467*6777b538SAndroid Build Coastguard Worker   auto cookie_partition_key =
2468*6777b538SAndroid Build Coastguard Worker       CookiePartitionKey::FromURLForTesting(GURL("https://toplevelsite.com"));
2469*6777b538SAndroid Build Coastguard Worker 
2470*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), https_www_bar_.url(),
2471*6777b538SAndroid Build Coastguard Worker                         "__Host-A=B; secure; path=/; partitioned",
2472*6777b538SAndroid Build Coastguard Worker                         cookie_partition_key));
2473*6777b538SAndroid Build Coastguard Worker   // Set a cookie with a Max-Age. Since we only parse integers for this
2474*6777b538SAndroid Build Coastguard Worker   // attribute, 1 second is the minimum allowable time.
2475*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), https_www_bar_.url(),
2476*6777b538SAndroid Build Coastguard Worker                         "__Host-C=D; secure; path=/; partitioned; max-age=1",
2477*6777b538SAndroid Build Coastguard Worker                         cookie_partition_key));
2478*6777b538SAndroid Build Coastguard Worker 
2479*6777b538SAndroid Build Coastguard Worker   CookieList cookies =
2480*6777b538SAndroid Build Coastguard Worker       GetAllCookiesForURL(cm.get(), https_www_bar_.url(),
2481*6777b538SAndroid Build Coastguard Worker                           CookiePartitionKeyCollection(cookie_partition_key));
2482*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, cookies.size());
2483*6777b538SAndroid Build Coastguard Worker 
2484*6777b538SAndroid Build Coastguard Worker   // Sleep for entire Max-Age of the second cookie.
2485*6777b538SAndroid Build Coastguard Worker   base::PlatformThread::Sleep(base::Seconds(1));
2486*6777b538SAndroid Build Coastguard Worker 
2487*6777b538SAndroid Build Coastguard Worker   cookies =
2488*6777b538SAndroid Build Coastguard Worker       GetAllCookiesForURL(cm.get(), https_www_bar_.url(),
2489*6777b538SAndroid Build Coastguard Worker                           CookiePartitionKeyCollection(cookie_partition_key));
2490*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, cookies.size());
2491*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("__Host-A", cookies[0].Name());
2492*6777b538SAndroid Build Coastguard Worker }
2493*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,DeleteExpiredAfterTimeElapsed_GetAllCookies)2494*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, DeleteExpiredAfterTimeElapsed_GetAllCookies) {
2495*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(
2496*6777b538SAndroid Build Coastguard Worker       /*store=*/nullptr, net::NetLog::Get());
2497*6777b538SAndroid Build Coastguard Worker 
2498*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), https_www_bar_.url(),
2499*6777b538SAndroid Build Coastguard Worker                         "__Host-A=B; secure; path=/",
2500*6777b538SAndroid Build Coastguard Worker                         /*cookie_partition_key=*/std::nullopt));
2501*6777b538SAndroid Build Coastguard Worker   // Set a cookie with a Max-Age. Since we only parse integers for this
2502*6777b538SAndroid Build Coastguard Worker   // attribute, 1 second is the minimum allowable time.
2503*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), https_www_bar_.url(),
2504*6777b538SAndroid Build Coastguard Worker                         "__Host-C=D; secure; path=/; max-age=1",
2505*6777b538SAndroid Build Coastguard Worker                         /*cookie_partition_key=*/std::nullopt));
2506*6777b538SAndroid Build Coastguard Worker 
2507*6777b538SAndroid Build Coastguard Worker   GetAllCookiesCallback get_cookies_callback1;
2508*6777b538SAndroid Build Coastguard Worker   cm->GetAllCookiesAsync(get_cookies_callback1.MakeCallback());
2509*6777b538SAndroid Build Coastguard Worker   get_cookies_callback1.WaitUntilDone();
2510*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(2u, get_cookies_callback1.cookies().size());
2511*6777b538SAndroid Build Coastguard Worker 
2512*6777b538SAndroid Build Coastguard Worker   // Sleep for entire Max-Age of the second cookie.
2513*6777b538SAndroid Build Coastguard Worker   base::PlatformThread::Sleep(base::Seconds(1));
2514*6777b538SAndroid Build Coastguard Worker 
2515*6777b538SAndroid Build Coastguard Worker   GetAllCookiesCallback get_cookies_callback2;
2516*6777b538SAndroid Build Coastguard Worker   cm->GetAllCookiesAsync(get_cookies_callback2.MakeCallback());
2517*6777b538SAndroid Build Coastguard Worker   get_cookies_callback2.WaitUntilDone();
2518*6777b538SAndroid Build Coastguard Worker 
2519*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(1u, get_cookies_callback2.cookies().size());
2520*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("__Host-A", get_cookies_callback2.cookies()[0].Name());
2521*6777b538SAndroid Build Coastguard Worker }
2522*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,DeleteExpiredPartitionedCookiesAfterTimeElapsed_GetAllCookies)2523*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest,
2524*6777b538SAndroid Build Coastguard Worker        DeleteExpiredPartitionedCookiesAfterTimeElapsed_GetAllCookies) {
2525*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(
2526*6777b538SAndroid Build Coastguard Worker       /*store=*/nullptr, net::NetLog::Get());
2527*6777b538SAndroid Build Coastguard Worker   auto cookie_partition_key =
2528*6777b538SAndroid Build Coastguard Worker       CookiePartitionKey::FromURLForTesting(GURL("https://toplevelsite.com"));
2529*6777b538SAndroid Build Coastguard Worker 
2530*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), https_www_bar_.url(),
2531*6777b538SAndroid Build Coastguard Worker                         "__Host-A=B; secure; path=/; partitioned",
2532*6777b538SAndroid Build Coastguard Worker                         cookie_partition_key));
2533*6777b538SAndroid Build Coastguard Worker   // Set a cookie with a Max-Age. Since we only parse integers for this
2534*6777b538SAndroid Build Coastguard Worker   // attribute, 1 second is the minimum allowable time.
2535*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), https_www_bar_.url(),
2536*6777b538SAndroid Build Coastguard Worker                         "__Host-C=D; secure; path=/; max-age=1; partitioned",
2537*6777b538SAndroid Build Coastguard Worker                         cookie_partition_key));
2538*6777b538SAndroid Build Coastguard Worker 
2539*6777b538SAndroid Build Coastguard Worker   GetAllCookiesCallback get_cookies_callback1;
2540*6777b538SAndroid Build Coastguard Worker   cm->GetAllCookiesAsync(get_cookies_callback1.MakeCallback());
2541*6777b538SAndroid Build Coastguard Worker   get_cookies_callback1.WaitUntilDone();
2542*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(2u, get_cookies_callback1.cookies().size());
2543*6777b538SAndroid Build Coastguard Worker 
2544*6777b538SAndroid Build Coastguard Worker   // Sleep for entire Max-Age of the second cookie.
2545*6777b538SAndroid Build Coastguard Worker   base::PlatformThread::Sleep(base::Seconds(1));
2546*6777b538SAndroid Build Coastguard Worker 
2547*6777b538SAndroid Build Coastguard Worker   GetAllCookiesCallback get_cookies_callback2;
2548*6777b538SAndroid Build Coastguard Worker   cm->GetAllCookiesAsync(get_cookies_callback2.MakeCallback());
2549*6777b538SAndroid Build Coastguard Worker   get_cookies_callback2.WaitUntilDone();
2550*6777b538SAndroid Build Coastguard Worker 
2551*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(1u, get_cookies_callback2.cookies().size());
2552*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("__Host-A", get_cookies_callback2.cookies()[0].Name());
2553*6777b538SAndroid Build Coastguard Worker }
2554*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,DeletePartitionedCookie)2555*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, DeletePartitionedCookie) {
2556*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(
2557*6777b538SAndroid Build Coastguard Worker       /*store=*/nullptr, net::NetLog::Get());
2558*6777b538SAndroid Build Coastguard Worker   auto cookie_partition_key =
2559*6777b538SAndroid Build Coastguard Worker       CookiePartitionKey::FromURLForTesting(GURL("https://toplevelsite.com"));
2560*6777b538SAndroid Build Coastguard Worker 
2561*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), https_www_bar_.url(),
2562*6777b538SAndroid Build Coastguard Worker                         "__Host-A=B; secure; path=/; partitioned",
2563*6777b538SAndroid Build Coastguard Worker                         cookie_partition_key));
2564*6777b538SAndroid Build Coastguard Worker   // Set another partitioned and an unpartitioned cookie and make sure they are
2565*6777b538SAndroid Build Coastguard Worker   // unaffected.
2566*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), https_www_bar_.url(),
2567*6777b538SAndroid Build Coastguard Worker                         "__Host-C=D; secure; path=/; partitioned",
2568*6777b538SAndroid Build Coastguard Worker                         cookie_partition_key));
2569*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), https_www_bar_.url(),
2570*6777b538SAndroid Build Coastguard Worker                         "__Host-E=F; secure; path=/", std::nullopt));
2571*6777b538SAndroid Build Coastguard Worker 
2572*6777b538SAndroid Build Coastguard Worker   auto cookie = CanonicalCookie::CreateForTesting(
2573*6777b538SAndroid Build Coastguard Worker       https_www_bar_.url(), "__Host-A=B; secure; path=/; partitioned",
2574*6777b538SAndroid Build Coastguard Worker       /*creation_time=*/Time::Now(), /*server_time=*/std::nullopt,
2575*6777b538SAndroid Build Coastguard Worker       cookie_partition_key);
2576*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(cookie);
2577*6777b538SAndroid Build Coastguard Worker 
2578*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<unsigned int> delete_callback;
2579*6777b538SAndroid Build Coastguard Worker   cm->DeleteCanonicalCookieAsync(*cookie, delete_callback.MakeCallback());
2580*6777b538SAndroid Build Coastguard Worker   delete_callback.WaitUntilDone();
2581*6777b538SAndroid Build Coastguard Worker 
2582*6777b538SAndroid Build Coastguard Worker   CookieList cookies =
2583*6777b538SAndroid Build Coastguard Worker       GetAllCookiesForURL(cm.get(), https_www_bar_.url(),
2584*6777b538SAndroid Build Coastguard Worker                           CookiePartitionKeyCollection(cookie_partition_key));
2585*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, cookies.size());
2586*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(cookies[0].Name(), "__Host-C");
2587*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(cookies[1].Name(), "__Host-E");
2588*6777b538SAndroid Build Coastguard Worker }
2589*6777b538SAndroid Build Coastguard Worker 
2590*6777b538SAndroid Build Coastguard Worker // Tests importing from a persistent cookie store that contains duplicate
2591*6777b538SAndroid Build Coastguard Worker // equivalent cookies. This situation should be handled by removing the
2592*6777b538SAndroid Build Coastguard Worker // duplicate cookie (both from the in-memory cache, and from the backing store).
2593*6777b538SAndroid Build Coastguard Worker //
2594*6777b538SAndroid Build Coastguard Worker // This is a regression test for: http://crbug.com/17855.
TEST_F(CookieMonsterTest,DontImportDuplicateCookies)2595*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, DontImportDuplicateCookies) {
2596*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
2597*6777b538SAndroid Build Coastguard Worker 
2598*6777b538SAndroid Build Coastguard Worker   // We will fill some initial cookies into the PersistentCookieStore,
2599*6777b538SAndroid Build Coastguard Worker   // to simulate a database with 4 duplicates.  Note that we need to
2600*6777b538SAndroid Build Coastguard Worker   // be careful not to have any duplicate creation times at all (as it's a
2601*6777b538SAndroid Build Coastguard Worker   // violation of a CookieMonster invariant) even if Time::Now() doesn't
2602*6777b538SAndroid Build Coastguard Worker   // move between calls.
2603*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<CanonicalCookie>> initial_cookies;
2604*6777b538SAndroid Build Coastguard Worker 
2605*6777b538SAndroid Build Coastguard Worker   // Insert 4 cookies with name "X" on path "/", with varying creation
2606*6777b538SAndroid Build Coastguard Worker   // dates. We expect only the most recent one to be preserved following
2607*6777b538SAndroid Build Coastguard Worker   // the import.
2608*6777b538SAndroid Build Coastguard Worker 
2609*6777b538SAndroid Build Coastguard Worker   AddCookieToList(GURL("http://www.foo.com"),
2610*6777b538SAndroid Build Coastguard Worker                   "X=1; path=/" + FutureCookieExpirationString(),
2611*6777b538SAndroid Build Coastguard Worker                   Time::Now() + base::Days(3), &initial_cookies);
2612*6777b538SAndroid Build Coastguard Worker 
2613*6777b538SAndroid Build Coastguard Worker   AddCookieToList(GURL("http://www.foo.com"),
2614*6777b538SAndroid Build Coastguard Worker                   "X=2; path=/" + FutureCookieExpirationString(),
2615*6777b538SAndroid Build Coastguard Worker                   Time::Now() + base::Days(1), &initial_cookies);
2616*6777b538SAndroid Build Coastguard Worker 
2617*6777b538SAndroid Build Coastguard Worker   // ===> This one is the WINNER (biggest creation time).  <====
2618*6777b538SAndroid Build Coastguard Worker   AddCookieToList(GURL("http://www.foo.com"),
2619*6777b538SAndroid Build Coastguard Worker                   "X=3; path=/" + FutureCookieExpirationString(),
2620*6777b538SAndroid Build Coastguard Worker                   Time::Now() + base::Days(4), &initial_cookies);
2621*6777b538SAndroid Build Coastguard Worker 
2622*6777b538SAndroid Build Coastguard Worker   AddCookieToList(GURL("http://www.foo.com"),
2623*6777b538SAndroid Build Coastguard Worker                   "X=4; path=/" + FutureCookieExpirationString(), Time::Now(),
2624*6777b538SAndroid Build Coastguard Worker                   &initial_cookies);
2625*6777b538SAndroid Build Coastguard Worker 
2626*6777b538SAndroid Build Coastguard Worker   // Insert 2 cookies with name "X" on path "/2", with varying creation
2627*6777b538SAndroid Build Coastguard Worker   // dates. We expect only the most recent one to be preserved the import.
2628*6777b538SAndroid Build Coastguard Worker 
2629*6777b538SAndroid Build Coastguard Worker   // ===> This one is the WINNER (biggest creation time).  <====
2630*6777b538SAndroid Build Coastguard Worker   AddCookieToList(GURL("http://www.foo.com"),
2631*6777b538SAndroid Build Coastguard Worker                   "X=a1; path=/2" + FutureCookieExpirationString(),
2632*6777b538SAndroid Build Coastguard Worker                   Time::Now() + base::Days(9), &initial_cookies);
2633*6777b538SAndroid Build Coastguard Worker 
2634*6777b538SAndroid Build Coastguard Worker   AddCookieToList(GURL("http://www.foo.com"),
2635*6777b538SAndroid Build Coastguard Worker                   "X=a2; path=/2" + FutureCookieExpirationString(),
2636*6777b538SAndroid Build Coastguard Worker                   Time::Now() + base::Days(2), &initial_cookies);
2637*6777b538SAndroid Build Coastguard Worker 
2638*6777b538SAndroid Build Coastguard Worker   // Insert 1 cookie with name "Y" on path "/".
2639*6777b538SAndroid Build Coastguard Worker   AddCookieToList(GURL("http://www.foo.com"),
2640*6777b538SAndroid Build Coastguard Worker                   "Y=a; path=/" + FutureCookieExpirationString(),
2641*6777b538SAndroid Build Coastguard Worker                   Time::Now() + base::Days(10), &initial_cookies);
2642*6777b538SAndroid Build Coastguard Worker 
2643*6777b538SAndroid Build Coastguard Worker   // Inject our initial cookies into the mock PersistentCookieStore.
2644*6777b538SAndroid Build Coastguard Worker   store->SetLoadExpectation(true, std::move(initial_cookies));
2645*6777b538SAndroid Build Coastguard Worker 
2646*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
2647*6777b538SAndroid Build Coastguard Worker 
2648*6777b538SAndroid Build Coastguard Worker   // Verify that duplicates were not imported for path "/".
2649*6777b538SAndroid Build Coastguard Worker   // (If this had failed, GetCookies() would have also returned X=1, X=2, X=4).
2650*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("X=3; Y=a", GetCookies(cm.get(), GURL("http://www.foo.com/")));
2651*6777b538SAndroid Build Coastguard Worker 
2652*6777b538SAndroid Build Coastguard Worker   // Verify that same-named cookie on a different path ("/x2") didn't get
2653*6777b538SAndroid Build Coastguard Worker   // messed up.
2654*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("X=a1; X=3; Y=a",
2655*6777b538SAndroid Build Coastguard Worker             GetCookies(cm.get(), GURL("http://www.foo.com/2/x")));
2656*6777b538SAndroid Build Coastguard Worker 
2657*6777b538SAndroid Build Coastguard Worker   // Verify that the PersistentCookieStore was told to kill its 4 duplicates.
2658*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(4u, store->commands().size());
2659*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[0].type);
2660*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[1].type);
2661*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[2].type);
2662*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[3].type);
2663*6777b538SAndroid Build Coastguard Worker }
2664*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,DontImportDuplicateCookies_PartitionedCookies)2665*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, DontImportDuplicateCookies_PartitionedCookies) {
2666*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<CanonicalCookie>> initial_cookies;
2667*6777b538SAndroid Build Coastguard Worker 
2668*6777b538SAndroid Build Coastguard Worker   auto cookie_partition_key =
2669*6777b538SAndroid Build Coastguard Worker       CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com"));
2670*6777b538SAndroid Build Coastguard Worker   GURL cookie_url("https://www.bar.com");
2671*6777b538SAndroid Build Coastguard Worker 
2672*6777b538SAndroid Build Coastguard Worker   // Insert 3 partitioned cookies with same name, partition key, and path.
2673*6777b538SAndroid Build Coastguard Worker 
2674*6777b538SAndroid Build Coastguard Worker   // ===> This one is the WINNER (biggest creation time).  <====
2675*6777b538SAndroid Build Coastguard Worker   auto cc = CanonicalCookie::CreateForTesting(
2676*6777b538SAndroid Build Coastguard Worker       cookie_url, "__Host-Z=a; Secure; Path=/; Partitioned; Max-Age=3456000",
2677*6777b538SAndroid Build Coastguard Worker       Time::Now() + base::Days(2), std::nullopt, cookie_partition_key);
2678*6777b538SAndroid Build Coastguard Worker   initial_cookies.push_back(std::move(cc));
2679*6777b538SAndroid Build Coastguard Worker 
2680*6777b538SAndroid Build Coastguard Worker   cc = CanonicalCookie::CreateForTesting(
2681*6777b538SAndroid Build Coastguard Worker       cookie_url, "__Host-Z=b; Secure; Path=/; Partitioned; Max-Age=3456000",
2682*6777b538SAndroid Build Coastguard Worker       Time::Now(), std::nullopt, cookie_partition_key);
2683*6777b538SAndroid Build Coastguard Worker   initial_cookies.push_back(std::move(cc));
2684*6777b538SAndroid Build Coastguard Worker 
2685*6777b538SAndroid Build Coastguard Worker   cc = CanonicalCookie::CreateForTesting(
2686*6777b538SAndroid Build Coastguard Worker       cookie_url, "__Host-Z=c; Secure; Path=/; Partitioned; Max-Age=3456000",
2687*6777b538SAndroid Build Coastguard Worker       Time::Now() + base::Days(1), std::nullopt, cookie_partition_key);
2688*6777b538SAndroid Build Coastguard Worker   initial_cookies.push_back(std::move(cc));
2689*6777b538SAndroid Build Coastguard Worker 
2690*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
2691*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
2692*6777b538SAndroid Build Coastguard Worker 
2693*6777b538SAndroid Build Coastguard Worker   store->SetLoadExpectation(true, std::move(initial_cookies));
2694*6777b538SAndroid Build Coastguard Worker 
2695*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("__Host-Z=a",
2696*6777b538SAndroid Build Coastguard Worker             GetCookies(cm.get(), GURL("https://www.bar.com/"),
2697*6777b538SAndroid Build Coastguard Worker                        CookiePartitionKeyCollection(cookie_partition_key)));
2698*6777b538SAndroid Build Coastguard Worker 
2699*6777b538SAndroid Build Coastguard Worker   // Verify that the PersistentCookieStore was told to kill the 2
2700*6777b538SAndroid Build Coastguard Worker   // duplicates.
2701*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(2u, store->commands().size());
2702*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[0].type);
2703*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[1].type);
2704*6777b538SAndroid Build Coastguard Worker }
2705*6777b538SAndroid Build Coastguard Worker 
2706*6777b538SAndroid Build Coastguard Worker // Tests importing from a persistent cookie store that contains cookies
2707*6777b538SAndroid Build Coastguard Worker // with duplicate creation times.  This is OK now, but it still interacts
2708*6777b538SAndroid Build Coastguard Worker // with the de-duplication algorithm.
2709*6777b538SAndroid Build Coastguard Worker //
2710*6777b538SAndroid Build Coastguard Worker // This is a regression test for: http://crbug.com/43188.
TEST_F(CookieMonsterTest,ImportDuplicateCreationTimes)2711*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, ImportDuplicateCreationTimes) {
2712*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
2713*6777b538SAndroid Build Coastguard Worker 
2714*6777b538SAndroid Build Coastguard Worker   Time now(Time::Now());
2715*6777b538SAndroid Build Coastguard Worker   Time earlier(now - base::Days(1));
2716*6777b538SAndroid Build Coastguard Worker 
2717*6777b538SAndroid Build Coastguard Worker   // Insert 8 cookies, four with the current time as creation times, and
2718*6777b538SAndroid Build Coastguard Worker   // four with the earlier time as creation times.  We should only get
2719*6777b538SAndroid Build Coastguard Worker   // two cookies remaining, but which two (other than that there should
2720*6777b538SAndroid Build Coastguard Worker   // be one from each set) will be random.
2721*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<CanonicalCookie>> initial_cookies;
2722*6777b538SAndroid Build Coastguard Worker   AddCookieToList(GURL("http://www.foo.com"), "X=1; path=/", now,
2723*6777b538SAndroid Build Coastguard Worker                   &initial_cookies);
2724*6777b538SAndroid Build Coastguard Worker   AddCookieToList(GURL("http://www.foo.com"), "X=2; path=/", now,
2725*6777b538SAndroid Build Coastguard Worker                   &initial_cookies);
2726*6777b538SAndroid Build Coastguard Worker   AddCookieToList(GURL("http://www.foo.com"), "X=3; path=/", now,
2727*6777b538SAndroid Build Coastguard Worker                   &initial_cookies);
2728*6777b538SAndroid Build Coastguard Worker   AddCookieToList(GURL("http://www.foo.com"), "X=4; path=/", now,
2729*6777b538SAndroid Build Coastguard Worker                   &initial_cookies);
2730*6777b538SAndroid Build Coastguard Worker 
2731*6777b538SAndroid Build Coastguard Worker   AddCookieToList(GURL("http://www.foo.com"), "Y=1; path=/", earlier,
2732*6777b538SAndroid Build Coastguard Worker                   &initial_cookies);
2733*6777b538SAndroid Build Coastguard Worker   AddCookieToList(GURL("http://www.foo.com"), "Y=2; path=/", earlier,
2734*6777b538SAndroid Build Coastguard Worker                   &initial_cookies);
2735*6777b538SAndroid Build Coastguard Worker   AddCookieToList(GURL("http://www.foo.com"), "Y=3; path=/", earlier,
2736*6777b538SAndroid Build Coastguard Worker                   &initial_cookies);
2737*6777b538SAndroid Build Coastguard Worker   AddCookieToList(GURL("http://www.foo.com"), "Y=4; path=/", earlier,
2738*6777b538SAndroid Build Coastguard Worker                   &initial_cookies);
2739*6777b538SAndroid Build Coastguard Worker 
2740*6777b538SAndroid Build Coastguard Worker   // Inject our initial cookies into the mock PersistentCookieStore.
2741*6777b538SAndroid Build Coastguard Worker   store->SetLoadExpectation(true, std::move(initial_cookies));
2742*6777b538SAndroid Build Coastguard Worker 
2743*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
2744*6777b538SAndroid Build Coastguard Worker 
2745*6777b538SAndroid Build Coastguard Worker   CookieList list(GetAllCookies(cm.get()));
2746*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2U, list.size());
2747*6777b538SAndroid Build Coastguard Worker   // Confirm that we have one of each.
2748*6777b538SAndroid Build Coastguard Worker   std::string name1(list[0].Name());
2749*6777b538SAndroid Build Coastguard Worker   std::string name2(list[1].Name());
2750*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(name1 == "X" || name2 == "X");
2751*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(name1 == "Y" || name2 == "Y");
2752*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(name1, name2);
2753*6777b538SAndroid Build Coastguard Worker }
2754*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,ImportDuplicateCreationTimes_PartitionedCookies)2755*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, ImportDuplicateCreationTimes_PartitionedCookies) {
2756*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
2757*6777b538SAndroid Build Coastguard Worker 
2758*6777b538SAndroid Build Coastguard Worker   Time now(Time::Now());
2759*6777b538SAndroid Build Coastguard Worker   Time earlier(now - base::Days(1));
2760*6777b538SAndroid Build Coastguard Worker 
2761*6777b538SAndroid Build Coastguard Worker   GURL cookie_url("https://www.foo.com");
2762*6777b538SAndroid Build Coastguard Worker   auto cookie_partition_key =
2763*6777b538SAndroid Build Coastguard Worker       CookiePartitionKey::FromURLForTesting(GURL("https://www.bar.com"));
2764*6777b538SAndroid Build Coastguard Worker 
2765*6777b538SAndroid Build Coastguard Worker   // Insert 6 cookies, four with the current time as creation times, and
2766*6777b538SAndroid Build Coastguard Worker   // four with the earlier time as creation times.  We should only get
2767*6777b538SAndroid Build Coastguard Worker   // two cookies remaining, but which two (other than that there should
2768*6777b538SAndroid Build Coastguard Worker   // be one from each set) will be random.
2769*6777b538SAndroid Build Coastguard Worker 
2770*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<CanonicalCookie>> initial_cookies;
2771*6777b538SAndroid Build Coastguard Worker   auto cc = CanonicalCookie::CreateForTesting(
2772*6777b538SAndroid Build Coastguard Worker       cookie_url, "__Host-X=1; Secure; Path=/; Partitioned; Max-Age=3456000",
2773*6777b538SAndroid Build Coastguard Worker       now, std::nullopt, cookie_partition_key);
2774*6777b538SAndroid Build Coastguard Worker   initial_cookies.push_back(std::move(cc));
2775*6777b538SAndroid Build Coastguard Worker   cc = CanonicalCookie::CreateForTesting(
2776*6777b538SAndroid Build Coastguard Worker       cookie_url, "__Host-X=2; Secure; Path=/; Partitioned; Max-Age=3456000",
2777*6777b538SAndroid Build Coastguard Worker       now, std::nullopt, cookie_partition_key);
2778*6777b538SAndroid Build Coastguard Worker   initial_cookies.push_back(std::move(cc));
2779*6777b538SAndroid Build Coastguard Worker   cc = CanonicalCookie::CreateForTesting(
2780*6777b538SAndroid Build Coastguard Worker       cookie_url, "__Host-X=3; Secure; Path=/; Partitioned; Max-Age=3456000",
2781*6777b538SAndroid Build Coastguard Worker       now, std::nullopt, cookie_partition_key);
2782*6777b538SAndroid Build Coastguard Worker   initial_cookies.push_back(std::move(cc));
2783*6777b538SAndroid Build Coastguard Worker 
2784*6777b538SAndroid Build Coastguard Worker   cc = CanonicalCookie::CreateForTesting(
2785*6777b538SAndroid Build Coastguard Worker       cookie_url, "__Host-Y=1; Secure; Path=/; Partitioned; Max-Age=3456000",
2786*6777b538SAndroid Build Coastguard Worker       earlier, std::nullopt, cookie_partition_key);
2787*6777b538SAndroid Build Coastguard Worker   initial_cookies.push_back(std::move(cc));
2788*6777b538SAndroid Build Coastguard Worker   cc = CanonicalCookie::CreateForTesting(
2789*6777b538SAndroid Build Coastguard Worker       cookie_url, "__Host-Y=2; Secure; Path=/; Partitioned; Max-Age=3456000",
2790*6777b538SAndroid Build Coastguard Worker       earlier, std::nullopt, cookie_partition_key);
2791*6777b538SAndroid Build Coastguard Worker   initial_cookies.push_back(std::move(cc));
2792*6777b538SAndroid Build Coastguard Worker   cc = CanonicalCookie::CreateForTesting(
2793*6777b538SAndroid Build Coastguard Worker       cookie_url, "__Host-Y=3; Secure; Path=/; Partitioned; Max-Age=3456000",
2794*6777b538SAndroid Build Coastguard Worker       earlier, std::nullopt, cookie_partition_key);
2795*6777b538SAndroid Build Coastguard Worker   initial_cookies.push_back(std::move(cc));
2796*6777b538SAndroid Build Coastguard Worker 
2797*6777b538SAndroid Build Coastguard Worker   // Inject our initial cookies into the mock PersistentCookieStore.
2798*6777b538SAndroid Build Coastguard Worker   store->SetLoadExpectation(true, std::move(initial_cookies));
2799*6777b538SAndroid Build Coastguard Worker 
2800*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
2801*6777b538SAndroid Build Coastguard Worker 
2802*6777b538SAndroid Build Coastguard Worker   CookieList list(GetAllCookies(cm.get()));
2803*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2U, list.size());
2804*6777b538SAndroid Build Coastguard Worker   // Confirm that we have one of each.
2805*6777b538SAndroid Build Coastguard Worker   std::string name1(list[0].Name());
2806*6777b538SAndroid Build Coastguard Worker   std::string name2(list[1].Name());
2807*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(name1 == "__Host-X" || name2 == "__Host-X");
2808*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(name1 == "__Host-Y" || name2 == "__Host-Y");
2809*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(name1, name2);
2810*6777b538SAndroid Build Coastguard Worker }
2811*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,PredicateSeesAllCookies)2812*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, PredicateSeesAllCookies) {
2813*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
2814*6777b538SAndroid Build Coastguard Worker 
2815*6777b538SAndroid Build Coastguard Worker   const base::Time now = PopulateCmForPredicateCheck(cm.get());
2816*6777b538SAndroid Build Coastguard Worker   // We test that we can see all cookies with |delete_info|. This includes
2817*6777b538SAndroid Build Coastguard Worker   // host, http_only, host secure, and all domain cookies.
2818*6777b538SAndroid Build Coastguard Worker   CookieDeletionInfo delete_info(base::Time(), now);
2819*6777b538SAndroid Build Coastguard Worker   delete_info.value_for_testing = "A";
2820*6777b538SAndroid Build Coastguard Worker 
2821*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(8u, DeleteAllMatchingInfo(cm.get(), std::move(delete_info)));
2822*6777b538SAndroid Build Coastguard Worker 
2823*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("dom_2=B; dom_3=C; host_3=C",
2824*6777b538SAndroid Build Coastguard Worker             GetCookies(cm.get(), GURL(kTopLevelDomainPlus3)));
2825*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("dom_2=B; host_2=B; sec_host=B",
2826*6777b538SAndroid Build Coastguard Worker             GetCookies(cm.get(), GURL(kTopLevelDomainPlus2Secure)));
2827*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("", GetCookies(cm.get(), GURL(kTopLevelDomainPlus1)));
2828*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("dom_path_2=B; host_path_2=B; dom_2=B; host_2=B; sec_host=B",
2829*6777b538SAndroid Build Coastguard Worker             GetCookies(cm.get(), GURL(kTopLevelDomainPlus2Secure +
2830*6777b538SAndroid Build Coastguard Worker                                       std::string("/dir1/dir2/xxx"))));
2831*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("dom_2=B; host_2=B; sec_host=B; __Host-pc_2=B",
2832*6777b538SAndroid Build Coastguard Worker             GetCookies(cm.get(), GURL(kTopLevelDomainPlus2Secure),
2833*6777b538SAndroid Build Coastguard Worker                        CookiePartitionKeyCollection(
2834*6777b538SAndroid Build Coastguard Worker                            CookiePartitionKey::FromURLForTesting(
2835*6777b538SAndroid Build Coastguard Worker                                GURL(kTopLevelDomainPlus1)))));
2836*6777b538SAndroid Build Coastguard Worker }
2837*6777b538SAndroid Build Coastguard Worker 
2838*6777b538SAndroid Build Coastguard Worker // Mainly a test of GetEffectiveDomain, or more specifically, of the
2839*6777b538SAndroid Build Coastguard Worker // expected behavior of GetEffectiveDomain within the CookieMonster.
TEST_F(CookieMonsterTest,GetKey)2840*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, GetKey) {
2841*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
2842*6777b538SAndroid Build Coastguard Worker 
2843*6777b538SAndroid Build Coastguard Worker   // This test is really only interesting if GetKey() actually does something.
2844*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("foo.com", cm->GetKey("www.foo.com"));
2845*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("google.izzie", cm->GetKey("www.google.izzie"));
2846*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("google.izzie", cm->GetKey(".google.izzie"));
2847*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("bbc.co.uk", cm->GetKey("bbc.co.uk"));
2848*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("bbc.co.uk", cm->GetKey("a.b.c.d.bbc.co.uk"));
2849*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("apple.com", cm->GetKey("a.b.c.d.apple.com"));
2850*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("apple.izzie", cm->GetKey("a.b.c.d.apple.izzie"));
2851*6777b538SAndroid Build Coastguard Worker 
2852*6777b538SAndroid Build Coastguard Worker   // Cases where the effective domain is null, so we use the host
2853*6777b538SAndroid Build Coastguard Worker   // as the key.
2854*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("co.uk", cm->GetKey("co.uk"));
2855*6777b538SAndroid Build Coastguard Worker   const std::string extension_name("iehocdgbbocmkdidlbnnfbmbinnahbae");
2856*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(extension_name, cm->GetKey(extension_name));
2857*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("com", cm->GetKey("com"));
2858*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("hostalias", cm->GetKey("hostalias"));
2859*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("localhost", cm->GetKey("localhost"));
2860*6777b538SAndroid Build Coastguard Worker }
2861*6777b538SAndroid Build Coastguard Worker 
2862*6777b538SAndroid Build Coastguard Worker // Test that cookies transfer from/to the backing store correctly.
2863*6777b538SAndroid Build Coastguard Worker // TODO(crbug.com/1225444): Include partitioned cookies in this test when we
2864*6777b538SAndroid Build Coastguard Worker // start saving them in the persistent store.
TEST_F(CookieMonsterTest,BackingStoreCommunication)2865*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, BackingStoreCommunication) {
2866*6777b538SAndroid Build Coastguard Worker   // Store details for cookies transforming through the backing store interface.
2867*6777b538SAndroid Build Coastguard Worker 
2868*6777b538SAndroid Build Coastguard Worker   base::Time current(base::Time::Now());
2869*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<MockSimplePersistentCookieStore>();
2870*6777b538SAndroid Build Coastguard Worker   base::Time expires(base::Time::Now() + base::Seconds(100));
2871*6777b538SAndroid Build Coastguard Worker 
2872*6777b538SAndroid Build Coastguard Worker   const CookiesInputInfo input_info[] = {
2873*6777b538SAndroid Build Coastguard Worker       {GURL("https://a.b.foo.com"), "a", "1", "a.b.foo.com", "/path/to/cookie",
2874*6777b538SAndroid Build Coastguard Worker        expires, true /* secure */, false, CookieSameSite::NO_RESTRICTION,
2875*6777b538SAndroid Build Coastguard Worker        COOKIE_PRIORITY_DEFAULT},
2876*6777b538SAndroid Build Coastguard Worker       {GURL("https://www.foo.com"), "b", "2", ".foo.com", "/path/from/cookie",
2877*6777b538SAndroid Build Coastguard Worker        expires + base::Seconds(10), true, true, CookieSameSite::NO_RESTRICTION,
2878*6777b538SAndroid Build Coastguard Worker        COOKIE_PRIORITY_DEFAULT},
2879*6777b538SAndroid Build Coastguard Worker       {GURL("https://foo.com"), "c", "3", "foo.com", "/another/path/to/cookie",
2880*6777b538SAndroid Build Coastguard Worker        base::Time::Now() + base::Seconds(100), false, false,
2881*6777b538SAndroid Build Coastguard Worker        CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT}};
2882*6777b538SAndroid Build Coastguard Worker   const int INPUT_DELETE = 1;
2883*6777b538SAndroid Build Coastguard Worker 
2884*6777b538SAndroid Build Coastguard Worker   // Create new cookies and flush them to the store.
2885*6777b538SAndroid Build Coastguard Worker   {
2886*6777b538SAndroid Build Coastguard Worker     auto cmout =
2887*6777b538SAndroid Build Coastguard Worker         std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
2888*6777b538SAndroid Build Coastguard Worker     for (const auto& cookie : input_info) {
2889*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(SetCanonicalCookie(
2890*6777b538SAndroid Build Coastguard Worker           cmout.get(),
2891*6777b538SAndroid Build Coastguard Worker           CanonicalCookie::CreateUnsafeCookieForTesting(
2892*6777b538SAndroid Build Coastguard Worker               cookie.name, cookie.value, cookie.domain, cookie.path,
2893*6777b538SAndroid Build Coastguard Worker               base::Time(), cookie.expiration_time, base::Time(), base::Time(),
2894*6777b538SAndroid Build Coastguard Worker               cookie.secure, cookie.http_only, cookie.same_site,
2895*6777b538SAndroid Build Coastguard Worker               cookie.priority),
2896*6777b538SAndroid Build Coastguard Worker           cookie.url, true /*modify_httponly*/));
2897*6777b538SAndroid Build Coastguard Worker     }
2898*6777b538SAndroid Build Coastguard Worker 
2899*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(FindAndDeleteCookie(cmout.get(),
2900*6777b538SAndroid Build Coastguard Worker                                     input_info[INPUT_DELETE].domain,
2901*6777b538SAndroid Build Coastguard Worker                                     input_info[INPUT_DELETE].name));
2902*6777b538SAndroid Build Coastguard Worker   }
2903*6777b538SAndroid Build Coastguard Worker 
2904*6777b538SAndroid Build Coastguard Worker   // Create a new cookie monster and make sure that everything is correct
2905*6777b538SAndroid Build Coastguard Worker   {
2906*6777b538SAndroid Build Coastguard Worker     auto cmin =
2907*6777b538SAndroid Build Coastguard Worker         std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
2908*6777b538SAndroid Build Coastguard Worker     CookieList cookies(GetAllCookies(cmin.get()));
2909*6777b538SAndroid Build Coastguard Worker     ASSERT_EQ(2u, cookies.size());
2910*6777b538SAndroid Build Coastguard Worker     // Ordering is path length, then creation time.  So second cookie
2911*6777b538SAndroid Build Coastguard Worker     // will come first, and we need to swap them.
2912*6777b538SAndroid Build Coastguard Worker     std::swap(cookies[0], cookies[1]);
2913*6777b538SAndroid Build Coastguard Worker     for (int output_index = 0; output_index < 2; output_index++) {
2914*6777b538SAndroid Build Coastguard Worker       int input_index = output_index * 2;
2915*6777b538SAndroid Build Coastguard Worker       const CookiesInputInfo* input = &input_info[input_index];
2916*6777b538SAndroid Build Coastguard Worker       const CanonicalCookie* output = &cookies[output_index];
2917*6777b538SAndroid Build Coastguard Worker 
2918*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(input->name, output->Name());
2919*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(input->value, output->Value());
2920*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(input->url.host(), output->Domain());
2921*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(input->path, output->Path());
2922*6777b538SAndroid Build Coastguard Worker       EXPECT_LE(current.ToInternalValue(),
2923*6777b538SAndroid Build Coastguard Worker                 output->CreationDate().ToInternalValue());
2924*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(input->secure, output->SecureAttribute());
2925*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(input->http_only, output->IsHttpOnly());
2926*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(input->same_site, output->SameSite());
2927*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(output->IsPersistent());
2928*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(input->expiration_time.ToInternalValue(),
2929*6777b538SAndroid Build Coastguard Worker                 output->ExpiryDate().ToInternalValue());
2930*6777b538SAndroid Build Coastguard Worker     }
2931*6777b538SAndroid Build Coastguard Worker   }
2932*6777b538SAndroid Build Coastguard Worker }
2933*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,RestoreDifferentCookieSameCreationTime)2934*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, RestoreDifferentCookieSameCreationTime) {
2935*6777b538SAndroid Build Coastguard Worker   // Test that we can restore different cookies with duplicate creation times.
2936*6777b538SAndroid Build Coastguard Worker   base::Time current(base::Time::Now());
2937*6777b538SAndroid Build Coastguard Worker   scoped_refptr<MockPersistentCookieStore> store =
2938*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<MockPersistentCookieStore>();
2939*6777b538SAndroid Build Coastguard Worker 
2940*6777b538SAndroid Build Coastguard Worker   {
2941*6777b538SAndroid Build Coastguard Worker     CookieMonster cmout(store.get(), net::NetLog::Get());
2942*6777b538SAndroid Build Coastguard Worker     GURL url("http://www.example.com/");
2943*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(
2944*6777b538SAndroid Build Coastguard Worker         SetCookieWithCreationTime(&cmout, url, "A=1; max-age=600", current));
2945*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(
2946*6777b538SAndroid Build Coastguard Worker         SetCookieWithCreationTime(&cmout, url, "B=2; max-age=600", current));
2947*6777b538SAndroid Build Coastguard Worker   }
2948*6777b538SAndroid Build Coastguard Worker 
2949*6777b538SAndroid Build Coastguard Worker   // Play back the cookies into store 2.
2950*6777b538SAndroid Build Coastguard Worker   scoped_refptr<MockPersistentCookieStore> store2 =
2951*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<MockPersistentCookieStore>();
2952*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<CanonicalCookie>> load_expectation;
2953*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, store->commands().size());
2954*6777b538SAndroid Build Coastguard Worker   for (const CookieStoreCommand& command : store->commands()) {
2955*6777b538SAndroid Build Coastguard Worker     ASSERT_EQ(command.type, CookieStoreCommand::ADD);
2956*6777b538SAndroid Build Coastguard Worker     load_expectation.push_back(
2957*6777b538SAndroid Build Coastguard Worker         std::make_unique<CanonicalCookie>(command.cookie));
2958*6777b538SAndroid Build Coastguard Worker   }
2959*6777b538SAndroid Build Coastguard Worker   store2->SetLoadExpectation(true, std::move(load_expectation));
2960*6777b538SAndroid Build Coastguard Worker 
2961*6777b538SAndroid Build Coastguard Worker   // Now read them in. Should get two cookies, not one.
2962*6777b538SAndroid Build Coastguard Worker   {
2963*6777b538SAndroid Build Coastguard Worker     CookieMonster cmin(store2.get(), net::NetLog::Get());
2964*6777b538SAndroid Build Coastguard Worker     CookieList cookies(GetAllCookies(&cmin));
2965*6777b538SAndroid Build Coastguard Worker     ASSERT_EQ(2u, cookies.size());
2966*6777b538SAndroid Build Coastguard Worker   }
2967*6777b538SAndroid Build Coastguard Worker }
2968*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,CookieListOrdering)2969*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, CookieListOrdering) {
2970*6777b538SAndroid Build Coastguard Worker   // Put a random set of cookies into a monster and make sure
2971*6777b538SAndroid Build Coastguard Worker   // they're returned in the right order.
2972*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
2973*6777b538SAndroid Build Coastguard Worker 
2974*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
2975*6777b538SAndroid Build Coastguard Worker       SetCookie(cm.get(), GURL("http://d.c.b.a.foo.com/aa/x.html"), "c=1"));
2976*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), GURL("http://b.a.foo.com/aa/bb/cc/x.html"),
2977*6777b538SAndroid Build Coastguard Worker                         "d=1; domain=b.a.foo.com"));
2978*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), GURL("http://b.a.foo.com/aa/bb/cc/x.html"),
2979*6777b538SAndroid Build Coastguard Worker                         "a=4; domain=b.a.foo.com"));
2980*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), GURL("http://c.b.a.foo.com/aa/bb/cc/x.html"),
2981*6777b538SAndroid Build Coastguard Worker                         "e=1; domain=c.b.a.foo.com"));
2982*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
2983*6777b538SAndroid Build Coastguard Worker       SetCookie(cm.get(), GURL("http://d.c.b.a.foo.com/aa/bb/x.html"), "b=1"));
2984*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), GURL("http://news.bbc.co.uk/midpath/x.html"),
2985*6777b538SAndroid Build Coastguard Worker                         "g=10"));
2986*6777b538SAndroid Build Coastguard Worker   {
2987*6777b538SAndroid Build Coastguard Worker     unsigned int i = 0;
2988*6777b538SAndroid Build Coastguard Worker     CookieList cookies(GetAllCookiesForURL(
2989*6777b538SAndroid Build Coastguard Worker         cm.get(), GURL("http://d.c.b.a.foo.com/aa/bb/cc/dd")));
2990*6777b538SAndroid Build Coastguard Worker     ASSERT_EQ(5u, cookies.size());
2991*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ("d", cookies[i++].Name());
2992*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ("a", cookies[i++].Name());
2993*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ("e", cookies[i++].Name());
2994*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ("b", cookies[i++].Name());
2995*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ("c", cookies[i++].Name());
2996*6777b538SAndroid Build Coastguard Worker   }
2997*6777b538SAndroid Build Coastguard Worker 
2998*6777b538SAndroid Build Coastguard Worker   {
2999*6777b538SAndroid Build Coastguard Worker     unsigned int i = 0;
3000*6777b538SAndroid Build Coastguard Worker     CookieList cookies(GetAllCookies(cm.get()));
3001*6777b538SAndroid Build Coastguard Worker     ASSERT_EQ(6u, cookies.size());
3002*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ("d", cookies[i++].Name());
3003*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ("a", cookies[i++].Name());
3004*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ("e", cookies[i++].Name());
3005*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ("g", cookies[i++].Name());
3006*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ("b", cookies[i++].Name());
3007*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ("c", cookies[i++].Name());
3008*6777b538SAndroid Build Coastguard Worker   }
3009*6777b538SAndroid Build Coastguard Worker }
3010*6777b538SAndroid Build Coastguard Worker 
3011*6777b538SAndroid Build Coastguard Worker // These garbage collection tests and CookieMonstertest.TestGCTimes (in
3012*6777b538SAndroid Build Coastguard Worker // cookie_monster_perftest.cc) are somewhat complementary.  These tests probe
3013*6777b538SAndroid Build Coastguard Worker // for whether garbage collection always happens when it should (i.e. that we
3014*6777b538SAndroid Build Coastguard Worker // actually get rid of cookies when we should).  The perftest is probing for
3015*6777b538SAndroid Build Coastguard Worker // whether garbage collection happens when it shouldn't.  See comments
3016*6777b538SAndroid Build Coastguard Worker // before that test for more details.
3017*6777b538SAndroid Build Coastguard Worker 
3018*6777b538SAndroid Build Coastguard Worker // Check to make sure that a whole lot of recent cookies doesn't get rid of
3019*6777b538SAndroid Build Coastguard Worker // anything after garbage collection is checked for.
TEST_F(CookieMonsterTest,GarbageCollectionKeepsRecentEphemeralCookies)3020*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, GarbageCollectionKeepsRecentEphemeralCookies) {
3021*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<CookieMonster> cm(
3022*6777b538SAndroid Build Coastguard Worker       CreateMonsterForGC(CookieMonster::kMaxCookies * 2 /* num_cookies */));
3023*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieMonster::kMaxCookies * 2, GetAllCookies(cm.get()).size());
3024*6777b538SAndroid Build Coastguard Worker   // Will trigger GC.
3025*6777b538SAndroid Build Coastguard Worker   SetCookie(cm.get(), GURL("http://newdomain.com"), "b=2");
3026*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieMonster::kMaxCookies * 2 + 1, GetAllCookies(cm.get()).size());
3027*6777b538SAndroid Build Coastguard Worker }
3028*6777b538SAndroid Build Coastguard Worker 
3029*6777b538SAndroid Build Coastguard Worker // A whole lot of recent cookies; GC shouldn't happen.
TEST_F(CookieMonsterTest,GarbageCollectionKeepsRecentCookies)3030*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, GarbageCollectionKeepsRecentCookies) {
3031*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<CookieMonster> cm = CreateMonsterFromStoreForGC(
3032*6777b538SAndroid Build Coastguard Worker       CookieMonster::kMaxCookies * 2 /* num_cookies */, 0 /* num_old_cookies */,
3033*6777b538SAndroid Build Coastguard Worker       0, 0, CookieMonster::kSafeFromGlobalPurgeDays * 2);
3034*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieMonster::kMaxCookies * 2, GetAllCookies(cm.get()).size());
3035*6777b538SAndroid Build Coastguard Worker   // Will trigger GC.
3036*6777b538SAndroid Build Coastguard Worker   SetCookie(cm.get(), GURL("http://newdomain.com"), "b=2");
3037*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieMonster::kMaxCookies * 2 + 1, GetAllCookies(cm.get()).size());
3038*6777b538SAndroid Build Coastguard Worker }
3039*6777b538SAndroid Build Coastguard Worker 
3040*6777b538SAndroid Build Coastguard Worker // Test case where there are more than kMaxCookies - kPurgeCookies recent
3041*6777b538SAndroid Build Coastguard Worker // cookies. All old cookies should be garbage collected, all recent cookies
3042*6777b538SAndroid Build Coastguard Worker // kept.
TEST_F(CookieMonsterTest,GarbageCollectionKeepsOnlyRecentCookies)3043*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, GarbageCollectionKeepsOnlyRecentCookies) {
3044*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<CookieMonster> cm = CreateMonsterFromStoreForGC(
3045*6777b538SAndroid Build Coastguard Worker       CookieMonster::kMaxCookies * 2 /* num_cookies */,
3046*6777b538SAndroid Build Coastguard Worker       CookieMonster::kMaxCookies / 2 /* num_old_cookies */, 0, 0,
3047*6777b538SAndroid Build Coastguard Worker       CookieMonster::kSafeFromGlobalPurgeDays * 2);
3048*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieMonster::kMaxCookies * 2, GetAllCookies(cm.get()).size());
3049*6777b538SAndroid Build Coastguard Worker   // Will trigger GC.
3050*6777b538SAndroid Build Coastguard Worker   SetCookie(cm.get(), GURL("http://newdomain.com"), "b=2");
3051*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieMonster::kMaxCookies * 2 - CookieMonster::kMaxCookies / 2 + 1,
3052*6777b538SAndroid Build Coastguard Worker             GetAllCookies(cm.get()).size());
3053*6777b538SAndroid Build Coastguard Worker }
3054*6777b538SAndroid Build Coastguard Worker 
3055*6777b538SAndroid Build Coastguard Worker // Test case where there are exactly kMaxCookies - kPurgeCookies recent cookies.
3056*6777b538SAndroid Build Coastguard Worker // All old cookies should be deleted.
TEST_F(CookieMonsterTest,GarbageCollectionExactlyAllOldCookiesDeleted)3057*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, GarbageCollectionExactlyAllOldCookiesDeleted) {
3058*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<CookieMonster> cm = CreateMonsterFromStoreForGC(
3059*6777b538SAndroid Build Coastguard Worker       CookieMonster::kMaxCookies * 2 /* num_cookies */,
3060*6777b538SAndroid Build Coastguard Worker       CookieMonster::kMaxCookies + CookieMonster::kPurgeCookies +
3061*6777b538SAndroid Build Coastguard Worker           1 /* num_old_cookies */,
3062*6777b538SAndroid Build Coastguard Worker       0, 0, CookieMonster::kSafeFromGlobalPurgeDays * 2);
3063*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieMonster::kMaxCookies * 2, GetAllCookies(cm.get()).size());
3064*6777b538SAndroid Build Coastguard Worker   // Will trigger GC.
3065*6777b538SAndroid Build Coastguard Worker   SetCookie(cm.get(), GURL("http://newdomain.com"), "b=2");
3066*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieMonster::kMaxCookies - CookieMonster::kPurgeCookies,
3067*6777b538SAndroid Build Coastguard Worker             GetAllCookies(cm.get()).size());
3068*6777b538SAndroid Build Coastguard Worker }
3069*6777b538SAndroid Build Coastguard Worker 
3070*6777b538SAndroid Build Coastguard Worker // Test case where there are less than kMaxCookies - kPurgeCookies recent
3071*6777b538SAndroid Build Coastguard Worker // cookies. Enough old cookies should be deleted to reach kMaxCookies -
3072*6777b538SAndroid Build Coastguard Worker // kPurgeCookies total cookies, but no more. Some old cookies should be kept.
TEST_F(CookieMonsterTest,GarbageCollectionTriggers5)3073*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, GarbageCollectionTriggers5) {
3074*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<CookieMonster> cm = CreateMonsterFromStoreForGC(
3075*6777b538SAndroid Build Coastguard Worker       CookieMonster::kMaxCookies * 2 /* num_cookies */,
3076*6777b538SAndroid Build Coastguard Worker       CookieMonster::kMaxCookies * 3 / 2 /* num_old_cookies */, 0, 0,
3077*6777b538SAndroid Build Coastguard Worker       CookieMonster::kSafeFromGlobalPurgeDays * 2);
3078*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieMonster::kMaxCookies * 2, GetAllCookies(cm.get()).size());
3079*6777b538SAndroid Build Coastguard Worker   // Will trigger GC.
3080*6777b538SAndroid Build Coastguard Worker   SetCookie(cm.get(), GURL("http://newdomain.com"), "b=2");
3081*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieMonster::kMaxCookies - CookieMonster::kPurgeCookies,
3082*6777b538SAndroid Build Coastguard Worker             GetAllCookies(cm.get()).size());
3083*6777b538SAndroid Build Coastguard Worker }
3084*6777b538SAndroid Build Coastguard Worker 
3085*6777b538SAndroid Build Coastguard Worker // Tests garbage collection when there are only secure cookies.
3086*6777b538SAndroid Build Coastguard Worker // See https://crbug/730000
TEST_F(CookieMonsterTest,GarbageCollectWithSecureCookiesOnly)3087*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, GarbageCollectWithSecureCookiesOnly) {
3088*6777b538SAndroid Build Coastguard Worker   // Create a CookieMonster at its cookie limit. A bit confusing, but the second
3089*6777b538SAndroid Build Coastguard Worker   // number is a subset of the first number.
3090*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<CookieMonster> cm = CreateMonsterFromStoreForGC(
3091*6777b538SAndroid Build Coastguard Worker       CookieMonster::kMaxCookies /* num_secure_cookies */,
3092*6777b538SAndroid Build Coastguard Worker       CookieMonster::kMaxCookies /* num_old_secure_cookies */,
3093*6777b538SAndroid Build Coastguard Worker       0 /* num_non_secure_cookies */, 0 /* num_old_non_secure_cookies */,
3094*6777b538SAndroid Build Coastguard Worker       CookieMonster::kSafeFromGlobalPurgeDays * 2 /* days_old */);
3095*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieMonster::kMaxCookies, GetAllCookies(cm.get()).size());
3096*6777b538SAndroid Build Coastguard Worker 
3097*6777b538SAndroid Build Coastguard Worker   // Trigger purge with a secure cookie (So there are still no insecure
3098*6777b538SAndroid Build Coastguard Worker   // cookies).
3099*6777b538SAndroid Build Coastguard Worker   SetCookie(cm.get(), GURL("https://newdomain.com"), "b=2; Secure");
3100*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieMonster::kMaxCookies - CookieMonster::kPurgeCookies,
3101*6777b538SAndroid Build Coastguard Worker             GetAllCookies(cm.get()).size());
3102*6777b538SAndroid Build Coastguard Worker }
3103*6777b538SAndroid Build Coastguard Worker 
3104*6777b538SAndroid Build Coastguard Worker // Tests that if the main load event happens before the loaded event for a
3105*6777b538SAndroid Build Coastguard Worker // particular key, the tasks for that key run first.
TEST_F(CookieMonsterTest,WhileLoadingLoadCompletesBeforeKeyLoadCompletes)3106*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, WhileLoadingLoadCompletesBeforeKeyLoadCompletes) {
3107*6777b538SAndroid Build Coastguard Worker   const GURL kUrl = GURL(kTopLevelDomainPlus1);
3108*6777b538SAndroid Build Coastguard Worker 
3109*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
3110*6777b538SAndroid Build Coastguard Worker   store->set_store_load_commands(true);
3111*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
3112*6777b538SAndroid Build Coastguard Worker 
3113*6777b538SAndroid Build Coastguard Worker   auto cookie =
3114*6777b538SAndroid Build Coastguard Worker       CanonicalCookie::CreateForTesting(kUrl, "a=b", base::Time::Now());
3115*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<CookieAccessResult> set_cookie_callback;
3116*6777b538SAndroid Build Coastguard Worker   cm->SetCanonicalCookieAsync(std::move(cookie), kUrl,
3117*6777b538SAndroid Build Coastguard Worker                               CookieOptions::MakeAllInclusive(),
3118*6777b538SAndroid Build Coastguard Worker                               set_cookie_callback.MakeCallback());
3119*6777b538SAndroid Build Coastguard Worker 
3120*6777b538SAndroid Build Coastguard Worker   GetAllCookiesCallback get_cookies_callback1;
3121*6777b538SAndroid Build Coastguard Worker   cm->GetAllCookiesAsync(get_cookies_callback1.MakeCallback());
3122*6777b538SAndroid Build Coastguard Worker 
3123*6777b538SAndroid Build Coastguard Worker   // Two load events should have been queued.
3124*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(2u, store->commands().size());
3125*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(CookieStoreCommand::LOAD, store->commands()[0].type);
3126*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(CookieStoreCommand::LOAD_COOKIES_FOR_KEY,
3127*6777b538SAndroid Build Coastguard Worker             store->commands()[1].type);
3128*6777b538SAndroid Build Coastguard Worker 
3129*6777b538SAndroid Build Coastguard Worker   // The main load completes first (With no cookies).
3130*6777b538SAndroid Build Coastguard Worker   store->TakeCallbackAt(0).Run(std::vector<std::unique_ptr<CanonicalCookie>>());
3131*6777b538SAndroid Build Coastguard Worker 
3132*6777b538SAndroid Build Coastguard Worker   // The tasks should run in order, and the get should see the cookies.
3133*6777b538SAndroid Build Coastguard Worker 
3134*6777b538SAndroid Build Coastguard Worker   set_cookie_callback.WaitUntilDone();
3135*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(set_cookie_callback.result().status.IsInclude());
3136*6777b538SAndroid Build Coastguard Worker 
3137*6777b538SAndroid Build Coastguard Worker   get_cookies_callback1.WaitUntilDone();
3138*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, get_cookies_callback1.cookies().size());
3139*6777b538SAndroid Build Coastguard Worker 
3140*6777b538SAndroid Build Coastguard Worker   // The loaded for key event completes late, with not cookies (Since they
3141*6777b538SAndroid Build Coastguard Worker   // were already loaded).
3142*6777b538SAndroid Build Coastguard Worker   store->TakeCallbackAt(1).Run(std::vector<std::unique_ptr<CanonicalCookie>>());
3143*6777b538SAndroid Build Coastguard Worker 
3144*6777b538SAndroid Build Coastguard Worker   // The just set cookie should still be in the store.
3145*6777b538SAndroid Build Coastguard Worker   GetAllCookiesCallback get_cookies_callback2;
3146*6777b538SAndroid Build Coastguard Worker   cm->GetAllCookiesAsync(get_cookies_callback2.MakeCallback());
3147*6777b538SAndroid Build Coastguard Worker   get_cookies_callback2.WaitUntilDone();
3148*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, get_cookies_callback2.cookies().size());
3149*6777b538SAndroid Build Coastguard Worker }
3150*6777b538SAndroid Build Coastguard Worker 
3151*6777b538SAndroid Build Coastguard Worker // Tests that case that DeleteAll is waiting for load to complete, and then a
3152*6777b538SAndroid Build Coastguard Worker // get is queued. The get should wait to run until after all the cookies are
3153*6777b538SAndroid Build Coastguard Worker // retrieved, and should return nothing, since all cookies were just deleted.
TEST_F(CookieMonsterTest,WhileLoadingDeleteAllGetForURL)3154*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, WhileLoadingDeleteAllGetForURL) {
3155*6777b538SAndroid Build Coastguard Worker   const GURL kUrl = GURL(kTopLevelDomainPlus1);
3156*6777b538SAndroid Build Coastguard Worker 
3157*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
3158*6777b538SAndroid Build Coastguard Worker   store->set_store_load_commands(true);
3159*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
3160*6777b538SAndroid Build Coastguard Worker 
3161*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<uint32_t> delete_callback;
3162*6777b538SAndroid Build Coastguard Worker   cm->DeleteAllAsync(delete_callback.MakeCallback());
3163*6777b538SAndroid Build Coastguard Worker 
3164*6777b538SAndroid Build Coastguard Worker   GetCookieListCallback get_cookie_list_callback;
3165*6777b538SAndroid Build Coastguard Worker   cm->GetCookieListWithOptionsAsync(kUrl, CookieOptions::MakeAllInclusive(),
3166*6777b538SAndroid Build Coastguard Worker                                     CookiePartitionKeyCollection(),
3167*6777b538SAndroid Build Coastguard Worker                                     get_cookie_list_callback.MakeCallback());
3168*6777b538SAndroid Build Coastguard Worker 
3169*6777b538SAndroid Build Coastguard Worker   // Only the main load should have been queued.
3170*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(1u, store->commands().size());
3171*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(CookieStoreCommand::LOAD, store->commands()[0].type);
3172*6777b538SAndroid Build Coastguard Worker 
3173*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<CanonicalCookie>> cookies;
3174*6777b538SAndroid Build Coastguard Worker   // When passed to the CookieMonster, it takes ownership of the pointed to
3175*6777b538SAndroid Build Coastguard Worker   // cookies.
3176*6777b538SAndroid Build Coastguard Worker   cookies.push_back(
3177*6777b538SAndroid Build Coastguard Worker       CanonicalCookie::CreateForTesting(kUrl, "a=b", base::Time::Now()));
3178*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(cookies[0]);
3179*6777b538SAndroid Build Coastguard Worker   store->TakeCallbackAt(0).Run(std::move(cookies));
3180*6777b538SAndroid Build Coastguard Worker 
3181*6777b538SAndroid Build Coastguard Worker   delete_callback.WaitUntilDone();
3182*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, delete_callback.result());
3183*6777b538SAndroid Build Coastguard Worker 
3184*6777b538SAndroid Build Coastguard Worker   get_cookie_list_callback.WaitUntilDone();
3185*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, get_cookie_list_callback.cookies().size());
3186*6777b538SAndroid Build Coastguard Worker }
3187*6777b538SAndroid Build Coastguard Worker 
3188*6777b538SAndroid Build Coastguard Worker // Tests that a set cookie call sandwiched between two get all cookies, all
3189*6777b538SAndroid Build Coastguard Worker // before load completes, affects the first but not the second. The set should
3190*6777b538SAndroid Build Coastguard Worker // also not trigger a LoadCookiesForKey (As that could complete only after the
3191*6777b538SAndroid Build Coastguard Worker // main load for the store).
TEST_F(CookieMonsterTest,WhileLoadingGetAllSetGetAll)3192*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, WhileLoadingGetAllSetGetAll) {
3193*6777b538SAndroid Build Coastguard Worker   const GURL kUrl = GURL(kTopLevelDomainPlus1);
3194*6777b538SAndroid Build Coastguard Worker 
3195*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
3196*6777b538SAndroid Build Coastguard Worker   store->set_store_load_commands(true);
3197*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
3198*6777b538SAndroid Build Coastguard Worker 
3199*6777b538SAndroid Build Coastguard Worker   GetAllCookiesCallback get_cookies_callback1;
3200*6777b538SAndroid Build Coastguard Worker   cm->GetAllCookiesAsync(get_cookies_callback1.MakeCallback());
3201*6777b538SAndroid Build Coastguard Worker 
3202*6777b538SAndroid Build Coastguard Worker   auto cookie =
3203*6777b538SAndroid Build Coastguard Worker       CanonicalCookie::CreateForTesting(kUrl, "a=b", base::Time::Now());
3204*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<CookieAccessResult> set_cookie_callback;
3205*6777b538SAndroid Build Coastguard Worker   cm->SetCanonicalCookieAsync(std::move(cookie), kUrl,
3206*6777b538SAndroid Build Coastguard Worker                               CookieOptions::MakeAllInclusive(),
3207*6777b538SAndroid Build Coastguard Worker                               set_cookie_callback.MakeCallback());
3208*6777b538SAndroid Build Coastguard Worker 
3209*6777b538SAndroid Build Coastguard Worker   GetAllCookiesCallback get_cookies_callback2;
3210*6777b538SAndroid Build Coastguard Worker   cm->GetAllCookiesAsync(get_cookies_callback2.MakeCallback());
3211*6777b538SAndroid Build Coastguard Worker 
3212*6777b538SAndroid Build Coastguard Worker   // Only the main load should have been queued.
3213*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(1u, store->commands().size());
3214*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(CookieStoreCommand::LOAD, store->commands()[0].type);
3215*6777b538SAndroid Build Coastguard Worker 
3216*6777b538SAndroid Build Coastguard Worker   // The load completes (With no cookies).
3217*6777b538SAndroid Build Coastguard Worker   store->TakeCallbackAt(0).Run(std::vector<std::unique_ptr<CanonicalCookie>>());
3218*6777b538SAndroid Build Coastguard Worker 
3219*6777b538SAndroid Build Coastguard Worker   get_cookies_callback1.WaitUntilDone();
3220*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, get_cookies_callback1.cookies().size());
3221*6777b538SAndroid Build Coastguard Worker 
3222*6777b538SAndroid Build Coastguard Worker   set_cookie_callback.WaitUntilDone();
3223*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(set_cookie_callback.result().status.IsInclude());
3224*6777b538SAndroid Build Coastguard Worker 
3225*6777b538SAndroid Build Coastguard Worker   get_cookies_callback2.WaitUntilDone();
3226*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, get_cookies_callback2.cookies().size());
3227*6777b538SAndroid Build Coastguard Worker }
3228*6777b538SAndroid Build Coastguard Worker 
3229*6777b538SAndroid Build Coastguard Worker namespace {
3230*6777b538SAndroid Build Coastguard Worker 
RunClosureOnAllCookiesReceived(base::OnceClosure closure,const CookieList & cookie_list)3231*6777b538SAndroid Build Coastguard Worker void RunClosureOnAllCookiesReceived(base::OnceClosure closure,
3232*6777b538SAndroid Build Coastguard Worker                                     const CookieList& cookie_list) {
3233*6777b538SAndroid Build Coastguard Worker   std::move(closure).Run();
3234*6777b538SAndroid Build Coastguard Worker }
3235*6777b538SAndroid Build Coastguard Worker 
3236*6777b538SAndroid Build Coastguard Worker }  // namespace
3237*6777b538SAndroid Build Coastguard Worker 
3238*6777b538SAndroid Build Coastguard Worker // Tests that if a single cookie task is queued as a result of a task performed
3239*6777b538SAndroid Build Coastguard Worker // on all cookies when loading completes, it will be run after any already
3240*6777b538SAndroid Build Coastguard Worker // queued tasks.
TEST_F(CookieMonsterTest,CheckOrderOfCookieTaskQueueWhenLoadingCompletes)3241*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, CheckOrderOfCookieTaskQueueWhenLoadingCompletes) {
3242*6777b538SAndroid Build Coastguard Worker   const GURL kUrl = GURL(kTopLevelDomainPlus1);
3243*6777b538SAndroid Build Coastguard Worker 
3244*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
3245*6777b538SAndroid Build Coastguard Worker   store->set_store_load_commands(true);
3246*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
3247*6777b538SAndroid Build Coastguard Worker 
3248*6777b538SAndroid Build Coastguard Worker   // Get all cookies task that queues a task to set a cookie when executed.
3249*6777b538SAndroid Build Coastguard Worker   auto cookie =
3250*6777b538SAndroid Build Coastguard Worker       CanonicalCookie::CreateForTesting(kUrl, "a=b", base::Time::Now());
3251*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<CookieAccessResult> set_cookie_callback;
3252*6777b538SAndroid Build Coastguard Worker   cm->GetAllCookiesAsync(base::BindOnce(
3253*6777b538SAndroid Build Coastguard Worker       &RunClosureOnAllCookiesReceived,
3254*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&CookieStore::SetCanonicalCookieAsync,
3255*6777b538SAndroid Build Coastguard Worker                      base::Unretained(cm.get()), std::move(cookie), kUrl,
3256*6777b538SAndroid Build Coastguard Worker                      CookieOptions::MakeAllInclusive(),
3257*6777b538SAndroid Build Coastguard Worker                      set_cookie_callback.MakeCallback(), std::nullopt)));
3258*6777b538SAndroid Build Coastguard Worker 
3259*6777b538SAndroid Build Coastguard Worker   // Get cookie task. Queued before the delete task is executed, so should not
3260*6777b538SAndroid Build Coastguard Worker   // see the set cookie.
3261*6777b538SAndroid Build Coastguard Worker   GetAllCookiesCallback get_cookies_callback1;
3262*6777b538SAndroid Build Coastguard Worker   cm->GetAllCookiesAsync(get_cookies_callback1.MakeCallback());
3263*6777b538SAndroid Build Coastguard Worker 
3264*6777b538SAndroid Build Coastguard Worker   // Only the main load should have been queued.
3265*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(1u, store->commands().size());
3266*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(CookieStoreCommand::LOAD, store->commands()[0].type);
3267*6777b538SAndroid Build Coastguard Worker 
3268*6777b538SAndroid Build Coastguard Worker   // The load completes.
3269*6777b538SAndroid Build Coastguard Worker   store->TakeCallbackAt(0).Run(std::vector<std::unique_ptr<CanonicalCookie>>());
3270*6777b538SAndroid Build Coastguard Worker 
3271*6777b538SAndroid Build Coastguard Worker   // The get cookies call should see no cookies set.
3272*6777b538SAndroid Build Coastguard Worker   get_cookies_callback1.WaitUntilDone();
3273*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, get_cookies_callback1.cookies().size());
3274*6777b538SAndroid Build Coastguard Worker 
3275*6777b538SAndroid Build Coastguard Worker   set_cookie_callback.WaitUntilDone();
3276*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(set_cookie_callback.result().status.IsInclude());
3277*6777b538SAndroid Build Coastguard Worker 
3278*6777b538SAndroid Build Coastguard Worker   // A subsequent get cookies call should see the new cookie.
3279*6777b538SAndroid Build Coastguard Worker   GetAllCookiesCallback get_cookies_callback2;
3280*6777b538SAndroid Build Coastguard Worker   cm->GetAllCookiesAsync(get_cookies_callback2.MakeCallback());
3281*6777b538SAndroid Build Coastguard Worker   get_cookies_callback2.WaitUntilDone();
3282*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, get_cookies_callback2.cookies().size());
3283*6777b538SAndroid Build Coastguard Worker }
3284*6777b538SAndroid Build Coastguard Worker 
3285*6777b538SAndroid Build Coastguard Worker // Test that FlushStore() is forwarded to the store and callbacks are posted.
TEST_F(CookieMonsterTest,FlushStore)3286*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, FlushStore) {
3287*6777b538SAndroid Build Coastguard Worker   auto counter = base::MakeRefCounted<CallbackCounter>();
3288*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<FlushablePersistentStore>();
3289*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store, net::NetLog::Get());
3290*6777b538SAndroid Build Coastguard Worker 
3291*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0, store->flush_count());
3292*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0, counter->callback_count());
3293*6777b538SAndroid Build Coastguard Worker 
3294*6777b538SAndroid Build Coastguard Worker   // Before initialization, FlushStore() should just run the callback.
3295*6777b538SAndroid Build Coastguard Worker   cm->FlushStore(base::BindOnce(&CallbackCounter::Callback, counter));
3296*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
3297*6777b538SAndroid Build Coastguard Worker 
3298*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0, store->flush_count());
3299*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(1, counter->callback_count());
3300*6777b538SAndroid Build Coastguard Worker 
3301*6777b538SAndroid Build Coastguard Worker   // NULL callback is safe.
3302*6777b538SAndroid Build Coastguard Worker   cm->FlushStore(base::OnceClosure());
3303*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
3304*6777b538SAndroid Build Coastguard Worker 
3305*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0, store->flush_count());
3306*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(1, counter->callback_count());
3307*6777b538SAndroid Build Coastguard Worker 
3308*6777b538SAndroid Build Coastguard Worker   // After initialization, FlushStore() should delegate to the store.
3309*6777b538SAndroid Build Coastguard Worker   GetAllCookies(cm.get());  // Force init.
3310*6777b538SAndroid Build Coastguard Worker   cm->FlushStore(base::BindOnce(&CallbackCounter::Callback, counter));
3311*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
3312*6777b538SAndroid Build Coastguard Worker 
3313*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(1, store->flush_count());
3314*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(2, counter->callback_count());
3315*6777b538SAndroid Build Coastguard Worker 
3316*6777b538SAndroid Build Coastguard Worker   // NULL callback is still safe.
3317*6777b538SAndroid Build Coastguard Worker   cm->FlushStore(base::DoNothing());
3318*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
3319*6777b538SAndroid Build Coastguard Worker 
3320*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(2, store->flush_count());
3321*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(2, counter->callback_count());
3322*6777b538SAndroid Build Coastguard Worker 
3323*6777b538SAndroid Build Coastguard Worker   // If there's no backing store, FlushStore() is always a safe no-op.
3324*6777b538SAndroid Build Coastguard Worker   cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
3325*6777b538SAndroid Build Coastguard Worker   GetAllCookies(cm.get());  // Force init.
3326*6777b538SAndroid Build Coastguard Worker   cm->FlushStore(base::DoNothing());
3327*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
3328*6777b538SAndroid Build Coastguard Worker 
3329*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(2, counter->callback_count());
3330*6777b538SAndroid Build Coastguard Worker 
3331*6777b538SAndroid Build Coastguard Worker   cm->FlushStore(base::BindOnce(&CallbackCounter::Callback, counter));
3332*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
3333*6777b538SAndroid Build Coastguard Worker 
3334*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(3, counter->callback_count());
3335*6777b538SAndroid Build Coastguard Worker }
3336*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,SetAllCookies)3337*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, SetAllCookies) {
3338*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<FlushablePersistentStore>();
3339*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
3340*6777b538SAndroid Build Coastguard Worker   cm->SetPersistSessionCookies(true);
3341*6777b538SAndroid Build Coastguard Worker 
3342*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), "U=V; path=/"));
3343*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), "W=X; path=/foo"));
3344*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), "Y=Z; path=/"));
3345*6777b538SAndroid Build Coastguard Worker 
3346*6777b538SAndroid Build Coastguard Worker   CookieList list;
3347*6777b538SAndroid Build Coastguard Worker   list.push_back(*CanonicalCookie::CreateUnsafeCookieForTesting(
3348*6777b538SAndroid Build Coastguard Worker       "A", "B", "." + http_www_foo_.url().host(), "/", base::Time::Now(),
3349*6777b538SAndroid Build Coastguard Worker       base::Time(), base::Time(), base::Time(), false, false,
3350*6777b538SAndroid Build Coastguard Worker       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT));
3351*6777b538SAndroid Build Coastguard Worker   list.push_back(*CanonicalCookie::CreateUnsafeCookieForTesting(
3352*6777b538SAndroid Build Coastguard Worker       "C", "D", "." + http_www_foo_.url().host(), "/bar", base::Time::Now(),
3353*6777b538SAndroid Build Coastguard Worker       base::Time(), base::Time(), base::Time(), false, false,
3354*6777b538SAndroid Build Coastguard Worker       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT));
3355*6777b538SAndroid Build Coastguard Worker   list.push_back(*CanonicalCookie::CreateUnsafeCookieForTesting(
3356*6777b538SAndroid Build Coastguard Worker       "W", "X", "." + http_www_foo_.url().host(), "/", base::Time::Now(),
3357*6777b538SAndroid Build Coastguard Worker       base::Time(), base::Time(), base::Time(), false, false,
3358*6777b538SAndroid Build Coastguard Worker       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT));
3359*6777b538SAndroid Build Coastguard Worker   list.push_back(*CanonicalCookie::CreateUnsafeCookieForTesting(
3360*6777b538SAndroid Build Coastguard Worker       "__Host-Y", "Z", https_www_foo_.url().host(), "/", base::Time::Now(),
3361*6777b538SAndroid Build Coastguard Worker       base::Time(), base::Time(), base::Time(), true, false,
3362*6777b538SAndroid Build Coastguard Worker       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
3363*6777b538SAndroid Build Coastguard Worker       CookiePartitionKey::FromURLForTesting(GURL("https://toplevelsite.com"))));
3364*6777b538SAndroid Build Coastguard Worker   // Expired cookie, should not be stored.
3365*6777b538SAndroid Build Coastguard Worker   list.push_back(*CanonicalCookie::CreateUnsafeCookieForTesting(
3366*6777b538SAndroid Build Coastguard Worker       "expired", "foobar", https_www_foo_.url().host(), "/",
3367*6777b538SAndroid Build Coastguard Worker       base::Time::Now() - base::Days(1), base::Time::Now() - base::Days(2),
3368*6777b538SAndroid Build Coastguard Worker       base::Time(), base::Time(), /*secure=*/true, /*httponly=*/false,
3369*6777b538SAndroid Build Coastguard Worker       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT));
3370*6777b538SAndroid Build Coastguard Worker 
3371*6777b538SAndroid Build Coastguard Worker   // SetAllCookies must not flush.
3372*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0, store->flush_count());
3373*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetAllCookies(cm.get(), list));
3374*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, store->flush_count());
3375*6777b538SAndroid Build Coastguard Worker 
3376*6777b538SAndroid Build Coastguard Worker   CookieList cookies = GetAllCookies(cm.get());
3377*6777b538SAndroid Build Coastguard Worker   size_t expected_size = 4;  // "A", "W" and "Y". "U" is gone.
3378*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(expected_size, cookies.size());
3379*6777b538SAndroid Build Coastguard Worker   auto it = cookies.begin();
3380*6777b538SAndroid Build Coastguard Worker 
3381*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(it != cookies.end());
3382*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("C", it->Name());
3383*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("D", it->Value());
3384*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("/bar", it->Path());  // The path has been updated.
3385*6777b538SAndroid Build Coastguard Worker 
3386*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(++it != cookies.end());
3387*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("A", it->Name());
3388*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("B", it->Value());
3389*6777b538SAndroid Build Coastguard Worker 
3390*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(++it != cookies.end());
3391*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("W", it->Name());
3392*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("X", it->Value());
3393*6777b538SAndroid Build Coastguard Worker 
3394*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(++it != cookies.end());
3395*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("__Host-Y", it->Name());
3396*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("Z", it->Value());
3397*6777b538SAndroid Build Coastguard Worker 
3398*6777b538SAndroid Build Coastguard Worker   cm = nullptr;
3399*6777b538SAndroid Build Coastguard Worker   auto entries = net_log_.GetEntries();
3400*6777b538SAndroid Build Coastguard Worker   size_t pos = ExpectLogContainsSomewhere(
3401*6777b538SAndroid Build Coastguard Worker       entries, 0, NetLogEventType::COOKIE_STORE_ALIVE, NetLogEventPhase::BEGIN);
3402*6777b538SAndroid Build Coastguard Worker   pos = ExpectLogContainsSomewhere(
3403*6777b538SAndroid Build Coastguard Worker       entries, pos, NetLogEventType::COOKIE_STORE_SESSION_PERSISTENCE,
3404*6777b538SAndroid Build Coastguard Worker       NetLogEventPhase::NONE);
3405*6777b538SAndroid Build Coastguard Worker   pos = ExpectLogContainsSomewhere(entries, pos,
3406*6777b538SAndroid Build Coastguard Worker                                    NetLogEventType::COOKIE_STORE_COOKIE_ADDED,
3407*6777b538SAndroid Build Coastguard Worker                                    NetLogEventPhase::NONE);
3408*6777b538SAndroid Build Coastguard Worker   ExpectLogContainsSomewhere(entries, pos, NetLogEventType::COOKIE_STORE_ALIVE,
3409*6777b538SAndroid Build Coastguard Worker                              NetLogEventPhase::END);
3410*6777b538SAndroid Build Coastguard Worker }
3411*6777b538SAndroid Build Coastguard Worker 
3412*6777b538SAndroid Build Coastguard Worker // Check that DeleteAll does flush (as a quick check that flush_count() works).
TEST_F(CookieMonsterTest,DeleteAll)3413*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, DeleteAll) {
3414*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<FlushablePersistentStore>();
3415*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
3416*6777b538SAndroid Build Coastguard Worker   cm->SetPersistSessionCookies(true);
3417*6777b538SAndroid Build Coastguard Worker 
3418*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), "X=Y; path=/"));
3419*6777b538SAndroid Build Coastguard Worker 
3420*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0, store->flush_count());
3421*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, DeleteAll(cm.get()));
3422*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, store->flush_count());
3423*6777b538SAndroid Build Coastguard Worker 
3424*6777b538SAndroid Build Coastguard Worker   cm = nullptr;
3425*6777b538SAndroid Build Coastguard Worker   auto entries = net_log_.GetEntries();
3426*6777b538SAndroid Build Coastguard Worker   size_t pos = ExpectLogContainsSomewhere(
3427*6777b538SAndroid Build Coastguard Worker       entries, 0, NetLogEventType::COOKIE_STORE_ALIVE, NetLogEventPhase::BEGIN);
3428*6777b538SAndroid Build Coastguard Worker   pos = ExpectLogContainsSomewhere(
3429*6777b538SAndroid Build Coastguard Worker       entries, pos, NetLogEventType::COOKIE_STORE_SESSION_PERSISTENCE,
3430*6777b538SAndroid Build Coastguard Worker       NetLogEventPhase::NONE);
3431*6777b538SAndroid Build Coastguard Worker   pos = ExpectLogContainsSomewhere(entries, pos,
3432*6777b538SAndroid Build Coastguard Worker                                    NetLogEventType::COOKIE_STORE_COOKIE_ADDED,
3433*6777b538SAndroid Build Coastguard Worker                                    NetLogEventPhase::NONE);
3434*6777b538SAndroid Build Coastguard Worker   pos = ExpectLogContainsSomewhere(entries, pos,
3435*6777b538SAndroid Build Coastguard Worker                                    NetLogEventType::COOKIE_STORE_COOKIE_DELETED,
3436*6777b538SAndroid Build Coastguard Worker                                    NetLogEventPhase::NONE);
3437*6777b538SAndroid Build Coastguard Worker   ExpectLogContainsSomewhere(entries, pos, NetLogEventType::COOKIE_STORE_ALIVE,
3438*6777b538SAndroid Build Coastguard Worker                              NetLogEventPhase::END);
3439*6777b538SAndroid Build Coastguard Worker }
3440*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,HistogramCheck)3441*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, HistogramCheck) {
3442*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
3443*6777b538SAndroid Build Coastguard Worker 
3444*6777b538SAndroid Build Coastguard Worker   // Should match call in InitializeHistograms, but doesn't really matter
3445*6777b538SAndroid Build Coastguard Worker   // since the histogram should have been initialized by the CM construction
3446*6777b538SAndroid Build Coastguard Worker   // above.
3447*6777b538SAndroid Build Coastguard Worker   base::HistogramBase* expired_histogram = base::Histogram::FactoryGet(
3448*6777b538SAndroid Build Coastguard Worker       "Cookie.ExpirationDurationMinutesSecure", 1, 10 * 365 * 24 * 60, 50,
3449*6777b538SAndroid Build Coastguard Worker       base::Histogram::kUmaTargetedHistogramFlag);
3450*6777b538SAndroid Build Coastguard Worker 
3451*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<base::HistogramSamples> samples1(
3452*6777b538SAndroid Build Coastguard Worker       expired_histogram->SnapshotSamples());
3453*6777b538SAndroid Build Coastguard Worker   auto cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
3454*6777b538SAndroid Build Coastguard Worker       "a", "b", "a.url", "/", base::Time(),
3455*6777b538SAndroid Build Coastguard Worker       base::Time::Now() + base::Minutes(59), base::Time(), base::Time(),
3456*6777b538SAndroid Build Coastguard Worker       /*secure=*/true,
3457*6777b538SAndroid Build Coastguard Worker       /*httponly=*/false, CookieSameSite::NO_RESTRICTION,
3458*6777b538SAndroid Build Coastguard Worker       COOKIE_PRIORITY_DEFAULT);
3459*6777b538SAndroid Build Coastguard Worker   GURL source_url = cookie_util::SimulatedCookieSource(*cookie, "https");
3460*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(SetCanonicalCookie(cm.get(), std::move(cookie), source_url,
3461*6777b538SAndroid Build Coastguard Worker                                  /*modify_httponly=*/true));
3462*6777b538SAndroid Build Coastguard Worker 
3463*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<base::HistogramSamples> samples2(
3464*6777b538SAndroid Build Coastguard Worker       expired_histogram->SnapshotSamples());
3465*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(samples1->TotalCount() + 1, samples2->TotalCount());
3466*6777b538SAndroid Build Coastguard Worker 
3467*6777b538SAndroid Build Coastguard Worker   // kValidCookieLine creates a session cookie.
3468*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), kValidCookieLine));
3469*6777b538SAndroid Build Coastguard Worker 
3470*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<base::HistogramSamples> samples3(
3471*6777b538SAndroid Build Coastguard Worker       expired_histogram->SnapshotSamples());
3472*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(samples2->TotalCount(), samples3->TotalCount());
3473*6777b538SAndroid Build Coastguard Worker }
3474*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,InvalidExpiryTime)3475*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, InvalidExpiryTime) {
3476*6777b538SAndroid Build Coastguard Worker   std::string cookie_line =
3477*6777b538SAndroid Build Coastguard Worker       std::string(kValidCookieLine) + "; expires=Blarg arg arg";
3478*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<CanonicalCookie> cookie(CanonicalCookie::CreateForTesting(
3479*6777b538SAndroid Build Coastguard Worker       http_www_foo_.url(), cookie_line, Time::Now()));
3480*6777b538SAndroid Build Coastguard Worker   ASSERT_FALSE(cookie->IsPersistent());
3481*6777b538SAndroid Build Coastguard Worker }
3482*6777b538SAndroid Build Coastguard Worker 
3483*6777b538SAndroid Build Coastguard Worker // Test that CookieMonster writes session cookies into the underlying
3484*6777b538SAndroid Build Coastguard Worker // CookieStore if the "persist session cookies" option is on.
TEST_F(CookieMonsterTest,PersistSessionCookies)3485*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, PersistSessionCookies) {
3486*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
3487*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
3488*6777b538SAndroid Build Coastguard Worker   cm->SetPersistSessionCookies(true);
3489*6777b538SAndroid Build Coastguard Worker 
3490*6777b538SAndroid Build Coastguard Worker   // All cookies set with SetCookie are session cookies.
3491*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), "A=B"));
3492*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("A=B", GetCookies(cm.get(), http_www_foo_.url()));
3493*6777b538SAndroid Build Coastguard Worker 
3494*6777b538SAndroid Build Coastguard Worker   // The cookie was written to the backing store.
3495*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, store->commands().size());
3496*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[0].type);
3497*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("A", store->commands()[0].cookie.Name());
3498*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("B", store->commands()[0].cookie.Value());
3499*6777b538SAndroid Build Coastguard Worker 
3500*6777b538SAndroid Build Coastguard Worker   // Modify the cookie.
3501*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), "A=C"));
3502*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("A=C", GetCookies(cm.get(), http_www_foo_.url()));
3503*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3u, store->commands().size());
3504*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[1].type);
3505*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("A", store->commands()[1].cookie.Name());
3506*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("B", store->commands()[1].cookie.Value());
3507*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[2].type);
3508*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("A", store->commands()[2].cookie.Name());
3509*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("C", store->commands()[2].cookie.Value());
3510*6777b538SAndroid Build Coastguard Worker 
3511*6777b538SAndroid Build Coastguard Worker   // Delete the cookie. Using .host() here since it's a host and not domain
3512*6777b538SAndroid Build Coastguard Worker   // cookie.
3513*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(FindAndDeleteCookie(cm.get(), http_www_foo_.host(), "A"));
3514*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("", GetCookies(cm.get(), http_www_foo_.url()));
3515*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(4u, store->commands().size());
3516*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[3].type);
3517*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("A", store->commands()[3].cookie.Name());
3518*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("C", store->commands()[3].cookie.Value());
3519*6777b538SAndroid Build Coastguard Worker }
3520*6777b538SAndroid Build Coastguard Worker 
3521*6777b538SAndroid Build Coastguard Worker // Test the commands sent to the persistent cookie store.
TEST_F(CookieMonsterTest,PersisentCookieStorageTest)3522*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, PersisentCookieStorageTest) {
3523*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
3524*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
3525*6777b538SAndroid Build Coastguard Worker 
3526*6777b538SAndroid Build Coastguard Worker   // Add a cookie.
3527*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(),
3528*6777b538SAndroid Build Coastguard Worker                         "A=B" + FutureCookieExpirationString()));
3529*6777b538SAndroid Build Coastguard Worker   this->MatchCookieLines("A=B", GetCookies(cm.get(), http_www_foo_.url()));
3530*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(1u, store->commands().size());
3531*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[0].type);
3532*6777b538SAndroid Build Coastguard Worker   // Remove it.
3533*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), "A=B; max-age=0"));
3534*6777b538SAndroid Build Coastguard Worker   this->MatchCookieLines(std::string(),
3535*6777b538SAndroid Build Coastguard Worker                          GetCookies(cm.get(), http_www_foo_.url()));
3536*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(2u, store->commands().size());
3537*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[1].type);
3538*6777b538SAndroid Build Coastguard Worker 
3539*6777b538SAndroid Build Coastguard Worker   // Add a cookie.
3540*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(),
3541*6777b538SAndroid Build Coastguard Worker                         "A=B" + FutureCookieExpirationString()));
3542*6777b538SAndroid Build Coastguard Worker   this->MatchCookieLines("A=B", GetCookies(cm.get(), http_www_foo_.url()));
3543*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(3u, store->commands().size());
3544*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[2].type);
3545*6777b538SAndroid Build Coastguard Worker   // Overwrite it.
3546*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(),
3547*6777b538SAndroid Build Coastguard Worker                         "A=Foo" + FutureCookieExpirationString()));
3548*6777b538SAndroid Build Coastguard Worker   this->MatchCookieLines("A=Foo", GetCookies(cm.get(), http_www_foo_.url()));
3549*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(5u, store->commands().size());
3550*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[3].type);
3551*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[4].type);
3552*6777b538SAndroid Build Coastguard Worker 
3553*6777b538SAndroid Build Coastguard Worker   // Create some non-persistent cookies and check that they don't go to the
3554*6777b538SAndroid Build Coastguard Worker   // persistent storage.
3555*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), "B=Bar"));
3556*6777b538SAndroid Build Coastguard Worker   this->MatchCookieLines("A=Foo; B=Bar",
3557*6777b538SAndroid Build Coastguard Worker                          GetCookies(cm.get(), http_www_foo_.url()));
3558*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(5u, store->commands().size());
3559*6777b538SAndroid Build Coastguard Worker }
3560*6777b538SAndroid Build Coastguard Worker 
3561*6777b538SAndroid Build Coastguard Worker // Test to assure that cookies with control characters are purged appropriately.
3562*6777b538SAndroid Build Coastguard Worker // See http://crbug.com/238041 for background.
TEST_F(CookieMonsterTest,ControlCharacterPurge)3563*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, ControlCharacterPurge) {
3564*6777b538SAndroid Build Coastguard Worker   const Time now1(Time::Now());
3565*6777b538SAndroid Build Coastguard Worker   const Time now2(Time::Now() + base::Seconds(1));
3566*6777b538SAndroid Build Coastguard Worker   const Time now3(Time::Now() + base::Seconds(2));
3567*6777b538SAndroid Build Coastguard Worker   const Time now4(Time::Now() + base::Seconds(3));
3568*6777b538SAndroid Build Coastguard Worker   const Time later(now1 + base::Days(1));
3569*6777b538SAndroid Build Coastguard Worker   const GURL url("https://host/path");
3570*6777b538SAndroid Build Coastguard Worker   const std::string domain("host");
3571*6777b538SAndroid Build Coastguard Worker   const std::string path("/path");
3572*6777b538SAndroid Build Coastguard Worker 
3573*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
3574*6777b538SAndroid Build Coastguard Worker 
3575*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<CanonicalCookie>> initial_cookies;
3576*6777b538SAndroid Build Coastguard Worker 
3577*6777b538SAndroid Build Coastguard Worker   AddCookieToList(url, "foo=bar; path=" + path, now1, &initial_cookies);
3578*6777b538SAndroid Build Coastguard Worker 
3579*6777b538SAndroid Build Coastguard Worker   // We have to manually build these cookies because they contain control
3580*6777b538SAndroid Build Coastguard Worker   // characters, and our cookie line parser rejects control characters.
3581*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<CanonicalCookie> cc =
3582*6777b538SAndroid Build Coastguard Worker       CanonicalCookie::CreateUnsafeCookieForTesting(
3583*6777b538SAndroid Build Coastguard Worker           "baz",
3584*6777b538SAndroid Build Coastguard Worker           "\x05"
3585*6777b538SAndroid Build Coastguard Worker           "boo",
3586*6777b538SAndroid Build Coastguard Worker           "." + domain, path, now2, later, base::Time(), base::Time(),
3587*6777b538SAndroid Build Coastguard Worker           true /* secure */, false /* httponly */,
3588*6777b538SAndroid Build Coastguard Worker           CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT);
3589*6777b538SAndroid Build Coastguard Worker   initial_cookies.push_back(std::move(cc));
3590*6777b538SAndroid Build Coastguard Worker 
3591*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<CanonicalCookie> cc2 =
3592*6777b538SAndroid Build Coastguard Worker       CanonicalCookie::CreateUnsafeCookieForTesting(
3593*6777b538SAndroid Build Coastguard Worker           "baz",
3594*6777b538SAndroid Build Coastguard Worker           "\x7F"
3595*6777b538SAndroid Build Coastguard Worker           "boo",
3596*6777b538SAndroid Build Coastguard Worker           "." + domain, path, now3, later, base::Time(), base::Time(),
3597*6777b538SAndroid Build Coastguard Worker           true /* secure */, false /* httponly */,
3598*6777b538SAndroid Build Coastguard Worker           CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT);
3599*6777b538SAndroid Build Coastguard Worker   initial_cookies.push_back(std::move(cc2));
3600*6777b538SAndroid Build Coastguard Worker 
3601*6777b538SAndroid Build Coastguard Worker   // Partitioned cookies with control characters should not be loaded.
3602*6777b538SAndroid Build Coastguard Worker   auto cookie_partition_key =
3603*6777b538SAndroid Build Coastguard Worker       CookiePartitionKey::FromURLForTesting(GURL("https://toplevelsite.com"));
3604*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<CanonicalCookie> cc3 =
3605*6777b538SAndroid Build Coastguard Worker       CanonicalCookie::CreateUnsafeCookieForTesting(
3606*6777b538SAndroid Build Coastguard Worker           "__Host-baz",
3607*6777b538SAndroid Build Coastguard Worker           "\x7F"
3608*6777b538SAndroid Build Coastguard Worker           "boo",
3609*6777b538SAndroid Build Coastguard Worker           domain, "/", now3, later, base::Time(), base::Time(),
3610*6777b538SAndroid Build Coastguard Worker           true /* secure */, false /* httponly */,
3611*6777b538SAndroid Build Coastguard Worker           CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
3612*6777b538SAndroid Build Coastguard Worker           cookie_partition_key);
3613*6777b538SAndroid Build Coastguard Worker   initial_cookies.push_back(std::move(cc3));
3614*6777b538SAndroid Build Coastguard Worker 
3615*6777b538SAndroid Build Coastguard Worker   AddCookieToList(url, "hello=world; path=" + path, now4, &initial_cookies);
3616*6777b538SAndroid Build Coastguard Worker 
3617*6777b538SAndroid Build Coastguard Worker   // Inject our initial cookies into the mock PersistentCookieStore.
3618*6777b538SAndroid Build Coastguard Worker   store->SetLoadExpectation(true, std::move(initial_cookies));
3619*6777b538SAndroid Build Coastguard Worker 
3620*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
3621*6777b538SAndroid Build Coastguard Worker 
3622*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("foo=bar; hello=world",
3623*6777b538SAndroid Build Coastguard Worker             GetCookies(cm.get(), url,
3624*6777b538SAndroid Build Coastguard Worker                        CookiePartitionKeyCollection(cookie_partition_key)));
3625*6777b538SAndroid Build Coastguard Worker }
3626*6777b538SAndroid Build Coastguard Worker 
3627*6777b538SAndroid Build Coastguard Worker // Test that cookie source schemes are histogrammed correctly.
TEST_F(CookieMonsterTest,CookieSourceHistogram)3628*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, CookieSourceHistogram) {
3629*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histograms;
3630*6777b538SAndroid Build Coastguard Worker   const std::string cookie_source_histogram = "Cookie.CookieSourceScheme";
3631*6777b538SAndroid Build Coastguard Worker 
3632*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
3633*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
3634*6777b538SAndroid Build Coastguard Worker 
3635*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(cookie_source_histogram, 0);
3636*6777b538SAndroid Build Coastguard Worker 
3637*6777b538SAndroid Build Coastguard Worker   // Set a secure cookie on a cryptographic scheme.
3638*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), https_www_foo_.url(), "A=B; path=/; Secure"));
3639*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(cookie_source_histogram, 1);
3640*6777b538SAndroid Build Coastguard Worker   histograms.ExpectBucketCount(
3641*6777b538SAndroid Build Coastguard Worker       cookie_source_histogram,
3642*6777b538SAndroid Build Coastguard Worker       CookieMonster::CookieSource::kSecureCookieCryptographicScheme, 1);
3643*6777b538SAndroid Build Coastguard Worker 
3644*6777b538SAndroid Build Coastguard Worker   // Set a non-secure cookie on a cryptographic scheme.
3645*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), https_www_foo_.url(), "C=D; path=/;"));
3646*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(cookie_source_histogram, 2);
3647*6777b538SAndroid Build Coastguard Worker   histograms.ExpectBucketCount(
3648*6777b538SAndroid Build Coastguard Worker       cookie_source_histogram,
3649*6777b538SAndroid Build Coastguard Worker       CookieMonster::CookieSource::kNonsecureCookieCryptographicScheme, 1);
3650*6777b538SAndroid Build Coastguard Worker 
3651*6777b538SAndroid Build Coastguard Worker   // Set a secure cookie on a non-cryptographic scheme.
3652*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(SetCookie(cm.get(), http_www_foo_.url(), "D=E; path=/; Secure"));
3653*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(cookie_source_histogram, 2);
3654*6777b538SAndroid Build Coastguard Worker   histograms.ExpectBucketCount(
3655*6777b538SAndroid Build Coastguard Worker       cookie_source_histogram,
3656*6777b538SAndroid Build Coastguard Worker       CookieMonster::CookieSource::kSecureCookieNoncryptographicScheme, 0);
3657*6777b538SAndroid Build Coastguard Worker 
3658*6777b538SAndroid Build Coastguard Worker   // Overwrite a secure cookie (set by a cryptographic scheme) on a
3659*6777b538SAndroid Build Coastguard Worker   // non-cryptographic scheme.
3660*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(SetCookie(cm.get(), http_www_foo_.url(), "A=B; path=/; Secure"));
3661*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(cookie_source_histogram, 2);
3662*6777b538SAndroid Build Coastguard Worker   histograms.ExpectBucketCount(
3663*6777b538SAndroid Build Coastguard Worker       cookie_source_histogram,
3664*6777b538SAndroid Build Coastguard Worker       CookieMonster::CookieSource::kSecureCookieCryptographicScheme, 1);
3665*6777b538SAndroid Build Coastguard Worker   histograms.ExpectBucketCount(
3666*6777b538SAndroid Build Coastguard Worker       cookie_source_histogram,
3667*6777b538SAndroid Build Coastguard Worker       CookieMonster::CookieSource::kSecureCookieNoncryptographicScheme, 0);
3668*6777b538SAndroid Build Coastguard Worker 
3669*6777b538SAndroid Build Coastguard Worker   // Test that attempting to clear a secure cookie on a http:// URL does
3670*6777b538SAndroid Build Coastguard Worker   // nothing.
3671*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), https_www_foo_.url(), "F=G; path=/; Secure"));
3672*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(cookie_source_histogram, 3);
3673*6777b538SAndroid Build Coastguard Worker   std::string cookies1 = GetCookies(cm.get(), https_www_foo_.url());
3674*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(std::string::npos, cookies1.find("F=G"));
3675*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(SetCookie(cm.get(), http_www_foo_.url(),
3676*6777b538SAndroid Build Coastguard Worker                          "F=G; path=/; Expires=Thu, 01-Jan-1970 00:00:01 GMT"));
3677*6777b538SAndroid Build Coastguard Worker   std::string cookies2 = GetCookies(cm.get(), https_www_foo_.url());
3678*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(std::string::npos, cookies2.find("F=G"));
3679*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(cookie_source_histogram, 3);
3680*6777b538SAndroid Build Coastguard Worker 
3681*6777b538SAndroid Build Coastguard Worker   // Set a non-secure cookie on a non-cryptographic scheme.
3682*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), "H=I; path=/"));
3683*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(cookie_source_histogram, 4);
3684*6777b538SAndroid Build Coastguard Worker   histograms.ExpectBucketCount(
3685*6777b538SAndroid Build Coastguard Worker       cookie_source_histogram,
3686*6777b538SAndroid Build Coastguard Worker       CookieMonster::CookieSource::kNonsecureCookieNoncryptographicScheme, 1);
3687*6777b538SAndroid Build Coastguard Worker }
3688*6777b538SAndroid Build Coastguard Worker 
3689*6777b538SAndroid Build Coastguard Worker // Test that inserting the first cookie for a key and deleting the last cookie
3690*6777b538SAndroid Build Coastguard Worker // for a key correctly reflected in the Cookie.NumKeys histogram.
TEST_F(CookieMonsterTest,NumKeysHistogram)3691*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, NumKeysHistogram) {
3692*6777b538SAndroid Build Coastguard Worker   const char kHistogramName[] = "Cookie.NumKeys";
3693*6777b538SAndroid Build Coastguard Worker 
3694*6777b538SAndroid Build Coastguard Worker   // Test loading cookies from store.
3695*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
3696*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<CanonicalCookie>> initial_cookies;
3697*6777b538SAndroid Build Coastguard Worker   initial_cookies.push_back(CanonicalCookie::CreateForTesting(
3698*6777b538SAndroid Build Coastguard Worker       GURL("http://domain1.test"), "A=1", base::Time::Now()));
3699*6777b538SAndroid Build Coastguard Worker   initial_cookies.push_back(CanonicalCookie::CreateForTesting(
3700*6777b538SAndroid Build Coastguard Worker       GURL("http://domain2.test"), "A=1", base::Time::Now()));
3701*6777b538SAndroid Build Coastguard Worker   initial_cookies.push_back(CanonicalCookie::CreateForTesting(
3702*6777b538SAndroid Build Coastguard Worker       GURL("http://sub.domain2.test"), "A=1", base::Time::Now()));
3703*6777b538SAndroid Build Coastguard Worker   initial_cookies.push_back(CanonicalCookie::CreateForTesting(
3704*6777b538SAndroid Build Coastguard Worker       GURL("http://domain3.test"), "A=1", base::Time::Now()));
3705*6777b538SAndroid Build Coastguard Worker   initial_cookies.push_back(CanonicalCookie::CreateForTesting(
3706*6777b538SAndroid Build Coastguard Worker       GURL("http://domain3.test"), "B=1", base::Time::Now()));
3707*6777b538SAndroid Build Coastguard Worker   store->SetLoadExpectation(true /* return_value */,
3708*6777b538SAndroid Build Coastguard Worker                             std::move(initial_cookies));
3709*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
3710*6777b538SAndroid Build Coastguard Worker   {
3711*6777b538SAndroid Build Coastguard Worker     base::HistogramTester histogram_tester;
3712*6777b538SAndroid Build Coastguard Worker     // Access the cookies to trigger loading from the persistent store.
3713*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(5u, this->GetAllCookies(cm.get()).size());
3714*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(cm->DoRecordPeriodicStatsForTesting());
3715*6777b538SAndroid Build Coastguard Worker     // There should be 3 keys: "domain1.test", "domain2.test", and
3716*6777b538SAndroid Build Coastguard Worker     // "domain3.test".
3717*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample(kHistogramName, 3 /* sample */,
3718*6777b538SAndroid Build Coastguard Worker                                         1 /* count */);
3719*6777b538SAndroid Build Coastguard Worker   }
3720*6777b538SAndroid Build Coastguard Worker 
3721*6777b538SAndroid Build Coastguard Worker   // Test adding cookies for already existing key.
3722*6777b538SAndroid Build Coastguard Worker   {
3723*6777b538SAndroid Build Coastguard Worker     base::HistogramTester histogram_tester;
3724*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(CreateAndSetCookie(cm.get(), GURL("https://domain1.test"),
3725*6777b538SAndroid Build Coastguard Worker                                    "B=1", CookieOptions::MakeAllInclusive()));
3726*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(CreateAndSetCookie(cm.get(), GURL("http://sub.domain1.test"),
3727*6777b538SAndroid Build Coastguard Worker                                    "B=1", CookieOptions::MakeAllInclusive()));
3728*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(cm->DoRecordPeriodicStatsForTesting());
3729*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample(kHistogramName, 3 /* sample */,
3730*6777b538SAndroid Build Coastguard Worker                                         1 /* count */);
3731*6777b538SAndroid Build Coastguard Worker   }
3732*6777b538SAndroid Build Coastguard Worker 
3733*6777b538SAndroid Build Coastguard Worker   // Test adding a cookie for a new key.
3734*6777b538SAndroid Build Coastguard Worker   {
3735*6777b538SAndroid Build Coastguard Worker     base::HistogramTester histogram_tester;
3736*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(CreateAndSetCookie(cm.get(), GURL("https://domain4.test"),
3737*6777b538SAndroid Build Coastguard Worker                                    "A=1", CookieOptions::MakeAllInclusive()));
3738*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(cm->DoRecordPeriodicStatsForTesting());
3739*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample(kHistogramName, 4 /* sample */,
3740*6777b538SAndroid Build Coastguard Worker                                         1 /* count */);
3741*6777b538SAndroid Build Coastguard Worker   }
3742*6777b538SAndroid Build Coastguard Worker 
3743*6777b538SAndroid Build Coastguard Worker   // Test overwriting the only cookie for a key. (Deletes and inserts, so the
3744*6777b538SAndroid Build Coastguard Worker   // total doesn't change.)
3745*6777b538SAndroid Build Coastguard Worker   {
3746*6777b538SAndroid Build Coastguard Worker     base::HistogramTester histogram_tester;
3747*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(CreateAndSetCookie(cm.get(), GURL("https://domain4.test"),
3748*6777b538SAndroid Build Coastguard Worker                                    "A=2", CookieOptions::MakeAllInclusive()));
3749*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(cm->DoRecordPeriodicStatsForTesting());
3750*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample(kHistogramName, 4 /* sample */,
3751*6777b538SAndroid Build Coastguard Worker                                         1 /* count */);
3752*6777b538SAndroid Build Coastguard Worker   }
3753*6777b538SAndroid Build Coastguard Worker 
3754*6777b538SAndroid Build Coastguard Worker   // Test deleting cookie for a key with more than one cookie.
3755*6777b538SAndroid Build Coastguard Worker   {
3756*6777b538SAndroid Build Coastguard Worker     base::HistogramTester histogram_tester;
3757*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(CreateAndSetCookie(cm.get(), GURL("https://domain2.test"),
3758*6777b538SAndroid Build Coastguard Worker                                    "A=1; Max-Age=0",
3759*6777b538SAndroid Build Coastguard Worker                                    CookieOptions::MakeAllInclusive()));
3760*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(cm->DoRecordPeriodicStatsForTesting());
3761*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample(kHistogramName, 4 /* sample */,
3762*6777b538SAndroid Build Coastguard Worker                                         1 /* count */);
3763*6777b538SAndroid Build Coastguard Worker   }
3764*6777b538SAndroid Build Coastguard Worker 
3765*6777b538SAndroid Build Coastguard Worker   // Test deleting cookie for a key with only one cookie.
3766*6777b538SAndroid Build Coastguard Worker   {
3767*6777b538SAndroid Build Coastguard Worker     base::HistogramTester histogram_tester;
3768*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(CreateAndSetCookie(cm.get(), GURL("https://domain4.test"),
3769*6777b538SAndroid Build Coastguard Worker                                    "A=1; Max-Age=0",
3770*6777b538SAndroid Build Coastguard Worker                                    CookieOptions::MakeAllInclusive()));
3771*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(cm->DoRecordPeriodicStatsForTesting());
3772*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample(kHistogramName, 3 /* sample */,
3773*6777b538SAndroid Build Coastguard Worker                                         1 /* count */);
3774*6777b538SAndroid Build Coastguard Worker   }
3775*6777b538SAndroid Build Coastguard Worker }
3776*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,CookieCount2Histogram)3777*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, CookieCount2Histogram) {
3778*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
3779*6777b538SAndroid Build Coastguard Worker 
3780*6777b538SAndroid Build Coastguard Worker   {
3781*6777b538SAndroid Build Coastguard Worker     base::HistogramTester histogram_tester;
3782*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(cm->DoRecordPeriodicStatsForTesting());
3783*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample("Cookie.Count2",
3784*6777b538SAndroid Build Coastguard Worker                                         /*sample=*/0,
3785*6777b538SAndroid Build Coastguard Worker                                         /*expected_bucket_count=*/1);
3786*6777b538SAndroid Build Coastguard Worker   }
3787*6777b538SAndroid Build Coastguard Worker 
3788*6777b538SAndroid Build Coastguard Worker   {
3789*6777b538SAndroid Build Coastguard Worker     base::HistogramTester histogram_tester;
3790*6777b538SAndroid Build Coastguard Worker 
3791*6777b538SAndroid Build Coastguard Worker     auto cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
3792*6777b538SAndroid Build Coastguard Worker         "a", "b", "a.url", "/", base::Time(),
3793*6777b538SAndroid Build Coastguard Worker         base::Time::Now() + base::Minutes(59), base::Time(), base::Time(),
3794*6777b538SAndroid Build Coastguard Worker         /*secure=*/true,
3795*6777b538SAndroid Build Coastguard Worker         /*httponly=*/false, CookieSameSite::NO_RESTRICTION,
3796*6777b538SAndroid Build Coastguard Worker         COOKIE_PRIORITY_DEFAULT);
3797*6777b538SAndroid Build Coastguard Worker     GURL source_url = cookie_util::SimulatedCookieSource(*cookie, "https");
3798*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(SetCanonicalCookie(cm.get(), std::move(cookie), source_url,
3799*6777b538SAndroid Build Coastguard Worker                                    /*modify_httponly=*/true));
3800*6777b538SAndroid Build Coastguard Worker 
3801*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(cm->DoRecordPeriodicStatsForTesting());
3802*6777b538SAndroid Build Coastguard Worker 
3803*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample("Cookie.Count2", /*sample=*/1,
3804*6777b538SAndroid Build Coastguard Worker                                         /*expected_bucket_count=*/1);
3805*6777b538SAndroid Build Coastguard Worker   }
3806*6777b538SAndroid Build Coastguard Worker }
3807*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,CookieJarSizeHistograms)3808*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, CookieJarSizeHistograms) {
3809*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
3810*6777b538SAndroid Build Coastguard Worker 
3811*6777b538SAndroid Build Coastguard Worker   {
3812*6777b538SAndroid Build Coastguard Worker     base::HistogramTester histogram_tester;
3813*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(cm->DoRecordPeriodicStatsForTesting());
3814*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample("Cookie.CookieJarSize",
3815*6777b538SAndroid Build Coastguard Worker                                         /*sample=*/0,
3816*6777b538SAndroid Build Coastguard Worker                                         /*expected_bucket_count=*/1);
3817*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample("Cookie.AvgCookieJarSizePerKey",
3818*6777b538SAndroid Build Coastguard Worker                                         /*sample=*/0,
3819*6777b538SAndroid Build Coastguard Worker                                         /*expected_bucket_count=*/1);
3820*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample("Cookie.MaxCookieJarSizePerKey",
3821*6777b538SAndroid Build Coastguard Worker                                         /*sample=*/0,
3822*6777b538SAndroid Build Coastguard Worker                                         /*expected_bucket_count=*/1);
3823*6777b538SAndroid Build Coastguard Worker   }
3824*6777b538SAndroid Build Coastguard Worker 
3825*6777b538SAndroid Build Coastguard Worker   auto set_cookie =
3826*6777b538SAndroid Build Coastguard Worker       [&](const std::string& name, int cookie_value_size_kb,
3827*6777b538SAndroid Build Coastguard Worker           const std::string& domain, CookieSameSite same_site,
3828*6777b538SAndroid Build Coastguard Worker           const std::optional<CookiePartitionKey>& partition_key) {
3829*6777b538SAndroid Build Coastguard Worker         auto cc = CanonicalCookie::CreateUnsafeCookieForTesting(
3830*6777b538SAndroid Build Coastguard Worker             name, std::string(cookie_value_size_kb * 1024, '0'), domain, "/",
3831*6777b538SAndroid Build Coastguard Worker             base::Time(), base::Time::Now() + base::Minutes(59), base::Time(),
3832*6777b538SAndroid Build Coastguard Worker             base::Time(),
3833*6777b538SAndroid Build Coastguard Worker             /*secure=*/true,
3834*6777b538SAndroid Build Coastguard Worker             /*httponly=*/false, same_site, COOKIE_PRIORITY_DEFAULT,
3835*6777b538SAndroid Build Coastguard Worker             partition_key);
3836*6777b538SAndroid Build Coastguard Worker         GURL source_url = cookie_util::SimulatedCookieSource(*cc, "https");
3837*6777b538SAndroid Build Coastguard Worker         ASSERT_TRUE(SetCanonicalCookie(cm.get(), std::move(cc), source_url,
3838*6777b538SAndroid Build Coastguard Worker                                        /*can_modify_httponly=*/true));
3839*6777b538SAndroid Build Coastguard Worker       };
3840*6777b538SAndroid Build Coastguard Worker 
3841*6777b538SAndroid Build Coastguard Worker   {  // Add unpartitioned cookie.
3842*6777b538SAndroid Build Coastguard Worker     base::HistogramTester histogram_tester;
3843*6777b538SAndroid Build Coastguard Worker     set_cookie("a", 2, "a.url", CookieSameSite::NO_RESTRICTION, std::nullopt);
3844*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(cm->DoRecordPeriodicStatsForTesting());
3845*6777b538SAndroid Build Coastguard Worker 
3846*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample("Cookie.CookieJarSize",
3847*6777b538SAndroid Build Coastguard Worker                                         /*sample=*/2,
3848*6777b538SAndroid Build Coastguard Worker                                         /*expected_bucket_count=*/1);
3849*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample("Cookie.AvgCookieJarSizePerKey",
3850*6777b538SAndroid Build Coastguard Worker                                         /*sample=*/2,
3851*6777b538SAndroid Build Coastguard Worker                                         /*expected_bucket_count=*/1);
3852*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample("Cookie.MaxCookieJarSizePerKey",
3853*6777b538SAndroid Build Coastguard Worker                                         /*sample=*/2,
3854*6777b538SAndroid Build Coastguard Worker                                         /*expected_bucket_count=*/1);
3855*6777b538SAndroid Build Coastguard Worker   }
3856*6777b538SAndroid Build Coastguard Worker 
3857*6777b538SAndroid Build Coastguard Worker   {  // Add partitioned cookie, should not impact the counter.
3858*6777b538SAndroid Build Coastguard Worker     base::HistogramTester histogram_tester;
3859*6777b538SAndroid Build Coastguard Worker     set_cookie("b", 3, "a.url", CookieSameSite::NO_RESTRICTION,
3860*6777b538SAndroid Build Coastguard Worker                CookiePartitionKey::FromURLForTesting(
3861*6777b538SAndroid Build Coastguard Worker                    GURL("https://toplevelsite.com")));
3862*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(cm->DoRecordPeriodicStatsForTesting());
3863*6777b538SAndroid Build Coastguard Worker 
3864*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample("Cookie.CookieJarSize",
3865*6777b538SAndroid Build Coastguard Worker                                         /*sample=*/2,
3866*6777b538SAndroid Build Coastguard Worker                                         /*expected_bucket_count=*/1);
3867*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample("Cookie.AvgCookieJarSizePerKey",
3868*6777b538SAndroid Build Coastguard Worker                                         /*sample=*/2,
3869*6777b538SAndroid Build Coastguard Worker                                         /*expected_bucket_count=*/1);
3870*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample("Cookie.MaxCookieJarSizePerKey",
3871*6777b538SAndroid Build Coastguard Worker                                         /*sample=*/2,
3872*6777b538SAndroid Build Coastguard Worker                                         /*expected_bucket_count=*/1);
3873*6777b538SAndroid Build Coastguard Worker   }
3874*6777b538SAndroid Build Coastguard Worker 
3875*6777b538SAndroid Build Coastguard Worker   {  // Add unpartitioned cookie from another domain. Is also SameSite=Lax to
3876*6777b538SAndroid Build Coastguard Worker      // ensure the counter includes SameSite cookies.
3877*6777b538SAndroid Build Coastguard Worker     base::HistogramTester histogram_tester;
3878*6777b538SAndroid Build Coastguard Worker     set_cookie("c", 4, "c.url", CookieSameSite::LAX_MODE, std::nullopt);
3879*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(cm->DoRecordPeriodicStatsForTesting());
3880*6777b538SAndroid Build Coastguard Worker 
3881*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample("Cookie.CookieJarSize",
3882*6777b538SAndroid Build Coastguard Worker                                         /*sample=*/6,
3883*6777b538SAndroid Build Coastguard Worker                                         /*expected_bucket_count=*/1);
3884*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample("Cookie.AvgCookieJarSizePerKey",
3885*6777b538SAndroid Build Coastguard Worker                                         /*sample=*/3,
3886*6777b538SAndroid Build Coastguard Worker                                         /*expected_bucket_count=*/1);
3887*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample("Cookie.MaxCookieJarSizePerKey",
3888*6777b538SAndroid Build Coastguard Worker                                         /*sample=*/4,
3889*6777b538SAndroid Build Coastguard Worker                                         /*expected_bucket_count=*/1);
3890*6777b538SAndroid Build Coastguard Worker   }
3891*6777b538SAndroid Build Coastguard Worker }
3892*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,PartitionedCookieHistograms)3893*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, PartitionedCookieHistograms) {
3894*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
3895*6777b538SAndroid Build Coastguard Worker 
3896*6777b538SAndroid Build Coastguard Worker   {
3897*6777b538SAndroid Build Coastguard Worker     base::HistogramTester histogram_tester;
3898*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(cm->DoRecordPeriodicStatsForTesting());
3899*6777b538SAndroid Build Coastguard Worker 
3900*6777b538SAndroid Build Coastguard Worker     // Cookie counters.
3901*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample("Cookie.PartitionedCookieCount",
3902*6777b538SAndroid Build Coastguard Worker                                         /*sample=*/0,
3903*6777b538SAndroid Build Coastguard Worker                                         /*count=*/1);
3904*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample("Cookie.PartitionedCookieCount.Nonced",
3905*6777b538SAndroid Build Coastguard Worker                                         /*sample=*/0,
3906*6777b538SAndroid Build Coastguard Worker                                         /*count=*/1);
3907*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample(
3908*6777b538SAndroid Build Coastguard Worker         "Cookie.PartitionedCookieCount.Unnonced", /*sample=*/0,
3909*6777b538SAndroid Build Coastguard Worker         /*count=*/1);
3910*6777b538SAndroid Build Coastguard Worker 
3911*6777b538SAndroid Build Coastguard Worker     // Partitioned cookie jar size.
3912*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample(
3913*6777b538SAndroid Build Coastguard Worker         "Cookie.PartitionedCookieJarSizeKibibytes",
3914*6777b538SAndroid Build Coastguard Worker         /*sample=*/0,
3915*6777b538SAndroid Build Coastguard Worker         /*count=*/1);
3916*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample(
3917*6777b538SAndroid Build Coastguard Worker         "Cookie.PartitionedCookieJarSizeKibibytes.Nonced", /*sample=*/0,
3918*6777b538SAndroid Build Coastguard Worker         /*count=*/1);
3919*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample(
3920*6777b538SAndroid Build Coastguard Worker         "Cookie.PartitionedCookieJarSizeKibibytes.Unnonced", /*sample=*/0,
3921*6777b538SAndroid Build Coastguard Worker         /*count=*/1);
3922*6777b538SAndroid Build Coastguard Worker 
3923*6777b538SAndroid Build Coastguard Worker     // Partitioned cookie jar size per partition.
3924*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample("Cookie.CookiePartitionSizeKibibytes",
3925*6777b538SAndroid Build Coastguard Worker                                         /*sample=*/0,
3926*6777b538SAndroid Build Coastguard Worker                                         /*count=*/0);
3927*6777b538SAndroid Build Coastguard Worker   }
3928*6777b538SAndroid Build Coastguard Worker 
3929*6777b538SAndroid Build Coastguard Worker   {  // Add unpartitioned cookie.
3930*6777b538SAndroid Build Coastguard Worker     base::HistogramTester histogram_tester;
3931*6777b538SAndroid Build Coastguard Worker     auto cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
3932*6777b538SAndroid Build Coastguard Worker         "a", "b", "a.url", "/", base::Time(),
3933*6777b538SAndroid Build Coastguard Worker         base::Time::Now() + base::Minutes(59), base::Time(), base::Time(),
3934*6777b538SAndroid Build Coastguard Worker         /*secure=*/true,
3935*6777b538SAndroid Build Coastguard Worker         /*httponly=*/false, CookieSameSite::NO_RESTRICTION,
3936*6777b538SAndroid Build Coastguard Worker         COOKIE_PRIORITY_DEFAULT);
3937*6777b538SAndroid Build Coastguard Worker     GURL source_url = cookie_util::SimulatedCookieSource(*cookie, "https");
3938*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(SetCanonicalCookie(cm.get(), std::move(cookie), source_url,
3939*6777b538SAndroid Build Coastguard Worker                                    /*modify_httponly=*/true));
3940*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(cm->DoRecordPeriodicStatsForTesting());
3941*6777b538SAndroid Build Coastguard Worker 
3942*6777b538SAndroid Build Coastguard Worker     // Cookie counters.
3943*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample("Cookie.PartitionedCookieCount",
3944*6777b538SAndroid Build Coastguard Worker                                         /*sample=*/0,
3945*6777b538SAndroid Build Coastguard Worker                                         /*count=*/1);
3946*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample("Cookie.PartitionedCookieCount.Nonced",
3947*6777b538SAndroid Build Coastguard Worker                                         /*sample=*/0,
3948*6777b538SAndroid Build Coastguard Worker                                         /*count=*/1);
3949*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample(
3950*6777b538SAndroid Build Coastguard Worker         "Cookie.PartitionedCookieCount.Unnonced", /*sample=*/0,
3951*6777b538SAndroid Build Coastguard Worker         /*count=*/1);
3952*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample("Cookie.Count2", /*sample=*/1,
3953*6777b538SAndroid Build Coastguard Worker                                         /*count=*/1);
3954*6777b538SAndroid Build Coastguard Worker 
3955*6777b538SAndroid Build Coastguard Worker     // Partitioned cookie jar size.
3956*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample(
3957*6777b538SAndroid Build Coastguard Worker         "Cookie.PartitionedCookieJarSizeKibibytes",
3958*6777b538SAndroid Build Coastguard Worker         /*sample=*/0,
3959*6777b538SAndroid Build Coastguard Worker         /*count=*/1);
3960*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample(
3961*6777b538SAndroid Build Coastguard Worker         "Cookie.PartitionedCookieJarSizeKibibytes.Nonced", /*sample=*/0,
3962*6777b538SAndroid Build Coastguard Worker         /*count=*/1);
3963*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample(
3964*6777b538SAndroid Build Coastguard Worker         "Cookie.PartitionedCookieJarSizeKibibytes.Unnonced", /*sample=*/0,
3965*6777b538SAndroid Build Coastguard Worker         /*count=*/1);
3966*6777b538SAndroid Build Coastguard Worker 
3967*6777b538SAndroid Build Coastguard Worker     // Partitioned cookie jar size per partition.
3968*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample("Cookie.CookiePartitionSizeKibibytes",
3969*6777b538SAndroid Build Coastguard Worker                                         /*sample=*/0,
3970*6777b538SAndroid Build Coastguard Worker                                         /*count=*/0);
3971*6777b538SAndroid Build Coastguard Worker   }
3972*6777b538SAndroid Build Coastguard Worker 
3973*6777b538SAndroid Build Coastguard Worker   {  // Add unnonced partitioned cookie.
3974*6777b538SAndroid Build Coastguard Worker     base::HistogramTester histogram_tester;
3975*6777b538SAndroid Build Coastguard Worker     auto cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
3976*6777b538SAndroid Build Coastguard Worker         "a", std::string(2 * 1024, '0'), "a.url", "/", base::Time(),
3977*6777b538SAndroid Build Coastguard Worker         base::Time::Now() + base::Minutes(59), base::Time(), base::Time(),
3978*6777b538SAndroid Build Coastguard Worker         /*secure=*/true,
3979*6777b538SAndroid Build Coastguard Worker         /*httponly=*/false, CookieSameSite::NO_RESTRICTION,
3980*6777b538SAndroid Build Coastguard Worker         COOKIE_PRIORITY_DEFAULT,
3981*6777b538SAndroid Build Coastguard Worker         CookiePartitionKey::FromURLForTesting(GURL("https://example.com")));
3982*6777b538SAndroid Build Coastguard Worker     GURL source_url = cookie_util::SimulatedCookieSource(*cookie, "https");
3983*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(SetCanonicalCookie(cm.get(), std::move(cookie), source_url,
3984*6777b538SAndroid Build Coastguard Worker                                    /*modify_httponly=*/true));
3985*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(cm->DoRecordPeriodicStatsForTesting());
3986*6777b538SAndroid Build Coastguard Worker 
3987*6777b538SAndroid Build Coastguard Worker     // Cookie counters.
3988*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample("Cookie.PartitionedCookieCount",
3989*6777b538SAndroid Build Coastguard Worker                                         /*sample=*/1,
3990*6777b538SAndroid Build Coastguard Worker                                         /*count=*/1);
3991*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample("Cookie.PartitionedCookieCount.Nonced",
3992*6777b538SAndroid Build Coastguard Worker                                         /*sample=*/0,
3993*6777b538SAndroid Build Coastguard Worker                                         /*count=*/1);
3994*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample(
3995*6777b538SAndroid Build Coastguard Worker         "Cookie.PartitionedCookieCount.Unnonced", /*sample=*/1,
3996*6777b538SAndroid Build Coastguard Worker         /*count=*/1);
3997*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample("Cookie.Count2", /*sample=*/1,
3998*6777b538SAndroid Build Coastguard Worker                                         /*count=*/1);
3999*6777b538SAndroid Build Coastguard Worker 
4000*6777b538SAndroid Build Coastguard Worker     // Partitioned cookie jar size.
4001*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample(
4002*6777b538SAndroid Build Coastguard Worker         "Cookie.PartitionedCookieJarSizeKibibytes",
4003*6777b538SAndroid Build Coastguard Worker         /*sample=*/2,
4004*6777b538SAndroid Build Coastguard Worker         /*count=*/1);
4005*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample(
4006*6777b538SAndroid Build Coastguard Worker         "Cookie.PartitionedCookieJarSizeKibibytes.Nonced", /*sample=*/0,
4007*6777b538SAndroid Build Coastguard Worker         /*count=*/1);
4008*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample(
4009*6777b538SAndroid Build Coastguard Worker         "Cookie.PartitionedCookieJarSizeKibibytes.Unnonced", /*sample=*/2,
4010*6777b538SAndroid Build Coastguard Worker         /*count=*/1);
4011*6777b538SAndroid Build Coastguard Worker 
4012*6777b538SAndroid Build Coastguard Worker     // Partitioned cookie jar size per partition.
4013*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample("Cookie.CookiePartitionSizeKibibytes",
4014*6777b538SAndroid Build Coastguard Worker                                         /*sample=*/2,
4015*6777b538SAndroid Build Coastguard Worker                                         /*count=*/1);
4016*6777b538SAndroid Build Coastguard Worker   }
4017*6777b538SAndroid Build Coastguard Worker 
4018*6777b538SAndroid Build Coastguard Worker   {  // Add nonced partitioned cookie.
4019*6777b538SAndroid Build Coastguard Worker     base::HistogramTester histogram_tester;
4020*6777b538SAndroid Build Coastguard Worker     auto cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
4021*6777b538SAndroid Build Coastguard Worker         "a", std::string(3 * 1024, '0'), "a.url", "/", base::Time(),
4022*6777b538SAndroid Build Coastguard Worker         base::Time::Now() + base::Minutes(59), base::Time(), base::Time(),
4023*6777b538SAndroid Build Coastguard Worker         /*secure=*/true,
4024*6777b538SAndroid Build Coastguard Worker         /*httponly=*/false, CookieSameSite::NO_RESTRICTION,
4025*6777b538SAndroid Build Coastguard Worker         COOKIE_PRIORITY_DEFAULT,
4026*6777b538SAndroid Build Coastguard Worker         CookiePartitionKey::FromURLForTesting(
4027*6777b538SAndroid Build Coastguard Worker             GURL("https://example.com"),
4028*6777b538SAndroid Build Coastguard Worker             CookiePartitionKey::AncestorChainBit::kCrossSite,
4029*6777b538SAndroid Build Coastguard Worker             base::UnguessableToken::Create()));
4030*6777b538SAndroid Build Coastguard Worker     GURL source_url = cookie_util::SimulatedCookieSource(*cookie, "https");
4031*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(SetCanonicalCookie(cm.get(), std::move(cookie), source_url,
4032*6777b538SAndroid Build Coastguard Worker                                    /*modify_httponly=*/true));
4033*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(cm->DoRecordPeriodicStatsForTesting());
4034*6777b538SAndroid Build Coastguard Worker 
4035*6777b538SAndroid Build Coastguard Worker     // Cookie counts.
4036*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample("Cookie.PartitionedCookieCount",
4037*6777b538SAndroid Build Coastguard Worker                                         /*sample=*/2,
4038*6777b538SAndroid Build Coastguard Worker                                         /*count=*/1);
4039*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample("Cookie.PartitionedCookieCount.Nonced",
4040*6777b538SAndroid Build Coastguard Worker                                         /*sample=*/1,
4041*6777b538SAndroid Build Coastguard Worker                                         /*count=*/1);
4042*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample(
4043*6777b538SAndroid Build Coastguard Worker         "Cookie.PartitionedCookieCount.Unnonced", /*sample=*/1,
4044*6777b538SAndroid Build Coastguard Worker         /*count=*/1);
4045*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample("Cookie.Count2", /*sample=*/1,
4046*6777b538SAndroid Build Coastguard Worker                                         /*count=*/1);
4047*6777b538SAndroid Build Coastguard Worker 
4048*6777b538SAndroid Build Coastguard Worker     // Partitioned cookie jar size.
4049*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample(
4050*6777b538SAndroid Build Coastguard Worker         "Cookie.PartitionedCookieJarSizeKibibytes",
4051*6777b538SAndroid Build Coastguard Worker         /*sample=*/5,
4052*6777b538SAndroid Build Coastguard Worker         /*count=*/1);
4053*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample(
4054*6777b538SAndroid Build Coastguard Worker         "Cookie.PartitionedCookieJarSizeKibibytes.Nonced", /*sample=*/3,
4055*6777b538SAndroid Build Coastguard Worker         /*count=*/1);
4056*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample(
4057*6777b538SAndroid Build Coastguard Worker         "Cookie.PartitionedCookieJarSizeKibibytes.Unnonced", /*sample=*/2,
4058*6777b538SAndroid Build Coastguard Worker         /*count=*/1);
4059*6777b538SAndroid Build Coastguard Worker 
4060*6777b538SAndroid Build Coastguard Worker     // Partitioned cookie jar size per partition.
4061*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectBucketCount("Cookie.CookiePartitionSizeKibibytes",
4062*6777b538SAndroid Build Coastguard Worker                                        /*sample=*/2,
4063*6777b538SAndroid Build Coastguard Worker                                        /*count=*/1);
4064*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectBucketCount("Cookie.CookiePartitionSizeKibibytes",
4065*6777b538SAndroid Build Coastguard Worker                                        /*sample=*/3,
4066*6777b538SAndroid Build Coastguard Worker                                        /*count=*/1);
4067*6777b538SAndroid Build Coastguard Worker   }
4068*6777b538SAndroid Build Coastguard Worker }
4069*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,MaxSameSiteNoneCookiesPerKey)4070*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, MaxSameSiteNoneCookiesPerKey) {
4071*6777b538SAndroid Build Coastguard Worker   const char kHistogramName[] = "Cookie.MaxSameSiteNoneCookiesPerKey";
4072*6777b538SAndroid Build Coastguard Worker 
4073*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
4074*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
4075*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0u, GetAllCookies(cm.get()).size());
4076*6777b538SAndroid Build Coastguard Worker 
4077*6777b538SAndroid Build Coastguard Worker   {  // Only SameSite cookies should not log a sample.
4078*6777b538SAndroid Build Coastguard Worker     base::HistogramTester histogram_tester;
4079*6777b538SAndroid Build Coastguard Worker 
4080*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CreateAndSetCookie(cm.get(), GURL("https://domain1.test"),
4081*6777b538SAndroid Build Coastguard Worker                                    "A=1;SameSite=Lax",
4082*6777b538SAndroid Build Coastguard Worker                                    CookieOptions::MakeAllInclusive()));
4083*6777b538SAndroid Build Coastguard Worker     ASSERT_EQ(1u, GetAllCookies(cm.get()).size());
4084*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(cm->DoRecordPeriodicStatsForTesting());
4085*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample(kHistogramName, 0 /* sample */,
4086*6777b538SAndroid Build Coastguard Worker                                         1 /* count */);
4087*6777b538SAndroid Build Coastguard Worker   }
4088*6777b538SAndroid Build Coastguard Worker 
4089*6777b538SAndroid Build Coastguard Worker   {  // SameSite=None cookie should log a sample.
4090*6777b538SAndroid Build Coastguard Worker     base::HistogramTester histogram_tester;
4091*6777b538SAndroid Build Coastguard Worker 
4092*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CreateAndSetCookie(cm.get(), GURL("https://domain1.test"),
4093*6777b538SAndroid Build Coastguard Worker                                    "B=2;SameSite=None;Secure",
4094*6777b538SAndroid Build Coastguard Worker                                    CookieOptions::MakeAllInclusive()));
4095*6777b538SAndroid Build Coastguard Worker     ASSERT_EQ(2u, GetAllCookies(cm.get()).size());
4096*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(cm->DoRecordPeriodicStatsForTesting());
4097*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample(kHistogramName, 1 /* sample */,
4098*6777b538SAndroid Build Coastguard Worker                                         1 /* count */);
4099*6777b538SAndroid Build Coastguard Worker   }
4100*6777b538SAndroid Build Coastguard Worker 
4101*6777b538SAndroid Build Coastguard Worker   {  // Should log the maximum number of SameSite=None cookies.
4102*6777b538SAndroid Build Coastguard Worker     base::HistogramTester histogram_tester;
4103*6777b538SAndroid Build Coastguard Worker 
4104*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CreateAndSetCookie(cm.get(), GURL("https://domain2.test"),
4105*6777b538SAndroid Build Coastguard Worker                                    "A=1;SameSite=None;Secure",
4106*6777b538SAndroid Build Coastguard Worker                                    CookieOptions::MakeAllInclusive()));
4107*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CreateAndSetCookie(cm.get(), GURL("https://domain2.test"),
4108*6777b538SAndroid Build Coastguard Worker                                    "B=2;SameSite=None;Secure",
4109*6777b538SAndroid Build Coastguard Worker                                    CookieOptions::MakeAllInclusive()));
4110*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CreateAndSetCookie(cm.get(), GURL("https://domain3.test"),
4111*6777b538SAndroid Build Coastguard Worker                                    "A=1;SameSite=None;Secure",
4112*6777b538SAndroid Build Coastguard Worker                                    CookieOptions::MakeAllInclusive()));
4113*6777b538SAndroid Build Coastguard Worker     ASSERT_EQ(5u, GetAllCookies(cm.get()).size());
4114*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(cm->DoRecordPeriodicStatsForTesting());
4115*6777b538SAndroid Build Coastguard Worker     histogram_tester.ExpectUniqueSample(kHistogramName, 2 /* sample */,
4116*6777b538SAndroid Build Coastguard Worker                                         1 /* count */);
4117*6777b538SAndroid Build Coastguard Worker   }
4118*6777b538SAndroid Build Coastguard Worker }
4119*6777b538SAndroid Build Coastguard Worker 
4120*6777b538SAndroid Build Coastguard Worker // Test that localhost URLs can set and get secure cookies, even if
4121*6777b538SAndroid Build Coastguard Worker // non-cryptographic.
TEST_F(CookieMonsterTest,SecureCookieLocalhost)4122*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, SecureCookieLocalhost) {
4123*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, nullptr);
4124*6777b538SAndroid Build Coastguard Worker 
4125*6777b538SAndroid Build Coastguard Worker   GURL insecure_localhost("http://localhost");
4126*6777b538SAndroid Build Coastguard Worker   GURL secure_localhost("https://localhost");
4127*6777b538SAndroid Build Coastguard Worker 
4128*6777b538SAndroid Build Coastguard Worker   // Insecure localhost can set secure cookie, and warning is attached to
4129*6777b538SAndroid Build Coastguard Worker   // status.
4130*6777b538SAndroid Build Coastguard Worker   {
4131*6777b538SAndroid Build Coastguard Worker     auto cookie = CanonicalCookie::CreateForTesting(
4132*6777b538SAndroid Build Coastguard Worker         insecure_localhost, "from_insecure_localhost=1; Secure",
4133*6777b538SAndroid Build Coastguard Worker         base::Time::Now());
4134*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(cookie);
4135*6777b538SAndroid Build Coastguard Worker     CookieInclusionStatus status =
4136*6777b538SAndroid Build Coastguard Worker         SetCanonicalCookieReturnAccessResult(cm.get(), std::move(cookie),
4137*6777b538SAndroid Build Coastguard Worker                                              insecure_localhost,
4138*6777b538SAndroid Build Coastguard Worker                                              true /* can_modify_httponly */)
4139*6777b538SAndroid Build Coastguard Worker             .status;
4140*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(status.IsInclude());
4141*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(status.HasExactlyWarningReasonsForTesting(
4142*6777b538SAndroid Build Coastguard Worker         {CookieInclusionStatus::WARN_SECURE_ACCESS_GRANTED_NON_CRYPTOGRAPHIC}));
4143*6777b538SAndroid Build Coastguard Worker   }
4144*6777b538SAndroid Build Coastguard Worker   // Secure localhost can set secure cookie, and warning is not attached to
4145*6777b538SAndroid Build Coastguard Worker   // status.
4146*6777b538SAndroid Build Coastguard Worker   {
4147*6777b538SAndroid Build Coastguard Worker     auto cookie = CanonicalCookie::CreateForTesting(
4148*6777b538SAndroid Build Coastguard Worker         secure_localhost, "from_secure_localhost=1; Secure", base::Time::Now());
4149*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(cookie);
4150*6777b538SAndroid Build Coastguard Worker     CookieInclusionStatus status =
4151*6777b538SAndroid Build Coastguard Worker         SetCanonicalCookieReturnAccessResult(cm.get(), std::move(cookie),
4152*6777b538SAndroid Build Coastguard Worker                                              secure_localhost,
4153*6777b538SAndroid Build Coastguard Worker                                              true /* can_modify_httponly */)
4154*6777b538SAndroid Build Coastguard Worker             .status;
4155*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(CookieInclusionStatus(), status);
4156*6777b538SAndroid Build Coastguard Worker   }
4157*6777b538SAndroid Build Coastguard Worker 
4158*6777b538SAndroid Build Coastguard Worker   // Insecure localhost can get secure cookies, and warning is attached to
4159*6777b538SAndroid Build Coastguard Worker   // status.
4160*6777b538SAndroid Build Coastguard Worker   {
4161*6777b538SAndroid Build Coastguard Worker     GetCookieListCallback callback;
4162*6777b538SAndroid Build Coastguard Worker     cm->GetCookieListWithOptionsAsync(
4163*6777b538SAndroid Build Coastguard Worker         insecure_localhost, CookieOptions::MakeAllInclusive(),
4164*6777b538SAndroid Build Coastguard Worker         CookiePartitionKeyCollection(), callback.MakeCallback());
4165*6777b538SAndroid Build Coastguard Worker     callback.WaitUntilDone();
4166*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(2u, callback.cookies_with_access_results().size());
4167*6777b538SAndroid Build Coastguard Worker     for (const auto& cookie_item : callback.cookies_with_access_results()) {
4168*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(cookie_item.cookie.SecureAttribute());
4169*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(cookie_item.access_result.status.IsInclude());
4170*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(
4171*6777b538SAndroid Build Coastguard Worker           cookie_item.access_result.status.HasExactlyWarningReasonsForTesting(
4172*6777b538SAndroid Build Coastguard Worker               {CookieInclusionStatus::
4173*6777b538SAndroid Build Coastguard Worker                    WARN_SECURE_ACCESS_GRANTED_NON_CRYPTOGRAPHIC}));
4174*6777b538SAndroid Build Coastguard Worker     }
4175*6777b538SAndroid Build Coastguard Worker   }
4176*6777b538SAndroid Build Coastguard Worker   // Secure localhost can get secure cookies, and warning is not attached to
4177*6777b538SAndroid Build Coastguard Worker   // status.
4178*6777b538SAndroid Build Coastguard Worker   {
4179*6777b538SAndroid Build Coastguard Worker     GetCookieListCallback callback;
4180*6777b538SAndroid Build Coastguard Worker     cm->GetCookieListWithOptionsAsync(
4181*6777b538SAndroid Build Coastguard Worker         secure_localhost, CookieOptions::MakeAllInclusive(),
4182*6777b538SAndroid Build Coastguard Worker         CookiePartitionKeyCollection(), callback.MakeCallback());
4183*6777b538SAndroid Build Coastguard Worker     callback.WaitUntilDone();
4184*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(2u, callback.cookies_with_access_results().size());
4185*6777b538SAndroid Build Coastguard Worker     for (const auto& cookie_item : callback.cookies_with_access_results()) {
4186*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(cookie_item.cookie.SecureAttribute());
4187*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(CookieInclusionStatus(), cookie_item.access_result.status);
4188*6777b538SAndroid Build Coastguard Worker     }
4189*6777b538SAndroid Build Coastguard Worker   }
4190*6777b538SAndroid Build Coastguard Worker }
4191*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,MaybeDeleteEquivalentCookieAndUpdateStatus)4192*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, MaybeDeleteEquivalentCookieAndUpdateStatus) {
4193*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
4194*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
4195*6777b538SAndroid Build Coastguard Worker 
4196*6777b538SAndroid Build Coastguard Worker   // Set a secure, httponly cookie from a secure origin
4197*6777b538SAndroid Build Coastguard Worker   auto preexisting_cookie = CanonicalCookie::CreateForTesting(
4198*6777b538SAndroid Build Coastguard Worker       https_www_foo_.url(), "A=B;Secure;HttpOnly", base::Time::Now());
4199*6777b538SAndroid Build Coastguard Worker   CookieAccessResult access_result = SetCanonicalCookieReturnAccessResult(
4200*6777b538SAndroid Build Coastguard Worker       cm.get(), std::move(preexisting_cookie), https_www_foo_.url(),
4201*6777b538SAndroid Build Coastguard Worker       true /* can_modify_httponly */);
4202*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(access_result.status.IsInclude());
4203*6777b538SAndroid Build Coastguard Worker 
4204*6777b538SAndroid Build Coastguard Worker   // Set a new cookie with a different name. Should work because cookies with
4205*6777b538SAndroid Build Coastguard Worker   // different names are not considered equivalent nor "equivalent for secure
4206*6777b538SAndroid Build Coastguard Worker   // cookie matching".
4207*6777b538SAndroid Build Coastguard Worker   // Same origin:
4208*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), https_www_foo_.url(), "B=A;"));
4209*6777b538SAndroid Build Coastguard Worker   // Different scheme, same domain:
4210*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), http_www_foo_.url(), "C=A;"));
4211*6777b538SAndroid Build Coastguard Worker 
4212*6777b538SAndroid Build Coastguard Worker   // Set a non-Secure cookie from an insecure origin that is
4213*6777b538SAndroid Build Coastguard Worker   // equivalent to the pre-existing Secure cookie.
4214*6777b538SAndroid Build Coastguard Worker   auto bad_cookie = CanonicalCookie::CreateForTesting(http_www_foo_.url(),
4215*6777b538SAndroid Build Coastguard Worker                                                       "A=D", base::Time::Now());
4216*6777b538SAndroid Build Coastguard Worker   // Allow modifying HttpOnly, so that we don't skip preexisting cookies for
4217*6777b538SAndroid Build Coastguard Worker   // being HttpOnly.
4218*6777b538SAndroid Build Coastguard Worker   access_result = SetCanonicalCookieReturnAccessResult(
4219*6777b538SAndroid Build Coastguard Worker       cm.get(), std::move(bad_cookie), http_www_foo_.url(),
4220*6777b538SAndroid Build Coastguard Worker       true /* can_modify_httponly */);
4221*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(access_result.status.HasExactlyExclusionReasonsForTesting(
4222*6777b538SAndroid Build Coastguard Worker       {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
4223*6777b538SAndroid Build Coastguard Worker   // The preexisting cookie should still be there.
4224*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(GetCookiesWithOptions(cm.get(), https_www_foo_.url(),
4225*6777b538SAndroid Build Coastguard Worker                                     CookieOptions::MakeAllInclusive()),
4226*6777b538SAndroid Build Coastguard Worker               ::testing::HasSubstr("A=B"));
4227*6777b538SAndroid Build Coastguard Worker 
4228*6777b538SAndroid Build Coastguard Worker   auto entries = net_log_.GetEntries();
4229*6777b538SAndroid Build Coastguard Worker   size_t skipped_secure_netlog_index = ExpectLogContainsSomewhere(
4230*6777b538SAndroid Build Coastguard Worker       entries, 0, NetLogEventType::COOKIE_STORE_COOKIE_REJECTED_SECURE,
4231*6777b538SAndroid Build Coastguard Worker       NetLogEventPhase::NONE);
4232*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(LogContainsEntryWithTypeAfter(
4233*6777b538SAndroid Build Coastguard Worker       entries, 0, NetLogEventType::COOKIE_STORE_COOKIE_REJECTED_HTTPONLY));
4234*6777b538SAndroid Build Coastguard Worker   ExpectLogContainsSomewhereAfter(
4235*6777b538SAndroid Build Coastguard Worker       entries, skipped_secure_netlog_index,
4236*6777b538SAndroid Build Coastguard Worker       NetLogEventType::COOKIE_STORE_COOKIE_PRESERVED_SKIPPED_SECURE,
4237*6777b538SAndroid Build Coastguard Worker       NetLogEventPhase::NONE);
4238*6777b538SAndroid Build Coastguard Worker 
4239*6777b538SAndroid Build Coastguard Worker   net_log_.Clear();
4240*6777b538SAndroid Build Coastguard Worker 
4241*6777b538SAndroid Build Coastguard Worker   // Set a non-secure cookie from an insecure origin that matches the name of an
4242*6777b538SAndroid Build Coastguard Worker   // already existing cookie but is not equivalent. This should fail since it's
4243*6777b538SAndroid Build Coastguard Worker   // trying to shadow a secure cookie.
4244*6777b538SAndroid Build Coastguard Worker   bad_cookie = CanonicalCookie::CreateForTesting(
4245*6777b538SAndroid Build Coastguard Worker       http_www_foo_.url(), "A=E; path=/some/path", base::Time::Now());
4246*6777b538SAndroid Build Coastguard Worker   // Allow modifying HttpOnly, so that we don't skip preexisting cookies for
4247*6777b538SAndroid Build Coastguard Worker   // being HttpOnly.
4248*6777b538SAndroid Build Coastguard Worker   access_result = SetCanonicalCookieReturnAccessResult(
4249*6777b538SAndroid Build Coastguard Worker       cm.get(), std::move(bad_cookie), http_www_foo_.url(),
4250*6777b538SAndroid Build Coastguard Worker       true /* can_modify_httponly */);
4251*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(access_result.status.HasExactlyExclusionReasonsForTesting(
4252*6777b538SAndroid Build Coastguard Worker       {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
4253*6777b538SAndroid Build Coastguard Worker   // The preexisting cookie should still be there.
4254*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(GetCookiesWithOptions(cm.get(), https_www_foo_.url(),
4255*6777b538SAndroid Build Coastguard Worker                                     CookieOptions::MakeAllInclusive()),
4256*6777b538SAndroid Build Coastguard Worker               ::testing::HasSubstr("A=B"));
4257*6777b538SAndroid Build Coastguard Worker 
4258*6777b538SAndroid Build Coastguard Worker   entries = net_log_.GetEntries();
4259*6777b538SAndroid Build Coastguard Worker   skipped_secure_netlog_index = ExpectLogContainsSomewhere(
4260*6777b538SAndroid Build Coastguard Worker       entries, 0, NetLogEventType::COOKIE_STORE_COOKIE_REJECTED_SECURE,
4261*6777b538SAndroid Build Coastguard Worker       NetLogEventPhase::NONE);
4262*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(LogContainsEntryWithTypeAfter(
4263*6777b538SAndroid Build Coastguard Worker       entries, 0, NetLogEventType::COOKIE_STORE_COOKIE_REJECTED_HTTPONLY));
4264*6777b538SAndroid Build Coastguard Worker   // There wasn't actually a strictly equivalent cookie that we would have
4265*6777b538SAndroid Build Coastguard Worker   // deleted.
4266*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(LogContainsEntryWithTypeAfter(
4267*6777b538SAndroid Build Coastguard Worker       entries, skipped_secure_netlog_index,
4268*6777b538SAndroid Build Coastguard Worker       NetLogEventType::COOKIE_STORE_COOKIE_PRESERVED_SKIPPED_SECURE));
4269*6777b538SAndroid Build Coastguard Worker 
4270*6777b538SAndroid Build Coastguard Worker   net_log_.Clear();
4271*6777b538SAndroid Build Coastguard Worker 
4272*6777b538SAndroid Build Coastguard Worker   // Test skipping equivalent cookie for HttpOnly only.
4273*6777b538SAndroid Build Coastguard Worker   bad_cookie = CanonicalCookie::CreateForTesting(
4274*6777b538SAndroid Build Coastguard Worker       https_www_foo_.url(), "A=E; Secure", base::Time::Now());
4275*6777b538SAndroid Build Coastguard Worker   access_result = SetCanonicalCookieReturnAccessResult(
4276*6777b538SAndroid Build Coastguard Worker       cm.get(), std::move(bad_cookie), https_www_foo_.url(),
4277*6777b538SAndroid Build Coastguard Worker       false /* can_modify_httponly */);
4278*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(access_result.status.HasExactlyExclusionReasonsForTesting(
4279*6777b538SAndroid Build Coastguard Worker       {CookieInclusionStatus::EXCLUDE_OVERWRITE_HTTP_ONLY}));
4280*6777b538SAndroid Build Coastguard Worker 
4281*6777b538SAndroid Build Coastguard Worker   entries = net_log_.GetEntries();
4282*6777b538SAndroid Build Coastguard Worker   ExpectLogContainsSomewhere(
4283*6777b538SAndroid Build Coastguard Worker       entries, 0, NetLogEventType::COOKIE_STORE_COOKIE_REJECTED_HTTPONLY,
4284*6777b538SAndroid Build Coastguard Worker       NetLogEventPhase::NONE);
4285*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(LogContainsEntryWithTypeAfter(
4286*6777b538SAndroid Build Coastguard Worker       entries, 0, NetLogEventType::COOKIE_STORE_COOKIE_REJECTED_SECURE));
4287*6777b538SAndroid Build Coastguard Worker }
4288*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,MaybeDeleteEquivalentCookieAndUpdateStatus_PartitionedCookies)4289*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest,
4290*6777b538SAndroid Build Coastguard Worker        MaybeDeleteEquivalentCookieAndUpdateStatus_PartitionedCookies) {
4291*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
4292*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
4293*6777b538SAndroid Build Coastguard Worker 
4294*6777b538SAndroid Build Coastguard Worker   // Test adding two cookies with the same name, domain, and path but different
4295*6777b538SAndroid Build Coastguard Worker   // partition keys.
4296*6777b538SAndroid Build Coastguard Worker   auto cookie_partition_key1 =
4297*6777b538SAndroid Build Coastguard Worker       CookiePartitionKey::FromURLForTesting(GURL("https://toplevelsite1.com"));
4298*6777b538SAndroid Build Coastguard Worker 
4299*6777b538SAndroid Build Coastguard Worker   auto preexisting_cookie = CanonicalCookie::CreateForTesting(
4300*6777b538SAndroid Build Coastguard Worker       https_www_foo_.url(), "__Host-A=B; Secure; Path=/; Partitioned; HttpOnly",
4301*6777b538SAndroid Build Coastguard Worker       base::Time::Now(), std::nullopt /* server_time */,
4302*6777b538SAndroid Build Coastguard Worker       cookie_partition_key1 /* cookie_partition_key */);
4303*6777b538SAndroid Build Coastguard Worker   CookieAccessResult access_result = SetCanonicalCookieReturnAccessResult(
4304*6777b538SAndroid Build Coastguard Worker       cm.get(), std::move(preexisting_cookie), https_www_foo_.url(),
4305*6777b538SAndroid Build Coastguard Worker       true /* can_modify_httponly */);
4306*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(access_result.status.IsInclude());
4307*6777b538SAndroid Build Coastguard Worker 
4308*6777b538SAndroid Build Coastguard Worker   // Should be able to set a cookie with a different partition key.
4309*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), https_www_foo_.url(),
4310*6777b538SAndroid Build Coastguard Worker                         "__Host-A=C; Secure; Path=/; Partitioned",
4311*6777b538SAndroid Build Coastguard Worker                         CookiePartitionKey::FromURLForTesting(
4312*6777b538SAndroid Build Coastguard Worker                             GURL("https://toplevelsite2.com"))));
4313*6777b538SAndroid Build Coastguard Worker 
4314*6777b538SAndroid Build Coastguard Worker   // Should not overwrite HttpOnly cookie.
4315*6777b538SAndroid Build Coastguard Worker   auto bad_cookie = CanonicalCookie::CreateForTesting(
4316*6777b538SAndroid Build Coastguard Worker       https_www_foo_.url(), "__Host-A=D; Secure; Path=/; Partitioned",
4317*6777b538SAndroid Build Coastguard Worker       base::Time::Now(), std::nullopt /* server_time */, cookie_partition_key1);
4318*6777b538SAndroid Build Coastguard Worker   access_result = SetCanonicalCookieReturnAccessResult(
4319*6777b538SAndroid Build Coastguard Worker       cm.get(), std::move(bad_cookie), https_www_foo_.url(),
4320*6777b538SAndroid Build Coastguard Worker       false /* can_modify_httponly */);
4321*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(access_result.status.HasExactlyExclusionReasonsForTesting(
4322*6777b538SAndroid Build Coastguard Worker       {CookieInclusionStatus::EXCLUDE_OVERWRITE_HTTP_ONLY}));
4323*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
4324*6777b538SAndroid Build Coastguard Worker       GetCookiesWithOptions(
4325*6777b538SAndroid Build Coastguard Worker           cm.get(), https_www_foo_.url(), CookieOptions::MakeAllInclusive(),
4326*6777b538SAndroid Build Coastguard Worker           CookiePartitionKeyCollection(cookie_partition_key1)),
4327*6777b538SAndroid Build Coastguard Worker       ::testing::HasSubstr("A=B"));
4328*6777b538SAndroid Build Coastguard Worker }
4329*6777b538SAndroid Build Coastguard Worker 
4330*6777b538SAndroid Build Coastguard Worker // Tests whether cookies that vary based on their source scheme/port are
4331*6777b538SAndroid Build Coastguard Worker // overwritten correctly depending on the state of the origin-bound feature
4332*6777b538SAndroid Build Coastguard Worker // flags.
4333*6777b538SAndroid Build Coastguard Worker class CookieMonsterTest_MaybeDeleteEquivalentCookieAndUpdateStatus
4334*6777b538SAndroid Build Coastguard Worker     : public CookieMonsterTest {
4335*6777b538SAndroid Build Coastguard Worker  public:
4336*6777b538SAndroid Build Coastguard Worker   // Creates a store, CookieMonster, and inserts a single cookie, created on an
4337*6777b538SAndroid Build Coastguard Worker   // https/443 origin.
InitializeTest()4338*6777b538SAndroid Build Coastguard Worker   void InitializeTest() {
4339*6777b538SAndroid Build Coastguard Worker     store_ = base::MakeRefCounted<MockPersistentCookieStore>();
4340*6777b538SAndroid Build Coastguard Worker     cm_ = std::make_unique<CookieMonster>(store_.get(), net::NetLog::Get());
4341*6777b538SAndroid Build Coastguard Worker 
4342*6777b538SAndroid Build Coastguard Worker     auto preexisting_cookie_https = CanonicalCookie::CreateForTesting(
4343*6777b538SAndroid Build Coastguard Worker         https_www_foo_.url(), "A=PreexistingHttps443", base::Time::Now());
4344*6777b538SAndroid Build Coastguard Worker 
4345*6777b538SAndroid Build Coastguard Worker     CookieAccessResult access_result = SetCanonicalCookieReturnAccessResult(
4346*6777b538SAndroid Build Coastguard Worker         cm_.get(), std::move(preexisting_cookie_https), https_www_foo_.url(),
4347*6777b538SAndroid Build Coastguard Worker         /*can_modify_httponly=*/true);
4348*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(access_result.status.IsInclude());
4349*6777b538SAndroid Build Coastguard Worker 
4350*6777b538SAndroid Build Coastguard Worker     auto preexisting_domain_cookie_https = CanonicalCookie::CreateForTesting(
4351*6777b538SAndroid Build Coastguard Worker         https_www_foo_.url(),
4352*6777b538SAndroid Build Coastguard Worker         "A=PreexistingDomainHttps443; Domain=" + https_www_foo_.domain(),
4353*6777b538SAndroid Build Coastguard Worker         base::Time::Now());
4354*6777b538SAndroid Build Coastguard Worker 
4355*6777b538SAndroid Build Coastguard Worker     access_result = SetCanonicalCookieReturnAccessResult(
4356*6777b538SAndroid Build Coastguard Worker         cm_.get(), std::move(preexisting_domain_cookie_https),
4357*6777b538SAndroid Build Coastguard Worker         https_www_foo_.url(),
4358*6777b538SAndroid Build Coastguard Worker         /*can_modify_httponly=*/true);
4359*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(access_result.status.IsInclude());
4360*6777b538SAndroid Build Coastguard Worker 
4361*6777b538SAndroid Build Coastguard Worker     ASSERT_EQ(GetAllCookies(cm_.get()).size(), 2UL);
4362*6777b538SAndroid Build Coastguard Worker   }
4363*6777b538SAndroid Build Coastguard Worker 
4364*6777b538SAndroid Build Coastguard Worker   // Inserts a single cookie that differs from "PreexistingHttps443" by scheme
4365*6777b538SAndroid Build Coastguard Worker   // only.
AddHttpPort443Cookie()4366*6777b538SAndroid Build Coastguard Worker   void AddHttpPort443Cookie() {
4367*6777b538SAndroid Build Coastguard Worker     GURL::Replacements replace_scheme;
4368*6777b538SAndroid Build Coastguard Worker     replace_scheme.SetSchemeStr("http");
4369*6777b538SAndroid Build Coastguard Worker     // We need to explicitly set the existing port, otherwise GURL will
4370*6777b538SAndroid Build Coastguard Worker     // implicitly take the port of the new scheme. I.e.: We'll inadvertently
4371*6777b538SAndroid Build Coastguard Worker     // change the port to 80.
4372*6777b538SAndroid Build Coastguard Worker     replace_scheme.SetPortStr("443");
4373*6777b538SAndroid Build Coastguard Worker     GURL foo_made_http = https_www_foo_.url().ReplaceComponents(replace_scheme);
4374*6777b538SAndroid Build Coastguard Worker 
4375*6777b538SAndroid Build Coastguard Worker     auto differ_by_scheme_only = CanonicalCookie::CreateForTesting(
4376*6777b538SAndroid Build Coastguard Worker         foo_made_http, "A=InsertedHttp443", base::Time::Now());
4377*6777b538SAndroid Build Coastguard Worker 
4378*6777b538SAndroid Build Coastguard Worker     CookieAccessResult access_result = SetCanonicalCookieReturnAccessResult(
4379*6777b538SAndroid Build Coastguard Worker         cm_.get(), std::move(differ_by_scheme_only), foo_made_http,
4380*6777b538SAndroid Build Coastguard Worker         /*can_modify_httponly=*/true);
4381*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(access_result.status.IsInclude());
4382*6777b538SAndroid Build Coastguard Worker   }
4383*6777b538SAndroid Build Coastguard Worker 
4384*6777b538SAndroid Build Coastguard Worker   // Inserts a single cookie that differs from "PreexistingHttps443" by port
4385*6777b538SAndroid Build Coastguard Worker   // only.
AddHttpsPort80Cookie()4386*6777b538SAndroid Build Coastguard Worker   void AddHttpsPort80Cookie() {
4387*6777b538SAndroid Build Coastguard Worker     GURL::Replacements replace_port;
4388*6777b538SAndroid Build Coastguard Worker     replace_port.SetPortStr("80");
4389*6777b538SAndroid Build Coastguard Worker     GURL foo_made_80 = https_www_foo_.url().ReplaceComponents(replace_port);
4390*6777b538SAndroid Build Coastguard Worker 
4391*6777b538SAndroid Build Coastguard Worker     auto differ_by_port_only = CanonicalCookie::CreateForTesting(
4392*6777b538SAndroid Build Coastguard Worker         foo_made_80, "A=InsertedHttps80", base::Time::Now());
4393*6777b538SAndroid Build Coastguard Worker 
4394*6777b538SAndroid Build Coastguard Worker     CookieAccessResult access_result = SetCanonicalCookieReturnAccessResult(
4395*6777b538SAndroid Build Coastguard Worker         cm_.get(), std::move(differ_by_port_only), foo_made_80,
4396*6777b538SAndroid Build Coastguard Worker         /*can_modify_httponly=*/true);
4397*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(access_result.status.IsInclude());
4398*6777b538SAndroid Build Coastguard Worker   }
4399*6777b538SAndroid Build Coastguard Worker 
4400*6777b538SAndroid Build Coastguard Worker   // Inserts a single Domain cookie that differs from
4401*6777b538SAndroid Build Coastguard Worker   // "PreexistingDomainHttps443" by port only.
AddDomainHttpsPort80Cookie()4402*6777b538SAndroid Build Coastguard Worker   void AddDomainHttpsPort80Cookie() {
4403*6777b538SAndroid Build Coastguard Worker     GURL::Replacements replace_port;
4404*6777b538SAndroid Build Coastguard Worker     replace_port.SetPortStr("80");
4405*6777b538SAndroid Build Coastguard Worker     GURL foo_made_80 = https_www_foo_.url().ReplaceComponents(replace_port);
4406*6777b538SAndroid Build Coastguard Worker 
4407*6777b538SAndroid Build Coastguard Worker     auto differ_by_port_only = CanonicalCookie::CreateForTesting(
4408*6777b538SAndroid Build Coastguard Worker         foo_made_80,
4409*6777b538SAndroid Build Coastguard Worker         "A=InsertedDomainHttps80; Domain=" + https_www_foo_.domain(),
4410*6777b538SAndroid Build Coastguard Worker         base::Time::Now());
4411*6777b538SAndroid Build Coastguard Worker 
4412*6777b538SAndroid Build Coastguard Worker     CookieAccessResult access_result = SetCanonicalCookieReturnAccessResult(
4413*6777b538SAndroid Build Coastguard Worker         cm_.get(), std::move(differ_by_port_only), foo_made_80,
4414*6777b538SAndroid Build Coastguard Worker         /*can_modify_httponly=*/true);
4415*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(access_result.status.IsInclude());
4416*6777b538SAndroid Build Coastguard Worker   }
4417*6777b538SAndroid Build Coastguard Worker 
4418*6777b538SAndroid Build Coastguard Worker   scoped_refptr<net::MockPersistentCookieStore> store_;
4419*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<CookieMonster> cm_;
4420*6777b538SAndroid Build Coastguard Worker   base::test::ScopedFeatureList scoped_feature_list_;
4421*6777b538SAndroid Build Coastguard Worker };
4422*6777b538SAndroid Build Coastguard Worker 
4423*6777b538SAndroid Build Coastguard Worker // Scheme binding disabled.
4424*6777b538SAndroid Build Coastguard Worker // Port binding disabled.
4425*6777b538SAndroid Build Coastguard Worker // Cookies that differ only in their scheme and/or port should overwrite the
4426*6777b538SAndroid Build Coastguard Worker // preexisting cookies.
TEST_F(CookieMonsterTest_MaybeDeleteEquivalentCookieAndUpdateStatus,NoSchemeNoPort)4427*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest_MaybeDeleteEquivalentCookieAndUpdateStatus,
4428*6777b538SAndroid Build Coastguard Worker        NoSchemeNoPort) {
4429*6777b538SAndroid Build Coastguard Worker   scoped_feature_list_.InitWithFeatures(
4430*6777b538SAndroid Build Coastguard Worker       {}, {net::features::kEnableSchemeBoundCookies,
4431*6777b538SAndroid Build Coastguard Worker            net::features::kEnablePortBoundCookies});
4432*6777b538SAndroid Build Coastguard Worker 
4433*6777b538SAndroid Build Coastguard Worker   InitializeTest();
4434*6777b538SAndroid Build Coastguard Worker 
4435*6777b538SAndroid Build Coastguard Worker   AddHttpPort443Cookie();
4436*6777b538SAndroid Build Coastguard Worker 
4437*6777b538SAndroid Build Coastguard Worker   auto cookies = GetAllCookies(cm_.get());
4438*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cookies,
4439*6777b538SAndroid Build Coastguard Worker               testing::UnorderedElementsAre(
4440*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "InsertedHttp443"),
4441*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "PreexistingDomainHttps443")));
4442*6777b538SAndroid Build Coastguard Worker 
4443*6777b538SAndroid Build Coastguard Worker   AddHttpsPort80Cookie();
4444*6777b538SAndroid Build Coastguard Worker 
4445*6777b538SAndroid Build Coastguard Worker   cookies = GetAllCookies(cm_.get());
4446*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cookies,
4447*6777b538SAndroid Build Coastguard Worker               testing::UnorderedElementsAre(
4448*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "InsertedHttps80"),
4449*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "PreexistingDomainHttps443")));
4450*6777b538SAndroid Build Coastguard Worker 
4451*6777b538SAndroid Build Coastguard Worker   AddDomainHttpsPort80Cookie();
4452*6777b538SAndroid Build Coastguard Worker 
4453*6777b538SAndroid Build Coastguard Worker   cookies = GetAllCookies(cm_.get());
4454*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cookies,
4455*6777b538SAndroid Build Coastguard Worker               testing::UnorderedElementsAre(
4456*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "InsertedHttps80"),
4457*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "InsertedDomainHttps80")));
4458*6777b538SAndroid Build Coastguard Worker }
4459*6777b538SAndroid Build Coastguard Worker 
4460*6777b538SAndroid Build Coastguard Worker // Scheme binding enabled.
4461*6777b538SAndroid Build Coastguard Worker // Port binding disabled.
4462*6777b538SAndroid Build Coastguard Worker // Cookies that differ in scheme are separate, cookies that differ only by
4463*6777b538SAndroid Build Coastguard Worker // port should be overwritten.
TEST_F(CookieMonsterTest_MaybeDeleteEquivalentCookieAndUpdateStatus,YesSchemeNoPort)4464*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest_MaybeDeleteEquivalentCookieAndUpdateStatus,
4465*6777b538SAndroid Build Coastguard Worker        YesSchemeNoPort) {
4466*6777b538SAndroid Build Coastguard Worker   scoped_feature_list_.InitWithFeatures(
4467*6777b538SAndroid Build Coastguard Worker       {net::features::kEnableSchemeBoundCookies},
4468*6777b538SAndroid Build Coastguard Worker       {net::features::kEnablePortBoundCookies});
4469*6777b538SAndroid Build Coastguard Worker 
4470*6777b538SAndroid Build Coastguard Worker   InitializeTest();
4471*6777b538SAndroid Build Coastguard Worker 
4472*6777b538SAndroid Build Coastguard Worker   AddHttpPort443Cookie();
4473*6777b538SAndroid Build Coastguard Worker 
4474*6777b538SAndroid Build Coastguard Worker   auto cookies = GetAllCookies(cm_.get());
4475*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cookies,
4476*6777b538SAndroid Build Coastguard Worker               testing::UnorderedElementsAre(
4477*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "PreexistingHttps443"),
4478*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "InsertedHttp443"),
4479*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "PreexistingDomainHttps443")));
4480*6777b538SAndroid Build Coastguard Worker 
4481*6777b538SAndroid Build Coastguard Worker   AddHttpsPort80Cookie();
4482*6777b538SAndroid Build Coastguard Worker 
4483*6777b538SAndroid Build Coastguard Worker   cookies = GetAllCookies(cm_.get());
4484*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cookies,
4485*6777b538SAndroid Build Coastguard Worker               testing::UnorderedElementsAre(
4486*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "InsertedHttp443"),
4487*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "InsertedHttps80"),
4488*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "PreexistingDomainHttps443")));
4489*6777b538SAndroid Build Coastguard Worker 
4490*6777b538SAndroid Build Coastguard Worker   AddDomainHttpsPort80Cookie();
4491*6777b538SAndroid Build Coastguard Worker 
4492*6777b538SAndroid Build Coastguard Worker   cookies = GetAllCookies(cm_.get());
4493*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cookies,
4494*6777b538SAndroid Build Coastguard Worker               testing::UnorderedElementsAre(
4495*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "InsertedHttp443"),
4496*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "InsertedHttps80"),
4497*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "InsertedDomainHttps80")));
4498*6777b538SAndroid Build Coastguard Worker }
4499*6777b538SAndroid Build Coastguard Worker 
4500*6777b538SAndroid Build Coastguard Worker // Scheme binding disabled.
4501*6777b538SAndroid Build Coastguard Worker // Port binding enabled.
4502*6777b538SAndroid Build Coastguard Worker // Cookies that differ only by scheme and Domain cookies that differ only by
4503*6777b538SAndroid Build Coastguard Worker // port should be overwritten. Host cookies that differ only by port are
4504*6777b538SAndroid Build Coastguard Worker // separate.
TEST_F(CookieMonsterTest_MaybeDeleteEquivalentCookieAndUpdateStatus,NoSchemeYesPort)4505*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest_MaybeDeleteEquivalentCookieAndUpdateStatus,
4506*6777b538SAndroid Build Coastguard Worker        NoSchemeYesPort) {
4507*6777b538SAndroid Build Coastguard Worker   scoped_feature_list_.InitWithFeatures(
4508*6777b538SAndroid Build Coastguard Worker       {net::features::kEnablePortBoundCookies},
4509*6777b538SAndroid Build Coastguard Worker       {net::features::kEnableSchemeBoundCookies});
4510*6777b538SAndroid Build Coastguard Worker 
4511*6777b538SAndroid Build Coastguard Worker   InitializeTest();
4512*6777b538SAndroid Build Coastguard Worker 
4513*6777b538SAndroid Build Coastguard Worker   AddHttpPort443Cookie();
4514*6777b538SAndroid Build Coastguard Worker 
4515*6777b538SAndroid Build Coastguard Worker   auto cookies = GetAllCookies(cm_.get());
4516*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cookies,
4517*6777b538SAndroid Build Coastguard Worker               testing::UnorderedElementsAre(
4518*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "InsertedHttp443"),
4519*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "PreexistingDomainHttps443")));
4520*6777b538SAndroid Build Coastguard Worker 
4521*6777b538SAndroid Build Coastguard Worker   AddHttpsPort80Cookie();
4522*6777b538SAndroid Build Coastguard Worker 
4523*6777b538SAndroid Build Coastguard Worker   cookies = GetAllCookies(cm_.get());
4524*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cookies,
4525*6777b538SAndroid Build Coastguard Worker               testing::UnorderedElementsAre(
4526*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "InsertedHttp443"),
4527*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "InsertedHttps80"),
4528*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "PreexistingDomainHttps443")));
4529*6777b538SAndroid Build Coastguard Worker 
4530*6777b538SAndroid Build Coastguard Worker   AddDomainHttpsPort80Cookie();
4531*6777b538SAndroid Build Coastguard Worker 
4532*6777b538SAndroid Build Coastguard Worker   cookies = GetAllCookies(cm_.get());
4533*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cookies,
4534*6777b538SAndroid Build Coastguard Worker               testing::UnorderedElementsAre(
4535*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "InsertedHttp443"),
4536*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "InsertedHttps80"),
4537*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "InsertedDomainHttps80")));
4538*6777b538SAndroid Build Coastguard Worker }
4539*6777b538SAndroid Build Coastguard Worker 
4540*6777b538SAndroid Build Coastguard Worker // Scheme binding enabled.
4541*6777b538SAndroid Build Coastguard Worker // Port binding enabled.
4542*6777b538SAndroid Build Coastguard Worker // Cookies that differ by port or scheme are separate. Except for Domain cookies
4543*6777b538SAndroid Build Coastguard Worker // which will be overwritten if they differ only by port.
TEST_F(CookieMonsterTest_MaybeDeleteEquivalentCookieAndUpdateStatus,YesSchemeYesPort)4544*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest_MaybeDeleteEquivalentCookieAndUpdateStatus,
4545*6777b538SAndroid Build Coastguard Worker        YesSchemeYesPort) {
4546*6777b538SAndroid Build Coastguard Worker   scoped_feature_list_.InitWithFeatures(
4547*6777b538SAndroid Build Coastguard Worker       {net::features::kEnableSchemeBoundCookies,
4548*6777b538SAndroid Build Coastguard Worker        net::features::kEnablePortBoundCookies},
4549*6777b538SAndroid Build Coastguard Worker       {});
4550*6777b538SAndroid Build Coastguard Worker 
4551*6777b538SAndroid Build Coastguard Worker   InitializeTest();
4552*6777b538SAndroid Build Coastguard Worker 
4553*6777b538SAndroid Build Coastguard Worker   AddHttpPort443Cookie();
4554*6777b538SAndroid Build Coastguard Worker 
4555*6777b538SAndroid Build Coastguard Worker   auto cookies = GetAllCookies(cm_.get());
4556*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cookies,
4557*6777b538SAndroid Build Coastguard Worker               testing::UnorderedElementsAre(
4558*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "PreexistingHttps443"),
4559*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "InsertedHttp443"),
4560*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "PreexistingDomainHttps443")));
4561*6777b538SAndroid Build Coastguard Worker 
4562*6777b538SAndroid Build Coastguard Worker   AddHttpsPort80Cookie();
4563*6777b538SAndroid Build Coastguard Worker 
4564*6777b538SAndroid Build Coastguard Worker   cookies = GetAllCookies(cm_.get());
4565*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cookies,
4566*6777b538SAndroid Build Coastguard Worker               testing::UnorderedElementsAre(
4567*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "PreexistingHttps443"),
4568*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "InsertedHttp443"),
4569*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "InsertedHttps80"),
4570*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "PreexistingDomainHttps443")));
4571*6777b538SAndroid Build Coastguard Worker 
4572*6777b538SAndroid Build Coastguard Worker   AddDomainHttpsPort80Cookie();
4573*6777b538SAndroid Build Coastguard Worker 
4574*6777b538SAndroid Build Coastguard Worker   cookies = GetAllCookies(cm_.get());
4575*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cookies,
4576*6777b538SAndroid Build Coastguard Worker               testing::UnorderedElementsAre(
4577*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "PreexistingHttps443"),
4578*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "InsertedHttp443"),
4579*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "InsertedHttps80"),
4580*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("A", "InsertedDomainHttps80")));
4581*6777b538SAndroid Build Coastguard Worker }
4582*6777b538SAndroid Build Coastguard Worker 
4583*6777b538SAndroid Build Coastguard Worker // Tests that only the correct set of (potentially duplicate) cookies are loaded
4584*6777b538SAndroid Build Coastguard Worker // from the backend store depending on the state of the origin-bound feature
4585*6777b538SAndroid Build Coastguard Worker // flags.
4586*6777b538SAndroid Build Coastguard Worker class CookieMonsterTest_StoreLoadedCookies : public CookieMonsterTest {
4587*6777b538SAndroid Build Coastguard Worker  public:
InitializeTest()4588*6777b538SAndroid Build Coastguard Worker   void InitializeTest() {
4589*6777b538SAndroid Build Coastguard Worker     store_ = base::MakeRefCounted<MockPersistentCookieStore>();
4590*6777b538SAndroid Build Coastguard Worker     cm_ = std::make_unique<CookieMonster>(store_.get(), net::NetLog::Get());
4591*6777b538SAndroid Build Coastguard Worker 
4592*6777b538SAndroid Build Coastguard Worker     base::Time most_recent_time = base::Time::Now();
4593*6777b538SAndroid Build Coastguard Worker     base::Time middle_time = most_recent_time - base::Minutes(1);
4594*6777b538SAndroid Build Coastguard Worker     base::Time least_recent_time = middle_time - base::Minutes(1);
4595*6777b538SAndroid Build Coastguard Worker 
4596*6777b538SAndroid Build Coastguard Worker     auto basic_cookie = CanonicalCookie::CreateForTesting(
4597*6777b538SAndroid Build Coastguard Worker         https_www_foo_.url(), "A=basic", base::Time::Now());
4598*6777b538SAndroid Build Coastguard Worker 
4599*6777b538SAndroid Build Coastguard Worker     // When there are duplicate cookies the most recent one is kept. So, this
4600*6777b538SAndroid Build Coastguard Worker     // one.
4601*6777b538SAndroid Build Coastguard Worker     basic_cookie->SetCreationDate(most_recent_time);
4602*6777b538SAndroid Build Coastguard Worker     starting_list_.push_back(std::move(basic_cookie));
4603*6777b538SAndroid Build Coastguard Worker 
4604*6777b538SAndroid Build Coastguard Worker     GURL::Replacements replace_scheme;
4605*6777b538SAndroid Build Coastguard Worker     replace_scheme.SetSchemeStr("http");
4606*6777b538SAndroid Build Coastguard Worker     // We need to explicitly set the existing port, otherwise GURL will
4607*6777b538SAndroid Build Coastguard Worker     // implicitly take the port of the new scheme. I.e.: We'll inadvertently
4608*6777b538SAndroid Build Coastguard Worker     // change the port to 80.
4609*6777b538SAndroid Build Coastguard Worker     replace_scheme.SetPortStr("443");
4610*6777b538SAndroid Build Coastguard Worker     GURL foo_with_http = https_www_foo_.url().ReplaceComponents(replace_scheme);
4611*6777b538SAndroid Build Coastguard Worker 
4612*6777b538SAndroid Build Coastguard Worker     auto http_cookie = CanonicalCookie::CreateForTesting(
4613*6777b538SAndroid Build Coastguard Worker         foo_with_http, "A=http", base::Time::Now());
4614*6777b538SAndroid Build Coastguard Worker 
4615*6777b538SAndroid Build Coastguard Worker     http_cookie->SetCreationDate(middle_time);
4616*6777b538SAndroid Build Coastguard Worker     starting_list_.push_back(std::move(http_cookie));
4617*6777b538SAndroid Build Coastguard Worker 
4618*6777b538SAndroid Build Coastguard Worker     GURL::Replacements replace_port;
4619*6777b538SAndroid Build Coastguard Worker     replace_port.SetPortStr("450");
4620*6777b538SAndroid Build Coastguard Worker     GURL foo_with_450 = https_www_foo_.url().ReplaceComponents(replace_port);
4621*6777b538SAndroid Build Coastguard Worker 
4622*6777b538SAndroid Build Coastguard Worker     auto port_450_cookie = CanonicalCookie::CreateForTesting(
4623*6777b538SAndroid Build Coastguard Worker         foo_with_450, "A=port450", base::Time::Now());
4624*6777b538SAndroid Build Coastguard Worker     port_450_cookie->SetCreationDate(least_recent_time);
4625*6777b538SAndroid Build Coastguard Worker     starting_list_.push_back(std::move(port_450_cookie));
4626*6777b538SAndroid Build Coastguard Worker 
4627*6777b538SAndroid Build Coastguard Worker     auto basic_domain_cookie = CanonicalCookie::CreateForTesting(
4628*6777b538SAndroid Build Coastguard Worker         https_www_foo_.url(),
4629*6777b538SAndroid Build Coastguard Worker         "A=basic_domain; Domain=" + https_www_foo_.domain(), base::Time::Now());
4630*6777b538SAndroid Build Coastguard Worker 
4631*6777b538SAndroid Build Coastguard Worker     // When there are duplicate domain cookies the most recent one is kept. So,
4632*6777b538SAndroid Build Coastguard Worker     // this one.
4633*6777b538SAndroid Build Coastguard Worker     basic_domain_cookie->SetCreationDate(most_recent_time);
4634*6777b538SAndroid Build Coastguard Worker     starting_list_.push_back(std::move(basic_domain_cookie));
4635*6777b538SAndroid Build Coastguard Worker 
4636*6777b538SAndroid Build Coastguard Worker     auto http_domain_cookie = CanonicalCookie::CreateForTesting(
4637*6777b538SAndroid Build Coastguard Worker         foo_with_http, "A=http_domain; Domain=" + https_www_foo_.domain(),
4638*6777b538SAndroid Build Coastguard Worker         base::Time::Now());
4639*6777b538SAndroid Build Coastguard Worker 
4640*6777b538SAndroid Build Coastguard Worker     http_domain_cookie->SetCreationDate(middle_time);
4641*6777b538SAndroid Build Coastguard Worker     starting_list_.push_back(std::move(http_domain_cookie));
4642*6777b538SAndroid Build Coastguard Worker 
4643*6777b538SAndroid Build Coastguard Worker     // Domain cookies don't consider the port, so this cookie should always be
4644*6777b538SAndroid Build Coastguard Worker     // considered a duplicate.
4645*6777b538SAndroid Build Coastguard Worker     auto port_450_domain_cookie = CanonicalCookie::CreateForTesting(
4646*6777b538SAndroid Build Coastguard Worker         foo_with_450, "A=port450_domain; Domain=" + https_www_foo_.domain(),
4647*6777b538SAndroid Build Coastguard Worker         base::Time::Now());
4648*6777b538SAndroid Build Coastguard Worker     port_450_domain_cookie->SetCreationDate(least_recent_time);
4649*6777b538SAndroid Build Coastguard Worker     starting_list_.push_back(std::move(port_450_domain_cookie));
4650*6777b538SAndroid Build Coastguard Worker 
4651*6777b538SAndroid Build Coastguard Worker     ASSERT_EQ(starting_list_.size(), 6UL);
4652*6777b538SAndroid Build Coastguard Worker   }
4653*6777b538SAndroid Build Coastguard Worker 
4654*6777b538SAndroid Build Coastguard Worker   scoped_refptr<net::MockPersistentCookieStore> store_;
4655*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<CookieMonster> cm_;
4656*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<CanonicalCookie>> starting_list_;
4657*6777b538SAndroid Build Coastguard Worker   base::test::ScopedFeatureList scoped_feature_list_;
4658*6777b538SAndroid Build Coastguard Worker };
4659*6777b538SAndroid Build Coastguard Worker 
4660*6777b538SAndroid Build Coastguard Worker // Scheme binding disabled.
4661*6777b538SAndroid Build Coastguard Worker // Port binding disabled.
4662*6777b538SAndroid Build Coastguard Worker // Only 2 cookies, the most recently created, should exist.
TEST_F(CookieMonsterTest_StoreLoadedCookies,NoSchemeNoPort)4663*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest_StoreLoadedCookies, NoSchemeNoPort) {
4664*6777b538SAndroid Build Coastguard Worker   scoped_feature_list_.InitWithFeatures(
4665*6777b538SAndroid Build Coastguard Worker       {}, {net::features::kEnableSchemeBoundCookies,
4666*6777b538SAndroid Build Coastguard Worker            net::features::kEnablePortBoundCookies});
4667*6777b538SAndroid Build Coastguard Worker   InitializeTest();
4668*6777b538SAndroid Build Coastguard Worker   cm_->StoreLoadedCookies(std::move(starting_list_));
4669*6777b538SAndroid Build Coastguard Worker   auto cookies = GetAllCookies(cm_.get());
4670*6777b538SAndroid Build Coastguard Worker 
4671*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cookies, testing::UnorderedElementsAre(
4672*6777b538SAndroid Build Coastguard Worker                            MatchesCookieNameValue("A", "basic"),
4673*6777b538SAndroid Build Coastguard Worker                            MatchesCookieNameValue("A", "basic_domain")));
4674*6777b538SAndroid Build Coastguard Worker }
4675*6777b538SAndroid Build Coastguard Worker 
4676*6777b538SAndroid Build Coastguard Worker // Scheme binding enabled.
4677*6777b538SAndroid Build Coastguard Worker // Port binding disabled.
4678*6777b538SAndroid Build Coastguard Worker // 4 Cookies should exist.
TEST_F(CookieMonsterTest_StoreLoadedCookies,YesSchemeNoPort)4679*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest_StoreLoadedCookies, YesSchemeNoPort) {
4680*6777b538SAndroid Build Coastguard Worker   scoped_feature_list_.InitWithFeatures(
4681*6777b538SAndroid Build Coastguard Worker       {net::features::kEnableSchemeBoundCookies},
4682*6777b538SAndroid Build Coastguard Worker       {net::features::kEnablePortBoundCookies});
4683*6777b538SAndroid Build Coastguard Worker   InitializeTest();
4684*6777b538SAndroid Build Coastguard Worker   cm_->StoreLoadedCookies(std::move(starting_list_));
4685*6777b538SAndroid Build Coastguard Worker   auto cookies = GetAllCookies(cm_.get());
4686*6777b538SAndroid Build Coastguard Worker 
4687*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cookies, testing::UnorderedElementsAre(
4688*6777b538SAndroid Build Coastguard Worker                            MatchesCookieNameValue("A", "basic"),
4689*6777b538SAndroid Build Coastguard Worker                            MatchesCookieNameValue("A", "http"),
4690*6777b538SAndroid Build Coastguard Worker                            MatchesCookieNameValue("A", "basic_domain"),
4691*6777b538SAndroid Build Coastguard Worker                            MatchesCookieNameValue("A", "http_domain")));
4692*6777b538SAndroid Build Coastguard Worker }
4693*6777b538SAndroid Build Coastguard Worker 
4694*6777b538SAndroid Build Coastguard Worker // Scheme binding disabled.
4695*6777b538SAndroid Build Coastguard Worker // Port binding enabled.
4696*6777b538SAndroid Build Coastguard Worker // 3 Cookies should exist.
TEST_F(CookieMonsterTest_StoreLoadedCookies,NoSchemeYesPort)4697*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest_StoreLoadedCookies, NoSchemeYesPort) {
4698*6777b538SAndroid Build Coastguard Worker   scoped_feature_list_.InitWithFeatures(
4699*6777b538SAndroid Build Coastguard Worker       {net::features::kEnablePortBoundCookies},
4700*6777b538SAndroid Build Coastguard Worker       {net::features::kEnableSchemeBoundCookies});
4701*6777b538SAndroid Build Coastguard Worker   InitializeTest();
4702*6777b538SAndroid Build Coastguard Worker   cm_->StoreLoadedCookies(std::move(starting_list_));
4703*6777b538SAndroid Build Coastguard Worker   auto cookies = GetAllCookies(cm_.get());
4704*6777b538SAndroid Build Coastguard Worker 
4705*6777b538SAndroid Build Coastguard Worker   // Domain cookies aren't bound to a port by design, so duplicates across ports
4706*6777b538SAndroid Build Coastguard Worker   // should still be removed. I.e.: "A=port450_domain"
4707*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cookies, testing::UnorderedElementsAre(
4708*6777b538SAndroid Build Coastguard Worker                            MatchesCookieNameValue("A", "basic"),
4709*6777b538SAndroid Build Coastguard Worker                            MatchesCookieNameValue("A", "port450"),
4710*6777b538SAndroid Build Coastguard Worker                            MatchesCookieNameValue("A", "basic_domain")));
4711*6777b538SAndroid Build Coastguard Worker }
4712*6777b538SAndroid Build Coastguard Worker 
4713*6777b538SAndroid Build Coastguard Worker // Scheme binding enabled.
4714*6777b538SAndroid Build Coastguard Worker // Port binding enabled.
4715*6777b538SAndroid Build Coastguard Worker // 5 Cookies should exist.
TEST_F(CookieMonsterTest_StoreLoadedCookies,YesSchemeYesPort)4716*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest_StoreLoadedCookies, YesSchemeYesPort) {
4717*6777b538SAndroid Build Coastguard Worker   scoped_feature_list_.InitWithFeatures(
4718*6777b538SAndroid Build Coastguard Worker       {net::features::kEnablePortBoundCookies,
4719*6777b538SAndroid Build Coastguard Worker        net::features::kEnableSchemeBoundCookies},
4720*6777b538SAndroid Build Coastguard Worker       {});
4721*6777b538SAndroid Build Coastguard Worker 
4722*6777b538SAndroid Build Coastguard Worker   InitializeTest();
4723*6777b538SAndroid Build Coastguard Worker   cm_->StoreLoadedCookies(std::move(starting_list_));
4724*6777b538SAndroid Build Coastguard Worker   auto cookies = GetAllCookies(cm_.get());
4725*6777b538SAndroid Build Coastguard Worker 
4726*6777b538SAndroid Build Coastguard Worker   // Domain cookies aren't bound to a port by design, so duplicates across ports
4727*6777b538SAndroid Build Coastguard Worker   // should still be removed. I.e.: "A=port450_domain"
4728*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cookies, testing::UnorderedElementsAre(
4729*6777b538SAndroid Build Coastguard Worker                            MatchesCookieNameValue("A", "basic"),
4730*6777b538SAndroid Build Coastguard Worker                            MatchesCookieNameValue("A", "http"),
4731*6777b538SAndroid Build Coastguard Worker                            MatchesCookieNameValue("A", "port450"),
4732*6777b538SAndroid Build Coastguard Worker                            MatchesCookieNameValue("A", "basic_domain"),
4733*6777b538SAndroid Build Coastguard Worker                            MatchesCookieNameValue("A", "http_domain")));
4734*6777b538SAndroid Build Coastguard Worker }
4735*6777b538SAndroid Build Coastguard Worker 
4736*6777b538SAndroid Build Coastguard Worker // Test skipping a cookie in MaybeDeleteEquivalentCookieAndUpdateStatus for
4737*6777b538SAndroid Build Coastguard Worker // multiple reasons (Secure and HttpOnly).
TEST_F(CookieMonsterTest,SkipDontOverwriteForMultipleReasons)4738*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, SkipDontOverwriteForMultipleReasons) {
4739*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
4740*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
4741*6777b538SAndroid Build Coastguard Worker 
4742*6777b538SAndroid Build Coastguard Worker   // Set a secure, httponly cookie from a secure origin
4743*6777b538SAndroid Build Coastguard Worker   auto preexisting_cookie = CanonicalCookie::CreateForTesting(
4744*6777b538SAndroid Build Coastguard Worker       https_www_foo_.url(), "A=B;Secure;HttpOnly", base::Time::Now());
4745*6777b538SAndroid Build Coastguard Worker   CookieAccessResult access_result = SetCanonicalCookieReturnAccessResult(
4746*6777b538SAndroid Build Coastguard Worker       cm.get(), std::move(preexisting_cookie), https_www_foo_.url(),
4747*6777b538SAndroid Build Coastguard Worker       true /* can_modify_httponly */);
4748*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(access_result.status.IsInclude());
4749*6777b538SAndroid Build Coastguard Worker 
4750*6777b538SAndroid Build Coastguard Worker   // Attempt to set a new cookie with the same name that is not Secure or
4751*6777b538SAndroid Build Coastguard Worker   // Httponly from an insecure scheme.
4752*6777b538SAndroid Build Coastguard Worker   auto cookie = CanonicalCookie::CreateForTesting(http_www_foo_.url(), "A=B",
4753*6777b538SAndroid Build Coastguard Worker                                                   base::Time::Now());
4754*6777b538SAndroid Build Coastguard Worker   access_result = SetCanonicalCookieReturnAccessResult(
4755*6777b538SAndroid Build Coastguard Worker       cm.get(), std::move(cookie), http_www_foo_.url(),
4756*6777b538SAndroid Build Coastguard Worker       false /* can_modify_httponly */);
4757*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(access_result.status.HasExactlyExclusionReasonsForTesting(
4758*6777b538SAndroid Build Coastguard Worker       {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE,
4759*6777b538SAndroid Build Coastguard Worker        CookieInclusionStatus::EXCLUDE_OVERWRITE_HTTP_ONLY}));
4760*6777b538SAndroid Build Coastguard Worker 
4761*6777b538SAndroid Build Coastguard Worker   auto entries = net_log_.GetEntries();
4762*6777b538SAndroid Build Coastguard Worker   ExpectLogContainsSomewhere(
4763*6777b538SAndroid Build Coastguard Worker       entries, 0, NetLogEventType::COOKIE_STORE_COOKIE_REJECTED_SECURE,
4764*6777b538SAndroid Build Coastguard Worker       NetLogEventPhase::NONE);
4765*6777b538SAndroid Build Coastguard Worker   ExpectLogContainsSomewhere(
4766*6777b538SAndroid Build Coastguard Worker       entries, 0, NetLogEventType::COOKIE_STORE_COOKIE_REJECTED_HTTPONLY,
4767*6777b538SAndroid Build Coastguard Worker       NetLogEventPhase::NONE);
4768*6777b538SAndroid Build Coastguard Worker }
4769*6777b538SAndroid Build Coastguard Worker 
4770*6777b538SAndroid Build Coastguard Worker // Test that when we check for equivalent cookies, we don't remove any if the
4771*6777b538SAndroid Build Coastguard Worker // cookie should not be set.
TEST_F(CookieMonsterTest,DontDeleteEquivalentCookieIfSetIsRejected)4772*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, DontDeleteEquivalentCookieIfSetIsRejected) {
4773*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
4774*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
4775*6777b538SAndroid Build Coastguard Worker 
4776*6777b538SAndroid Build Coastguard Worker   auto preexisting_cookie = CanonicalCookie::CreateForTesting(
4777*6777b538SAndroid Build Coastguard Worker       http_www_foo_.url(), "cookie=foo", base::Time::Now());
4778*6777b538SAndroid Build Coastguard Worker   CookieAccessResult access_result = SetCanonicalCookieReturnAccessResult(
4779*6777b538SAndroid Build Coastguard Worker       cm.get(), std::move(preexisting_cookie), http_www_foo_.url(),
4780*6777b538SAndroid Build Coastguard Worker       false /* can_modify_httponly */);
4781*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(access_result.status.IsInclude());
4782*6777b538SAndroid Build Coastguard Worker 
4783*6777b538SAndroid Build Coastguard Worker   auto bad_cookie = CanonicalCookie::CreateForTesting(
4784*6777b538SAndroid Build Coastguard Worker       http_www_foo_.url(), "cookie=bar;secure", base::Time::Now());
4785*6777b538SAndroid Build Coastguard Worker   CookieAccessResult access_result2 = SetCanonicalCookieReturnAccessResult(
4786*6777b538SAndroid Build Coastguard Worker       cm.get(), std::move(bad_cookie), http_www_foo_.url(),
4787*6777b538SAndroid Build Coastguard Worker       false /* can_modify_httponly */);
4788*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(access_result2.status.HasExactlyExclusionReasonsForTesting(
4789*6777b538SAndroid Build Coastguard Worker       {CookieInclusionStatus::EXCLUDE_SECURE_ONLY}));
4790*6777b538SAndroid Build Coastguard Worker 
4791*6777b538SAndroid Build Coastguard Worker   // Check that the original cookie is still there.
4792*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("cookie=foo", GetCookies(cm.get(), https_www_foo_.url()));
4793*6777b538SAndroid Build Coastguard Worker }
4794*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,SetSecureCookies)4795*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, SetSecureCookies) {
4796*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
4797*6777b538SAndroid Build Coastguard Worker 
4798*6777b538SAndroid Build Coastguard Worker   GURL http_url("http://www.foo.com");
4799*6777b538SAndroid Build Coastguard Worker   GURL http_superdomain_url("http://foo.com");
4800*6777b538SAndroid Build Coastguard Worker   GURL https_url("https://www.foo.com");
4801*6777b538SAndroid Build Coastguard Worker   GURL https_foo_url("https://www.foo.com/foo");
4802*6777b538SAndroid Build Coastguard Worker   GURL http_foo_url("http://www.foo.com/foo");
4803*6777b538SAndroid Build Coastguard Worker 
4804*6777b538SAndroid Build Coastguard Worker   // A non-secure cookie can be created from either a URL with a secure or
4805*6777b538SAndroid Build Coastguard Worker   // insecure scheme.
4806*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
4807*6777b538SAndroid Build Coastguard Worker       CreateAndSetCookieReturnStatus(cm.get(), http_url, "A=C;").IsInclude());
4808*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
4809*6777b538SAndroid Build Coastguard Worker       CreateAndSetCookieReturnStatus(cm.get(), https_url, "A=B;").IsInclude());
4810*6777b538SAndroid Build Coastguard Worker 
4811*6777b538SAndroid Build Coastguard Worker   // A secure cookie cannot be set from a URL with an insecure scheme.
4812*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), http_url, "A=B; Secure")
4813*6777b538SAndroid Build Coastguard Worker                   .HasExactlyExclusionReasonsForTesting(
4814*6777b538SAndroid Build Coastguard Worker                       {CookieInclusionStatus::EXCLUDE_SECURE_ONLY}));
4815*6777b538SAndroid Build Coastguard Worker 
4816*6777b538SAndroid Build Coastguard Worker   // A secure cookie can be set from a URL with a secure scheme.
4817*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), https_url, "A=B; Secure")
4818*6777b538SAndroid Build Coastguard Worker                   .IsInclude());
4819*6777b538SAndroid Build Coastguard Worker 
4820*6777b538SAndroid Build Coastguard Worker   // If a non-secure cookie is created from a URL with an insecure scheme, and a
4821*6777b538SAndroid Build Coastguard Worker   // secure cookie with the same name already exists, do not update the cookie.
4822*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), https_url, "A=B; Secure")
4823*6777b538SAndroid Build Coastguard Worker                   .IsInclude());
4824*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), http_url, "A=C;")
4825*6777b538SAndroid Build Coastguard Worker                   .HasExactlyExclusionReasonsForTesting(
4826*6777b538SAndroid Build Coastguard Worker                       {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
4827*6777b538SAndroid Build Coastguard Worker 
4828*6777b538SAndroid Build Coastguard Worker   // If a non-secure cookie is created from a URL with an secure scheme, and a
4829*6777b538SAndroid Build Coastguard Worker   // secure cookie with the same name already exists, update the cookie.
4830*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), https_url, "A=B; Secure")
4831*6777b538SAndroid Build Coastguard Worker                   .IsInclude());
4832*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
4833*6777b538SAndroid Build Coastguard Worker       CreateAndSetCookieReturnStatus(cm.get(), https_url, "A=C;").IsInclude());
4834*6777b538SAndroid Build Coastguard Worker 
4835*6777b538SAndroid Build Coastguard Worker   // If a non-secure cookie is created from a URL with an insecure scheme, and
4836*6777b538SAndroid Build Coastguard Worker   // a secure cookie with the same name already exists, do not update the cookie
4837*6777b538SAndroid Build Coastguard Worker   // if the new cookie's path matches the existing cookie's path.
4838*6777b538SAndroid Build Coastguard Worker   //
4839*6777b538SAndroid Build Coastguard Worker   // With an existing cookie whose path is '/', a cookie with the same name
4840*6777b538SAndroid Build Coastguard Worker   // cannot be set on the same domain, regardless of path:
4841*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), https_url, "A=B; Secure")
4842*6777b538SAndroid Build Coastguard Worker                   .IsInclude());
4843*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), http_url, "A=C; path=/")
4844*6777b538SAndroid Build Coastguard Worker                   .HasExactlyExclusionReasonsForTesting(
4845*6777b538SAndroid Build Coastguard Worker                       {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
4846*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
4847*6777b538SAndroid Build Coastguard Worker       CreateAndSetCookieReturnStatus(cm.get(), http_url, "A=C; path=/my/path")
4848*6777b538SAndroid Build Coastguard Worker           .HasExactlyExclusionReasonsForTesting(
4849*6777b538SAndroid Build Coastguard Worker               {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
4850*6777b538SAndroid Build Coastguard Worker 
4851*6777b538SAndroid Build Coastguard Worker   // But if the existing cookie has a path somewhere under the root, cookies
4852*6777b538SAndroid Build Coastguard Worker   // with the same name may be set for paths which don't overlap the existing
4853*6777b538SAndroid Build Coastguard Worker   // cookie.
4854*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
4855*6777b538SAndroid Build Coastguard Worker       SetCookie(cm.get(), https_url, "WITH_PATH=B; Secure; path=/my/path"));
4856*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), http_url, "WITH_PATH=C")
4857*6777b538SAndroid Build Coastguard Worker                   .IsInclude());
4858*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
4859*6777b538SAndroid Build Coastguard Worker       CreateAndSetCookieReturnStatus(cm.get(), http_url, "WITH_PATH=C; path=/")
4860*6777b538SAndroid Build Coastguard Worker           .IsInclude());
4861*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), http_url,
4862*6777b538SAndroid Build Coastguard Worker                                              "WITH_PATH=C; path=/your/path")
4863*6777b538SAndroid Build Coastguard Worker                   .IsInclude());
4864*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), http_url,
4865*6777b538SAndroid Build Coastguard Worker                                              "WITH_PATH=C; path=/my/path")
4866*6777b538SAndroid Build Coastguard Worker                   .HasExactlyExclusionReasonsForTesting(
4867*6777b538SAndroid Build Coastguard Worker                       {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
4868*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), http_url,
4869*6777b538SAndroid Build Coastguard Worker                                              "WITH_PATH=C; path=/my/path/sub")
4870*6777b538SAndroid Build Coastguard Worker                   .HasExactlyExclusionReasonsForTesting(
4871*6777b538SAndroid Build Coastguard Worker                       {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
4872*6777b538SAndroid Build Coastguard Worker 
4873*6777b538SAndroid Build Coastguard Worker   DeleteAll(cm.get());
4874*6777b538SAndroid Build Coastguard Worker 
4875*6777b538SAndroid Build Coastguard Worker   // If a secure cookie is set on top of an existing insecure cookie but with a
4876*6777b538SAndroid Build Coastguard Worker   // different path, both are retained.
4877*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
4878*6777b538SAndroid Build Coastguard Worker       CreateAndSetCookieReturnStatus(cm.get(), http_url, "A=B; path=/foo")
4879*6777b538SAndroid Build Coastguard Worker           .IsInclude());
4880*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
4881*6777b538SAndroid Build Coastguard Worker       CreateAndSetCookieReturnStatus(cm.get(), https_url, "A=C; Secure; path=/")
4882*6777b538SAndroid Build Coastguard Worker           .IsInclude());
4883*6777b538SAndroid Build Coastguard Worker 
4884*6777b538SAndroid Build Coastguard Worker   // Querying from an insecure url gets only the insecure cookie, but querying
4885*6777b538SAndroid Build Coastguard Worker   // from a secure url returns both.
4886*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("A=B", GetCookies(cm.get(), http_foo_url));
4887*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(GetCookies(cm.get(), https_foo_url), testing::HasSubstr("A=B"));
4888*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(GetCookies(cm.get(), https_foo_url), testing::HasSubstr("A=C"));
4889*6777b538SAndroid Build Coastguard Worker 
4890*6777b538SAndroid Build Coastguard Worker   // Attempting to set an insecure cookie (from an insecure scheme) that domain-
4891*6777b538SAndroid Build Coastguard Worker   // matches and path-matches the secure cookie fails i.e. the secure cookie is
4892*6777b538SAndroid Build Coastguard Worker   // left alone...
4893*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
4894*6777b538SAndroid Build Coastguard Worker       CreateAndSetCookieReturnStatus(cm.get(), http_url, "A=D; path=/foo")
4895*6777b538SAndroid Build Coastguard Worker           .HasExactlyExclusionReasonsForTesting(
4896*6777b538SAndroid Build Coastguard Worker               {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
4897*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), http_url, "A=D; path=/")
4898*6777b538SAndroid Build Coastguard Worker                   .HasExactlyExclusionReasonsForTesting(
4899*6777b538SAndroid Build Coastguard Worker                       {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
4900*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(GetCookies(cm.get(), https_foo_url), testing::HasSubstr("A=C"));
4901*6777b538SAndroid Build Coastguard Worker 
4902*6777b538SAndroid Build Coastguard Worker   // ...but the original insecure cookie is still retained.
4903*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(GetCookies(cm.get(), https_foo_url), testing::HasSubstr("A=B"));
4904*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(GetCookies(cm.get(), https_foo_url),
4905*6777b538SAndroid Build Coastguard Worker               testing::Not(testing::HasSubstr("A=D")));
4906*6777b538SAndroid Build Coastguard Worker 
4907*6777b538SAndroid Build Coastguard Worker   // Deleting the secure cookie leaves only the original insecure cookie.
4908*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookieReturnStatus(
4909*6777b538SAndroid Build Coastguard Worker                   cm.get(), https_url,
4910*6777b538SAndroid Build Coastguard Worker                   "A=C; path=/; Expires=Thu, 01-Jan-1970 00:00:01 GMT")
4911*6777b538SAndroid Build Coastguard Worker                   .IsInclude());
4912*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("A=B", GetCookies(cm.get(), https_foo_url));
4913*6777b538SAndroid Build Coastguard Worker 
4914*6777b538SAndroid Build Coastguard Worker   // If a non-secure cookie is created from a URL with an insecure scheme, and
4915*6777b538SAndroid Build Coastguard Worker   // a secure cookie with the same name already exists, if the domain strings
4916*6777b538SAndroid Build Coastguard Worker   // domain-match, do not update the cookie.
4917*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), https_url, "A=B; Secure")
4918*6777b538SAndroid Build Coastguard Worker                   .IsInclude());
4919*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
4920*6777b538SAndroid Build Coastguard Worker       CreateAndSetCookieReturnStatus(cm.get(), http_url, "A=C; domain=foo.com")
4921*6777b538SAndroid Build Coastguard Worker           .HasExactlyExclusionReasonsForTesting(
4922*6777b538SAndroid Build Coastguard Worker               {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
4923*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), http_url,
4924*6777b538SAndroid Build Coastguard Worker                                              "A=C; domain=www.foo.com")
4925*6777b538SAndroid Build Coastguard Worker                   .HasExactlyExclusionReasonsForTesting(
4926*6777b538SAndroid Build Coastguard Worker                       {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
4927*6777b538SAndroid Build Coastguard Worker 
4928*6777b538SAndroid Build Coastguard Worker   // Since A=B was set above with no domain string, set a different cookie here
4929*6777b538SAndroid Build Coastguard Worker   // so the insecure examples aren't trying to overwrite the one above.
4930*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), https_url,
4931*6777b538SAndroid Build Coastguard Worker                                              "B=C; Secure; domain=foo.com")
4932*6777b538SAndroid Build Coastguard Worker                   .IsInclude());
4933*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
4934*6777b538SAndroid Build Coastguard Worker       CreateAndSetCookieReturnStatus(cm.get(), http_url, "B=D; domain=foo.com")
4935*6777b538SAndroid Build Coastguard Worker           .HasExactlyExclusionReasonsForTesting(
4936*6777b538SAndroid Build Coastguard Worker               {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
4937*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), http_url, "B=D")
4938*6777b538SAndroid Build Coastguard Worker                   .HasExactlyExclusionReasonsForTesting(
4939*6777b538SAndroid Build Coastguard Worker                       {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
4940*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
4941*6777b538SAndroid Build Coastguard Worker       CreateAndSetCookieReturnStatus(cm.get(), http_superdomain_url, "B=D")
4942*6777b538SAndroid Build Coastguard Worker           .HasExactlyExclusionReasonsForTesting(
4943*6777b538SAndroid Build Coastguard Worker               {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
4944*6777b538SAndroid Build Coastguard Worker 
4945*6777b538SAndroid Build Coastguard Worker   // Verify that if an httponly version of the cookie exists, adding a Secure
4946*6777b538SAndroid Build Coastguard Worker   // version of the cookie still does not overwrite it.
4947*6777b538SAndroid Build Coastguard Worker   CookieOptions include_httponly = CookieOptions::MakeAllInclusive();
4948*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookie(cm.get(), https_url, "C=D; httponly",
4949*6777b538SAndroid Build Coastguard Worker                                  include_httponly));
4950*6777b538SAndroid Build Coastguard Worker   // Note that the lack of an explicit options object below uses the default,
4951*6777b538SAndroid Build Coastguard Worker   // which in this case includes "exclude_httponly = true".
4952*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), https_url, "C=E; Secure")
4953*6777b538SAndroid Build Coastguard Worker                   .HasExactlyExclusionReasonsForTesting(
4954*6777b538SAndroid Build Coastguard Worker                       {CookieInclusionStatus::EXCLUDE_OVERWRITE_HTTP_ONLY}));
4955*6777b538SAndroid Build Coastguard Worker 
4956*6777b538SAndroid Build Coastguard Worker   auto entries = net_log_.GetEntries();
4957*6777b538SAndroid Build Coastguard Worker   ExpectLogContainsSomewhere(
4958*6777b538SAndroid Build Coastguard Worker       entries, 0, NetLogEventType::COOKIE_STORE_COOKIE_REJECTED_HTTPONLY,
4959*6777b538SAndroid Build Coastguard Worker       NetLogEventPhase::NONE);
4960*6777b538SAndroid Build Coastguard Worker }
4961*6777b538SAndroid Build Coastguard Worker 
4962*6777b538SAndroid Build Coastguard Worker // Tests the behavior of "Leave Secure Cookies Alone" in
4963*6777b538SAndroid Build Coastguard Worker // MaybeDeleteEquivalentCookieAndUpdateStatus().
4964*6777b538SAndroid Build Coastguard Worker // Check domain-match criterion: If either cookie domain matches the other,
4965*6777b538SAndroid Build Coastguard Worker // don't set the insecure cookie.
TEST_F(CookieMonsterTest,LeaveSecureCookiesAlone_DomainMatch)4966*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, LeaveSecureCookiesAlone_DomainMatch) {
4967*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
4968*6777b538SAndroid Build Coastguard Worker 
4969*6777b538SAndroid Build Coastguard Worker   // These domains will domain-match each other.
4970*6777b538SAndroid Build Coastguard Worker   const char* kRegistrableDomain = "foo.com";
4971*6777b538SAndroid Build Coastguard Worker   const char* kSuperdomain = "a.foo.com";
4972*6777b538SAndroid Build Coastguard Worker   const char* kDomain = "b.a.foo.com";
4973*6777b538SAndroid Build Coastguard Worker   const char* kSubdomain = "c.b.a.foo.com";
4974*6777b538SAndroid Build Coastguard Worker   // This domain does not match any, aside from the registrable domain.
4975*6777b538SAndroid Build Coastguard Worker   const char* kAnotherDomain = "z.foo.com";
4976*6777b538SAndroid Build Coastguard Worker 
4977*6777b538SAndroid Build Coastguard Worker   for (const char* preexisting_cookie_host :
4978*6777b538SAndroid Build Coastguard Worker        {kRegistrableDomain, kSuperdomain, kDomain, kSubdomain}) {
4979*6777b538SAndroid Build Coastguard Worker     GURL preexisting_cookie_url(
4980*6777b538SAndroid Build Coastguard Worker         base::StrCat({url::kHttpsScheme, url::kStandardSchemeSeparator,
4981*6777b538SAndroid Build Coastguard Worker                       preexisting_cookie_host}));
4982*6777b538SAndroid Build Coastguard Worker     for (const char* new_cookie_host :
4983*6777b538SAndroid Build Coastguard Worker          {kRegistrableDomain, kSuperdomain, kDomain, kSubdomain}) {
4984*6777b538SAndroid Build Coastguard Worker       GURL https_url(base::StrCat(
4985*6777b538SAndroid Build Coastguard Worker           {url::kHttpsScheme, url::kStandardSchemeSeparator, new_cookie_host}));
4986*6777b538SAndroid Build Coastguard Worker       GURL http_url(base::StrCat(
4987*6777b538SAndroid Build Coastguard Worker           {url::kHttpScheme, url::kStandardSchemeSeparator, new_cookie_host}));
4988*6777b538SAndroid Build Coastguard Worker 
4989*6777b538SAndroid Build Coastguard Worker       // Preexisting Secure host and domain cookies.
4990*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(CreateAndSetCookieReturnStatus(
4991*6777b538SAndroid Build Coastguard Worker                       cm.get(), preexisting_cookie_url, "A=0; Secure")
4992*6777b538SAndroid Build Coastguard Worker                       .IsInclude());
4993*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(
4994*6777b538SAndroid Build Coastguard Worker           CreateAndSetCookieReturnStatus(
4995*6777b538SAndroid Build Coastguard Worker               cm.get(), preexisting_cookie_url,
4996*6777b538SAndroid Build Coastguard Worker               base::StrCat({"B=0; Secure; Domain=", preexisting_cookie_host}))
4997*6777b538SAndroid Build Coastguard Worker               .IsInclude());
4998*6777b538SAndroid Build Coastguard Worker 
4999*6777b538SAndroid Build Coastguard Worker       // Don't set insecure cookie from an insecure URL if equivalent secure
5000*6777b538SAndroid Build Coastguard Worker       // cookie exists.
5001*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), http_url, "A=1")
5002*6777b538SAndroid Build Coastguard Worker                       .HasExactlyExclusionReasonsForTesting(
5003*6777b538SAndroid Build Coastguard Worker                           {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}))
5004*6777b538SAndroid Build Coastguard Worker           << "Insecure host cookie from " << http_url
5005*6777b538SAndroid Build Coastguard Worker           << " should not be set if equivalent secure host cookie from "
5006*6777b538SAndroid Build Coastguard Worker           << preexisting_cookie_url << " exists.";
5007*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(CreateAndSetCookieReturnStatus(
5008*6777b538SAndroid Build Coastguard Worker                       cm.get(), http_url,
5009*6777b538SAndroid Build Coastguard Worker                       base::StrCat({"A=2; Domain=", new_cookie_host}))
5010*6777b538SAndroid Build Coastguard Worker                       .HasExactlyExclusionReasonsForTesting(
5011*6777b538SAndroid Build Coastguard Worker                           {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}))
5012*6777b538SAndroid Build Coastguard Worker           << "Insecure domain cookie from " << http_url
5013*6777b538SAndroid Build Coastguard Worker           << " should not be set if equivalent secure host cookie from "
5014*6777b538SAndroid Build Coastguard Worker           << preexisting_cookie_url << " exists.";
5015*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), http_url, "B=1")
5016*6777b538SAndroid Build Coastguard Worker                       .HasExactlyExclusionReasonsForTesting(
5017*6777b538SAndroid Build Coastguard Worker                           {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}))
5018*6777b538SAndroid Build Coastguard Worker           << "Insecure host cookie from " << http_url
5019*6777b538SAndroid Build Coastguard Worker           << " should not be set if equivalent secure domain cookie from "
5020*6777b538SAndroid Build Coastguard Worker           << preexisting_cookie_url << " exists.";
5021*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(CreateAndSetCookieReturnStatus(
5022*6777b538SAndroid Build Coastguard Worker                       cm.get(), http_url,
5023*6777b538SAndroid Build Coastguard Worker                       base::StrCat({"B=2; Domain=", new_cookie_host}))
5024*6777b538SAndroid Build Coastguard Worker                       .HasExactlyExclusionReasonsForTesting(
5025*6777b538SAndroid Build Coastguard Worker                           {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}))
5026*6777b538SAndroid Build Coastguard Worker           << "Insecure domain cookie from " << http_url
5027*6777b538SAndroid Build Coastguard Worker           << " should not be set if equivalent secure domain cookie from "
5028*6777b538SAndroid Build Coastguard Worker           << preexisting_cookie_url << " exists.";
5029*6777b538SAndroid Build Coastguard Worker 
5030*6777b538SAndroid Build Coastguard Worker       // Allow setting insecure cookie from a secure URL even if equivalent
5031*6777b538SAndroid Build Coastguard Worker       // secure cookie exists.
5032*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), https_url, "A=3;")
5033*6777b538SAndroid Build Coastguard Worker                       .IsInclude())
5034*6777b538SAndroid Build Coastguard Worker           << "Insecure host cookie from " << https_url
5035*6777b538SAndroid Build Coastguard Worker           << " can be set even if equivalent secure host cookie from "
5036*6777b538SAndroid Build Coastguard Worker           << preexisting_cookie_url << " exists.";
5037*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(CreateAndSetCookieReturnStatus(
5038*6777b538SAndroid Build Coastguard Worker                       cm.get(), https_url,
5039*6777b538SAndroid Build Coastguard Worker                       base::StrCat({"A=4; Domain=", new_cookie_host}))
5040*6777b538SAndroid Build Coastguard Worker                       .IsInclude())
5041*6777b538SAndroid Build Coastguard Worker           << "Insecure domain cookie from " << https_url
5042*6777b538SAndroid Build Coastguard Worker           << " can be set even if equivalent secure host cookie from "
5043*6777b538SAndroid Build Coastguard Worker           << preexisting_cookie_url << " exists.";
5044*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), https_url, "B=3;")
5045*6777b538SAndroid Build Coastguard Worker                       .IsInclude())
5046*6777b538SAndroid Build Coastguard Worker           << "Insecure host cookie from " << https_url
5047*6777b538SAndroid Build Coastguard Worker           << " can be set even if equivalent secure domain cookie from "
5048*6777b538SAndroid Build Coastguard Worker           << preexisting_cookie_url << " exists.";
5049*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(CreateAndSetCookieReturnStatus(
5050*6777b538SAndroid Build Coastguard Worker                       cm.get(), https_url,
5051*6777b538SAndroid Build Coastguard Worker                       base::StrCat({"B=4; Domain=", new_cookie_host}))
5052*6777b538SAndroid Build Coastguard Worker                       .IsInclude())
5053*6777b538SAndroid Build Coastguard Worker           << "Insecure domain cookie from " << https_url
5054*6777b538SAndroid Build Coastguard Worker           << " can be set even if equivalent secure domain cookie from "
5055*6777b538SAndroid Build Coastguard Worker           << preexisting_cookie_url << " exists.";
5056*6777b538SAndroid Build Coastguard Worker 
5057*6777b538SAndroid Build Coastguard Worker       DeleteAll(cm.get());
5058*6777b538SAndroid Build Coastguard Worker     }
5059*6777b538SAndroid Build Coastguard Worker   }
5060*6777b538SAndroid Build Coastguard Worker 
5061*6777b538SAndroid Build Coastguard Worker   // Test non-domain-matching case. These sets should all be allowed because the
5062*6777b538SAndroid Build Coastguard Worker   // cookie is not equivalent.
5063*6777b538SAndroid Build Coastguard Worker   GURL nonmatching_https_url(base::StrCat(
5064*6777b538SAndroid Build Coastguard Worker       {url::kHttpsScheme, url::kStandardSchemeSeparator, kAnotherDomain}));
5065*6777b538SAndroid Build Coastguard Worker 
5066*6777b538SAndroid Build Coastguard Worker   for (const char* host : {kSuperdomain, kDomain, kSubdomain}) {
5067*6777b538SAndroid Build Coastguard Worker     GURL https_url(
5068*6777b538SAndroid Build Coastguard Worker         base::StrCat({url::kHttpsScheme, url::kStandardSchemeSeparator, host}));
5069*6777b538SAndroid Build Coastguard Worker     GURL http_url(
5070*6777b538SAndroid Build Coastguard Worker         base::StrCat({url::kHttpScheme, url::kStandardSchemeSeparator, host}));
5071*6777b538SAndroid Build Coastguard Worker 
5072*6777b538SAndroid Build Coastguard Worker     // Preexisting Secure host and domain cookies.
5073*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), nonmatching_https_url,
5074*6777b538SAndroid Build Coastguard Worker                                                "A=0; Secure")
5075*6777b538SAndroid Build Coastguard Worker                     .IsInclude());
5076*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(CreateAndSetCookieReturnStatus(
5077*6777b538SAndroid Build Coastguard Worker                     cm.get(), nonmatching_https_url,
5078*6777b538SAndroid Build Coastguard Worker                     base::StrCat({"B=0; Secure; Domain=", kAnotherDomain}))
5079*6777b538SAndroid Build Coastguard Worker                     .IsInclude());
5080*6777b538SAndroid Build Coastguard Worker 
5081*6777b538SAndroid Build Coastguard Worker     // New cookie from insecure URL is set.
5082*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(
5083*6777b538SAndroid Build Coastguard Worker         CreateAndSetCookieReturnStatus(cm.get(), http_url, "A=1;").IsInclude())
5084*6777b538SAndroid Build Coastguard Worker         << "Insecure host cookie from " << http_url
5085*6777b538SAndroid Build Coastguard Worker         << " can be set even if equivalent secure host cookie from "
5086*6777b538SAndroid Build Coastguard Worker         << nonmatching_https_url << " exists.";
5087*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(CreateAndSetCookieReturnStatus(
5088*6777b538SAndroid Build Coastguard Worker                     cm.get(), http_url, base::StrCat({"A=2; Domain=", host}))
5089*6777b538SAndroid Build Coastguard Worker                     .IsInclude())
5090*6777b538SAndroid Build Coastguard Worker         << "Insecure domain cookie from " << http_url
5091*6777b538SAndroid Build Coastguard Worker         << " can be set even if equivalent secure host cookie from "
5092*6777b538SAndroid Build Coastguard Worker         << nonmatching_https_url << " exists.";
5093*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(
5094*6777b538SAndroid Build Coastguard Worker         CreateAndSetCookieReturnStatus(cm.get(), http_url, "B=1;").IsInclude())
5095*6777b538SAndroid Build Coastguard Worker         << "Insecure host cookie from " << http_url
5096*6777b538SAndroid Build Coastguard Worker         << " can be set even if equivalent secure domain cookie from "
5097*6777b538SAndroid Build Coastguard Worker         << nonmatching_https_url << " exists.";
5098*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(CreateAndSetCookieReturnStatus(
5099*6777b538SAndroid Build Coastguard Worker                     cm.get(), http_url, base::StrCat({"B=2; Domain=", host}))
5100*6777b538SAndroid Build Coastguard Worker                     .IsInclude())
5101*6777b538SAndroid Build Coastguard Worker         << "Insecure domain cookie from " << http_url
5102*6777b538SAndroid Build Coastguard Worker         << " can be set even if equivalent secure domain cookie from "
5103*6777b538SAndroid Build Coastguard Worker         << nonmatching_https_url << " exists.";
5104*6777b538SAndroid Build Coastguard Worker 
5105*6777b538SAndroid Build Coastguard Worker     // New cookie from secure URL is set.
5106*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(
5107*6777b538SAndroid Build Coastguard Worker         CreateAndSetCookieReturnStatus(cm.get(), https_url, "A=3;").IsInclude())
5108*6777b538SAndroid Build Coastguard Worker         << "Insecure host cookie from " << https_url
5109*6777b538SAndroid Build Coastguard Worker         << " can be set even if equivalent secure host cookie from "
5110*6777b538SAndroid Build Coastguard Worker         << nonmatching_https_url << " exists.";
5111*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(CreateAndSetCookieReturnStatus(
5112*6777b538SAndroid Build Coastguard Worker                     cm.get(), https_url, base::StrCat({"A=4; Domain=", host}))
5113*6777b538SAndroid Build Coastguard Worker                     .IsInclude())
5114*6777b538SAndroid Build Coastguard Worker         << "Insecure domain cookie from " << https_url
5115*6777b538SAndroid Build Coastguard Worker         << " can be set even if equivalent secure host cookie from "
5116*6777b538SAndroid Build Coastguard Worker         << nonmatching_https_url << " exists.";
5117*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(
5118*6777b538SAndroid Build Coastguard Worker         CreateAndSetCookieReturnStatus(cm.get(), https_url, "B=3;").IsInclude())
5119*6777b538SAndroid Build Coastguard Worker         << "Insecure host cookie from " << https_url
5120*6777b538SAndroid Build Coastguard Worker         << " can be set even if equivalent secure host cookie from "
5121*6777b538SAndroid Build Coastguard Worker         << nonmatching_https_url << " exists.";
5122*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(CreateAndSetCookieReturnStatus(
5123*6777b538SAndroid Build Coastguard Worker                     cm.get(), https_url, base::StrCat({"B=4; Domain=", host}))
5124*6777b538SAndroid Build Coastguard Worker                     .IsInclude())
5125*6777b538SAndroid Build Coastguard Worker         << "Insecure domain cookie from " << https_url
5126*6777b538SAndroid Build Coastguard Worker         << " can be set even if equivalent secure host cookie from "
5127*6777b538SAndroid Build Coastguard Worker         << nonmatching_https_url << " exists.";
5128*6777b538SAndroid Build Coastguard Worker 
5129*6777b538SAndroid Build Coastguard Worker     DeleteAll(cm.get());
5130*6777b538SAndroid Build Coastguard Worker   }
5131*6777b538SAndroid Build Coastguard Worker }
5132*6777b538SAndroid Build Coastguard Worker 
5133*6777b538SAndroid Build Coastguard Worker // Tests the behavior of "Leave Secure Cookies Alone" in
5134*6777b538SAndroid Build Coastguard Worker // MaybeDeleteEquivalentCookieAndUpdateStatus().
5135*6777b538SAndroid Build Coastguard Worker // Check path-match criterion: If the new cookie is for the same path or a
5136*6777b538SAndroid Build Coastguard Worker // subdirectory of the preexisting cookie's path, don't set the new cookie.
TEST_F(CookieMonsterTest,LeaveSecureCookiesAlone_PathMatch)5137*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, LeaveSecureCookiesAlone_PathMatch) {
5138*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, net::NetLog::Get());
5139*6777b538SAndroid Build Coastguard Worker 
5140*6777b538SAndroid Build Coastguard Worker   // A path that is later in this list will path-match all the paths before it.
5141*6777b538SAndroid Build Coastguard Worker   const char* kPaths[] = {"/", "/1", "/1/2", "/1/2/3"};
5142*6777b538SAndroid Build Coastguard Worker   // This path does not match any, aside from the root path.
5143*6777b538SAndroid Build Coastguard Worker   const char* kOtherDirectory = "/9";
5144*6777b538SAndroid Build Coastguard Worker 
5145*6777b538SAndroid Build Coastguard Worker   for (int preexisting_cookie_path_index = 0; preexisting_cookie_path_index < 4;
5146*6777b538SAndroid Build Coastguard Worker        ++preexisting_cookie_path_index) {
5147*6777b538SAndroid Build Coastguard Worker     const char* preexisting_cookie_path = kPaths[preexisting_cookie_path_index];
5148*6777b538SAndroid Build Coastguard Worker     GURL preexisting_cookie_url(
5149*6777b538SAndroid Build Coastguard Worker         base::StrCat({url::kHttpsScheme, url::kStandardSchemeSeparator,
5150*6777b538SAndroid Build Coastguard Worker                       "a.foo.com", preexisting_cookie_path}));
5151*6777b538SAndroid Build Coastguard Worker     for (int new_cookie_path_index = 0; new_cookie_path_index < 4;
5152*6777b538SAndroid Build Coastguard Worker          ++new_cookie_path_index) {
5153*6777b538SAndroid Build Coastguard Worker       const char* new_cookie_path = kPaths[new_cookie_path_index];
5154*6777b538SAndroid Build Coastguard Worker       bool should_path_match =
5155*6777b538SAndroid Build Coastguard Worker           new_cookie_path_index >= preexisting_cookie_path_index;
5156*6777b538SAndroid Build Coastguard Worker       GURL https_url(
5157*6777b538SAndroid Build Coastguard Worker           base::StrCat({url::kHttpsScheme, url::kStandardSchemeSeparator,
5158*6777b538SAndroid Build Coastguard Worker                         "a.foo.com", new_cookie_path}));
5159*6777b538SAndroid Build Coastguard Worker       GURL http_url(
5160*6777b538SAndroid Build Coastguard Worker           base::StrCat({url::kHttpScheme, url::kStandardSchemeSeparator,
5161*6777b538SAndroid Build Coastguard Worker                         "a.foo.com", new_cookie_path}));
5162*6777b538SAndroid Build Coastguard Worker 
5163*6777b538SAndroid Build Coastguard Worker       // Preexisting Secure cookie.
5164*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(
5165*6777b538SAndroid Build Coastguard Worker           CreateAndSetCookieReturnStatus(
5166*6777b538SAndroid Build Coastguard Worker               cm.get(), preexisting_cookie_url,
5167*6777b538SAndroid Build Coastguard Worker               base::StrCat({"A=0; Secure; Path=", preexisting_cookie_path}))
5168*6777b538SAndroid Build Coastguard Worker               .IsInclude());
5169*6777b538SAndroid Build Coastguard Worker 
5170*6777b538SAndroid Build Coastguard Worker       // Don't set insecure cookie from an insecure URL if equivalent secure
5171*6777b538SAndroid Build Coastguard Worker       // cookie exists.
5172*6777b538SAndroid Build Coastguard Worker       CookieInclusionStatus set = CreateAndSetCookieReturnStatus(
5173*6777b538SAndroid Build Coastguard Worker           cm.get(), http_url, base::StrCat({"A=1; Path=", new_cookie_path}));
5174*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(should_path_match
5175*6777b538SAndroid Build Coastguard Worker                       ? set.HasExactlyExclusionReasonsForTesting(
5176*6777b538SAndroid Build Coastguard Worker                             {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE})
5177*6777b538SAndroid Build Coastguard Worker                       : set.IsInclude())
5178*6777b538SAndroid Build Coastguard Worker           << "Insecure cookie from " << http_url << " should "
5179*6777b538SAndroid Build Coastguard Worker           << (should_path_match ? "not " : "")
5180*6777b538SAndroid Build Coastguard Worker           << "be set if equivalent secure cookie from "
5181*6777b538SAndroid Build Coastguard Worker           << preexisting_cookie_url << " exists.";
5182*6777b538SAndroid Build Coastguard Worker 
5183*6777b538SAndroid Build Coastguard Worker       // Allow setting insecure cookie from a secure URL even if equivalent
5184*6777b538SAndroid Build Coastguard Worker       // secure cookie exists.
5185*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(CreateAndSetCookieReturnStatus(
5186*6777b538SAndroid Build Coastguard Worker                       cm.get(), https_url,
5187*6777b538SAndroid Build Coastguard Worker                       base::StrCat({"A=2; Path=", new_cookie_path}))
5188*6777b538SAndroid Build Coastguard Worker                       .IsInclude())
5189*6777b538SAndroid Build Coastguard Worker           << "Insecure cookie from " << http_url
5190*6777b538SAndroid Build Coastguard Worker           << " can be set even if equivalent secure cookie from "
5191*6777b538SAndroid Build Coastguard Worker           << preexisting_cookie_url << " exists.";
5192*6777b538SAndroid Build Coastguard Worker 
5193*6777b538SAndroid Build Coastguard Worker       DeleteAll(cm.get());
5194*6777b538SAndroid Build Coastguard Worker     }
5195*6777b538SAndroid Build Coastguard Worker   }
5196*6777b538SAndroid Build Coastguard Worker 
5197*6777b538SAndroid Build Coastguard Worker   // Test non-matching-path case. These sets should all be allowed because the
5198*6777b538SAndroid Build Coastguard Worker   // cookie is not equivalent.
5199*6777b538SAndroid Build Coastguard Worker   GURL nonmatching_https_url(
5200*6777b538SAndroid Build Coastguard Worker       base::StrCat({url::kHttpsScheme, url::kStandardSchemeSeparator,
5201*6777b538SAndroid Build Coastguard Worker                     "a.foo.com", kOtherDirectory}));
5202*6777b538SAndroid Build Coastguard Worker 
5203*6777b538SAndroid Build Coastguard Worker   for (int new_cookie_path_index = 1; new_cookie_path_index < 4;
5204*6777b538SAndroid Build Coastguard Worker        ++new_cookie_path_index) {
5205*6777b538SAndroid Build Coastguard Worker     const char* new_cookie_path = kPaths[new_cookie_path_index];
5206*6777b538SAndroid Build Coastguard Worker     GURL https_url(base::StrCat(
5207*6777b538SAndroid Build Coastguard Worker         {url::kHttpsScheme, url::kStandardSchemeSeparator, new_cookie_path}));
5208*6777b538SAndroid Build Coastguard Worker     GURL http_url(base::StrCat(
5209*6777b538SAndroid Build Coastguard Worker         {url::kHttpScheme, url::kStandardSchemeSeparator, new_cookie_path}));
5210*6777b538SAndroid Build Coastguard Worker 
5211*6777b538SAndroid Build Coastguard Worker     // Preexisting Secure cookie.
5212*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(CreateAndSetCookieReturnStatus(
5213*6777b538SAndroid Build Coastguard Worker                     cm.get(), nonmatching_https_url,
5214*6777b538SAndroid Build Coastguard Worker                     base::StrCat({"A=0; Secure; Path=", kOtherDirectory}))
5215*6777b538SAndroid Build Coastguard Worker                     .IsInclude());
5216*6777b538SAndroid Build Coastguard Worker 
5217*6777b538SAndroid Build Coastguard Worker     // New cookie from insecure URL is set.
5218*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(
5219*6777b538SAndroid Build Coastguard Worker         CreateAndSetCookieReturnStatus(
5220*6777b538SAndroid Build Coastguard Worker             cm.get(), http_url, base::StrCat({"A=1; Path=", new_cookie_path}))
5221*6777b538SAndroid Build Coastguard Worker             .IsInclude())
5222*6777b538SAndroid Build Coastguard Worker         << "Insecure cookie from " << http_url
5223*6777b538SAndroid Build Coastguard Worker         << " can be set even if equivalent secure cookie from "
5224*6777b538SAndroid Build Coastguard Worker         << nonmatching_https_url << " exists.";
5225*6777b538SAndroid Build Coastguard Worker 
5226*6777b538SAndroid Build Coastguard Worker     // New cookie from secure URL is set.
5227*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(
5228*6777b538SAndroid Build Coastguard Worker         CreateAndSetCookieReturnStatus(
5229*6777b538SAndroid Build Coastguard Worker             cm.get(), https_url, base::StrCat({"A=1; Path=", new_cookie_path}))
5230*6777b538SAndroid Build Coastguard Worker             .IsInclude())
5231*6777b538SAndroid Build Coastguard Worker         << "Insecure cookie from " << https_url
5232*6777b538SAndroid Build Coastguard Worker         << " can be set even if equivalent secure cookie from "
5233*6777b538SAndroid Build Coastguard Worker         << nonmatching_https_url << " exists.";
5234*6777b538SAndroid Build Coastguard Worker   }
5235*6777b538SAndroid Build Coastguard Worker }
5236*6777b538SAndroid Build Coastguard Worker 
5237*6777b538SAndroid Build Coastguard Worker // Tests for behavior for strict secure cookies.
TEST_F(CookieMonsterTest,EvictSecureCookies)5238*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, EvictSecureCookies) {
5239*6777b538SAndroid Build Coastguard Worker   // Hard-coding limits in the test, but use DCHECK_EQ to enforce constraint.
5240*6777b538SAndroid Build Coastguard Worker   DCHECK_EQ(180U, CookieMonster::kDomainMaxCookies);
5241*6777b538SAndroid Build Coastguard Worker   DCHECK_EQ(150U, CookieMonster::kDomainMaxCookies -
5242*6777b538SAndroid Build Coastguard Worker                       CookieMonster::kDomainPurgeCookies);
5243*6777b538SAndroid Build Coastguard Worker   DCHECK_EQ(3300U, CookieMonster::kMaxCookies);
5244*6777b538SAndroid Build Coastguard Worker   DCHECK_EQ(30, CookieMonster::kSafeFromGlobalPurgeDays);
5245*6777b538SAndroid Build Coastguard Worker 
5246*6777b538SAndroid Build Coastguard Worker   // If secure cookies for one domain hit the per domain limit (180), a
5247*6777b538SAndroid Build Coastguard Worker   // non-secure cookie will not evict them (and, in fact, the non-secure cookie
5248*6777b538SAndroid Build Coastguard Worker   // will be removed right after creation).
5249*6777b538SAndroid Build Coastguard Worker   const CookiesEntry test1[] = {{180U, true}, {1U, false}};
5250*6777b538SAndroid Build Coastguard Worker   TestSecureCookieEviction(test1, 150U, 0U, nullptr);
5251*6777b538SAndroid Build Coastguard Worker 
5252*6777b538SAndroid Build Coastguard Worker   // If non-secure cookies for one domain hit the per domain limit (180), the
5253*6777b538SAndroid Build Coastguard Worker   // creation of secure cookies will evict the non-secure cookies first, making
5254*6777b538SAndroid Build Coastguard Worker   // room for the secure cookies.
5255*6777b538SAndroid Build Coastguard Worker   const CookiesEntry test2[] = {{180U, false}, {20U, true}};
5256*6777b538SAndroid Build Coastguard Worker   TestSecureCookieEviction(test2, 20U, 149U, nullptr);
5257*6777b538SAndroid Build Coastguard Worker 
5258*6777b538SAndroid Build Coastguard Worker   // If secure cookies for one domain go past the per domain limit (180), they
5259*6777b538SAndroid Build Coastguard Worker   // will be evicted as normal by the per domain purge amount (30) down to a
5260*6777b538SAndroid Build Coastguard Worker   // lower amount (150), and then will continue to create the remaining cookies
5261*6777b538SAndroid Build Coastguard Worker   // (19 more to 169).
5262*6777b538SAndroid Build Coastguard Worker   const CookiesEntry test3[] = {{200U, true}};
5263*6777b538SAndroid Build Coastguard Worker   TestSecureCookieEviction(test3, 169U, 0U, nullptr);
5264*6777b538SAndroid Build Coastguard Worker 
5265*6777b538SAndroid Build Coastguard Worker   // If a non-secure cookie is created, and a number of secure cookies exceeds
5266*6777b538SAndroid Build Coastguard Worker   // the per domain limit (18), the total cookies will be evicted down to a
5267*6777b538SAndroid Build Coastguard Worker   // lower amount (150), enforcing the eviction of the non-secure cookie, and
5268*6777b538SAndroid Build Coastguard Worker   // the remaining secure cookies will be created (another 19 to 169).
5269*6777b538SAndroid Build Coastguard Worker   const CookiesEntry test4[] = {{1U, false}, {199U, true}};
5270*6777b538SAndroid Build Coastguard Worker   TestSecureCookieEviction(test4, 169U, 0U, nullptr);
5271*6777b538SAndroid Build Coastguard Worker 
5272*6777b538SAndroid Build Coastguard Worker   // If an even number of non-secure and secure cookies are created below the
5273*6777b538SAndroid Build Coastguard Worker   // per-domain limit (180), all will be created and none evicted.
5274*6777b538SAndroid Build Coastguard Worker   const CookiesEntry test5[] = {{75U, false}, {75U, true}};
5275*6777b538SAndroid Build Coastguard Worker   TestSecureCookieEviction(test5, 75U, 75U, nullptr);
5276*6777b538SAndroid Build Coastguard Worker 
5277*6777b538SAndroid Build Coastguard Worker   // If the same number of secure and non-secure cookies are created (50 each)
5278*6777b538SAndroid Build Coastguard Worker   // below the per domain limit (180), and then another set of secure cookies
5279*6777b538SAndroid Build Coastguard Worker   // are created to bring the total above the per-domain limit, all secure
5280*6777b538SAndroid Build Coastguard Worker   // cookies will be retained, and the non-secure cookies will be culled down
5281*6777b538SAndroid Build Coastguard Worker   // to the limit.
5282*6777b538SAndroid Build Coastguard Worker   const CookiesEntry test6[] = {{50U, true}, {50U, false}, {81U, true}};
5283*6777b538SAndroid Build Coastguard Worker   TestSecureCookieEviction(test6, 131U, 19U, nullptr);
5284*6777b538SAndroid Build Coastguard Worker 
5285*6777b538SAndroid Build Coastguard Worker   // If the same number of non-secure and secure cookies are created (50 each)
5286*6777b538SAndroid Build Coastguard Worker   // below the per domain limit (180), and then another set of non-secure
5287*6777b538SAndroid Build Coastguard Worker   // cookies are created to bring the total above the per-domain limit, all
5288*6777b538SAndroid Build Coastguard Worker   // secure cookies will be retained, and the non-secure cookies will be culled
5289*6777b538SAndroid Build Coastguard Worker   // down to the limit.
5290*6777b538SAndroid Build Coastguard Worker   const CookiesEntry test7[] = {{50U, false}, {50U, true}, {81U, false}};
5291*6777b538SAndroid Build Coastguard Worker   TestSecureCookieEviction(test7, 50U, 100U, nullptr);
5292*6777b538SAndroid Build Coastguard Worker 
5293*6777b538SAndroid Build Coastguard Worker   // If the same number of non-secure and secure cookies are created (50 each)
5294*6777b538SAndroid Build Coastguard Worker   // below the per domain limit (180), and then another set of non-secure
5295*6777b538SAndroid Build Coastguard Worker   // cookies are created to bring the total above the per-domain limit, all
5296*6777b538SAndroid Build Coastguard Worker   // secure cookies will be retained, and the non-secure cookies will be culled
5297*6777b538SAndroid Build Coastguard Worker   // down to the limit, then the remaining non-secure cookies will be created
5298*6777b538SAndroid Build Coastguard Worker   // (9).
5299*6777b538SAndroid Build Coastguard Worker   const CookiesEntry test8[] = {{50U, false}, {50U, true}, {90U, false}};
5300*6777b538SAndroid Build Coastguard Worker   TestSecureCookieEviction(test8, 50U, 109U, nullptr);
5301*6777b538SAndroid Build Coastguard Worker 
5302*6777b538SAndroid Build Coastguard Worker   // If a number of non-secure cookies are created on other hosts (20) and are
5303*6777b538SAndroid Build Coastguard Worker   // past the global 'safe' date, and then the number of non-secure cookies for
5304*6777b538SAndroid Build Coastguard Worker   // a single domain are brought to the per-domain limit (180), followed by
5305*6777b538SAndroid Build Coastguard Worker   // another set of secure cookies on that same domain (20), all the secure
5306*6777b538SAndroid Build Coastguard Worker   // cookies for that domain should be retained, while the non-secure should be
5307*6777b538SAndroid Build Coastguard Worker   // culled down to the per-domain limit. The non-secure cookies for other
5308*6777b538SAndroid Build Coastguard Worker   // domains should remain untouched.
5309*6777b538SAndroid Build Coastguard Worker   const CookiesEntry test9[] = {{180U, false}, {20U, true}};
5310*6777b538SAndroid Build Coastguard Worker   const AltHosts test9_alt_hosts(0, 20);
5311*6777b538SAndroid Build Coastguard Worker   TestSecureCookieEviction(test9, 20U, 169U, &test9_alt_hosts);
5312*6777b538SAndroid Build Coastguard Worker 
5313*6777b538SAndroid Build Coastguard Worker   // If a number of secure cookies are created on other hosts and hit the global
5314*6777b538SAndroid Build Coastguard Worker   // cookie limit (3300) and are past the global 'safe' date, and then a single
5315*6777b538SAndroid Build Coastguard Worker   // non-secure cookie is created now, the secure cookies are removed so that
5316*6777b538SAndroid Build Coastguard Worker   // the global total number of cookies is at the global purge goal (3000), but
5317*6777b538SAndroid Build Coastguard Worker   // the non-secure cookie is not evicted since it is too young.
5318*6777b538SAndroid Build Coastguard Worker   const CookiesEntry test10[] = {{1U, false}};
5319*6777b538SAndroid Build Coastguard Worker   const AltHosts test10_alt_hosts(3300, 0);
5320*6777b538SAndroid Build Coastguard Worker   TestSecureCookieEviction(test10, 2999U, 1U, &test10_alt_hosts);
5321*6777b538SAndroid Build Coastguard Worker 
5322*6777b538SAndroid Build Coastguard Worker   // If a number of non-secure cookies are created on other hosts and hit the
5323*6777b538SAndroid Build Coastguard Worker   // global cookie limit (3300) and are past the global 'safe' date, and then a
5324*6777b538SAndroid Build Coastguard Worker   // single non-secure cookie is created now, the non-secure cookies are removed
5325*6777b538SAndroid Build Coastguard Worker   // so that the global total number of cookies is at the global purge goal
5326*6777b538SAndroid Build Coastguard Worker   // (3000).
5327*6777b538SAndroid Build Coastguard Worker   const CookiesEntry test11[] = {{1U, false}};
5328*6777b538SAndroid Build Coastguard Worker   const AltHosts test11_alt_hosts(0, 3300);
5329*6777b538SAndroid Build Coastguard Worker   TestSecureCookieEviction(test11, 0U, 3000U, &test11_alt_hosts);
5330*6777b538SAndroid Build Coastguard Worker 
5331*6777b538SAndroid Build Coastguard Worker   // If a number of non-secure cookies are created on other hosts and hit the
5332*6777b538SAndroid Build Coastguard Worker   // global cookie limit (3300) and are past the global 'safe' date, and then a
5333*6777b538SAndroid Build Coastguard Worker   // single ecure cookie is created now, the non-secure cookies are removed so
5334*6777b538SAndroid Build Coastguard Worker   // that the global total number of cookies is at the global purge goal (3000),
5335*6777b538SAndroid Build Coastguard Worker   // but the secure cookie is not evicted.
5336*6777b538SAndroid Build Coastguard Worker   const CookiesEntry test12[] = {{1U, true}};
5337*6777b538SAndroid Build Coastguard Worker   const AltHosts test12_alt_hosts(0, 3300);
5338*6777b538SAndroid Build Coastguard Worker   TestSecureCookieEviction(test12, 1U, 2999U, &test12_alt_hosts);
5339*6777b538SAndroid Build Coastguard Worker 
5340*6777b538SAndroid Build Coastguard Worker   // If a total number of secure and non-secure cookies are created on other
5341*6777b538SAndroid Build Coastguard Worker   // hosts and hit the global cookie limit (3300) and are past the global 'safe'
5342*6777b538SAndroid Build Coastguard Worker   // date, and then a single non-secure cookie is created now, the global
5343*6777b538SAndroid Build Coastguard Worker   // non-secure cookies are removed so that the global total number of cookies
5344*6777b538SAndroid Build Coastguard Worker   // is at the global purge goal (3000), but the secure cookies are not evicted.
5345*6777b538SAndroid Build Coastguard Worker   const CookiesEntry test13[] = {{1U, false}};
5346*6777b538SAndroid Build Coastguard Worker   const AltHosts test13_alt_hosts(1500, 1800);
5347*6777b538SAndroid Build Coastguard Worker   TestSecureCookieEviction(test13, 1500U, 1500, &test13_alt_hosts);
5348*6777b538SAndroid Build Coastguard Worker 
5349*6777b538SAndroid Build Coastguard Worker   // If a total number of secure and non-secure cookies are created on other
5350*6777b538SAndroid Build Coastguard Worker   // hosts and hit the global cookie limit (3300) and are past the global 'safe'
5351*6777b538SAndroid Build Coastguard Worker   // date, and then a single secure cookie is created now, the global non-secure
5352*6777b538SAndroid Build Coastguard Worker   // cookies are removed so that the global total number of cookies is at the
5353*6777b538SAndroid Build Coastguard Worker   // global purge goal (3000), but the secure cookies are not evicted.
5354*6777b538SAndroid Build Coastguard Worker   const CookiesEntry test14[] = {{1U, true}};
5355*6777b538SAndroid Build Coastguard Worker   const AltHosts test14_alt_hosts(1500, 1800);
5356*6777b538SAndroid Build Coastguard Worker   TestSecureCookieEviction(test14, 1501U, 1499, &test14_alt_hosts);
5357*6777b538SAndroid Build Coastguard Worker }
5358*6777b538SAndroid Build Coastguard Worker 
5359*6777b538SAndroid Build Coastguard Worker // Tests that strict secure cookies doesn't trip equivalent cookie checks
5360*6777b538SAndroid Build Coastguard Worker // accidentally. Regression test for https://crbug.com/569943.
TEST_F(CookieMonsterTest,EquivalentCookies)5361*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, EquivalentCookies) {
5362*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, nullptr);
5363*6777b538SAndroid Build Coastguard Worker   GURL http_url("http://www.foo.com");
5364*6777b538SAndroid Build Coastguard Worker   GURL http_superdomain_url("http://foo.com");
5365*6777b538SAndroid Build Coastguard Worker   GURL https_url("https://www.foo.com");
5366*6777b538SAndroid Build Coastguard Worker 
5367*6777b538SAndroid Build Coastguard Worker   // Tests that non-equivalent cookies because of the path attribute can be set
5368*6777b538SAndroid Build Coastguard Worker   // successfully.
5369*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), https_url, "A=B; Secure")
5370*6777b538SAndroid Build Coastguard Worker                   .IsInclude());
5371*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), https_url,
5372*6777b538SAndroid Build Coastguard Worker                                              "A=C; path=/some/other/path")
5373*6777b538SAndroid Build Coastguard Worker                   .IsInclude());
5374*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(SetCookie(cm.get(), http_url, "A=D; path=/some/other/path"));
5375*6777b538SAndroid Build Coastguard Worker 
5376*6777b538SAndroid Build Coastguard Worker   // Tests that non-equivalent cookies because of the domain attribute can be
5377*6777b538SAndroid Build Coastguard Worker   // set successfully.
5378*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), https_url, "A=B; Secure")
5379*6777b538SAndroid Build Coastguard Worker                   .IsInclude());
5380*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
5381*6777b538SAndroid Build Coastguard Worker       CreateAndSetCookieReturnStatus(cm.get(), https_url, "A=C; domain=foo.com")
5382*6777b538SAndroid Build Coastguard Worker           .IsInclude());
5383*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(SetCookie(cm.get(), http_url, "A=D; domain=foo.com"));
5384*6777b538SAndroid Build Coastguard Worker }
5385*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,SetCanonicalCookieDoesNotBlockForLoadAll)5386*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, SetCanonicalCookieDoesNotBlockForLoadAll) {
5387*6777b538SAndroid Build Coastguard Worker   scoped_refptr<MockPersistentCookieStore> persistent_store =
5388*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<MockPersistentCookieStore>();
5389*6777b538SAndroid Build Coastguard Worker   // Collect load commands so we have control over their execution.
5390*6777b538SAndroid Build Coastguard Worker   persistent_store->set_store_load_commands(true);
5391*6777b538SAndroid Build Coastguard Worker   CookieMonster cm(persistent_store.get(), nullptr);
5392*6777b538SAndroid Build Coastguard Worker 
5393*6777b538SAndroid Build Coastguard Worker   // Start of a canonical cookie set.
5394*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<CookieAccessResult> callback_set;
5395*6777b538SAndroid Build Coastguard Worker   GURL cookie_url("http://a.com/");
5396*6777b538SAndroid Build Coastguard Worker   cm.SetCanonicalCookieAsync(
5397*6777b538SAndroid Build Coastguard Worker       CanonicalCookie::CreateForTesting(cookie_url, "A=B", base::Time::Now()),
5398*6777b538SAndroid Build Coastguard Worker       cookie_url, CookieOptions::MakeAllInclusive(),
5399*6777b538SAndroid Build Coastguard Worker       callback_set.MakeCallback());
5400*6777b538SAndroid Build Coastguard Worker 
5401*6777b538SAndroid Build Coastguard Worker   // Get cookies for a different URL.
5402*6777b538SAndroid Build Coastguard Worker   GetCookieListCallback callback_get;
5403*6777b538SAndroid Build Coastguard Worker   cm.GetCookieListWithOptionsAsync(
5404*6777b538SAndroid Build Coastguard Worker       GURL("http://b.com/"), CookieOptions::MakeAllInclusive(),
5405*6777b538SAndroid Build Coastguard Worker       CookiePartitionKeyCollection(), callback_get.MakeCallback());
5406*6777b538SAndroid Build Coastguard Worker 
5407*6777b538SAndroid Build Coastguard Worker   // Now go through the store commands, and execute individual loads.
5408*6777b538SAndroid Build Coastguard Worker   const auto& commands = persistent_store->commands();
5409*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < commands.size(); ++i) {
5410*6777b538SAndroid Build Coastguard Worker     if (commands[i].type == CookieStoreCommand::LOAD_COOKIES_FOR_KEY)
5411*6777b538SAndroid Build Coastguard Worker       persistent_store->TakeCallbackAt(i).Run(
5412*6777b538SAndroid Build Coastguard Worker           std::vector<std::unique_ptr<CanonicalCookie>>());
5413*6777b538SAndroid Build Coastguard Worker   }
5414*6777b538SAndroid Build Coastguard Worker 
5415*6777b538SAndroid Build Coastguard Worker   // This should be enough for both individual commands.
5416*6777b538SAndroid Build Coastguard Worker   callback_set.WaitUntilDone();
5417*6777b538SAndroid Build Coastguard Worker   callback_get.WaitUntilDone();
5418*6777b538SAndroid Build Coastguard Worker 
5419*6777b538SAndroid Build Coastguard Worker   // Now execute full-store loads as well.
5420*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < commands.size(); ++i) {
5421*6777b538SAndroid Build Coastguard Worker     if (commands[i].type == CookieStoreCommand::LOAD)
5422*6777b538SAndroid Build Coastguard Worker       persistent_store->TakeCallbackAt(i).Run(
5423*6777b538SAndroid Build Coastguard Worker           std::vector<std::unique_ptr<CanonicalCookie>>());
5424*6777b538SAndroid Build Coastguard Worker   }
5425*6777b538SAndroid Build Coastguard Worker }
5426*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,DeleteDuplicateCTime)5427*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, DeleteDuplicateCTime) {
5428*6777b538SAndroid Build Coastguard Worker   const char* const kNames[] = {"A", "B", "C"};
5429*6777b538SAndroid Build Coastguard Worker 
5430*6777b538SAndroid Build Coastguard Worker   // Tests that DeleteCanonicalCookie properly distinguishes different cookies
5431*6777b538SAndroid Build Coastguard Worker   // (e.g. different name or path) with identical ctime on same domain.
5432*6777b538SAndroid Build Coastguard Worker   // This gets tested a few times with different deletion target, to make sure
5433*6777b538SAndroid Build Coastguard Worker   // that the implementation doesn't just happen to pick the right one because
5434*6777b538SAndroid Build Coastguard Worker   // of implementation details.
5435*6777b538SAndroid Build Coastguard Worker   for (const auto* name : kNames) {
5436*6777b538SAndroid Build Coastguard Worker     CookieMonster cm(nullptr, nullptr);
5437*6777b538SAndroid Build Coastguard Worker     Time now = Time::Now();
5438*6777b538SAndroid Build Coastguard Worker     GURL url("http://www.example.com");
5439*6777b538SAndroid Build Coastguard Worker 
5440*6777b538SAndroid Build Coastguard Worker     for (size_t i = 0; i < std::size(kNames); ++i) {
5441*6777b538SAndroid Build Coastguard Worker       std::string cookie_string =
5442*6777b538SAndroid Build Coastguard Worker           base::StrCat({kNames[i], "=", base::NumberToString(i)});
5443*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(SetCookieWithCreationTime(&cm, url, cookie_string, now));
5444*6777b538SAndroid Build Coastguard Worker     }
5445*6777b538SAndroid Build Coastguard Worker 
5446*6777b538SAndroid Build Coastguard Worker     // Delete the run'th cookie.
5447*6777b538SAndroid Build Coastguard Worker     CookieList all_cookies = GetAllCookiesForURLWithOptions(
5448*6777b538SAndroid Build Coastguard Worker         &cm, url, CookieOptions::MakeAllInclusive());
5449*6777b538SAndroid Build Coastguard Worker     ASSERT_EQ(all_cookies.size(), std::size(kNames));
5450*6777b538SAndroid Build Coastguard Worker     for (size_t i = 0; i < std::size(kNames); ++i) {
5451*6777b538SAndroid Build Coastguard Worker       const CanonicalCookie& cookie = all_cookies[i];
5452*6777b538SAndroid Build Coastguard Worker       if (cookie.Name() == name) {
5453*6777b538SAndroid Build Coastguard Worker         EXPECT_TRUE(DeleteCanonicalCookie(&cm, cookie));
5454*6777b538SAndroid Build Coastguard Worker       }
5455*6777b538SAndroid Build Coastguard Worker     }
5456*6777b538SAndroid Build Coastguard Worker 
5457*6777b538SAndroid Build Coastguard Worker     // Check that the right cookie got removed.
5458*6777b538SAndroid Build Coastguard Worker     all_cookies = GetAllCookiesForURLWithOptions(
5459*6777b538SAndroid Build Coastguard Worker         &cm, url, CookieOptions::MakeAllInclusive());
5460*6777b538SAndroid Build Coastguard Worker     ASSERT_EQ(all_cookies.size(), std::size(kNames) - 1);
5461*6777b538SAndroid Build Coastguard Worker     for (size_t i = 0; i < std::size(kNames) - 1; ++i) {
5462*6777b538SAndroid Build Coastguard Worker       const CanonicalCookie& cookie = all_cookies[i];
5463*6777b538SAndroid Build Coastguard Worker       EXPECT_NE(cookie.Name(), name);
5464*6777b538SAndroid Build Coastguard Worker     }
5465*6777b538SAndroid Build Coastguard Worker   }
5466*6777b538SAndroid Build Coastguard Worker }
5467*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,DeleteCookieWithInheritedTimestamps)5468*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, DeleteCookieWithInheritedTimestamps) {
5469*6777b538SAndroid Build Coastguard Worker   Time t1 = Time::Now();
5470*6777b538SAndroid Build Coastguard Worker   Time t2 = t1 + base::Seconds(1);
5471*6777b538SAndroid Build Coastguard Worker   GURL url("http://www.example.com");
5472*6777b538SAndroid Build Coastguard Worker   std::string cookie_line = "foo=bar";
5473*6777b538SAndroid Build Coastguard Worker   CookieOptions options = CookieOptions::MakeAllInclusive();
5474*6777b538SAndroid Build Coastguard Worker   std::optional<base::Time> server_time = std::nullopt;
5475*6777b538SAndroid Build Coastguard Worker   std::optional<CookiePartitionKey> partition_key = std::nullopt;
5476*6777b538SAndroid Build Coastguard Worker   CookieMonster cm(nullptr, nullptr);
5477*6777b538SAndroid Build Coastguard Worker 
5478*6777b538SAndroid Build Coastguard Worker   // Write a cookie created at |t1|.
5479*6777b538SAndroid Build Coastguard Worker   auto cookie = CanonicalCookie::CreateForTesting(url, cookie_line, t1,
5480*6777b538SAndroid Build Coastguard Worker                                                   server_time, partition_key);
5481*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<CookieAccessResult> set_callback_1;
5482*6777b538SAndroid Build Coastguard Worker   cm.SetCanonicalCookieAsync(std::move(cookie), url, options,
5483*6777b538SAndroid Build Coastguard Worker                              set_callback_1.MakeCallback());
5484*6777b538SAndroid Build Coastguard Worker   set_callback_1.WaitUntilDone();
5485*6777b538SAndroid Build Coastguard Worker 
5486*6777b538SAndroid Build Coastguard Worker   // Overwrite the cookie at |t2|.
5487*6777b538SAndroid Build Coastguard Worker   cookie = CanonicalCookie::CreateForTesting(url, cookie_line, t2, server_time,
5488*6777b538SAndroid Build Coastguard Worker                                              partition_key);
5489*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<CookieAccessResult> set_callback_2;
5490*6777b538SAndroid Build Coastguard Worker   cm.SetCanonicalCookieAsync(std::move(cookie), url, options,
5491*6777b538SAndroid Build Coastguard Worker                              set_callback_2.MakeCallback());
5492*6777b538SAndroid Build Coastguard Worker   set_callback_2.WaitUntilDone();
5493*6777b538SAndroid Build Coastguard Worker 
5494*6777b538SAndroid Build Coastguard Worker   // The second cookie overwrites the first one but it will inherit the creation
5495*6777b538SAndroid Build Coastguard Worker   // timestamp |t1|. Test that deleting the new cookie still works.
5496*6777b538SAndroid Build Coastguard Worker   cookie = CanonicalCookie::CreateForTesting(url, cookie_line, t2, server_time,
5497*6777b538SAndroid Build Coastguard Worker                                              partition_key);
5498*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<unsigned int> delete_callback;
5499*6777b538SAndroid Build Coastguard Worker   cm.DeleteCanonicalCookieAsync(*cookie, delete_callback.MakeCallback());
5500*6777b538SAndroid Build Coastguard Worker   delete_callback.WaitUntilDone();
5501*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1U, delete_callback.result());
5502*6777b538SAndroid Build Coastguard Worker }
5503*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,RejectCreatedSameSiteCookieOnSet)5504*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, RejectCreatedSameSiteCookieOnSet) {
5505*6777b538SAndroid Build Coastguard Worker   GURL url("http://www.example.com");
5506*6777b538SAndroid Build Coastguard Worker   std::string cookie_line = "foo=bar; SameSite=Lax";
5507*6777b538SAndroid Build Coastguard Worker 
5508*6777b538SAndroid Build Coastguard Worker   CookieMonster cm(nullptr, nullptr);
5509*6777b538SAndroid Build Coastguard Worker   CookieOptions env_cross_site;
5510*6777b538SAndroid Build Coastguard Worker   env_cross_site.set_same_site_cookie_context(
5511*6777b538SAndroid Build Coastguard Worker       CookieOptions::SameSiteCookieContext(
5512*6777b538SAndroid Build Coastguard Worker           CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE));
5513*6777b538SAndroid Build Coastguard Worker 
5514*6777b538SAndroid Build Coastguard Worker   CookieInclusionStatus status;
5515*6777b538SAndroid Build Coastguard Worker   // Cookie can be created successfully; SameSite is not checked on Creation.
5516*6777b538SAndroid Build Coastguard Worker   auto cookie = CanonicalCookie::CreateForTesting(
5517*6777b538SAndroid Build Coastguard Worker       url, cookie_line, base::Time::Now(),
5518*6777b538SAndroid Build Coastguard Worker       /*server_time=*/std::nullopt,
5519*6777b538SAndroid Build Coastguard Worker       /*cookie_partition_key=*/std::nullopt,
5520*6777b538SAndroid Build Coastguard Worker       /*block_truncated=*/true, CookieSourceType::kUnknown, &status);
5521*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(cookie != nullptr);
5522*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(status.IsInclude());
5523*6777b538SAndroid Build Coastguard Worker 
5524*6777b538SAndroid Build Coastguard Worker   // ... but the environment is checked on set, so this may be rejected then.
5525*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<CookieAccessResult> callback;
5526*6777b538SAndroid Build Coastguard Worker   cm.SetCanonicalCookieAsync(std::move(cookie), url, env_cross_site,
5527*6777b538SAndroid Build Coastguard Worker                              callback.MakeCallback());
5528*6777b538SAndroid Build Coastguard Worker   callback.WaitUntilDone();
5529*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(callback.result().status.HasExactlyExclusionReasonsForTesting(
5530*6777b538SAndroid Build Coastguard Worker       {CookieInclusionStatus::EXCLUDE_SAMESITE_LAX}));
5531*6777b538SAndroid Build Coastguard Worker }
5532*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,RejectCreatedSecureCookieOnSet)5533*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, RejectCreatedSecureCookieOnSet) {
5534*6777b538SAndroid Build Coastguard Worker   GURL http_url("http://www.example.com");
5535*6777b538SAndroid Build Coastguard Worker   std::string cookie_line = "foo=bar; Secure";
5536*6777b538SAndroid Build Coastguard Worker 
5537*6777b538SAndroid Build Coastguard Worker   CookieMonster cm(nullptr, nullptr);
5538*6777b538SAndroid Build Coastguard Worker   CookieInclusionStatus status;
5539*6777b538SAndroid Build Coastguard Worker   // Cookie can be created successfully from an any url. Secure is not checked
5540*6777b538SAndroid Build Coastguard Worker   // on Create.
5541*6777b538SAndroid Build Coastguard Worker   auto cookie = CanonicalCookie::CreateForTesting(
5542*6777b538SAndroid Build Coastguard Worker       http_url, cookie_line, base::Time::Now(), /*server_time=*/std::nullopt,
5543*6777b538SAndroid Build Coastguard Worker       /*cookie_partition_key=*/std::nullopt, /*block_truncated=*/true,
5544*6777b538SAndroid Build Coastguard Worker       CookieSourceType::kUnknown, &status);
5545*6777b538SAndroid Build Coastguard Worker 
5546*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(cookie != nullptr);
5547*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(status.IsInclude());
5548*6777b538SAndroid Build Coastguard Worker 
5549*6777b538SAndroid Build Coastguard Worker   // Cookie is rejected when attempting to set from a non-secure scheme.
5550*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<CookieAccessResult> callback;
5551*6777b538SAndroid Build Coastguard Worker   cm.SetCanonicalCookieAsync(std::move(cookie), http_url,
5552*6777b538SAndroid Build Coastguard Worker                              CookieOptions::MakeAllInclusive(),
5553*6777b538SAndroid Build Coastguard Worker                              callback.MakeCallback());
5554*6777b538SAndroid Build Coastguard Worker   callback.WaitUntilDone();
5555*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(callback.result().status.HasExactlyExclusionReasonsForTesting(
5556*6777b538SAndroid Build Coastguard Worker       {CookieInclusionStatus::EXCLUDE_SECURE_ONLY}));
5557*6777b538SAndroid Build Coastguard Worker }
5558*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,RejectCreatedHttpOnlyCookieOnSet)5559*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, RejectCreatedHttpOnlyCookieOnSet) {
5560*6777b538SAndroid Build Coastguard Worker   GURL url("http://www.example.com");
5561*6777b538SAndroid Build Coastguard Worker   std::string cookie_line = "foo=bar; HttpOnly";
5562*6777b538SAndroid Build Coastguard Worker 
5563*6777b538SAndroid Build Coastguard Worker   CookieMonster cm(nullptr, nullptr);
5564*6777b538SAndroid Build Coastguard Worker   CookieInclusionStatus status;
5565*6777b538SAndroid Build Coastguard Worker   // Cookie can be created successfully; HttpOnly is not checked on Create.
5566*6777b538SAndroid Build Coastguard Worker   auto cookie = CanonicalCookie::CreateForTesting(
5567*6777b538SAndroid Build Coastguard Worker       url, cookie_line, base::Time::Now(),
5568*6777b538SAndroid Build Coastguard Worker       /*server_time=*/std::nullopt,
5569*6777b538SAndroid Build Coastguard Worker       /*cookie_partition_key=*/std::nullopt,
5570*6777b538SAndroid Build Coastguard Worker       /*block_truncated=*/true, CookieSourceType::kUnknown, &status);
5571*6777b538SAndroid Build Coastguard Worker 
5572*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(cookie != nullptr);
5573*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(status.IsInclude());
5574*6777b538SAndroid Build Coastguard Worker 
5575*6777b538SAndroid Build Coastguard Worker   // Cookie is rejected when attempting to set with a CookieOptions that does
5576*6777b538SAndroid Build Coastguard Worker   // not allow httponly.
5577*6777b538SAndroid Build Coastguard Worker   CookieOptions options_no_httponly;
5578*6777b538SAndroid Build Coastguard Worker   options_no_httponly.set_same_site_cookie_context(
5579*6777b538SAndroid Build Coastguard Worker       CookieOptions::SameSiteCookieContext(
5580*6777b538SAndroid Build Coastguard Worker           CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT));
5581*6777b538SAndroid Build Coastguard Worker   options_no_httponly.set_exclude_httponly();  // Default, but make it explicit.
5582*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<CookieAccessResult> callback;
5583*6777b538SAndroid Build Coastguard Worker   cm.SetCanonicalCookieAsync(std::move(cookie), url, options_no_httponly,
5584*6777b538SAndroid Build Coastguard Worker                              callback.MakeCallback());
5585*6777b538SAndroid Build Coastguard Worker   callback.WaitUntilDone();
5586*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(callback.result().status.HasExactlyExclusionReasonsForTesting(
5587*6777b538SAndroid Build Coastguard Worker       {CookieInclusionStatus::EXCLUDE_HTTP_ONLY}));
5588*6777b538SAndroid Build Coastguard Worker }
5589*6777b538SAndroid Build Coastguard Worker 
5590*6777b538SAndroid Build Coastguard Worker // Test that SameSite=None requires Secure.
TEST_F(CookieMonsterTest,CookiesWithoutSameSiteMustBeSecure)5591*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, CookiesWithoutSameSiteMustBeSecure) {
5592*6777b538SAndroid Build Coastguard Worker   const base::TimeDelta kLongAge = kLaxAllowUnsafeMaxAge * 4;
5593*6777b538SAndroid Build Coastguard Worker   const base::TimeDelta kShortAge = kLaxAllowUnsafeMaxAge / 4;
5594*6777b538SAndroid Build Coastguard Worker 
5595*6777b538SAndroid Build Coastguard Worker   struct TestCase {
5596*6777b538SAndroid Build Coastguard Worker     bool is_url_secure;
5597*6777b538SAndroid Build Coastguard Worker     std::string cookie_line;
5598*6777b538SAndroid Build Coastguard Worker     CookieInclusionStatus expected_set_cookie_result;
5599*6777b538SAndroid Build Coastguard Worker     // Only makes sense to check if result is INCLUDE:
5600*6777b538SAndroid Build Coastguard Worker     CookieEffectiveSameSite expected_effective_samesite =
5601*6777b538SAndroid Build Coastguard Worker         CookieEffectiveSameSite::NO_RESTRICTION;
5602*6777b538SAndroid Build Coastguard Worker     base::TimeDelta creation_time_delta = base::TimeDelta();
5603*6777b538SAndroid Build Coastguard Worker   } test_cases[] = {
5604*6777b538SAndroid Build Coastguard Worker       // Feature enabled:
5605*6777b538SAndroid Build Coastguard Worker       // Cookie set from a secure URL with SameSite enabled is not rejected.
5606*6777b538SAndroid Build Coastguard Worker       {true, "A=B; SameSite=Lax", CookieInclusionStatus(),
5607*6777b538SAndroid Build Coastguard Worker        CookieEffectiveSameSite::LAX_MODE},
5608*6777b538SAndroid Build Coastguard Worker       // Cookie set from a secure URL which is defaulted into Lax is not
5609*6777b538SAndroid Build Coastguard Worker       // rejected.
5610*6777b538SAndroid Build Coastguard Worker       {true, "A=B",  // recently-set session cookie.
5611*6777b538SAndroid Build Coastguard Worker        CookieInclusionStatus(), CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE,
5612*6777b538SAndroid Build Coastguard Worker        kShortAge},
5613*6777b538SAndroid Build Coastguard Worker       {true, "A=B",  // not-recently-set session cookie.
5614*6777b538SAndroid Build Coastguard Worker        CookieInclusionStatus(), CookieEffectiveSameSite::LAX_MODE, kLongAge},
5615*6777b538SAndroid Build Coastguard Worker       // Cookie set from a secure URL with SameSite=None and Secure is set.
5616*6777b538SAndroid Build Coastguard Worker       {true, "A=B; SameSite=None; Secure", CookieInclusionStatus(),
5617*6777b538SAndroid Build Coastguard Worker        CookieEffectiveSameSite::NO_RESTRICTION},
5618*6777b538SAndroid Build Coastguard Worker       // Cookie set from a secure URL with SameSite=None but not specifying
5619*6777b538SAndroid Build Coastguard Worker       // Secure is rejected.
5620*6777b538SAndroid Build Coastguard Worker       {true, "A=B; SameSite=None",
5621*6777b538SAndroid Build Coastguard Worker        CookieInclusionStatus(
5622*6777b538SAndroid Build Coastguard Worker            CookieInclusionStatus::EXCLUDE_SAMESITE_NONE_INSECURE,
5623*6777b538SAndroid Build Coastguard Worker            CookieInclusionStatus::WARN_SAMESITE_NONE_INSECURE)},
5624*6777b538SAndroid Build Coastguard Worker       // Cookie set from an insecure URL which defaults into LAX_MODE is not
5625*6777b538SAndroid Build Coastguard Worker       // rejected.
5626*6777b538SAndroid Build Coastguard Worker       {false, "A=B",  // recently-set session cookie.
5627*6777b538SAndroid Build Coastguard Worker        CookieInclusionStatus(), CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE,
5628*6777b538SAndroid Build Coastguard Worker        kShortAge},
5629*6777b538SAndroid Build Coastguard Worker       {false, "A=B",  // not-recently-set session cookie.
5630*6777b538SAndroid Build Coastguard Worker        CookieInclusionStatus(), CookieEffectiveSameSite::LAX_MODE, kLongAge},
5631*6777b538SAndroid Build Coastguard Worker       {false, "A=B; Max-Age=1000000",  // recently-set persistent cookie.
5632*6777b538SAndroid Build Coastguard Worker        CookieInclusionStatus(), CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE,
5633*6777b538SAndroid Build Coastguard Worker        kShortAge},
5634*6777b538SAndroid Build Coastguard Worker       {false,
5635*6777b538SAndroid Build Coastguard Worker        "A=B; Max-Age=1000000",  // not-recently-set persistent cookie.
5636*6777b538SAndroid Build Coastguard Worker        CookieInclusionStatus(), CookieEffectiveSameSite::LAX_MODE, kLongAge},
5637*6777b538SAndroid Build Coastguard Worker   };
5638*6777b538SAndroid Build Coastguard Worker 
5639*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(nullptr, nullptr);
5640*6777b538SAndroid Build Coastguard Worker   GURL secure_url("https://www.example1.test");
5641*6777b538SAndroid Build Coastguard Worker   GURL insecure_url("http://www.example2.test");
5642*6777b538SAndroid Build Coastguard Worker 
5643*6777b538SAndroid Build Coastguard Worker   int length = sizeof(test_cases) / sizeof(test_cases[0]);
5644*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < length; ++i) {
5645*6777b538SAndroid Build Coastguard Worker     TestCase test = test_cases[i];
5646*6777b538SAndroid Build Coastguard Worker 
5647*6777b538SAndroid Build Coastguard Worker     GURL url = test.is_url_secure ? secure_url : insecure_url;
5648*6777b538SAndroid Build Coastguard Worker     base::Time creation_time = base::Time::Now() - test.creation_time_delta;
5649*6777b538SAndroid Build Coastguard Worker     auto cookie =
5650*6777b538SAndroid Build Coastguard Worker         CanonicalCookie::CreateForTesting(url, test.cookie_line, creation_time);
5651*6777b538SAndroid Build Coastguard Worker     // Make a copy so we can delete it after the test.
5652*6777b538SAndroid Build Coastguard Worker     CanonicalCookie cookie_copy = *cookie;
5653*6777b538SAndroid Build Coastguard Worker     CookieAccessResult result = SetCanonicalCookieReturnAccessResult(
5654*6777b538SAndroid Build Coastguard Worker         cm.get(), std::move(cookie), url,
5655*6777b538SAndroid Build Coastguard Worker         true /* can_modify_httponly (irrelevant) */);
5656*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(test.expected_set_cookie_result, result.status)
5657*6777b538SAndroid Build Coastguard Worker         << "Test case " << i << " failed.";
5658*6777b538SAndroid Build Coastguard Worker     if (result.status.IsInclude()) {
5659*6777b538SAndroid Build Coastguard Worker       auto cookies = GetAllCookiesForURL(cm.get(), url);
5660*6777b538SAndroid Build Coastguard Worker       ASSERT_EQ(1u, cookies.size());
5661*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(test.expected_effective_samesite, result.effective_same_site)
5662*6777b538SAndroid Build Coastguard Worker           << "Test case " << i << " failed.";
5663*6777b538SAndroid Build Coastguard Worker       DeleteCanonicalCookie(cm.get(), cookie_copy);
5664*6777b538SAndroid Build Coastguard Worker     }
5665*6777b538SAndroid Build Coastguard Worker   }
5666*6777b538SAndroid Build Coastguard Worker }
5667*6777b538SAndroid Build Coastguard Worker 
5668*6777b538SAndroid Build Coastguard Worker class CookieMonsterNotificationTest : public CookieMonsterTest {
5669*6777b538SAndroid Build Coastguard Worker  public:
CookieMonsterNotificationTest()5670*6777b538SAndroid Build Coastguard Worker   CookieMonsterNotificationTest()
5671*6777b538SAndroid Build Coastguard Worker       : test_url_("http://www.foo.com/foo"),
5672*6777b538SAndroid Build Coastguard Worker         store_(base::MakeRefCounted<MockPersistentCookieStore>()),
5673*6777b538SAndroid Build Coastguard Worker         monster_(std::make_unique<CookieMonster>(store_.get(), nullptr)) {}
5674*6777b538SAndroid Build Coastguard Worker 
5675*6777b538SAndroid Build Coastguard Worker   ~CookieMonsterNotificationTest() override = default;
5676*6777b538SAndroid Build Coastguard Worker 
monster()5677*6777b538SAndroid Build Coastguard Worker   CookieMonster* monster() { return monster_.get(); }
5678*6777b538SAndroid Build Coastguard Worker 
5679*6777b538SAndroid Build Coastguard Worker  protected:
5680*6777b538SAndroid Build Coastguard Worker   const GURL test_url_;
5681*6777b538SAndroid Build Coastguard Worker 
5682*6777b538SAndroid Build Coastguard Worker  private:
5683*6777b538SAndroid Build Coastguard Worker   scoped_refptr<MockPersistentCookieStore> store_;
5684*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<CookieMonster> monster_;
5685*6777b538SAndroid Build Coastguard Worker };
5686*6777b538SAndroid Build Coastguard Worker 
RecordCookieChanges(std::vector<CanonicalCookie> * out_cookies,std::vector<CookieChangeCause> * out_causes,const CookieChangeInfo & change)5687*6777b538SAndroid Build Coastguard Worker void RecordCookieChanges(std::vector<CanonicalCookie>* out_cookies,
5688*6777b538SAndroid Build Coastguard Worker                          std::vector<CookieChangeCause>* out_causes,
5689*6777b538SAndroid Build Coastguard Worker                          const CookieChangeInfo& change) {
5690*6777b538SAndroid Build Coastguard Worker   DCHECK(out_cookies);
5691*6777b538SAndroid Build Coastguard Worker   out_cookies->push_back(change.cookie);
5692*6777b538SAndroid Build Coastguard Worker   if (out_causes)
5693*6777b538SAndroid Build Coastguard Worker     out_causes->push_back(change.cause);
5694*6777b538SAndroid Build Coastguard Worker }
5695*6777b538SAndroid Build Coastguard Worker 
5696*6777b538SAndroid Build Coastguard Worker // Tests that there are no changes emitted for cookie loading, but there are
5697*6777b538SAndroid Build Coastguard Worker // changes emitted for other operations.
TEST_F(CookieMonsterNotificationTest,NoNotificationOnLoad)5698*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterNotificationTest, NoNotificationOnLoad) {
5699*6777b538SAndroid Build Coastguard Worker   // Create a persistent store that will not synchronously satisfy the
5700*6777b538SAndroid Build Coastguard Worker   // loading requirement.
5701*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
5702*6777b538SAndroid Build Coastguard Worker   store->set_store_load_commands(true);
5703*6777b538SAndroid Build Coastguard Worker 
5704*6777b538SAndroid Build Coastguard Worker   // Bind it to a CookieMonster
5705*6777b538SAndroid Build Coastguard Worker   auto monster = std::make_unique<CookieMonster>(store.get(), nullptr);
5706*6777b538SAndroid Build Coastguard Worker 
5707*6777b538SAndroid Build Coastguard Worker   // Trigger load dispatch and confirm it.
5708*6777b538SAndroid Build Coastguard Worker   monster->GetAllCookiesAsync(CookieStore::GetAllCookiesCallback());
5709*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(1u, store->commands().size());
5710*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieStoreCommand::LOAD, store->commands()[0].type);
5711*6777b538SAndroid Build Coastguard Worker 
5712*6777b538SAndroid Build Coastguard Worker   // Attach a change subscription.
5713*6777b538SAndroid Build Coastguard Worker   std::vector<CanonicalCookie> cookies;
5714*6777b538SAndroid Build Coastguard Worker   std::vector<CookieChangeCause> causes;
5715*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<CookieChangeSubscription> subscription =
5716*6777b538SAndroid Build Coastguard Worker       monster->GetChangeDispatcher().AddCallbackForAllChanges(
5717*6777b538SAndroid Build Coastguard Worker           base::BindRepeating(&RecordCookieChanges, &cookies, &causes));
5718*6777b538SAndroid Build Coastguard Worker 
5719*6777b538SAndroid Build Coastguard Worker   // Set up some initial cookies, including duplicates.
5720*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<CanonicalCookie>> initial_cookies;
5721*6777b538SAndroid Build Coastguard Worker   GURL url("http://www.foo.com");
5722*6777b538SAndroid Build Coastguard Worker   initial_cookies.push_back(
5723*6777b538SAndroid Build Coastguard Worker       CanonicalCookie::CreateForTesting(url, "X=1; path=/", base::Time::Now()));
5724*6777b538SAndroid Build Coastguard Worker   initial_cookies.push_back(
5725*6777b538SAndroid Build Coastguard Worker       CanonicalCookie::CreateForTesting(url, "Y=1; path=/", base::Time::Now()));
5726*6777b538SAndroid Build Coastguard Worker   initial_cookies.push_back(CanonicalCookie::CreateForTesting(
5727*6777b538SAndroid Build Coastguard Worker       url, "Y=2; path=/", base::Time::Now() + base::Days(1)));
5728*6777b538SAndroid Build Coastguard Worker 
5729*6777b538SAndroid Build Coastguard Worker   // Execute the load
5730*6777b538SAndroid Build Coastguard Worker   store->TakeCallbackAt(0).Run(std::move(initial_cookies));
5731*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
5732*6777b538SAndroid Build Coastguard Worker 
5733*6777b538SAndroid Build Coastguard Worker   // We should see no insertions (because loads do not cause notifications to be
5734*6777b538SAndroid Build Coastguard Worker   // dispatched), no deletions (because overwriting a duplicate cookie on load
5735*6777b538SAndroid Build Coastguard Worker   // does not trigger a notification), and two cookies in the monster.
5736*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, cookies.size());
5737*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, causes.size());
5738*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, this->GetAllCookies(monster.get()).size());
5739*6777b538SAndroid Build Coastguard Worker 
5740*6777b538SAndroid Build Coastguard Worker   // Change the cookies again to make sure that other changes do emit
5741*6777b538SAndroid Build Coastguard Worker   // notifications.
5742*6777b538SAndroid Build Coastguard Worker   this->CreateAndSetCookie(monster.get(), url, "X=2; path=/",
5743*6777b538SAndroid Build Coastguard Worker                            CookieOptions::MakeAllInclusive());
5744*6777b538SAndroid Build Coastguard Worker   this->CreateAndSetCookie(monster.get(), url, "Y=3; path=/; max-age=0",
5745*6777b538SAndroid Build Coastguard Worker                            CookieOptions::MakeAllInclusive());
5746*6777b538SAndroid Build Coastguard Worker 
5747*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
5748*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(3u, cookies.size());
5749*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(3u, causes.size());
5750*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("X", cookies[0].Name());
5751*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("1", cookies[0].Value());
5752*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieChangeCause::OVERWRITE, causes[0]);
5753*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("X", cookies[1].Name());
5754*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("2", cookies[1].Value());
5755*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieChangeCause::INSERTED, causes[1]);
5756*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("Y", cookies[2].Name());
5757*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("2", cookies[2].Value());
5758*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CookieChangeCause::EXPIRED_OVERWRITE, causes[2]);
5759*6777b538SAndroid Build Coastguard Worker }
5760*6777b538SAndroid Build Coastguard Worker 
5761*6777b538SAndroid Build Coastguard Worker class CookieMonsterLegacyCookieAccessTest : public CookieMonsterTest {
5762*6777b538SAndroid Build Coastguard Worker  public:
CookieMonsterLegacyCookieAccessTest()5763*6777b538SAndroid Build Coastguard Worker   CookieMonsterLegacyCookieAccessTest()
5764*6777b538SAndroid Build Coastguard Worker       : cm_(std::make_unique<CookieMonster>(nullptr /* store */,
5765*6777b538SAndroid Build Coastguard Worker                                             nullptr /* netlog */
5766*6777b538SAndroid Build Coastguard Worker                                             )) {
5767*6777b538SAndroid Build Coastguard Worker     // Need to reset first because there cannot be two TaskEnvironments at the
5768*6777b538SAndroid Build Coastguard Worker     // same time.
5769*6777b538SAndroid Build Coastguard Worker     task_environment_.reset();
5770*6777b538SAndroid Build Coastguard Worker     task_environment_ =
5771*6777b538SAndroid Build Coastguard Worker         std::make_unique<base::test::SingleThreadTaskEnvironment>(
5772*6777b538SAndroid Build Coastguard Worker             base::test::TaskEnvironment::TimeSource::MOCK_TIME);
5773*6777b538SAndroid Build Coastguard Worker 
5774*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<TestCookieAccessDelegate> access_delegate =
5775*6777b538SAndroid Build Coastguard Worker         std::make_unique<TestCookieAccessDelegate>();
5776*6777b538SAndroid Build Coastguard Worker     access_delegate_ = access_delegate.get();
5777*6777b538SAndroid Build Coastguard Worker     cm_->SetCookieAccessDelegate(std::move(access_delegate));
5778*6777b538SAndroid Build Coastguard Worker   }
5779*6777b538SAndroid Build Coastguard Worker 
5780*6777b538SAndroid Build Coastguard Worker   ~CookieMonsterLegacyCookieAccessTest() override = default;
5781*6777b538SAndroid Build Coastguard Worker 
5782*6777b538SAndroid Build Coastguard Worker  protected:
5783*6777b538SAndroid Build Coastguard Worker   const std::string kDomain = "example.test";
5784*6777b538SAndroid Build Coastguard Worker   const GURL kHttpsUrl = GURL("https://example.test");
5785*6777b538SAndroid Build Coastguard Worker   const GURL kHttpUrl = GURL("http://example.test");
5786*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<CookieMonster> cm_;
5787*6777b538SAndroid Build Coastguard Worker   raw_ptr<TestCookieAccessDelegate> access_delegate_;
5788*6777b538SAndroid Build Coastguard Worker };
5789*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterLegacyCookieAccessTest,SetLegacyNoSameSiteCookie)5790*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterLegacyCookieAccessTest, SetLegacyNoSameSiteCookie) {
5791*6777b538SAndroid Build Coastguard Worker   // Check that setting unspecified-SameSite cookie from cross-site context
5792*6777b538SAndroid Build Coastguard Worker   // fails if not set to Legacy semantics, but succeeds if set to legacy.
5793*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(CreateAndSetCookie(cm_.get(), kHttpUrl, "cookie=chocolate_chip",
5794*6777b538SAndroid Build Coastguard Worker                                   CookieOptions()));
5795*6777b538SAndroid Build Coastguard Worker   access_delegate_->SetExpectationForCookieDomain(
5796*6777b538SAndroid Build Coastguard Worker       kDomain, CookieAccessSemantics::UNKNOWN);
5797*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(CreateAndSetCookie(cm_.get(), kHttpUrl, "cookie=chocolate_chip",
5798*6777b538SAndroid Build Coastguard Worker                                   CookieOptions()));
5799*6777b538SAndroid Build Coastguard Worker   access_delegate_->SetExpectationForCookieDomain(
5800*6777b538SAndroid Build Coastguard Worker       kDomain, CookieAccessSemantics::NONLEGACY);
5801*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(CreateAndSetCookie(cm_.get(), kHttpUrl, "cookie=chocolate_chip",
5802*6777b538SAndroid Build Coastguard Worker                                   CookieOptions()));
5803*6777b538SAndroid Build Coastguard Worker   access_delegate_->SetExpectationForCookieDomain(
5804*6777b538SAndroid Build Coastguard Worker       kDomain, CookieAccessSemantics::LEGACY);
5805*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookie(cm_.get(), kHttpUrl, "cookie=chocolate_chip",
5806*6777b538SAndroid Build Coastguard Worker                                  CookieOptions()));
5807*6777b538SAndroid Build Coastguard Worker }
5808*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterLegacyCookieAccessTest,GetLegacyNoSameSiteCookie)5809*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterLegacyCookieAccessTest, GetLegacyNoSameSiteCookie) {
5810*6777b538SAndroid Build Coastguard Worker   // Set a cookie with no SameSite attribute.
5811*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CreateAndSetCookie(cm_.get(), kHttpUrl, "cookie=chocolate_chip",
5812*6777b538SAndroid Build Coastguard Worker                                  CookieOptions::MakeAllInclusive()));
5813*6777b538SAndroid Build Coastguard Worker 
5814*6777b538SAndroid Build Coastguard Worker   // Getting the cookie fails unless semantics is legacy.
5815*6777b538SAndroid Build Coastguard Worker   access_delegate_->SetExpectationForCookieDomain(
5816*6777b538SAndroid Build Coastguard Worker       kDomain, CookieAccessSemantics::UNKNOWN);
5817*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("", GetCookiesWithOptions(cm_.get(), kHttpUrl, CookieOptions()));
5818*6777b538SAndroid Build Coastguard Worker   access_delegate_->SetExpectationForCookieDomain(
5819*6777b538SAndroid Build Coastguard Worker       kDomain, CookieAccessSemantics::NONLEGACY);
5820*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("", GetCookiesWithOptions(cm_.get(), kHttpUrl, CookieOptions()));
5821*6777b538SAndroid Build Coastguard Worker   access_delegate_->SetExpectationForCookieDomain(
5822*6777b538SAndroid Build Coastguard Worker       kDomain, CookieAccessSemantics::LEGACY);
5823*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("cookie=chocolate_chip",
5824*6777b538SAndroid Build Coastguard Worker             GetCookiesWithOptions(cm_.get(), kHttpUrl, CookieOptions()));
5825*6777b538SAndroid Build Coastguard Worker }
5826*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterLegacyCookieAccessTest,SetLegacySameSiteNoneInsecureCookie)5827*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterLegacyCookieAccessTest,
5828*6777b538SAndroid Build Coastguard Worker        SetLegacySameSiteNoneInsecureCookie) {
5829*6777b538SAndroid Build Coastguard Worker   access_delegate_->SetExpectationForCookieDomain(
5830*6777b538SAndroid Build Coastguard Worker       kDomain, CookieAccessSemantics::UNKNOWN);
5831*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(CreateAndSetCookie(cm_.get(), kHttpsUrl,
5832*6777b538SAndroid Build Coastguard Worker                                   "cookie=oatmeal_raisin; SameSite=None",
5833*6777b538SAndroid Build Coastguard Worker                                   CookieOptions()));
5834*6777b538SAndroid Build Coastguard Worker   access_delegate_->SetExpectationForCookieDomain(
5835*6777b538SAndroid Build Coastguard Worker       kDomain, CookieAccessSemantics::NONLEGACY);
5836*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(CreateAndSetCookie(cm_.get(), kHttpsUrl,
5837*6777b538SAndroid Build Coastguard Worker                                   "cookie=oatmeal_raisin; SameSite=None",
5838*6777b538SAndroid Build Coastguard Worker                                   CookieOptions()));
5839*6777b538SAndroid Build Coastguard Worker   // Setting the access semantics to legacy allows setting the cookie.
5840*6777b538SAndroid Build Coastguard Worker   access_delegate_->SetExpectationForCookieDomain(
5841*6777b538SAndroid Build Coastguard Worker       kDomain, CookieAccessSemantics::LEGACY);
5842*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookie(cm_.get(), kHttpsUrl,
5843*6777b538SAndroid Build Coastguard Worker                                  "cookie=oatmeal_raisin; SameSite=None",
5844*6777b538SAndroid Build Coastguard Worker                                  CookieOptions()));
5845*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("cookie=oatmeal_raisin",
5846*6777b538SAndroid Build Coastguard Worker             GetCookiesWithOptions(cm_.get(), kHttpsUrl, CookieOptions()));
5847*6777b538SAndroid Build Coastguard Worker }
5848*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterLegacyCookieAccessTest,GetLegacySameSiteNoneInsecureCookie)5849*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterLegacyCookieAccessTest,
5850*6777b538SAndroid Build Coastguard Worker        GetLegacySameSiteNoneInsecureCookie) {
5851*6777b538SAndroid Build Coastguard Worker   // Need to inject such a cookie under legacy semantics.
5852*6777b538SAndroid Build Coastguard Worker   access_delegate_->SetExpectationForCookieDomain(
5853*6777b538SAndroid Build Coastguard Worker       kDomain, CookieAccessSemantics::LEGACY);
5854*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CreateAndSetCookie(cm_.get(), kHttpUrl,
5855*6777b538SAndroid Build Coastguard Worker                                  "cookie=oatmeal_raisin; SameSite=None",
5856*6777b538SAndroid Build Coastguard Worker                                  CookieOptions::MakeAllInclusive()));
5857*6777b538SAndroid Build Coastguard Worker   // Getting a SameSite=None but non-Secure cookie fails unless semantics is
5858*6777b538SAndroid Build Coastguard Worker   // legacy.
5859*6777b538SAndroid Build Coastguard Worker   access_delegate_->SetExpectationForCookieDomain(
5860*6777b538SAndroid Build Coastguard Worker       kDomain, CookieAccessSemantics::UNKNOWN);
5861*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("", GetCookiesWithOptions(cm_.get(), kHttpUrl, CookieOptions()));
5862*6777b538SAndroid Build Coastguard Worker   access_delegate_->SetExpectationForCookieDomain(
5863*6777b538SAndroid Build Coastguard Worker       kDomain, CookieAccessSemantics::NONLEGACY);
5864*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("", GetCookiesWithOptions(cm_.get(), kHttpUrl, CookieOptions()));
5865*6777b538SAndroid Build Coastguard Worker   access_delegate_->SetExpectationForCookieDomain(
5866*6777b538SAndroid Build Coastguard Worker       kDomain, CookieAccessSemantics::LEGACY);
5867*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("cookie=oatmeal_raisin",
5868*6777b538SAndroid Build Coastguard Worker             GetCookiesWithOptions(cm_.get(), kHttpUrl, CookieOptions()));
5869*6777b538SAndroid Build Coastguard Worker }
5870*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,IsCookieSentToSamePortThatSetIt)5871*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, IsCookieSentToSamePortThatSetIt) {
5872*6777b538SAndroid Build Coastguard Worker   // Note: `IsCookieSentToSamePortThatSetIt()` only uses the source_scheme if
5873*6777b538SAndroid Build Coastguard Worker   // the port is valid, specified, and doesn't match the url's port. So for test
5874*6777b538SAndroid Build Coastguard Worker   // cases where the above aren't true the value of source_scheme is irreleant.
5875*6777b538SAndroid Build Coastguard Worker 
5876*6777b538SAndroid Build Coastguard Worker   // Test unspecified.
5877*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(CookieMonster::IsCookieSentToSamePortThatSetIt(
5878*6777b538SAndroid Build Coastguard Worker                 GURL("https://foo.com"), url::PORT_UNSPECIFIED,
5879*6777b538SAndroid Build Coastguard Worker                 CookieSourceScheme::kSecure),
5880*6777b538SAndroid Build Coastguard Worker             CookieMonster::CookieSentToSamePort::kSourcePortUnspecified);
5881*6777b538SAndroid Build Coastguard Worker 
5882*6777b538SAndroid Build Coastguard Worker   // Test invalid.
5883*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(CookieMonster::IsCookieSentToSamePortThatSetIt(
5884*6777b538SAndroid Build Coastguard Worker                 GURL("https://foo.com"), url::PORT_INVALID,
5885*6777b538SAndroid Build Coastguard Worker                 CookieSourceScheme::kSecure),
5886*6777b538SAndroid Build Coastguard Worker             CookieMonster::CookieSentToSamePort::kInvalid);
5887*6777b538SAndroid Build Coastguard Worker 
5888*6777b538SAndroid Build Coastguard Worker   // Test same.
5889*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(CookieMonster::IsCookieSentToSamePortThatSetIt(
5890*6777b538SAndroid Build Coastguard Worker                 GURL("https://foo.com"), 443, CookieSourceScheme::kSecure),
5891*6777b538SAndroid Build Coastguard Worker             CookieMonster::CookieSentToSamePort::kYes);
5892*6777b538SAndroid Build Coastguard Worker 
5893*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(
5894*6777b538SAndroid Build Coastguard Worker       CookieMonster::IsCookieSentToSamePortThatSetIt(
5895*6777b538SAndroid Build Coastguard Worker           GURL("https://foo.com:1234"), 1234, CookieSourceScheme::kSecure),
5896*6777b538SAndroid Build Coastguard Worker       CookieMonster::CookieSentToSamePort::kYes);
5897*6777b538SAndroid Build Coastguard Worker 
5898*6777b538SAndroid Build Coastguard Worker   // Test different but default.
5899*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(CookieMonster::IsCookieSentToSamePortThatSetIt(
5900*6777b538SAndroid Build Coastguard Worker                 GURL("https://foo.com"), 80, CookieSourceScheme::kNonSecure),
5901*6777b538SAndroid Build Coastguard Worker             CookieMonster::CookieSentToSamePort::kNoButDefault);
5902*6777b538SAndroid Build Coastguard Worker 
5903*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(
5904*6777b538SAndroid Build Coastguard Worker       CookieMonster::IsCookieSentToSamePortThatSetIt(
5905*6777b538SAndroid Build Coastguard Worker           GURL("https://foo.com:443"), 80, CookieSourceScheme::kNonSecure),
5906*6777b538SAndroid Build Coastguard Worker       CookieMonster::CookieSentToSamePort::kNoButDefault);
5907*6777b538SAndroid Build Coastguard Worker 
5908*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(CookieMonster::IsCookieSentToSamePortThatSetIt(
5909*6777b538SAndroid Build Coastguard Worker                 GURL("wss://foo.com"), 80, CookieSourceScheme::kNonSecure),
5910*6777b538SAndroid Build Coastguard Worker             CookieMonster::CookieSentToSamePort::kNoButDefault);
5911*6777b538SAndroid Build Coastguard Worker 
5912*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(CookieMonster::IsCookieSentToSamePortThatSetIt(
5913*6777b538SAndroid Build Coastguard Worker                 GURL("http://foo.com"), 443, CookieSourceScheme::kSecure),
5914*6777b538SAndroid Build Coastguard Worker             CookieMonster::CookieSentToSamePort::kNoButDefault);
5915*6777b538SAndroid Build Coastguard Worker 
5916*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(CookieMonster::IsCookieSentToSamePortThatSetIt(
5917*6777b538SAndroid Build Coastguard Worker                 GURL("ws://foo.com"), 443, CookieSourceScheme::kSecure),
5918*6777b538SAndroid Build Coastguard Worker             CookieMonster::CookieSentToSamePort::kNoButDefault);
5919*6777b538SAndroid Build Coastguard Worker 
5920*6777b538SAndroid Build Coastguard Worker   // Test different.
5921*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(CookieMonster::IsCookieSentToSamePortThatSetIt(
5922*6777b538SAndroid Build Coastguard Worker                 GURL("http://foo.com:9000"), 85, CookieSourceScheme::kSecure),
5923*6777b538SAndroid Build Coastguard Worker             CookieMonster::CookieSentToSamePort::kNo);
5924*6777b538SAndroid Build Coastguard Worker 
5925*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(CookieMonster::IsCookieSentToSamePortThatSetIt(
5926*6777b538SAndroid Build Coastguard Worker                 GURL("https://foo.com"), 80, CookieSourceScheme::kSecure),
5927*6777b538SAndroid Build Coastguard Worker             CookieMonster::CookieSentToSamePort::kNo);
5928*6777b538SAndroid Build Coastguard Worker 
5929*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(CookieMonster::IsCookieSentToSamePortThatSetIt(
5930*6777b538SAndroid Build Coastguard Worker                 GURL("wss://foo.com"), 80, CookieSourceScheme::kSecure),
5931*6777b538SAndroid Build Coastguard Worker             CookieMonster::CookieSentToSamePort::kNo);
5932*6777b538SAndroid Build Coastguard Worker 
5933*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(CookieMonster::IsCookieSentToSamePortThatSetIt(
5934*6777b538SAndroid Build Coastguard Worker                 GURL("http://foo.com"), 443, CookieSourceScheme::kNonSecure),
5935*6777b538SAndroid Build Coastguard Worker             CookieMonster::CookieSentToSamePort::kNo);
5936*6777b538SAndroid Build Coastguard Worker 
5937*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(CookieMonster::IsCookieSentToSamePortThatSetIt(
5938*6777b538SAndroid Build Coastguard Worker                 GURL("ws://foo.com"), 443, CookieSourceScheme::kNonSecure),
5939*6777b538SAndroid Build Coastguard Worker             CookieMonster::CookieSentToSamePort::kNo);
5940*6777b538SAndroid Build Coastguard Worker 
5941*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(CookieMonster::IsCookieSentToSamePortThatSetIt(
5942*6777b538SAndroid Build Coastguard Worker                 GURL("http://foo.com:444"), 443, CookieSourceScheme::kSecure),
5943*6777b538SAndroid Build Coastguard Worker             CookieMonster::CookieSentToSamePort::kNo);
5944*6777b538SAndroid Build Coastguard Worker }
5945*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,CookieDomainSetHistogram)5946*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, CookieDomainSetHistogram) {
5947*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histograms;
5948*6777b538SAndroid Build Coastguard Worker   const char kHistogramName[] = "Cookie.DomainSet";
5949*6777b538SAndroid Build Coastguard Worker 
5950*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
5951*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
5952*6777b538SAndroid Build Coastguard Worker 
5953*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramName, 0);
5954*6777b538SAndroid Build Coastguard Worker 
5955*6777b538SAndroid Build Coastguard Worker   // Set a host only cookie (non-Domain).
5956*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), https_www_foo_.url(), "A=B"));
5957*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramName, 1);
5958*6777b538SAndroid Build Coastguard Worker   histograms.ExpectBucketCount(kHistogramName, false, 1);
5959*6777b538SAndroid Build Coastguard Worker 
5960*6777b538SAndroid Build Coastguard Worker   // Set a domain cookie.
5961*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), https_www_foo_.url(),
5962*6777b538SAndroid Build Coastguard Worker                         "A=B; Domain=" + https_www_foo_.host()));
5963*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramName, 2);
5964*6777b538SAndroid Build Coastguard Worker   histograms.ExpectBucketCount(kHistogramName, true, 1);
5965*6777b538SAndroid Build Coastguard Worker 
5966*6777b538SAndroid Build Coastguard Worker   // Invalid cookies don't count toward the histogram.
5967*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(
5968*6777b538SAndroid Build Coastguard Worker       SetCookie(cm.get(), https_www_foo_.url(), "A=B; Domain=other.com"));
5969*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramName, 2);
5970*6777b538SAndroid Build Coastguard Worker   histograms.ExpectBucketCount(kHistogramName, false, 1);
5971*6777b538SAndroid Build Coastguard Worker }
5972*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,CookiePortReadHistogram)5973*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, CookiePortReadHistogram) {
5974*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histograms;
5975*6777b538SAndroid Build Coastguard Worker   const char kHistogramName[] = "Cookie.Port.Read.RemoteHost";
5976*6777b538SAndroid Build Coastguard Worker   const char kHistogramNameLocal[] = "Cookie.Port.Read.Localhost";
5977*6777b538SAndroid Build Coastguard Worker 
5978*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
5979*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
5980*6777b538SAndroid Build Coastguard Worker 
5981*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramName, 0);
5982*6777b538SAndroid Build Coastguard Worker 
5983*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), GURL("https://www.foo.com"), "A=B"));
5984*6777b538SAndroid Build Coastguard Worker 
5985*6777b538SAndroid Build Coastguard Worker   // May as well check that it didn't change the histogram...
5986*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramName, 0);
5987*6777b538SAndroid Build Coastguard Worker 
5988*6777b538SAndroid Build Coastguard Worker   // Now read it from some different ports. This requires some knowledge of how
5989*6777b538SAndroid Build Coastguard Worker   // `ReducePortRangeForCookieHistogram` maps ports, but that's probably fine.
5990*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(GetCookies(cm.get(), GURL("https://www.foo.com")), "A=B");
5991*6777b538SAndroid Build Coastguard Worker   // https default is 443, so check that.
5992*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramName, 1);
5993*6777b538SAndroid Build Coastguard Worker   histograms.ExpectBucketCount(kHistogramName,
5994*6777b538SAndroid Build Coastguard Worker                                ReducePortRangeForCookieHistogram(443), 1);
5995*6777b538SAndroid Build Coastguard Worker 
5996*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(GetCookies(cm.get(), GURL("https://www.foo.com:82")), "A=B");
5997*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramName, 2);
5998*6777b538SAndroid Build Coastguard Worker   histograms.ExpectBucketCount(kHistogramName,
5999*6777b538SAndroid Build Coastguard Worker                                ReducePortRangeForCookieHistogram(82), 1);
6000*6777b538SAndroid Build Coastguard Worker 
6001*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(GetCookies(cm.get(), GURL("https://www.foo.com:8080")), "A=B");
6002*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramName, 3);
6003*6777b538SAndroid Build Coastguard Worker   histograms.ExpectBucketCount(kHistogramName,
6004*6777b538SAndroid Build Coastguard Worker                                ReducePortRangeForCookieHistogram(8080), 1);
6005*6777b538SAndroid Build Coastguard Worker 
6006*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(GetCookies(cm.get(), GURL("https://www.foo.com:1234")), "A=B");
6007*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramName, 4);
6008*6777b538SAndroid Build Coastguard Worker   histograms.ExpectBucketCount(kHistogramName,
6009*6777b538SAndroid Build Coastguard Worker                                ReducePortRangeForCookieHistogram(1234), 1);
6010*6777b538SAndroid Build Coastguard Worker 
6011*6777b538SAndroid Build Coastguard Worker   // Histogram should not increment if nothing is read.
6012*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(GetCookies(cm.get(), GURL("https://www.other.com")), "");
6013*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramName, 4);
6014*6777b538SAndroid Build Coastguard Worker 
6015*6777b538SAndroid Build Coastguard Worker   // Make sure the correct histogram is chosen for localhost.
6016*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), GURL("https://localhost"), "local=host"));
6017*6777b538SAndroid Build Coastguard Worker 
6018*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramNameLocal, 0);
6019*6777b538SAndroid Build Coastguard Worker 
6020*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(GetCookies(cm.get(), GURL("https://localhost:82")), "local=host");
6021*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramNameLocal, 1);
6022*6777b538SAndroid Build Coastguard Worker   histograms.ExpectBucketCount(kHistogramNameLocal,
6023*6777b538SAndroid Build Coastguard Worker                                ReducePortRangeForCookieHistogram(82), 1);
6024*6777b538SAndroid Build Coastguard Worker }
6025*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,CookiePortSetHistogram)6026*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, CookiePortSetHistogram) {
6027*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histograms;
6028*6777b538SAndroid Build Coastguard Worker   const char kHistogramName[] = "Cookie.Port.Set.RemoteHost";
6029*6777b538SAndroid Build Coastguard Worker   const char kHistogramNameLocal[] = "Cookie.Port.Set.Localhost";
6030*6777b538SAndroid Build Coastguard Worker 
6031*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
6032*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
6033*6777b538SAndroid Build Coastguard Worker 
6034*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramName, 0);
6035*6777b538SAndroid Build Coastguard Worker 
6036*6777b538SAndroid Build Coastguard Worker   // Set some cookies. This requires some knowledge of how
6037*6777b538SAndroid Build Coastguard Worker   // ReducePortRangeForCookieHistogram maps ports, but that's probably fine.
6038*6777b538SAndroid Build Coastguard Worker 
6039*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), GURL("https://www.foo.com"), "A=B"));
6040*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramName, 1);
6041*6777b538SAndroid Build Coastguard Worker   histograms.ExpectBucketCount(kHistogramName,
6042*6777b538SAndroid Build Coastguard Worker                                ReducePortRangeForCookieHistogram(443), 1);
6043*6777b538SAndroid Build Coastguard Worker 
6044*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), GURL("https://www.foo.com:80"), "A=B"));
6045*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramName, 2);
6046*6777b538SAndroid Build Coastguard Worker   histograms.ExpectBucketCount(kHistogramName,
6047*6777b538SAndroid Build Coastguard Worker                                ReducePortRangeForCookieHistogram(80), 1);
6048*6777b538SAndroid Build Coastguard Worker 
6049*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), GURL("https://www.foo.com:9000"), "A=B"));
6050*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramName, 3);
6051*6777b538SAndroid Build Coastguard Worker   histograms.ExpectBucketCount(kHistogramName,
6052*6777b538SAndroid Build Coastguard Worker                                ReducePortRangeForCookieHistogram(9000), 1);
6053*6777b538SAndroid Build Coastguard Worker 
6054*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), GURL("https://www.foo.com:1234"), "A=B"));
6055*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramName, 4);
6056*6777b538SAndroid Build Coastguard Worker   histograms.ExpectBucketCount(kHistogramName,
6057*6777b538SAndroid Build Coastguard Worker                                ReducePortRangeForCookieHistogram(1234), 1);
6058*6777b538SAndroid Build Coastguard Worker 
6059*6777b538SAndroid Build Coastguard Worker   // Histogram should not increment for invalid cookie.
6060*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(SetCookie(cm.get(), GURL("https://www.foo.com"),
6061*6777b538SAndroid Build Coastguard Worker                          "A=B; Domain=malformedcookie.com"));
6062*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramName, 4);
6063*6777b538SAndroid Build Coastguard Worker 
6064*6777b538SAndroid Build Coastguard Worker   // Nor should it increment for a read operation
6065*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(GetCookies(cm.get(), GURL("https://www.foo.com")), "");
6066*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramName, 4);
6067*6777b538SAndroid Build Coastguard Worker 
6068*6777b538SAndroid Build Coastguard Worker   // Make sure the correct histogram is chosen for localhost.
6069*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramNameLocal, 0);
6070*6777b538SAndroid Build Coastguard Worker 
6071*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
6072*6777b538SAndroid Build Coastguard Worker       SetCookie(cm.get(), GURL("https://localhost:1234"), "local=host"));
6073*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramNameLocal, 1);
6074*6777b538SAndroid Build Coastguard Worker   histograms.ExpectBucketCount(kHistogramNameLocal,
6075*6777b538SAndroid Build Coastguard Worker                                ReducePortRangeForCookieHistogram(1234), 1);
6076*6777b538SAndroid Build Coastguard Worker }
6077*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,CookiePortReadDiffersFromSetHistogram)6078*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, CookiePortReadDiffersFromSetHistogram) {
6079*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histograms;
6080*6777b538SAndroid Build Coastguard Worker   const char kHistogramName[] = "Cookie.Port.ReadDiffersFromSet.RemoteHost";
6081*6777b538SAndroid Build Coastguard Worker   const char kHistogramNameLocal[] = "Cookie.Port.ReadDiffersFromSet.Localhost";
6082*6777b538SAndroid Build Coastguard Worker   const char kHistogramNameDomainSet[] =
6083*6777b538SAndroid Build Coastguard Worker       "Cookie.Port.ReadDiffersFromSet.DomainSet";
6084*6777b538SAndroid Build Coastguard Worker 
6085*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
6086*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
6087*6777b538SAndroid Build Coastguard Worker 
6088*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramName, 0);
6089*6777b538SAndroid Build Coastguard Worker 
6090*6777b538SAndroid Build Coastguard Worker   // Set some cookies. One with a port, one without, and one with an invalid
6091*6777b538SAndroid Build Coastguard Worker   // port.
6092*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), GURL("https://www.foo.com/withport"),
6093*6777b538SAndroid Build Coastguard Worker                         "A=B; Path=/withport"));  // Port 443
6094*6777b538SAndroid Build Coastguard Worker 
6095*6777b538SAndroid Build Coastguard Worker   auto unspecified_cookie = CanonicalCookie::CreateForTesting(
6096*6777b538SAndroid Build Coastguard Worker       GURL("https://www.foo.com/withoutport"), "C=D; Path=/withoutport",
6097*6777b538SAndroid Build Coastguard Worker       base::Time::Now());
6098*6777b538SAndroid Build Coastguard Worker   // Force to be unspecified.
6099*6777b538SAndroid Build Coastguard Worker   unspecified_cookie->SetSourcePort(url::PORT_UNSPECIFIED);
6100*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCanonicalCookieReturnAccessResult(
6101*6777b538SAndroid Build Coastguard Worker                   cm.get(), std::move(unspecified_cookie),
6102*6777b538SAndroid Build Coastguard Worker                   GURL("https://www.foo.com/withoutport"),
6103*6777b538SAndroid Build Coastguard Worker                   false /*can_modify_httponly*/)
6104*6777b538SAndroid Build Coastguard Worker                   .status.IsInclude());
6105*6777b538SAndroid Build Coastguard Worker 
6106*6777b538SAndroid Build Coastguard Worker   auto invalid_cookie = CanonicalCookie::CreateForTesting(
6107*6777b538SAndroid Build Coastguard Worker       GURL("https://www.foo.com/invalidport"), "E=F; Path=/invalidport",
6108*6777b538SAndroid Build Coastguard Worker       base::Time::Now());
6109*6777b538SAndroid Build Coastguard Worker   // Force to be invalid.
6110*6777b538SAndroid Build Coastguard Worker   invalid_cookie->SetSourcePort(99999);
6111*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCanonicalCookieReturnAccessResult(
6112*6777b538SAndroid Build Coastguard Worker                   cm.get(), std::move(invalid_cookie),
6113*6777b538SAndroid Build Coastguard Worker                   GURL("https://www.foo.com/invalidport"),
6114*6777b538SAndroid Build Coastguard Worker                   false /*can_modify_httponly*/)
6115*6777b538SAndroid Build Coastguard Worker                   .status.IsInclude());
6116*6777b538SAndroid Build Coastguard Worker 
6117*6777b538SAndroid Build Coastguard Worker   // Try same port.
6118*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(GetCookies(cm.get(), GURL("https://www.foo.com/withport")), "A=B");
6119*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramName, 1);
6120*6777b538SAndroid Build Coastguard Worker   histograms.ExpectBucketCount(kHistogramName,
6121*6777b538SAndroid Build Coastguard Worker                                CookieMonster::CookieSentToSamePort::kYes, 1);
6122*6777b538SAndroid Build Coastguard Worker 
6123*6777b538SAndroid Build Coastguard Worker   // Try different port.
6124*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(GetCookies(cm.get(), GURL("https://www.foo.com:8080/withport")),
6125*6777b538SAndroid Build Coastguard Worker             "A=B");
6126*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramName, 2);
6127*6777b538SAndroid Build Coastguard Worker   histograms.ExpectBucketCount(kHistogramName,
6128*6777b538SAndroid Build Coastguard Worker                                CookieMonster::CookieSentToSamePort::kNo, 1);
6129*6777b538SAndroid Build Coastguard Worker 
6130*6777b538SAndroid Build Coastguard Worker   // Try different port, but it's the default for a different scheme.
6131*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(GetCookies(cm.get(), GURL("http://www.foo.com/withport")), "A=B");
6132*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramName, 3);
6133*6777b538SAndroid Build Coastguard Worker   histograms.ExpectBucketCount(
6134*6777b538SAndroid Build Coastguard Worker       kHistogramName, CookieMonster::CookieSentToSamePort::kNoButDefault, 1);
6135*6777b538SAndroid Build Coastguard Worker 
6136*6777b538SAndroid Build Coastguard Worker   // Now try it with an unspecified port cookie.
6137*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(GetCookies(cm.get(), GURL("http://www.foo.com/withoutport")),
6138*6777b538SAndroid Build Coastguard Worker             "C=D");
6139*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramName, 4);
6140*6777b538SAndroid Build Coastguard Worker   histograms.ExpectBucketCount(
6141*6777b538SAndroid Build Coastguard Worker       kHistogramName,
6142*6777b538SAndroid Build Coastguard Worker       CookieMonster::CookieSentToSamePort::kSourcePortUnspecified, 1);
6143*6777b538SAndroid Build Coastguard Worker 
6144*6777b538SAndroid Build Coastguard Worker   // Finally try it with an invalid port cookie.
6145*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(GetCookies(cm.get(), GURL("http://www.foo.com/invalidport")),
6146*6777b538SAndroid Build Coastguard Worker             "E=F");
6147*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramName, 5);
6148*6777b538SAndroid Build Coastguard Worker   histograms.ExpectBucketCount(
6149*6777b538SAndroid Build Coastguard Worker       kHistogramName, CookieMonster::CookieSentToSamePort::kInvalid, 1);
6150*6777b538SAndroid Build Coastguard Worker 
6151*6777b538SAndroid Build Coastguard Worker   // Make sure the correct histogram is chosen for localhost.
6152*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramNameLocal, 0);
6153*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), GURL("https://localhost"), "local=host"));
6154*6777b538SAndroid Build Coastguard Worker 
6155*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(GetCookies(cm.get(), GURL("https://localhost")), "local=host");
6156*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramNameLocal, 1);
6157*6777b538SAndroid Build Coastguard Worker   histograms.ExpectBucketCount(kHistogramNameLocal,
6158*6777b538SAndroid Build Coastguard Worker                                CookieMonster::CookieSentToSamePort::kYes, 1);
6159*6777b538SAndroid Build Coastguard Worker 
6160*6777b538SAndroid Build Coastguard Worker   // Make sure the Domain set version works.
6161*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCookie(cm.get(), GURL("https://www.foo.com/withDomain"),
6162*6777b538SAndroid Build Coastguard Worker                         "W=D; Domain=foo.com; Path=/withDomain"));
6163*6777b538SAndroid Build Coastguard Worker 
6164*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramNameDomainSet, 0);
6165*6777b538SAndroid Build Coastguard Worker 
6166*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(GetCookies(cm.get(), GURL("https://www.foo.com/withDomain")),
6167*6777b538SAndroid Build Coastguard Worker             "W=D");
6168*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramNameDomainSet, 1);
6169*6777b538SAndroid Build Coastguard Worker   histograms.ExpectBucketCount(kHistogramNameDomainSet,
6170*6777b538SAndroid Build Coastguard Worker                                CookieMonster::CookieSentToSamePort::kYes, 1);
6171*6777b538SAndroid Build Coastguard Worker   // The RemoteHost histogram should also increase with this cookie. Domain
6172*6777b538SAndroid Build Coastguard Worker   // cookies aren't special insofar as this metric is concerned.
6173*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramName, 6);
6174*6777b538SAndroid Build Coastguard Worker   histograms.ExpectBucketCount(kHistogramName,
6175*6777b538SAndroid Build Coastguard Worker                                CookieMonster::CookieSentToSamePort::kYes, 2);
6176*6777b538SAndroid Build Coastguard Worker }
6177*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,CookieSourceSchemeNameHistogram)6178*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, CookieSourceSchemeNameHistogram) {
6179*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histograms;
6180*6777b538SAndroid Build Coastguard Worker   const char kHistogramName[] = "Cookie.CookieSourceSchemeName";
6181*6777b538SAndroid Build Coastguard Worker 
6182*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
6183*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
6184*6777b538SAndroid Build Coastguard Worker 
6185*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramName, 0);
6186*6777b538SAndroid Build Coastguard Worker 
6187*6777b538SAndroid Build Coastguard Worker   struct TestCase {
6188*6777b538SAndroid Build Coastguard Worker     CookieSourceSchemeName enum_value;
6189*6777b538SAndroid Build Coastguard Worker     std::string scheme;
6190*6777b538SAndroid Build Coastguard Worker   };
6191*6777b538SAndroid Build Coastguard Worker 
6192*6777b538SAndroid Build Coastguard Worker   // Test the usual and a smattering of some other types including a kOther.
6193*6777b538SAndroid Build Coastguard Worker   // It doesn't matter if we add this to the scheme registry or not because we
6194*6777b538SAndroid Build Coastguard Worker   // don't actually need the whole url to parse, we just need GURL to pick up on
6195*6777b538SAndroid Build Coastguard Worker   // the scheme correctly (which it does). What the rest of the cookie code does
6196*6777b538SAndroid Build Coastguard Worker   // with the oddly formed GURL is out of scope of this test (i.e. we don't
6197*6777b538SAndroid Build Coastguard Worker   // care).
6198*6777b538SAndroid Build Coastguard Worker   const TestCase kTestCases[] = {
6199*6777b538SAndroid Build Coastguard Worker       {CookieSourceSchemeName::kHttpsScheme, url::kHttpsScheme},
6200*6777b538SAndroid Build Coastguard Worker       {CookieSourceSchemeName::kHttpScheme, url::kHttpScheme},
6201*6777b538SAndroid Build Coastguard Worker       {CookieSourceSchemeName::kWssScheme, url::kWssScheme},
6202*6777b538SAndroid Build Coastguard Worker       {CookieSourceSchemeName::kWsScheme, url::kWsScheme},
6203*6777b538SAndroid Build Coastguard Worker       {CookieSourceSchemeName::kChromeExtensionScheme, "chrome-extension"},
6204*6777b538SAndroid Build Coastguard Worker       {CookieSourceSchemeName::kFileScheme, url::kFileScheme},
6205*6777b538SAndroid Build Coastguard Worker       {CookieSourceSchemeName::kOther, "abcd1234"}};
6206*6777b538SAndroid Build Coastguard Worker 
6207*6777b538SAndroid Build Coastguard Worker   // Make sure all the schemes are considered cookieable.
6208*6777b538SAndroid Build Coastguard Worker   std::vector<std::string> schemes;
6209*6777b538SAndroid Build Coastguard Worker   for (auto test_case : kTestCases) {
6210*6777b538SAndroid Build Coastguard Worker     schemes.push_back(test_case.scheme);
6211*6777b538SAndroid Build Coastguard Worker   }
6212*6777b538SAndroid Build Coastguard Worker   ResultSavingCookieCallback<bool> cookie_scheme_callback;
6213*6777b538SAndroid Build Coastguard Worker   cm->SetCookieableSchemes(schemes, cookie_scheme_callback.MakeCallback());
6214*6777b538SAndroid Build Coastguard Worker   cookie_scheme_callback.WaitUntilDone();
6215*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(cookie_scheme_callback.result());
6216*6777b538SAndroid Build Coastguard Worker 
6217*6777b538SAndroid Build Coastguard Worker   const char kUrl[] = "://www.foo.com";
6218*6777b538SAndroid Build Coastguard Worker   int count = 0;
6219*6777b538SAndroid Build Coastguard Worker 
6220*6777b538SAndroid Build Coastguard Worker   // Test all the cases.
6221*6777b538SAndroid Build Coastguard Worker   for (auto test_case : kTestCases) {
6222*6777b538SAndroid Build Coastguard Worker     histograms.ExpectBucketCount(kHistogramName, test_case.enum_value, 0);
6223*6777b538SAndroid Build Coastguard Worker 
6224*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(SetCookie(cm.get(), GURL(test_case.scheme + kUrl), "A=B"));
6225*6777b538SAndroid Build Coastguard Worker 
6226*6777b538SAndroid Build Coastguard Worker     histograms.ExpectBucketCount(kHistogramName, test_case.enum_value, 1);
6227*6777b538SAndroid Build Coastguard Worker     histograms.ExpectTotalCount(kHistogramName, ++count);
6228*6777b538SAndroid Build Coastguard Worker   }
6229*6777b538SAndroid Build Coastguard Worker 
6230*6777b538SAndroid Build Coastguard Worker   // This metric is only for cookies that are actually set. Make sure the
6231*6777b538SAndroid Build Coastguard Worker   // histogram doesn't increment for cookies that fail to set.
6232*6777b538SAndroid Build Coastguard Worker 
6233*6777b538SAndroid Build Coastguard Worker   // Try to set an invalid cookie, for instance: a non-cookieable scheme will be
6234*6777b538SAndroid Build Coastguard Worker   // rejected.
6235*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(SetCookie(cm.get(), GURL("invalidscheme://foo.com"), "A=B"));
6236*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount(kHistogramName, count);
6237*6777b538SAndroid Build Coastguard Worker }
6238*6777b538SAndroid Build Coastguard Worker 
6239*6777b538SAndroid Build Coastguard Worker class FirstPartySetEnabledCookieMonsterTest : public CookieMonsterTest {
6240*6777b538SAndroid Build Coastguard Worker  public:
FirstPartySetEnabledCookieMonsterTest()6241*6777b538SAndroid Build Coastguard Worker   FirstPartySetEnabledCookieMonsterTest()
6242*6777b538SAndroid Build Coastguard Worker       : cm_(nullptr /* store */, nullptr /* netlog */
6243*6777b538SAndroid Build Coastguard Worker         ) {
6244*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<TestCookieAccessDelegate> access_delegate =
6245*6777b538SAndroid Build Coastguard Worker         std::make_unique<TestCookieAccessDelegate>();
6246*6777b538SAndroid Build Coastguard Worker     access_delegate_ = access_delegate.get();
6247*6777b538SAndroid Build Coastguard Worker     cm_.SetCookieAccessDelegate(std::move(access_delegate));
6248*6777b538SAndroid Build Coastguard Worker   }
6249*6777b538SAndroid Build Coastguard Worker 
6250*6777b538SAndroid Build Coastguard Worker   ~FirstPartySetEnabledCookieMonsterTest() override = default;
6251*6777b538SAndroid Build Coastguard Worker 
cm()6252*6777b538SAndroid Build Coastguard Worker   CookieMonster* cm() { return &cm_; }
6253*6777b538SAndroid Build Coastguard Worker 
6254*6777b538SAndroid Build Coastguard Worker  protected:
6255*6777b538SAndroid Build Coastguard Worker   CookieMonster cm_;
6256*6777b538SAndroid Build Coastguard Worker   raw_ptr<TestCookieAccessDelegate> access_delegate_;
6257*6777b538SAndroid Build Coastguard Worker };
6258*6777b538SAndroid Build Coastguard Worker 
TEST_F(FirstPartySetEnabledCookieMonsterTest,RecordsPeriodicFPSSizes)6259*6777b538SAndroid Build Coastguard Worker TEST_F(FirstPartySetEnabledCookieMonsterTest, RecordsPeriodicFPSSizes) {
6260*6777b538SAndroid Build Coastguard Worker   net::SchemefulSite owner1(GURL("https://owner1.test"));
6261*6777b538SAndroid Build Coastguard Worker   net::SchemefulSite owner2(GURL("https://owner2.test"));
6262*6777b538SAndroid Build Coastguard Worker   net::SchemefulSite member1(GURL("https://member1.test"));
6263*6777b538SAndroid Build Coastguard Worker   net::SchemefulSite member2(GURL("https://member2.test"));
6264*6777b538SAndroid Build Coastguard Worker   net::SchemefulSite member3(GURL("https://member3.test"));
6265*6777b538SAndroid Build Coastguard Worker   net::SchemefulSite member4(GURL("https://member4.test"));
6266*6777b538SAndroid Build Coastguard Worker 
6267*6777b538SAndroid Build Coastguard Worker   access_delegate_->SetFirstPartySets({
6268*6777b538SAndroid Build Coastguard Worker       {owner1,
6269*6777b538SAndroid Build Coastguard Worker        net::FirstPartySetEntry(owner1, net::SiteType::kPrimary, std::nullopt)},
6270*6777b538SAndroid Build Coastguard Worker       {member1, net::FirstPartySetEntry(owner1, net::SiteType::kAssociated, 0)},
6271*6777b538SAndroid Build Coastguard Worker       {member2, net::FirstPartySetEntry(owner1, net::SiteType::kAssociated, 1)},
6272*6777b538SAndroid Build Coastguard Worker       {owner2,
6273*6777b538SAndroid Build Coastguard Worker        net::FirstPartySetEntry(owner2, net::SiteType::kPrimary, std::nullopt)},
6274*6777b538SAndroid Build Coastguard Worker       {member3, net::FirstPartySetEntry(owner2, net::SiteType::kAssociated, 0)},
6275*6777b538SAndroid Build Coastguard Worker       {member4, net::FirstPartySetEntry(owner2, net::SiteType::kAssociated, 1)},
6276*6777b538SAndroid Build Coastguard Worker   });
6277*6777b538SAndroid Build Coastguard Worker 
6278*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(SetCookie(cm(), GURL("https://owner1.test"), kValidCookieLine));
6279*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(SetCookie(cm(), GURL("https://subdomain.member1.test"),
6280*6777b538SAndroid Build Coastguard Worker                         kValidCookieLine));
6281*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(SetCookie(cm(), GURL("https://member2.test"), kValidCookieLine));
6282*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(
6283*6777b538SAndroid Build Coastguard Worker       SetCookie(cm(), GURL("https://subdomain.owner2.test"), kValidCookieLine));
6284*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(SetCookie(cm(), GURL("https://member3.test"), kValidCookieLine));
6285*6777b538SAndroid Build Coastguard Worker   // No cookie set for member4.test.
6286*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(
6287*6777b538SAndroid Build Coastguard Worker       SetCookie(cm(), GURL("https://unrelated1.test"), kValidCookieLine));
6288*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(
6289*6777b538SAndroid Build Coastguard Worker       SetCookie(cm(), GURL("https://unrelated2.test"), kValidCookieLine));
6290*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(
6291*6777b538SAndroid Build Coastguard Worker       SetCookie(cm(), GURL("https://unrelated3.test"), kValidCookieLine));
6292*6777b538SAndroid Build Coastguard Worker 
6293*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histogram_tester;
6294*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cm()->DoRecordPeriodicStatsForTesting());
6295*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(histogram_tester.GetAllSamples("Cookie.PerFirstPartySetCount"),
6296*6777b538SAndroid Build Coastguard Worker               testing::ElementsAre(  //
6297*6777b538SAndroid Build Coastguard Worker                                      // owner2.test & member3.test
6298*6777b538SAndroid Build Coastguard Worker                   base::Bucket(2 /* min */, 1 /* samples */),
6299*6777b538SAndroid Build Coastguard Worker                   // owner1.test, member1.test, & member2.test
6300*6777b538SAndroid Build Coastguard Worker                   base::Bucket(3 /* min */, 1 /* samples */)));
6301*6777b538SAndroid Build Coastguard Worker }
6302*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,GetAllCookiesForURLNonce)6303*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, GetAllCookiesForURLNonce) {
6304*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
6305*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
6306*6777b538SAndroid Build Coastguard Worker   CookieOptions options = CookieOptions::MakeAllInclusive();
6307*6777b538SAndroid Build Coastguard Worker 
6308*6777b538SAndroid Build Coastguard Worker   auto anonymous_iframe_key = CookiePartitionKey::FromURLForTesting(
6309*6777b538SAndroid Build Coastguard Worker       GURL("https://anonymous-iframe.test"),
6310*6777b538SAndroid Build Coastguard Worker       CookiePartitionKey::AncestorChainBit::kCrossSite,
6311*6777b538SAndroid Build Coastguard Worker       base::UnguessableToken::Create());
6312*6777b538SAndroid Build Coastguard Worker 
6313*6777b538SAndroid Build Coastguard Worker   // Define cookies from outside an anonymous iframe:
6314*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookie(cm.get(), https_www_foo_.url(),
6315*6777b538SAndroid Build Coastguard Worker                                  "A=0; Secure; HttpOnly; Path=/;", options));
6316*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookie(cm.get(), https_www_foo_.url(),
6317*6777b538SAndroid Build Coastguard Worker                                  "__Host-B=0; Secure; HttpOnly; Path=/;",
6318*6777b538SAndroid Build Coastguard Worker                                  options));
6319*6777b538SAndroid Build Coastguard Worker 
6320*6777b538SAndroid Build Coastguard Worker   // Define cookies from inside an anonymous iframe:
6321*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookie(
6322*6777b538SAndroid Build Coastguard Worker       cm.get(), https_www_foo_.url(),
6323*6777b538SAndroid Build Coastguard Worker       "__Host-B=1; Secure; HttpOnly; Path=/; Partitioned", options,
6324*6777b538SAndroid Build Coastguard Worker       std::nullopt, std::nullopt, anonymous_iframe_key));
6325*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookie(
6326*6777b538SAndroid Build Coastguard Worker       cm.get(), https_www_foo_.url(),
6327*6777b538SAndroid Build Coastguard Worker       "__Host-C=0; Secure; HttpOnly; Path=/; Partitioned", options,
6328*6777b538SAndroid Build Coastguard Worker       std::nullopt, std::nullopt, anonymous_iframe_key));
6329*6777b538SAndroid Build Coastguard Worker 
6330*6777b538SAndroid Build Coastguard Worker   // Check cookies from outside the anonymous iframe:
6331*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(GetAllCookiesForURL(cm.get(), https_www_foo_.url()),
6332*6777b538SAndroid Build Coastguard Worker               ElementsAre(MatchesCookieNameValue("A", "0"),
6333*6777b538SAndroid Build Coastguard Worker                           MatchesCookieNameValue("__Host-B", "0")));
6334*6777b538SAndroid Build Coastguard Worker 
6335*6777b538SAndroid Build Coastguard Worker   // Check cookies from inside the anonymous iframe:
6336*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
6337*6777b538SAndroid Build Coastguard Worker       GetAllCookiesForURL(cm.get(), https_www_foo_.url(),
6338*6777b538SAndroid Build Coastguard Worker                           CookiePartitionKeyCollection(anonymous_iframe_key)),
6339*6777b538SAndroid Build Coastguard Worker       ElementsAre(MatchesCookieNameValue("__Host-B", "1"),
6340*6777b538SAndroid Build Coastguard Worker                   MatchesCookieNameValue("__Host-C", "0")));
6341*6777b538SAndroid Build Coastguard Worker }
6342*6777b538SAndroid Build Coastguard Worker 
TEST_F(CookieMonsterTest,SiteHasCookieInOtherPartition)6343*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, SiteHasCookieInOtherPartition) {
6344*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
6345*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
6346*6777b538SAndroid Build Coastguard Worker   CookieOptions options = CookieOptions::MakeAllInclusive();
6347*6777b538SAndroid Build Coastguard Worker 
6348*6777b538SAndroid Build Coastguard Worker   GURL url("https://subdomain.example.com/");
6349*6777b538SAndroid Build Coastguard Worker   net::SchemefulSite site(url);
6350*6777b538SAndroid Build Coastguard Worker   auto partition_key =
6351*6777b538SAndroid Build Coastguard Worker       CookiePartitionKey::FromURLForTesting(GURL("https://toplevelsite.com"));
6352*6777b538SAndroid Build Coastguard Worker 
6353*6777b538SAndroid Build Coastguard Worker   // At first it should return nullopt...
6354*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cm->SiteHasCookieInOtherPartition(site, partition_key));
6355*6777b538SAndroid Build Coastguard Worker 
6356*6777b538SAndroid Build Coastguard Worker   // ...until we load cookies for that domain.
6357*6777b538SAndroid Build Coastguard Worker   GetAllCookiesForURL(cm.get(), url,
6358*6777b538SAndroid Build Coastguard Worker                       CookiePartitionKeyCollection::ContainsAll());
6359*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cm->SiteHasCookieInOtherPartition(site, partition_key),
6360*6777b538SAndroid Build Coastguard Worker               testing::Optional(false));
6361*6777b538SAndroid Build Coastguard Worker 
6362*6777b538SAndroid Build Coastguard Worker   // Set partitioned cookie.
6363*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookie(
6364*6777b538SAndroid Build Coastguard Worker       cm.get(), url, "foo=bar; Secure; SameSite=None; Partitioned", options,
6365*6777b538SAndroid Build Coastguard Worker       std::nullopt, std::nullopt, partition_key));
6366*6777b538SAndroid Build Coastguard Worker 
6367*6777b538SAndroid Build Coastguard Worker   // Should return false with that cookie's partition key.
6368*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cm->SiteHasCookieInOtherPartition(site, partition_key),
6369*6777b538SAndroid Build Coastguard Worker               testing::Optional(false));
6370*6777b538SAndroid Build Coastguard Worker 
6371*6777b538SAndroid Build Coastguard Worker   auto other_partition_key = CookiePartitionKey::FromURLForTesting(
6372*6777b538SAndroid Build Coastguard Worker       GURL("https://nottoplevelsite.com"));
6373*6777b538SAndroid Build Coastguard Worker 
6374*6777b538SAndroid Build Coastguard Worker   // Should return true with another partition key.
6375*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cm->SiteHasCookieInOtherPartition(site, other_partition_key),
6376*6777b538SAndroid Build Coastguard Worker               testing::Optional(true));
6377*6777b538SAndroid Build Coastguard Worker 
6378*6777b538SAndroid Build Coastguard Worker   // Set a nonced partitioned cookie with a different partition key.
6379*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookie(
6380*6777b538SAndroid Build Coastguard Worker       cm.get(), url, "foo=bar; Secure; SameSite=None; Partitioned", options,
6381*6777b538SAndroid Build Coastguard Worker       std::nullopt, std::nullopt,
6382*6777b538SAndroid Build Coastguard Worker       CookiePartitionKey::FromURLForTesting(
6383*6777b538SAndroid Build Coastguard Worker           GURL("https://nottoplevelsite.com"),
6384*6777b538SAndroid Build Coastguard Worker           CookiePartitionKey::AncestorChainBit::kCrossSite,
6385*6777b538SAndroid Build Coastguard Worker           base::UnguessableToken::Create())));
6386*6777b538SAndroid Build Coastguard Worker 
6387*6777b538SAndroid Build Coastguard Worker   // Should still return false with the original partition key.
6388*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cm->SiteHasCookieInOtherPartition(site, partition_key),
6389*6777b538SAndroid Build Coastguard Worker               testing::Optional(false));
6390*6777b538SAndroid Build Coastguard Worker 
6391*6777b538SAndroid Build Coastguard Worker   // Set unpartitioned cookie.
6392*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CreateAndSetCookie(cm.get(), url,
6393*6777b538SAndroid Build Coastguard Worker                                  "bar=baz; Secure; SameSite=None;", options,
6394*6777b538SAndroid Build Coastguard Worker                                  std::nullopt, std::nullopt));
6395*6777b538SAndroid Build Coastguard Worker 
6396*6777b538SAndroid Build Coastguard Worker   // Should still return false with the original cookie's partition key. This
6397*6777b538SAndroid Build Coastguard Worker   // method only considers partitioned cookies.
6398*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cm->SiteHasCookieInOtherPartition(site, partition_key),
6399*6777b538SAndroid Build Coastguard Worker               testing::Optional(false));
6400*6777b538SAndroid Build Coastguard Worker 
6401*6777b538SAndroid Build Coastguard Worker   // Should return nullopt when the partition key is nullopt.
6402*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(
6403*6777b538SAndroid Build Coastguard Worker       cm->SiteHasCookieInOtherPartition(site, /*partition_key=*/std::nullopt));
6404*6777b538SAndroid Build Coastguard Worker }
6405*6777b538SAndroid Build Coastguard Worker 
6406*6777b538SAndroid Build Coastguard Worker // Test that domain cookies which shadow origin cookies are excluded when scheme
6407*6777b538SAndroid Build Coastguard Worker // binding is enabled.
TEST_F(CookieMonsterTest,FilterCookiesWithOptionsExcludeShadowingDomains)6408*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, FilterCookiesWithOptionsExcludeShadowingDomains) {
6409*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
6410*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
6411*6777b538SAndroid Build Coastguard Worker   base::Time creation_time = base::Time::Now();
6412*6777b538SAndroid Build Coastguard Worker   std::optional<base::Time> server_time = std::nullopt;
6413*6777b538SAndroid Build Coastguard Worker   CookieOptions options = CookieOptions::MakeAllInclusive();
6414*6777b538SAndroid Build Coastguard Worker   options.set_return_excluded_cookies();
6415*6777b538SAndroid Build Coastguard Worker 
6416*6777b538SAndroid Build Coastguard Worker   auto CookieListsMatch = [](const CookieAccessResultList& actual,
6417*6777b538SAndroid Build Coastguard Worker                              const CookieList& expected) {
6418*6777b538SAndroid Build Coastguard Worker     if (actual.size() != expected.size()) {
6419*6777b538SAndroid Build Coastguard Worker       return false;
6420*6777b538SAndroid Build Coastguard Worker     }
6421*6777b538SAndroid Build Coastguard Worker 
6422*6777b538SAndroid Build Coastguard Worker     for (size_t i = 0; i < actual.size(); i++) {
6423*6777b538SAndroid Build Coastguard Worker       if (!actual[i].cookie.IsEquivalent(expected[i])) {
6424*6777b538SAndroid Build Coastguard Worker         return false;
6425*6777b538SAndroid Build Coastguard Worker       }
6426*6777b538SAndroid Build Coastguard Worker     }
6427*6777b538SAndroid Build Coastguard Worker 
6428*6777b538SAndroid Build Coastguard Worker     return true;
6429*6777b538SAndroid Build Coastguard Worker   };
6430*6777b538SAndroid Build Coastguard Worker 
6431*6777b538SAndroid Build Coastguard Worker   // We only exclude shadowing domain cookies when scheme binding is enabled.
6432*6777b538SAndroid Build Coastguard Worker   base::test::ScopedFeatureList scoped_feature_list;
6433*6777b538SAndroid Build Coastguard Worker   scoped_feature_list.InitWithFeatures(
6434*6777b538SAndroid Build Coastguard Worker       {net::features::kEnableSchemeBoundCookies},
6435*6777b538SAndroid Build Coastguard Worker       {net::features::kEnablePortBoundCookies});
6436*6777b538SAndroid Build Coastguard Worker 
6437*6777b538SAndroid Build Coastguard Worker   std::vector<CanonicalCookie*> cookie_ptrs;
6438*6777b538SAndroid Build Coastguard Worker   CookieAccessResultList included;
6439*6777b538SAndroid Build Coastguard Worker   CookieAccessResultList excluded;
6440*6777b538SAndroid Build Coastguard Worker 
6441*6777b538SAndroid Build Coastguard Worker   auto reset = [&cookie_ptrs, &included, &excluded]() {
6442*6777b538SAndroid Build Coastguard Worker     cookie_ptrs.clear();
6443*6777b538SAndroid Build Coastguard Worker     included.clear();
6444*6777b538SAndroid Build Coastguard Worker     excluded.clear();
6445*6777b538SAndroid Build Coastguard Worker   };
6446*6777b538SAndroid Build Coastguard Worker 
6447*6777b538SAndroid Build Coastguard Worker   auto origin_cookie1 = CanonicalCookie::CreateForTesting(
6448*6777b538SAndroid Build Coastguard Worker       https_www_foo_.url(), "foo1=origin", creation_time, server_time);
6449*6777b538SAndroid Build Coastguard Worker   auto origin_cookie2 = CanonicalCookie::CreateForTesting(
6450*6777b538SAndroid Build Coastguard Worker       https_www_foo_.url(), "foo2=origin", creation_time, server_time);
6451*6777b538SAndroid Build Coastguard Worker 
6452*6777b538SAndroid Build Coastguard Worker   auto domain_cookie1 = CanonicalCookie::CreateForTesting(
6453*6777b538SAndroid Build Coastguard Worker       https_www_foo_.url(), "foo1=domain; Domain=" + https_www_foo_.domain(),
6454*6777b538SAndroid Build Coastguard Worker       creation_time, server_time);
6455*6777b538SAndroid Build Coastguard Worker 
6456*6777b538SAndroid Build Coastguard Worker   // Shadowing domain cookie after the origin cookie.
6457*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {origin_cookie1.get(), origin_cookie2.get(),
6458*6777b538SAndroid Build Coastguard Worker                  domain_cookie1.get()};
6459*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(https_www_foo_.url(), options, &cookie_ptrs,
6460*6777b538SAndroid Build Coastguard Worker                                &included, &excluded);
6461*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(included, {*origin_cookie1, *origin_cookie2}));
6462*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(excluded, {*domain_cookie1}));
6463*6777b538SAndroid Build Coastguard Worker   reset();
6464*6777b538SAndroid Build Coastguard Worker 
6465*6777b538SAndroid Build Coastguard Worker   // Shadowing domain cookie before the origin cookie.
6466*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {domain_cookie1.get(), origin_cookie2.get(),
6467*6777b538SAndroid Build Coastguard Worker                  origin_cookie1.get()};
6468*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(https_www_foo_.url(), options, &cookie_ptrs,
6469*6777b538SAndroid Build Coastguard Worker                                &included, &excluded);
6470*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(included, {*origin_cookie2, *origin_cookie1}));
6471*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(excluded, {*domain_cookie1}));
6472*6777b538SAndroid Build Coastguard Worker   reset();
6473*6777b538SAndroid Build Coastguard Worker 
6474*6777b538SAndroid Build Coastguard Worker   auto domain_cookie2 = CanonicalCookie::CreateForTesting(
6475*6777b538SAndroid Build Coastguard Worker       https_www_foo_.url(), "foo2=domain; Domain=" + https_www_foo_.domain(),
6476*6777b538SAndroid Build Coastguard Worker       creation_time, server_time);
6477*6777b538SAndroid Build Coastguard Worker 
6478*6777b538SAndroid Build Coastguard Worker   // Multiple different shadowing domain cookies.
6479*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {domain_cookie1.get(), origin_cookie2.get(),
6480*6777b538SAndroid Build Coastguard Worker                  origin_cookie1.get(), domain_cookie2.get()};
6481*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(https_www_foo_.url(), options, &cookie_ptrs,
6482*6777b538SAndroid Build Coastguard Worker                                &included, &excluded);
6483*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(included, {*origin_cookie2, *origin_cookie1}));
6484*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(excluded, {*domain_cookie1, *domain_cookie2}));
6485*6777b538SAndroid Build Coastguard Worker   reset();
6486*6777b538SAndroid Build Coastguard Worker 
6487*6777b538SAndroid Build Coastguard Worker   auto domain_cookie3 = CanonicalCookie::CreateForTesting(
6488*6777b538SAndroid Build Coastguard Worker       https_www_foo_.url(), "foo3=domain; Domain=" + https_www_foo_.domain(),
6489*6777b538SAndroid Build Coastguard Worker       creation_time, server_time);
6490*6777b538SAndroid Build Coastguard Worker 
6491*6777b538SAndroid Build Coastguard Worker   // Non-shadowing domain cookie should be included.
6492*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {domain_cookie1.get(), origin_cookie2.get(),
6493*6777b538SAndroid Build Coastguard Worker                  origin_cookie1.get(), domain_cookie2.get(),
6494*6777b538SAndroid Build Coastguard Worker                  domain_cookie3.get()};
6495*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(https_www_foo_.url(), options, &cookie_ptrs,
6496*6777b538SAndroid Build Coastguard Worker                                &included, &excluded);
6497*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(
6498*6777b538SAndroid Build Coastguard Worker       included, {*origin_cookie2, *origin_cookie1, *domain_cookie3}));
6499*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(excluded, {*domain_cookie1, *domain_cookie2}));
6500*6777b538SAndroid Build Coastguard Worker   reset();
6501*6777b538SAndroid Build Coastguard Worker 
6502*6777b538SAndroid Build Coastguard Worker   auto sub_domain_cookie1 = CanonicalCookie::CreateForTesting(
6503*6777b538SAndroid Build Coastguard Worker       https_www_foo_.url(), "foo1=subdomain; Domain=" + https_www_foo_.host(),
6504*6777b538SAndroid Build Coastguard Worker       creation_time, server_time);
6505*6777b538SAndroid Build Coastguard Worker 
6506*6777b538SAndroid Build Coastguard Worker   // If there are multiple domain cookies that shadow the same cookie, they
6507*6777b538SAndroid Build Coastguard Worker   // should all be excluded.
6508*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {domain_cookie1.get(), origin_cookie2.get(),
6509*6777b538SAndroid Build Coastguard Worker                  origin_cookie1.get(), sub_domain_cookie1.get()};
6510*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(https_www_foo_.url(), options, &cookie_ptrs,
6511*6777b538SAndroid Build Coastguard Worker                                &included, &excluded);
6512*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(included, {*origin_cookie2, *origin_cookie1}));
6513*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
6514*6777b538SAndroid Build Coastguard Worker       CookieListsMatch(excluded, {*domain_cookie1, *sub_domain_cookie1}));
6515*6777b538SAndroid Build Coastguard Worker   reset();
6516*6777b538SAndroid Build Coastguard Worker 
6517*6777b538SAndroid Build Coastguard Worker   // Domain cookies may shadow each other.
6518*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {domain_cookie1.get(), sub_domain_cookie1.get()};
6519*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(https_www_foo_.url(), options, &cookie_ptrs,
6520*6777b538SAndroid Build Coastguard Worker                                &included, &excluded);
6521*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
6522*6777b538SAndroid Build Coastguard Worker       CookieListsMatch(included, {*domain_cookie1, *sub_domain_cookie1}));
6523*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(excluded, {}));
6524*6777b538SAndroid Build Coastguard Worker   reset();
6525*6777b538SAndroid Build Coastguard Worker 
6526*6777b538SAndroid Build Coastguard Worker   auto path_origin_cookie1 = CanonicalCookie::CreateForTesting(
6527*6777b538SAndroid Build Coastguard Worker       https_www_foo_.url(), "foo1=pathorigin; Path=/bar", creation_time,
6528*6777b538SAndroid Build Coastguard Worker       server_time);
6529*6777b538SAndroid Build Coastguard Worker 
6530*6777b538SAndroid Build Coastguard Worker   // Origin cookies on different paths may not be shadowed, even if the
6531*6777b538SAndroid Build Coastguard Worker   // origin cookie wouldn't be included on this request.
6532*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {path_origin_cookie1.get(), domain_cookie1.get()};
6533*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(https_www_foo_.url(), options, &cookie_ptrs,
6534*6777b538SAndroid Build Coastguard Worker                                &included, &excluded);
6535*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(included, {}));
6536*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
6537*6777b538SAndroid Build Coastguard Worker       CookieListsMatch(excluded, {*path_origin_cookie1, *domain_cookie1}));
6538*6777b538SAndroid Build Coastguard Worker   reset();
6539*6777b538SAndroid Build Coastguard Worker 
6540*6777b538SAndroid Build Coastguard Worker   auto insecure_origin_cookie1 = CanonicalCookie::CreateForTesting(
6541*6777b538SAndroid Build Coastguard Worker       http_www_foo_.url(), "foo1=insecureorigin", creation_time, server_time);
6542*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(insecure_origin_cookie1->SourceScheme(),
6543*6777b538SAndroid Build Coastguard Worker             CookieSourceScheme::kNonSecure);
6544*6777b538SAndroid Build Coastguard Worker 
6545*6777b538SAndroid Build Coastguard Worker   // Origin cookies that are excluded due to scheme binding don't affect domain
6546*6777b538SAndroid Build Coastguard Worker   // cookies.
6547*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {insecure_origin_cookie1.get(), domain_cookie1.get()};
6548*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(https_www_foo_.url(), options, &cookie_ptrs,
6549*6777b538SAndroid Build Coastguard Worker                                &included, &excluded);
6550*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(included, {*domain_cookie1}));
6551*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(excluded, {*insecure_origin_cookie1}));
6552*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
6553*6777b538SAndroid Build Coastguard Worker       excluded[0].access_result.status.HasExactlyExclusionReasonsForTesting(
6554*6777b538SAndroid Build Coastguard Worker           {CookieInclusionStatus::EXCLUDE_SCHEME_MISMATCH}));
6555*6777b538SAndroid Build Coastguard Worker   reset();
6556*6777b538SAndroid Build Coastguard Worker 
6557*6777b538SAndroid Build Coastguard Worker   auto insecure_domain_cookie1 = CanonicalCookie::CreateForTesting(
6558*6777b538SAndroid Build Coastguard Worker       http_www_foo_.url(),
6559*6777b538SAndroid Build Coastguard Worker       "foo1=insecuredomain; Domain=" + http_www_foo_.domain(), creation_time,
6560*6777b538SAndroid Build Coastguard Worker       server_time);
6561*6777b538SAndroid Build Coastguard Worker 
6562*6777b538SAndroid Build Coastguard Worker   // Domain cookies that are excluded due to scheme binding shouldn't also be
6563*6777b538SAndroid Build Coastguard Worker   // exclude because of shadowing.
6564*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {origin_cookie1.get(), insecure_domain_cookie1.get()};
6565*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(https_www_foo_.url(), options, &cookie_ptrs,
6566*6777b538SAndroid Build Coastguard Worker                                &included, &excluded);
6567*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(included, {*origin_cookie1}));
6568*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(excluded, {*insecure_domain_cookie1}));
6569*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
6570*6777b538SAndroid Build Coastguard Worker       excluded[0].access_result.status.HasExactlyExclusionReasonsForTesting(
6571*6777b538SAndroid Build Coastguard Worker           {CookieInclusionStatus::EXCLUDE_SCHEME_MISMATCH}));
6572*6777b538SAndroid Build Coastguard Worker   reset();
6573*6777b538SAndroid Build Coastguard Worker 
6574*6777b538SAndroid Build Coastguard Worker   // If both domain and origin cookie are excluded due to scheme binding then
6575*6777b538SAndroid Build Coastguard Worker   // domain cookie shouldn't get shadowing exclusion.
6576*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {insecure_origin_cookie1.get(), insecure_domain_cookie1.get()};
6577*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(https_www_foo_.url(), options, &cookie_ptrs,
6578*6777b538SAndroid Build Coastguard Worker                                &included, &excluded);
6579*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(included, {}));
6580*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(
6581*6777b538SAndroid Build Coastguard Worker       excluded, {*insecure_origin_cookie1, *insecure_domain_cookie1}));
6582*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
6583*6777b538SAndroid Build Coastguard Worker       excluded[1].access_result.status.HasExactlyExclusionReasonsForTesting(
6584*6777b538SAndroid Build Coastguard Worker           {CookieInclusionStatus::EXCLUDE_SCHEME_MISMATCH}));
6585*6777b538SAndroid Build Coastguard Worker   reset();
6586*6777b538SAndroid Build Coastguard Worker 
6587*6777b538SAndroid Build Coastguard Worker   cm->SetCookieAccessDelegate(std::make_unique<TestCookieAccessDelegate>());
6588*6777b538SAndroid Build Coastguard Worker 
6589*6777b538SAndroid Build Coastguard Worker   CookieURLHelper http_www_trustworthy =
6590*6777b538SAndroid Build Coastguard Worker       CookieURLHelper("http://www.trustworthysitefortestdelegate.example");
6591*6777b538SAndroid Build Coastguard Worker   CookieURLHelper https_www_trustworthy =
6592*6777b538SAndroid Build Coastguard Worker       CookieURLHelper("https://www.trustworthysitefortestdelegate.example");
6593*6777b538SAndroid Build Coastguard Worker 
6594*6777b538SAndroid Build Coastguard Worker   auto trust_origin_cookie1 = CanonicalCookie::CreateForTesting(
6595*6777b538SAndroid Build Coastguard Worker       http_www_trustworthy.url(), "foo1=trustorigin", creation_time,
6596*6777b538SAndroid Build Coastguard Worker       server_time);
6597*6777b538SAndroid Build Coastguard Worker 
6598*6777b538SAndroid Build Coastguard Worker   auto secure_trust_domain_cookie1 = CanonicalCookie::CreateForTesting(
6599*6777b538SAndroid Build Coastguard Worker       https_www_trustworthy.url(),
6600*6777b538SAndroid Build Coastguard Worker       "foo1=securetrustdomain; Domain=" + https_www_trustworthy.domain(),
6601*6777b538SAndroid Build Coastguard Worker       creation_time, server_time);
6602*6777b538SAndroid Build Coastguard Worker   auto secure_trust_domain_cookie2 = CanonicalCookie::CreateForTesting(
6603*6777b538SAndroid Build Coastguard Worker       https_www_trustworthy.url(),
6604*6777b538SAndroid Build Coastguard Worker       "foo2=securetrustdomain; Domain=" + https_www_trustworthy.domain(),
6605*6777b538SAndroid Build Coastguard Worker       creation_time, server_time);
6606*6777b538SAndroid Build Coastguard Worker 
6607*6777b538SAndroid Build Coastguard Worker   // Securely set domain cookies are excluded when shadowing trustworthy-ly set
6608*6777b538SAndroid Build Coastguard Worker   // origin cookies.
6609*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {trust_origin_cookie1.get(), secure_trust_domain_cookie1.get(),
6610*6777b538SAndroid Build Coastguard Worker                  secure_trust_domain_cookie2.get()};
6611*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(http_www_trustworthy.url(), options,
6612*6777b538SAndroid Build Coastguard Worker                                &cookie_ptrs, &included, &excluded);
6613*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(
6614*6777b538SAndroid Build Coastguard Worker       included, {*trust_origin_cookie1, *secure_trust_domain_cookie2}));
6615*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(excluded, {*secure_trust_domain_cookie1}));
6616*6777b538SAndroid Build Coastguard Worker   reset();
6617*6777b538SAndroid Build Coastguard Worker 
6618*6777b538SAndroid Build Coastguard Worker   auto trust_domain_cookie1 = CanonicalCookie::CreateForTesting(
6619*6777b538SAndroid Build Coastguard Worker       http_www_trustworthy.url(),
6620*6777b538SAndroid Build Coastguard Worker       "foo1=trustdomain; Domain=" + http_www_trustworthy.domain(),
6621*6777b538SAndroid Build Coastguard Worker       creation_time, server_time);
6622*6777b538SAndroid Build Coastguard Worker   auto trust_domain_cookie2 = CanonicalCookie::CreateForTesting(
6623*6777b538SAndroid Build Coastguard Worker       http_www_trustworthy.url(),
6624*6777b538SAndroid Build Coastguard Worker       "foo2=trustdomain; Domain=" + http_www_trustworthy.domain(),
6625*6777b538SAndroid Build Coastguard Worker       creation_time, server_time);
6626*6777b538SAndroid Build Coastguard Worker   auto secure_trust_origin_cookie1 = CanonicalCookie::CreateForTesting(
6627*6777b538SAndroid Build Coastguard Worker       https_www_trustworthy.url(), "foo1=securetrustorigin", creation_time,
6628*6777b538SAndroid Build Coastguard Worker       server_time);
6629*6777b538SAndroid Build Coastguard Worker 
6630*6777b538SAndroid Build Coastguard Worker   // Trustworthy-ly set domain cookies are excluded when shadowing securely set
6631*6777b538SAndroid Build Coastguard Worker   // origin cookies.
6632*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {secure_trust_origin_cookie1.get(), trust_domain_cookie1.get(),
6633*6777b538SAndroid Build Coastguard Worker                  trust_domain_cookie2.get()};
6634*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(http_www_trustworthy.url(), options,
6635*6777b538SAndroid Build Coastguard Worker                                &cookie_ptrs, &included, &excluded);
6636*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(
6637*6777b538SAndroid Build Coastguard Worker       included, {*secure_trust_origin_cookie1, *trust_domain_cookie2}));
6638*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(excluded, {*trust_domain_cookie1}));
6639*6777b538SAndroid Build Coastguard Worker   reset();
6640*6777b538SAndroid Build Coastguard Worker 
6641*6777b538SAndroid Build Coastguard Worker   auto port_origin_cookie1 = CanonicalCookie::CreateForTesting(
6642*6777b538SAndroid Build Coastguard Worker       https_www_foo_.url(), "foo1=differentportorigin", creation_time,
6643*6777b538SAndroid Build Coastguard Worker       server_time);
6644*6777b538SAndroid Build Coastguard Worker   port_origin_cookie1->SetSourcePort(123);
6645*6777b538SAndroid Build Coastguard Worker 
6646*6777b538SAndroid Build Coastguard Worker   // Origin cookies that have warnings due to port binding don't affect domain
6647*6777b538SAndroid Build Coastguard Worker   // cookies.
6648*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {port_origin_cookie1.get(), domain_cookie1.get()};
6649*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(https_www_foo_.url(), options, &cookie_ptrs,
6650*6777b538SAndroid Build Coastguard Worker                                &included, &excluded);
6651*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
6652*6777b538SAndroid Build Coastguard Worker       CookieListsMatch(included, {*port_origin_cookie1, *domain_cookie1}));
6653*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(included[0].access_result.status.HasWarningReason(
6654*6777b538SAndroid Build Coastguard Worker       CookieInclusionStatus::WARN_PORT_MISMATCH));
6655*6777b538SAndroid Build Coastguard Worker   reset();
6656*6777b538SAndroid Build Coastguard Worker 
6657*6777b538SAndroid Build Coastguard Worker   auto port_insecure_origin_cookie1 =
6658*6777b538SAndroid Build Coastguard Worker       std::make_unique<CanonicalCookie>(*insecure_origin_cookie1);
6659*6777b538SAndroid Build Coastguard Worker   port_insecure_origin_cookie1->SetSourcePort(123);
6660*6777b538SAndroid Build Coastguard Worker 
6661*6777b538SAndroid Build Coastguard Worker   // Origin cookies that have excluded due to scheme binding and have a port
6662*6777b538SAndroid Build Coastguard Worker   // binding warning don't affect domain cookies.
6663*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {port_insecure_origin_cookie1.get(), domain_cookie1.get()};
6664*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(https_www_foo_.url(), options, &cookie_ptrs,
6665*6777b538SAndroid Build Coastguard Worker                                &included, &excluded);
6666*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(included, {*domain_cookie1}));
6667*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
6668*6777b538SAndroid Build Coastguard Worker       excluded[0].access_result.status.HasExactlyWarningReasonsForTesting(
6669*6777b538SAndroid Build Coastguard Worker           {CookieInclusionStatus::WARN_PORT_MISMATCH}));
6670*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
6671*6777b538SAndroid Build Coastguard Worker       excluded[0].access_result.status.HasExactlyExclusionReasonsForTesting(
6672*6777b538SAndroid Build Coastguard Worker           {CookieInclusionStatus::EXCLUDE_SCHEME_MISMATCH}));
6673*6777b538SAndroid Build Coastguard Worker   reset();
6674*6777b538SAndroid Build Coastguard Worker 
6675*6777b538SAndroid Build Coastguard Worker   // Enable port binding to test with port exclusions.
6676*6777b538SAndroid Build Coastguard Worker   scoped_feature_list.Reset();
6677*6777b538SAndroid Build Coastguard Worker   scoped_feature_list.InitWithFeatures(
6678*6777b538SAndroid Build Coastguard Worker       {net::features::kEnableSchemeBoundCookies,
6679*6777b538SAndroid Build Coastguard Worker        net::features::kEnablePortBoundCookies},
6680*6777b538SAndroid Build Coastguard Worker       {});
6681*6777b538SAndroid Build Coastguard Worker 
6682*6777b538SAndroid Build Coastguard Worker   // Origin cookies that are excluded due to port binding don't affect domain
6683*6777b538SAndroid Build Coastguard Worker   // cookies.
6684*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {port_origin_cookie1.get(), domain_cookie1.get()};
6685*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(https_www_foo_.url(), options, &cookie_ptrs,
6686*6777b538SAndroid Build Coastguard Worker                                &included, &excluded);
6687*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(included, {*domain_cookie1}));
6688*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(excluded, {*port_origin_cookie1}));
6689*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
6690*6777b538SAndroid Build Coastguard Worker       excluded[0].access_result.status.HasExactlyExclusionReasonsForTesting(
6691*6777b538SAndroid Build Coastguard Worker           {CookieInclusionStatus::EXCLUDE_PORT_MISMATCH}));
6692*6777b538SAndroid Build Coastguard Worker   reset();
6693*6777b538SAndroid Build Coastguard Worker 
6694*6777b538SAndroid Build Coastguard Worker   // Origin cookies that are excluded due to scheme and port binding don't
6695*6777b538SAndroid Build Coastguard Worker   // affect domain cookies.
6696*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {port_insecure_origin_cookie1.get(), domain_cookie1.get()};
6697*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(https_www_foo_.url(), options, &cookie_ptrs,
6698*6777b538SAndroid Build Coastguard Worker                                &included, &excluded);
6699*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(included, {*domain_cookie1}));
6700*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(excluded, {*port_insecure_origin_cookie1}));
6701*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
6702*6777b538SAndroid Build Coastguard Worker       excluded[0].access_result.status.HasExactlyExclusionReasonsForTesting(
6703*6777b538SAndroid Build Coastguard Worker           {CookieInclusionStatus::EXCLUDE_SCHEME_MISMATCH,
6704*6777b538SAndroid Build Coastguard Worker            CookieInclusionStatus::EXCLUDE_PORT_MISMATCH}));
6705*6777b538SAndroid Build Coastguard Worker   reset();
6706*6777b538SAndroid Build Coastguard Worker }
6707*6777b538SAndroid Build Coastguard Worker 
6708*6777b538SAndroid Build Coastguard Worker // Test that domain cookies which shadow origin cookies have warnings when
6709*6777b538SAndroid Build Coastguard Worker // scheme binding is disabled.
TEST_F(CookieMonsterTest,FilterCookiesWithOptionsWarnShadowingDomains)6710*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, FilterCookiesWithOptionsWarnShadowingDomains) {
6711*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
6712*6777b538SAndroid Build Coastguard Worker   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
6713*6777b538SAndroid Build Coastguard Worker   base::Time creation_time = base::Time::Now();
6714*6777b538SAndroid Build Coastguard Worker   std::optional<base::Time> server_time = std::nullopt;
6715*6777b538SAndroid Build Coastguard Worker   CookieOptions options = CookieOptions::MakeAllInclusive();
6716*6777b538SAndroid Build Coastguard Worker   options.set_return_excluded_cookies();
6717*6777b538SAndroid Build Coastguard Worker 
6718*6777b538SAndroid Build Coastguard Worker   auto CookieListsMatch = [](const CookieAccessResultList& actual,
6719*6777b538SAndroid Build Coastguard Worker                              const std::vector<CanonicalCookie*>& expected) {
6720*6777b538SAndroid Build Coastguard Worker     if (actual.size() != expected.size()) {
6721*6777b538SAndroid Build Coastguard Worker       return false;
6722*6777b538SAndroid Build Coastguard Worker     }
6723*6777b538SAndroid Build Coastguard Worker 
6724*6777b538SAndroid Build Coastguard Worker     for (size_t i = 0; i < actual.size(); i++) {
6725*6777b538SAndroid Build Coastguard Worker       if (!actual[i].cookie.IsEquivalent(*expected[i])) {
6726*6777b538SAndroid Build Coastguard Worker         return false;
6727*6777b538SAndroid Build Coastguard Worker       }
6728*6777b538SAndroid Build Coastguard Worker     }
6729*6777b538SAndroid Build Coastguard Worker 
6730*6777b538SAndroid Build Coastguard Worker     return true;
6731*6777b538SAndroid Build Coastguard Worker   };
6732*6777b538SAndroid Build Coastguard Worker 
6733*6777b538SAndroid Build Coastguard Worker   // Confirms that of all the cookies in `actual` only the ones also in
6734*6777b538SAndroid Build Coastguard Worker   // `expected` have WARN_SHADOWING_DOMAIN.
6735*6777b538SAndroid Build Coastguard Worker   auto DomainCookiesHaveWarnings =
6736*6777b538SAndroid Build Coastguard Worker       [](const CookieAccessResultList& actual,
6737*6777b538SAndroid Build Coastguard Worker          const std::vector<CanonicalCookie>& expected) {
6738*6777b538SAndroid Build Coastguard Worker         std::map<CanonicalCookie, CookieInclusionStatus> cookie_result_map;
6739*6777b538SAndroid Build Coastguard Worker         for (const auto& cookie_result : actual) {
6740*6777b538SAndroid Build Coastguard Worker           cookie_result_map.insert(
6741*6777b538SAndroid Build Coastguard Worker               {cookie_result.cookie, cookie_result.access_result.status});
6742*6777b538SAndroid Build Coastguard Worker         }
6743*6777b538SAndroid Build Coastguard Worker 
6744*6777b538SAndroid Build Coastguard Worker         for (const auto& cookie : expected) {
6745*6777b538SAndroid Build Coastguard Worker           // This is a touch hacky but will always work because if the
6746*6777b538SAndroid Build Coastguard Worker           // cookie_result_map doesn't contain `cookie` it'll create a default
6747*6777b538SAndroid Build Coastguard Worker           // entry with an empty status which will always fail the check. I.e.:
6748*6777b538SAndroid Build Coastguard Worker           // return false.
6749*6777b538SAndroid Build Coastguard Worker           if (!cookie_result_map[cookie].HasWarningReason(
6750*6777b538SAndroid Build Coastguard Worker                   CookieInclusionStatus::WARN_SHADOWING_DOMAIN)) {
6751*6777b538SAndroid Build Coastguard Worker             return false;
6752*6777b538SAndroid Build Coastguard Worker           }
6753*6777b538SAndroid Build Coastguard Worker 
6754*6777b538SAndroid Build Coastguard Worker           // Remove cookies that were part of `expected`.
6755*6777b538SAndroid Build Coastguard Worker           cookie_result_map.erase(cookie);
6756*6777b538SAndroid Build Coastguard Worker         }
6757*6777b538SAndroid Build Coastguard Worker 
6758*6777b538SAndroid Build Coastguard Worker         // If any of the remaining cookies have the warning, return false.
6759*6777b538SAndroid Build Coastguard Worker         for (const auto& item : cookie_result_map) {
6760*6777b538SAndroid Build Coastguard Worker           if (item.second.HasWarningReason(
6761*6777b538SAndroid Build Coastguard Worker                   CookieInclusionStatus::WARN_SHADOWING_DOMAIN)) {
6762*6777b538SAndroid Build Coastguard Worker             return false;
6763*6777b538SAndroid Build Coastguard Worker           }
6764*6777b538SAndroid Build Coastguard Worker         }
6765*6777b538SAndroid Build Coastguard Worker 
6766*6777b538SAndroid Build Coastguard Worker         return true;
6767*6777b538SAndroid Build Coastguard Worker       };
6768*6777b538SAndroid Build Coastguard Worker 
6769*6777b538SAndroid Build Coastguard Worker   // We only apply warnings to shadowing domain cookies when scheme binding is
6770*6777b538SAndroid Build Coastguard Worker   // disabled.
6771*6777b538SAndroid Build Coastguard Worker   base::test::ScopedFeatureList scoped_feature_list;
6772*6777b538SAndroid Build Coastguard Worker   scoped_feature_list.InitWithFeatures(
6773*6777b538SAndroid Build Coastguard Worker       {}, {net::features::kEnableSchemeBoundCookies,
6774*6777b538SAndroid Build Coastguard Worker            net::features::kEnablePortBoundCookies});
6775*6777b538SAndroid Build Coastguard Worker 
6776*6777b538SAndroid Build Coastguard Worker   std::vector<CanonicalCookie*> cookie_ptrs;
6777*6777b538SAndroid Build Coastguard Worker   CookieAccessResultList included;
6778*6777b538SAndroid Build Coastguard Worker   CookieAccessResultList excluded;
6779*6777b538SAndroid Build Coastguard Worker 
6780*6777b538SAndroid Build Coastguard Worker   auto reset = [&cookie_ptrs, &included, &excluded]() {
6781*6777b538SAndroid Build Coastguard Worker     cookie_ptrs.clear();
6782*6777b538SAndroid Build Coastguard Worker     included.clear();
6783*6777b538SAndroid Build Coastguard Worker     excluded.clear();
6784*6777b538SAndroid Build Coastguard Worker   };
6785*6777b538SAndroid Build Coastguard Worker 
6786*6777b538SAndroid Build Coastguard Worker   auto origin_cookie1 = CanonicalCookie::CreateForTesting(
6787*6777b538SAndroid Build Coastguard Worker       https_www_foo_.url(), "foo1=origin", creation_time, server_time);
6788*6777b538SAndroid Build Coastguard Worker   auto origin_cookie2 = CanonicalCookie::CreateForTesting(
6789*6777b538SAndroid Build Coastguard Worker       https_www_foo_.url(), "foo2=origin", creation_time, server_time);
6790*6777b538SAndroid Build Coastguard Worker 
6791*6777b538SAndroid Build Coastguard Worker   auto domain_cookie1 = CanonicalCookie::CreateForTesting(
6792*6777b538SAndroid Build Coastguard Worker       https_www_foo_.url(), "foo1=domain; Domain=" + https_www_foo_.domain(),
6793*6777b538SAndroid Build Coastguard Worker       creation_time, server_time);
6794*6777b538SAndroid Build Coastguard Worker 
6795*6777b538SAndroid Build Coastguard Worker   // Shadowing domain cookie after the origin cookie.
6796*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {origin_cookie1.get(), origin_cookie2.get(),
6797*6777b538SAndroid Build Coastguard Worker                  domain_cookie1.get()};
6798*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(https_www_foo_.url(), options, &cookie_ptrs,
6799*6777b538SAndroid Build Coastguard Worker                                &included, &excluded);
6800*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(included, cookie_ptrs));
6801*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DomainCookiesHaveWarnings(included, {*domain_cookie1}));
6802*6777b538SAndroid Build Coastguard Worker   reset();
6803*6777b538SAndroid Build Coastguard Worker 
6804*6777b538SAndroid Build Coastguard Worker   // Shadowing domain cookie before the origin cookie.
6805*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {domain_cookie1.get(), origin_cookie2.get(),
6806*6777b538SAndroid Build Coastguard Worker                  origin_cookie1.get()};
6807*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(https_www_foo_.url(), options, &cookie_ptrs,
6808*6777b538SAndroid Build Coastguard Worker                                &included, &excluded);
6809*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(included, cookie_ptrs));
6810*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DomainCookiesHaveWarnings(included, {*domain_cookie1}));
6811*6777b538SAndroid Build Coastguard Worker   reset();
6812*6777b538SAndroid Build Coastguard Worker 
6813*6777b538SAndroid Build Coastguard Worker   auto domain_cookie2 = CanonicalCookie::CreateForTesting(
6814*6777b538SAndroid Build Coastguard Worker       https_www_foo_.url(), "foo2=domain; Domain=" + https_www_foo_.domain(),
6815*6777b538SAndroid Build Coastguard Worker       creation_time, server_time);
6816*6777b538SAndroid Build Coastguard Worker 
6817*6777b538SAndroid Build Coastguard Worker   // Multiple different shadowing domain cookies.
6818*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {domain_cookie1.get(), origin_cookie2.get(),
6819*6777b538SAndroid Build Coastguard Worker                  origin_cookie1.get(), domain_cookie2.get()};
6820*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(https_www_foo_.url(), options, &cookie_ptrs,
6821*6777b538SAndroid Build Coastguard Worker                                &included, &excluded);
6822*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(included, cookie_ptrs));
6823*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
6824*6777b538SAndroid Build Coastguard Worker       DomainCookiesHaveWarnings(included, {*domain_cookie1, *domain_cookie2}));
6825*6777b538SAndroid Build Coastguard Worker   reset();
6826*6777b538SAndroid Build Coastguard Worker 
6827*6777b538SAndroid Build Coastguard Worker   auto domain_cookie3 = CanonicalCookie::CreateForTesting(
6828*6777b538SAndroid Build Coastguard Worker       https_www_foo_.url(), "foo3=domain; Domain=" + https_www_foo_.domain(),
6829*6777b538SAndroid Build Coastguard Worker       creation_time, server_time);
6830*6777b538SAndroid Build Coastguard Worker 
6831*6777b538SAndroid Build Coastguard Worker   // Non-shadowing domain cookie shouldn't have a warning.
6832*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {domain_cookie1.get(), origin_cookie2.get(),
6833*6777b538SAndroid Build Coastguard Worker                  origin_cookie1.get(), domain_cookie2.get(),
6834*6777b538SAndroid Build Coastguard Worker                  domain_cookie3.get()};
6835*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(https_www_foo_.url(), options, &cookie_ptrs,
6836*6777b538SAndroid Build Coastguard Worker                                &included, &excluded);
6837*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(included, cookie_ptrs));
6838*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
6839*6777b538SAndroid Build Coastguard Worker       DomainCookiesHaveWarnings(included, {*domain_cookie1, *domain_cookie2}));
6840*6777b538SAndroid Build Coastguard Worker   reset();
6841*6777b538SAndroid Build Coastguard Worker 
6842*6777b538SAndroid Build Coastguard Worker   auto sub_domain_cookie1 = CanonicalCookie::CreateForTesting(
6843*6777b538SAndroid Build Coastguard Worker       https_www_foo_.url(), "foo1=subdomain; Domain=" + https_www_foo_.host(),
6844*6777b538SAndroid Build Coastguard Worker       creation_time, server_time);
6845*6777b538SAndroid Build Coastguard Worker 
6846*6777b538SAndroid Build Coastguard Worker   // If there are multiple domain cookies that shadow the same cookie, they
6847*6777b538SAndroid Build Coastguard Worker   // should all have a warning.
6848*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {domain_cookie1.get(), origin_cookie2.get(),
6849*6777b538SAndroid Build Coastguard Worker                  origin_cookie1.get(), sub_domain_cookie1.get()};
6850*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(https_www_foo_.url(), options, &cookie_ptrs,
6851*6777b538SAndroid Build Coastguard Worker                                &included, &excluded);
6852*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(included, cookie_ptrs));
6853*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DomainCookiesHaveWarnings(
6854*6777b538SAndroid Build Coastguard Worker       included, {*domain_cookie1, *sub_domain_cookie1}));
6855*6777b538SAndroid Build Coastguard Worker   reset();
6856*6777b538SAndroid Build Coastguard Worker 
6857*6777b538SAndroid Build Coastguard Worker   // Domain cookies may shadow each other.
6858*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {domain_cookie1.get(), sub_domain_cookie1.get()};
6859*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(https_www_foo_.url(), options, &cookie_ptrs,
6860*6777b538SAndroid Build Coastguard Worker                                &included, &excluded);
6861*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(included, cookie_ptrs));
6862*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DomainCookiesHaveWarnings(included, {}));
6863*6777b538SAndroid Build Coastguard Worker   reset();
6864*6777b538SAndroid Build Coastguard Worker 
6865*6777b538SAndroid Build Coastguard Worker   auto path_origin_cookie1 = CanonicalCookie::CreateForTesting(
6866*6777b538SAndroid Build Coastguard Worker       https_www_foo_.url(), "foo1=pathorigin; Path=/bar", creation_time,
6867*6777b538SAndroid Build Coastguard Worker       server_time);
6868*6777b538SAndroid Build Coastguard Worker 
6869*6777b538SAndroid Build Coastguard Worker   // Origin cookies on different paths may not be shadowed, even if the
6870*6777b538SAndroid Build Coastguard Worker   // origin cookie wouldn't be included on this request.
6871*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {path_origin_cookie1.get(), domain_cookie1.get()};
6872*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(https_www_foo_.url(), options, &cookie_ptrs,
6873*6777b538SAndroid Build Coastguard Worker                                &included, &excluded);
6874*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(included, {domain_cookie1.get()}));
6875*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DomainCookiesHaveWarnings(included, {*domain_cookie1}));
6876*6777b538SAndroid Build Coastguard Worker   reset();
6877*6777b538SAndroid Build Coastguard Worker 
6878*6777b538SAndroid Build Coastguard Worker   auto insecure_origin_cookie1 = CanonicalCookie::CreateForTesting(
6879*6777b538SAndroid Build Coastguard Worker       http_www_foo_.url(), "foo1=insecureorigin", creation_time, server_time);
6880*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(insecure_origin_cookie1->SourceScheme(),
6881*6777b538SAndroid Build Coastguard Worker             CookieSourceScheme::kNonSecure);
6882*6777b538SAndroid Build Coastguard Worker 
6883*6777b538SAndroid Build Coastguard Worker   // Origin cookies that have a warning for scheme binding don't affect domain
6884*6777b538SAndroid Build Coastguard Worker   // cookies.
6885*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {insecure_origin_cookie1.get(), domain_cookie1.get()};
6886*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(https_www_foo_.url(), options, &cookie_ptrs,
6887*6777b538SAndroid Build Coastguard Worker                                &included, &excluded);
6888*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(included, cookie_ptrs));
6889*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DomainCookiesHaveWarnings(included, {}));
6890*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(included[0].access_result.status.HasWarningReason(
6891*6777b538SAndroid Build Coastguard Worker       CookieInclusionStatus::WARN_SCHEME_MISMATCH));
6892*6777b538SAndroid Build Coastguard Worker   reset();
6893*6777b538SAndroid Build Coastguard Worker 
6894*6777b538SAndroid Build Coastguard Worker   auto insecure_domain_cookie1 = CanonicalCookie::CreateForTesting(
6895*6777b538SAndroid Build Coastguard Worker       http_www_foo_.url(),
6896*6777b538SAndroid Build Coastguard Worker       "foo1=insecuredomain; Domain=" + http_www_foo_.domain(), creation_time,
6897*6777b538SAndroid Build Coastguard Worker       server_time);
6898*6777b538SAndroid Build Coastguard Worker 
6899*6777b538SAndroid Build Coastguard Worker   // Domain cookies that are excluded due to scheme binding shouldn't also get a
6900*6777b538SAndroid Build Coastguard Worker   // shadow warning.
6901*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {origin_cookie1.get(), insecure_domain_cookie1.get()};
6902*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(https_www_foo_.url(), options, &cookie_ptrs,
6903*6777b538SAndroid Build Coastguard Worker                                &included, &excluded);
6904*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(included, cookie_ptrs));
6905*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DomainCookiesHaveWarnings(included, {}));
6906*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
6907*6777b538SAndroid Build Coastguard Worker       included[1].access_result.status.HasExactlyWarningReasonsForTesting(
6908*6777b538SAndroid Build Coastguard Worker           {CookieInclusionStatus::WARN_SCHEME_MISMATCH}));
6909*6777b538SAndroid Build Coastguard Worker   reset();
6910*6777b538SAndroid Build Coastguard Worker 
6911*6777b538SAndroid Build Coastguard Worker   // If both domain and origin cookie have warnings due to scheme binding then
6912*6777b538SAndroid Build Coastguard Worker   // domain cookie shouldn't get shadowing warning.
6913*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {insecure_origin_cookie1.get(), insecure_domain_cookie1.get()};
6914*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(https_www_foo_.url(), options, &cookie_ptrs,
6915*6777b538SAndroid Build Coastguard Worker                                &included, &excluded);
6916*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(included, cookie_ptrs));
6917*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DomainCookiesHaveWarnings(included, {}));
6918*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(included[0].access_result.status.HasWarningReason(
6919*6777b538SAndroid Build Coastguard Worker       CookieInclusionStatus::WARN_SCHEME_MISMATCH));
6920*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
6921*6777b538SAndroid Build Coastguard Worker       included[1].access_result.status.HasExactlyWarningReasonsForTesting(
6922*6777b538SAndroid Build Coastguard Worker           {CookieInclusionStatus::WARN_SCHEME_MISMATCH}));
6923*6777b538SAndroid Build Coastguard Worker   reset();
6924*6777b538SAndroid Build Coastguard Worker 
6925*6777b538SAndroid Build Coastguard Worker   cm->SetCookieAccessDelegate(std::make_unique<TestCookieAccessDelegate>());
6926*6777b538SAndroid Build Coastguard Worker 
6927*6777b538SAndroid Build Coastguard Worker   CookieURLHelper http_www_trustworthy =
6928*6777b538SAndroid Build Coastguard Worker       CookieURLHelper("http://www.trustworthysitefortestdelegate.example");
6929*6777b538SAndroid Build Coastguard Worker   CookieURLHelper https_www_trustworthy =
6930*6777b538SAndroid Build Coastguard Worker       CookieURLHelper("https://www.trustworthysitefortestdelegate.example");
6931*6777b538SAndroid Build Coastguard Worker 
6932*6777b538SAndroid Build Coastguard Worker   auto trust_origin_cookie1 = CanonicalCookie::CreateForTesting(
6933*6777b538SAndroid Build Coastguard Worker       http_www_trustworthy.url(), "foo1=trustorigin", creation_time,
6934*6777b538SAndroid Build Coastguard Worker       server_time);
6935*6777b538SAndroid Build Coastguard Worker 
6936*6777b538SAndroid Build Coastguard Worker   auto secure_trust_domain_cookie1 = CanonicalCookie::CreateForTesting(
6937*6777b538SAndroid Build Coastguard Worker       https_www_trustworthy.url(),
6938*6777b538SAndroid Build Coastguard Worker       "foo1=securetrustdomain; Domain=" + https_www_trustworthy.domain(),
6939*6777b538SAndroid Build Coastguard Worker       creation_time, server_time);
6940*6777b538SAndroid Build Coastguard Worker   auto secure_trust_domain_cookie2 = CanonicalCookie::CreateForTesting(
6941*6777b538SAndroid Build Coastguard Worker       https_www_trustworthy.url(),
6942*6777b538SAndroid Build Coastguard Worker       "foo2=securetrustdomain; Domain=" + https_www_trustworthy.domain(),
6943*6777b538SAndroid Build Coastguard Worker       creation_time, server_time);
6944*6777b538SAndroid Build Coastguard Worker 
6945*6777b538SAndroid Build Coastguard Worker   // Securely set domain cookie has warning when shadowing trustworthy-ly set
6946*6777b538SAndroid Build Coastguard Worker   // origin cookies.
6947*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {trust_origin_cookie1.get(), secure_trust_domain_cookie1.get(),
6948*6777b538SAndroid Build Coastguard Worker                  secure_trust_domain_cookie2.get()};
6949*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(http_www_trustworthy.url(), options,
6950*6777b538SAndroid Build Coastguard Worker                                &cookie_ptrs, &included, &excluded);
6951*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(included, cookie_ptrs));
6952*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
6953*6777b538SAndroid Build Coastguard Worker       DomainCookiesHaveWarnings(included, {*secure_trust_domain_cookie1}));
6954*6777b538SAndroid Build Coastguard Worker   reset();
6955*6777b538SAndroid Build Coastguard Worker 
6956*6777b538SAndroid Build Coastguard Worker   auto trust_domain_cookie1 = CanonicalCookie::CreateForTesting(
6957*6777b538SAndroid Build Coastguard Worker       http_www_trustworthy.url(),
6958*6777b538SAndroid Build Coastguard Worker       "foo1=trustdomain; Domain=" + http_www_trustworthy.domain(),
6959*6777b538SAndroid Build Coastguard Worker       creation_time, server_time);
6960*6777b538SAndroid Build Coastguard Worker   auto trust_domain_cookie2 = CanonicalCookie::CreateForTesting(
6961*6777b538SAndroid Build Coastguard Worker       http_www_trustworthy.url(),
6962*6777b538SAndroid Build Coastguard Worker       "foo2=trustdomain; Domain=" + http_www_trustworthy.domain(),
6963*6777b538SAndroid Build Coastguard Worker       creation_time, server_time);
6964*6777b538SAndroid Build Coastguard Worker   auto secure_trust_origin_cookie1 = CanonicalCookie::CreateForTesting(
6965*6777b538SAndroid Build Coastguard Worker       https_www_trustworthy.url(), "foo1=securetrustorigin", creation_time,
6966*6777b538SAndroid Build Coastguard Worker       server_time);
6967*6777b538SAndroid Build Coastguard Worker 
6968*6777b538SAndroid Build Coastguard Worker   // Trustworthy-ly set domain cookies are excluded when shadowing securely set
6969*6777b538SAndroid Build Coastguard Worker   // origin cookies.
6970*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {secure_trust_origin_cookie1.get(), trust_domain_cookie1.get(),
6971*6777b538SAndroid Build Coastguard Worker                  trust_domain_cookie2.get()};
6972*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(http_www_trustworthy.url(), options,
6973*6777b538SAndroid Build Coastguard Worker                                &cookie_ptrs, &included, &excluded);
6974*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(included, cookie_ptrs));
6975*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DomainCookiesHaveWarnings(included, {*trust_domain_cookie1}));
6976*6777b538SAndroid Build Coastguard Worker   reset();
6977*6777b538SAndroid Build Coastguard Worker 
6978*6777b538SAndroid Build Coastguard Worker   auto port_origin_cookie1 = CanonicalCookie::CreateForTesting(
6979*6777b538SAndroid Build Coastguard Worker       https_www_foo_.url(), "foo1=differentportorigin", creation_time,
6980*6777b538SAndroid Build Coastguard Worker       server_time);
6981*6777b538SAndroid Build Coastguard Worker   port_origin_cookie1->SetSourcePort(123);
6982*6777b538SAndroid Build Coastguard Worker 
6983*6777b538SAndroid Build Coastguard Worker   // Origin cookies that have warnings due to port binding don't affect domain
6984*6777b538SAndroid Build Coastguard Worker   // cookies.
6985*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {port_origin_cookie1.get(), domain_cookie1.get()};
6986*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(https_www_foo_.url(), options, &cookie_ptrs,
6987*6777b538SAndroid Build Coastguard Worker                                &included, &excluded);
6988*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(included, cookie_ptrs));
6989*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DomainCookiesHaveWarnings(included, {}));
6990*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(included[0].access_result.status.HasWarningReason(
6991*6777b538SAndroid Build Coastguard Worker       CookieInclusionStatus::WARN_PORT_MISMATCH));
6992*6777b538SAndroid Build Coastguard Worker   reset();
6993*6777b538SAndroid Build Coastguard Worker 
6994*6777b538SAndroid Build Coastguard Worker   auto port_insecure_origin_cookie1 =
6995*6777b538SAndroid Build Coastguard Worker       std::make_unique<CanonicalCookie>(*insecure_origin_cookie1);
6996*6777b538SAndroid Build Coastguard Worker   port_insecure_origin_cookie1->SetSourcePort(123);
6997*6777b538SAndroid Build Coastguard Worker 
6998*6777b538SAndroid Build Coastguard Worker   // Origin cookies that have warnings due to scheme and port binding don't
6999*6777b538SAndroid Build Coastguard Worker   // affect domain cookies.
7000*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {port_insecure_origin_cookie1.get(), domain_cookie1.get()};
7001*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(https_www_foo_.url(), options, &cookie_ptrs,
7002*6777b538SAndroid Build Coastguard Worker                                &included, &excluded);
7003*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(included, cookie_ptrs));
7004*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DomainCookiesHaveWarnings(included, {}));
7005*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
7006*6777b538SAndroid Build Coastguard Worker       included[0].access_result.status.HasExactlyWarningReasonsForTesting(
7007*6777b538SAndroid Build Coastguard Worker           {CookieInclusionStatus::WARN_SCHEME_MISMATCH,
7008*6777b538SAndroid Build Coastguard Worker            CookieInclusionStatus::WARN_PORT_MISMATCH}));
7009*6777b538SAndroid Build Coastguard Worker   reset();
7010*6777b538SAndroid Build Coastguard Worker 
7011*6777b538SAndroid Build Coastguard Worker   // Enable port binding to test with port exclusions.
7012*6777b538SAndroid Build Coastguard Worker   scoped_feature_list.Reset();
7013*6777b538SAndroid Build Coastguard Worker   scoped_feature_list.InitWithFeatures(
7014*6777b538SAndroid Build Coastguard Worker       {net::features::kEnablePortBoundCookies},
7015*6777b538SAndroid Build Coastguard Worker       {net::features::kEnableSchemeBoundCookies});
7016*6777b538SAndroid Build Coastguard Worker 
7017*6777b538SAndroid Build Coastguard Worker   // Origin cookies that are excluded due to port binding don't affect domain
7018*6777b538SAndroid Build Coastguard Worker   // cookies.
7019*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {port_origin_cookie1.get(), domain_cookie1.get()};
7020*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(https_www_foo_.url(), options, &cookie_ptrs,
7021*6777b538SAndroid Build Coastguard Worker                                &included, &excluded);
7022*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(included, {domain_cookie1.get()}));
7023*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DomainCookiesHaveWarnings(included, {}));
7024*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(excluded, {port_origin_cookie1.get()}));
7025*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
7026*6777b538SAndroid Build Coastguard Worker       excluded[0].access_result.status.HasExactlyExclusionReasonsForTesting(
7027*6777b538SAndroid Build Coastguard Worker           {CookieInclusionStatus::EXCLUDE_PORT_MISMATCH}));
7028*6777b538SAndroid Build Coastguard Worker   reset();
7029*6777b538SAndroid Build Coastguard Worker 
7030*6777b538SAndroid Build Coastguard Worker   // Origin cookies that are excluded due to port binding and have a scheme
7031*6777b538SAndroid Build Coastguard Worker   // binding warning don't affect domain cookies.
7032*6777b538SAndroid Build Coastguard Worker   cookie_ptrs = {port_insecure_origin_cookie1.get(), domain_cookie1.get()};
7033*6777b538SAndroid Build Coastguard Worker   cm->FilterCookiesWithOptions(https_www_foo_.url(), options, &cookie_ptrs,
7034*6777b538SAndroid Build Coastguard Worker                                &included, &excluded);
7035*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(included, {domain_cookie1.get()}));
7036*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DomainCookiesHaveWarnings(included, {}));
7037*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(CookieListsMatch(excluded, {port_insecure_origin_cookie1.get()}));
7038*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
7039*6777b538SAndroid Build Coastguard Worker       excluded[0].access_result.status.HasExactlyExclusionReasonsForTesting(
7040*6777b538SAndroid Build Coastguard Worker           {CookieInclusionStatus::EXCLUDE_PORT_MISMATCH}));
7041*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(excluded[0].access_result.status.HasWarningReason(
7042*6777b538SAndroid Build Coastguard Worker       CookieInclusionStatus::WARN_SCHEME_MISMATCH));
7043*6777b538SAndroid Build Coastguard Worker   reset();
7044*6777b538SAndroid Build Coastguard Worker }
7045*6777b538SAndroid Build Coastguard Worker 
7046*6777b538SAndroid Build Coastguard Worker // This test sets a cookie (only checked using IsCanonicalForFromStorage)
7047*6777b538SAndroid Build Coastguard Worker // that's 300 days old and expires in 800 days. It checks that this cookie was
7048*6777b538SAndroid Build Coastguard Worker // stored, and then update it. It checks that the updated cookie has the
7049*6777b538SAndroid Build Coastguard Worker // creation and expiry dates expected.
TEST_F(CookieMonsterTest,FromStorageCookieCreated300DaysAgoThenUpdatedNow)7050*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, FromStorageCookieCreated300DaysAgoThenUpdatedNow) {
7051*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<FlushablePersistentStore>();
7052*6777b538SAndroid Build Coastguard Worker   auto cookie_monster =
7053*6777b538SAndroid Build Coastguard Worker       std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
7054*6777b538SAndroid Build Coastguard Worker   cookie_monster->SetPersistSessionCookies(true);
7055*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(GetAllCookies(cookie_monster.get()).empty());
7056*6777b538SAndroid Build Coastguard Worker 
7057*6777b538SAndroid Build Coastguard Worker   // Bypass IsCanonical and store a 300 day old cookie to bypass clamping.
7058*6777b538SAndroid Build Coastguard Worker   base::Time original_creation = base::Time::Now() - base::Days(300);
7059*6777b538SAndroid Build Coastguard Worker   base::Time original_expiry = original_creation + base::Days(800);
7060*6777b538SAndroid Build Coastguard Worker   CookieList list;
7061*6777b538SAndroid Build Coastguard Worker   list.push_back(*CanonicalCookie::CreateUnsafeCookieForTesting(
7062*6777b538SAndroid Build Coastguard Worker       "A", "B", "." + https_www_foo_.url().host(), "/", original_creation,
7063*6777b538SAndroid Build Coastguard Worker       original_expiry, base::Time(), base::Time(), true, false,
7064*6777b538SAndroid Build Coastguard Worker       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT));
7065*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetAllCookies(cookie_monster.get(), list));
7066*6777b538SAndroid Build Coastguard Worker 
7067*6777b538SAndroid Build Coastguard Worker   // Verify the cookie exists and was not clamped, even if clamping is on.
7068*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(GetAllCookies(cookie_monster.get()),
7069*6777b538SAndroid Build Coastguard Worker               ElementsAre(MatchesCookieNameValueCreationExpiry(
7070*6777b538SAndroid Build Coastguard Worker                   "A", "B", original_creation, original_expiry)));
7071*6777b538SAndroid Build Coastguard Worker 
7072*6777b538SAndroid Build Coastguard Worker   // Update the cookie without bypassing clamping.
7073*6777b538SAndroid Build Coastguard Worker   base::Time new_creation = base::Time::Now();
7074*6777b538SAndroid Build Coastguard Worker   base::Time new_expiry = new_creation + base::Days(800);
7075*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCanonicalCookie(
7076*6777b538SAndroid Build Coastguard Worker       cookie_monster.get(),
7077*6777b538SAndroid Build Coastguard Worker       CanonicalCookie::CreateSanitizedCookie(
7078*6777b538SAndroid Build Coastguard Worker           https_www_foo_.url(), "A", "B", https_www_foo_.url().host(), "/",
7079*6777b538SAndroid Build Coastguard Worker           new_creation, new_expiry, base::Time(), true, false,
7080*6777b538SAndroid Build Coastguard Worker           CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, std::nullopt,
7081*6777b538SAndroid Build Coastguard Worker           /*status=*/nullptr),
7082*6777b538SAndroid Build Coastguard Worker       https_www_foo_.url(), false));
7083*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
7084*6777b538SAndroid Build Coastguard Worker       GetAllCookies(cookie_monster.get()),
7085*6777b538SAndroid Build Coastguard Worker       ElementsAre(MatchesCookieNameValueCreationExpiry(
7086*6777b538SAndroid Build Coastguard Worker           "A", "B", original_creation, new_creation + base::Days(400))));
7087*6777b538SAndroid Build Coastguard Worker }
7088*6777b538SAndroid Build Coastguard Worker 
7089*6777b538SAndroid Build Coastguard Worker // This test sets a cookie (only checked using IsCanonicalForFromStorage)
7090*6777b538SAndroid Build Coastguard Worker // that's 500 days old and expires in 800 days. It checks that this cookie was
7091*6777b538SAndroid Build Coastguard Worker // stored, and then update it. It checks that the updated cookie has the
7092*6777b538SAndroid Build Coastguard Worker // creation and expiry dates expected.
TEST_F(CookieMonsterTest,FromStorageCookieCreated500DaysAgoThenUpdatedNow)7093*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, FromStorageCookieCreated500DaysAgoThenUpdatedNow) {
7094*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<FlushablePersistentStore>();
7095*6777b538SAndroid Build Coastguard Worker   auto cookie_monster =
7096*6777b538SAndroid Build Coastguard Worker       std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
7097*6777b538SAndroid Build Coastguard Worker   cookie_monster->SetPersistSessionCookies(true);
7098*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(GetAllCookies(cookie_monster.get()).empty());
7099*6777b538SAndroid Build Coastguard Worker 
7100*6777b538SAndroid Build Coastguard Worker   // Bypass IsCanonical and store a 500 day old cookie to bypass clamping.
7101*6777b538SAndroid Build Coastguard Worker   base::Time original_creation = base::Time::Now() - base::Days(500);
7102*6777b538SAndroid Build Coastguard Worker   base::Time original_expiry = original_creation + base::Days(800);
7103*6777b538SAndroid Build Coastguard Worker   CookieList list;
7104*6777b538SAndroid Build Coastguard Worker   list.push_back(*CanonicalCookie::CreateUnsafeCookieForTesting(
7105*6777b538SAndroid Build Coastguard Worker       "A", "B", "." + https_www_foo_.url().host(), "/", original_creation,
7106*6777b538SAndroid Build Coastguard Worker       original_expiry, base::Time(), base::Time(), true, false,
7107*6777b538SAndroid Build Coastguard Worker       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT));
7108*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetAllCookies(cookie_monster.get(), list));
7109*6777b538SAndroid Build Coastguard Worker 
7110*6777b538SAndroid Build Coastguard Worker   // Verify the cookie exists and was not clamped, even if clamping is on.
7111*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(GetAllCookies(cookie_monster.get()),
7112*6777b538SAndroid Build Coastguard Worker               ElementsAre(MatchesCookieNameValueCreationExpiry(
7113*6777b538SAndroid Build Coastguard Worker                   "A", "B", original_creation, original_expiry)));
7114*6777b538SAndroid Build Coastguard Worker 
7115*6777b538SAndroid Build Coastguard Worker   // Update the cookie without bypassing clamping.
7116*6777b538SAndroid Build Coastguard Worker   base::Time new_creation = base::Time::Now();
7117*6777b538SAndroid Build Coastguard Worker   base::Time new_expiry = new_creation + base::Days(800);
7118*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCanonicalCookie(
7119*6777b538SAndroid Build Coastguard Worker       cookie_monster.get(),
7120*6777b538SAndroid Build Coastguard Worker       CanonicalCookie::CreateSanitizedCookie(
7121*6777b538SAndroid Build Coastguard Worker           https_www_foo_.url(), "A", "B", https_www_foo_.url().host(), "/",
7122*6777b538SAndroid Build Coastguard Worker           new_creation, new_expiry, base::Time(), true, false,
7123*6777b538SAndroid Build Coastguard Worker           CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, std::nullopt,
7124*6777b538SAndroid Build Coastguard Worker           /*status=*/nullptr),
7125*6777b538SAndroid Build Coastguard Worker       https_www_foo_.url(), false));
7126*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
7127*6777b538SAndroid Build Coastguard Worker       GetAllCookies(cookie_monster.get()),
7128*6777b538SAndroid Build Coastguard Worker       ElementsAre(MatchesCookieNameValueCreationExpiry(
7129*6777b538SAndroid Build Coastguard Worker           "A", "B", original_creation, new_creation + base::Days(400))));
7130*6777b538SAndroid Build Coastguard Worker }
7131*6777b538SAndroid Build Coastguard Worker 
7132*6777b538SAndroid Build Coastguard Worker // This test sets a cookie (checked using IsCanonical) that's 300 days old and
7133*6777b538SAndroid Build Coastguard Worker // expires in 800 days. It checks that this cookie was stored, and then update
7134*6777b538SAndroid Build Coastguard Worker // it. It checks that the updated cookie has the creation and expiry dates
7135*6777b538SAndroid Build Coastguard Worker // expected.
TEST_F(CookieMonsterTest,SanitizedCookieCreated300DaysAgoThenUpdatedNow)7136*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, SanitizedCookieCreated300DaysAgoThenUpdatedNow) {
7137*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<FlushablePersistentStore>();
7138*6777b538SAndroid Build Coastguard Worker   auto cookie_monster =
7139*6777b538SAndroid Build Coastguard Worker       std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
7140*6777b538SAndroid Build Coastguard Worker   cookie_monster->SetPersistSessionCookies(true);
7141*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(GetAllCookies(cookie_monster.get()).empty());
7142*6777b538SAndroid Build Coastguard Worker 
7143*6777b538SAndroid Build Coastguard Worker   // Store a 300 day old cookie without bypassing clamping.
7144*6777b538SAndroid Build Coastguard Worker   base::Time original_creation = base::Time::Now() - base::Days(300);
7145*6777b538SAndroid Build Coastguard Worker   base::Time original_expiry = original_creation + base::Days(800);
7146*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCanonicalCookie(
7147*6777b538SAndroid Build Coastguard Worker       cookie_monster.get(),
7148*6777b538SAndroid Build Coastguard Worker       CanonicalCookie::CreateSanitizedCookie(
7149*6777b538SAndroid Build Coastguard Worker           https_www_foo_.url(), "A", "B", https_www_foo_.url().host(), "/",
7150*6777b538SAndroid Build Coastguard Worker           original_creation, original_expiry, base::Time(), true, false,
7151*6777b538SAndroid Build Coastguard Worker           CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, std::nullopt,
7152*6777b538SAndroid Build Coastguard Worker           /*status=*/nullptr),
7153*6777b538SAndroid Build Coastguard Worker       https_www_foo_.url(), false));
7154*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
7155*6777b538SAndroid Build Coastguard Worker       GetAllCookies(cookie_monster.get()),
7156*6777b538SAndroid Build Coastguard Worker       ElementsAre(MatchesCookieNameValueCreationExpiry(
7157*6777b538SAndroid Build Coastguard Worker           "A", "B", original_creation, original_creation + base::Days(400))));
7158*6777b538SAndroid Build Coastguard Worker 
7159*6777b538SAndroid Build Coastguard Worker   // Update the cookie without bypassing clamping.
7160*6777b538SAndroid Build Coastguard Worker   base::Time new_creation = base::Time::Now();
7161*6777b538SAndroid Build Coastguard Worker   base::Time new_expiry = new_creation + base::Days(800);
7162*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCanonicalCookie(
7163*6777b538SAndroid Build Coastguard Worker       cookie_monster.get(),
7164*6777b538SAndroid Build Coastguard Worker       CanonicalCookie::CreateSanitizedCookie(
7165*6777b538SAndroid Build Coastguard Worker           https_www_foo_.url(), "A", "B", https_www_foo_.url().host(), "/",
7166*6777b538SAndroid Build Coastguard Worker           new_creation, new_expiry, base::Time(), true, false,
7167*6777b538SAndroid Build Coastguard Worker           CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, std::nullopt,
7168*6777b538SAndroid Build Coastguard Worker           /*status=*/nullptr),
7169*6777b538SAndroid Build Coastguard Worker       https_www_foo_.url(), false));
7170*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
7171*6777b538SAndroid Build Coastguard Worker       GetAllCookies(cookie_monster.get()),
7172*6777b538SAndroid Build Coastguard Worker       ElementsAre(MatchesCookieNameValueCreationExpiry(
7173*6777b538SAndroid Build Coastguard Worker           "A", "B", original_creation, new_creation + base::Days(400))));
7174*6777b538SAndroid Build Coastguard Worker }
7175*6777b538SAndroid Build Coastguard Worker 
7176*6777b538SAndroid Build Coastguard Worker // This test sets a cookie (checked using IsCanonical) that's 500 days old and
7177*6777b538SAndroid Build Coastguard Worker // expires in 800 days. It checks that this cookie was stored, and then update
7178*6777b538SAndroid Build Coastguard Worker // it. It checks that the updated cookie has the creation and expiry dates
7179*6777b538SAndroid Build Coastguard Worker // expected.
TEST_F(CookieMonsterTest,SanitizedCookieCreated500DaysAgoThenUpdatedNow)7180*6777b538SAndroid Build Coastguard Worker TEST_F(CookieMonsterTest, SanitizedCookieCreated500DaysAgoThenUpdatedNow) {
7181*6777b538SAndroid Build Coastguard Worker   auto store = base::MakeRefCounted<FlushablePersistentStore>();
7182*6777b538SAndroid Build Coastguard Worker   auto cookie_monster =
7183*6777b538SAndroid Build Coastguard Worker       std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
7184*6777b538SAndroid Build Coastguard Worker   cookie_monster->SetPersistSessionCookies(true);
7185*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(GetAllCookies(cookie_monster.get()).empty());
7186*6777b538SAndroid Build Coastguard Worker 
7187*6777b538SAndroid Build Coastguard Worker   // Store a 500 day old cookie without bypassing clamping.
7188*6777b538SAndroid Build Coastguard Worker   base::Time original_creation = base::Time::Now() - base::Days(500);
7189*6777b538SAndroid Build Coastguard Worker   base::Time original_expiry = original_creation + base::Days(800);
7190*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCanonicalCookie(
7191*6777b538SAndroid Build Coastguard Worker       cookie_monster.get(),
7192*6777b538SAndroid Build Coastguard Worker       CanonicalCookie::CreateSanitizedCookie(
7193*6777b538SAndroid Build Coastguard Worker           https_www_foo_.url(), "A", "B", https_www_foo_.url().host(), "/",
7194*6777b538SAndroid Build Coastguard Worker           original_creation, original_expiry, base::Time(), true, false,
7195*6777b538SAndroid Build Coastguard Worker           CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, std::nullopt,
7196*6777b538SAndroid Build Coastguard Worker           /*status=*/nullptr),
7197*6777b538SAndroid Build Coastguard Worker       https_www_foo_.url(), false));
7198*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(GetAllCookies(cookie_monster.get()).empty());
7199*6777b538SAndroid Build Coastguard Worker 
7200*6777b538SAndroid Build Coastguard Worker   // Update the cookie without bypassing clamping.
7201*6777b538SAndroid Build Coastguard Worker   base::Time new_creation = base::Time::Now();
7202*6777b538SAndroid Build Coastguard Worker   base::Time new_expiry = new_creation + base::Days(800);
7203*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SetCanonicalCookie(
7204*6777b538SAndroid Build Coastguard Worker       cookie_monster.get(),
7205*6777b538SAndroid Build Coastguard Worker       CanonicalCookie::CreateSanitizedCookie(
7206*6777b538SAndroid Build Coastguard Worker           https_www_foo_.url(), "A", "B", https_www_foo_.url().host(), "/",
7207*6777b538SAndroid Build Coastguard Worker           new_creation, new_expiry, base::Time(), true, false,
7208*6777b538SAndroid Build Coastguard Worker           CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, std::nullopt,
7209*6777b538SAndroid Build Coastguard Worker           /*status=*/nullptr),
7210*6777b538SAndroid Build Coastguard Worker       https_www_foo_.url(), false));
7211*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(GetAllCookies(cookie_monster.get()),
7212*6777b538SAndroid Build Coastguard Worker               ElementsAre(MatchesCookieNameValueCreationExpiry(
7213*6777b538SAndroid Build Coastguard Worker                   "A", "B", new_creation, new_creation + base::Days(400))));
7214*6777b538SAndroid Build Coastguard Worker }
7215*6777b538SAndroid Build Coastguard Worker 
7216*6777b538SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(/* no label */,
7217*6777b538SAndroid Build Coastguard Worker                          CookieMonsterTestPriorityGarbageCollectionObc,
7218*6777b538SAndroid Build Coastguard Worker                          testing::Combine(testing::Bool(), testing::Bool()));
7219*6777b538SAndroid Build Coastguard Worker 
7220*6777b538SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(/* no label */,
7221*6777b538SAndroid Build Coastguard Worker                          CookieMonsterTestGarbageCollectionObc,
7222*6777b538SAndroid Build Coastguard Worker                          testing::ValuesIn(std::vector<std::tuple<bool, bool>>{
7223*6777b538SAndroid Build Coastguard Worker                              {true, false},
7224*6777b538SAndroid Build Coastguard Worker                              {false, true},
7225*6777b538SAndroid Build Coastguard Worker                              {true, true}}));
7226*6777b538SAndroid Build Coastguard Worker 
7227*6777b538SAndroid Build Coastguard Worker }  // namespace net
7228