Home | History | Annotate | Download | only in history
      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