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
, CannedDeleteCookie
) {
221 CreateCookiesForTest();
222 scoped_refptr
<CannedBrowsingDataCookieHelper
> helper(
223 new CannedBrowsingDataCookieHelper(
224 testing_profile_
->GetRequestContext()));
226 ASSERT_TRUE(helper
->empty());
228 const GURL
origin1("http://www.google.com");
229 const GURL
origin2("http://www.gmail.google.com");
230 helper
->AddChangedCookie(origin1
, origin1
, "A=1", net::CookieOptions());
231 helper
->AddChangedCookie(origin2
, origin2
, "B=1", net::CookieOptions());
233 helper
->StartFetching(
234 base::Bind(&BrowsingDataCookieHelperTest::FetchCallback
,
235 base::Unretained(this)));
236 base::RunLoop().RunUntilIdle();
238 EXPECT_EQ(2u, helper
->GetCookieCount());
240 helper
->DeleteCookie(cookie_list_
[0]);
242 EXPECT_EQ(1u, helper
->GetCookieCount());
243 helper
->StartFetching(
244 base::Bind(&BrowsingDataCookieHelperTest::DeleteCallback
,
245 base::Unretained(this)));
246 base::RunLoop().RunUntilIdle();
249 TEST_F(BrowsingDataCookieHelperTest
, CannedDomainCookie
) {
250 const GURL
origin("http://www.google.com");
251 net::CookieList cookie
;
253 scoped_refptr
<CannedBrowsingDataCookieHelper
> helper(
254 new CannedBrowsingDataCookieHelper(
255 testing_profile_
->GetRequestContext()));
257 ASSERT_TRUE(helper
->empty());
258 helper
->AddChangedCookie(origin
, origin
, "A=1", net::CookieOptions());
259 helper
->AddChangedCookie(origin
, origin
, "A=1; Domain=.www.google.com",
260 net::CookieOptions());
261 // Try adding invalid cookies that will be ignored.
262 helper
->AddChangedCookie(origin
, origin
, std::string(), net::CookieOptions());
263 helper
->AddChangedCookie(origin
,
265 "C=bad guy; Domain=wrongdomain.com",
266 net::CookieOptions());
268 helper
->StartFetching(
269 base::Bind(&BrowsingDataCookieHelperTest::CannedDomainCookieCallback
,
270 base::Unretained(this)));
271 cookie
= cookie_list_
;
274 ASSERT_TRUE(helper
->empty());
276 helper
->AddReadCookies(origin
, origin
, cookie
);
277 helper
->StartFetching(
278 base::Bind(&BrowsingDataCookieHelperTest::CannedDomainCookieCallback
,
279 base::Unretained(this)));
282 TEST_F(BrowsingDataCookieHelperTest
, CannedUnique
) {
283 const GURL
origin("http://www.google.com");
284 net::CookieList cookie
;
286 scoped_refptr
<CannedBrowsingDataCookieHelper
> helper(
287 new CannedBrowsingDataCookieHelper(
288 testing_profile_
->GetRequestContext()));
290 ASSERT_TRUE(helper
->empty());
291 helper
->AddChangedCookie(origin
, origin
, "A=1", net::CookieOptions());
292 helper
->AddChangedCookie(origin
, origin
, "A=1", net::CookieOptions());
293 helper
->StartFetching(
294 base::Bind(&BrowsingDataCookieHelperTest::CannedUniqueCallback
,
295 base::Unretained(this)));
297 cookie
= cookie_list_
;
299 ASSERT_TRUE(helper
->empty());
301 helper
->AddReadCookies(origin
, origin
, cookie
);
302 helper
->AddReadCookies(origin
, origin
, cookie
);
303 helper
->StartFetching(
304 base::Bind(&BrowsingDataCookieHelperTest::CannedUniqueCallback
,
305 base::Unretained(this)));
308 TEST_F(BrowsingDataCookieHelperTest
, CannedReplaceCookie
) {
309 const GURL
origin("http://www.google.com");
310 net::CookieList cookie
;
312 scoped_refptr
<CannedBrowsingDataCookieHelper
> helper(
313 new CannedBrowsingDataCookieHelper(
314 testing_profile_
->GetRequestContext()));
316 ASSERT_TRUE(helper
->empty());
317 helper
->AddChangedCookie(origin
, origin
, "A=1", net::CookieOptions());
318 helper
->AddChangedCookie(origin
, origin
, "A=2", net::CookieOptions());
319 helper
->AddChangedCookie(origin
, origin
, "A=3; Path=/example/0",
320 net::CookieOptions());
321 helper
->AddChangedCookie(origin
, origin
, "A=4; Path=/example/0",
322 net::CookieOptions());
323 helper
->AddChangedCookie(origin
, origin
, "A=5; Domain=google.com",
324 net::CookieOptions());
325 helper
->AddChangedCookie(origin
, origin
, "A=6; Domain=google.com",
326 net::CookieOptions());
327 helper
->AddChangedCookie(origin
, origin
,
328 "A=7; Domain=google.com; Path=/example/1",
329 net::CookieOptions());
330 helper
->AddChangedCookie(origin
, origin
,
331 "A=8; Domain=google.com; Path=/example/1",
332 net::CookieOptions());
334 helper
->AddChangedCookie(origin
, origin
,
335 "A=9; Domain=www.google.com",
336 net::CookieOptions());
337 helper
->AddChangedCookie(origin
, origin
,
338 "A=10; Domain=www.google.com",
339 net::CookieOptions());
341 helper
->StartFetching(
342 base::Bind(&BrowsingDataCookieHelperTest::CannedReplaceCookieCallback
,
343 base::Unretained(this)));
345 cookie
= cookie_list_
;
347 ASSERT_TRUE(helper
->empty());
349 helper
->AddReadCookies(origin
, origin
, cookie
);
350 helper
->AddReadCookies(origin
, origin
, cookie
);
351 helper
->StartFetching(
352 base::Bind(&BrowsingDataCookieHelperTest::CannedReplaceCookieCallback
,
353 base::Unretained(this)));
356 TEST_F(BrowsingDataCookieHelperTest
, CannedEmpty
) {
357 const GURL
url_google("http://www.google.com");
359 scoped_refptr
<CannedBrowsingDataCookieHelper
> helper(
360 new CannedBrowsingDataCookieHelper(
361 testing_profile_
->GetRequestContext()));
363 ASSERT_TRUE(helper
->empty());
364 helper
->AddChangedCookie(url_google
, url_google
, "a=1",
365 net::CookieOptions());
366 ASSERT_FALSE(helper
->empty());
368 ASSERT_TRUE(helper
->empty());
370 net::CookieList cookies
;
371 net::ParsedCookie
pc("a=1");
372 scoped_ptr
<net::CanonicalCookie
> cookie(
373 new net::CanonicalCookie(url_google
, pc
));
374 cookies
.push_back(*cookie
);
376 helper
->AddReadCookies(url_google
, url_google
, cookies
);
377 ASSERT_FALSE(helper
->empty());
379 ASSERT_TRUE(helper
->empty());
382 TEST_F(BrowsingDataCookieHelperTest
, CannedDifferentFrames
) {
383 GURL
frame1_url("http://www.google.com");
384 GURL
frame2_url("http://www.google.de");
385 GURL
request_url("http://www.google.com");
387 scoped_refptr
<CannedBrowsingDataCookieHelper
> helper(
388 new CannedBrowsingDataCookieHelper(
389 testing_profile_
->GetRequestContext()));
391 ASSERT_TRUE(helper
->empty());
392 helper
->AddChangedCookie(frame1_url
, request_url
, "a=1",
393 net::CookieOptions());
394 helper
->AddChangedCookie(frame1_url
, request_url
, "b=1",
395 net::CookieOptions());
396 helper
->AddChangedCookie(frame2_url
, request_url
, "c=1",
397 net::CookieOptions());
399 helper
->StartFetching(
400 base::Bind(&BrowsingDataCookieHelperTest::CannedDifferentFramesCallback
,
401 base::Unretained(this)));
404 TEST_F(BrowsingDataCookieHelperTest
, CannedGetCookieCount
) {
405 // The URL in the omnibox is a frame URL. This is not necessarily the request
406 // URL, since websites usually include other resources.
407 GURL
frame1_url("http://www.google.com");
408 GURL
frame2_url("http://www.google.de");
409 // The request URL used for all cookies that are added to the |helper|.
410 GURL
request1_url("http://static.google.com/foo/res1.html");
411 GURL
request2_url("http://static.google.com/bar/res2.html");
412 std::string
cookie_domain(".www.google.com");
413 std::string
cookie_pair1("A=1");
414 std::string
cookie_pair2("B=1");
415 // The cookie pair used for adding a cookie that overrides the cookie created
416 // with |cookie_pair1|. The cookie-name of |cookie_pair3| must match the
417 // cookie-name of |cookie-pair1|.
418 std::string
cookie_pair3("A=2");
419 // The cookie pair used for adding a non host-only cookie. The cookie-name
420 // must match the cookie-name of |cookie_pair1| in order to add a host-only
421 // and a non host-only cookie with the same name below.
422 std::string
cookie_pair4("A=3");
424 scoped_refptr
<CannedBrowsingDataCookieHelper
> helper(
425 new CannedBrowsingDataCookieHelper(
426 testing_profile_
->GetRequestContext()));
428 // Add two different cookies (distinguished by the tuple [cookie-name,
429 // domain-value, path-value]) for a HTTP request to |frame1_url| and verify
430 // that the cookie count is increased to two. The set-cookie-string consists
431 // only of the cookie-pair. This means that the host and the default-path of
432 // the |request_url| are used as domain-value and path-value for the added
434 EXPECT_EQ(0U, helper
->GetCookieCount());
435 helper
->AddChangedCookie(frame1_url
, frame1_url
, cookie_pair1
,
436 net::CookieOptions());
437 EXPECT_EQ(1U, helper
->GetCookieCount());
438 helper
->AddChangedCookie(frame1_url
, frame1_url
, cookie_pair2
,
439 net::CookieOptions());
440 EXPECT_EQ(2U, helper
->GetCookieCount());
442 // Use a different frame URL for adding another cookie that will replace one
443 // of the previously added cookies. This could happen during an automatic
444 // redirect e.g. |frame1_url| redirects to |frame2_url| and a cookie set by a
445 // request to |frame1_url| is updated.
446 helper
->AddChangedCookie(frame2_url
, frame1_url
, cookie_pair3
,
447 net::CookieOptions());
448 EXPECT_EQ(2U, helper
->GetCookieCount());
450 // Add two more cookies that are set while loading resources. The two cookies
451 // below have a differnt path-value since the request URLs have different
453 helper
->AddChangedCookie(frame2_url
, request1_url
, cookie_pair3
,
454 net::CookieOptions());
455 EXPECT_EQ(3U, helper
->GetCookieCount());
456 helper
->AddChangedCookie(frame2_url
, request2_url
, cookie_pair3
,
457 net::CookieOptions());
458 EXPECT_EQ(4U, helper
->GetCookieCount());
460 // Host-only and domain cookies are treated as seperate items. This means that
461 // the following two cookie-strings are stored as two separate cookies, even
462 // though they have the same name and are send with the same request:
464 // "A=3; Domain=www.google.com"
465 // Add a domain cookie and check if it increases the cookie count.
466 helper
->AddChangedCookie(frame2_url
, frame1_url
,
467 cookie_pair4
+ "; Domain=" + cookie_domain
,
468 net::CookieOptions());
469 EXPECT_EQ(5U, helper
->GetCookieCount());