1 // Copyright (c) 2011 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/cookies_tree_model.h" 6 7 #include <string> 8 9 #include "chrome/browser/content_settings/stub_settings_observer.h" 10 #include "chrome/browser/mock_browsing_data_appcache_helper.h" 11 #include "chrome/browser/mock_browsing_data_database_helper.h" 12 #include "chrome/browser/mock_browsing_data_indexed_db_helper.h" 13 #include "chrome/browser/mock_browsing_data_local_storage_helper.h" 14 #include "chrome/test/testing_profile.h" 15 #include "content/common/notification_details.h" 16 #include "content/common/notification_type.h" 17 #include "net/url_request/url_request_context.h" 18 #include "net/url_request/url_request_context_getter.h" 19 #include "testing/gtest/include/gtest/gtest.h" 20 21 22 namespace { 23 24 class CookiesTreeModelTest : public testing::Test { 25 public: 26 CookiesTreeModelTest() : ui_thread_(BrowserThread::UI, &message_loop_), 27 io_thread_(BrowserThread::IO, &message_loop_) { 28 } 29 30 virtual ~CookiesTreeModelTest() { 31 } 32 33 virtual void SetUp() { 34 profile_.reset(new TestingProfile()); 35 profile_->CreateRequestContext(); 36 mock_browsing_data_database_helper_ = 37 new MockBrowsingDataDatabaseHelper(profile_.get()); 38 mock_browsing_data_local_storage_helper_ = 39 new MockBrowsingDataLocalStorageHelper(profile_.get()); 40 mock_browsing_data_session_storage_helper_ = 41 new MockBrowsingDataLocalStorageHelper(profile_.get()); 42 mock_browsing_data_appcache_helper_ = 43 new MockBrowsingDataAppCacheHelper(profile_.get()); 44 mock_browsing_data_indexed_db_helper_ = 45 new MockBrowsingDataIndexedDBHelper(profile_.get()); 46 } 47 48 CookiesTreeModel* CreateCookiesTreeModelWithInitialSample() { 49 net::CookieMonster* monster = profile_->GetCookieMonster(); 50 monster->SetCookie(GURL("http://foo1"), "A=1"); 51 monster->SetCookie(GURL("http://foo2"), "B=1"); 52 monster->SetCookie(GURL("http://foo3"), "C=1"); 53 CookiesTreeModel* cookies_model = new CookiesTreeModel( 54 monster, mock_browsing_data_database_helper_, 55 mock_browsing_data_local_storage_helper_, 56 mock_browsing_data_session_storage_helper_, 57 mock_browsing_data_appcache_helper_, 58 mock_browsing_data_indexed_db_helper_, 59 false); 60 mock_browsing_data_database_helper_->AddDatabaseSamples(); 61 mock_browsing_data_database_helper_->Notify(); 62 mock_browsing_data_local_storage_helper_->AddLocalStorageSamples(); 63 mock_browsing_data_local_storage_helper_->Notify(); 64 mock_browsing_data_session_storage_helper_->AddLocalStorageSamples(); 65 mock_browsing_data_session_storage_helper_->Notify(); 66 mock_browsing_data_indexed_db_helper_->AddIndexedDBSamples(); 67 mock_browsing_data_indexed_db_helper_->Notify(); 68 { 69 SCOPED_TRACE("Initial State 3 cookies, 2 databases, 2 local storages, " 70 "2 session storages, 2 indexed DBs"); 71 // 32 because there's the root, then foo1 -> cookies -> a, 72 // foo2 -> cookies -> b, foo3 -> cookies -> c, 73 // dbhost1 -> database -> db1, dbhost2 -> database -> db2, 74 // host1 -> localstorage -> http://host1:1/, 75 // host2 -> localstorage -> http://host2:2/. 76 // host1 -> sessionstorage -> http://host1:1/, 77 // host2 -> sessionstorage -> http://host2:2/, 78 // idbhost1 -> indexeddb -> http://idbhost1:1/, 79 // idbhost2 -> indexeddb -> http://idbhost2:2/. 80 EXPECT_EQ(32, cookies_model->GetRoot()->GetTotalNodeCount()); 81 EXPECT_EQ("db1,db2", GetDisplayedDatabases(cookies_model)); 82 EXPECT_EQ("http://host1:1/,http://host2:2/", 83 GetDisplayedLocalStorages(cookies_model)); 84 EXPECT_EQ("http://host1:1/,http://host2:2/", 85 GetDisplayedSessionStorages(cookies_model)); 86 EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/", 87 GetDisplayedIndexedDBs(cookies_model)); 88 } 89 return cookies_model; 90 } 91 92 // Get the cookie names in the cookie list, as a comma seperated string. 93 // (Note that the CookieMonster cookie list is sorted by domain.) 94 // Ex: 95 // monster->SetCookie(GURL("http://b"), "X=1") 96 // monster->SetCookie(GURL("http://a"), "Y=1") 97 // EXPECT_STREQ("Y,X", GetMonsterCookies(monster).c_str()); 98 std::string GetMonsterCookies(net::CookieMonster* monster) { 99 std::vector<std::string> parts; 100 net::CookieList cookie_list = monster->GetAllCookies(); 101 for (size_t i = 0; i < cookie_list.size(); ++i) 102 parts.push_back(cookie_list[i].Name()); 103 return JoinString(parts, ','); 104 } 105 106 std::string GetNodesOfChildren( 107 const CookieTreeNode* node, 108 CookieTreeNode::DetailedInfo::NodeType node_type) { 109 if (node->child_count()) { 110 std::string retval; 111 for (int i = 0; i < node->child_count(); ++i) { 112 retval += GetNodesOfChildren(node->GetChild(i), node_type); 113 } 114 return retval; 115 } else { 116 if (node->GetDetailedInfo().node_type == node_type) { 117 switch (node_type) { 118 case CookieTreeNode::DetailedInfo::TYPE_SESSION_STORAGE: 119 return node->GetDetailedInfo().session_storage_info->origin + ","; 120 case CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE: 121 return node->GetDetailedInfo().local_storage_info->origin + ","; 122 case CookieTreeNode::DetailedInfo::TYPE_DATABASE: 123 return node->GetDetailedInfo().database_info->database_name + ","; 124 case CookieTreeNode::DetailedInfo::TYPE_COOKIE: 125 return node->GetDetailedInfo().cookie->Name() + ","; 126 case CookieTreeNode::DetailedInfo::TYPE_APPCACHE: 127 return node->GetDetailedInfo().appcache_info->manifest_url.spec() + 128 ","; 129 case CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB: 130 return node->GetDetailedInfo().indexed_db_info->origin + ","; 131 default: 132 return ""; 133 } 134 } else { 135 return ""; 136 } 137 } 138 } 139 140 std::string GetCookiesOfChildren(const CookieTreeNode* node) { 141 return GetNodesOfChildren(node, CookieTreeNode::DetailedInfo::TYPE_COOKIE); 142 } 143 144 std::string GetDatabasesOfChildren(const CookieTreeNode* node) { 145 return GetNodesOfChildren(node, 146 CookieTreeNode::DetailedInfo::TYPE_DATABASE); 147 } 148 149 std::string GetLocalStoragesOfChildren(const CookieTreeNode* node) { 150 return GetNodesOfChildren(node, 151 CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE); 152 } 153 154 std::string GetSessionStoragesOfChildren(const CookieTreeNode* node) { 155 return GetNodesOfChildren( 156 node, CookieTreeNode::DetailedInfo::TYPE_SESSION_STORAGE); 157 } 158 159 std::string GetIndexedDBsOfChildren(const CookieTreeNode* node) { 160 return GetNodesOfChildren( 161 node, CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB); 162 } 163 164 // Get the nodes names displayed in the view (if we had one) in the order 165 // they are displayed, as a comma seperated string. 166 // Ex: EXPECT_STREQ("X,Y", GetDisplayedNodes(cookies_view, type).c_str()); 167 std::string GetDisplayedNodes(CookiesTreeModel* cookies_model, 168 CookieTreeNode::DetailedInfo::NodeType type) { 169 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>( 170 cookies_model->GetRoot()); 171 std::string retval = GetNodesOfChildren(root, type); 172 if (retval.length() && retval[retval.length() - 1] == ',') 173 retval.erase(retval.length() - 1); 174 return retval; 175 } 176 177 std::string GetDisplayedCookies(CookiesTreeModel* cookies_model) { 178 return GetDisplayedNodes(cookies_model, 179 CookieTreeNode::DetailedInfo::TYPE_COOKIE); 180 } 181 182 std::string GetDisplayedDatabases(CookiesTreeModel* cookies_model) { 183 return GetDisplayedNodes(cookies_model, 184 CookieTreeNode::DetailedInfo::TYPE_DATABASE); 185 } 186 187 std::string GetDisplayedLocalStorages(CookiesTreeModel* cookies_model) { 188 return GetDisplayedNodes(cookies_model, 189 CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE); 190 } 191 192 std::string GetDisplayedSessionStorages(CookiesTreeModel* cookies_model) { 193 return GetDisplayedNodes( 194 cookies_model, CookieTreeNode::DetailedInfo::TYPE_SESSION_STORAGE); 195 } 196 197 std::string GetDisplayedAppCaches(CookiesTreeModel* cookies_model) { 198 return GetDisplayedNodes(cookies_model, 199 CookieTreeNode::DetailedInfo::TYPE_APPCACHE); 200 } 201 202 std::string GetDisplayedIndexedDBs(CookiesTreeModel* cookies_model) { 203 return GetDisplayedNodes(cookies_model, 204 CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB); 205 } 206 207 // Do not call on the root. 208 void DeleteStoredObjects(CookieTreeNode* node) { 209 node->DeleteStoredObjects(); 210 CookieTreeNode* parent_node = node->parent(); 211 DCHECK(parent_node); 212 delete parent_node->GetModel()->Remove(parent_node, node); 213 } 214 215 protected: 216 MessageLoop message_loop_; 217 BrowserThread ui_thread_; 218 BrowserThread io_thread_; 219 220 scoped_ptr<TestingProfile> profile_; 221 scoped_refptr<MockBrowsingDataDatabaseHelper> 222 mock_browsing_data_database_helper_; 223 scoped_refptr<MockBrowsingDataLocalStorageHelper> 224 mock_browsing_data_local_storage_helper_; 225 scoped_refptr<MockBrowsingDataLocalStorageHelper> 226 mock_browsing_data_session_storage_helper_; 227 scoped_refptr<MockBrowsingDataAppCacheHelper> 228 mock_browsing_data_appcache_helper_; 229 scoped_refptr<MockBrowsingDataIndexedDBHelper> 230 mock_browsing_data_indexed_db_helper_; 231 }; 232 233 TEST_F(CookiesTreeModelTest, RemoveAll) { 234 scoped_ptr<CookiesTreeModel> cookies_model( 235 CreateCookiesTreeModelWithInitialSample()); 236 net::CookieMonster* monster = profile_->GetCookieMonster(); 237 238 // Reset the selection of the first row. 239 { 240 SCOPED_TRACE("Before removing"); 241 EXPECT_EQ(GetMonsterCookies(monster), 242 GetDisplayedCookies(cookies_model.get())); 243 EXPECT_EQ("db1,db2", 244 GetDisplayedDatabases(cookies_model.get())); 245 EXPECT_EQ("http://host1:1/,http://host2:2/", 246 GetDisplayedLocalStorages(cookies_model.get())); 247 EXPECT_EQ("http://host1:1/,http://host2:2/", 248 GetDisplayedSessionStorages(cookies_model.get())); 249 EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/", 250 GetDisplayedIndexedDBs(cookies_model.get())); 251 } 252 253 mock_browsing_data_database_helper_->Reset(); 254 mock_browsing_data_local_storage_helper_->Reset(); 255 mock_browsing_data_session_storage_helper_->Reset(); 256 mock_browsing_data_indexed_db_helper_->Reset(); 257 258 cookies_model->DeleteAllStoredObjects(); 259 260 { 261 SCOPED_TRACE("After removing"); 262 EXPECT_EQ(1, cookies_model->GetRoot()->GetTotalNodeCount()); 263 EXPECT_EQ(0, cookies_model->GetRoot()->child_count()); 264 EXPECT_EQ(std::string(""), GetMonsterCookies(monster)); 265 EXPECT_EQ(GetMonsterCookies(monster), 266 GetDisplayedCookies(cookies_model.get())); 267 EXPECT_TRUE(mock_browsing_data_database_helper_->AllDeleted()); 268 EXPECT_TRUE(mock_browsing_data_local_storage_helper_->AllDeleted()); 269 EXPECT_FALSE(mock_browsing_data_session_storage_helper_->AllDeleted()); 270 EXPECT_TRUE(mock_browsing_data_indexed_db_helper_->AllDeleted()); 271 } 272 } 273 274 TEST_F(CookiesTreeModelTest, Remove) { 275 scoped_ptr<CookiesTreeModel> cookies_model( 276 CreateCookiesTreeModelWithInitialSample()); 277 net::CookieMonster* monster = profile_->GetCookieMonster(); 278 279 DeleteStoredObjects(cookies_model->GetRoot()->GetChild(0)); 280 { 281 SCOPED_TRACE("First cookie origin removed"); 282 EXPECT_STREQ("B,C", GetMonsterCookies(monster).c_str()); 283 EXPECT_STREQ("B,C", GetDisplayedCookies(cookies_model.get()).c_str()); 284 EXPECT_EQ("db1,db2", GetDisplayedDatabases(cookies_model.get())); 285 EXPECT_EQ("http://host1:1/,http://host2:2/", 286 GetDisplayedLocalStorages(cookies_model.get())); 287 EXPECT_EQ("http://host1:1/,http://host2:2/", 288 GetDisplayedSessionStorages(cookies_model.get())); 289 EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/", 290 GetDisplayedIndexedDBs(cookies_model.get())); 291 EXPECT_EQ(29, cookies_model->GetRoot()->GetTotalNodeCount()); 292 } 293 294 DeleteStoredObjects(cookies_model->GetRoot()->GetChild(2)); 295 { 296 SCOPED_TRACE("First database origin removed"); 297 EXPECT_STREQ("B,C", GetMonsterCookies(monster).c_str()); 298 EXPECT_STREQ("B,C", GetDisplayedCookies(cookies_model.get()).c_str()); 299 EXPECT_EQ("db2", GetDisplayedDatabases(cookies_model.get())); 300 EXPECT_EQ("http://host1:1/,http://host2:2/", 301 GetDisplayedLocalStorages(cookies_model.get())); 302 EXPECT_EQ("http://host1:1/,http://host2:2/", 303 GetDisplayedSessionStorages(cookies_model.get())); 304 EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/", 305 GetDisplayedIndexedDBs(cookies_model.get())); 306 EXPECT_EQ(26, cookies_model->GetRoot()->GetTotalNodeCount()); 307 } 308 309 DeleteStoredObjects(cookies_model->GetRoot()->GetChild(3)); 310 { 311 SCOPED_TRACE("First local storage origin removed"); 312 EXPECT_STREQ("B,C", GetMonsterCookies(monster).c_str()); 313 EXPECT_STREQ("B,C", GetDisplayedCookies(cookies_model.get()).c_str()); 314 EXPECT_EQ("db2", GetDisplayedDatabases(cookies_model.get())); 315 EXPECT_EQ("http://host2:2/", 316 GetDisplayedLocalStorages(cookies_model.get())); 317 EXPECT_EQ("http://host2:2/", 318 GetDisplayedSessionStorages(cookies_model.get())); 319 EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/", 320 GetDisplayedIndexedDBs(cookies_model.get())); 321 EXPECT_EQ(21, cookies_model->GetRoot()->GetTotalNodeCount()); 322 } 323 324 DeleteStoredObjects(cookies_model->GetRoot()->GetChild(4)); 325 { 326 SCOPED_TRACE("First IndexedDB origin removed"); 327 EXPECT_STREQ("B,C", GetMonsterCookies(monster).c_str()); 328 EXPECT_STREQ("B,C", GetDisplayedCookies(cookies_model.get()).c_str()); 329 EXPECT_EQ("db2", GetDisplayedDatabases(cookies_model.get())); 330 EXPECT_EQ("http://host2:2/", 331 GetDisplayedLocalStorages(cookies_model.get())); 332 EXPECT_EQ("http://host2:2/", 333 GetDisplayedSessionStorages(cookies_model.get())); 334 EXPECT_EQ("http://idbhost2:2/", 335 GetDisplayedIndexedDBs(cookies_model.get())); 336 EXPECT_EQ(18, cookies_model->GetRoot()->GetTotalNodeCount()); 337 } 338 } 339 340 TEST_F(CookiesTreeModelTest, RemoveCookiesNode) { 341 scoped_ptr<CookiesTreeModel> cookies_model( 342 CreateCookiesTreeModelWithInitialSample()); 343 net::CookieMonster* monster = profile_->GetCookieMonster(); 344 345 DeleteStoredObjects(cookies_model->GetRoot()->GetChild(0)->GetChild(0)); 346 { 347 SCOPED_TRACE("First origin removed"); 348 EXPECT_STREQ("B,C", GetMonsterCookies(monster).c_str()); 349 EXPECT_STREQ("B,C", GetDisplayedCookies(cookies_model.get()).c_str()); 350 // 28 because in this case, the origin remains, although the COOKIES 351 // node beneath it has been deleted. So, we have 352 // root -> foo1 -> cookies -> a, foo2, foo3 -> cookies -> c 353 // dbhost1 -> database -> db1, dbhost2 -> database -> db2, 354 // host1 -> localstorage -> http://host1:1/, 355 // host2 -> localstorage -> http://host2:2/, 356 // idbhost1 -> sessionstorage -> http://idbhost1:1/, 357 // idbhost2 -> sessionstorage -> http://idbhost2:2/. 358 EXPECT_EQ(30, cookies_model->GetRoot()->GetTotalNodeCount()); 359 EXPECT_EQ("db1,db2", GetDisplayedDatabases(cookies_model.get())); 360 EXPECT_EQ("http://host1:1/,http://host2:2/", 361 GetDisplayedLocalStorages(cookies_model.get())); 362 EXPECT_EQ("http://host1:1/,http://host2:2/", 363 GetDisplayedSessionStorages(cookies_model.get())); 364 EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/", 365 GetDisplayedIndexedDBs(cookies_model.get())); 366 } 367 368 DeleteStoredObjects(cookies_model->GetRoot()->GetChild(3)->GetChild(0)); 369 { 370 SCOPED_TRACE("First database removed"); 371 EXPECT_STREQ("B,C", GetMonsterCookies(monster).c_str()); 372 EXPECT_STREQ("B,C", GetDisplayedCookies(cookies_model.get()).c_str()); 373 EXPECT_EQ("db2", GetDisplayedDatabases(cookies_model.get())); 374 EXPECT_EQ("http://host1:1/,http://host2:2/", 375 GetDisplayedLocalStorages(cookies_model.get())); 376 EXPECT_EQ("http://host1:1/,http://host2:2/", 377 GetDisplayedSessionStorages(cookies_model.get())); 378 EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/", 379 GetDisplayedIndexedDBs(cookies_model.get())); 380 EXPECT_EQ(28, cookies_model->GetRoot()->GetTotalNodeCount()); 381 } 382 383 DeleteStoredObjects(cookies_model->GetRoot()->GetChild(5)->GetChild(0)); 384 { 385 SCOPED_TRACE("First origin removed"); 386 EXPECT_STREQ("B,C", GetMonsterCookies(monster).c_str()); 387 EXPECT_STREQ("B,C", GetDisplayedCookies(cookies_model.get()).c_str()); 388 EXPECT_EQ("db2", GetDisplayedDatabases(cookies_model.get())); 389 EXPECT_EQ("http://host2:2/", 390 GetDisplayedLocalStorages(cookies_model.get())); 391 EXPECT_EQ("http://host1:1/,http://host2:2/", 392 GetDisplayedSessionStorages(cookies_model.get())); 393 EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/", 394 GetDisplayedIndexedDBs(cookies_model.get())); 395 EXPECT_EQ(26, cookies_model->GetRoot()->GetTotalNodeCount()); 396 } 397 } 398 399 TEST_F(CookiesTreeModelTest, RemoveCookieNode) { 400 scoped_ptr<CookiesTreeModel> cookies_model( 401 CreateCookiesTreeModelWithInitialSample()); 402 net::CookieMonster* monster = profile_->GetCookieMonster(); 403 404 DeleteStoredObjects(cookies_model->GetRoot()->GetChild(1)->GetChild(0)); 405 { 406 SCOPED_TRACE("Second origin COOKIES node removed"); 407 EXPECT_STREQ("A,C", GetMonsterCookies(monster).c_str()); 408 EXPECT_STREQ("A,C", GetDisplayedCookies(cookies_model.get()).c_str()); 409 EXPECT_EQ("db1,db2", GetDisplayedDatabases(cookies_model.get())); 410 EXPECT_EQ("http://host1:1/,http://host2:2/", 411 GetDisplayedLocalStorages(cookies_model.get())); 412 EXPECT_EQ("http://host1:1/,http://host2:2/", 413 GetDisplayedSessionStorages(cookies_model.get())); 414 EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/", 415 GetDisplayedIndexedDBs(cookies_model.get())); 416 // 28 because in this case, the origin remains, although the COOKIES 417 // node beneath it has been deleted. So, we have 418 // root -> foo1 -> cookies -> a, foo2, foo3 -> cookies -> c 419 // dbhost1 -> database -> db1, dbhost2 -> database -> db2, 420 // host1 -> localstorage -> http://host1:1/, 421 // host2 -> localstorage -> http://host2:2/. 422 // host1 -> sessionstorage -> http://host1:1/, 423 // host2 -> sessionstorage -> http://host2:2/, 424 // idbhost1 -> sessionstorage -> http://idbhost1:1/, 425 // idbhost2 -> sessionstorage -> http://idbhost2:2/. 426 EXPECT_EQ(30, cookies_model->GetRoot()->GetTotalNodeCount()); 427 } 428 429 DeleteStoredObjects(cookies_model->GetRoot()->GetChild(3)->GetChild(0)); 430 { 431 SCOPED_TRACE("First database removed"); 432 EXPECT_STREQ("A,C", GetMonsterCookies(monster).c_str()); 433 EXPECT_STREQ("A,C", GetDisplayedCookies(cookies_model.get()).c_str()); 434 EXPECT_EQ("db2", GetDisplayedDatabases(cookies_model.get())); 435 EXPECT_EQ("http://host1:1/,http://host2:2/", 436 GetDisplayedLocalStorages(cookies_model.get())); 437 EXPECT_EQ("http://host1:1/,http://host2:2/", 438 GetDisplayedSessionStorages(cookies_model.get())); 439 EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/", 440 GetDisplayedIndexedDBs(cookies_model.get())); 441 EXPECT_EQ(28, cookies_model->GetRoot()->GetTotalNodeCount()); 442 } 443 444 DeleteStoredObjects(cookies_model->GetRoot()->GetChild(5)->GetChild(0)); 445 { 446 SCOPED_TRACE("First origin removed"); 447 EXPECT_STREQ("A,C", GetMonsterCookies(monster).c_str()); 448 EXPECT_STREQ("A,C", GetDisplayedCookies(cookies_model.get()).c_str()); 449 EXPECT_EQ("db2", GetDisplayedDatabases(cookies_model.get())); 450 EXPECT_EQ("http://host2:2/", 451 GetDisplayedLocalStorages(cookies_model.get())); 452 EXPECT_EQ("http://host1:1/,http://host2:2/", 453 GetDisplayedSessionStorages(cookies_model.get())); 454 EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/", 455 GetDisplayedIndexedDBs(cookies_model.get())); 456 EXPECT_EQ(26, cookies_model->GetRoot()->GetTotalNodeCount()); 457 } 458 } 459 460 TEST_F(CookiesTreeModelTest, RemoveSingleCookieNode) { 461 net::CookieMonster* monster = profile_->GetCookieMonster(); 462 monster->SetCookie(GURL("http://foo1"), "A=1"); 463 monster->SetCookie(GURL("http://foo2"), "B=1"); 464 monster->SetCookie(GURL("http://foo3"), "C=1"); 465 monster->SetCookie(GURL("http://foo3"), "D=1"); 466 CookiesTreeModel cookies_model(monster, 467 mock_browsing_data_database_helper_, 468 mock_browsing_data_local_storage_helper_, 469 mock_browsing_data_session_storage_helper_, 470 mock_browsing_data_appcache_helper_, 471 mock_browsing_data_indexed_db_helper_, 472 false); 473 mock_browsing_data_database_helper_->AddDatabaseSamples(); 474 mock_browsing_data_database_helper_->Notify(); 475 mock_browsing_data_local_storage_helper_->AddLocalStorageSamples(); 476 mock_browsing_data_local_storage_helper_->Notify(); 477 mock_browsing_data_session_storage_helper_->AddLocalStorageSamples(); 478 mock_browsing_data_session_storage_helper_->Notify(); 479 mock_browsing_data_indexed_db_helper_->AddIndexedDBSamples(); 480 mock_browsing_data_indexed_db_helper_->Notify(); 481 482 { 483 SCOPED_TRACE("Initial State 4 cookies, 2 databases, 2 local storages, " 484 "2 session storages, 2 indexed DBs"); 485 // 33 because there's the root, then foo1 -> cookies -> a, 486 // foo2 -> cookies -> b, foo3 -> cookies -> c,d 487 // dbhost1 -> database -> db1, dbhost2 -> database -> db2, 488 // host1 -> localstorage -> http://host1:1/, 489 // host2 -> localstorage -> http://host2:2/. 490 // host1 -> sessionstorage -> http://host1:1/, 491 // host2 -> sessionstorage -> http://host2:2/, 492 // idbhost1 -> sessionstorage -> http://idbhost1:1/, 493 // idbhost2 -> sessionstorage -> http://idbhost2:2/. 494 EXPECT_EQ(33, cookies_model.GetRoot()->GetTotalNodeCount()); 495 EXPECT_STREQ("A,B,C,D", GetMonsterCookies(monster).c_str()); 496 EXPECT_STREQ("A,B,C,D", GetDisplayedCookies(&cookies_model).c_str()); 497 EXPECT_EQ("db1,db2", GetDisplayedDatabases(&cookies_model)); 498 EXPECT_EQ("http://host1:1/,http://host2:2/", 499 GetDisplayedLocalStorages(&cookies_model)); 500 EXPECT_EQ("http://host1:1/,http://host2:2/", 501 GetDisplayedSessionStorages(&cookies_model)); 502 EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/", 503 GetDisplayedIndexedDBs(&cookies_model)); 504 } 505 DeleteStoredObjects(cookies_model.GetRoot()->GetChild(2)); 506 { 507 SCOPED_TRACE("Third origin removed"); 508 EXPECT_STREQ("A,B", GetMonsterCookies(monster).c_str()); 509 EXPECT_STREQ("A,B", GetDisplayedCookies(&cookies_model).c_str()); 510 EXPECT_EQ("db1,db2", GetDisplayedDatabases(&cookies_model)); 511 EXPECT_EQ("http://host1:1/,http://host2:2/", 512 GetDisplayedLocalStorages(&cookies_model)); 513 EXPECT_EQ("http://host1:1/,http://host2:2/", 514 GetDisplayedSessionStorages(&cookies_model)); 515 EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/", 516 GetDisplayedIndexedDBs(&cookies_model)); 517 EXPECT_EQ(29, cookies_model.GetRoot()->GetTotalNodeCount()); 518 } 519 } 520 521 TEST_F(CookiesTreeModelTest, RemoveSingleCookieNodeOf3) { 522 net::CookieMonster* monster = profile_->GetCookieMonster(); 523 monster->SetCookie(GURL("http://foo1"), "A=1"); 524 monster->SetCookie(GURL("http://foo2"), "B=1"); 525 monster->SetCookie(GURL("http://foo3"), "C=1"); 526 monster->SetCookie(GURL("http://foo3"), "D=1"); 527 monster->SetCookie(GURL("http://foo3"), "E=1"); 528 CookiesTreeModel cookies_model(monster, 529 mock_browsing_data_database_helper_, 530 mock_browsing_data_local_storage_helper_, 531 mock_browsing_data_session_storage_helper_, 532 mock_browsing_data_appcache_helper_, 533 mock_browsing_data_indexed_db_helper_, 534 false); 535 mock_browsing_data_database_helper_->AddDatabaseSamples(); 536 mock_browsing_data_database_helper_->Notify(); 537 mock_browsing_data_local_storage_helper_->AddLocalStorageSamples(); 538 mock_browsing_data_local_storage_helper_->Notify(); 539 mock_browsing_data_session_storage_helper_->AddLocalStorageSamples(); 540 mock_browsing_data_session_storage_helper_->Notify(); 541 mock_browsing_data_indexed_db_helper_->AddIndexedDBSamples(); 542 mock_browsing_data_indexed_db_helper_->Notify(); 543 544 { 545 SCOPED_TRACE("Initial State 5 cookies, 2 databases, 2 local storages, " 546 "2 session storages, 2 indexed DBs"); 547 // 34 because there's the root, then foo1 -> cookies -> a, 548 // foo2 -> cookies -> b, foo3 -> cookies -> c,d,e 549 // dbhost1 -> database -> db1, dbhost2 -> database -> db2, 550 // host1 -> localstorage -> http://host1:1/, 551 // host2 -> localstorage -> http://host2:2/. 552 // host1 -> sessionstorage -> http://host1:1/, 553 // host2 -> sessionstorage -> http://host2:2/, 554 // idbhost1 -> sessionstorage -> http://idbhost1:1/, 555 // idbhost2 -> sessionstorage -> http://idbhost2:2/. 556 EXPECT_EQ(34, cookies_model.GetRoot()->GetTotalNodeCount()); 557 EXPECT_STREQ("A,B,C,D,E", GetMonsterCookies(monster).c_str()); 558 EXPECT_STREQ("A,B,C,D,E", GetDisplayedCookies(&cookies_model).c_str()); 559 EXPECT_EQ("db1,db2", GetDisplayedDatabases(&cookies_model)); 560 EXPECT_EQ("http://host1:1/,http://host2:2/", 561 GetDisplayedLocalStorages(&cookies_model)); 562 EXPECT_EQ("http://host1:1/,http://host2:2/", 563 GetDisplayedSessionStorages(&cookies_model)); 564 EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/", 565 GetDisplayedIndexedDBs(&cookies_model)); 566 } 567 DeleteStoredObjects(cookies_model.GetRoot()->GetChild(2)->GetChild(0)-> 568 GetChild(1)); 569 { 570 SCOPED_TRACE("Middle cookie in third origin removed"); 571 EXPECT_STREQ("A,B,C,E", GetMonsterCookies(monster).c_str()); 572 EXPECT_STREQ("A,B,C,E", GetDisplayedCookies(&cookies_model).c_str()); 573 EXPECT_EQ(33, cookies_model.GetRoot()->GetTotalNodeCount()); 574 EXPECT_EQ("db1,db2", GetDisplayedDatabases(&cookies_model)); 575 EXPECT_EQ("http://host1:1/,http://host2:2/", 576 GetDisplayedLocalStorages(&cookies_model)); 577 EXPECT_EQ("http://host1:1/,http://host2:2/", 578 GetDisplayedSessionStorages(&cookies_model)); 579 EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/", 580 GetDisplayedIndexedDBs(&cookies_model)); 581 } 582 } 583 584 TEST_F(CookiesTreeModelTest, RemoveSecondOrigin) { 585 net::CookieMonster* monster = profile_->GetCookieMonster(); 586 monster->SetCookie(GURL("http://foo1"), "A=1"); 587 monster->SetCookie(GURL("http://foo2"), "B=1"); 588 monster->SetCookie(GURL("http://foo3"), "C=1"); 589 monster->SetCookie(GURL("http://foo3"), "D=1"); 590 monster->SetCookie(GURL("http://foo3"), "E=1"); 591 CookiesTreeModel cookies_model(monster, 592 mock_browsing_data_database_helper_, 593 mock_browsing_data_local_storage_helper_, 594 mock_browsing_data_session_storage_helper_, 595 mock_browsing_data_appcache_helper_, 596 mock_browsing_data_indexed_db_helper_, 597 false); 598 { 599 SCOPED_TRACE("Initial State 5 cookies"); 600 // 11 because there's the root, then foo1 -> cookies -> a, 601 // foo2 -> cookies -> b, foo3 -> cookies -> c,d,e 602 EXPECT_EQ(12, cookies_model.GetRoot()->GetTotalNodeCount()); 603 EXPECT_STREQ("A,B,C,D,E", GetMonsterCookies(monster).c_str()); 604 EXPECT_STREQ("A,B,C,D,E", GetDisplayedCookies(&cookies_model).c_str()); 605 } 606 DeleteStoredObjects(cookies_model.GetRoot()->GetChild(1)); 607 { 608 SCOPED_TRACE("Second origin removed"); 609 EXPECT_STREQ("A,C,D,E", GetMonsterCookies(monster).c_str()); 610 EXPECT_STREQ("A,C,D,E", GetDisplayedCookies(&cookies_model).c_str()); 611 // Left with root -> foo1 -> cookies -> a, foo3 -> cookies -> c,d,e 612 EXPECT_EQ(9, cookies_model.GetRoot()->GetTotalNodeCount()); 613 } 614 } 615 616 TEST_F(CookiesTreeModelTest, OriginOrdering) { 617 net::CookieMonster* monster = profile_->GetCookieMonster(); 618 monster->SetCookie(GURL("http://a.foo2.com"), "A=1"); 619 monster->SetCookie(GURL("http://foo2.com"), "B=1"); 620 monster->SetCookie(GURL("http://b.foo1.com"), "C=1"); 621 monster->SetCookie(GURL("http://foo4.com"), "D=1; domain=.foo4.com;" 622 " path=/;"); // Leading dot on the foo4 623 monster->SetCookie(GURL("http://a.foo1.com"), "E=1"); 624 monster->SetCookie(GURL("http://foo1.com"), "F=1"); 625 monster->SetCookie(GURL("http://foo3.com"), "G=1"); 626 monster->SetCookie(GURL("http://foo4.com"), "H=1"); 627 628 CookiesTreeModel cookies_model(monster, 629 new MockBrowsingDataDatabaseHelper(profile_.get()), 630 new MockBrowsingDataLocalStorageHelper(profile_.get()), 631 new MockBrowsingDataLocalStorageHelper(profile_.get()), 632 new MockBrowsingDataAppCacheHelper(profile_.get()), 633 new MockBrowsingDataIndexedDBHelper(profile_.get()), 634 false); 635 636 { 637 SCOPED_TRACE("Initial State 8 cookies"); 638 // CookieMonster orders cookies by pathlength, then by creation time. 639 // All paths are length 1. 640 EXPECT_STREQ("A,B,C,D,E,F,G,H", GetMonsterCookies(monster).c_str()); 641 EXPECT_STREQ("F,E,C,B,A,G,D,H", 642 GetDisplayedCookies(&cookies_model).c_str()); 643 } 644 DeleteStoredObjects(cookies_model.GetRoot()->GetChild(1)); // Delete "E" 645 { 646 EXPECT_STREQ("A,B,C,D,F,G,H", GetMonsterCookies(monster).c_str()); 647 EXPECT_STREQ("F,C,B,A,G,D,H", GetDisplayedCookies(&cookies_model).c_str()); 648 } 649 } 650 651 TEST_F(CookiesTreeModelTest, ContentSettings) { 652 GURL host("http://example.com/"); 653 ContentSettingsPattern pattern("[*.]example.com"); 654 net::CookieMonster* monster = profile_->GetCookieMonster(); 655 monster->SetCookie(host, "A=1"); 656 657 CookiesTreeModel cookies_model(monster, 658 new MockBrowsingDataDatabaseHelper(profile_.get()), 659 new MockBrowsingDataLocalStorageHelper(profile_.get()), 660 new MockBrowsingDataLocalStorageHelper(profile_.get()), 661 new MockBrowsingDataAppCacheHelper(profile_.get()), 662 new MockBrowsingDataIndexedDBHelper(profile_.get()), 663 false); 664 665 TestingProfile profile; 666 HostContentSettingsMap* content_settings = 667 profile.GetHostContentSettingsMap(); 668 StubSettingsObserver observer; 669 670 CookieTreeRootNode* root = 671 static_cast<CookieTreeRootNode*>(cookies_model.GetRoot()); 672 CookieTreeOriginNode* origin = root->GetOrCreateOriginNode(host); 673 674 EXPECT_EQ(1, origin->child_count()); 675 EXPECT_TRUE(origin->CanCreateContentException()); 676 origin->CreateContentException( 677 content_settings, CONTENT_SETTING_SESSION_ONLY); 678 679 EXPECT_EQ(2, observer.counter); 680 EXPECT_EQ(pattern, observer.last_pattern); 681 EXPECT_EQ(CONTENT_SETTING_SESSION_ONLY, 682 content_settings->GetContentSetting( 683 host, CONTENT_SETTINGS_TYPE_COOKIES, "")); 684 } 685 686 } // namespace 687