Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / browsing_data / browsing_data_cookie_helper_unittest.cc
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.
4
5 #include "chrome/browser/browsing_data/browsing_data_cookie_helper.h"
6
7 #include "base/bind.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"
15
16 namespace {
17
18 // Test expectations for a given cookie.
19 class CookieExpectation {
20  public:
21   CookieExpectation() : matched_(false) {}
22
23   bool MatchesCookie(const net::CanonicalCookie& cookie) const {
24     if (!source_.empty() && source_ != cookie.Source())
25       return false;
26     if (!domain_.empty() && domain_ != cookie.Domain())
27       return false;
28     if (!path_.empty() && path_ != cookie.Path())
29       return false;
30     if (!name_.empty() && name_ != cookie.Name())
31       return false;
32     if (!value_.empty() && value_ != cookie.Value())
33       return false;
34     return true;
35   }
36
37   std::string source_;
38   std::string domain_;
39   std::string path_;
40   std::string name_;
41   std::string value_;
42   bool matched_;
43 };
44
45 // Matches a CookieExpectation against a Cookie.
46 class CookieMatcher {
47  public:
48   explicit CookieMatcher(const net::CanonicalCookie& cookie)
49       : cookie_(cookie) {}
50   bool operator()(const CookieExpectation& expectation) {
51     return expectation.MatchesCookie(cookie_);
52   }
53   net::CanonicalCookie cookie_;
54 };
55
56 // Unary predicate to determine whether an expectation has been matched.
57 bool ExpectationIsMatched(const CookieExpectation& expectation) {
58   return expectation.matched_;
59 }
60
61 class BrowsingDataCookieHelperTest : public testing::Test {
62  public:
63   BrowsingDataCookieHelperTest()
64       : testing_profile_(new TestingProfile()) {
65   }
66
67   virtual void SetUp() OVERRIDE { cookie_expectations_.clear(); }
68
69   // Adds an expectation for a cookie that satisfies the given parameters.
70   void AddCookieExpectation(const char* source,
71                             const char* domain,
72                             const char* path,
73                             const char* name,
74                             const char* value) {
75     CookieExpectation matcher;
76     if (source)
77       matcher.source_ = source;
78     if (domain)
79       matcher.domain_ = domain;
80     if (path)
81       matcher.path_ = path;
82     if (name)
83       matcher.name_ = name;
84     if (value)
85       matcher.value_ = value;
86     cookie_expectations_.push_back(matcher);
87   }
88
89   // Checks the existing expectations, and then clears all existing
90   // expectations.
91   void CheckCookieExpectations() {
92     ASSERT_EQ(cookie_expectations_.size(), cookie_list_.size());
93
94     // For each cookie, look for a matching expectation.
95     for (net::CookieList::iterator it = cookie_list_.begin();
96          it != cookie_list_.end();
97          ++it) {
98       CookieMatcher matcher(*it);
99       std::vector<CookieExpectation>::iterator match = std::find_if(
100           cookie_expectations_.begin(), cookie_expectations_.end(), matcher);
101       if (match != cookie_expectations_.end())
102         match->matched_ = true;
103     }
104
105     // Check that each expectation has been matched.
106     unsigned long match_count = std::count_if(cookie_expectations_.begin(),
107                                               cookie_expectations_.end(),
108                                               ExpectationIsMatched);
109     EXPECT_EQ(cookie_expectations_.size(), match_count);
110
111     cookie_expectations_.clear();
112   }
113
114   void CreateCookiesForTest() {
115     scoped_refptr<net::CookieMonster> cookie_monster =
116         testing_profile_->GetCookieMonster();
117     cookie_monster->SetCookieWithOptionsAsync(
118         GURL("http://www.google.com"), "A=1", net::CookieOptions(),
119         net::CookieMonster::SetCookiesCallback());
120     cookie_monster->SetCookieWithOptionsAsync(
121         GURL("http://www.gmail.google.com"), "B=1", net::CookieOptions(),
122         net::CookieMonster::SetCookiesCallback());
123   }
124
125   void CreateCookiesForDomainCookieTest() {
126     scoped_refptr<net::CookieMonster> cookie_monster =
127         testing_profile_->GetCookieMonster();
128     cookie_monster->SetCookieWithOptionsAsync(
129         GURL("http://www.google.com"), "A=1", net::CookieOptions(),
130         net::CookieMonster::SetCookiesCallback());
131     cookie_monster->SetCookieWithOptionsAsync(
132         GURL("http://www.google.com"), "A=2; Domain=.www.google.com ",
133         net::CookieOptions(), net::CookieMonster::SetCookiesCallback());
134   }
135
136   void FetchCallback(const net::CookieList& cookies) {
137     cookie_list_ = cookies;
138
139     AddCookieExpectation(NULL, "www.google.com", NULL, "A", NULL);
140     AddCookieExpectation(NULL, "www.gmail.google.com", NULL, "B", NULL);
141     CheckCookieExpectations();
142   }
143
144   void DomainCookieCallback(const net::CookieList& cookies) {
145     cookie_list_ = cookies;
146
147     AddCookieExpectation(NULL, "www.google.com", NULL, "A", "1");
148     AddCookieExpectation(NULL, ".www.google.com", NULL, "A", "2");
149     CheckCookieExpectations();
150   }
151
152   void DeleteCallback(const net::CookieList& cookies) {
153     cookie_list_ = cookies;
154     AddCookieExpectation(NULL, "www.gmail.google.com", NULL, "B", NULL);
155     CheckCookieExpectations();
156   }
157
158   void CannedUniqueCallback(const net::CookieList& cookies) {
159     cookie_list_ = cookies;
160     AddCookieExpectation(
161         "http://www.google.com/", "www.google.com", "/", "A", NULL);
162     CheckCookieExpectations();
163   }
164
165   void CannedReplaceCookieCallback(const net::CookieList& cookies) {
166     cookie_list_ = cookies;
167     AddCookieExpectation(
168         "http://www.google.com/", "www.google.com", "/", "A", "2");
169     AddCookieExpectation(
170         "http://www.google.com/", "www.google.com", "/example/0", "A", "4");
171     AddCookieExpectation(
172         "http://www.google.com/", ".google.com", "/", "A", "6");
173     AddCookieExpectation(
174         "http://www.google.com/", ".google.com", "/example/1", "A", "8");
175     AddCookieExpectation(
176         "http://www.google.com/", ".www.google.com", "/", "A", "10");
177     CheckCookieExpectations();
178   }
179
180   void CannedDomainCookieCallback(const net::CookieList& cookies) {
181     cookie_list_ = cookies;
182     AddCookieExpectation(
183         "http://www.google.com/", "www.google.com", NULL, "A", NULL);
184     AddCookieExpectation(
185         "http://www.google.com/", ".www.google.com", NULL, "A", NULL);
186     CheckCookieExpectations();
187   }
188
189   void CannedDifferentFramesCallback(const net::CookieList& cookie_list) {
190     ASSERT_EQ(3U, cookie_list.size());
191   }
192
193   void DeleteCookie(BrowsingDataCookieHelper* helper, const GURL origin) {
194     for (net::CookieList::iterator it = cookie_list_.begin();
195          it != cookie_list_.end();
196          ++it) {
197       if (it->Source() == net::CanonicalCookie::GetCookieSourceFromURL(origin))
198         helper->DeleteCookie(*it);
199     }
200   }
201
202  protected:
203   content::TestBrowserThreadBundle thread_bundle_;
204   scoped_ptr<TestingProfile> testing_profile_;
205
206   std::vector<CookieExpectation> cookie_expectations_;
207   net::CookieList cookie_list_;
208 };
209
210 TEST_F(BrowsingDataCookieHelperTest, FetchData) {
211   CreateCookiesForTest();
212   scoped_refptr<BrowsingDataCookieHelper> cookie_helper(
213       new BrowsingDataCookieHelper(testing_profile_->GetRequestContext()));
214
215   cookie_helper->StartFetching(
216       base::Bind(&BrowsingDataCookieHelperTest::FetchCallback,
217                  base::Unretained(this)));
218   base::RunLoop().RunUntilIdle();
219 }
220
221 TEST_F(BrowsingDataCookieHelperTest, DomainCookie) {
222   CreateCookiesForDomainCookieTest();
223   scoped_refptr<BrowsingDataCookieHelper> cookie_helper(
224       new BrowsingDataCookieHelper(testing_profile_->GetRequestContext()));
225
226   cookie_helper->StartFetching(
227       base::Bind(&BrowsingDataCookieHelperTest::DomainCookieCallback,
228                  base::Unretained(this)));
229   base::RunLoop().RunUntilIdle();
230 }
231
232 TEST_F(BrowsingDataCookieHelperTest, DeleteCookie) {
233   CreateCookiesForTest();
234   scoped_refptr<BrowsingDataCookieHelper> cookie_helper(
235       new BrowsingDataCookieHelper(testing_profile_->GetRequestContext()));
236
237   cookie_helper->StartFetching(
238       base::Bind(&BrowsingDataCookieHelperTest::FetchCallback,
239                  base::Unretained(this)));
240   base::RunLoop().RunUntilIdle();
241
242   net::CanonicalCookie cookie = cookie_list_[0];
243   cookie_helper->DeleteCookie(cookie);
244
245   cookie_helper->StartFetching(
246       base::Bind(&BrowsingDataCookieHelperTest::DeleteCallback,
247                  base::Unretained(this)));
248   base::RunLoop().RunUntilIdle();
249 }
250
251 TEST_F(BrowsingDataCookieHelperTest, CannedDeleteCookie) {
252   CreateCookiesForTest();
253   scoped_refptr<CannedBrowsingDataCookieHelper> helper(
254       new CannedBrowsingDataCookieHelper(
255           testing_profile_->GetRequestContext()));
256
257   ASSERT_TRUE(helper->empty());
258
259   const GURL origin1("http://www.google.com");
260   const GURL origin2("http://www.gmail.google.com");
261   helper->AddChangedCookie(origin1, origin1, "A=1", net::CookieOptions());
262   helper->AddChangedCookie(origin2, origin2, "B=1", net::CookieOptions());
263
264   helper->StartFetching(
265       base::Bind(&BrowsingDataCookieHelperTest::FetchCallback,
266                  base::Unretained(this)));
267   base::RunLoop().RunUntilIdle();
268
269   EXPECT_EQ(2u, helper->GetCookieCount());
270
271   DeleteCookie(helper.get(), origin1);
272
273   EXPECT_EQ(1u, helper->GetCookieCount());
274   helper->StartFetching(
275       base::Bind(&BrowsingDataCookieHelperTest::DeleteCallback,
276                  base::Unretained(this)));
277   base::RunLoop().RunUntilIdle();
278 }
279
280 TEST_F(BrowsingDataCookieHelperTest, CannedDomainCookie) {
281   const GURL origin("http://www.google.com");
282   net::CookieList cookie;
283
284   scoped_refptr<CannedBrowsingDataCookieHelper> helper(
285       new CannedBrowsingDataCookieHelper(
286           testing_profile_->GetRequestContext()));
287
288   ASSERT_TRUE(helper->empty());
289   helper->AddChangedCookie(origin, origin, "A=1", net::CookieOptions());
290   helper->AddChangedCookie(origin, origin, "A=1; Domain=.www.google.com",
291                            net::CookieOptions());
292   // Try adding invalid cookies that will be ignored.
293   helper->AddChangedCookie(origin, origin, std::string(), net::CookieOptions());
294   helper->AddChangedCookie(origin,
295                            origin,
296                            "C=bad guy; Domain=wrongdomain.com",
297                            net::CookieOptions());
298
299   helper->StartFetching(
300       base::Bind(&BrowsingDataCookieHelperTest::CannedDomainCookieCallback,
301                  base::Unretained(this)));
302   cookie = cookie_list_;
303
304   helper->Reset();
305   ASSERT_TRUE(helper->empty());
306
307   helper->AddReadCookies(origin, origin, cookie);
308   helper->StartFetching(
309       base::Bind(&BrowsingDataCookieHelperTest::CannedDomainCookieCallback,
310                  base::Unretained(this)));
311 }
312
313 TEST_F(BrowsingDataCookieHelperTest, CannedUnique) {
314   const GURL origin("http://www.google.com");
315   net::CookieList cookie;
316
317   scoped_refptr<CannedBrowsingDataCookieHelper> helper(
318       new CannedBrowsingDataCookieHelper(
319           testing_profile_->GetRequestContext()));
320
321   ASSERT_TRUE(helper->empty());
322   helper->AddChangedCookie(origin, origin, "A=1", net::CookieOptions());
323   helper->AddChangedCookie(origin, origin, "A=1", net::CookieOptions());
324   helper->StartFetching(
325       base::Bind(&BrowsingDataCookieHelperTest::CannedUniqueCallback,
326                  base::Unretained(this)));
327
328   cookie = cookie_list_;
329   helper->Reset();
330   ASSERT_TRUE(helper->empty());
331
332   helper->AddReadCookies(origin, origin, cookie);
333   helper->AddReadCookies(origin, origin, cookie);
334   helper->StartFetching(
335       base::Bind(&BrowsingDataCookieHelperTest::CannedUniqueCallback,
336                  base::Unretained(this)));
337 }
338
339 TEST_F(BrowsingDataCookieHelperTest, CannedReplaceCookie) {
340   const GURL origin("http://www.google.com");
341   net::CookieList cookie;
342
343   scoped_refptr<CannedBrowsingDataCookieHelper> helper(
344       new CannedBrowsingDataCookieHelper(
345           testing_profile_->GetRequestContext()));
346
347   ASSERT_TRUE(helper->empty());
348   helper->AddChangedCookie(origin, origin, "A=1", net::CookieOptions());
349   helper->AddChangedCookie(origin, origin, "A=2", net::CookieOptions());
350   helper->AddChangedCookie(origin, origin, "A=3; Path=/example/0",
351                            net::CookieOptions());
352   helper->AddChangedCookie(origin, origin, "A=4; Path=/example/0",
353                            net::CookieOptions());
354   helper->AddChangedCookie(origin, origin, "A=5; Domain=google.com",
355                            net::CookieOptions());
356   helper->AddChangedCookie(origin, origin, "A=6; Domain=google.com",
357                            net::CookieOptions());
358   helper->AddChangedCookie(origin, origin,
359                            "A=7; Domain=google.com; Path=/example/1",
360                            net::CookieOptions());
361   helper->AddChangedCookie(origin, origin,
362                            "A=8; Domain=google.com; Path=/example/1",
363                            net::CookieOptions());
364
365   helper->AddChangedCookie(origin, origin,
366                           "A=9; Domain=www.google.com",
367                            net::CookieOptions());
368   helper->AddChangedCookie(origin, origin,
369                            "A=10; Domain=www.google.com",
370                            net::CookieOptions());
371
372   helper->StartFetching(
373       base::Bind(&BrowsingDataCookieHelperTest::CannedReplaceCookieCallback,
374                  base::Unretained(this)));
375
376   cookie = cookie_list_;
377   helper->Reset();
378   ASSERT_TRUE(helper->empty());
379
380   helper->AddReadCookies(origin, origin, cookie);
381   helper->AddReadCookies(origin, origin, cookie);
382   helper->StartFetching(
383       base::Bind(&BrowsingDataCookieHelperTest::CannedReplaceCookieCallback,
384                  base::Unretained(this)));
385 }
386
387 TEST_F(BrowsingDataCookieHelperTest, CannedEmpty) {
388   const GURL url_google("http://www.google.com");
389
390   scoped_refptr<CannedBrowsingDataCookieHelper> helper(
391       new CannedBrowsingDataCookieHelper(
392           testing_profile_->GetRequestContext()));
393
394   ASSERT_TRUE(helper->empty());
395   helper->AddChangedCookie(url_google, url_google, "a=1",
396                           net::CookieOptions());
397   ASSERT_FALSE(helper->empty());
398   helper->Reset();
399   ASSERT_TRUE(helper->empty());
400
401   net::CookieList cookies;
402   net::ParsedCookie pc("a=1");
403   scoped_ptr<net::CanonicalCookie> cookie(
404       new net::CanonicalCookie(url_google, pc));
405   cookies.push_back(*cookie);
406
407   helper->AddReadCookies(url_google, url_google, cookies);
408   ASSERT_FALSE(helper->empty());
409   helper->Reset();
410   ASSERT_TRUE(helper->empty());
411 }
412
413 TEST_F(BrowsingDataCookieHelperTest, CannedDifferentFrames) {
414   GURL frame1_url("http://www.google.com");
415   GURL frame2_url("http://www.google.de");
416   GURL request_url("http://www.google.com");
417
418   scoped_refptr<CannedBrowsingDataCookieHelper> helper(
419       new CannedBrowsingDataCookieHelper(
420           testing_profile_->GetRequestContext()));
421
422   ASSERT_TRUE(helper->empty());
423   helper->AddChangedCookie(frame1_url, request_url, "a=1",
424                            net::CookieOptions());
425   helper->AddChangedCookie(frame1_url, request_url, "b=1",
426                            net::CookieOptions());
427   helper->AddChangedCookie(frame2_url, request_url, "c=1",
428                            net::CookieOptions());
429
430   helper->StartFetching(
431       base::Bind(&BrowsingDataCookieHelperTest::CannedDifferentFramesCallback,
432                  base::Unretained(this)));
433 }
434
435 TEST_F(BrowsingDataCookieHelperTest, CannedGetCookieCount) {
436   // The URL in the omnibox is a frame URL. This is not necessarily the request
437   // URL, since websites usually include other resources.
438   GURL frame1_url("http://www.google.com");
439   GURL frame2_url("http://www.google.de");
440   // The request URL used for all cookies that are added to the |helper|.
441   GURL request1_url("http://static.google.com/foo/res1.html");
442   GURL request2_url("http://static.google.com/bar/res2.html");
443   std::string cookie_domain(".www.google.com");
444   std::string cookie_pair1("A=1");
445   std::string cookie_pair2("B=1");
446   // The cookie pair used for adding a cookie that overrides the cookie created
447   // with |cookie_pair1|. The cookie-name of |cookie_pair3| must match the
448   // cookie-name of |cookie-pair1|.
449   std::string cookie_pair3("A=2");
450   // The cookie pair used for adding a non host-only cookie. The cookie-name
451   // must match the cookie-name of |cookie_pair1| in order to add a host-only
452   // and a non host-only cookie with the same name below.
453   std::string cookie_pair4("A=3");
454
455   scoped_refptr<CannedBrowsingDataCookieHelper> helper(
456       new CannedBrowsingDataCookieHelper(
457           testing_profile_->GetRequestContext()));
458
459   // Add two different cookies (distinguished by the tuple [cookie-name,
460   // domain-value, path-value]) for a HTTP request to |frame1_url| and verify
461   // that the cookie count is increased to two. The set-cookie-string consists
462   // only of the cookie-pair. This means that the host and the default-path of
463   // the |request_url| are used as domain-value and path-value for the added
464   // cookies.
465   EXPECT_EQ(0U, helper->GetCookieCount());
466   helper->AddChangedCookie(frame1_url, frame1_url, cookie_pair1,
467                            net::CookieOptions());
468   EXPECT_EQ(1U, helper->GetCookieCount());
469   helper->AddChangedCookie(frame1_url, frame1_url, cookie_pair2,
470                            net::CookieOptions());
471   EXPECT_EQ(2U, helper->GetCookieCount());
472
473   // Use a different frame URL for adding another cookie that will replace one
474   // of the previously added cookies. This could happen during an automatic
475   // redirect e.g. |frame1_url| redirects to |frame2_url| and a cookie set by a
476   // request to |frame1_url| is updated.
477   helper->AddChangedCookie(frame2_url, frame1_url, cookie_pair3,
478                            net::CookieOptions());
479   EXPECT_EQ(2U, helper->GetCookieCount());
480
481   // Add two more cookies that are set while loading resources. The two cookies
482   // below have a differnt path-value since the request URLs have different
483   // paths.
484   helper->AddChangedCookie(frame2_url, request1_url, cookie_pair3,
485                            net::CookieOptions());
486   EXPECT_EQ(3U, helper->GetCookieCount());
487   helper->AddChangedCookie(frame2_url, request2_url, cookie_pair3,
488                            net::CookieOptions());
489   EXPECT_EQ(4U, helper->GetCookieCount());
490
491   // Host-only and domain cookies are treated as seperate items. This means that
492   // the following two cookie-strings are stored as two separate cookies, even
493   // though they have the same name and are send with the same request:
494   //   "A=1;
495   //   "A=3; Domain=www.google.com"
496   // Add a domain cookie and check if it increases the cookie count.
497   helper->AddChangedCookie(frame2_url, frame1_url,
498                            cookie_pair4 + "; Domain=" + cookie_domain,
499                            net::CookieOptions());
500   EXPECT_EQ(5U, helper->GetCookieCount());
501 }
502
503 }  // namespace