Home | History | Annotate | Download | only in browsing_data
      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 class BrowsingDataCookieHelperTest : public testing::Test {
     19  public:
     20   BrowsingDataCookieHelperTest()
     21       : testing_profile_(new TestingProfile()) {
     22   }
     23 
     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());
     33   }
     34 
     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());
     44   }
     45 
     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();
     50 
     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());
     55 
     56     ASSERT_TRUE(++it != cookies.end());
     57     EXPECT_EQ("www.gmail.google.com", it->Domain());
     58     EXPECT_EQ("B", it->Name());
     59 
     60     ASSERT_TRUE(++it == cookies.end());
     61   }
     62 
     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();
     67 
     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());
     73 
     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());
     78 
     79     ASSERT_TRUE(++it == cookies.end());
     80   }
     81 
     82   void DeleteCallback(const net::CookieList& cookies) {
     83     ASSERT_EQ(1UL, cookies.size());
     84     net::CookieList::const_iterator it = cookies.begin();
     85 
     86     ASSERT_TRUE(it != cookies.end());
     87     EXPECT_EQ("www.gmail.google.com", it->Domain());
     88     EXPECT_EQ("B", it->Name());
     89 
     90     ASSERT_TRUE(++it == cookies.end());
     91   }
     92 
     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();
     97 
     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());
    103 
    104     ASSERT_TRUE(++it == cookies.end());
    105   }
    106 
    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();
    111 
    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());
    118 
    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());
    125 
    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());
    132 
    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());
    139 
    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());
    146 
    147     ASSERT_TRUE(++it == cookies.end());
    148   }
    149 
    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();
    154 
    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());
    159 
    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());
    164 
    165     ASSERT_TRUE(++it == cookies.end());
    166   }
    167 
    168   void CannedDifferentFramesCallback(const net::CookieList& cookie_list) {
    169     ASSERT_EQ(3U, cookie_list.size());
    170   }
    171 
    172  protected:
    173   content::TestBrowserThreadBundle thread_bundle_;
    174   scoped_ptr<TestingProfile> testing_profile_;
    175 
    176   net::CookieList cookie_list_;
    177 };
    178 
    179 TEST_F(BrowsingDataCookieHelperTest, FetchData) {
    180   CreateCookiesForTest();
    181   scoped_refptr<BrowsingDataCookieHelper> cookie_helper(
    182       new BrowsingDataCookieHelper(testing_profile_->GetRequestContext()));
    183 
    184   cookie_helper->StartFetching(
    185       base::Bind(&BrowsingDataCookieHelperTest::FetchCallback,
    186                  base::Unretained(this)));
    187   base::RunLoop().RunUntilIdle();
    188 }
    189 
    190 TEST_F(BrowsingDataCookieHelperTest, DomainCookie) {
    191   CreateCookiesForDomainCookieTest();
    192   scoped_refptr<BrowsingDataCookieHelper> cookie_helper(
    193       new BrowsingDataCookieHelper(testing_profile_->GetRequestContext()));
    194 
    195   cookie_helper->StartFetching(
    196       base::Bind(&BrowsingDataCookieHelperTest::DomainCookieCallback,
    197                  base::Unretained(this)));
    198   base::RunLoop().RunUntilIdle();
    199 }
    200 
    201 TEST_F(BrowsingDataCookieHelperTest, DeleteCookie) {
    202   CreateCookiesForTest();
    203   scoped_refptr<BrowsingDataCookieHelper> cookie_helper(
    204       new BrowsingDataCookieHelper(testing_profile_->GetRequestContext()));
    205 
    206   cookie_helper->StartFetching(
    207       base::Bind(&BrowsingDataCookieHelperTest::FetchCallback,
    208                  base::Unretained(this)));
    209   base::RunLoop().RunUntilIdle();
    210 
    211   net::CanonicalCookie cookie = cookie_list_[0];
    212   cookie_helper->DeleteCookie(cookie);
    213 
    214   cookie_helper->StartFetching(
    215       base::Bind(&BrowsingDataCookieHelperTest::DeleteCallback,
    216                  base::Unretained(this)));
    217   base::RunLoop().RunUntilIdle();
    218 }
    219 
    220 TEST_F(BrowsingDataCookieHelperTest, CannedDomainCookie) {
    221   const GURL origin("http://www.google.com");
    222   net::CookieList cookie;
    223 
    224   scoped_refptr<CannedBrowsingDataCookieHelper> helper(
    225       new CannedBrowsingDataCookieHelper(
    226           testing_profile_->GetRequestContext()));
    227 
    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,
    235                            origin,
    236                            "C=bad guy; Domain=wrongdomain.com",
    237                            net::CookieOptions());
    238 
    239   helper->StartFetching(
    240       base::Bind(&BrowsingDataCookieHelperTest::CannedDomainCookieCallback,
    241                  base::Unretained(this)));
    242   cookie = cookie_list_;
    243 
    244   helper->Reset();
    245   ASSERT_TRUE(helper->empty());
    246 
    247   helper->AddReadCookies(origin, origin, cookie);
    248   helper->StartFetching(
    249       base::Bind(&BrowsingDataCookieHelperTest::CannedDomainCookieCallback,
    250                  base::Unretained(this)));
    251 }
    252 
    253 TEST_F(BrowsingDataCookieHelperTest, CannedUnique) {
    254   const GURL origin("http://www.google.com");
    255   net::CookieList cookie;
    256 
    257   scoped_refptr<CannedBrowsingDataCookieHelper> helper(
    258       new CannedBrowsingDataCookieHelper(
    259           testing_profile_->GetRequestContext()));
    260 
    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)));
    267 
    268   cookie = cookie_list_;
    269   helper->Reset();
    270   ASSERT_TRUE(helper->empty());
    271 
    272   helper->AddReadCookies(origin, origin, cookie);
    273   helper->AddReadCookies(origin, origin, cookie);
    274   helper->StartFetching(
    275       base::Bind(&BrowsingDataCookieHelperTest::CannedUniqueCallback,
    276                  base::Unretained(this)));
    277 }
    278 
    279 TEST_F(BrowsingDataCookieHelperTest, CannedReplaceCookie) {
    280   const GURL origin("http://www.google.com");
    281   net::CookieList cookie;
    282 
    283   scoped_refptr<CannedBrowsingDataCookieHelper> helper(
    284       new CannedBrowsingDataCookieHelper(
    285           testing_profile_->GetRequestContext()));
    286 
    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());
    304 
    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());
    311 
    312   helper->StartFetching(
    313       base::Bind(&BrowsingDataCookieHelperTest::CannedReplaceCookieCallback,
    314                  base::Unretained(this)));
    315 
    316   cookie = cookie_list_;
    317   helper->Reset();
    318   ASSERT_TRUE(helper->empty());
    319 
    320   helper->AddReadCookies(origin, origin, cookie);
    321   helper->AddReadCookies(origin, origin, cookie);
    322   helper->StartFetching(
    323       base::Bind(&BrowsingDataCookieHelperTest::CannedReplaceCookieCallback,
    324                  base::Unretained(this)));
    325 }
    326 
    327 TEST_F(BrowsingDataCookieHelperTest, CannedEmpty) {
    328   const GURL url_google("http://www.google.com");
    329 
    330   scoped_refptr<CannedBrowsingDataCookieHelper> helper(
    331       new CannedBrowsingDataCookieHelper(
    332           testing_profile_->GetRequestContext()));
    333 
    334   ASSERT_TRUE(helper->empty());
    335   helper->AddChangedCookie(url_google, url_google, "a=1",
    336                           net::CookieOptions());
    337   ASSERT_FALSE(helper->empty());
    338   helper->Reset();
    339   ASSERT_TRUE(helper->empty());
    340 
    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);
    346 
    347   helper->AddReadCookies(url_google, url_google, cookies);
    348   ASSERT_FALSE(helper->empty());
    349   helper->Reset();
    350   ASSERT_TRUE(helper->empty());
    351 }
    352 
    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");
    357 
    358   scoped_refptr<CannedBrowsingDataCookieHelper> helper(
    359       new CannedBrowsingDataCookieHelper(
    360           testing_profile_->GetRequestContext()));
    361 
    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());
    369 
    370   helper->StartFetching(
    371       base::Bind(&BrowsingDataCookieHelperTest::CannedDifferentFramesCallback,
    372                  base::Unretained(this)));
    373 }
    374 
    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");
    394 
    395   scoped_refptr<CannedBrowsingDataCookieHelper> helper(
    396       new CannedBrowsingDataCookieHelper(
    397           testing_profile_->GetRequestContext()));
    398 
    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
    404   // cookies.
    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());
    412 
    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());
    420 
    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
    423   // paths.
    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());
    430 
    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:
    434   //   "A=1;
    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());
    441 }
    442 
    443 }  // namespace
    444