top_sites_unittest.cc revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
1// Copyright (c) 2010 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 "app/l10n_util.h" 6#include "base/file_util.h" 7#include "base/scoped_temp_dir.h" 8#include "base/string_util.h" 9#include "base/utf_string_conversions.h" 10#include "base/values.h" 11#include "chrome/browser/chrome_thread.h" 12#include "chrome/browser/history/top_sites.h" 13#include "chrome/browser/dom_ui/most_visited_handler.h" 14#include "chrome/browser/history/history_marshaling.h" 15#include "chrome/browser/history/top_sites_database.h" 16#include "chrome/browser/history/history_notifications.h" 17#include "chrome/common/chrome_paths.h" 18#include "chrome/test/testing_profile.h" 19#include "chrome/tools/profiles/thumbnail-inl.h" 20#include "gfx/codec/jpeg_codec.h" 21#include "googleurl/src/gurl.h" 22#include "grit/chromium_strings.h" 23#include "grit/generated_resources.h" 24#include "grit/locale_settings.h" 25#include "testing/gtest/include/gtest/gtest.h" 26#include "third_party/skia/include/core/SkBitmap.h" 27 28 29namespace history { 30 31static const unsigned char kBlob[] = 32 "12346102356120394751634516591348710478123649165419234519234512349134"; 33 34class TopSitesTest : public testing::Test { 35 public: 36 TopSitesTest() : number_of_callbacks_(0) { 37 } 38 ~TopSitesTest() { 39 } 40 41 TopSites& top_sites() { return *top_sites_; } 42 MostVisitedURLList& urls() { return urls_; } 43 Profile& profile() {return *profile_;} 44 FilePath& file_name() { return file_name_; } 45 RefCountedBytes* google_thumbnail() { return google_thumbnail_; } 46 RefCountedBytes* random_thumbnail() { return random_thumbnail_; } 47 RefCountedBytes* weewar_thumbnail() { return weewar_thumbnail_; } 48 CancelableRequestConsumer* consumer() { return &consumer_; } 49 size_t number_of_callbacks() {return number_of_callbacks_; } 50 // Prepopulated URLs - added at the back of TopSites. 51 GURL welcome_url() { 52 return GURL(l10n_util::GetStringUTF8(IDS_CHROME_WELCOME_URL)); 53 } 54 GURL themes_url() { 55 return GURL(l10n_util::GetStringUTF8(IDS_THEMES_GALLERY_URL)); 56 } 57 58 virtual void SetUp() { 59 profile_.reset(new TestingProfile); 60 top_sites_ = new TopSites(profile_.get()); 61 62 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 63 file_name_ = temp_dir_.path().AppendASCII("TopSites.db"); 64 EXPECT_TRUE(file_util::Delete(file_name_, false)); 65 66 std::vector<unsigned char> random_data(kBlob, kBlob + sizeof(kBlob)); 67 std::vector<unsigned char> google_data(kGoogleThumbnail, 68 kGoogleThumbnail + 69 sizeof(kGoogleThumbnail)); 70 std::vector<unsigned char> weewar_data(kWeewarThumbnail, 71 kWeewarThumbnail + 72 sizeof(kWeewarThumbnail)); 73 random_thumbnail_ = new RefCountedBytes(random_data); 74 google_thumbnail_ = new RefCountedBytes(google_data); 75 weewar_thumbnail_ = new RefCountedBytes(weewar_data); 76 } 77 78 virtual void TearDown() { 79 profile_.reset(); 80 TopSites::DeleteTopSites(top_sites_); 81 EXPECT_TRUE(file_util::Delete(file_name_, false)); 82 } 83 84 // Callback for TopSites::GetMostVisitedURLs. 85 void OnTopSitesAvailable(history::MostVisitedURLList data) { 86 urls_ = data; 87 number_of_callbacks_++; 88 } 89 90 // Wrappers that allow private TopSites functions to be called from the 91 // individual tests without making them all be friends. 92 GURL GetCanonicalURL(const GURL& url) const { 93 AutoLock lock(top_sites_->lock_); // The function asserts it's in the lock. 94 return top_sites_->GetCanonicalURL(url); 95 } 96 97 void StoreMostVisited(std::vector<MostVisitedURL>* urls) { 98 top_sites_->StoreMostVisited(urls); 99 } 100 101 static void DiffMostVisited(const std::vector<MostVisitedURL>& old_list, 102 const std::vector<MostVisitedURL>& new_list, 103 std::vector<size_t>* added_urls, 104 std::vector<size_t>* deleted_urls, 105 std::vector<size_t>* moved_urls) { 106 TopSites::DiffMostVisited(old_list, new_list, 107 added_urls, deleted_urls, moved_urls); 108 } 109 110 Lock& lock() { 111 return top_sites_->lock_; 112 } 113 114 private: 115 scoped_refptr<TopSites> top_sites_; 116 MostVisitedURLList urls_; 117 size_t number_of_callbacks_; 118 scoped_ptr<TestingProfile> profile_; 119 ScopedTempDir temp_dir_; 120 FilePath file_name_; // Database filename. 121 scoped_refptr<RefCountedBytes> google_thumbnail_; 122 scoped_refptr<RefCountedBytes> random_thumbnail_; 123 scoped_refptr<RefCountedBytes> weewar_thumbnail_; 124 MessageLoop message_loop_; 125 CancelableRequestConsumer consumer_; 126 127 DISALLOW_COPY_AND_ASSIGN(TopSitesTest); 128}; 129 130 131// A mockup of a HistoryService used for testing TopSites. 132class MockHistoryServiceImpl : public TopSites::MockHistoryService { 133 public: 134 MockHistoryServiceImpl() : num_thumbnail_requests_(0) {} 135 136 // Calls the callback directly with the results. 137 HistoryService::Handle QueryMostVisitedURLs( 138 int result_count, int days_back, 139 CancelableRequestConsumerBase* consumer, 140 HistoryService::QueryMostVisitedURLsCallback* callback) { 141 callback->Run(CancelableRequestProvider::Handle(0), // Handle is unused. 142 most_visited_urls_); 143 delete callback; 144 return 0; 145 } 146 147 // Add a page to the end of the pages list. 148 void AppendMockPage(const GURL& url, 149 const string16& title) { 150 MostVisitedURL page; 151 page.url = url; 152 page.title = title; 153 page.redirects = RedirectList(); 154 page.redirects.push_back(url); 155 most_visited_urls_.push_back(page); 156 } 157 158 // Removes the last URL in the list. 159 void RemoveMostVisitedURL() { 160 most_visited_urls_.pop_back(); 161 } 162 163 virtual void GetPageThumbnail( 164 const GURL& url, 165 CancelableRequestConsumerTSimple<size_t>* consumer, 166 HistoryService::ThumbnailDataCallback* callback, 167 size_t index) { 168 num_thumbnail_requests_++; 169 MostVisitedURL mvu; 170 mvu.url = url; 171 MostVisitedURLList::iterator pos = std::find(most_visited_urls_.begin(), 172 most_visited_urls_.end(), 173 mvu); 174 EXPECT_TRUE(pos != most_visited_urls_.end()) << url.spec(); 175 scoped_refptr<RefCountedBytes> thumbnail; 176 callback->Run(index, thumbnail); 177 delete callback; 178 } 179 180 void ResetNumberOfThumbnailRequests() { 181 num_thumbnail_requests_ = 0; 182 } 183 184 int GetNumberOfThumbnailRequests() { 185 return num_thumbnail_requests_; 186 } 187 188 private: 189 MostVisitedURLList most_visited_urls_; 190 int num_thumbnail_requests_; // Number of calls to GetPageThumbnail. 191}; 192 193 194// A mockup of a TopSitesDatabase used for testing TopSites. 195class MockTopSitesDatabaseImpl : public TopSitesDatabase { 196 public: 197 virtual void GetPageThumbnails(MostVisitedURLList* urls, 198 std::map<GURL, Images>* thumbnails) { 199 // Return a copy of the vector. 200 *urls = top_sites_list_; 201 *thumbnails = thumbnails_map_; 202 } 203 204 virtual void SetPageThumbnail(const MostVisitedURL& url, int url_rank, 205 const Images& thumbnail) { 206 SetPageRank(url, url_rank); 207 // Update thubmnail 208 thumbnails_map_[url.url] = thumbnail; 209 } 210 211 virtual void UpdatePageRank(const MostVisitedURL& url, int new_rank) { 212 MostVisitedURLList::iterator pos = std::find(top_sites_list_.begin(), 213 top_sites_list_.end(), 214 url); 215 // Is it in the right position? 216 int rank = pos - top_sites_list_.begin(); 217 if (rank != new_rank) { 218 // Move the URL to a new position. 219 top_sites_list_.erase(pos); 220 top_sites_list_.insert(top_sites_list_.begin() + new_rank, url); 221 } 222 } 223 224 virtual void SetPageRank(const MostVisitedURL& url, int url_rank) { 225 // Check if this url is in the list, and at which position. 226 MostVisitedURLList::iterator pos = std::find(top_sites_list_.begin(), 227 top_sites_list_.end(), 228 url); 229 if (pos == top_sites_list_.end()) { 230 // Add it to the list. 231 top_sites_list_.insert(top_sites_list_.begin() + url_rank, url); 232 } else { 233 UpdatePageRank(url, url_rank); 234 } 235 } 236 237 // Get a thumbnail for a given page. Returns true iff we have the thumbnail. 238 virtual bool GetPageThumbnail(const GURL& url, 239 Images* thumbnail) { 240 std::map<GURL, Images>::const_iterator found = 241 thumbnails_map_.find(url); 242 if (found == thumbnails_map_.end()) 243 return false; // No thumbnail for this URL. 244 245 thumbnail->thumbnail = found->second.thumbnail; 246 thumbnail->thumbnail_score = found->second.thumbnail_score; 247 return true; 248 } 249 250 virtual bool RemoveURL(const MostVisitedURL& url) { 251 // Comparison by url. 252 MostVisitedURLList::iterator pos = std::find(top_sites_list_.begin(), 253 top_sites_list_.end(), 254 url); 255 if (pos == top_sites_list_.end()) { 256 return false; 257 } 258 top_sites_list_.erase(pos); 259 thumbnails_map_.erase(url.url); 260 return true; 261 } 262 263 private: 264 MostVisitedURLList top_sites_list_; // Keeps the URLs sorted by score (rank). 265 std::map<GURL, Images> thumbnails_map_; 266}; 267 268 269// Helper function for appending a URL to a vector of "most visited" URLs, 270// using the default values for everything but the URL. 271static void AppendMostVisitedURL(std::vector<MostVisitedURL>* list, 272 const GURL& url) { 273 MostVisitedURL mv; 274 mv.url = url; 275 mv.redirects.push_back(url); 276 list->push_back(mv); 277} 278 279// Returns true if t1 and t2 contain the same data. 280static bool ThumbnailsAreEqual(RefCountedBytes* t1, 281 RefCountedBytes* t2) { 282 if (!t1 || !t2) 283 return false; 284 if (t1->data.size() != t2->data.size()) 285 return false; 286 return std::equal(t1->data.begin(), 287 t1->data.end(), 288 t2->data.begin()); 289} 290 291// Same as AppendMostVisitedURL except that it adds a redirect from the first 292// URL to the second. 293static void AppendMostVisitedURLWithRedirect( 294 std::vector<MostVisitedURL>* list, 295 const GURL& redirect_source, const GURL& redirect_dest) { 296 MostVisitedURL mv; 297 mv.url = redirect_dest; 298 mv.redirects.push_back(redirect_source); 299 mv.redirects.push_back(redirect_dest); 300 list->push_back(mv); 301} 302 303TEST_F(TopSitesTest, GetCanonicalURL) { 304 ChromeThread db_loop(ChromeThread::DB, MessageLoop::current()); 305 // Have two chains: 306 // google.com -> www.google.com 307 // news.google.com (no redirects) 308 GURL news("http://news.google.com/"); 309 GURL source("http://google.com/"); 310 GURL dest("http://www.google.com/"); 311 312 std::vector<MostVisitedURL> most_visited; 313 AppendMostVisitedURLWithRedirect(&most_visited, source, dest); 314 AppendMostVisitedURL(&most_visited, news); 315 StoreMostVisited(&most_visited); 316 317 // Random URLs not in the database are returned unchanged. 318 GURL result = GetCanonicalURL(GURL("http://fark.com/")); 319 EXPECT_EQ(GURL("http://fark.com/"), result); 320 321 // Easy case, there are no redirects and the exact URL is stored. 322 result = GetCanonicalURL(news); 323 EXPECT_EQ(news, result); 324 325 // The URL in question is the source URL in a redirect list. 326 result = GetCanonicalURL(source); 327 EXPECT_EQ(dest, result); 328 329 // The URL in question is the destination of a redirect. 330 result = GetCanonicalURL(dest); 331 EXPECT_EQ(dest, result); 332} 333 334TEST_F(TopSitesTest, DiffMostVisited) { 335 GURL stays_the_same("http://staysthesame/"); 336 GURL gets_added_1("http://getsadded1/"); 337 GURL gets_added_2("http://getsadded2/"); 338 GURL gets_deleted_1("http://getsdeleted2/"); 339 GURL gets_moved_1("http://getsmoved1/"); 340 341 std::vector<MostVisitedURL> old_list; 342 AppendMostVisitedURL(&old_list, stays_the_same); // 0 (unchanged) 343 AppendMostVisitedURL(&old_list, gets_deleted_1); // 1 (deleted) 344 AppendMostVisitedURL(&old_list, gets_moved_1); // 2 (moved to 3) 345 346 std::vector<MostVisitedURL> new_list; 347 AppendMostVisitedURL(&new_list, stays_the_same); // 0 (unchanged) 348 AppendMostVisitedURL(&new_list, gets_added_1); // 1 (added) 349 AppendMostVisitedURL(&new_list, gets_added_2); // 2 (added) 350 AppendMostVisitedURL(&new_list, gets_moved_1); // 3 (moved from 2) 351 352 std::vector<size_t> added; 353 std::vector<size_t> deleted; 354 std::vector<size_t> moved; 355 DiffMostVisited(old_list, new_list, &added, &deleted, &moved); 356 357 ASSERT_EQ(2u, added.size()); 358 ASSERT_EQ(1u, deleted.size()); 359 ASSERT_EQ(1u, moved.size()); 360 361 // There should be 2 URLs added, we don't assume what order they're in inside 362 // the result vector. 363 EXPECT_TRUE(added[0] == 1 || added[1] == 1); 364 EXPECT_TRUE(added[0] == 2 || added[1] == 2); 365 366 EXPECT_EQ(1u, deleted[0]); 367 EXPECT_EQ(3u, moved[0]); 368} 369 370TEST_F(TopSitesTest, SetPageThumbnail) { 371 ChromeThread db_loop(ChromeThread::DB, MessageLoop::current()); 372 GURL url1a("http://google.com/"); 373 GURL url1b("http://www.google.com/"); 374 GURL url2("http://images.google.com/"); 375 GURL invalid_url("chrome://favicon/http://google.com/"); 376 377 std::vector<MostVisitedURL> list; 378 AppendMostVisitedURL(&list, url2); 379 380 MostVisitedURL mv; 381 mv.url = url1b; 382 mv.redirects.push_back(url1a); 383 mv.redirects.push_back(url1b); 384 list.push_back(mv); 385 386 // Save our most visited data containing that one site. 387 StoreMostVisited(&list); 388 389 // Create a dummy thumbnail. 390 SkBitmap thumbnail; 391 thumbnail.setConfig(SkBitmap::kARGB_8888_Config, 4, 4); 392 thumbnail.allocPixels(); 393 thumbnail.eraseRGB(0x00, 0x00, 0x00); 394 395 base::Time now = base::Time::Now(); 396 ThumbnailScore low_score(1.0, true, true, now); 397 ThumbnailScore medium_score(0.5, true, true, now); 398 ThumbnailScore high_score(0.0, true, true, now); 399 400 // Setting the thumbnail for invalid pages should fail. 401 EXPECT_FALSE(top_sites().SetPageThumbnail(invalid_url, 402 thumbnail, medium_score)); 403 404 // Setting the thumbnail for url2 should succeed, lower scores shouldn't 405 // replace it, higher scores should. 406 EXPECT_TRUE(top_sites().SetPageThumbnail(url2, thumbnail, medium_score)); 407 EXPECT_FALSE(top_sites().SetPageThumbnail(url2, thumbnail, low_score)); 408 EXPECT_TRUE(top_sites().SetPageThumbnail(url2, thumbnail, high_score)); 409 410 // Set on the redirect source should succeed. It should be replacable by 411 // the same score on the redirect destination, which in turn should not 412 // be replaced by the source again. 413 EXPECT_TRUE(top_sites().SetPageThumbnail(url1a, thumbnail, medium_score)); 414 EXPECT_TRUE(top_sites().SetPageThumbnail(url1b, thumbnail, medium_score)); 415 EXPECT_FALSE(top_sites().SetPageThumbnail(url1a, thumbnail, medium_score)); 416} 417 418TEST_F(TopSitesTest, GetPageThumbnail) { 419 ChromeThread db_loop(ChromeThread::DB, MessageLoop::current()); 420 MostVisitedURLList url_list; 421 MostVisitedURL url1 = {GURL("http://asdf.com")}; 422 url1.redirects.push_back(url1.url); 423 url_list.push_back(url1); 424 425 MostVisitedURL url2 = {GURL("http://gmail.com")}; 426 url2.redirects.push_back(url2.url); 427 url2.redirects.push_back(GURL("http://mail.google.com")); 428 url_list.push_back(url2); 429 430 top_sites().UpdateMostVisited(url_list); 431 MessageLoop::current()->RunAllPending(); 432 433 // Create a dummy thumbnail. 434 SkBitmap thumbnail; 435 thumbnail.setConfig(SkBitmap::kARGB_8888_Config, 4, 4); 436 thumbnail.allocPixels(); 437 thumbnail.eraseRGB(0x00, 0x00, 0x00); 438 ThumbnailScore score(0.5, true, true, base::Time::Now()); 439 440 RefCountedBytes* result = NULL; 441 EXPECT_TRUE(top_sites().SetPageThumbnail(url1.url, thumbnail, score)); 442 EXPECT_TRUE(top_sites().GetPageThumbnail(url1.url, &result)); 443 444 EXPECT_TRUE(top_sites().SetPageThumbnail(GURL("http://gmail.com"), 445 thumbnail, score)); 446 EXPECT_TRUE(top_sites().GetPageThumbnail(GURL("http://gmail.com"), 447 &result)); 448 // Get a thumbnail via a redirect. 449 EXPECT_TRUE(top_sites().GetPageThumbnail(GURL("http://mail.google.com"), 450 &result)); 451 452 EXPECT_TRUE(top_sites().SetPageThumbnail(GURL("http://mail.google.com"), 453 thumbnail, score)); 454 EXPECT_TRUE(top_sites().GetPageThumbnail(url2.url, &result)); 455 456 scoped_ptr<SkBitmap> out_bitmap(gfx::JPEGCodec::Decode(result->front(), 457 result->size())); 458 EXPECT_EQ(0, memcmp(thumbnail.getPixels(), out_bitmap->getPixels(), 459 thumbnail.getSize())); 460} 461 462TEST_F(TopSitesTest, GetMostVisited) { 463 ChromeThread db_loop(ChromeThread::DB, MessageLoop::current()); 464 GURL news("http://news.google.com/"); 465 GURL google("http://google.com/"); 466 467 MockHistoryServiceImpl hs; 468 hs.AppendMockPage(news, ASCIIToUTF16("Google News")); 469 hs.AppendMockPage(google, ASCIIToUTF16("Google")); 470 top_sites().SetMockHistoryService(&hs); 471 472 top_sites().StartQueryForMostVisited(); 473 MessageLoop::current()->RunAllPending(); 474 top_sites().GetMostVisitedURLs( 475 consumer(), 476 NewCallback(static_cast<TopSitesTest*>(this), 477 &TopSitesTest::OnTopSitesAvailable)); 478 // 2 extra prepopulated URLs. 479 ASSERT_EQ(4u, urls().size()); 480 EXPECT_EQ(news, urls()[0].url); 481 EXPECT_EQ(google, urls()[1].url); 482 EXPECT_EQ(welcome_url(), urls()[2].url); 483 EXPECT_EQ(themes_url(), urls()[3].url); 484} 485 486TEST_F(TopSitesTest, MockDatabase) { 487 ChromeThread db_loop(ChromeThread::DB, MessageLoop::current()); 488 MockTopSitesDatabaseImpl* db = new MockTopSitesDatabaseImpl; 489 // |db| is destroyed when the top_sites is destroyed in TearDown. 490 top_sites().db_.reset(db); 491 MostVisitedURL url; 492 GURL asdf_url("http://asdf.com"); 493 string16 asdf_title(ASCIIToUTF16("ASDF")); 494 GURL google_url("http://google.com"); 495 string16 google_title(ASCIIToUTF16("Google")); 496 GURL news_url("http://news.google.com"); 497 string16 news_title(ASCIIToUTF16("Google News")); 498 499 url.url = asdf_url; 500 url.title = asdf_title; 501 url.redirects.push_back(url.url); 502 Images thumbnail; 503 db->SetPageThumbnail(url, 0, thumbnail); 504 505 top_sites().ReadDatabase(); 506 507 top_sites().GetMostVisitedURLs( 508 consumer(), 509 NewCallback(static_cast<TopSitesTest*>(this), 510 &TopSitesTest::OnTopSitesAvailable)); 511 ASSERT_EQ(3u, urls().size()); 512 EXPECT_EQ(asdf_url, urls()[0].url); 513 EXPECT_EQ(asdf_title, urls()[0].title); 514 EXPECT_EQ(welcome_url(), urls()[1].url); 515 EXPECT_EQ(themes_url(), urls()[2].url); 516 517 MostVisitedURL url2; 518 url2.url = google_url; 519 url2.title = google_title; 520 url2.redirects.push_back(url2.url); 521 522 // Add new thumbnail at rank 0 and shift the other result to 1. 523 db->SetPageThumbnail(url2, 0, thumbnail); 524 525 top_sites().ReadDatabase(); 526 527 top_sites().GetMostVisitedURLs( 528 consumer(), 529 NewCallback(static_cast<TopSitesTest*>(this), 530 &TopSitesTest::OnTopSitesAvailable)); 531 ASSERT_EQ(4u, urls().size()); 532 EXPECT_EQ(google_url, urls()[0].url); 533 EXPECT_EQ(google_title, urls()[0].title); 534 EXPECT_EQ(asdf_url, urls()[1].url); 535 EXPECT_EQ(asdf_title, urls()[1].title); 536 EXPECT_EQ(welcome_url(), urls()[2].url); 537 EXPECT_EQ(themes_url(), urls()[3].url); 538 539 MockHistoryServiceImpl hs; 540 // Add one old, one new URL to the history. 541 hs.AppendMockPage(google_url, google_title); 542 hs.AppendMockPage(news_url, news_title); 543 top_sites().SetMockHistoryService(&hs); 544 545 // This writes the new data to the DB. 546 top_sites().StartQueryForMostVisited(); 547 MessageLoop::current()->RunAllPending(); 548 549 std::map<GURL, Images> thumbnails; 550 MostVisitedURLList result; 551 db->GetPageThumbnails(&result, &thumbnails); 552 ASSERT_EQ(4u, result.size()); 553 EXPECT_EQ(google_title, result[0].title); 554 EXPECT_EQ(news_title, result[1].title); 555} 556 557// Test TopSitesDatabaseImpl. 558TEST_F(TopSitesTest, TopSitesDB) { 559 TopSitesDatabaseImpl db; 560 561 ASSERT_TRUE(db.Init(file_name())); 562 563 MostVisitedURL url; 564 GURL asdf_url("http://asdf.com"); 565 string16 asdf_title(ASCIIToUTF16("ASDF")); 566 GURL google_url("http://google.com"); 567 string16 google_title(ASCIIToUTF16("Google")); 568 GURL news_url("http://news.google.com"); 569 string16 news_title(ASCIIToUTF16("Google News")); 570 571 url.url = asdf_url; 572 url.title = asdf_title; 573 url.redirects.push_back(url.url); 574 Images thumbnail; 575 thumbnail.thumbnail = random_thumbnail(); 576 // Add asdf at rank 0. 577 db.SetPageThumbnail(url, 0, thumbnail); 578 579 Images result; 580 EXPECT_TRUE(db.GetPageThumbnail(url.url, &result)); 581 EXPECT_EQ(thumbnail.thumbnail->data.size(), result.thumbnail->data.size()); 582 EXPECT_TRUE(ThumbnailsAreEqual(thumbnail.thumbnail, result.thumbnail)); 583 584 MostVisitedURLList urls; 585 std::map<GURL, Images> thumbnails; 586 db.GetPageThumbnails(&urls, &thumbnails); 587 ASSERT_EQ(1u, urls.size()); 588 EXPECT_EQ(asdf_url, urls[0].url); 589 EXPECT_EQ(asdf_title, urls[0].title); 590 591 url.url = google_url; 592 url.title = google_title; 593 594 // Add google at rank 1 - no rank shifting. 595 db.SetPageThumbnail(url, 1, thumbnail); 596 db.GetPageThumbnails(&urls, &thumbnails); 597 ASSERT_EQ(2u, urls.size()); 598 EXPECT_EQ(asdf_url, urls[0].url); 599 EXPECT_EQ(asdf_title, urls[0].title); 600 EXPECT_EQ(google_url, urls[1].url); 601 EXPECT_EQ(google_title, urls[1].title); 602 603 url.url = news_url; 604 url.title = news_title; 605 606 // Add news at rank 1 - shift google to rank 2. 607 db.SetPageThumbnail(url, 1, thumbnail); 608 db.GetPageThumbnails(&urls, &thumbnails); 609 ASSERT_EQ(3u, urls.size()); 610 EXPECT_EQ(asdf_url, urls[0].url); 611 EXPECT_EQ(news_url, urls[1].url); 612 EXPECT_EQ(google_url, urls[2].url); 613 614 // Move news at rank 0 - shift the rest up. 615 db.SetPageThumbnail(url, 0, thumbnail); 616 db.GetPageThumbnails(&urls, &thumbnails); 617 ASSERT_EQ(3u, urls.size()); 618 EXPECT_EQ(news_url, urls[0].url); 619 EXPECT_EQ(asdf_url, urls[1].url); 620 EXPECT_EQ(google_url, urls[2].url); 621 622 // Move news at rank 2 - shift the rest down. 623 db.SetPageThumbnail(url, 2, thumbnail); 624 db.GetPageThumbnails(&urls, &thumbnails); 625 ASSERT_EQ(3u, urls.size()); 626 EXPECT_EQ(asdf_url, urls[0].url); 627 EXPECT_EQ(google_url, urls[1].url); 628 EXPECT_EQ(news_url, urls[2].url); 629 630 // Delete asdf. 631 url.url = asdf_url; 632 db.RemoveURL(url); 633 634 db.GetPageThumbnails(&urls, &thumbnails); 635 ASSERT_EQ(2u, urls.size()); 636 EXPECT_EQ(google_url, urls[0].url); 637 EXPECT_EQ(news_url, urls[1].url); 638} 639 640// Test TopSites with a real database. 641TEST_F(TopSitesTest, RealDatabase) { 642 ChromeThread db_loop(ChromeThread::DB, MessageLoop::current()); 643 TopSitesDatabaseImpl* db = new TopSitesDatabaseImpl; 644 645 ASSERT_TRUE(db->Init(file_name())); 646 // |db| is destroyed when the top_sites is destroyed in TearDown. 647 top_sites().db_.reset(db); 648 MostVisitedURL url; 649 GURL asdf_url("http://asdf.com"); 650 string16 asdf_title(ASCIIToUTF16("ASDF")); 651 GURL google1_url("http://google.com"); 652 GURL google2_url("http://google.com/redirect"); 653 GURL google3_url("http://www.google.com"); 654 string16 google_title(ASCIIToUTF16("Google")); 655 GURL news_url("http://news.google.com"); 656 string16 news_title(ASCIIToUTF16("Google News")); 657 658 url.url = asdf_url; 659 url.title = asdf_title; 660 url.redirects.push_back(url.url); 661 Images thumbnail; 662 thumbnail.thumbnail = random_thumbnail(); 663 db->SetPageThumbnail(url, 0, thumbnail); 664 665 top_sites().ReadDatabase(); 666 667 top_sites().GetMostVisitedURLs( 668 consumer(), 669 NewCallback(static_cast<TopSitesTest*>(this), 670 &TopSitesTest::OnTopSitesAvailable)); 671 ASSERT_EQ(3u, urls().size()); 672 EXPECT_EQ(asdf_url, urls()[0].url); 673 EXPECT_EQ(asdf_title, urls()[0].title); 674 EXPECT_EQ(welcome_url(), urls()[1].url); 675 EXPECT_EQ(themes_url(), urls()[2].url); 676 677 Images img_result; 678 db->GetPageThumbnail(asdf_url, &img_result); 679 EXPECT_TRUE(img_result.thumbnail != NULL); 680 EXPECT_TRUE(ThumbnailsAreEqual(random_thumbnail(), img_result.thumbnail)); 681 682 RefCountedBytes* thumbnail_result; 683 EXPECT_TRUE(top_sites().GetPageThumbnail(asdf_url, &thumbnail_result)); 684 EXPECT_TRUE(thumbnail_result != NULL); 685 EXPECT_TRUE(ThumbnailsAreEqual(random_thumbnail(), thumbnail_result)); 686 687 MostVisitedURL url2; 688 url2.url = google1_url; 689 url2.title = google_title; 690 url2.redirects.push_back(google1_url); 691 url2.redirects.push_back(google2_url); 692 url2.redirects.push_back(google3_url); 693 694 // Add new thumbnail at rank 0 and shift the other result to 1. 695 Images g_thumbnail; 696 g_thumbnail.thumbnail = google_thumbnail(); 697 db->SetPageThumbnail(url2, 0, g_thumbnail); 698 699 top_sites().ReadDatabase(); 700 701 top_sites().GetMostVisitedURLs( 702 consumer(), 703 NewCallback(static_cast<TopSitesTest*>(this), 704 &TopSitesTest::OnTopSitesAvailable)); 705 ASSERT_EQ(4u, urls().size()); 706 EXPECT_EQ(google1_url, urls()[0].url); 707 EXPECT_EQ(google_title, urls()[0].title); 708 EXPECT_TRUE(top_sites().GetPageThumbnail(google1_url, &thumbnail_result)); 709 EXPECT_TRUE(ThumbnailsAreEqual(google_thumbnail(), thumbnail_result)); 710 ASSERT_EQ(3u, urls()[0].redirects.size()); 711 EXPECT_EQ(google1_url, urls()[0].redirects[0]); 712 EXPECT_EQ(google2_url, urls()[0].redirects[1]); 713 EXPECT_EQ(google3_url, urls()[0].redirects[2]); 714 715 EXPECT_EQ(asdf_url, urls()[1].url); 716 EXPECT_EQ(asdf_title, urls()[1].title); 717 EXPECT_EQ(welcome_url(), urls()[2].url); 718 EXPECT_EQ(themes_url(), urls()[3].url); 719 720 MockHistoryServiceImpl hs; 721 // Add one old, one new URL to the history. 722 hs.AppendMockPage(google1_url, google_title); 723 hs.AppendMockPage(news_url, news_title); 724 top_sites().SetMockHistoryService(&hs); 725 726 // This requests data from History Service and writes it to the DB. 727 top_sites().StartQueryForMostVisited(); 728 MessageLoop::current()->RunAllPending(); 729 730 std::map<GURL, Images> thumbnails; 731 MostVisitedURLList results; 732 db->GetPageThumbnails(&results, &thumbnails); 733 ASSERT_EQ(4u, results.size()); 734 EXPECT_EQ(google_title, results[0].title); 735 EXPECT_EQ(news_title, results[1].title); 736 737 scoped_ptr<SkBitmap> weewar_bitmap( 738 gfx::JPEGCodec::Decode(weewar_thumbnail()->front(), 739 weewar_thumbnail()->size())); 740 741 base::Time now = base::Time::Now(); 742 ThumbnailScore low_score(1.0, true, true, now); 743 ThumbnailScore medium_score(0.5, true, true, now); 744 ThumbnailScore high_score(0.0, true, true, now); 745 746 // 1. Set to weewar. (Writes the thumbnail to the DB.) 747 EXPECT_TRUE(top_sites().SetPageThumbnail(google1_url, 748 *weewar_bitmap, 749 medium_score)); 750 RefCountedBytes* out_1; 751 Images out_2; 752 EXPECT_TRUE(top_sites().GetPageThumbnail(google1_url, &out_1)); 753 754 MessageLoop::current()->RunAllPending(); 755 756 db->GetPageThumbnail(url2.url, &out_2); 757 EXPECT_TRUE(ThumbnailsAreEqual(out_1, out_2.thumbnail)); 758 759 scoped_ptr<SkBitmap> google_bitmap( 760 gfx::JPEGCodec::Decode(google_thumbnail()->front(), 761 google_thumbnail()->size())); 762 763 // 2. Set to google - low score. 764 EXPECT_FALSE(top_sites().SetPageThumbnail(google1_url, 765 *google_bitmap, 766 low_score)); 767 768 // 3. Set to google - high score. 769 EXPECT_TRUE(top_sites().SetPageThumbnail(google1_url, 770 *google_bitmap, 771 high_score)); 772 // Check that the thumbnail was updated. 773 EXPECT_TRUE(top_sites().GetPageThumbnail(google1_url, &out_1)); 774 EXPECT_FALSE(ThumbnailsAreEqual(out_1, out_2.thumbnail)); 775 MessageLoop::current()->RunAllPending(); 776 777 // Read the new thumbnail from the DB - should match what's in TopSites. 778 db->GetPageThumbnail(url2.url, &out_2); 779 EXPECT_TRUE(ThumbnailsAreEqual(out_1, out_2.thumbnail)); 780 EXPECT_TRUE(high_score.Equals(out_2.thumbnail_score)); 781} 782 783TEST_F(TopSitesTest, DeleteNotifications) { 784 ChromeThread db_loop(ChromeThread::DB, MessageLoop::current()); 785 GURL google1_url("http://google.com"); 786 GURL google2_url("http://google.com/redirect"); 787 GURL google3_url("http://www.google.com"); 788 string16 google_title(ASCIIToUTF16("Google")); 789 GURL news_url("http://news.google.com"); 790 string16 news_title(ASCIIToUTF16("Google News")); 791 792 MockHistoryServiceImpl hs; 793 794 top_sites().Init(file_name()); 795 796 hs.AppendMockPage(google1_url, google_title); 797 hs.AppendMockPage(news_url, news_title); 798 top_sites().SetMockHistoryService(&hs); 799 800 top_sites().StartQueryForMostVisited(); 801 MessageLoop::current()->RunAllPending(); 802 803 top_sites().GetMostVisitedURLs( 804 consumer(), 805 NewCallback(static_cast<TopSitesTest*>(this), 806 &TopSitesTest::OnTopSitesAvailable)); 807 // 2 extra prepopulated URLs. 808 ASSERT_EQ(4u, urls().size()); 809 810 hs.RemoveMostVisitedURL(); 811 812 history::URLsDeletedDetails history_details; 813 history_details.all_history = false; 814 Details<URLsDeletedDetails> details(&history_details); 815 top_sites().Observe(NotificationType::HISTORY_URLS_DELETED, 816 Source<Profile> (&profile()), 817 details); 818 MessageLoop::current()->RunAllPending(); 819 820 top_sites().GetMostVisitedURLs( 821 consumer(), 822 NewCallback(static_cast<TopSitesTest*>(this), 823 &TopSitesTest::OnTopSitesAvailable)); 824 ASSERT_EQ(3u, urls().size()); 825 EXPECT_EQ(google_title, urls()[0].title); 826 EXPECT_EQ(welcome_url(), urls()[1].url); 827 EXPECT_EQ(themes_url(), urls()[2].url); 828 829 hs.RemoveMostVisitedURL(); 830 history_details.all_history = true; 831 details = Details<HistoryDetails>(&history_details); 832 top_sites().Observe(NotificationType::HISTORY_URLS_DELETED, 833 Source<Profile> (&profile()), 834 details); 835 MessageLoop::current()->RunAllPending(); 836 top_sites().GetMostVisitedURLs( 837 consumer(), 838 NewCallback(static_cast<TopSitesTest*>(this), 839 &TopSitesTest::OnTopSitesAvailable)); 840 ASSERT_EQ(2u, urls().size()); 841 EXPECT_EQ(welcome_url(), urls()[0].url); 842 EXPECT_EQ(themes_url(), urls()[1].url); 843} 844 845TEST_F(TopSitesTest, PinnedURLsDeleted) { 846 ChromeThread db_loop(ChromeThread::DB, MessageLoop::current()); 847 GURL google1_url("http://google.com"); 848 GURL google2_url("http://google.com/redirect"); 849 GURL google3_url("http://www.google.com"); 850 string16 google_title(ASCIIToUTF16("Google")); 851 GURL news_url("http://news.google.com"); 852 string16 news_title(ASCIIToUTF16("Google News")); 853 854 MockHistoryServiceImpl hs; 855 856 top_sites().Init(file_name()); 857 858 hs.AppendMockPage(google1_url, google_title); 859 hs.AppendMockPage(news_url, news_title); 860 top_sites().SetMockHistoryService(&hs); 861 862 top_sites().StartQueryForMostVisited(); 863 MessageLoop::current()->RunAllPending(); 864 top_sites().GetMostVisitedURLs( 865 consumer(), 866 NewCallback(static_cast<TopSitesTest*>(this), 867 &TopSitesTest::OnTopSitesAvailable)); 868 MessageLoop::current()->RunAllPending(); 869 EXPECT_EQ(1u, number_of_callbacks()); 870 // 2 extra prepopulated URLs. 871 ASSERT_EQ(4u, urls().size()); 872 873 top_sites().AddPinnedURL(news_url, 3); 874 EXPECT_TRUE(top_sites().IsURLPinned(news_url)); 875 876 hs.RemoveMostVisitedURL(); 877 history::URLsDeletedDetails history_details; 878 history_details.all_history = false; 879 history_details.urls.insert(news_url); 880 Details<URLsDeletedDetails> details(&history_details); 881 top_sites().Observe(NotificationType::HISTORY_URLS_DELETED, 882 Source<Profile> (&profile()), 883 details); 884 MessageLoop::current()->RunAllPending(); 885 top_sites().GetMostVisitedURLs( 886 consumer(), 887 NewCallback(static_cast<TopSitesTest*>(this), 888 &TopSitesTest::OnTopSitesAvailable)); 889 MessageLoop::current()->RunAllPending(); 890 EXPECT_EQ(2u, number_of_callbacks()); 891 ASSERT_EQ(3u, urls().size()); 892 EXPECT_FALSE(top_sites().IsURLPinned(news_url)); 893 894 hs.RemoveMostVisitedURL(); 895 history_details.all_history = true; 896 details = Details<HistoryDetails>(&history_details); 897 top_sites().Observe(NotificationType::HISTORY_URLS_DELETED, 898 Source<Profile> (&profile()), 899 details); 900 MessageLoop::current()->RunAllPending(); 901 top_sites().GetMostVisitedURLs( 902 consumer(), 903 NewCallback(static_cast<TopSitesTest*>(this), 904 &TopSitesTest::OnTopSitesAvailable)); 905 ASSERT_EQ(2u, urls().size()); 906 MessageLoop::current()->RunAllPending(); 907 908 top_sites().StartQueryForMostVisited(); 909 MessageLoop::current()->RunAllPending(); 910 top_sites().GetMostVisitedURLs( 911 consumer(), 912 NewCallback(static_cast<TopSitesTest*>(this), 913 &TopSitesTest::OnTopSitesAvailable)); 914 ASSERT_EQ(2u, urls().size()); 915 EXPECT_EQ(welcome_url(), urls()[0].url); 916 EXPECT_EQ(themes_url(), urls()[1].url); 917} 918 919TEST_F(TopSitesTest, GetUpdateDelay) { 920 top_sites().last_num_urls_changed_ = 0; 921 EXPECT_EQ(30, top_sites().GetUpdateDelay().InSeconds()); 922 923 top_sites().top_sites_.resize(20); 924 top_sites().last_num_urls_changed_ = 0; 925 EXPECT_EQ(60, top_sites().GetUpdateDelay().InMinutes()); 926 927 top_sites().last_num_urls_changed_ = 3; 928 EXPECT_EQ(52, top_sites().GetUpdateDelay().InMinutes()); 929 930 top_sites().last_num_urls_changed_ = 20; 931 EXPECT_EQ(1, top_sites().GetUpdateDelay().InMinutes()); 932} 933 934TEST_F(TopSitesTest, Migration) { 935 ChromeThread db_loop(ChromeThread::DB, MessageLoop::current()); 936 GURL google1_url("http://google.com"); 937 string16 google_title(ASCIIToUTF16("Google")); 938 GURL news_url("http://news.google.com"); 939 string16 news_title(ASCIIToUTF16("Google News")); 940 941 MockHistoryServiceImpl hs; 942 943 top_sites().Init(file_name()); 944 945 hs.AppendMockPage(google1_url, google_title); 946 hs.AppendMockPage(news_url, news_title); 947 top_sites().SetMockHistoryService(&hs); 948 MessageLoop::current()->RunAllPending(); 949 950 top_sites().StartMigration(); 951 EXPECT_TRUE(top_sites().migration_in_progress_); 952 MessageLoop::current()->RunAllPending(); 953 EXPECT_EQ(2, hs.GetNumberOfThumbnailRequests()); 954 EXPECT_FALSE(top_sites().migration_in_progress_); 955} 956 957TEST_F(TopSitesTest, QueueingRequestsForTopSites) { 958 ChromeThread db_loop(ChromeThread::DB, MessageLoop::current()); 959 CancelableRequestConsumer c1; 960 CancelableRequestConsumer c2; 961 CancelableRequestConsumer c3; 962 top_sites().GetMostVisitedURLs( 963 &c1, 964 NewCallback(static_cast<TopSitesTest*>(this), 965 &TopSitesTest::OnTopSitesAvailable)); 966 967 top_sites().GetMostVisitedURLs( 968 &c2, 969 NewCallback(static_cast<TopSitesTest*>(this), 970 &TopSitesTest::OnTopSitesAvailable)); 971 972 top_sites().GetMostVisitedURLs( 973 &c3, 974 NewCallback(static_cast<TopSitesTest*>(this), 975 &TopSitesTest::OnTopSitesAvailable)); 976 977 EXPECT_EQ(0u, number_of_callbacks()); 978 EXPECT_EQ(0u, urls().size()); 979 980 MostVisitedURLList pages; 981 MostVisitedURL url; 982 url.url = GURL("http://1.com/"); 983 url.redirects.push_back(url.url); 984 pages.push_back(url); 985 url.url = GURL("http://2.com/"); 986 url.redirects.push_back(url.url); 987 pages.push_back(url); 988 top_sites().OnTopSitesAvailable(0, pages); 989 MessageLoop::current()->RunAllPending(); 990 991 EXPECT_EQ(3u, number_of_callbacks()); 992 993 ASSERT_EQ(4u, urls().size()); 994 EXPECT_EQ("http://1.com/", urls()[0].url.spec()); 995 EXPECT_EQ("http://2.com/", urls()[1].url.spec()); 996 EXPECT_EQ(welcome_url(), urls()[2].url); 997 EXPECT_EQ(themes_url(), urls()[3].url); 998 999 1000 url.url = GURL("http://3.com/"); 1001 url.redirects.push_back(url.url); 1002 pages.push_back(url); 1003 top_sites().OnTopSitesAvailable(0, pages); 1004 MessageLoop::current()->RunAllPending(); 1005 1006 top_sites().GetMostVisitedURLs( 1007 &c3, 1008 NewCallback(static_cast<TopSitesTest*>(this), 1009 &TopSitesTest::OnTopSitesAvailable)); 1010 1011 EXPECT_EQ(4u, number_of_callbacks()); 1012 1013 ASSERT_EQ(5u, urls().size()); 1014 EXPECT_EQ("http://1.com/", urls()[0].url.spec()); 1015 EXPECT_EQ("http://2.com/", urls()[1].url.spec()); 1016 EXPECT_EQ("http://3.com/", urls()[2].url.spec()); 1017 EXPECT_EQ(welcome_url(), urls()[3].url); 1018 EXPECT_EQ(themes_url(), urls()[4].url); 1019 1020} 1021 1022TEST_F(TopSitesTest, CancelingRequestsForTopSites) { 1023 ChromeThread db_loop(ChromeThread::DB, MessageLoop::current()); 1024 CancelableRequestConsumer c1; 1025 CancelableRequestConsumer c2; 1026 top_sites().GetMostVisitedURLs( 1027 &c1, 1028 NewCallback(static_cast<TopSitesTest*>(this), 1029 &TopSitesTest::OnTopSitesAvailable)); 1030 1031 top_sites().GetMostVisitedURLs( 1032 &c2, 1033 NewCallback(static_cast<TopSitesTest*>(this), 1034 &TopSitesTest::OnTopSitesAvailable)); 1035 1036 { 1037 CancelableRequestConsumer c3; 1038 top_sites().GetMostVisitedURLs( 1039 &c3, 1040 NewCallback(static_cast<TopSitesTest*>(this), 1041 &TopSitesTest::OnTopSitesAvailable)); 1042 // c3 is out of scope, and the request should be cancelled. 1043 } 1044 1045 // No requests until OnTopSitesAvailable is called. 1046 EXPECT_EQ(0u, number_of_callbacks()); 1047 EXPECT_EQ(0u, urls().size()); 1048 1049 MostVisitedURLList pages; 1050 MostVisitedURL url; 1051 url.url = GURL("http://1.com/"); 1052 url.redirects.push_back(url.url); 1053 pages.push_back(url); 1054 url.url = GURL("http://2.com/"); 1055 pages.push_back(url); 1056 1057 top_sites().OnTopSitesAvailable(0, pages); 1058 MessageLoop::current()->RunAllPending(); 1059 1060 // 1 request was canceled. 1061 EXPECT_EQ(2u, number_of_callbacks()); 1062 1063 // 2 extra prepopulated URLs. 1064 ASSERT_EQ(4u, urls().size()); 1065 EXPECT_EQ("http://1.com/", urls()[0].url.spec()); 1066 EXPECT_EQ("http://2.com/", urls()[1].url.spec()); 1067} 1068 1069TEST_F(TopSitesTest, AddTemporaryThumbnail) { 1070 ChromeThread db_loop(ChromeThread::DB, MessageLoop::current()); 1071 GURL unknown_url("http://news.google.com/"); 1072 GURL invalid_url("chrome://thumb/http://google.com/"); 1073 GURL url1a("http://google.com/"); 1074 GURL url1b("http://www.google.com/"); 1075 1076 // Create a dummy thumbnail. 1077 SkBitmap thumbnail; 1078 thumbnail.setConfig(SkBitmap::kARGB_8888_Config, 4, 4); 1079 thumbnail.allocPixels(); 1080 thumbnail.eraseRGB(0x00, 0x00, 0x00); 1081 1082 ThumbnailScore medium_score(0.5, true, true, base::Time::Now()); 1083 1084 // Don't store thumbnails for Javascript URLs. 1085 EXPECT_FALSE(top_sites().SetPageThumbnail(invalid_url, 1086 thumbnail, medium_score)); 1087 // Store thumbnails for unknown (but valid) URLs temporarily - calls 1088 // AddTemporaryThumbnail. 1089 EXPECT_TRUE(top_sites().SetPageThumbnail(unknown_url, 1090 thumbnail, medium_score)); 1091 1092 std::vector<MostVisitedURL> list; 1093 1094 MostVisitedURL mv; 1095 mv.url = unknown_url; 1096 mv.redirects.push_back(mv.url); 1097 mv.redirects.push_back(url1a); 1098 mv.redirects.push_back(url1b); 1099 list.push_back(mv); 1100 1101 // Update URLs - use temporary thumbnails. 1102 top_sites().UpdateMostVisited(list); 1103 1104 RefCountedBytes* out = NULL; 1105 ASSERT_TRUE(top_sites().GetPageThumbnail(unknown_url, &out)); 1106 scoped_ptr<SkBitmap> out_bitmap(gfx::JPEGCodec::Decode(out->front(), 1107 out->size())); 1108 EXPECT_EQ(0, memcmp(thumbnail.getPixels(), out_bitmap->getPixels(), 1109 thumbnail.getSize())); 1110} 1111 1112TEST_F(TopSitesTest, Blacklisting) { 1113 ChromeThread db_loop(ChromeThread::DB, MessageLoop::current()); 1114 MostVisitedURLList pages; 1115 MostVisitedURL url, url1; 1116 url.url = GURL("http://bbc.com/"); 1117 url.redirects.push_back(url.url); 1118 pages.push_back(url); 1119 url1.url = GURL("http://google.com/"); 1120 url1.redirects.push_back(url1.url); 1121 pages.push_back(url1); 1122 1123 CancelableRequestConsumer c; 1124 top_sites().GetMostVisitedURLs( 1125 &c, 1126 NewCallback(static_cast<TopSitesTest*>(this), 1127 &TopSitesTest::OnTopSitesAvailable)); 1128 top_sites().OnTopSitesAvailable(0, pages); 1129 MessageLoop::current()->RunAllPending(); 1130 { 1131 Lock& l = lock(); 1132 AutoLock lock(l); // IsBlacklisted must be in a lock. 1133 EXPECT_FALSE(top_sites().IsBlacklisted(GURL("http://bbc.com/"))); 1134 } 1135 1136 EXPECT_EQ(1u, number_of_callbacks()); 1137 1138 ASSERT_EQ(4u, urls().size()); 1139 EXPECT_EQ("http://bbc.com/", urls()[0].url.spec()); 1140 EXPECT_EQ("http://google.com/", urls()[1].url.spec()); 1141 EXPECT_EQ(welcome_url(), urls()[2].url); 1142 EXPECT_EQ(themes_url(), urls()[3].url); 1143 EXPECT_FALSE(top_sites().HasBlacklistedItems()); 1144 1145 top_sites().AddBlacklistedURL(GURL("http://google.com/")); 1146 EXPECT_TRUE(top_sites().HasBlacklistedItems()); 1147 { 1148 Lock& l = lock(); 1149 AutoLock lock(l); // IsBlacklisted must be in a lock. 1150 EXPECT_TRUE(top_sites().IsBlacklisted(GURL("http://google.com/"))); 1151 EXPECT_FALSE(top_sites().IsBlacklisted(GURL("http://bbc.com/"))); 1152 EXPECT_FALSE(top_sites().IsBlacklisted(welcome_url())); 1153 } 1154 1155 top_sites().GetMostVisitedURLs( 1156 &c, 1157 NewCallback(static_cast<TopSitesTest*>(this), 1158 &TopSitesTest::OnTopSitesAvailable)); 1159 MessageLoop::current()->RunAllPending(); 1160 EXPECT_EQ(2u, number_of_callbacks()); 1161 ASSERT_EQ(3u, urls().size()); 1162 EXPECT_EQ("http://bbc.com/", urls()[0].url.spec()); 1163 EXPECT_EQ(welcome_url(), urls()[1].url); 1164 EXPECT_EQ(themes_url(), urls()[2].url); 1165 1166 top_sites().AddBlacklistedURL(welcome_url()); 1167 EXPECT_TRUE(top_sites().HasBlacklistedItems()); 1168 top_sites().GetMostVisitedURLs( 1169 &c, 1170 NewCallback(static_cast<TopSitesTest*>(this), 1171 &TopSitesTest::OnTopSitesAvailable)); 1172 ASSERT_EQ(2u, urls().size()); 1173 EXPECT_EQ("http://bbc.com/", urls()[0].url.spec()); 1174 EXPECT_EQ(themes_url(), urls()[1].url); 1175 1176 top_sites().RemoveBlacklistedURL(GURL("http://google.com/")); 1177 EXPECT_TRUE(top_sites().HasBlacklistedItems()); 1178 { 1179 Lock& l = lock(); 1180 AutoLock lock(l); // IsBlacklisted must be in a lock. 1181 EXPECT_FALSE(top_sites().IsBlacklisted(GURL("http://google.com/"))); 1182 } 1183 1184 top_sites().GetMostVisitedURLs( 1185 &c, 1186 NewCallback(static_cast<TopSitesTest*>(this), 1187 &TopSitesTest::OnTopSitesAvailable)); 1188 ASSERT_EQ(3u, urls().size()); 1189 EXPECT_EQ("http://bbc.com/", urls()[0].url.spec()); 1190 EXPECT_EQ("http://google.com/", urls()[1].url.spec()); 1191 EXPECT_EQ(themes_url(), urls()[2].url); 1192 1193 top_sites().ClearBlacklistedURLs(); 1194 EXPECT_FALSE(top_sites().HasBlacklistedItems()); 1195 top_sites().GetMostVisitedURLs( 1196 &c, 1197 NewCallback(static_cast<TopSitesTest*>(this), 1198 &TopSitesTest::OnTopSitesAvailable)); 1199 ASSERT_EQ(4u, urls().size()); 1200 EXPECT_EQ("http://bbc.com/", urls()[0].url.spec()); 1201 EXPECT_EQ("http://google.com/", urls()[1].url.spec()); 1202 EXPECT_EQ(welcome_url(), urls()[2].url); 1203 EXPECT_EQ(themes_url(), urls()[3].url); 1204} 1205 1206TEST_F(TopSitesTest, PinnedURLs) { 1207 ChromeThread db_loop(ChromeThread::DB, MessageLoop::current()); 1208 MostVisitedURLList pages; 1209 MostVisitedURL url, url1; 1210 url.url = GURL("http://bbc.com/"); 1211 url.redirects.push_back(url.url); 1212 pages.push_back(url); 1213 url1.url = GURL("http://google.com/"); 1214 url1.redirects.push_back(url1.url); 1215 pages.push_back(url1); 1216 1217 CancelableRequestConsumer c; 1218 top_sites().GetMostVisitedURLs( 1219 &c, 1220 NewCallback(static_cast<TopSitesTest*>(this), 1221 &TopSitesTest::OnTopSitesAvailable)); 1222 top_sites().OnTopSitesAvailable(0, pages); 1223 MessageLoop::current()->RunAllPending(); 1224 EXPECT_FALSE(top_sites().IsURLPinned(GURL("http://bbc.com/"))); 1225 1226 ASSERT_EQ(4u, urls().size()); 1227 EXPECT_EQ("http://bbc.com/", urls()[0].url.spec()); 1228 EXPECT_EQ("http://google.com/", urls()[1].url.spec()); 1229 EXPECT_EQ(welcome_url(), urls()[2].url); 1230 EXPECT_EQ(themes_url(), urls()[3].url); 1231 1232 top_sites().AddPinnedURL(GURL("http://google.com/"), 3); 1233 EXPECT_FALSE(top_sites().IsURLPinned(GURL("http://bbc.com/"))); 1234 EXPECT_FALSE(top_sites().IsURLPinned(welcome_url())); 1235 1236 top_sites().GetMostVisitedURLs( 1237 &c, 1238 NewCallback(static_cast<TopSitesTest*>(this), 1239 &TopSitesTest::OnTopSitesAvailable)); 1240 EXPECT_EQ(2u, number_of_callbacks()); 1241 ASSERT_EQ(4u, urls().size()); 1242 EXPECT_EQ("http://bbc.com/", urls()[0].url.spec()); 1243 EXPECT_EQ(welcome_url(), urls()[1].url); 1244 EXPECT_EQ(themes_url(), urls()[2].url); 1245 EXPECT_EQ("http://google.com/", urls()[3].url.spec()); 1246 1247 top_sites().RemovePinnedURL(GURL("http://google.com/")); 1248 EXPECT_FALSE(top_sites().IsURLPinned(GURL("http://google.com/"))); 1249 top_sites().GetMostVisitedURLs( 1250 &c, 1251 NewCallback(static_cast<TopSitesTest*>(this), 1252 &TopSitesTest::OnTopSitesAvailable)); 1253 1254 ASSERT_EQ(4u, urls().size()); 1255 EXPECT_EQ("http://bbc.com/", urls()[0].url.spec()); 1256 EXPECT_EQ("http://google.com/", urls()[1].url.spec()); 1257 EXPECT_EQ(welcome_url(), urls()[2].url); 1258 EXPECT_EQ(themes_url(), urls()[3].url); 1259 1260 top_sites().AddPinnedURL(GURL("http://bbc.com"), 1); 1261 top_sites().AddPinnedURL(themes_url(), 0); 1262 top_sites().GetMostVisitedURLs( 1263 &c, 1264 NewCallback(static_cast<TopSitesTest*>(this), 1265 &TopSitesTest::OnTopSitesAvailable)); 1266 1267 ASSERT_EQ(4u, urls().size()); 1268 EXPECT_EQ(themes_url(), urls()[0].url); 1269 EXPECT_EQ("http://bbc.com/", urls()[1].url.spec()); 1270 EXPECT_EQ("http://google.com/", urls()[2].url.spec()); 1271 EXPECT_EQ(welcome_url(), urls()[3].url); 1272 1273 top_sites().RemovePinnedURL(GURL("http://bbc.com")); 1274 top_sites().RemovePinnedURL(themes_url()); 1275 1276 top_sites().AddPinnedURL(welcome_url(), 1); 1277 top_sites().AddPinnedURL(GURL("http://bbc.com"), 3); 1278 1279 top_sites().GetMostVisitedURLs( 1280 &c, 1281 NewCallback(static_cast<TopSitesTest*>(this), 1282 &TopSitesTest::OnTopSitesAvailable)); 1283 1284 ASSERT_EQ(4u, urls().size()); 1285 EXPECT_EQ("http://google.com/", urls()[0].url.spec()); 1286 EXPECT_EQ(welcome_url(), urls()[1].url); 1287 EXPECT_EQ(themes_url(), urls()[2].url); 1288 EXPECT_EQ("http://bbc.com/", urls()[3].url.spec()); 1289} 1290 1291TEST_F(TopSitesTest, BlacklistingAndPinnedURLs) { 1292 ChromeThread db_loop(ChromeThread::DB, MessageLoop::current()); 1293 MostVisitedURLList pages; 1294 CancelableRequestConsumer c; 1295 top_sites().GetMostVisitedURLs( 1296 &c, 1297 NewCallback(static_cast<TopSitesTest*>(this), 1298 &TopSitesTest::OnTopSitesAvailable)); 1299 top_sites().OnTopSitesAvailable(0, pages); 1300 MessageLoop::current()->RunAllPending(); 1301 1302 ASSERT_EQ(2u, urls().size()); 1303 EXPECT_EQ(welcome_url(), urls()[0].url); 1304 EXPECT_EQ(themes_url(), urls()[1].url); 1305 1306 top_sites().AddPinnedURL(themes_url(), 1); 1307 top_sites().AddBlacklistedURL(welcome_url()); 1308 1309 top_sites().GetMostVisitedURLs( 1310 &c, 1311 NewCallback(static_cast<TopSitesTest*>(this), 1312 &TopSitesTest::OnTopSitesAvailable)); 1313 1314 ASSERT_EQ(2u, urls().size()); 1315 EXPECT_EQ(GURL(), urls()[0].url); 1316 EXPECT_EQ(themes_url(), urls()[1].url); 1317 1318} 1319 1320TEST_F(TopSitesTest, AddPrepopulatedPages) { 1321 MostVisitedURLList pages; 1322 top_sites().AddPrepopulatedPages(&pages); 1323 ASSERT_EQ(2u, pages.size()); 1324 EXPECT_EQ(welcome_url(), pages[0].url); 1325 EXPECT_EQ(themes_url(), pages[1].url); 1326 1327 pages.clear(); 1328 1329 MostVisitedURL url = {themes_url()}; 1330 pages.push_back(url); 1331 1332 top_sites().AddPrepopulatedPages(&pages); 1333 1334 // Themes URL is already in pages; should not be added twice. 1335 ASSERT_EQ(2u, pages.size()); 1336 EXPECT_EQ(themes_url(), pages[0].url); 1337 EXPECT_EQ(welcome_url(), pages[1].url); 1338} 1339 1340} // namespace history 1341