1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/browsing_data/browsing_data_cookie_helper.h"
8 #include "base/run_loop.h"
9 #include "chrome/test/base/testing_profile.h"
10 #include "content/public/test/test_browser_thread_bundle.h"
11 #include "net/cookies/canonical_cookie.h"
12 #include "net/cookies/parsed_cookie.h"
13 #include "net/url_request/url_request_context_getter.h"
14 #include "testing/gtest/include/gtest/gtest.h"
18 class BrowsingDataCookieHelperTest : public testing::Test {
20 BrowsingDataCookieHelperTest()
21 : testing_profile_(new TestingProfile()) {
24 void CreateCookiesForTest() {
25 scoped_refptr<net::CookieMonster> cookie_monster =
26 testing_profile_->GetCookieMonster();
27 cookie_monster->SetCookieWithOptionsAsync(
28 GURL("http://www.google.com"), "A=1", net::CookieOptions(),
29 net::CookieMonster::SetCookiesCallback());
30 cookie_monster->SetCookieWithOptionsAsync(
31 GURL("http://www.gmail.google.com"), "B=1", net::CookieOptions(),
32 net::CookieMonster::SetCookiesCallback());
35 void CreateCookiesForDomainCookieTest() {
36 scoped_refptr<net::CookieMonster> cookie_monster =
37 testing_profile_->GetCookieMonster();
38 cookie_monster->SetCookieWithOptionsAsync(
39 GURL("http://www.google.com"), "A=1", net::CookieOptions(),
40 net::CookieMonster::SetCookiesCallback());
41 cookie_monster->SetCookieWithOptionsAsync(
42 GURL("http://www.google.com"), "A=2; Domain=.www.google.com ",
43 net::CookieOptions(), net::CookieMonster::SetCookiesCallback());
46 void FetchCallback(const net::CookieList& cookies) {
47 ASSERT_EQ(2UL, cookies.size());
48 cookie_list_ = cookies;
49 net::CookieList::const_iterator it = cookies.begin();
51 // Correct because fetching cookies will get a sorted cookie list.
52 ASSERT_TRUE(it != cookies.end());
53 EXPECT_EQ("www.google.com", it->Domain());
54 EXPECT_EQ("A", it->Name());
56 ASSERT_TRUE(++it != cookies.end());
57 EXPECT_EQ("www.gmail.google.com", it->Domain());
58 EXPECT_EQ("B", it->Name());
60 ASSERT_TRUE(++it == cookies.end());
63 void DomainCookieCallback(const net::CookieList& cookies) {
64 ASSERT_EQ(2UL, cookies.size());
65 cookie_list_ = cookies;
66 net::CookieList::const_iterator it = cookies.begin();
68 // Correct because fetching cookies will get a sorted cookie list.
69 ASSERT_TRUE(it != cookies.end());
70 EXPECT_EQ("www.google.com", it->Domain());
71 EXPECT_EQ("A", it->Name());
72 EXPECT_EQ("1", it->Value());
74 ASSERT_TRUE(++it != cookies.end());
75 EXPECT_EQ(".www.google.com", it->Domain());
76 EXPECT_EQ("A", it->Name());
77 EXPECT_EQ("2", it->Value());
79 ASSERT_TRUE(++it == cookies.end());
82 void DeleteCallback(const net::CookieList& cookies) {
83 ASSERT_EQ(1UL, cookies.size());
84 net::CookieList::const_iterator it = cookies.begin();
86 ASSERT_TRUE(it != cookies.end());
87 EXPECT_EQ("www.gmail.google.com", it->Domain());
88 EXPECT_EQ("B", it->Name());
90 ASSERT_TRUE(++it == cookies.end());
93 void CannedUniqueCallback(const net::CookieList& cookies) {
94 EXPECT_EQ(1UL, cookies.size());
95 cookie_list_ = cookies;
96 net::CookieList::const_iterator it = cookies.begin();
98 ASSERT_TRUE(it != cookies.end());
99 EXPECT_EQ("http://www.google.com/", it->Source());
100 EXPECT_EQ("www.google.com", it->Domain());
101 EXPECT_EQ("/", it->Path());
102 EXPECT_EQ("A", it->Name());
104 ASSERT_TRUE(++it == cookies.end());
107 void CannedReplaceCookieCallback(const net::CookieList& cookies) {
108 EXPECT_EQ(5UL, cookies.size());
109 cookie_list_ = cookies;
110 net::CookieList::const_iterator it = cookies.begin();
112 ASSERT_TRUE(it != cookies.end());
113 EXPECT_EQ("http://www.google.com/", it->Source());
114 EXPECT_EQ("www.google.com", it->Domain());
115 EXPECT_EQ("/", it->Path());
116 EXPECT_EQ("A", it->Name());
117 EXPECT_EQ("2", it->Value());
119 ASSERT_TRUE(++it != cookies.end());
120 EXPECT_EQ("http://www.google.com/", it->Source());
121 EXPECT_EQ("www.google.com", it->Domain());
122 EXPECT_EQ("/example/0", it->Path());
123 EXPECT_EQ("A", it->Name());
124 EXPECT_EQ("4", it->Value());
126 ASSERT_TRUE(++it != cookies.end());
127 EXPECT_EQ("http://www.google.com/", it->Source());
128 EXPECT_EQ(".google.com", it->Domain());
129 EXPECT_EQ("/", it->Path());
130 EXPECT_EQ("A", it->Name());
131 EXPECT_EQ("6", it->Value());
133 ASSERT_TRUE(++it != cookies.end());
134 EXPECT_EQ("http://www.google.com/", it->Source());
135 EXPECT_EQ(".google.com", it->Domain());
136 EXPECT_EQ("/example/1", it->Path());
137 EXPECT_EQ("A", it->Name());
138 EXPECT_EQ("8", it->Value());
140 ASSERT_TRUE(++it != cookies.end());
141 EXPECT_EQ("http://www.google.com/", it->Source());
142 EXPECT_EQ(".www.google.com", it->Domain());
143 EXPECT_EQ("/", it->Path());
144 EXPECT_EQ("A", it->Name());
145 EXPECT_EQ("10", it->Value());
147 ASSERT_TRUE(++it == cookies.end());
150 void CannedDomainCookieCallback(const net::CookieList& cookies) {
151 ASSERT_EQ(2UL, cookies.size());
152 cookie_list_ = cookies;
153 net::CookieList::const_iterator it = cookies.begin();
155 ASSERT_TRUE(it != cookies.end());
156 EXPECT_EQ("http://www.google.com/", it->Source());
157 EXPECT_EQ("A", it->Name());
158 EXPECT_EQ("www.google.com", it->Domain());
160 ASSERT_TRUE(++it != cookies.end());
161 EXPECT_EQ("http://www.google.com/", it->Source());
162 EXPECT_EQ("A", it->Name());
163 EXPECT_EQ(".www.google.com", it->Domain());
165 ASSERT_TRUE(++it == cookies.end());
168 void CannedDifferentFramesCallback(const net::CookieList& cookie_list) {
169 ASSERT_EQ(3U, cookie_list.size());
173 content::TestBrowserThreadBundle thread_bundle_;
174 scoped_ptr<TestingProfile> testing_profile_;
176 net::CookieList cookie_list_;
179 TEST_F(BrowsingDataCookieHelperTest, FetchData) {
180 CreateCookiesForTest();
181 scoped_refptr<BrowsingDataCookieHelper> cookie_helper(
182 new BrowsingDataCookieHelper(testing_profile_->GetRequestContext()));
184 cookie_helper->StartFetching(
185 base::Bind(&BrowsingDataCookieHelperTest::FetchCallback,
186 base::Unretained(this)));
187 base::RunLoop().RunUntilIdle();
190 TEST_F(BrowsingDataCookieHelperTest, DomainCookie) {
191 CreateCookiesForDomainCookieTest();
192 scoped_refptr<BrowsingDataCookieHelper> cookie_helper(
193 new BrowsingDataCookieHelper(testing_profile_->GetRequestContext()));
195 cookie_helper->StartFetching(
196 base::Bind(&BrowsingDataCookieHelperTest::DomainCookieCallback,
197 base::Unretained(this)));
198 base::RunLoop().RunUntilIdle();
201 TEST_F(BrowsingDataCookieHelperTest, DeleteCookie) {
202 CreateCookiesForTest();
203 scoped_refptr<BrowsingDataCookieHelper> cookie_helper(
204 new BrowsingDataCookieHelper(testing_profile_->GetRequestContext()));
206 cookie_helper->StartFetching(
207 base::Bind(&BrowsingDataCookieHelperTest::FetchCallback,
208 base::Unretained(this)));
209 base::RunLoop().RunUntilIdle();
211 net::CanonicalCookie cookie = cookie_list_[0];
212 cookie_helper->DeleteCookie(cookie);
214 cookie_helper->StartFetching(
215 base::Bind(&BrowsingDataCookieHelperTest::DeleteCallback,
216 base::Unretained(this)));
217 base::RunLoop().RunUntilIdle();
220 TEST_F(BrowsingDataCookieHelperTest, CannedDomainCookie) {
221 const GURL origin("http://www.google.com");
222 net::CookieList cookie;
224 scoped_refptr<CannedBrowsingDataCookieHelper> helper(
225 new CannedBrowsingDataCookieHelper(
226 testing_profile_->GetRequestContext()));
228 ASSERT_TRUE(helper->empty());
229 helper->AddChangedCookie(origin, origin, "A=1", net::CookieOptions());
230 helper->AddChangedCookie(origin, origin, "A=1; Domain=.www.google.com",
231 net::CookieOptions());
232 // Try adding invalid cookies that will be ignored.
233 helper->AddChangedCookie(origin, origin, std::string(), net::CookieOptions());
234 helper->AddChangedCookie(origin,
236 "C=bad guy; Domain=wrongdomain.com",
237 net::CookieOptions());
239 helper->StartFetching(
240 base::Bind(&BrowsingDataCookieHelperTest::CannedDomainCookieCallback,
241 base::Unretained(this)));
242 cookie = cookie_list_;
245 ASSERT_TRUE(helper->empty());
247 helper->AddReadCookies(origin, origin, cookie);
248 helper->StartFetching(
249 base::Bind(&BrowsingDataCookieHelperTest::CannedDomainCookieCallback,
250 base::Unretained(this)));
253 TEST_F(BrowsingDataCookieHelperTest, CannedUnique) {
254 const GURL origin("http://www.google.com");
255 net::CookieList cookie;
257 scoped_refptr<CannedBrowsingDataCookieHelper> helper(
258 new CannedBrowsingDataCookieHelper(
259 testing_profile_->GetRequestContext()));
261 ASSERT_TRUE(helper->empty());
262 helper->AddChangedCookie(origin, origin, "A=1", net::CookieOptions());
263 helper->AddChangedCookie(origin, origin, "A=1", net::CookieOptions());
264 helper->StartFetching(
265 base::Bind(&BrowsingDataCookieHelperTest::CannedUniqueCallback,
266 base::Unretained(this)));
268 cookie = cookie_list_;
270 ASSERT_TRUE(helper->empty());
272 helper->AddReadCookies(origin, origin, cookie);
273 helper->AddReadCookies(origin, origin, cookie);
274 helper->StartFetching(
275 base::Bind(&BrowsingDataCookieHelperTest::CannedUniqueCallback,
276 base::Unretained(this)));
279 TEST_F(BrowsingDataCookieHelperTest, CannedReplaceCookie) {
280 const GURL origin("http://www.google.com");
281 net::CookieList cookie;
283 scoped_refptr<CannedBrowsingDataCookieHelper> helper(
284 new CannedBrowsingDataCookieHelper(
285 testing_profile_->GetRequestContext()));
287 ASSERT_TRUE(helper->empty());
288 helper->AddChangedCookie(origin, origin, "A=1", net::CookieOptions());
289 helper->AddChangedCookie(origin, origin, "A=2", net::CookieOptions());
290 helper->AddChangedCookie(origin, origin, "A=3; Path=/example/0",
291 net::CookieOptions());
292 helper->AddChangedCookie(origin, origin, "A=4; Path=/example/0",
293 net::CookieOptions());
294 helper->AddChangedCookie(origin, origin, "A=5; Domain=google.com",
295 net::CookieOptions());
296 helper->AddChangedCookie(origin, origin, "A=6; Domain=google.com",
297 net::CookieOptions());
298 helper->AddChangedCookie(origin, origin,
299 "A=7; Domain=google.com; Path=/example/1",
300 net::CookieOptions());
301 helper->AddChangedCookie(origin, origin,
302 "A=8; Domain=google.com; Path=/example/1",
303 net::CookieOptions());
305 helper->AddChangedCookie(origin, origin,
306 "A=9; Domain=www.google.com",
307 net::CookieOptions());
308 helper->AddChangedCookie(origin, origin,
309 "A=10; Domain=www.google.com",
310 net::CookieOptions());
312 helper->StartFetching(
313 base::Bind(&BrowsingDataCookieHelperTest::CannedReplaceCookieCallback,
314 base::Unretained(this)));
316 cookie = cookie_list_;
318 ASSERT_TRUE(helper->empty());
320 helper->AddReadCookies(origin, origin, cookie);
321 helper->AddReadCookies(origin, origin, cookie);
322 helper->StartFetching(
323 base::Bind(&BrowsingDataCookieHelperTest::CannedReplaceCookieCallback,
324 base::Unretained(this)));
327 TEST_F(BrowsingDataCookieHelperTest, CannedEmpty) {
328 const GURL url_google("http://www.google.com");
330 scoped_refptr<CannedBrowsingDataCookieHelper> helper(
331 new CannedBrowsingDataCookieHelper(
332 testing_profile_->GetRequestContext()));
334 ASSERT_TRUE(helper->empty());
335 helper->AddChangedCookie(url_google, url_google, "a=1",
336 net::CookieOptions());
337 ASSERT_FALSE(helper->empty());
339 ASSERT_TRUE(helper->empty());
341 net::CookieList cookies;
342 net::ParsedCookie pc("a=1");
343 scoped_ptr<net::CanonicalCookie> cookie(
344 new net::CanonicalCookie(url_google, pc));
345 cookies.push_back(*cookie);
347 helper->AddReadCookies(url_google, url_google, cookies);
348 ASSERT_FALSE(helper->empty());
350 ASSERT_TRUE(helper->empty());
353 TEST_F(BrowsingDataCookieHelperTest, CannedDifferentFrames) {
354 GURL frame1_url("http://www.google.com");
355 GURL frame2_url("http://www.google.de");
356 GURL request_url("http://www.google.com");
358 scoped_refptr<CannedBrowsingDataCookieHelper> helper(
359 new CannedBrowsingDataCookieHelper(
360 testing_profile_->GetRequestContext()));
362 ASSERT_TRUE(helper->empty());
363 helper->AddChangedCookie(frame1_url, request_url, "a=1",
364 net::CookieOptions());
365 helper->AddChangedCookie(frame1_url, request_url, "b=1",
366 net::CookieOptions());
367 helper->AddChangedCookie(frame2_url, request_url, "c=1",
368 net::CookieOptions());
370 helper->StartFetching(
371 base::Bind(&BrowsingDataCookieHelperTest::CannedDifferentFramesCallback,
372 base::Unretained(this)));
375 TEST_F(BrowsingDataCookieHelperTest, CannedGetCookieCount) {
376 // The URL in the omnibox is a frame URL. This is not necessarily the request
377 // URL, since websites usually include other resources.
378 GURL frame1_url("http://www.google.com");
379 GURL frame2_url("http://www.google.de");
380 // The request URL used for all cookies that are added to the |helper|.
381 GURL request1_url("http://static.google.com/foo/res1.html");
382 GURL request2_url("http://static.google.com/bar/res2.html");
383 std::string cookie_domain(".www.google.com");
384 std::string cookie_pair1("A=1");
385 std::string cookie_pair2("B=1");
386 // The cookie pair used for adding a cookie that overrides the cookie created
387 // with |cookie_pair1|. The cookie-name of |cookie_pair3| must match the
388 // cookie-name of |cookie-pair1|.
389 std::string cookie_pair3("A=2");
390 // The cookie pair used for adding a non host-only cookie. The cookie-name
391 // must match the cookie-name of |cookie_pair1| in order to add a host-only
392 // and a non host-only cookie with the same name below.
393 std::string cookie_pair4("A=3");
395 scoped_refptr<CannedBrowsingDataCookieHelper> helper(
396 new CannedBrowsingDataCookieHelper(
397 testing_profile_->GetRequestContext()));
399 // Add two different cookies (distinguished by the tuple [cookie-name,
400 // domain-value, path-value]) for a HTTP request to |frame1_url| and verify
401 // that the cookie count is increased to two. The set-cookie-string consists
402 // only of the cookie-pair. This means that the host and the default-path of
403 // the |request_url| are used as domain-value and path-value for the added
405 EXPECT_EQ(0U, helper->GetCookieCount());
406 helper->AddChangedCookie(frame1_url, frame1_url, cookie_pair1,
407 net::CookieOptions());
408 EXPECT_EQ(1U, helper->GetCookieCount());
409 helper->AddChangedCookie(frame1_url, frame1_url, cookie_pair2,
410 net::CookieOptions());
411 EXPECT_EQ(2U, helper->GetCookieCount());
413 // Use a different frame URL for adding another cookie that will replace one
414 // of the previously added cookies. This could happen during an automatic
415 // redirect e.g. |frame1_url| redirects to |frame2_url| and a cookie set by a
416 // request to |frame1_url| is updated.
417 helper->AddChangedCookie(frame2_url, frame1_url, cookie_pair3,
418 net::CookieOptions());
419 EXPECT_EQ(2U, helper->GetCookieCount());
421 // Add two more cookies that are set while loading resources. The two cookies
422 // below have a differnt path-value since the request URLs have different
424 helper->AddChangedCookie(frame2_url, request1_url, cookie_pair3,
425 net::CookieOptions());
426 EXPECT_EQ(3U, helper->GetCookieCount());
427 helper->AddChangedCookie(frame2_url, request2_url, cookie_pair3,
428 net::CookieOptions());
429 EXPECT_EQ(4U, helper->GetCookieCount());
431 // Host-only and domain cookies are treated as seperate items. This means that
432 // the following two cookie-strings are stored as two separate cookies, even
433 // though they have the same name and are send with the same request:
435 // "A=3; Domain=www.google.com"
436 // Add a domain cookie and check if it increases the cookie count.
437 helper->AddChangedCookie(frame2_url, frame1_url,
438 cookie_pair4 + "; Domain=" + cookie_domain,
439 net::CookieOptions());
440 EXPECT_EQ(5U, helper->GetCookieCount());