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