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