xref: /aosp_15_r20/external/cronet/net/cookies/cookie_monster_store_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/cookies/cookie_monster_store_test.h"
6 
7 #include "base/functional/bind.h"
8 #include "base/location.h"
9 #include "base/strings/stringprintf.h"
10 #include "base/task/single_thread_task_runner.h"
11 #include "base/time/time.h"
12 #include "net/cookies/cookie_constants.h"
13 #include "net/cookies/cookie_util.h"
14 #include "net/cookies/parsed_cookie.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "url/gurl.h"
17 
18 namespace net {
19 
CookieStoreCommand(Type type,CookieMonster::PersistentCookieStore::LoadedCallback loaded_callback,const std::string & key)20 CookieStoreCommand::CookieStoreCommand(
21     Type type,
22     CookieMonster::PersistentCookieStore::LoadedCallback loaded_callback,
23     const std::string& key)
24     : type(type), loaded_callback(std::move(loaded_callback)), key(key) {}
25 
CookieStoreCommand(Type type,const CanonicalCookie & cookie)26 CookieStoreCommand::CookieStoreCommand(Type type, const CanonicalCookie& cookie)
27     : type(type), cookie(cookie) {}
28 
29 CookieStoreCommand::CookieStoreCommand(CookieStoreCommand&& other) = default;
30 CookieStoreCommand::~CookieStoreCommand() = default;
31 
32 MockPersistentCookieStore::MockPersistentCookieStore() = default;
33 
SetLoadExpectation(bool return_value,std::vector<std::unique_ptr<CanonicalCookie>> result)34 void MockPersistentCookieStore::SetLoadExpectation(
35     bool return_value,
36     std::vector<std::unique_ptr<CanonicalCookie>> result) {
37   load_return_value_ = return_value;
38   load_result_.swap(result);
39 }
40 
Load(LoadedCallback loaded_callback,const NetLogWithSource &)41 void MockPersistentCookieStore::Load(LoadedCallback loaded_callback,
42                                      const NetLogWithSource& /* net_log */) {
43   if (store_load_commands_) {
44     commands_.push_back(CookieStoreCommand(CookieStoreCommand::LOAD,
45                                            std::move(loaded_callback), ""));
46     return;
47   }
48   std::vector<std::unique_ptr<CanonicalCookie>> out_cookies;
49   if (load_return_value_) {
50     out_cookies.swap(load_result_);
51     loaded_ = true;
52   }
53   base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
54       FROM_HERE,
55       base::BindOnce(std::move(loaded_callback), std::move(out_cookies)));
56 }
57 
LoadCookiesForKey(const std::string & key,LoadedCallback loaded_callback)58 void MockPersistentCookieStore::LoadCookiesForKey(
59     const std::string& key,
60     LoadedCallback loaded_callback) {
61   if (store_load_commands_) {
62     commands_.push_back(
63         CookieStoreCommand(CookieStoreCommand::LOAD_COOKIES_FOR_KEY,
64                            std::move(loaded_callback), key));
65     return;
66   }
67   if (!loaded_) {
68     Load(std::move(loaded_callback), NetLogWithSource());
69   } else {
70     std::vector<std::unique_ptr<CanonicalCookie>> empty_cookies;
71     base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
72         FROM_HERE,
73         base::BindOnce(std::move(loaded_callback), std::move(empty_cookies)));
74   }
75 }
76 
AddCookie(const CanonicalCookie & cookie)77 void MockPersistentCookieStore::AddCookie(const CanonicalCookie& cookie) {
78   commands_.push_back(CookieStoreCommand(CookieStoreCommand::ADD, cookie));
79 }
80 
UpdateCookieAccessTime(const CanonicalCookie & cookie)81 void MockPersistentCookieStore::UpdateCookieAccessTime(
82     const CanonicalCookie& cookie) {
83 }
84 
DeleteCookie(const CanonicalCookie & cookie)85 void MockPersistentCookieStore::DeleteCookie(const CanonicalCookie& cookie) {
86   commands_.push_back(CookieStoreCommand(CookieStoreCommand::REMOVE, cookie));
87 }
88 
SetForceKeepSessionState()89 void MockPersistentCookieStore::SetForceKeepSessionState() {}
90 
SetBeforeCommitCallback(base::RepeatingClosure callback)91 void MockPersistentCookieStore::SetBeforeCommitCallback(
92     base::RepeatingClosure callback) {}
93 
Flush(base::OnceClosure callback)94 void MockPersistentCookieStore::Flush(base::OnceClosure callback) {
95   if (!callback.is_null())
96     base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
97         FROM_HERE, std::move(callback));
98 }
99 
100 MockPersistentCookieStore::~MockPersistentCookieStore() = default;
101 
BuildCanonicalCookie(const GURL & url,const std::string & cookie_line,const base::Time & creation_time)102 std::unique_ptr<CanonicalCookie> BuildCanonicalCookie(
103     const GURL& url,
104     const std::string& cookie_line,
105     const base::Time& creation_time) {
106   // Parse the cookie line.
107   ParsedCookie pc(cookie_line);
108   EXPECT_TRUE(pc.IsValid());
109 
110   // This helper is simplistic in interpreting a parsed cookie, in order to
111   // avoid duplicated CookieMonster's CanonPath() and CanonExpiration()
112   // functions. Would be nice to export them, and re-use here.
113   EXPECT_FALSE(pc.HasMaxAge());
114   EXPECT_TRUE(pc.HasPath());
115   base::Time cookie_expires =
116       pc.HasExpires() ? cookie_util::ParseCookieExpirationTime(pc.Expires())
117                       : base::Time();
118   std::string cookie_path = pc.Path();
119 
120   return CanonicalCookie::CreateUnsafeCookieForTesting(
121       pc.Name(), pc.Value(), "." + url.host(), cookie_path, creation_time,
122       cookie_expires, base::Time(), base::Time(), pc.IsSecure(),
123       pc.IsHttpOnly(), pc.SameSite(), pc.Priority());
124 }
125 
AddCookieToList(const GURL & url,const std::string & cookie_line,const base::Time & creation_time,std::vector<std::unique_ptr<CanonicalCookie>> * out_list)126 void AddCookieToList(const GURL& url,
127                      const std::string& cookie_line,
128                      const base::Time& creation_time,
129                      std::vector<std::unique_ptr<CanonicalCookie>>* out_list) {
130   std::unique_ptr<CanonicalCookie> cookie(
131       BuildCanonicalCookie(url, cookie_line, creation_time));
132 
133   out_list->push_back(std::move(cookie));
134 }
135 
136 MockSimplePersistentCookieStore::MockSimplePersistentCookieStore() = default;
137 
Load(LoadedCallback loaded_callback,const NetLogWithSource &)138 void MockSimplePersistentCookieStore::Load(
139     LoadedCallback loaded_callback,
140     const NetLogWithSource& /* net_log */) {
141   std::vector<std::unique_ptr<CanonicalCookie>> out_cookies;
142 
143   for (const auto& cookie_map_it : cookies_) {
144     out_cookies.push_back(
145         std::make_unique<CanonicalCookie>(cookie_map_it.second));
146   }
147 
148   base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
149       FROM_HERE,
150       base::BindOnce(std::move(loaded_callback), std::move(out_cookies)));
151   loaded_ = true;
152 }
153 
LoadCookiesForKey(const std::string & key,LoadedCallback loaded_callback)154 void MockSimplePersistentCookieStore::LoadCookiesForKey(
155     const std::string& key,
156     LoadedCallback loaded_callback) {
157   if (!loaded_) {
158     Load(std::move(loaded_callback), NetLogWithSource());
159   } else {
160     std::vector<std::unique_ptr<CanonicalCookie>> empty_cookies;
161     base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
162         FROM_HERE,
163         base::BindOnce(std::move(loaded_callback), std::move(empty_cookies)));
164   }
165 }
166 
AddCookie(const CanonicalCookie & cookie)167 void MockSimplePersistentCookieStore::AddCookie(const CanonicalCookie& cookie) {
168   const auto& key = cookie.UniqueKey();
169   EXPECT_TRUE(cookies_.find(key) == cookies_.end());
170   cookies_[key] = cookie;
171 }
172 
UpdateCookieAccessTime(const CanonicalCookie & cookie)173 void MockSimplePersistentCookieStore::UpdateCookieAccessTime(
174     const CanonicalCookie& cookie) {
175   const auto& key = cookie.UniqueKey();
176   ASSERT_TRUE(cookies_.find(key) != cookies_.end());
177   cookies_[key].SetLastAccessDate(base::Time::Now());
178 }
179 
DeleteCookie(const CanonicalCookie & cookie)180 void MockSimplePersistentCookieStore::DeleteCookie(
181     const CanonicalCookie& cookie) {
182   const auto& key = cookie.UniqueKey();
183   auto it = cookies_.find(key);
184   ASSERT_TRUE(it != cookies_.end());
185   cookies_.erase(it);
186 }
187 
SetForceKeepSessionState()188 void MockSimplePersistentCookieStore::SetForceKeepSessionState() {}
189 
SetBeforeCommitCallback(base::RepeatingClosure callback)190 void MockSimplePersistentCookieStore::SetBeforeCommitCallback(
191     base::RepeatingClosure callback) {}
192 
Flush(base::OnceClosure callback)193 void MockSimplePersistentCookieStore::Flush(base::OnceClosure callback) {
194   if (!callback.is_null())
195     base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
196         FROM_HERE, std::move(callback));
197 }
198 
CreateMonsterFromStoreForGC(int num_secure_cookies,int num_old_secure_cookies,int num_non_secure_cookies,int num_old_non_secure_cookies,int days_old)199 std::unique_ptr<CookieMonster> CreateMonsterFromStoreForGC(
200     int num_secure_cookies,
201     int num_old_secure_cookies,
202     int num_non_secure_cookies,
203     int num_old_non_secure_cookies,
204     int days_old) {
205   base::Time current(base::Time::Now());
206   base::Time past_creation(base::Time::Now() - base::Days(100));
207   auto store = base::MakeRefCounted<MockSimplePersistentCookieStore>();
208   int total_cookies = num_secure_cookies + num_non_secure_cookies;
209   int base = 0;
210   // Must expire to be persistent
211   for (int i = 0; i < total_cookies; i++) {
212     int num_old_cookies;
213     bool secure;
214     if (i < num_secure_cookies) {
215       num_old_cookies = num_old_secure_cookies;
216       secure = true;
217     } else {
218       base = num_secure_cookies;
219       num_old_cookies = num_old_non_secure_cookies;
220       secure = false;
221     }
222     base::Time creation_time = past_creation + base::Microseconds(i);
223     base::Time expiration_time = current + base::Days(30);
224     base::Time last_access_time = ((i - base) < num_old_cookies)
225                                       ? current - base::Days(days_old)
226                                       : current;
227 
228     // The URL must be HTTPS since |secure| can be true or false, and because
229     // strict secure cookies are enforced, the cookie will fail to be created if
230     // |secure| is true but the URL is an insecure scheme.
231     std::unique_ptr<CanonicalCookie> cc =
232         CanonicalCookie::CreateUnsafeCookieForTesting(
233             "a", "1", base::StringPrintf("h%05d.izzle", i), "/path",
234             creation_time, expiration_time, base::Time(), base::Time(), secure,
235             false, CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT);
236     cc->SetLastAccessDate(last_access_time);
237     store->AddCookie(*cc);
238   }
239 
240   return std::make_unique<CookieMonster>(store.get(), /*net_log=*/nullptr);
241 }
242 
243 MockSimplePersistentCookieStore::~MockSimplePersistentCookieStore() = default;
244 
245 }  // namespace net
246