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/memory/weak_ptr.h" 7 #include "base/message_loop/message_loop.h" 8 #include "base/path_service.h" 9 #include "base/strings/utf_string_conversions.h" 10 #include "base/task/cancelable_task_tracker.h" 11 #include "chrome/browser/chrome_notification_types.h" 12 #include "chrome/browser/history/history_db_task.h" 13 #include "chrome/browser/history/history_notifications.h" 14 #include "chrome/browser/history/history_service_factory.h" 15 #include "chrome/browser/history/history_unittest_base.h" 16 #include "chrome/browser/history/top_sites.h" 17 #include "chrome/browser/history/top_sites_cache.h" 18 #include "chrome/browser/history/top_sites_impl.h" 19 #include "chrome/common/chrome_constants.h" 20 #include "chrome/common/chrome_paths.h" 21 #include "chrome/test/base/testing_profile.h" 22 #include "components/history/core/browser/history_types.h" 23 #include "content/public/browser/notification_service.h" 24 #include "content/public/test/test_browser_thread.h" 25 #include "testing/gtest/include/gtest/gtest.h" 26 #include "third_party/skia/include/core/SkBitmap.h" 27 #include "ui/gfx/codec/jpeg_codec.h" 28 #include "url/gurl.h" 29 30 using content::BrowserThread; 31 32 class TestTopSitesObserver : public history::TopSitesObserver { 33 public: 34 explicit TestTopSitesObserver(Profile* profile, history::TopSites* top_sites); 35 virtual ~TestTopSitesObserver(); 36 // TopSitesObserver: 37 virtual void TopSitesLoaded(history::TopSites* top_sites) OVERRIDE; 38 virtual void TopSitesChanged(history::TopSites* top_sites) OVERRIDE; 39 40 private: 41 Profile* profile_; 42 history::TopSites* top_sites_; 43 }; 44 45 TestTopSitesObserver::~TestTopSitesObserver() { 46 top_sites_->RemoveObserver(this); 47 } 48 49 TestTopSitesObserver::TestTopSitesObserver(Profile* profile, 50 history::TopSites* top_sites) 51 : profile_(profile), top_sites_(top_sites) { 52 DCHECK(top_sites_); 53 top_sites_->AddObserver(this); 54 } 55 56 void TestTopSitesObserver::TopSitesLoaded(history::TopSites* top_sites) { 57 content::NotificationService::current()->Notify( 58 chrome::NOTIFICATION_TOP_SITES_LOADED, 59 content::Source<Profile>(profile_), 60 content::Details<history::TopSites>(top_sites)); 61 } 62 63 void TestTopSitesObserver::TopSitesChanged(history::TopSites* top_sites) { 64 content::NotificationService::current()->Notify( 65 chrome::NOTIFICATION_TOP_SITES_CHANGED, 66 content::Source<Profile>(profile_), 67 content::NotificationService::NoDetails()); 68 } 69 70 namespace history { 71 72 namespace { 73 74 // Used by WaitForHistory, see it for details. 75 class WaitForHistoryTask : public HistoryDBTask { 76 public: 77 WaitForHistoryTask() {} 78 79 virtual bool RunOnDBThread(HistoryBackend* backend, 80 HistoryDatabase* db) OVERRIDE { 81 return true; 82 } 83 84 virtual void DoneRunOnMainThread() OVERRIDE { 85 base::MessageLoop::current()->Quit(); 86 } 87 88 private: 89 virtual ~WaitForHistoryTask() {} 90 91 DISALLOW_COPY_AND_ASSIGN(WaitForHistoryTask); 92 }; 93 94 // Used for querying top sites. Either runs sequentially, or runs a nested 95 // nested message loop until the response is complete. The later is used when 96 // TopSites is queried before it finishes loading. 97 class TopSitesQuerier { 98 public: 99 TopSitesQuerier() 100 : number_of_callbacks_(0), 101 waiting_(false), 102 weak_ptr_factory_(this) {} 103 104 // Queries top sites. If |wait| is true a nested message loop is run until the 105 // callback is notified. 106 void QueryTopSites(TopSitesImpl* top_sites, bool wait) { 107 QueryAllTopSites(top_sites, wait, false); 108 } 109 110 // Queries top sites, including potentially forced URLs if 111 // |include_forced_urls| is true. 112 void QueryAllTopSites(TopSitesImpl* top_sites, 113 bool wait, 114 bool include_forced_urls) { 115 int start_number_of_callbacks = number_of_callbacks_; 116 top_sites->GetMostVisitedURLs( 117 base::Bind(&TopSitesQuerier::OnTopSitesAvailable, 118 weak_ptr_factory_.GetWeakPtr()), 119 include_forced_urls); 120 if (wait && start_number_of_callbacks == number_of_callbacks_) { 121 waiting_ = true; 122 base::MessageLoop::current()->Run(); 123 } 124 } 125 126 void CancelRequest() { 127 weak_ptr_factory_.InvalidateWeakPtrs(); 128 } 129 130 void set_urls(const MostVisitedURLList& urls) { urls_ = urls; } 131 const MostVisitedURLList& urls() const { return urls_; } 132 133 int number_of_callbacks() const { return number_of_callbacks_; } 134 135 private: 136 // Callback for TopSitesImpl::GetMostVisitedURLs. 137 void OnTopSitesAvailable(const history::MostVisitedURLList& data) { 138 urls_ = data; 139 number_of_callbacks_++; 140 if (waiting_) { 141 base::MessageLoop::current()->Quit(); 142 waiting_ = false; 143 } 144 } 145 146 MostVisitedURLList urls_; 147 int number_of_callbacks_; 148 bool waiting_; 149 base::WeakPtrFactory<TopSitesQuerier> weak_ptr_factory_; 150 151 DISALLOW_COPY_AND_ASSIGN(TopSitesQuerier); 152 }; 153 154 // Extracts the data from |t1| into a SkBitmap. This is intended for usage of 155 // thumbnail data, which is stored as jpgs. 156 SkBitmap ExtractThumbnail(const base::RefCountedMemory& t1) { 157 scoped_ptr<SkBitmap> image(gfx::JPEGCodec::Decode(t1.front(), 158 t1.size())); 159 return image.get() ? *image : SkBitmap(); 160 } 161 162 // Returns true if t1 and t2 contain the same data. 163 bool ThumbnailsAreEqual(base::RefCountedMemory* t1, 164 base::RefCountedMemory* t2) { 165 if (!t1 || !t2) 166 return false; 167 if (t1->size() != t2->size()) 168 return false; 169 return !memcmp(t1->front(), t2->front(), t1->size()); 170 } 171 172 } // namespace 173 174 class TopSitesImplTest : public HistoryUnitTestBase { 175 public: 176 TopSitesImplTest() 177 : ui_thread_(BrowserThread::UI, &message_loop_), 178 db_thread_(BrowserThread::DB, &message_loop_) { 179 } 180 181 virtual void SetUp() { 182 profile_.reset(new TestingProfile); 183 if (CreateHistoryAndTopSites()) { 184 ASSERT_TRUE(profile_->CreateHistoryService(false, false)); 185 CreateTopSitesAndObserver(); 186 profile_->BlockUntilTopSitesLoaded(); 187 } 188 } 189 190 virtual void TearDown() { 191 top_sites_observer_.reset(); 192 profile_.reset(); 193 } 194 195 // Returns true if history and top sites should be created in SetUp. 196 virtual bool CreateHistoryAndTopSites() { 197 return true; 198 } 199 200 // Gets the thumbnail for |url| from TopSites. 201 SkBitmap GetThumbnail(const GURL& url) { 202 scoped_refptr<base::RefCountedMemory> data; 203 return top_sites()->GetPageThumbnail(url, false, &data) ? 204 ExtractThumbnail(*data.get()) : SkBitmap(); 205 } 206 207 // Creates a bitmap of the specified color. Caller takes ownership. 208 gfx::Image CreateBitmap(SkColor color) { 209 SkBitmap thumbnail; 210 thumbnail.allocN32Pixels(4, 4); 211 thumbnail.eraseColor(color); 212 return gfx::Image::CreateFrom1xBitmap(thumbnail); // adds ref. 213 } 214 215 // Forces top sites to load top sites from history, then recreates top sites. 216 // Recreating top sites makes sure the changes from history are saved and 217 // loaded from the db. 218 void RefreshTopSitesAndRecreate() { 219 StartQueryForMostVisited(); 220 WaitForHistory(); 221 RecreateTopSitesAndBlock(); 222 } 223 224 // Blocks the caller until history processes a task. This is useful if you 225 // need to wait until you know history has processed a task. 226 void WaitForHistory() { 227 history_service()->ScheduleDBTask( 228 scoped_ptr<history::HistoryDBTask>(new WaitForHistoryTask()), 229 &history_tracker_); 230 base::MessageLoop::current()->Run(); 231 } 232 233 // Waits for top sites to finish processing a task. This is useful if you need 234 // to wait until top sites finishes processing a task. 235 void WaitForTopSites() { 236 top_sites()->backend_->DoEmptyRequest( 237 base::Bind(&TopSitesImplTest::QuitCallback, base::Unretained(this)), 238 &top_sites_tracker_); 239 base::MessageLoop::current()->Run(); 240 } 241 242 TopSitesImpl* top_sites() { 243 return static_cast<TopSitesImpl*>(profile_->GetTopSites()); 244 } 245 TestingProfile* profile() {return profile_.get();} 246 HistoryService* history_service() { 247 return HistoryServiceFactory::GetForProfile(profile_.get(), 248 Profile::EXPLICIT_ACCESS); 249 } 250 251 MostVisitedURLList GetPrepopulatePages() { 252 return top_sites()->GetPrepopulatePages(); 253 } 254 255 // Returns true if the TopSitesQuerier contains the prepopulate data starting 256 // at |start_index|. 257 void ContainsPrepopulatePages(const TopSitesQuerier& querier, 258 size_t start_index) { 259 MostVisitedURLList prepopulate_urls = GetPrepopulatePages(); 260 ASSERT_LE(start_index + prepopulate_urls.size(), querier.urls().size()); 261 for (size_t i = 0; i < prepopulate_urls.size(); ++i) { 262 EXPECT_EQ(prepopulate_urls[i].url.spec(), 263 querier.urls()[start_index + i].url.spec()) << " @ index " << 264 i; 265 } 266 } 267 268 // Used for callbacks from history. 269 void EmptyCallback() { 270 } 271 272 // Quit the current message loop when invoked. Useful when running a nested 273 // message loop. 274 void QuitCallback() { 275 base::MessageLoop::current()->Quit(); 276 } 277 278 // Adds a page to history. 279 void AddPageToHistory(const GURL& url) { 280 RedirectList redirects; 281 redirects.push_back(url); 282 history_service()->AddPage( 283 url, base::Time::Now(), reinterpret_cast<ContextID>(1), 0, GURL(), 284 redirects, ui::PAGE_TRANSITION_TYPED, history::SOURCE_BROWSED, 285 false); 286 } 287 288 // Adds a page to history. 289 void AddPageToHistory(const GURL& url, const base::string16& title) { 290 RedirectList redirects; 291 redirects.push_back(url); 292 history_service()->AddPage( 293 url, base::Time::Now(), reinterpret_cast<ContextID>(1), 0, GURL(), 294 redirects, ui::PAGE_TRANSITION_TYPED, history::SOURCE_BROWSED, 295 false); 296 history_service()->SetPageTitle(url, title); 297 } 298 299 // Adds a page to history. 300 void AddPageToHistory(const GURL& url, 301 const base::string16& title, 302 const history::RedirectList& redirects, 303 base::Time time) { 304 history_service()->AddPage( 305 url, time, reinterpret_cast<ContextID>(1), 0, GURL(), 306 redirects, ui::PAGE_TRANSITION_TYPED, history::SOURCE_BROWSED, 307 false); 308 history_service()->SetPageTitle(url, title); 309 } 310 311 // Delets a url. 312 void DeleteURL(const GURL& url) { 313 history_service()->DeleteURL(url); 314 } 315 316 // Returns true if the thumbnail equals the specified bytes. 317 bool ThumbnailEqualsBytes(const gfx::Image& image, 318 base::RefCountedMemory* bytes) { 319 scoped_refptr<base::RefCountedBytes> encoded_image; 320 TopSitesImpl::EncodeBitmap(image, &encoded_image); 321 return ThumbnailsAreEqual(encoded_image.get(), bytes); 322 } 323 324 // Recreates top sites. This forces top sites to reread from the db. 325 void RecreateTopSitesAndBlock() { 326 // Recreate TopSites and wait for it to load. 327 CreateTopSitesAndObserver(); 328 // As history already loaded we have to fake this call. 329 profile()->BlockUntilTopSitesLoaded(); 330 } 331 332 // Wrappers that allow private TopSites functions to be called from the 333 // individual tests without making them all be friends. 334 GURL GetCanonicalURL(const GURL& url) { 335 return top_sites()->cache_->GetCanonicalURL(url); 336 } 337 338 void SetTopSites(const MostVisitedURLList& new_top_sites) { 339 top_sites()->SetTopSites(new_top_sites); 340 } 341 342 bool AddForcedURL(const GURL& url, base::Time time) { 343 return top_sites()->AddForcedURL(url, time); 344 } 345 346 void StartQueryForMostVisited() { 347 top_sites()->StartQueryForMostVisited(); 348 } 349 350 void SetLastNumUrlsChanged(size_t value) { 351 top_sites()->last_num_urls_changed_ = value; 352 } 353 354 size_t last_num_urls_changed() { return top_sites()->last_num_urls_changed_; } 355 356 base::TimeDelta GetUpdateDelay() { 357 return top_sites()->GetUpdateDelay(); 358 } 359 360 bool IsTopSitesLoaded() { return top_sites()->loaded_; } 361 362 bool AddPrepopulatedPages(MostVisitedURLList* urls) { 363 return top_sites()->AddPrepopulatedPages(urls, 0u); 364 } 365 366 void EmptyThreadSafeCache() { 367 base::AutoLock lock(top_sites()->lock_); 368 MostVisitedURLList empty; 369 top_sites()->thread_safe_cache_->SetTopSites(empty); 370 } 371 372 void CreateTopSitesAndObserver() { 373 if (top_sites_observer_) 374 top_sites_observer_.reset(); 375 376 profile_->CreateTopSites(); 377 top_sites_observer_.reset( 378 new TestTopSitesObserver(profile_.get(), profile_->GetTopSites())); 379 } 380 381 private: 382 base::MessageLoopForUI message_loop_; 383 content::TestBrowserThread ui_thread_; 384 content::TestBrowserThread db_thread_; 385 scoped_ptr<TestingProfile> profile_; 386 scoped_ptr<TestTopSitesObserver> top_sites_observer_; 387 // To cancel HistoryService tasks. 388 base::CancelableTaskTracker history_tracker_; 389 390 // To cancel TopSitesBackend tasks. 391 base::CancelableTaskTracker top_sites_tracker_; 392 393 DISALLOW_COPY_AND_ASSIGN(TopSitesImplTest); 394 }; // Class TopSitesImplTest 395 396 // Helper function for appending a URL to a vector of "most visited" URLs, 397 // using the default values for everything but the URL. 398 static void AppendMostVisitedURL(std::vector<MostVisitedURL>* list, 399 const GURL& url) { 400 MostVisitedURL mv; 401 mv.url = url; 402 mv.redirects.push_back(url); 403 list->push_back(mv); 404 } 405 406 // Helper function for appending a URL to a vector of "most visited" URLs, 407 // using the default values for everything but the URL. 408 static void AppendForcedMostVisitedURL(std::vector<MostVisitedURL>* list, 409 const GURL& url, 410 double last_forced_time) { 411 MostVisitedURL mv; 412 mv.url = url; 413 mv.last_forced_time = base::Time::FromJsTime(last_forced_time); 414 mv.redirects.push_back(url); 415 list->push_back(mv); 416 } 417 418 // Same as AppendMostVisitedURL except that it adds a redirect from the first 419 // URL to the second. 420 static void AppendMostVisitedURLWithRedirect( 421 std::vector<MostVisitedURL>* list, 422 const GURL& redirect_source, const GURL& redirect_dest) { 423 MostVisitedURL mv; 424 mv.url = redirect_dest; 425 mv.redirects.push_back(redirect_source); 426 mv.redirects.push_back(redirect_dest); 427 list->push_back(mv); 428 } 429 430 // Tests GetCanonicalURL. 431 TEST_F(TopSitesImplTest, GetCanonicalURL) { 432 // Have two chains: 433 // google.com -> www.google.com 434 // news.google.com (no redirects) 435 GURL news("http://news.google.com/"); 436 GURL source("http://google.com/"); 437 GURL dest("http://www.google.com/"); 438 439 std::vector<MostVisitedURL> most_visited; 440 AppendMostVisitedURLWithRedirect(&most_visited, source, dest); 441 AppendMostVisitedURL(&most_visited, news); 442 SetTopSites(most_visited); 443 444 // Random URLs not in the database are returned unchanged. 445 GURL result = GetCanonicalURL(GURL("http://fark.com/")); 446 EXPECT_EQ(GURL("http://fark.com/"), result); 447 448 // Easy case, there are no redirects and the exact URL is stored. 449 result = GetCanonicalURL(news); 450 EXPECT_EQ(news, result); 451 452 // The URL in question is the source URL in a redirect list. 453 result = GetCanonicalURL(source); 454 EXPECT_EQ(dest, result); 455 456 // The URL in question is the destination of a redirect. 457 result = GetCanonicalURL(dest); 458 EXPECT_EQ(dest, result); 459 } 460 461 // Tests DiffMostVisited. 462 TEST_F(TopSitesImplTest, DiffMostVisited) { 463 GURL stays_the_same("http://staysthesame/"); 464 GURL gets_added_1("http://getsadded1/"); 465 GURL gets_added_2("http://getsadded2/"); 466 GURL gets_deleted_1("http://getsdeleted1/"); 467 GURL gets_moved_1("http://getsmoved1/"); 468 469 std::vector<MostVisitedURL> old_list; 470 AppendMostVisitedURL(&old_list, stays_the_same); // 0 (unchanged) 471 AppendMostVisitedURL(&old_list, gets_deleted_1); // 1 (deleted) 472 AppendMostVisitedURL(&old_list, gets_moved_1); // 2 (moved to 3) 473 474 std::vector<MostVisitedURL> new_list; 475 AppendMostVisitedURL(&new_list, stays_the_same); // 0 (unchanged) 476 AppendMostVisitedURL(&new_list, gets_added_1); // 1 (added) 477 AppendMostVisitedURL(&new_list, gets_added_2); // 2 (added) 478 AppendMostVisitedURL(&new_list, gets_moved_1); // 3 (moved from 2) 479 480 history::TopSitesDelta delta; 481 history::TopSitesImpl::DiffMostVisited(old_list, new_list, &delta); 482 483 ASSERT_EQ(2u, delta.added.size()); 484 EXPECT_TRUE(gets_added_1 == delta.added[0].url.url); 485 EXPECT_EQ(1, delta.added[0].rank); 486 EXPECT_TRUE(gets_added_2 == delta.added[1].url.url); 487 EXPECT_EQ(2, delta.added[1].rank); 488 489 ASSERT_EQ(1u, delta.deleted.size()); 490 EXPECT_TRUE(gets_deleted_1 == delta.deleted[0].url); 491 492 ASSERT_EQ(1u, delta.moved.size()); 493 EXPECT_TRUE(gets_moved_1 == delta.moved[0].url.url); 494 EXPECT_EQ(3, delta.moved[0].rank); 495 } 496 497 // Tests DiffMostVisited with forced URLs. 498 TEST_F(TopSitesImplTest, DiffMostVisitedWithForced) { 499 // Forced URLs. 500 GURL stays_the_same_1("http://staysthesame1/"); 501 GURL new_last_forced_time("http://newlastforcedtime/"); 502 GURL stays_the_same_2("http://staysthesame2/"); 503 GURL move_to_nonforced("http://movetononforced/"); 504 GURL gets_added_1("http://getsadded1/"); 505 GURL gets_deleted_1("http://getsdeleted1/"); 506 // Non-forced URLs. 507 GURL move_to_forced("http://movetoforced/"); 508 GURL stays_the_same_3("http://staysthesame3/"); 509 GURL gets_added_2("http://getsadded2/"); 510 GURL gets_deleted_2("http://getsdeleted2/"); 511 GURL gets_moved_1("http://getsmoved1/"); 512 513 std::vector<MostVisitedURL> old_list; 514 AppendForcedMostVisitedURL(&old_list, stays_the_same_1, 1000); 515 AppendForcedMostVisitedURL(&old_list, new_last_forced_time, 2000); 516 AppendForcedMostVisitedURL(&old_list, stays_the_same_2, 3000); 517 AppendForcedMostVisitedURL(&old_list, move_to_nonforced, 4000); 518 AppendForcedMostVisitedURL(&old_list, gets_deleted_1, 5000); 519 AppendMostVisitedURL(&old_list, move_to_forced); 520 AppendMostVisitedURL(&old_list, stays_the_same_3); 521 AppendMostVisitedURL(&old_list, gets_deleted_2); 522 AppendMostVisitedURL(&old_list, gets_moved_1); 523 524 std::vector<MostVisitedURL> new_list; 525 AppendForcedMostVisitedURL(&new_list, stays_the_same_1, 1000); 526 AppendForcedMostVisitedURL(&new_list, stays_the_same_2, 3000); 527 AppendForcedMostVisitedURL(&new_list, new_last_forced_time, 4000); 528 AppendForcedMostVisitedURL(&new_list, gets_added_1, 5000); 529 AppendForcedMostVisitedURL(&new_list, move_to_forced, 6000); 530 AppendMostVisitedURL(&new_list, move_to_nonforced); 531 AppendMostVisitedURL(&new_list, stays_the_same_3); 532 AppendMostVisitedURL(&new_list, gets_added_2); 533 AppendMostVisitedURL(&new_list, gets_moved_1); 534 535 history::TopSitesDelta delta; 536 history::TopSitesImpl::DiffMostVisited(old_list, new_list, &delta); 537 538 ASSERT_EQ(2u, delta.added.size()); 539 EXPECT_TRUE(gets_added_1 == delta.added[0].url.url); 540 EXPECT_EQ(-1, delta.added[0].rank); 541 EXPECT_TRUE(gets_added_2 == delta.added[1].url.url); 542 EXPECT_EQ(2, delta.added[1].rank); 543 544 ASSERT_EQ(2u, delta.deleted.size()); 545 EXPECT_TRUE(gets_deleted_1 == delta.deleted[0].url); 546 EXPECT_TRUE(gets_deleted_2 == delta.deleted[1].url); 547 548 ASSERT_EQ(3u, delta.moved.size()); 549 EXPECT_TRUE(new_last_forced_time == delta.moved[0].url.url); 550 EXPECT_EQ(-1, delta.moved[0].rank); 551 EXPECT_EQ(base::Time::FromJsTime(4000), delta.moved[0].url.last_forced_time); 552 EXPECT_TRUE(move_to_forced == delta.moved[1].url.url); 553 EXPECT_EQ(-1, delta.moved[1].rank); 554 EXPECT_EQ(base::Time::FromJsTime(6000), delta.moved[1].url.last_forced_time); 555 EXPECT_TRUE(move_to_nonforced == delta.moved[2].url.url); 556 EXPECT_EQ(0, delta.moved[2].rank); 557 EXPECT_TRUE(delta.moved[2].url.last_forced_time.is_null()); 558 } 559 560 // Tests SetPageThumbnail. 561 TEST_F(TopSitesImplTest, SetPageThumbnail) { 562 GURL url1a("http://google.com/"); 563 GURL url1b("http://www.google.com/"); 564 GURL url2("http://images.google.com/"); 565 GURL invalid_url("chrome://favicon/http://google.com/"); 566 567 std::vector<MostVisitedURL> list; 568 AppendMostVisitedURL(&list, url2); 569 570 MostVisitedURL mv; 571 mv.url = url1b; 572 mv.redirects.push_back(url1a); 573 mv.redirects.push_back(url1b); 574 list.push_back(mv); 575 576 // Save our most visited data containing that one site. 577 SetTopSites(list); 578 579 // Create a dummy thumbnail. 580 gfx::Image thumbnail(CreateBitmap(SK_ColorWHITE)); 581 582 base::Time now = base::Time::Now(); 583 ThumbnailScore low_score(1.0, true, true, now); 584 ThumbnailScore medium_score(0.5, true, true, now); 585 ThumbnailScore high_score(0.0, true, true, now); 586 587 // Setting the thumbnail for invalid pages should fail. 588 EXPECT_FALSE(top_sites()->SetPageThumbnail(invalid_url, 589 thumbnail, medium_score)); 590 591 // Setting the thumbnail for url2 should succeed, lower scores shouldn't 592 // replace it, higher scores should. 593 EXPECT_TRUE(top_sites()->SetPageThumbnail(url2, thumbnail, medium_score)); 594 EXPECT_FALSE(top_sites()->SetPageThumbnail(url2, thumbnail, low_score)); 595 EXPECT_TRUE(top_sites()->SetPageThumbnail(url2, thumbnail, high_score)); 596 597 // Set on the redirect source should succeed. It should be replacable by 598 // the same score on the redirect destination, which in turn should not 599 // be replaced by the source again. 600 EXPECT_TRUE(top_sites()->SetPageThumbnail(url1a, thumbnail, medium_score)); 601 EXPECT_TRUE(top_sites()->SetPageThumbnail(url1b, thumbnail, medium_score)); 602 EXPECT_FALSE(top_sites()->SetPageThumbnail(url1a, thumbnail, medium_score)); 603 } 604 605 // Makes sure a thumbnail is correctly removed when the page is removed. 606 TEST_F(TopSitesImplTest, ThumbnailRemoved) { 607 GURL url("http://google.com/"); 608 609 // Configure top sites with 'google.com'. 610 std::vector<MostVisitedURL> list; 611 AppendMostVisitedURL(&list, url); 612 SetTopSites(list); 613 614 // Create a dummy thumbnail. 615 gfx::Image thumbnail(CreateBitmap(SK_ColorRED)); 616 617 base::Time now = base::Time::Now(); 618 ThumbnailScore low_score(1.0, true, true, now); 619 ThumbnailScore medium_score(0.5, true, true, now); 620 ThumbnailScore high_score(0.0, true, true, now); 621 622 // Set the thumbnail. 623 EXPECT_TRUE(top_sites()->SetPageThumbnail(url, thumbnail, medium_score)); 624 625 // Make sure the thumbnail was actually set. 626 scoped_refptr<base::RefCountedMemory> result; 627 EXPECT_TRUE(top_sites()->GetPageThumbnail(url, false, &result)); 628 EXPECT_TRUE(ThumbnailEqualsBytes(thumbnail, result.get())); 629 630 // Reset the thumbnails and make sure we don't get it back. 631 SetTopSites(MostVisitedURLList()); 632 RefreshTopSitesAndRecreate(); 633 EXPECT_FALSE(top_sites()->GetPageThumbnail(url, false, &result)); 634 } 635 636 // Tests GetPageThumbnail. 637 TEST_F(TopSitesImplTest, GetPageThumbnail) { 638 MostVisitedURLList url_list; 639 MostVisitedURL url1; 640 url1.url = GURL("http://asdf.com"); 641 url1.redirects.push_back(url1.url); 642 url_list.push_back(url1); 643 644 MostVisitedURL url2; 645 url2.url = GURL("http://gmail.com"); 646 url2.redirects.push_back(url2.url); 647 url2.redirects.push_back(GURL("http://mail.google.com")); 648 url_list.push_back(url2); 649 650 SetTopSites(url_list); 651 652 // Create a dummy thumbnail. 653 gfx::Image thumbnail(CreateBitmap(SK_ColorWHITE)); 654 ThumbnailScore score(0.5, true, true, base::Time::Now()); 655 656 scoped_refptr<base::RefCountedMemory> result; 657 EXPECT_TRUE(top_sites()->SetPageThumbnail(url1.url, thumbnail, score)); 658 EXPECT_TRUE(top_sites()->GetPageThumbnail(url1.url, false, &result)); 659 660 EXPECT_TRUE(top_sites()->SetPageThumbnail(GURL("http://gmail.com"), 661 thumbnail, score)); 662 EXPECT_TRUE(top_sites()->GetPageThumbnail(GURL("http://gmail.com"), 663 false, 664 &result)); 665 // Get a thumbnail via a redirect. 666 EXPECT_TRUE(top_sites()->GetPageThumbnail(GURL("http://mail.google.com"), 667 false, 668 &result)); 669 670 EXPECT_TRUE(top_sites()->SetPageThumbnail(GURL("http://mail.google.com"), 671 thumbnail, score)); 672 EXPECT_TRUE(top_sites()->GetPageThumbnail(url2.url, false, &result)); 673 674 EXPECT_TRUE(ThumbnailEqualsBytes(thumbnail, result.get())); 675 } 676 677 // Tests GetMostVisitedURLs. 678 TEST_F(TopSitesImplTest, GetMostVisited) { 679 GURL news("http://news.google.com/"); 680 GURL google("http://google.com/"); 681 682 AddPageToHistory(news); 683 AddPageToHistory(google); 684 685 StartQueryForMostVisited(); 686 WaitForHistory(); 687 688 TopSitesQuerier querier; 689 querier.QueryTopSites(top_sites(), false); 690 691 ASSERT_EQ(1, querier.number_of_callbacks()); 692 693 // 2 extra prepopulated URLs. 694 ASSERT_EQ(2u + GetPrepopulatePages().size(), querier.urls().size()); 695 EXPECT_EQ(news, querier.urls()[0].url); 696 EXPECT_EQ(google, querier.urls()[1].url); 697 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier, 2)); 698 } 699 700 // Makes sure changes done to top sites get mirrored to the db. 701 TEST_F(TopSitesImplTest, SaveToDB) { 702 MostVisitedURL url; 703 GURL asdf_url("http://asdf.com"); 704 base::string16 asdf_title(base::ASCIIToUTF16("ASDF")); 705 GURL google_url("http://google.com"); 706 base::string16 google_title(base::ASCIIToUTF16("Google")); 707 GURL news_url("http://news.google.com"); 708 base::string16 news_title(base::ASCIIToUTF16("Google News")); 709 710 // Add asdf_url to history. 711 AddPageToHistory(asdf_url, asdf_title); 712 713 // Make TopSites reread from the db. 714 StartQueryForMostVisited(); 715 WaitForHistory(); 716 717 // Add a thumbnail. 718 gfx::Image tmp_bitmap(CreateBitmap(SK_ColorBLUE)); 719 ASSERT_TRUE(top_sites()->SetPageThumbnail(asdf_url, tmp_bitmap, 720 ThumbnailScore())); 721 722 RecreateTopSitesAndBlock(); 723 724 { 725 TopSitesQuerier querier; 726 querier.QueryTopSites(top_sites(), false); 727 ASSERT_EQ(1u + GetPrepopulatePages().size(), querier.urls().size()); 728 EXPECT_EQ(asdf_url, querier.urls()[0].url); 729 EXPECT_EQ(asdf_title, querier.urls()[0].title); 730 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier, 1)); 731 732 scoped_refptr<base::RefCountedMemory> read_data; 733 EXPECT_TRUE(top_sites()->GetPageThumbnail(asdf_url, false, &read_data)); 734 EXPECT_TRUE(ThumbnailEqualsBytes(tmp_bitmap, read_data.get())); 735 } 736 737 MostVisitedURL url2; 738 url2.url = google_url; 739 url2.title = google_title; 740 url2.redirects.push_back(url2.url); 741 742 AddPageToHistory(url2.url, url2.title); 743 744 // Add new thumbnail at rank 0 and shift the other result to 1. 745 ASSERT_TRUE(top_sites()->SetPageThumbnail(google_url, 746 tmp_bitmap, 747 ThumbnailScore())); 748 749 // Make TopSites reread from the db. 750 RefreshTopSitesAndRecreate(); 751 752 { 753 TopSitesQuerier querier; 754 querier.QueryTopSites(top_sites(), false); 755 ASSERT_EQ(2u + GetPrepopulatePages().size(), querier.urls().size()); 756 EXPECT_EQ(asdf_url, querier.urls()[0].url); 757 EXPECT_EQ(asdf_title, querier.urls()[0].title); 758 EXPECT_EQ(google_url, querier.urls()[1].url); 759 EXPECT_EQ(google_title, querier.urls()[1].title); 760 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier, 2)); 761 } 762 } 763 764 // Makes sure forced URLs in top sites get mirrored to the db. 765 TEST_F(TopSitesImplTest, SaveForcedToDB) { 766 MostVisitedURL url; 767 GURL asdf_url("http://asdf.com"); 768 base::string16 asdf_title(base::ASCIIToUTF16("ASDF")); 769 GURL google_url("http://google.com"); 770 base::string16 google_title(base::ASCIIToUTF16("Google")); 771 GURL news_url("http://news.google.com"); 772 base::string16 news_title(base::ASCIIToUTF16("Google News")); 773 774 // Add a number of forced URLs. 775 std::vector<MostVisitedURL> list; 776 AppendForcedMostVisitedURL(&list, GURL("http://forced1"), 1000); 777 list[0].title = base::ASCIIToUTF16("forced1"); 778 AppendForcedMostVisitedURL(&list, GURL("http://forced2"), 2000); 779 AppendForcedMostVisitedURL(&list, GURL("http://forced3"), 3000); 780 AppendForcedMostVisitedURL(&list, GURL("http://forced4"), 4000); 781 SetTopSites(list); 782 783 // Add a thumbnail. 784 gfx::Image red_thumbnail(CreateBitmap(SK_ColorRED)); 785 ASSERT_TRUE(top_sites()->SetPageThumbnail( 786 GURL("http://forced1"), red_thumbnail, ThumbnailScore())); 787 788 // Get the original thumbnail for later comparison. Some compression can 789 // happen in |top_sites| and we don't want to depend on that. 790 SkBitmap orig_thumbnail = GetThumbnail(GURL("http://forced1")); 791 792 // Force-flush the cache to ensure we don't reread from it inadvertently. 793 EmptyThreadSafeCache(); 794 795 // Make TopSites reread from the db. 796 StartQueryForMostVisited(); 797 WaitForHistory(); 798 799 TopSitesQuerier querier; 800 querier.QueryAllTopSites(top_sites(), true, true); 801 802 ASSERT_EQ(4u + GetPrepopulatePages().size(), querier.urls().size()); 803 EXPECT_EQ(GURL("http://forced1"), querier.urls()[0].url); 804 EXPECT_EQ(base::ASCIIToUTF16("forced1"), querier.urls()[0].title); 805 SkBitmap thumbnail = GetThumbnail(GURL("http://forced1")); 806 ASSERT_EQ(orig_thumbnail.getSize(), thumbnail.getSize()); 807 orig_thumbnail.lockPixels(); 808 thumbnail.lockPixels(); 809 EXPECT_EQ(0, memcmp(orig_thumbnail.getPixels(), thumbnail.getPixels(), 810 orig_thumbnail.getSize())); 811 thumbnail.unlockPixels(); 812 orig_thumbnail.unlockPixels(); 813 EXPECT_EQ(base::Time::FromJsTime(1000), querier.urls()[0].last_forced_time); 814 EXPECT_EQ(GURL("http://forced2"), querier.urls()[1].url); 815 EXPECT_EQ(base::Time::FromJsTime(2000), querier.urls()[1].last_forced_time); 816 EXPECT_EQ(GURL("http://forced3"), querier.urls()[2].url); 817 EXPECT_EQ(base::Time::FromJsTime(3000), querier.urls()[2].last_forced_time); 818 EXPECT_EQ(GURL("http://forced4"), querier.urls()[3].url); 819 EXPECT_EQ(base::Time::FromJsTime(4000), querier.urls()[3].last_forced_time); 820 821 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier, 4)); 822 } 823 824 // More permutations of saving to db. 825 TEST_F(TopSitesImplTest, RealDatabase) { 826 MostVisitedURL url; 827 GURL asdf_url("http://asdf.com"); 828 base::string16 asdf_title(base::ASCIIToUTF16("ASDF")); 829 GURL google1_url("http://google.com"); 830 GURL google2_url("http://google.com/redirect"); 831 GURL google3_url("http://www.google.com"); 832 base::string16 google_title(base::ASCIIToUTF16("Google")); 833 GURL news_url("http://news.google.com"); 834 base::string16 news_title(base::ASCIIToUTF16("Google News")); 835 836 url.url = asdf_url; 837 url.title = asdf_title; 838 url.redirects.push_back(url.url); 839 gfx::Image asdf_thumbnail(CreateBitmap(SK_ColorRED)); 840 ASSERT_TRUE(top_sites()->SetPageThumbnail( 841 asdf_url, asdf_thumbnail, ThumbnailScore())); 842 843 base::Time add_time(base::Time::Now()); 844 AddPageToHistory(url.url, url.title, url.redirects, add_time); 845 846 RefreshTopSitesAndRecreate(); 847 848 { 849 TopSitesQuerier querier; 850 querier.QueryTopSites(top_sites(), false); 851 852 ASSERT_EQ(1u + GetPrepopulatePages().size(), querier.urls().size()); 853 EXPECT_EQ(asdf_url, querier.urls()[0].url); 854 EXPECT_EQ(asdf_title, querier.urls()[0].title); 855 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier, 1)); 856 857 scoped_refptr<base::RefCountedMemory> read_data; 858 EXPECT_TRUE(top_sites()->GetPageThumbnail(asdf_url, false, &read_data)); 859 EXPECT_TRUE(ThumbnailEqualsBytes(asdf_thumbnail, read_data.get())); 860 } 861 862 MostVisitedURL url2; 863 url2.url = google3_url; 864 url2.title = google_title; 865 url2.redirects.push_back(google1_url); 866 url2.redirects.push_back(google2_url); 867 url2.redirects.push_back(google3_url); 868 869 AddPageToHistory(google3_url, url2.title, url2.redirects, 870 add_time - base::TimeDelta::FromMinutes(1)); 871 // Add google twice so that it becomes the first visited site. 872 AddPageToHistory(google3_url, url2.title, url2.redirects, 873 add_time - base::TimeDelta::FromMinutes(2)); 874 875 gfx::Image google_thumbnail(CreateBitmap(SK_ColorBLUE)); 876 ASSERT_TRUE(top_sites()->SetPageThumbnail( 877 url2.url, google_thumbnail, ThumbnailScore())); 878 879 RefreshTopSitesAndRecreate(); 880 881 { 882 scoped_refptr<base::RefCountedMemory> read_data; 883 TopSitesQuerier querier; 884 querier.QueryTopSites(top_sites(), false); 885 886 ASSERT_EQ(2u + GetPrepopulatePages().size(), querier.urls().size()); 887 EXPECT_EQ(google1_url, querier.urls()[0].url); 888 EXPECT_EQ(google_title, querier.urls()[0].title); 889 ASSERT_EQ(3u, querier.urls()[0].redirects.size()); 890 EXPECT_TRUE(top_sites()->GetPageThumbnail(google3_url, false, &read_data)); 891 EXPECT_TRUE(ThumbnailEqualsBytes(google_thumbnail, read_data.get())); 892 893 EXPECT_EQ(asdf_url, querier.urls()[1].url); 894 EXPECT_EQ(asdf_title, querier.urls()[1].title); 895 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier, 2)); 896 } 897 898 gfx::Image weewar_bitmap(CreateBitmap(SK_ColorYELLOW)); 899 900 base::Time thumbnail_time(base::Time::Now()); 901 ThumbnailScore low_score(1.0, true, true, thumbnail_time); 902 ThumbnailScore medium_score(0.5, true, true, thumbnail_time); 903 ThumbnailScore high_score(0.0, true, true, thumbnail_time); 904 905 // 1. Set to weewar. (Writes the thumbnail to the DB.) 906 EXPECT_TRUE(top_sites()->SetPageThumbnail(google3_url, 907 weewar_bitmap, 908 medium_score)); 909 RefreshTopSitesAndRecreate(); 910 { 911 scoped_refptr<base::RefCountedMemory> read_data; 912 EXPECT_TRUE(top_sites()->GetPageThumbnail(google3_url, false, &read_data)); 913 EXPECT_TRUE(ThumbnailEqualsBytes(weewar_bitmap, read_data.get())); 914 } 915 916 gfx::Image green_bitmap(CreateBitmap(SK_ColorGREEN)); 917 918 // 2. Set to google - low score. 919 EXPECT_FALSE(top_sites()->SetPageThumbnail(google3_url, 920 green_bitmap, 921 low_score)); 922 923 // 3. Set to google - high score. 924 EXPECT_TRUE(top_sites()->SetPageThumbnail(google1_url, 925 green_bitmap, 926 high_score)); 927 928 // Check that the thumbnail was updated. 929 RefreshTopSitesAndRecreate(); 930 { 931 scoped_refptr<base::RefCountedMemory> read_data; 932 EXPECT_TRUE(top_sites()->GetPageThumbnail(google3_url, false, &read_data)); 933 EXPECT_FALSE(ThumbnailEqualsBytes(weewar_bitmap, read_data.get())); 934 EXPECT_TRUE(ThumbnailEqualsBytes(green_bitmap, read_data.get())); 935 } 936 } 937 938 TEST_F(TopSitesImplTest, DeleteNotifications) { 939 GURL google1_url("http://google.com"); 940 GURL google2_url("http://google.com/redirect"); 941 GURL google3_url("http://www.google.com"); 942 base::string16 google_title(base::ASCIIToUTF16("Google")); 943 GURL news_url("http://news.google.com"); 944 base::string16 news_title(base::ASCIIToUTF16("Google News")); 945 946 AddPageToHistory(google1_url, google_title); 947 AddPageToHistory(news_url, news_title); 948 949 RefreshTopSitesAndRecreate(); 950 951 { 952 TopSitesQuerier querier; 953 querier.QueryTopSites(top_sites(), false); 954 955 ASSERT_EQ(GetPrepopulatePages().size() + 2, querier.urls().size()); 956 } 957 958 DeleteURL(news_url); 959 960 // Wait for history to process the deletion. 961 WaitForHistory(); 962 963 { 964 TopSitesQuerier querier; 965 querier.QueryTopSites(top_sites(), false); 966 967 ASSERT_EQ(1u + GetPrepopulatePages().size(), querier.urls().size()); 968 EXPECT_EQ(google_title, querier.urls()[0].title); 969 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier, 1)); 970 } 971 972 // Now reload. This verifies topsites actually wrote the deletion to disk. 973 RefreshTopSitesAndRecreate(); 974 975 { 976 TopSitesQuerier querier; 977 querier.QueryTopSites(top_sites(), false); 978 979 ASSERT_EQ(1u + GetPrepopulatePages().size(), querier.urls().size()); 980 EXPECT_EQ(google_title, querier.urls()[0].title); 981 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier, 1)); 982 } 983 984 DeleteURL(google1_url); 985 986 // Wait for history to process the deletion. 987 WaitForHistory(); 988 989 { 990 TopSitesQuerier querier; 991 querier.QueryTopSites(top_sites(), false); 992 993 ASSERT_EQ(GetPrepopulatePages().size(), querier.urls().size()); 994 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier, 0)); 995 } 996 997 // Now reload. This verifies topsites actually wrote the deletion to disk. 998 RefreshTopSitesAndRecreate(); 999 1000 { 1001 TopSitesQuerier querier; 1002 querier.QueryTopSites(top_sites(), false); 1003 1004 ASSERT_EQ(GetPrepopulatePages().size(), querier.urls().size()); 1005 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier, 0)); 1006 } 1007 } 1008 1009 // Makes sure GetUpdateDelay is updated appropriately. 1010 TEST_F(TopSitesImplTest, GetUpdateDelay) { 1011 SetLastNumUrlsChanged(0); 1012 EXPECT_EQ(30, GetUpdateDelay().InSeconds()); 1013 1014 MostVisitedURLList url_list; 1015 url_list.resize(20); 1016 GURL tmp_url(GURL("http://x")); 1017 for (size_t i = 0; i < url_list.size(); ++i) { 1018 url_list[i].url = tmp_url; 1019 url_list[i].redirects.push_back(tmp_url); 1020 } 1021 SetTopSites(url_list); 1022 EXPECT_EQ(20u, last_num_urls_changed()); 1023 SetLastNumUrlsChanged(0); 1024 EXPECT_EQ(60, GetUpdateDelay().InMinutes()); 1025 1026 SetLastNumUrlsChanged(3); 1027 EXPECT_EQ(52, GetUpdateDelay().InMinutes()); 1028 1029 SetLastNumUrlsChanged(20); 1030 EXPECT_EQ(1, GetUpdateDelay().InMinutes()); 1031 } 1032 1033 // Verifies that callbacks are notified correctly if requested before top sites 1034 // has loaded. 1035 TEST_F(TopSitesImplTest, NotifyCallbacksWhenLoaded) { 1036 // Recreate top sites. It won't be loaded now. 1037 CreateTopSitesAndObserver(); 1038 1039 EXPECT_FALSE(IsTopSitesLoaded()); 1040 1041 TopSitesQuerier querier1; 1042 TopSitesQuerier querier2; 1043 TopSitesQuerier querier3; 1044 1045 // Starts the queries. 1046 querier1.QueryTopSites(top_sites(), false); 1047 querier2.QueryTopSites(top_sites(), false); 1048 querier3.QueryTopSites(top_sites(), false); 1049 1050 // We shouldn't have gotten a callback. 1051 EXPECT_EQ(0, querier1.number_of_callbacks()); 1052 EXPECT_EQ(0, querier2.number_of_callbacks()); 1053 EXPECT_EQ(0, querier3.number_of_callbacks()); 1054 1055 // Wait for loading to complete. 1056 profile()->BlockUntilTopSitesLoaded(); 1057 1058 // Now we should have gotten the callbacks. 1059 EXPECT_EQ(1, querier1.number_of_callbacks()); 1060 EXPECT_EQ(GetPrepopulatePages().size(), querier1.urls().size()); 1061 EXPECT_EQ(1, querier2.number_of_callbacks()); 1062 EXPECT_EQ(GetPrepopulatePages().size(), querier2.urls().size()); 1063 EXPECT_EQ(1, querier3.number_of_callbacks()); 1064 EXPECT_EQ(GetPrepopulatePages().size(), querier3.urls().size()); 1065 1066 // Reset the top sites. 1067 MostVisitedURLList pages; 1068 MostVisitedURL url; 1069 url.url = GURL("http://1.com/"); 1070 url.redirects.push_back(url.url); 1071 pages.push_back(url); 1072 url.url = GURL("http://2.com/"); 1073 url.redirects.push_back(url.url); 1074 pages.push_back(url); 1075 SetTopSites(pages); 1076 1077 // Recreate top sites. It won't be loaded now. 1078 CreateTopSitesAndObserver(); 1079 1080 EXPECT_FALSE(IsTopSitesLoaded()); 1081 1082 TopSitesQuerier querier4; 1083 1084 // Query again. 1085 querier4.QueryTopSites(top_sites(), false); 1086 1087 // We shouldn't have gotten a callback. 1088 EXPECT_EQ(0, querier4.number_of_callbacks()); 1089 1090 // Wait for loading to complete. 1091 profile()->BlockUntilTopSitesLoaded(); 1092 1093 // Now we should have gotten the callbacks. 1094 EXPECT_EQ(1, querier4.number_of_callbacks()); 1095 ASSERT_EQ(2u + GetPrepopulatePages().size(), querier4.urls().size()); 1096 1097 EXPECT_EQ("http://1.com/", querier4.urls()[0].url.spec()); 1098 EXPECT_EQ("http://2.com/", querier4.urls()[1].url.spec()); 1099 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier4, 2)); 1100 1101 // Reset the top sites again, this time don't reload. 1102 url.url = GURL("http://3.com/"); 1103 url.redirects.push_back(url.url); 1104 pages.push_back(url); 1105 SetTopSites(pages); 1106 1107 // Query again. 1108 TopSitesQuerier querier5; 1109 querier5.QueryTopSites(top_sites(), true); 1110 1111 EXPECT_EQ(1, querier5.number_of_callbacks()); 1112 1113 ASSERT_EQ(3u + GetPrepopulatePages().size(), querier5.urls().size()); 1114 EXPECT_EQ("http://1.com/", querier5.urls()[0].url.spec()); 1115 EXPECT_EQ("http://2.com/", querier5.urls()[1].url.spec()); 1116 EXPECT_EQ("http://3.com/", querier5.urls()[2].url.spec()); 1117 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier5, 3)); 1118 } 1119 1120 // Makes sure canceled requests are not notified. 1121 TEST_F(TopSitesImplTest, CancelingRequestsForTopSites) { 1122 // Recreate top sites. It won't be loaded now. 1123 CreateTopSitesAndObserver(); 1124 1125 EXPECT_FALSE(IsTopSitesLoaded()); 1126 1127 TopSitesQuerier querier1; 1128 TopSitesQuerier querier2; 1129 1130 // Starts the queries. 1131 querier1.QueryTopSites(top_sites(), false); 1132 querier2.QueryTopSites(top_sites(), false); 1133 1134 // We shouldn't have gotten a callback. 1135 EXPECT_EQ(0, querier1.number_of_callbacks()); 1136 EXPECT_EQ(0, querier2.number_of_callbacks()); 1137 1138 querier2.CancelRequest(); 1139 1140 // Wait for loading to complete. 1141 profile()->BlockUntilTopSitesLoaded(); 1142 1143 // The first callback should succeed. 1144 EXPECT_EQ(1, querier1.number_of_callbacks()); 1145 EXPECT_EQ(GetPrepopulatePages().size(), querier1.urls().size()); 1146 1147 // And the canceled callback should not be notified. 1148 EXPECT_EQ(0, querier2.number_of_callbacks()); 1149 } 1150 1151 // Makes sure temporary thumbnails are copied over correctly. 1152 TEST_F(TopSitesImplTest, AddTemporaryThumbnail) { 1153 GURL unknown_url("http://news.google.com/"); 1154 GURL invalid_url("chrome://thumb/http://google.com/"); 1155 GURL url1a("http://google.com/"); 1156 GURL url1b("http://www.google.com/"); 1157 1158 // Create a dummy thumbnail. 1159 gfx::Image thumbnail(CreateBitmap(SK_ColorRED)); 1160 1161 ThumbnailScore medium_score(0.5, true, true, base::Time::Now()); 1162 1163 // Don't store thumbnails for Javascript URLs. 1164 EXPECT_FALSE(top_sites()->SetPageThumbnail(invalid_url, 1165 thumbnail, 1166 medium_score)); 1167 // Store thumbnails for unknown (but valid) URLs temporarily - calls 1168 // AddTemporaryThumbnail. 1169 EXPECT_TRUE(top_sites()->SetPageThumbnail(unknown_url, 1170 thumbnail, 1171 medium_score)); 1172 1173 // We shouldn't get the thumnail back though (the url isn't in to sites yet). 1174 scoped_refptr<base::RefCountedMemory> out; 1175 EXPECT_FALSE(top_sites()->GetPageThumbnail(unknown_url, false, &out)); 1176 // But we should be able to get the temporary page thumbnail score. 1177 ThumbnailScore out_score; 1178 EXPECT_TRUE(top_sites()->GetTemporaryPageThumbnailScore(unknown_url, 1179 &out_score)); 1180 EXPECT_TRUE(medium_score.Equals(out_score)); 1181 1182 std::vector<MostVisitedURL> list; 1183 1184 MostVisitedURL mv; 1185 mv.url = unknown_url; 1186 mv.redirects.push_back(mv.url); 1187 mv.redirects.push_back(url1a); 1188 mv.redirects.push_back(url1b); 1189 list.push_back(mv); 1190 1191 // Update URLs. This should result in using thumbnail. 1192 SetTopSites(list); 1193 1194 ASSERT_TRUE(top_sites()->GetPageThumbnail(unknown_url, false, &out)); 1195 EXPECT_TRUE(ThumbnailEqualsBytes(thumbnail, out.get())); 1196 } 1197 1198 // Tests variations of blacklisting. 1199 TEST_F(TopSitesImplTest, Blacklisting) { 1200 MostVisitedURLList pages; 1201 MostVisitedURL url, url1; 1202 url.url = GURL("http://bbc.com/"); 1203 url.redirects.push_back(url.url); 1204 pages.push_back(url); 1205 url1.url = GURL("http://google.com/"); 1206 url1.redirects.push_back(url1.url); 1207 pages.push_back(url1); 1208 1209 SetTopSites(pages); 1210 EXPECT_FALSE(top_sites()->IsBlacklisted(GURL("http://bbc.com/"))); 1211 1212 // Blacklist google.com. 1213 top_sites()->AddBlacklistedURL(GURL("http://google.com/")); 1214 1215 GURL prepopulate_url = GetPrepopulatePages()[0].url; 1216 1217 EXPECT_TRUE(top_sites()->HasBlacklistedItems()); 1218 EXPECT_TRUE(top_sites()->IsBlacklisted(GURL("http://google.com/"))); 1219 EXPECT_FALSE(top_sites()->IsBlacklisted(GURL("http://bbc.com/"))); 1220 EXPECT_FALSE(top_sites()->IsBlacklisted(prepopulate_url)); 1221 1222 // Make sure the blacklisted site isn't returned in the results. 1223 { 1224 TopSitesQuerier q; 1225 q.QueryTopSites(top_sites(), true); 1226 ASSERT_EQ(1u + GetPrepopulatePages().size(), q.urls().size()); 1227 EXPECT_EQ("http://bbc.com/", q.urls()[0].url.spec()); 1228 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(q, 1)); 1229 } 1230 1231 // Recreate top sites and make sure blacklisted url was correctly read. 1232 RecreateTopSitesAndBlock(); 1233 { 1234 TopSitesQuerier q; 1235 q.QueryTopSites(top_sites(), true); 1236 ASSERT_EQ(1u + GetPrepopulatePages().size(), q.urls().size()); 1237 EXPECT_EQ("http://bbc.com/", q.urls()[0].url.spec()); 1238 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(q, 1)); 1239 } 1240 1241 // Blacklist one of the prepopulate urls. 1242 top_sites()->AddBlacklistedURL(prepopulate_url); 1243 EXPECT_TRUE(top_sites()->HasBlacklistedItems()); 1244 1245 // Make sure the blacklisted prepopulate url isn't returned. 1246 { 1247 TopSitesQuerier q; 1248 q.QueryTopSites(top_sites(), true); 1249 ASSERT_EQ(1u + GetPrepopulatePages().size() - 1, q.urls().size()); 1250 EXPECT_EQ("http://bbc.com/", q.urls()[0].url.spec()); 1251 for (size_t i = 1; i < q.urls().size(); ++i) 1252 EXPECT_NE(prepopulate_url.spec(), q.urls()[i].url.spec()); 1253 } 1254 1255 // Mark google as no longer blacklisted. 1256 top_sites()->RemoveBlacklistedURL(GURL("http://google.com/")); 1257 EXPECT_TRUE(top_sites()->HasBlacklistedItems()); 1258 EXPECT_FALSE(top_sites()->IsBlacklisted(GURL("http://google.com/"))); 1259 1260 // Make sure google is returned now. 1261 { 1262 TopSitesQuerier q; 1263 q.QueryTopSites(top_sites(), true); 1264 ASSERT_EQ(2u + GetPrepopulatePages().size() - 1, q.urls().size()); 1265 EXPECT_EQ("http://bbc.com/", q.urls()[0].url.spec()); 1266 EXPECT_EQ("http://google.com/", q.urls()[1].url.spec()); 1267 // Android has only one prepopulated page which has been blacklisted, so 1268 // only 2 urls are returned. 1269 if (q.urls().size() > 2) 1270 EXPECT_NE(prepopulate_url.spec(), q.urls()[2].url.spec()); 1271 else 1272 EXPECT_EQ(1u, GetPrepopulatePages().size()); 1273 } 1274 1275 // Remove all blacklisted sites. 1276 top_sites()->ClearBlacklistedURLs(); 1277 EXPECT_FALSE(top_sites()->HasBlacklistedItems()); 1278 1279 { 1280 TopSitesQuerier q; 1281 q.QueryTopSites(top_sites(), true); 1282 ASSERT_EQ(2u + GetPrepopulatePages().size(), q.urls().size()); 1283 EXPECT_EQ("http://bbc.com/", q.urls()[0].url.spec()); 1284 EXPECT_EQ("http://google.com/", q.urls()[1].url.spec()); 1285 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(q, 2)); 1286 } 1287 } 1288 1289 // Makes sure prepopulated pages exist. 1290 TEST_F(TopSitesImplTest, AddPrepopulatedPages) { 1291 TopSitesQuerier q; 1292 q.QueryTopSites(top_sites(), true); 1293 EXPECT_EQ(GetPrepopulatePages().size(), q.urls().size()); 1294 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(q, 0)); 1295 1296 MostVisitedURLList pages = q.urls(); 1297 EXPECT_FALSE(AddPrepopulatedPages(&pages)); 1298 1299 EXPECT_EQ(GetPrepopulatePages().size(), pages.size()); 1300 q.set_urls(pages); 1301 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(q, 0)); 1302 } 1303 1304 // Ensure calling SetTopSites with forced sites already in the DB works. 1305 // This test both eviction and 1306 TEST_F(TopSitesImplTest, SetForcedTopSites) { 1307 // Create forced elements in old URL list. 1308 MostVisitedURLList old_url_list; 1309 AppendForcedMostVisitedURL(&old_url_list, GURL("http://oldforced/0"), 1000); 1310 AppendForcedMostVisitedURL(&old_url_list, GURL("http://oldforced/1"), 4000); 1311 AppendForcedMostVisitedURL(&old_url_list, GURL("http://oldforced/2"), 7000); 1312 AppendForcedMostVisitedURL(&old_url_list, GURL("http://oldforced/3"), 10000); 1313 AppendForcedMostVisitedURL(&old_url_list, GURL("http://oldforced/4"), 11000); 1314 AppendForcedMostVisitedURL(&old_url_list, GURL("http://oldforced/5"), 12000); 1315 AppendForcedMostVisitedURL(&old_url_list, GURL("http://oldforced/6"), 13000); 1316 AppendForcedMostVisitedURL(&old_url_list, GURL("http://oldforced/7"), 18000); 1317 AppendForcedMostVisitedURL(&old_url_list, GURL("http://oldforced/8"), 21000); 1318 const size_t kNumOldForcedURLs = 9; 1319 1320 // Create forced elements in new URL list. 1321 MostVisitedURLList new_url_list; 1322 AppendForcedMostVisitedURL(&new_url_list, GURL("http://newforced/0"), 2000); 1323 AppendForcedMostVisitedURL(&new_url_list, GURL("http://newforced/1"), 3000); 1324 AppendForcedMostVisitedURL(&new_url_list, GURL("http://newforced/2"), 5000); 1325 AppendForcedMostVisitedURL(&new_url_list, GURL("http://newforced/3"), 6000); 1326 AppendForcedMostVisitedURL(&new_url_list, GURL("http://newforced/4"), 8000); 1327 AppendForcedMostVisitedURL(&new_url_list, GURL("http://newforced/5"), 9000); 1328 AppendForcedMostVisitedURL(&new_url_list, GURL("http://newforced/6"), 14000); 1329 AppendForcedMostVisitedURL(&new_url_list, GURL("http://newforced/7"), 15000); 1330 AppendForcedMostVisitedURL(&new_url_list, GURL("http://newforced/8"), 16000); 1331 AppendForcedMostVisitedURL(&new_url_list, GURL("http://newforced/9"), 17000); 1332 AppendForcedMostVisitedURL(&new_url_list, GURL("http://newforced/10"), 19000); 1333 AppendForcedMostVisitedURL(&new_url_list, GURL("http://newforced/11"), 20000); 1334 AppendForcedMostVisitedURL(&new_url_list, GURL("http://newforced/12"), 22000); 1335 1336 // Setup a number non-forced URLs in both old and new list. 1337 const size_t kNumNonForcedURLs = 20; // Maximum number of non-forced URLs. 1338 for (size_t i = 0; i < kNumNonForcedURLs; ++i) { 1339 std::ostringstream url; 1340 url << "http://oldnonforced/" << i; 1341 AppendMostVisitedURL(&old_url_list, GURL(url.str())); 1342 url.str(""); 1343 url << "http://newnonforced/" << i; 1344 AppendMostVisitedURL(&new_url_list, GURL(url.str())); 1345 } 1346 1347 // Set the initial list of URLs. 1348 SetTopSites(old_url_list); 1349 EXPECT_EQ(kNumOldForcedURLs + kNumNonForcedURLs, last_num_urls_changed()); 1350 1351 TopSitesQuerier querier; 1352 // Query only non-forced URLs first. 1353 querier.QueryTopSites(top_sites(), false); 1354 ASSERT_EQ(kNumNonForcedURLs, querier.urls().size()); 1355 1356 // Check first URL. 1357 EXPECT_EQ("http://oldnonforced/0", querier.urls()[0].url.spec()); 1358 1359 // Query all URLs. 1360 querier.QueryAllTopSites(top_sites(), false, true); 1361 EXPECT_EQ(kNumOldForcedURLs + kNumNonForcedURLs, querier.urls().size()); 1362 1363 // Check first URLs. 1364 EXPECT_EQ("http://oldforced/0", querier.urls()[0].url.spec()); 1365 EXPECT_EQ("http://oldnonforced/0", 1366 querier.urls()[kNumOldForcedURLs].url.spec()); 1367 1368 // Set the new list of URLs. 1369 SetTopSites(new_url_list); 1370 1371 // Query all URLs. 1372 querier.QueryAllTopSites(top_sites(), false, true); 1373 1374 // We should have reached the maximum of 20 forced URLs. 1375 ASSERT_EQ(20 + kNumNonForcedURLs, querier.urls().size()); 1376 1377 // Check forced URLs. They follow the order of timestamps above, smaller 1378 // timestamps since they were evicted. 1379 EXPECT_EQ("http://newforced/1", querier.urls()[0].url.spec()); 1380 EXPECT_EQ(3000, querier.urls()[0].last_forced_time.ToJsTime()); 1381 EXPECT_EQ("http://oldforced/1", querier.urls()[1].url.spec()); 1382 EXPECT_EQ(4000, querier.urls()[1].last_forced_time.ToJsTime()); 1383 EXPECT_EQ("http://newforced/2", querier.urls()[2].url.spec()); 1384 EXPECT_EQ(5000, querier.urls()[2].last_forced_time.ToJsTime()); 1385 EXPECT_EQ("http://newforced/3", querier.urls()[3].url.spec()); 1386 EXPECT_EQ(6000, querier.urls()[3].last_forced_time.ToJsTime()); 1387 EXPECT_EQ("http://oldforced/2", querier.urls()[4].url.spec()); 1388 EXPECT_EQ(7000, querier.urls()[4].last_forced_time.ToJsTime()); 1389 EXPECT_EQ("http://newforced/4", querier.urls()[5].url.spec()); 1390 EXPECT_EQ(8000, querier.urls()[5].last_forced_time.ToJsTime()); 1391 EXPECT_EQ("http://newforced/5", querier.urls()[6].url.spec()); 1392 EXPECT_EQ(9000, querier.urls()[6].last_forced_time.ToJsTime()); 1393 EXPECT_EQ("http://oldforced/3", querier.urls()[7].url.spec()); 1394 EXPECT_EQ(10000, querier.urls()[7].last_forced_time.ToJsTime()); 1395 EXPECT_EQ("http://oldforced/4", querier.urls()[8].url.spec()); 1396 EXPECT_EQ(11000, querier.urls()[8].last_forced_time.ToJsTime()); 1397 EXPECT_EQ("http://oldforced/5", querier.urls()[9].url.spec()); 1398 EXPECT_EQ(12000, querier.urls()[9].last_forced_time.ToJsTime()); 1399 EXPECT_EQ("http://oldforced/6", querier.urls()[10].url.spec()); 1400 EXPECT_EQ(13000, querier.urls()[10].last_forced_time.ToJsTime()); 1401 EXPECT_EQ("http://newforced/6", querier.urls()[11].url.spec()); 1402 EXPECT_EQ(14000, querier.urls()[11].last_forced_time.ToJsTime()); 1403 EXPECT_EQ("http://newforced/7", querier.urls()[12].url.spec()); 1404 EXPECT_EQ(15000, querier.urls()[12].last_forced_time.ToJsTime()); 1405 EXPECT_EQ("http://newforced/8", querier.urls()[13].url.spec()); 1406 EXPECT_EQ(16000, querier.urls()[13].last_forced_time.ToJsTime()); 1407 EXPECT_EQ("http://newforced/9", querier.urls()[14].url.spec()); 1408 EXPECT_EQ(17000, querier.urls()[14].last_forced_time.ToJsTime()); 1409 EXPECT_EQ("http://oldforced/7", querier.urls()[15].url.spec()); 1410 EXPECT_EQ(18000, querier.urls()[15].last_forced_time.ToJsTime()); 1411 EXPECT_EQ("http://newforced/10", querier.urls()[16].url.spec()); 1412 EXPECT_EQ(19000, querier.urls()[16].last_forced_time.ToJsTime()); 1413 EXPECT_EQ("http://newforced/11", querier.urls()[17].url.spec()); 1414 EXPECT_EQ(20000, querier.urls()[17].last_forced_time.ToJsTime()); 1415 EXPECT_EQ("http://oldforced/8", querier.urls()[18].url.spec()); 1416 EXPECT_EQ(21000, querier.urls()[18].last_forced_time.ToJsTime()); 1417 EXPECT_EQ("http://newforced/12", querier.urls()[19].url.spec()); 1418 EXPECT_EQ(22000, querier.urls()[19].last_forced_time.ToJsTime()); 1419 1420 // Check first and last non-forced URLs. 1421 EXPECT_EQ("http://newnonforced/0", querier.urls()[20].url.spec()); 1422 EXPECT_TRUE(querier.urls()[20].last_forced_time.is_null()); 1423 EXPECT_EQ("http://newnonforced/19", querier.urls()[39].url.spec()); 1424 EXPECT_TRUE(querier.urls()[39].last_forced_time.is_null()); 1425 } 1426 1427 TEST_F(TopSitesImplTest, SetForcedTopSitesWithCollisions) { 1428 1429 // Setup an old URL list in order to generate some collisions. 1430 MostVisitedURLList old_url_list; 1431 AppendForcedMostVisitedURL(&old_url_list, GURL("http://url/0"), 1000); 1432 // The following three will be evicted. 1433 AppendForcedMostVisitedURL(&old_url_list, GURL("http://collision/0"), 4000); 1434 AppendForcedMostVisitedURL(&old_url_list, GURL("http://collision/1"), 6000); 1435 AppendForcedMostVisitedURL(&old_url_list, GURL("http://collision/2"), 7000); 1436 // The following is evicted since all non-forced URLs are, therefore it 1437 // doesn't cause a collision. 1438 AppendMostVisitedURL(&old_url_list, GURL("http://noncollision/0")); 1439 SetTopSites(old_url_list); 1440 1441 // Setup a new URL list that will cause collisions. 1442 MostVisitedURLList new_url_list; 1443 AppendForcedMostVisitedURL(&new_url_list, GURL("http://collision/1"), 2000); 1444 AppendForcedMostVisitedURL(&new_url_list, GURL("http://url/2"), 3000); 1445 AppendForcedMostVisitedURL(&new_url_list, GURL("http://collision/0"), 5000); 1446 AppendForcedMostVisitedURL(&new_url_list, GURL("http://noncollision/0"), 1447 9000); 1448 AppendMostVisitedURL(&new_url_list, GURL("http://collision/2")); 1449 AppendMostVisitedURL(&new_url_list, GURL("http://url/3")); 1450 SetTopSites(new_url_list); 1451 1452 // Query all URLs. 1453 TopSitesQuerier querier; 1454 querier.QueryAllTopSites(top_sites(), false, true); 1455 1456 // Check URLs. When collision occurs, the incoming one is always preferred. 1457 ASSERT_EQ(7u + GetPrepopulatePages().size(), querier.urls().size()); 1458 EXPECT_EQ("http://url/0", querier.urls()[0].url.spec()); 1459 EXPECT_EQ(1000u, querier.urls()[0].last_forced_time.ToJsTime()); 1460 EXPECT_EQ("http://collision/1", querier.urls()[1].url.spec()); 1461 EXPECT_EQ(2000u, querier.urls()[1].last_forced_time.ToJsTime()); 1462 EXPECT_EQ("http://url/2", querier.urls()[2].url.spec()); 1463 EXPECT_EQ(3000u, querier.urls()[2].last_forced_time.ToJsTime()); 1464 EXPECT_EQ("http://collision/0", querier.urls()[3].url.spec()); 1465 EXPECT_EQ(5000u, querier.urls()[3].last_forced_time.ToJsTime()); 1466 EXPECT_EQ("http://noncollision/0", querier.urls()[4].url.spec()); 1467 EXPECT_EQ(9000u, querier.urls()[4].last_forced_time.ToJsTime()); 1468 EXPECT_EQ("http://collision/2", querier.urls()[5].url.spec()); 1469 EXPECT_TRUE(querier.urls()[5].last_forced_time.is_null()); 1470 EXPECT_EQ("http://url/3", querier.urls()[6].url.spec()); 1471 EXPECT_TRUE(querier.urls()[6].last_forced_time.is_null()); 1472 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier, 7)); 1473 } 1474 1475 TEST_F(TopSitesImplTest, SetTopSitesIdentical) { 1476 // Set the initial list of URLs. 1477 MostVisitedURLList url_list; 1478 AppendForcedMostVisitedURL(&url_list, GURL("http://url/0"), 1000); 1479 AppendMostVisitedURL(&url_list, GURL("http://url/1")); 1480 AppendMostVisitedURL(&url_list, GURL("http://url/2")); 1481 SetTopSites(url_list); 1482 1483 // Set the new list of URLs to be exactly the same. 1484 SetTopSites(MostVisitedURLList(url_list)); 1485 1486 // Query all URLs. 1487 TopSitesQuerier querier; 1488 querier.QueryAllTopSites(top_sites(), false, true); 1489 1490 // Check URLs. When collision occurs, the incoming one is always preferred. 1491 ASSERT_EQ(3u + GetPrepopulatePages().size(), querier.urls().size()); 1492 EXPECT_EQ("http://url/0", querier.urls()[0].url.spec()); 1493 EXPECT_EQ(1000u, querier.urls()[0].last_forced_time.ToJsTime()); 1494 EXPECT_EQ("http://url/1", querier.urls()[1].url.spec()); 1495 EXPECT_EQ("http://url/2", querier.urls()[2].url.spec()); 1496 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier, 3)); 1497 } 1498 1499 TEST_F(TopSitesImplTest, SetTopSitesWithAlreadyExistingForcedURLs) { 1500 // Set the initial list of URLs. 1501 MostVisitedURLList old_url_list; 1502 AppendForcedMostVisitedURL(&old_url_list, GURL("http://url/0/redir"), 1000); 1503 AppendForcedMostVisitedURL(&old_url_list, GURL("http://url/1"), 2000); 1504 SetTopSites(old_url_list); 1505 1506 // Setup a new URL list that will cause collisions. 1507 MostVisitedURLList new_url_list; 1508 AppendMostVisitedURLWithRedirect(&new_url_list, GURL("http://url/0/redir"), 1509 GURL("http://url/0")); 1510 AppendMostVisitedURL(&new_url_list, GURL("http://url/1")); 1511 SetTopSites(new_url_list); 1512 1513 // Query all URLs. 1514 TopSitesQuerier querier; 1515 querier.QueryAllTopSites(top_sites(), false, true); 1516 1517 // Check URLs. When collision occurs, the non-forced one is always preferred. 1518 ASSERT_EQ(2u + GetPrepopulatePages().size(), querier.urls().size()); 1519 EXPECT_EQ("http://url/0", querier.urls()[0].url.spec()); 1520 EXPECT_EQ("http://url/0/redir", querier.urls()[0].redirects[0].spec()); 1521 EXPECT_TRUE(querier.urls()[0].last_forced_time.is_null()); 1522 EXPECT_EQ("http://url/1", querier.urls()[1].url.spec()); 1523 EXPECT_TRUE(querier.urls()[1].last_forced_time.is_null()); 1524 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier, 2)); 1525 } 1526 1527 TEST_F(TopSitesImplTest, AddForcedURL) { 1528 // Set the initial list of URLs. 1529 MostVisitedURLList url_list; 1530 AppendForcedMostVisitedURL(&url_list, GURL("http://forced/0"), 2000); 1531 AppendForcedMostVisitedURL(&url_list, GURL("http://forced/1"), 4000); 1532 AppendMostVisitedURL(&url_list, GURL("http://nonforced/0")); 1533 AppendMostVisitedURL(&url_list, GURL("http://nonforced/1")); 1534 AppendMostVisitedURL(&url_list, GURL("http://nonforced/2")); 1535 SetTopSites(url_list); 1536 1537 // Add forced sites here and there to exercise a couple of cases. 1538 EXPECT_TRUE(AddForcedURL(GURL("http://forced/2"), 1539 base::Time::FromJsTime(5000))); 1540 EXPECT_TRUE(AddForcedURL(GURL("http://forced/3"), 1541 base::Time::FromJsTime(1000))); 1542 EXPECT_TRUE(AddForcedURL(GURL("http://forced/4"), 1543 base::Time::FromJsTime(3000))); 1544 1545 // Check URLs. 1546 TopSitesQuerier querier; 1547 querier.QueryAllTopSites(top_sites(), false, true); 1548 ASSERT_EQ(8u + GetPrepopulatePages().size(), querier.urls().size()); 1549 EXPECT_EQ("http://forced/3", querier.urls()[0].url.spec()); 1550 EXPECT_EQ(1000u, querier.urls()[0].last_forced_time.ToJsTime()); 1551 EXPECT_EQ("http://forced/0", querier.urls()[1].url.spec()); 1552 EXPECT_EQ(2000u, querier.urls()[1].last_forced_time.ToJsTime()); 1553 EXPECT_EQ("http://forced/4", querier.urls()[2].url.spec()); 1554 EXPECT_EQ(3000u, querier.urls()[2].last_forced_time.ToJsTime()); 1555 EXPECT_EQ("http://forced/1", querier.urls()[3].url.spec()); 1556 EXPECT_EQ(4000u, querier.urls()[3].last_forced_time.ToJsTime()); 1557 EXPECT_EQ("http://forced/2", querier.urls()[4].url.spec()); 1558 EXPECT_EQ(5000u, querier.urls()[4].last_forced_time.ToJsTime()); 1559 EXPECT_EQ("http://nonforced/0", querier.urls()[5].url.spec()); 1560 EXPECT_TRUE(querier.urls()[5].last_forced_time.is_null()); 1561 EXPECT_EQ("http://nonforced/1", querier.urls()[6].url.spec()); 1562 EXPECT_TRUE(querier.urls()[6].last_forced_time.is_null()); 1563 EXPECT_EQ("http://nonforced/2", querier.urls()[7].url.spec()); 1564 EXPECT_TRUE(querier.urls()[7].last_forced_time.is_null()); 1565 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier, 8)); 1566 1567 // Add some collisions with forced and non-forced. Non-forced URLs are never 1568 // expected to move. 1569 EXPECT_TRUE(AddForcedURL(GURL("http://forced/3"), 1570 base::Time::FromJsTime(4000))); 1571 EXPECT_TRUE(AddForcedURL(GURL("http://forced/1"), 1572 base::Time::FromJsTime(1000))); 1573 EXPECT_FALSE(AddForcedURL(GURL("http://nonforced/0"), 1574 base::Time::FromJsTime(6000))); 1575 1576 // Check relevant URLs. 1577 querier.QueryAllTopSites(top_sites(), false, true); 1578 ASSERT_EQ(8u + GetPrepopulatePages().size(), querier.urls().size()); 1579 EXPECT_EQ("http://forced/1", querier.urls()[0].url.spec()); 1580 EXPECT_EQ(1000u, querier.urls()[0].last_forced_time.ToJsTime()); 1581 EXPECT_EQ("http://forced/3", querier.urls()[3].url.spec()); 1582 EXPECT_EQ(4000u, querier.urls()[3].last_forced_time.ToJsTime()); 1583 EXPECT_EQ("http://nonforced/0", querier.urls()[5].url.spec()); 1584 EXPECT_TRUE(querier.urls()[5].last_forced_time.is_null()); 1585 1586 // Add a timestamp collision and make sure things don't break. 1587 EXPECT_TRUE(AddForcedURL(GURL("http://forced/5"), 1588 base::Time::FromJsTime(4000))); 1589 querier.QueryAllTopSites(top_sites(), false, true); 1590 ASSERT_EQ(9u + GetPrepopulatePages().size(), querier.urls().size()); 1591 EXPECT_EQ(4000u, querier.urls()[3].last_forced_time.ToJsTime()); 1592 EXPECT_EQ(4000u, querier.urls()[4].last_forced_time.ToJsTime()); 1593 // We don't care which order they get sorted in. 1594 if (querier.urls()[3].url.spec() == "http://forced/3") { 1595 EXPECT_EQ("http://forced/3", querier.urls()[3].url.spec()); 1596 EXPECT_EQ("http://forced/5", querier.urls()[4].url.spec()); 1597 } else { 1598 EXPECT_EQ("http://forced/5", querier.urls()[3].url.spec()); 1599 EXPECT_EQ("http://forced/3", querier.urls()[4].url.spec()); 1600 } 1601 1602 // Make sure the thumbnail is not lost when the timestamp is updated. 1603 gfx::Image red_thumbnail(CreateBitmap(SK_ColorRED)); 1604 ASSERT_TRUE(top_sites()->SetPageThumbnail( 1605 GURL("http://forced/5"), red_thumbnail, ThumbnailScore())); 1606 1607 // Get the original thumbnail for later comparison. Some compression can 1608 // happen in |top_sites| and we don't want to depend on that. 1609 SkBitmap orig_thumbnail = GetThumbnail(GURL("http://forced/5")); 1610 1611 EXPECT_TRUE(AddForcedURL(GURL("http://forced/5"), 1612 base::Time::FromJsTime(6000))); 1613 1614 // Ensure the thumbnail is still there even if the timestamp changed. 1615 querier.QueryAllTopSites(top_sites(), false, true); 1616 EXPECT_EQ("http://forced/5", querier.urls()[5].url.spec()); 1617 EXPECT_EQ(6000u, querier.urls()[5].last_forced_time.ToJsTime()); 1618 SkBitmap thumbnail = GetThumbnail(GURL("http://forced/5")); 1619 ASSERT_EQ(orig_thumbnail.getSize(), thumbnail.getSize()); 1620 orig_thumbnail.lockPixels(); 1621 thumbnail.lockPixels(); 1622 EXPECT_EQ(0, memcmp(orig_thumbnail.getPixels(), thumbnail.getPixels(), 1623 orig_thumbnail.getSize())); 1624 thumbnail.unlockPixels(); 1625 orig_thumbnail.unlockPixels(); 1626 } 1627 1628 } // namespace history 1629