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 "base/bind.h" 6 #include "base/bind_helpers.h" 7 #include "base/file_util.h" 8 #include "base/files/scoped_temp_dir.h" 9 #include "base/format_macros.h" 10 #include "base/memory/weak_ptr.h" 11 #include "base/path_service.h" 12 #include "base/strings/string_util.h" 13 #include "base/strings/utf_string_conversions.h" 14 #include "base/values.h" 15 #include "chrome/browser/chrome_notification_types.h" 16 #include "chrome/browser/history/history_backend.h" 17 #include "chrome/browser/history/history_database.h" 18 #include "chrome/browser/history/history_db_task.h" 19 #include "chrome/browser/history/history_marshaling.h" 20 #include "chrome/browser/history/history_notifications.h" 21 #include "chrome/browser/history/history_service_factory.h" 22 #include "chrome/browser/history/history_unittest_base.h" 23 #include "chrome/browser/history/top_sites_backend.h" 24 #include "chrome/browser/history/top_sites_cache.h" 25 #include "chrome/browser/history/top_sites_database.h" 26 #include "chrome/browser/history/top_sites_likely_impl.h" 27 #include "chrome/browser/ui/webui/ntp/most_visited_handler.h" 28 #include "chrome/common/cancelable_task_tracker.h" 29 #include "chrome/common/chrome_constants.h" 30 #include "chrome/common/chrome_paths.h" 31 #include "chrome/common/chrome_switches.h" 32 #include "chrome/test/base/testing_profile.h" 33 #include "chrome/tools/profiles/thumbnail-inl.h" 34 #include "content/public/test/test_browser_thread.h" 35 #include "content/public/test/test_utils.h" 36 #include "grit/chromium_strings.h" 37 #include "grit/generated_resources.h" 38 #include "grit/locale_settings.h" 39 #include "testing/gtest/include/gtest/gtest.h" 40 #include "third_party/skia/include/core/SkBitmap.h" 41 #include "ui/base/l10n/l10n_util.h" 42 #include "ui/gfx/codec/jpeg_codec.h" 43 #include "url/gurl.h" 44 45 using content::BrowserThread; 46 47 namespace history { 48 49 namespace { 50 51 // Used by WaitForHistory, see it for details. 52 class WaitForHistoryTask : public HistoryDBTask { 53 public: 54 WaitForHistoryTask() {} 55 56 virtual bool RunOnDBThread(HistoryBackend* backend, 57 HistoryDatabase* db) OVERRIDE { 58 return true; 59 } 60 61 virtual void DoneRunOnMainThread() OVERRIDE { 62 base::MessageLoop::current()->Quit(); 63 } 64 65 private: 66 virtual ~WaitForHistoryTask() {} 67 68 DISALLOW_COPY_AND_ASSIGN(WaitForHistoryTask); 69 }; 70 71 // Used for querying top sites. Either runs sequentially, or runs a nested 72 // nested message loop until the response is complete. The later is used when 73 // TopSites is queried before it finishes loading. 74 class TopSitesQuerier { 75 public: 76 TopSitesQuerier() 77 : weak_ptr_factory_(this), 78 number_of_callbacks_(0), 79 waiting_(false) {} 80 81 // Queries top sites. If |wait| is true a nested message loop is run until the 82 // callback is notified. 83 void QueryTopSites(TopSitesLikelyImpl* top_sites, bool wait) { 84 int start_number_of_callbacks = number_of_callbacks_; 85 top_sites->GetMostVisitedURLs( 86 base::Bind(&TopSitesQuerier::OnTopSitesAvailable, 87 weak_ptr_factory_.GetWeakPtr())); 88 if (wait && start_number_of_callbacks == number_of_callbacks_) { 89 waiting_ = true; 90 base::MessageLoop::current()->Run(); 91 } 92 } 93 94 void CancelRequest() { 95 weak_ptr_factory_.InvalidateWeakPtrs(); 96 } 97 98 void set_urls(const MostVisitedURLList& urls) { urls_ = urls; } 99 const MostVisitedURLList& urls() const { return urls_; } 100 101 int number_of_callbacks() const { return number_of_callbacks_; } 102 103 private: 104 // Callback for TopSitesLikelyImpl::GetMostVisitedURLs. 105 void OnTopSitesAvailable(const history::MostVisitedURLList& data) { 106 urls_ = data; 107 number_of_callbacks_++; 108 if (waiting_) { 109 base::MessageLoop::current()->Quit(); 110 waiting_ = false; 111 } 112 } 113 114 base::WeakPtrFactory<TopSitesQuerier> weak_ptr_factory_; 115 MostVisitedURLList urls_; 116 int number_of_callbacks_; 117 bool waiting_; 118 119 DISALLOW_COPY_AND_ASSIGN(TopSitesQuerier); 120 }; 121 122 // Extracts the data from |t1| into a SkBitmap. This is intended for usage of 123 // thumbnail data, which is stored as jpgs. 124 SkBitmap ExtractThumbnail(const base::RefCountedMemory& t1) { 125 scoped_ptr<SkBitmap> image(gfx::JPEGCodec::Decode(t1.front(), 126 t1.size())); 127 return image.get() ? *image : SkBitmap(); 128 } 129 130 // Returns true if t1 and t2 contain the same data. 131 bool ThumbnailsAreEqual(base::RefCountedMemory* t1, 132 base::RefCountedMemory* t2) { 133 if (!t1 || !t2) 134 return false; 135 if (t1->size() != t2->size()) 136 return false; 137 return !memcmp(t1->front(), t2->front(), t1->size()); 138 } 139 140 } // namespace 141 142 class TopSitesLikelyImplTest : public HistoryUnitTestBase { 143 public: 144 TopSitesLikelyImplTest() 145 : ui_thread_(BrowserThread::UI, &message_loop_), 146 db_thread_(BrowserThread::DB, &message_loop_) { 147 } 148 149 virtual void SetUp() { 150 profile_.reset(new TestingProfile); 151 if (CreateHistoryAndTopSites()) { 152 ASSERT_TRUE(profile_->CreateHistoryService(false, false)); 153 profile_->CreateTopSites(); 154 profile_->BlockUntilTopSitesLoaded(); 155 } 156 } 157 158 virtual void TearDown() { 159 profile_.reset(); 160 } 161 162 // Returns true if history and top sites should be created in SetUp. 163 virtual bool CreateHistoryAndTopSites() { 164 return true; 165 } 166 167 // Gets the thumbnail for |url| from TopSites. 168 SkBitmap GetThumbnail(const GURL& url) { 169 scoped_refptr<base::RefCountedMemory> data; 170 return top_sites()->GetPageThumbnail(url, &data) ? 171 ExtractThumbnail(*data.get()) : SkBitmap(); 172 } 173 174 // Creates a bitmap of the specified color. Caller takes ownership. 175 gfx::Image CreateBitmap(SkColor color) { 176 SkBitmap thumbnail; 177 thumbnail.setConfig(SkBitmap::kARGB_8888_Config, 4, 4); 178 thumbnail.allocPixels(); 179 thumbnail.eraseColor(color); 180 return gfx::Image::CreateFrom1xBitmap(thumbnail); // adds ref. 181 } 182 183 // Forces top sites to load top sites from history, then recreates top sites. 184 // Recreating top sites makes sure the changes from history are saved and 185 // loaded from the db. 186 void RefreshTopSitesAndRecreate() { 187 StartQueryForMostVisited(); 188 WaitForHistory(); 189 RecreateTopSitesAndBlock(); 190 } 191 192 // Blocks the caller until history processes a task. This is useful if you 193 // need to wait until you know history has processed a task. 194 void WaitForHistory() { 195 history_service()->ScheduleDBTask(new WaitForHistoryTask(), &consumer_); 196 base::MessageLoop::current()->Run(); 197 } 198 199 // Waits for top sites to finish processing a task. This is useful if you need 200 // to wait until top sites finishes processing a task. 201 void WaitForTopSites() { 202 top_sites()->backend_->DoEmptyRequest( 203 base::Bind(&TopSitesLikelyImplTest::QuitCallback, 204 base::Unretained(this)), 205 &cancelable_task_tracker_); 206 base::MessageLoop::current()->Run(); 207 } 208 209 TopSitesLikelyImpl* top_sites() { 210 return static_cast<TopSitesLikelyImpl*>(profile_->GetTopSites()); 211 } 212 CancelableRequestConsumer* consumer() { return &consumer_; } 213 TestingProfile* profile() {return profile_.get();} 214 HistoryService* history_service() { 215 return HistoryServiceFactory::GetForProfile(profile_.get(), 216 Profile::EXPLICIT_ACCESS); 217 } 218 219 MostVisitedURLList GetPrepopulatePages() { 220 return top_sites()->GetPrepopulatePages(); 221 } 222 223 // Returns true if the TopSitesQuerier contains the prepopulate data starting 224 // at |start_index|. 225 void ContainsPrepopulatePages(const TopSitesQuerier& querier, 226 size_t start_index) { 227 MostVisitedURLList prepopulate_urls = GetPrepopulatePages(); 228 ASSERT_LE(start_index + prepopulate_urls.size(), querier.urls().size()); 229 for (size_t i = 0; i < prepopulate_urls.size(); ++i) { 230 EXPECT_EQ(prepopulate_urls[i].url.spec(), 231 querier.urls()[start_index + i].url.spec()) << " @ index " << 232 i; 233 } 234 } 235 236 // Used for callbacks from history. 237 void EmptyCallback() { 238 } 239 240 // Quit the current message loop when invoked. Useful when running a nested 241 // message loop. 242 void QuitCallback() { 243 base::MessageLoop::current()->Quit(); 244 } 245 246 // Adds a page to history. 247 void AddPageToHistory(const GURL& url) { 248 RedirectList redirects; 249 redirects.push_back(url); 250 history_service()->AddPage( 251 url, base::Time::Now(), static_cast<void*>(this), 0, GURL(), 252 redirects, content::PAGE_TRANSITION_TYPED, history::SOURCE_BROWSED, 253 false); 254 } 255 256 // Adds a page to history. 257 void AddPageToHistory(const GURL& url, const string16& title) { 258 RedirectList redirects; 259 redirects.push_back(url); 260 history_service()->AddPage( 261 url, base::Time::Now(), static_cast<void*>(this), 0, GURL(), 262 redirects, content::PAGE_TRANSITION_TYPED, history::SOURCE_BROWSED, 263 false); 264 history_service()->SetPageTitle(url, title); 265 } 266 267 // Adds a page to history. 268 void AddPageToHistory(const GURL& url, 269 const string16& title, 270 const history::RedirectList& redirects, 271 base::Time time) { 272 history_service()->AddPage( 273 url, time, static_cast<void*>(this), 0, GURL(), 274 redirects, content::PAGE_TRANSITION_TYPED, history::SOURCE_BROWSED, 275 false); 276 history_service()->SetPageTitle(url, title); 277 } 278 279 // Delets a url. 280 void DeleteURL(const GURL& url) { 281 history_service()->DeleteURL(url); 282 } 283 284 // Returns true if the thumbnail equals the specified bytes. 285 bool ThumbnailEqualsBytes(const gfx::Image& image, 286 base::RefCountedMemory* bytes) { 287 scoped_refptr<base::RefCountedBytes> encoded_image; 288 TopSitesLikelyImpl::EncodeBitmap(image, &encoded_image); 289 return ThumbnailsAreEqual(encoded_image.get(), bytes); 290 } 291 292 // Recreates top sites. This forces top sites to reread from the db. 293 void RecreateTopSitesAndBlock() { 294 // Recreate TopSites and wait for it to load. 295 profile()->CreateTopSites(); 296 // As history already loaded we have to fake this call. 297 profile()->BlockUntilTopSitesLoaded(); 298 } 299 300 // Wrappers that allow private TopSites functions to be called from the 301 // individual tests without making them all be friends. 302 GURL GetCanonicalURL(const GURL& url) { 303 return top_sites()->cache_->GetCanonicalURL(url); 304 } 305 306 void SetTopSites(const MostVisitedURLList& new_top_sites) { 307 top_sites()->SetTopSites(new_top_sites); 308 } 309 310 void StartQueryForMostVisited() { 311 top_sites()->StartQueryForMostVisited(); 312 } 313 314 void SetLastNumUrlsChanged(size_t value) { 315 top_sites()->last_num_urls_changed_ = value; 316 } 317 318 size_t last_num_urls_changed() { return top_sites()->last_num_urls_changed_; } 319 320 base::TimeDelta GetUpdateDelay() { 321 return top_sites()->GetUpdateDelay(); 322 } 323 324 bool IsTopSitesLoaded() { return top_sites()->loaded_; } 325 326 bool AddPrepopulatedPages(MostVisitedURLList* urls) { 327 return top_sites()->AddPrepopulatedPages(urls); 328 } 329 330 private: 331 base::MessageLoopForUI message_loop_; 332 content::TestBrowserThread ui_thread_; 333 content::TestBrowserThread db_thread_; 334 scoped_ptr<TestingProfile> profile_; 335 336 // To cancel HistoryService tasks. 337 CancelableRequestConsumer consumer_; 338 339 // To cancel TopSitesBackend tasks. 340 CancelableTaskTracker cancelable_task_tracker_; 341 342 DISALLOW_COPY_AND_ASSIGN(TopSitesLikelyImplTest); 343 }; // Class TopSitesLikelyImplTest 344 345 class TopSitesLikelyMigrationTest : public TopSitesLikelyImplTest { 346 public: 347 TopSitesLikelyMigrationTest() {} 348 349 virtual void SetUp() { 350 TopSitesLikelyImplTest::SetUp(); 351 352 base::FilePath data_path; 353 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_path)); 354 data_path = data_path.AppendASCII("top_sites"); 355 356 // Set up history and thumbnails as they would be before migration. 357 ASSERT_NO_FATAL_FAILURE(ExecuteSQLScript( 358 data_path.AppendASCII("history.19.sql"), 359 profile()->GetPath().Append(chrome::kHistoryFilename))); 360 ASSERT_NO_FATAL_FAILURE(ExecuteSQLScript( 361 data_path.AppendASCII("thumbnails.3.sql"), 362 profile()->GetPath().Append(chrome::kThumbnailsFilename))); 363 364 ASSERT_TRUE(profile()->CreateHistoryService(false, false)); 365 profile()->CreateTopSites(); 366 profile()->BlockUntilTopSitesLoaded(); 367 } 368 369 // Returns true if history and top sites should be created in SetUp. 370 virtual bool CreateHistoryAndTopSites() OVERRIDE { 371 return false; 372 } 373 374 protected: 375 // Assertions for the migration test. This is extracted into a standalone 376 // method so that it can be invoked twice. 377 void MigrationAssertions() { 378 TopSitesQuerier querier; 379 querier.QueryTopSites(top_sites(), false); 380 381 // We shouldn't have gotten a callback. 382 EXPECT_EQ(1, querier.number_of_callbacks()); 383 384 // The data we loaded should contain google and yahoo. 385 ASSERT_EQ(2u + GetPrepopulatePages().size(), querier.urls().size()); 386 EXPECT_EQ(GURL("http://google.com/"), querier.urls()[0].url); 387 EXPECT_EQ(GURL("http://yahoo.com/"), querier.urls()[1].url); 388 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier, 2)); 389 390 SkBitmap goog_thumbnail = GetThumbnail(GURL("http://google.com/")); 391 EXPECT_EQ(1, goog_thumbnail.width()); 392 393 SkBitmap yahoo_thumbnail = GetThumbnail(GURL("http://yahoo.com/")); 394 EXPECT_EQ(2, yahoo_thumbnail.width()); 395 396 // Favicon assertions are handled in ThumbnailDatabase. 397 } 398 399 private: 400 DISALLOW_COPY_AND_ASSIGN(TopSitesLikelyMigrationTest); 401 }; 402 403 // Helper function for appending a URL to a vector of "most visited" URLs, 404 // using the default values for everything but the URL. 405 static void AppendMostVisitedURL(std::vector<MostVisitedURL>* list, 406 const GURL& url) { 407 MostVisitedURL mv; 408 mv.url = url; 409 mv.redirects.push_back(url); 410 list->push_back(mv); 411 } 412 413 // Same as AppendMostVisitedURL except that it adds a redirect from the first 414 // URL to the second. 415 static void AppendMostVisitedURLWithRedirect( 416 std::vector<MostVisitedURL>* list, 417 const GURL& redirect_source, const GURL& redirect_dest) { 418 MostVisitedURL mv; 419 mv.url = redirect_dest; 420 mv.redirects.push_back(redirect_source); 421 mv.redirects.push_back(redirect_dest); 422 list->push_back(mv); 423 } 424 425 // Tests GetCanonicalURL. 426 TEST_F(TopSitesLikelyImplTest, GetCanonicalURL) { 427 // Have two chains: 428 // google.com -> www.google.com 429 // news.google.com (no redirects) 430 GURL news("http://news.google.com/"); 431 GURL source("http://google.com/"); 432 GURL dest("http://www.google.com/"); 433 434 std::vector<MostVisitedURL> most_visited; 435 AppendMostVisitedURLWithRedirect(&most_visited, source, dest); 436 AppendMostVisitedURL(&most_visited, news); 437 SetTopSites(most_visited); 438 439 // Random URLs not in the database are returned unchanged. 440 GURL result = GetCanonicalURL(GURL("http://fark.com/")); 441 EXPECT_EQ(GURL("http://fark.com/"), result); 442 443 // Easy case, there are no redirects and the exact URL is stored. 444 result = GetCanonicalURL(news); 445 EXPECT_EQ(news, result); 446 447 // The URL in question is the source URL in a redirect list. 448 result = GetCanonicalURL(source); 449 EXPECT_EQ(dest, result); 450 451 // The URL in question is the destination of a redirect. 452 result = GetCanonicalURL(dest); 453 EXPECT_EQ(dest, result); 454 } 455 456 // Tests DiffMostVisited. 457 TEST_F(TopSitesLikelyImplTest, DiffMostVisited) { 458 GURL stays_the_same("http://staysthesame/"); 459 GURL gets_added_1("http://getsadded1/"); 460 GURL gets_added_2("http://getsadded2/"); 461 GURL gets_deleted_1("http://getsdeleted2/"); 462 GURL gets_moved_1("http://getsmoved1/"); 463 464 std::vector<MostVisitedURL> old_list; 465 AppendMostVisitedURL(&old_list, stays_the_same); // 0 (unchanged) 466 AppendMostVisitedURL(&old_list, gets_deleted_1); // 1 (deleted) 467 AppendMostVisitedURL(&old_list, gets_moved_1); // 2 (moved to 3) 468 469 std::vector<MostVisitedURL> new_list; 470 AppendMostVisitedURL(&new_list, stays_the_same); // 0 (unchanged) 471 AppendMostVisitedURL(&new_list, gets_added_1); // 1 (added) 472 AppendMostVisitedURL(&new_list, gets_added_2); // 2 (added) 473 AppendMostVisitedURL(&new_list, gets_moved_1); // 3 (moved from 2) 474 475 history::TopSitesDelta delta; 476 history::TopSitesLikelyImpl::DiffMostVisited(old_list, new_list, &delta); 477 478 ASSERT_EQ(2u, delta.added.size()); 479 ASSERT_TRUE(gets_added_1 == delta.added[0].url.url); 480 ASSERT_EQ(1, delta.added[0].rank); 481 ASSERT_TRUE(gets_added_2 == delta.added[1].url.url); 482 ASSERT_EQ(2, delta.added[1].rank); 483 484 ASSERT_EQ(1u, delta.deleted.size()); 485 ASSERT_TRUE(gets_deleted_1 == delta.deleted[0].url); 486 487 ASSERT_EQ(1u, delta.moved.size()); 488 ASSERT_TRUE(gets_moved_1 == delta.moved[0].url.url); 489 ASSERT_EQ(3, delta.moved[0].rank); 490 } 491 492 // Tests SetPageThumbnail. 493 TEST_F(TopSitesLikelyImplTest, SetPageThumbnail) { 494 GURL url1a("http://google.com/"); 495 GURL url1b("http://www.google.com/"); 496 GURL url2("http://images.google.com/"); 497 GURL invalid_url("chrome://favicon/http://google.com/"); 498 499 std::vector<MostVisitedURL> list; 500 AppendMostVisitedURL(&list, url2); 501 502 MostVisitedURL mv; 503 mv.url = url1b; 504 mv.redirects.push_back(url1a); 505 mv.redirects.push_back(url1b); 506 list.push_back(mv); 507 508 // Save our most visited data containing that one site. 509 SetTopSites(list); 510 511 // Create a dummy thumbnail. 512 gfx::Image thumbnail(CreateBitmap(SK_ColorWHITE)); 513 514 base::Time now = base::Time::Now(); 515 ThumbnailScore low_score(1.0, true, true, now); 516 ThumbnailScore medium_score(0.5, true, true, now); 517 ThumbnailScore high_score(0.0, true, true, now); 518 519 // Setting the thumbnail for invalid pages should fail. 520 EXPECT_FALSE(top_sites()->SetPageThumbnail(invalid_url, 521 thumbnail, medium_score)); 522 523 // Setting the thumbnail for url2 should succeed, lower scores shouldn't 524 // replace it, higher scores should. 525 EXPECT_TRUE(top_sites()->SetPageThumbnail(url2, thumbnail, medium_score)); 526 EXPECT_FALSE(top_sites()->SetPageThumbnail(url2, thumbnail, low_score)); 527 EXPECT_TRUE(top_sites()->SetPageThumbnail(url2, thumbnail, high_score)); 528 529 // Set on the redirect source should succeed. It should be replacable by 530 // the same score on the redirect destination, which in turn should not 531 // be replaced by the source again. 532 EXPECT_TRUE(top_sites()->SetPageThumbnail(url1a, thumbnail, medium_score)); 533 EXPECT_TRUE(top_sites()->SetPageThumbnail(url1b, thumbnail, medium_score)); 534 EXPECT_FALSE(top_sites()->SetPageThumbnail(url1a, thumbnail, medium_score)); 535 } 536 537 // Makes sure a thumbnail is correctly removed when the page is removed. 538 TEST_F(TopSitesLikelyImplTest, ThumbnailRemoved) { 539 GURL url("http://google.com/"); 540 541 // Configure top sites with 'google.com'. 542 std::vector<MostVisitedURL> list; 543 AppendMostVisitedURL(&list, url); 544 SetTopSites(list); 545 546 // Create a dummy thumbnail. 547 gfx::Image thumbnail(CreateBitmap(SK_ColorRED)); 548 549 base::Time now = base::Time::Now(); 550 ThumbnailScore low_score(1.0, true, true, now); 551 ThumbnailScore medium_score(0.5, true, true, now); 552 ThumbnailScore high_score(0.0, true, true, now); 553 554 // Set the thumbnail. 555 EXPECT_TRUE(top_sites()->SetPageThumbnail(url, thumbnail, medium_score)); 556 557 // Make sure the thumbnail was actually set. 558 scoped_refptr<base::RefCountedMemory> result; 559 EXPECT_TRUE(top_sites()->GetPageThumbnail(url, &result)); 560 EXPECT_TRUE(ThumbnailEqualsBytes(thumbnail, result.get())); 561 562 // Reset the thumbnails and make sure we don't get it back. 563 SetTopSites(MostVisitedURLList()); 564 RefreshTopSitesAndRecreate(); 565 EXPECT_FALSE(top_sites()->GetPageThumbnail(url, &result)); 566 } 567 568 // Tests GetPageThumbnail. 569 TEST_F(TopSitesLikelyImplTest, GetPageThumbnail) { 570 MostVisitedURLList url_list; 571 MostVisitedURL url1; 572 url1.url = GURL("http://asdf.com"); 573 url1.redirects.push_back(url1.url); 574 url_list.push_back(url1); 575 576 MostVisitedURL url2; 577 url2.url = GURL("http://gmail.com"); 578 url2.redirects.push_back(url2.url); 579 url2.redirects.push_back(GURL("http://mail.google.com")); 580 url_list.push_back(url2); 581 582 SetTopSites(url_list); 583 584 // Create a dummy thumbnail. 585 gfx::Image thumbnail(CreateBitmap(SK_ColorWHITE)); 586 ThumbnailScore score(0.5, true, true, base::Time::Now()); 587 588 scoped_refptr<base::RefCountedMemory> result; 589 EXPECT_TRUE(top_sites()->SetPageThumbnail(url1.url, thumbnail, score)); 590 EXPECT_TRUE(top_sites()->GetPageThumbnail(url1.url, &result)); 591 592 EXPECT_TRUE(top_sites()->SetPageThumbnail(GURL("http://gmail.com"), 593 thumbnail, score)); 594 EXPECT_TRUE(top_sites()->GetPageThumbnail(GURL("http://gmail.com"), 595 &result)); 596 // Get a thumbnail via a redirect. 597 EXPECT_TRUE(top_sites()->GetPageThumbnail(GURL("http://mail.google.com"), 598 &result)); 599 600 EXPECT_TRUE(top_sites()->SetPageThumbnail(GURL("http://mail.google.com"), 601 thumbnail, score)); 602 EXPECT_TRUE(top_sites()->GetPageThumbnail(url2.url, &result)); 603 604 EXPECT_TRUE(ThumbnailEqualsBytes(thumbnail, result.get())); 605 } 606 607 // Tests GetMostVisitedURLs. 608 TEST_F(TopSitesLikelyImplTest, GetMostVisited) { 609 GURL news("http://news.google.com/"); 610 GURL google("http://google.com/"); 611 612 AddPageToHistory(news); 613 AddPageToHistory(google); 614 615 StartQueryForMostVisited(); 616 WaitForHistory(); 617 618 TopSitesQuerier querier; 619 querier.QueryTopSites(top_sites(), false); 620 621 ASSERT_EQ(1, querier.number_of_callbacks()); 622 623 // 2 extra prepopulated URLs. 624 ASSERT_EQ(2u + GetPrepopulatePages().size(), querier.urls().size()); 625 EXPECT_EQ(news, querier.urls()[0].url); 626 EXPECT_EQ(google, querier.urls()[1].url); 627 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier, 2)); 628 } 629 630 // Makes sure changes done to top sites get mirrored to the db. 631 TEST_F(TopSitesLikelyImplTest, SaveToDB) { 632 MostVisitedURL url; 633 GURL asdf_url("http://asdf.com"); 634 string16 asdf_title(ASCIIToUTF16("ASDF")); 635 GURL google_url("http://google.com"); 636 string16 google_title(ASCIIToUTF16("Google")); 637 GURL news_url("http://news.google.com"); 638 string16 news_title(ASCIIToUTF16("Google News")); 639 640 // Add asdf_url to history. 641 AddPageToHistory(asdf_url, asdf_title); 642 643 // Make TopSites reread from the db. 644 StartQueryForMostVisited(); 645 WaitForHistory(); 646 647 // Add a thumbnail. 648 gfx::Image tmp_bitmap(CreateBitmap(SK_ColorBLUE)); 649 ASSERT_TRUE(top_sites()->SetPageThumbnail(asdf_url, tmp_bitmap, 650 ThumbnailScore())); 651 652 RecreateTopSitesAndBlock(); 653 654 { 655 TopSitesQuerier querier; 656 querier.QueryTopSites(top_sites(), false); 657 ASSERT_EQ(1u + GetPrepopulatePages().size(), querier.urls().size()); 658 EXPECT_EQ(asdf_url, querier.urls()[0].url); 659 EXPECT_EQ(asdf_title, querier.urls()[0].title); 660 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier, 1)); 661 662 scoped_refptr<base::RefCountedMemory> read_data; 663 EXPECT_TRUE(top_sites()->GetPageThumbnail(asdf_url, &read_data)); 664 EXPECT_TRUE(ThumbnailEqualsBytes(tmp_bitmap, read_data.get())); 665 } 666 667 MostVisitedURL url2; 668 url2.url = google_url; 669 url2.title = google_title; 670 url2.redirects.push_back(url2.url); 671 672 AddPageToHistory(url2.url, url2.title); 673 674 // Add new thumbnail at rank 0 and shift the other result to 1. 675 ASSERT_TRUE(top_sites()->SetPageThumbnail(google_url, 676 tmp_bitmap, 677 ThumbnailScore())); 678 679 // Make TopSites reread from the db. 680 RefreshTopSitesAndRecreate(); 681 682 { 683 TopSitesQuerier querier; 684 querier.QueryTopSites(top_sites(), false); 685 ASSERT_EQ(2u + GetPrepopulatePages().size(), querier.urls().size()); 686 EXPECT_EQ(asdf_url, querier.urls()[0].url); 687 EXPECT_EQ(asdf_title, querier.urls()[0].title); 688 EXPECT_EQ(google_url, querier.urls()[1].url); 689 EXPECT_EQ(google_title, querier.urls()[1].title); 690 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier, 2)); 691 } 692 } 693 694 // More permutations of saving to db. 695 TEST_F(TopSitesLikelyImplTest, RealDatabase) { 696 MostVisitedURL url; 697 GURL asdf_url("http://asdf.com"); 698 string16 asdf_title(ASCIIToUTF16("ASDF")); 699 GURL google1_url("http://google.com"); 700 GURL google2_url("http://google.com/redirect"); 701 GURL google3_url("http://www.google.com"); 702 string16 google_title(ASCIIToUTF16("Google")); 703 GURL news_url("http://news.google.com"); 704 string16 news_title(ASCIIToUTF16("Google News")); 705 706 url.url = asdf_url; 707 url.title = asdf_title; 708 url.redirects.push_back(url.url); 709 gfx::Image asdf_thumbnail(CreateBitmap(SK_ColorRED)); 710 ASSERT_TRUE(top_sites()->SetPageThumbnail( 711 asdf_url, asdf_thumbnail, ThumbnailScore())); 712 713 base::Time add_time(base::Time::Now()); 714 AddPageToHistory(url.url, url.title, url.redirects, add_time); 715 716 RefreshTopSitesAndRecreate(); 717 718 { 719 TopSitesQuerier querier; 720 querier.QueryTopSites(top_sites(), false); 721 722 ASSERT_EQ(1u + GetPrepopulatePages().size(), querier.urls().size()); 723 EXPECT_EQ(asdf_url, querier.urls()[0].url); 724 EXPECT_EQ(asdf_title, querier.urls()[0].title); 725 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier, 1)); 726 727 scoped_refptr<base::RefCountedMemory> read_data; 728 EXPECT_TRUE(top_sites()->GetPageThumbnail(asdf_url, &read_data)); 729 EXPECT_TRUE(ThumbnailEqualsBytes(asdf_thumbnail, read_data.get())); 730 } 731 732 MostVisitedURL url2; 733 url2.url = google3_url; 734 url2.title = google_title; 735 url2.redirects.push_back(google1_url); 736 url2.redirects.push_back(google2_url); 737 url2.redirects.push_back(google3_url); 738 739 AddPageToHistory(google3_url, url2.title, url2.redirects, 740 add_time - base::TimeDelta::FromMinutes(1)); 741 // Add google twice so that it becomes the first visited site. 742 AddPageToHistory(google3_url, url2.title, url2.redirects, 743 add_time - base::TimeDelta::FromMinutes(2)); 744 745 gfx::Image google_thumbnail(CreateBitmap(SK_ColorBLUE)); 746 ASSERT_TRUE(top_sites()->SetPageThumbnail( 747 url2.url, google_thumbnail, ThumbnailScore())); 748 749 RefreshTopSitesAndRecreate(); 750 751 { 752 scoped_refptr<base::RefCountedMemory> read_data; 753 TopSitesQuerier querier; 754 querier.QueryTopSites(top_sites(), false); 755 756 ASSERT_EQ(2u + GetPrepopulatePages().size(), querier.urls().size()); 757 EXPECT_EQ(google1_url, querier.urls()[0].url); 758 EXPECT_EQ(google_title, querier.urls()[0].title); 759 ASSERT_EQ(3u, querier.urls()[0].redirects.size()); 760 EXPECT_TRUE(top_sites()->GetPageThumbnail(google3_url, &read_data)); 761 EXPECT_TRUE(ThumbnailEqualsBytes(google_thumbnail, read_data.get())); 762 763 EXPECT_EQ(asdf_url, querier.urls()[1].url); 764 EXPECT_EQ(asdf_title, querier.urls()[1].title); 765 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier, 2)); 766 } 767 768 gfx::Image weewar_bitmap(CreateBitmap(SK_ColorYELLOW)); 769 770 base::Time thumbnail_time(base::Time::Now()); 771 ThumbnailScore low_score(1.0, true, true, thumbnail_time); 772 ThumbnailScore medium_score(0.5, true, true, thumbnail_time); 773 ThumbnailScore high_score(0.0, true, true, thumbnail_time); 774 775 // 1. Set to weewar. (Writes the thumbnail to the DB.) 776 EXPECT_TRUE(top_sites()->SetPageThumbnail(google3_url, 777 weewar_bitmap, 778 medium_score)); 779 RefreshTopSitesAndRecreate(); 780 { 781 scoped_refptr<base::RefCountedMemory> read_data; 782 EXPECT_TRUE(top_sites()->GetPageThumbnail(google3_url, &read_data)); 783 EXPECT_TRUE(ThumbnailEqualsBytes(weewar_bitmap, read_data.get())); 784 } 785 786 gfx::Image green_bitmap(CreateBitmap(SK_ColorGREEN)); 787 788 // 2. Set to google - low score. 789 EXPECT_FALSE(top_sites()->SetPageThumbnail(google3_url, 790 green_bitmap, 791 low_score)); 792 793 // 3. Set to google - high score. 794 EXPECT_TRUE(top_sites()->SetPageThumbnail(google1_url, 795 green_bitmap, 796 high_score)); 797 798 // Check that the thumbnail was updated. 799 RefreshTopSitesAndRecreate(); 800 { 801 scoped_refptr<base::RefCountedMemory> read_data; 802 EXPECT_TRUE(top_sites()->GetPageThumbnail(google3_url, &read_data)); 803 EXPECT_FALSE(ThumbnailEqualsBytes(weewar_bitmap, read_data.get())); 804 EXPECT_TRUE(ThumbnailEqualsBytes(green_bitmap, read_data.get())); 805 } 806 } 807 808 TEST_F(TopSitesLikelyImplTest, DeleteNotifications) { 809 GURL google1_url("http://google.com"); 810 GURL google2_url("http://google.com/redirect"); 811 GURL google3_url("http://www.google.com"); 812 string16 google_title(ASCIIToUTF16("Google")); 813 GURL news_url("http://news.google.com"); 814 string16 news_title(ASCIIToUTF16("Google News")); 815 816 AddPageToHistory(google1_url, google_title); 817 AddPageToHistory(news_url, news_title); 818 819 RefreshTopSitesAndRecreate(); 820 821 { 822 TopSitesQuerier querier; 823 querier.QueryTopSites(top_sites(), false); 824 825 ASSERT_EQ(GetPrepopulatePages().size() + 2, querier.urls().size()); 826 } 827 828 DeleteURL(news_url); 829 830 // Wait for history to process the deletion. 831 WaitForHistory(); 832 833 { 834 TopSitesQuerier querier; 835 querier.QueryTopSites(top_sites(), false); 836 837 ASSERT_EQ(1u + GetPrepopulatePages().size(), querier.urls().size()); 838 EXPECT_EQ(google_title, querier.urls()[0].title); 839 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier, 1)); 840 } 841 842 // Now reload. This verifies topsites actually wrote the deletion to disk. 843 RefreshTopSitesAndRecreate(); 844 845 { 846 TopSitesQuerier querier; 847 querier.QueryTopSites(top_sites(), false); 848 849 ASSERT_EQ(1u + GetPrepopulatePages().size(), querier.urls().size()); 850 EXPECT_EQ(google_title, querier.urls()[0].title); 851 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier, 1)); 852 } 853 854 DeleteURL(google1_url); 855 856 // Wait for history to process the deletion. 857 WaitForHistory(); 858 859 { 860 TopSitesQuerier querier; 861 querier.QueryTopSites(top_sites(), false); 862 863 ASSERT_EQ(GetPrepopulatePages().size(), querier.urls().size()); 864 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier, 0)); 865 } 866 867 // Now reload. This verifies topsites actually wrote the deletion to disk. 868 RefreshTopSitesAndRecreate(); 869 870 { 871 TopSitesQuerier querier; 872 querier.QueryTopSites(top_sites(), false); 873 874 ASSERT_EQ(GetPrepopulatePages().size(), querier.urls().size()); 875 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier, 0)); 876 } 877 } 878 879 // Makes sure GetUpdateDelay is updated appropriately. 880 TEST_F(TopSitesLikelyImplTest, GetUpdateDelay) { 881 SetLastNumUrlsChanged(0); 882 EXPECT_EQ(30, GetUpdateDelay().InSeconds()); 883 884 MostVisitedURLList url_list; 885 url_list.resize(20); 886 GURL tmp_url(GURL("http://x")); 887 for (size_t i = 0; i < url_list.size(); ++i) { 888 url_list[i].url = tmp_url; 889 url_list[i].redirects.push_back(tmp_url); 890 } 891 SetTopSites(url_list); 892 EXPECT_EQ(20u, last_num_urls_changed()); 893 SetLastNumUrlsChanged(0); 894 EXPECT_EQ(60, GetUpdateDelay().InMinutes()); 895 896 SetLastNumUrlsChanged(3); 897 EXPECT_EQ(52, GetUpdateDelay().InMinutes()); 898 899 SetLastNumUrlsChanged(20); 900 EXPECT_EQ(1, GetUpdateDelay().InMinutes()); 901 } 902 903 TEST_F(TopSitesLikelyMigrationTest, Migrate) { 904 EXPECT_TRUE(IsTopSitesLoaded()); 905 906 // Make sure the data was migrated to top sites. 907 ASSERT_NO_FATAL_FAILURE(MigrationAssertions()); 908 909 // We need to wait for top sites and history to finish processing requests. 910 WaitForTopSites(); 911 WaitForHistory(); 912 913 // Make sure there is no longer a Thumbnails file on disk. 914 ASSERT_FALSE(base::PathExists( 915 profile()->GetPath().Append(chrome::kThumbnailsFilename))); 916 917 // Recreate top sites and make sure everything is still there. 918 ASSERT_TRUE(profile()->CreateHistoryService(false, false)); 919 RecreateTopSitesAndBlock(); 920 921 ASSERT_NO_FATAL_FAILURE(MigrationAssertions()); 922 } 923 924 // Verifies that callbacks are notified correctly if requested before top sites 925 // has loaded. 926 TEST_F(TopSitesLikelyImplTest, NotifyCallbacksWhenLoaded) { 927 // Recreate top sites. It won't be loaded now. 928 profile()->CreateTopSites(); 929 930 EXPECT_FALSE(IsTopSitesLoaded()); 931 932 TopSitesQuerier querier1; 933 TopSitesQuerier querier2; 934 TopSitesQuerier querier3; 935 936 // Starts the queries. 937 querier1.QueryTopSites(top_sites(), false); 938 querier2.QueryTopSites(top_sites(), false); 939 querier3.QueryTopSites(top_sites(), false); 940 941 // We shouldn't have gotten a callback. 942 EXPECT_EQ(0, querier1.number_of_callbacks()); 943 EXPECT_EQ(0, querier2.number_of_callbacks()); 944 EXPECT_EQ(0, querier3.number_of_callbacks()); 945 946 // Wait for loading to complete. 947 profile()->BlockUntilTopSitesLoaded(); 948 949 // Now we should have gotten the callbacks. 950 EXPECT_EQ(1, querier1.number_of_callbacks()); 951 EXPECT_EQ(GetPrepopulatePages().size(), querier1.urls().size()); 952 EXPECT_EQ(1, querier2.number_of_callbacks()); 953 EXPECT_EQ(GetPrepopulatePages().size(), querier2.urls().size()); 954 EXPECT_EQ(1, querier3.number_of_callbacks()); 955 EXPECT_EQ(GetPrepopulatePages().size(), querier3.urls().size()); 956 957 // Reset the top sites. 958 MostVisitedURLList pages; 959 MostVisitedURL url; 960 url.url = GURL("http://1.com/"); 961 url.redirects.push_back(url.url); 962 pages.push_back(url); 963 url.url = GURL("http://2.com/"); 964 url.redirects.push_back(url.url); 965 pages.push_back(url); 966 SetTopSites(pages); 967 968 // Recreate top sites. It won't be loaded now. 969 profile()->CreateTopSites(); 970 971 EXPECT_FALSE(IsTopSitesLoaded()); 972 973 TopSitesQuerier querier4; 974 975 // Query again. 976 querier4.QueryTopSites(top_sites(), false); 977 978 // We shouldn't have gotten a callback. 979 EXPECT_EQ(0, querier4.number_of_callbacks()); 980 981 // Wait for loading to complete. 982 profile()->BlockUntilTopSitesLoaded(); 983 984 // Now we should have gotten the callbacks. 985 EXPECT_EQ(1, querier4.number_of_callbacks()); 986 ASSERT_EQ(2u + GetPrepopulatePages().size(), querier4.urls().size()); 987 988 EXPECT_EQ("http://1.com/", querier4.urls()[0].url.spec()); 989 EXPECT_EQ("http://2.com/", querier4.urls()[1].url.spec()); 990 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier4, 2)); 991 992 // Reset the top sites again, this time don't reload. 993 url.url = GURL("http://3.com/"); 994 url.redirects.push_back(url.url); 995 pages.push_back(url); 996 SetTopSites(pages); 997 998 // Query again. 999 TopSitesQuerier querier5; 1000 querier5.QueryTopSites(top_sites(), true); 1001 1002 EXPECT_EQ(1, querier5.number_of_callbacks()); 1003 1004 ASSERT_EQ(3u + GetPrepopulatePages().size(), querier5.urls().size()); 1005 EXPECT_EQ("http://1.com/", querier5.urls()[0].url.spec()); 1006 EXPECT_EQ("http://2.com/", querier5.urls()[1].url.spec()); 1007 EXPECT_EQ("http://3.com/", querier5.urls()[2].url.spec()); 1008 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier5, 3)); 1009 } 1010 1011 // Makes sure canceled requests are not notified. 1012 TEST_F(TopSitesLikelyImplTest, CancelingRequestsForTopSites) { 1013 // Recreate top sites. It won't be loaded now. 1014 profile()->CreateTopSites(); 1015 1016 EXPECT_FALSE(IsTopSitesLoaded()); 1017 1018 TopSitesQuerier querier1; 1019 TopSitesQuerier querier2; 1020 1021 // Starts the queries. 1022 querier1.QueryTopSites(top_sites(), false); 1023 querier2.QueryTopSites(top_sites(), false); 1024 1025 // We shouldn't have gotten a callback. 1026 EXPECT_EQ(0, querier1.number_of_callbacks()); 1027 EXPECT_EQ(0, querier2.number_of_callbacks()); 1028 1029 querier2.CancelRequest(); 1030 1031 // Wait for loading to complete. 1032 profile()->BlockUntilTopSitesLoaded(); 1033 1034 // The first callback should succeed. 1035 EXPECT_EQ(1, querier1.number_of_callbacks()); 1036 EXPECT_EQ(GetPrepopulatePages().size(), querier1.urls().size()); 1037 1038 // And the canceled callback should not be notified. 1039 EXPECT_EQ(0, querier2.number_of_callbacks()); 1040 } 1041 1042 // Makes sure temporary thumbnails are copied over correctly. 1043 TEST_F(TopSitesLikelyImplTest, AddTemporaryThumbnail) { 1044 GURL unknown_url("http://news.google.com/"); 1045 GURL invalid_url("chrome://thumb/http://google.com/"); 1046 GURL url1a("http://google.com/"); 1047 GURL url1b("http://www.google.com/"); 1048 1049 // Create a dummy thumbnail. 1050 gfx::Image thumbnail(CreateBitmap(SK_ColorRED)); 1051 1052 ThumbnailScore medium_score(0.5, true, true, base::Time::Now()); 1053 1054 // Don't store thumbnails for Javascript URLs. 1055 EXPECT_FALSE(top_sites()->SetPageThumbnail(invalid_url, 1056 thumbnail, 1057 medium_score)); 1058 // Store thumbnails for unknown (but valid) URLs temporarily - calls 1059 // AddTemporaryThumbnail. 1060 EXPECT_TRUE(top_sites()->SetPageThumbnail(unknown_url, 1061 thumbnail, 1062 medium_score)); 1063 1064 // We shouldn't get the thumnail back though (the url isn't in to sites yet). 1065 scoped_refptr<base::RefCountedMemory> out; 1066 EXPECT_FALSE(top_sites()->GetPageThumbnail(unknown_url, &out)); 1067 // But we should be able to get the temporary page thumbnail score. 1068 ThumbnailScore out_score; 1069 EXPECT_TRUE(top_sites()->GetTemporaryPageThumbnailScore(unknown_url, 1070 &out_score)); 1071 EXPECT_TRUE(medium_score.Equals(out_score)); 1072 1073 std::vector<MostVisitedURL> list; 1074 1075 MostVisitedURL mv; 1076 mv.url = unknown_url; 1077 mv.redirects.push_back(mv.url); 1078 mv.redirects.push_back(url1a); 1079 mv.redirects.push_back(url1b); 1080 list.push_back(mv); 1081 1082 // Update URLs. This should result in using thumbnail. 1083 SetTopSites(list); 1084 1085 ASSERT_TRUE(top_sites()->GetPageThumbnail(unknown_url, &out)); 1086 EXPECT_TRUE(ThumbnailEqualsBytes(thumbnail, out.get())); 1087 } 1088 1089 // Tests variations of blacklisting. 1090 TEST_F(TopSitesLikelyImplTest, Blacklisting) { 1091 MostVisitedURLList pages; 1092 MostVisitedURL url, url1; 1093 url.url = GURL("http://bbc.com/"); 1094 url.redirects.push_back(url.url); 1095 pages.push_back(url); 1096 url1.url = GURL("http://google.com/"); 1097 url1.redirects.push_back(url1.url); 1098 pages.push_back(url1); 1099 1100 SetTopSites(pages); 1101 EXPECT_FALSE(top_sites()->IsBlacklisted(GURL("http://bbc.com/"))); 1102 1103 // Blacklist google.com. 1104 top_sites()->AddBlacklistedURL(GURL("http://google.com/")); 1105 1106 GURL prepopulate_url = GetPrepopulatePages()[0].url; 1107 1108 EXPECT_TRUE(top_sites()->HasBlacklistedItems()); 1109 EXPECT_TRUE(top_sites()->IsBlacklisted(GURL("http://google.com/"))); 1110 EXPECT_FALSE(top_sites()->IsBlacklisted(GURL("http://bbc.com/"))); 1111 EXPECT_FALSE(top_sites()->IsBlacklisted(prepopulate_url)); 1112 1113 // Make sure the blacklisted site isn't returned in the results. 1114 { 1115 TopSitesQuerier q; 1116 q.QueryTopSites(top_sites(), true); 1117 ASSERT_EQ(1u + GetPrepopulatePages().size(), q.urls().size()); 1118 EXPECT_EQ("http://bbc.com/", q.urls()[0].url.spec()); 1119 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(q, 1)); 1120 } 1121 1122 // Recreate top sites and make sure blacklisted url was correctly read. 1123 RecreateTopSitesAndBlock(); 1124 { 1125 TopSitesQuerier q; 1126 q.QueryTopSites(top_sites(), true); 1127 ASSERT_EQ(1u + GetPrepopulatePages().size(), q.urls().size()); 1128 EXPECT_EQ("http://bbc.com/", q.urls()[0].url.spec()); 1129 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(q, 1)); 1130 } 1131 1132 // Blacklist one of the prepopulate urls. 1133 top_sites()->AddBlacklistedURL(prepopulate_url); 1134 EXPECT_TRUE(top_sites()->HasBlacklistedItems()); 1135 1136 // Make sure the blacklisted prepopulate url isn't returned. 1137 { 1138 TopSitesQuerier q; 1139 q.QueryTopSites(top_sites(), true); 1140 ASSERT_EQ(1u + GetPrepopulatePages().size() - 1, q.urls().size()); 1141 EXPECT_EQ("http://bbc.com/", q.urls()[0].url.spec()); 1142 for (size_t i = 1; i < q.urls().size(); ++i) 1143 EXPECT_NE(prepopulate_url.spec(), q.urls()[i].url.spec()); 1144 } 1145 1146 // Mark google as no longer blacklisted. 1147 top_sites()->RemoveBlacklistedURL(GURL("http://google.com/")); 1148 EXPECT_TRUE(top_sites()->HasBlacklistedItems()); 1149 EXPECT_FALSE(top_sites()->IsBlacklisted(GURL("http://google.com/"))); 1150 1151 // Make sure google is returned now. 1152 { 1153 TopSitesQuerier q; 1154 q.QueryTopSites(top_sites(), true); 1155 ASSERT_EQ(2u + GetPrepopulatePages().size() - 1, q.urls().size()); 1156 EXPECT_EQ("http://bbc.com/", q.urls()[0].url.spec()); 1157 EXPECT_EQ("http://google.com/", q.urls()[1].url.spec()); 1158 // Android has only one prepopulated page which has been blacklisted, so 1159 // only 2 urls are returned. 1160 if (q.urls().size() > 2) 1161 EXPECT_NE(prepopulate_url.spec(), q.urls()[2].url.spec()); 1162 else 1163 EXPECT_EQ(1u, GetPrepopulatePages().size()); 1164 } 1165 1166 // Remove all blacklisted sites. 1167 top_sites()->ClearBlacklistedURLs(); 1168 EXPECT_FALSE(top_sites()->HasBlacklistedItems()); 1169 1170 { 1171 TopSitesQuerier q; 1172 q.QueryTopSites(top_sites(), true); 1173 ASSERT_EQ(2u + GetPrepopulatePages().size(), q.urls().size()); 1174 EXPECT_EQ("http://bbc.com/", q.urls()[0].url.spec()); 1175 EXPECT_EQ("http://google.com/", q.urls()[1].url.spec()); 1176 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(q, 2)); 1177 } 1178 } 1179 1180 // Makes sure prepopulated pages exist. 1181 TEST_F(TopSitesLikelyImplTest, AddPrepopulatedPages) { 1182 TopSitesQuerier q; 1183 q.QueryTopSites(top_sites(), true); 1184 EXPECT_EQ(GetPrepopulatePages().size(), q.urls().size()); 1185 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(q, 0)); 1186 1187 MostVisitedURLList pages = q.urls(); 1188 EXPECT_FALSE(AddPrepopulatedPages(&pages)); 1189 1190 EXPECT_EQ(GetPrepopulatePages().size(), pages.size()); 1191 q.set_urls(pages); 1192 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(q, 0)); 1193 } 1194 1195 // Makes sure creating top sites before history is created works. 1196 TEST_F(TopSitesLikelyImplTest, CreateTopSitesThenHistory) { 1197 profile()->DestroyTopSites(); 1198 profile()->DestroyHistoryService(); 1199 1200 // Remove the TopSites file. This forces TopSites to wait until history loads 1201 // before TopSites is considered loaded. 1202 sql::Connection::Delete( 1203 profile()->GetPath().Append(chrome::kTopSitesFilename)); 1204 1205 // Create TopSites, but not History. 1206 profile()->CreateTopSites(); 1207 WaitForTopSites(); 1208 EXPECT_FALSE(IsTopSitesLoaded()); 1209 1210 // Load history, which should make TopSites finish loading too. 1211 ASSERT_TRUE(profile()->CreateHistoryService(false, false)); 1212 profile()->BlockUntilTopSitesLoaded(); 1213 EXPECT_TRUE(IsTopSitesLoaded()); 1214 } 1215 1216 class TopSitesLikelyUnloadTest : public TopSitesLikelyImplTest { 1217 public: 1218 TopSitesLikelyUnloadTest() {} 1219 1220 virtual bool CreateHistoryAndTopSites() OVERRIDE { 1221 return false; 1222 } 1223 1224 private: 1225 DISALLOW_COPY_AND_ASSIGN(TopSitesLikelyUnloadTest); 1226 }; 1227 1228 // Makes sure if history is unloaded after topsites is loaded we don't hit any 1229 // assertions. 1230 TEST_F(TopSitesLikelyUnloadTest, UnloadHistoryTest) { 1231 ASSERT_TRUE(profile()->CreateHistoryService(false, false)); 1232 profile()->CreateTopSites(); 1233 profile()->BlockUntilTopSitesLoaded(); 1234 HistoryServiceFactory::GetForProfile( 1235 profile(), Profile::EXPLICIT_ACCESS)->UnloadBackend(); 1236 profile()->BlockUntilHistoryProcessesPendingRequests(); 1237 } 1238 1239 // Makes sure if history (with migration code) is unloaded after topsites is 1240 // loaded we don't hit any assertions. 1241 TEST_F(TopSitesLikelyUnloadTest, UnloadWithMigration) { 1242 // Set up history and thumbnails as they would be before migration. 1243 base::FilePath data_path; 1244 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_path)); 1245 data_path = data_path.AppendASCII("top_sites"); 1246 ASSERT_NO_FATAL_FAILURE(ExecuteSQLScript( 1247 data_path.AppendASCII("history.19.sql"), 1248 profile()->GetPath().Append(chrome::kHistoryFilename))); 1249 ASSERT_NO_FATAL_FAILURE(ExecuteSQLScript( 1250 data_path.AppendASCII("thumbnails.3.sql"), 1251 profile()->GetPath().Append(chrome::kThumbnailsFilename))); 1252 1253 // Create history and block until it's loaded. 1254 ASSERT_TRUE(profile()->CreateHistoryService(false, false)); 1255 profile()->BlockUntilHistoryProcessesPendingRequests(); 1256 1257 // Create top sites and unload history. 1258 content::WindowedNotificationObserver observer( 1259 chrome::NOTIFICATION_TOP_SITES_LOADED, 1260 content::Source<Profile>(profile())); 1261 profile()->CreateTopSites(); 1262 HistoryServiceFactory::GetForProfile( 1263 profile(), Profile::EXPLICIT_ACCESS)->UnloadBackend(); 1264 profile()->BlockUntilHistoryProcessesPendingRequests(); 1265 observer.Wait(); 1266 } 1267 1268 } // namespace history 1269