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