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