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