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.
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"
30 using content::BrowserThread;
32 class TestTopSitesObserver : public history::TopSitesObserver {
34 explicit TestTopSitesObserver(Profile* profile, history::TopSites* top_sites);
35 virtual ~TestTopSitesObserver();
37 virtual void TopSitesLoaded(history::TopSites* top_sites) OVERRIDE;
38 virtual void TopSitesChanged(history::TopSites* top_sites) OVERRIDE;
42 history::TopSites* top_sites_;
45 TestTopSitesObserver::~TestTopSitesObserver() {
46 top_sites_->RemoveObserver(this);
49 TestTopSitesObserver::TestTopSitesObserver(Profile* profile,
50 history::TopSites* top_sites)
51 : profile_(profile), top_sites_(top_sites) {
53 top_sites_->AddObserver(this);
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));
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());
74 // Used by WaitForHistory, see it for details.
75 class WaitForHistoryTask : public HistoryDBTask {
77 WaitForHistoryTask() {}
79 virtual bool RunOnDBThread(HistoryBackend* backend,
80 HistoryDatabase* db) OVERRIDE {
84 virtual void DoneRunOnMainThread() OVERRIDE {
85 base::MessageLoop::current()->Quit();
89 virtual ~WaitForHistoryTask() {}
91 DISALLOW_COPY_AND_ASSIGN(WaitForHistoryTask);
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 {
100 : number_of_callbacks_(0),
102 weak_ptr_factory_(this) {}
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);
110 // Queries top sites, including potentially forced URLs if
111 // |include_forced_urls| is true.
112 void QueryAllTopSites(TopSitesImpl* top_sites,
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_) {
122 base::MessageLoop::current()->Run();
126 void CancelRequest() {
127 weak_ptr_factory_.InvalidateWeakPtrs();
130 void set_urls(const MostVisitedURLList& urls) { urls_ = urls; }
131 const MostVisitedURLList& urls() const { return urls_; }
133 int number_of_callbacks() const { return number_of_callbacks_; }
136 // Callback for TopSitesImpl::GetMostVisitedURLs.
137 void OnTopSitesAvailable(const history::MostVisitedURLList& data) {
139 number_of_callbacks_++;
141 base::MessageLoop::current()->Quit();
146 MostVisitedURLList urls_;
147 int number_of_callbacks_;
149 base::WeakPtrFactory<TopSitesQuerier> weak_ptr_factory_;
151 DISALLOW_COPY_AND_ASSIGN(TopSitesQuerier);
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(),
159 return image.get() ? *image : SkBitmap();
162 // Returns true if t1 and t2 contain the same data.
163 bool ThumbnailsAreEqual(base::RefCountedMemory* t1,
164 base::RefCountedMemory* t2) {
167 if (t1->size() != t2->size())
169 return !memcmp(t1->front(), t2->front(), t1->size());
174 class TopSitesImplTest : public HistoryUnitTestBase {
177 : ui_thread_(BrowserThread::UI, &message_loop_),
178 db_thread_(BrowserThread::DB, &message_loop_) {
181 virtual void SetUp() {
182 profile_.reset(new TestingProfile);
183 if (CreateHistoryAndTopSites()) {
184 ASSERT_TRUE(profile_->CreateHistoryService(false, false));
185 CreateTopSitesAndObserver();
186 profile_->BlockUntilTopSitesLoaded();
190 virtual void TearDown() {
191 top_sites_observer_.reset();
195 // Returns true if history and top sites should be created in SetUp.
196 virtual bool CreateHistoryAndTopSites() {
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();
207 // Creates a bitmap of the specified color. Caller takes ownership.
208 gfx::Image CreateBitmap(SkColor color) {
210 thumbnail.allocN32Pixels(4, 4);
211 thumbnail.eraseColor(color);
212 return gfx::Image::CreateFrom1xBitmap(thumbnail); // adds ref.
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();
221 RecreateTopSitesAndBlock();
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()),
230 base::MessageLoop::current()->Run();
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();
242 TopSitesImpl* top_sites() {
243 return static_cast<TopSitesImpl*>(profile_->GetTopSites());
245 TestingProfile* profile() {return profile_.get();}
246 HistoryService* history_service() {
247 return HistoryServiceFactory::GetForProfile(profile_.get(),
248 Profile::EXPLICIT_ACCESS);
251 MostVisitedURLList GetPrepopulatePages() {
252 return top_sites()->GetPrepopulatePages();
255 // Returns true if the TopSitesQuerier contains the prepopulate data starting
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 " <<
268 // Used for callbacks from history.
269 void EmptyCallback() {
272 // Quit the current message loop when invoked. Useful when running a nested
274 void QuitCallback() {
275 base::MessageLoop::current()->Quit();
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,
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,
296 history_service()->SetPageTitle(url, title);
299 // Adds a page to history.
300 void AddPageToHistory(const GURL& url,
301 const base::string16& title,
302 const history::RedirectList& redirects,
304 history_service()->AddPage(
305 url, time, reinterpret_cast<ContextID>(1), 0, GURL(),
306 redirects, ui::PAGE_TRANSITION_TYPED, history::SOURCE_BROWSED,
308 history_service()->SetPageTitle(url, title);
312 void DeleteURL(const GURL& url) {
313 history_service()->DeleteURL(url);
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);
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();
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);
338 void SetTopSites(const MostVisitedURLList& new_top_sites) {
339 top_sites()->SetTopSites(new_top_sites);
342 bool AddForcedURL(const GURL& url, base::Time time) {
343 return top_sites()->AddForcedURL(url, time);
346 void StartQueryForMostVisited() {
347 top_sites()->StartQueryForMostVisited();
350 void SetLastNumUrlsChanged(size_t value) {
351 top_sites()->last_num_urls_changed_ = value;
354 size_t last_num_urls_changed() { return top_sites()->last_num_urls_changed_; }
356 base::TimeDelta GetUpdateDelay() {
357 return top_sites()->GetUpdateDelay();
360 bool IsTopSitesLoaded() { return top_sites()->loaded_; }
362 bool AddPrepopulatedPages(MostVisitedURLList* urls) {
363 return top_sites()->AddPrepopulatedPages(urls, 0u);
366 void EmptyThreadSafeCache() {
367 base::AutoLock lock(top_sites()->lock_);
368 MostVisitedURLList empty;
369 top_sites()->thread_safe_cache_->SetTopSites(empty);
372 void CreateTopSitesAndObserver() {
373 if (top_sites_observer_)
374 top_sites_observer_.reset();
376 profile_->CreateTopSites();
377 top_sites_observer_.reset(
378 new TestTopSitesObserver(profile_.get(), profile_->GetTopSites()));
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_;
390 // To cancel TopSitesBackend tasks.
391 base::CancelableTaskTracker top_sites_tracker_;
393 DISALLOW_COPY_AND_ASSIGN(TopSitesImplTest);
394 }; // Class TopSitesImplTest
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,
402 mv.redirects.push_back(url);
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,
410 double last_forced_time) {
413 mv.last_forced_time = base::Time::FromJsTime(last_forced_time);
414 mv.redirects.push_back(url);
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) {
424 mv.url = redirect_dest;
425 mv.redirects.push_back(redirect_source);
426 mv.redirects.push_back(redirect_dest);
430 // Tests GetCanonicalURL.
431 TEST_F(TopSitesImplTest, GetCanonicalURL) {
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/");
439 std::vector<MostVisitedURL> most_visited;
440 AppendMostVisitedURLWithRedirect(&most_visited, source, dest);
441 AppendMostVisitedURL(&most_visited, news);
442 SetTopSites(most_visited);
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);
448 // Easy case, there are no redirects and the exact URL is stored.
449 result = GetCanonicalURL(news);
450 EXPECT_EQ(news, result);
452 // The URL in question is the source URL in a redirect list.
453 result = GetCanonicalURL(source);
454 EXPECT_EQ(dest, result);
456 // The URL in question is the destination of a redirect.
457 result = GetCanonicalURL(dest);
458 EXPECT_EQ(dest, result);
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/");
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)
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)
480 history::TopSitesDelta delta;
481 history::TopSitesImpl::DiffMostVisited(old_list, new_list, &delta);
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);
489 ASSERT_EQ(1u, delta.deleted.size());
490 EXPECT_TRUE(gets_deleted_1 == delta.deleted[0].url);
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);
497 // Tests DiffMostVisited with forced URLs.
498 TEST_F(TopSitesImplTest, DiffMostVisitedWithForced) {
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/");
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/");
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);
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);
535 history::TopSitesDelta delta;
536 history::TopSitesImpl::DiffMostVisited(old_list, new_list, &delta);
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);
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);
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());
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/");
567 std::vector<MostVisitedURL> list;
568 AppendMostVisitedURL(&list, url2);
572 mv.redirects.push_back(url1a);
573 mv.redirects.push_back(url1b);
576 // Save our most visited data containing that one site.
579 // Create a dummy thumbnail.
580 gfx::Image thumbnail(CreateBitmap(SK_ColorWHITE));
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);
587 // Setting the thumbnail for invalid pages should fail.
588 EXPECT_FALSE(top_sites()->SetPageThumbnail(invalid_url,
589 thumbnail, medium_score));
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));
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));
605 // Makes sure a thumbnail is correctly removed when the page is removed.
606 TEST_F(TopSitesImplTest, ThumbnailRemoved) {
607 GURL url("http://google.com/");
609 // Configure top sites with 'google.com'.
610 std::vector<MostVisitedURL> list;
611 AppendMostVisitedURL(&list, url);
614 // Create a dummy thumbnail.
615 gfx::Image thumbnail(CreateBitmap(SK_ColorRED));
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);
622 // Set the thumbnail.
623 EXPECT_TRUE(top_sites()->SetPageThumbnail(url, thumbnail, medium_score));
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()));
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));
636 // Tests GetPageThumbnail.
637 TEST_F(TopSitesImplTest, GetPageThumbnail) {
638 MostVisitedURLList url_list;
640 url1.url = GURL("http://asdf.com");
641 url1.redirects.push_back(url1.url);
642 url_list.push_back(url1);
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);
650 SetTopSites(url_list);
652 // Create a dummy thumbnail.
653 gfx::Image thumbnail(CreateBitmap(SK_ColorWHITE));
654 ThumbnailScore score(0.5, true, true, base::Time::Now());
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));
660 EXPECT_TRUE(top_sites()->SetPageThumbnail(GURL("http://gmail.com"),
662 EXPECT_TRUE(top_sites()->GetPageThumbnail(GURL("http://gmail.com"),
665 // Get a thumbnail via a redirect.
666 EXPECT_TRUE(top_sites()->GetPageThumbnail(GURL("http://mail.google.com"),
670 EXPECT_TRUE(top_sites()->SetPageThumbnail(GURL("http://mail.google.com"),
672 EXPECT_TRUE(top_sites()->GetPageThumbnail(url2.url, false, &result));
674 EXPECT_TRUE(ThumbnailEqualsBytes(thumbnail, result.get()));
677 // Tests GetMostVisitedURLs.
678 TEST_F(TopSitesImplTest, GetMostVisited) {
679 GURL news("http://news.google.com/");
680 GURL google("http://google.com/");
682 AddPageToHistory(news);
683 AddPageToHistory(google);
685 StartQueryForMostVisited();
688 TopSitesQuerier querier;
689 querier.QueryTopSites(top_sites(), false);
691 ASSERT_EQ(1, querier.number_of_callbacks());
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));
700 // Makes sure changes done to top sites get mirrored to the db.
701 TEST_F(TopSitesImplTest, SaveToDB) {
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"));
710 // Add asdf_url to history.
711 AddPageToHistory(asdf_url, asdf_title);
713 // Make TopSites reread from the db.
714 StartQueryForMostVisited();
718 gfx::Image tmp_bitmap(CreateBitmap(SK_ColorBLUE));
719 ASSERT_TRUE(top_sites()->SetPageThumbnail(asdf_url, tmp_bitmap,
722 RecreateTopSitesAndBlock();
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));
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()));
738 url2.url = google_url;
739 url2.title = google_title;
740 url2.redirects.push_back(url2.url);
742 AddPageToHistory(url2.url, url2.title);
744 // Add new thumbnail at rank 0 and shift the other result to 1.
745 ASSERT_TRUE(top_sites()->SetPageThumbnail(google_url,
749 // Make TopSites reread from the db.
750 RefreshTopSitesAndRecreate();
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));
764 // Makes sure forced URLs in top sites get mirrored to the db.
765 TEST_F(TopSitesImplTest, SaveForcedToDB) {
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"));
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);
784 gfx::Image red_thumbnail(CreateBitmap(SK_ColorRED));
785 ASSERT_TRUE(top_sites()->SetPageThumbnail(
786 GURL("http://forced1"), red_thumbnail, ThumbnailScore()));
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"));
792 // Force-flush the cache to ensure we don't reread from it inadvertently.
793 EmptyThreadSafeCache();
795 // Make TopSites reread from the db.
796 StartQueryForMostVisited();
799 TopSitesQuerier querier;
800 querier.QueryAllTopSites(top_sites(), true, true);
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);
821 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier, 4));
824 // More permutations of saving to db.
825 TEST_F(TopSitesImplTest, RealDatabase) {
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"));
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()));
843 base::Time add_time(base::Time::Now());
844 AddPageToHistory(url.url, url.title, url.redirects, add_time);
846 RefreshTopSitesAndRecreate();
849 TopSitesQuerier querier;
850 querier.QueryTopSites(top_sites(), false);
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));
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()));
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);
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));
875 gfx::Image google_thumbnail(CreateBitmap(SK_ColorBLUE));
876 ASSERT_TRUE(top_sites()->SetPageThumbnail(
877 url2.url, google_thumbnail, ThumbnailScore()));
879 RefreshTopSitesAndRecreate();
882 scoped_refptr<base::RefCountedMemory> read_data;
883 TopSitesQuerier querier;
884 querier.QueryTopSites(top_sites(), false);
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()));
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));
898 gfx::Image weewar_bitmap(CreateBitmap(SK_ColorYELLOW));
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);
905 // 1. Set to weewar. (Writes the thumbnail to the DB.)
906 EXPECT_TRUE(top_sites()->SetPageThumbnail(google3_url,
909 RefreshTopSitesAndRecreate();
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()));
916 gfx::Image green_bitmap(CreateBitmap(SK_ColorGREEN));
918 // 2. Set to google - low score.
919 EXPECT_FALSE(top_sites()->SetPageThumbnail(google3_url,
923 // 3. Set to google - high score.
924 EXPECT_TRUE(top_sites()->SetPageThumbnail(google1_url,
928 // Check that the thumbnail was updated.
929 RefreshTopSitesAndRecreate();
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()));
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"));
946 AddPageToHistory(google1_url, google_title);
947 AddPageToHistory(news_url, news_title);
949 RefreshTopSitesAndRecreate();
952 TopSitesQuerier querier;
953 querier.QueryTopSites(top_sites(), false);
955 ASSERT_EQ(GetPrepopulatePages().size() + 2, querier.urls().size());
960 // Wait for history to process the deletion.
964 TopSitesQuerier querier;
965 querier.QueryTopSites(top_sites(), false);
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));
972 // Now reload. This verifies topsites actually wrote the deletion to disk.
973 RefreshTopSitesAndRecreate();
976 TopSitesQuerier querier;
977 querier.QueryTopSites(top_sites(), false);
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));
984 DeleteURL(google1_url);
986 // Wait for history to process the deletion.
990 TopSitesQuerier querier;
991 querier.QueryTopSites(top_sites(), false);
993 ASSERT_EQ(GetPrepopulatePages().size(), querier.urls().size());
994 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier, 0));
997 // Now reload. This verifies topsites actually wrote the deletion to disk.
998 RefreshTopSitesAndRecreate();
1001 TopSitesQuerier querier;
1002 querier.QueryTopSites(top_sites(), false);
1004 ASSERT_EQ(GetPrepopulatePages().size(), querier.urls().size());
1005 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(querier, 0));
1009 // Makes sure GetUpdateDelay is updated appropriately.
1010 TEST_F(TopSitesImplTest, GetUpdateDelay) {
1011 SetLastNumUrlsChanged(0);
1012 EXPECT_EQ(30, GetUpdateDelay().InSeconds());
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);
1021 SetTopSites(url_list);
1022 EXPECT_EQ(20u, last_num_urls_changed());
1023 SetLastNumUrlsChanged(0);
1024 EXPECT_EQ(60, GetUpdateDelay().InMinutes());
1026 SetLastNumUrlsChanged(3);
1027 EXPECT_EQ(52, GetUpdateDelay().InMinutes());
1029 SetLastNumUrlsChanged(20);
1030 EXPECT_EQ(1, GetUpdateDelay().InMinutes());
1033 // Verifies that callbacks are notified correctly if requested before top sites
1035 TEST_F(TopSitesImplTest, NotifyCallbacksWhenLoaded) {
1036 // Recreate top sites. It won't be loaded now.
1037 CreateTopSitesAndObserver();
1039 EXPECT_FALSE(IsTopSitesLoaded());
1041 TopSitesQuerier querier1;
1042 TopSitesQuerier querier2;
1043 TopSitesQuerier querier3;
1045 // Starts the queries.
1046 querier1.QueryTopSites(top_sites(), false);
1047 querier2.QueryTopSites(top_sites(), false);
1048 querier3.QueryTopSites(top_sites(), false);
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());
1055 // Wait for loading to complete.
1056 profile()->BlockUntilTopSitesLoaded();
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());
1066 // Reset the top sites.
1067 MostVisitedURLList pages;
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);
1077 // Recreate top sites. It won't be loaded now.
1078 CreateTopSitesAndObserver();
1080 EXPECT_FALSE(IsTopSitesLoaded());
1082 TopSitesQuerier querier4;
1085 querier4.QueryTopSites(top_sites(), false);
1087 // We shouldn't have gotten a callback.
1088 EXPECT_EQ(0, querier4.number_of_callbacks());
1090 // Wait for loading to complete.
1091 profile()->BlockUntilTopSitesLoaded();
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());
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));
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);
1108 TopSitesQuerier querier5;
1109 querier5.QueryTopSites(top_sites(), true);
1111 EXPECT_EQ(1, querier5.number_of_callbacks());
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));
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();
1125 EXPECT_FALSE(IsTopSitesLoaded());
1127 TopSitesQuerier querier1;
1128 TopSitesQuerier querier2;
1130 // Starts the queries.
1131 querier1.QueryTopSites(top_sites(), false);
1132 querier2.QueryTopSites(top_sites(), false);
1134 // We shouldn't have gotten a callback.
1135 EXPECT_EQ(0, querier1.number_of_callbacks());
1136 EXPECT_EQ(0, querier2.number_of_callbacks());
1138 querier2.CancelRequest();
1140 // Wait for loading to complete.
1141 profile()->BlockUntilTopSitesLoaded();
1143 // The first callback should succeed.
1144 EXPECT_EQ(1, querier1.number_of_callbacks());
1145 EXPECT_EQ(GetPrepopulatePages().size(), querier1.urls().size());
1147 // And the canceled callback should not be notified.
1148 EXPECT_EQ(0, querier2.number_of_callbacks());
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/");
1158 // Create a dummy thumbnail.
1159 gfx::Image thumbnail(CreateBitmap(SK_ColorRED));
1161 ThumbnailScore medium_score(0.5, true, true, base::Time::Now());
1163 // Don't store thumbnails for Javascript URLs.
1164 EXPECT_FALSE(top_sites()->SetPageThumbnail(invalid_url,
1167 // Store thumbnails for unknown (but valid) URLs temporarily - calls
1168 // AddTemporaryThumbnail.
1169 EXPECT_TRUE(top_sites()->SetPageThumbnail(unknown_url,
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,
1180 EXPECT_TRUE(medium_score.Equals(out_score));
1182 std::vector<MostVisitedURL> list;
1185 mv.url = unknown_url;
1186 mv.redirects.push_back(mv.url);
1187 mv.redirects.push_back(url1a);
1188 mv.redirects.push_back(url1b);
1191 // Update URLs. This should result in using thumbnail.
1194 ASSERT_TRUE(top_sites()->GetPageThumbnail(unknown_url, false, &out));
1195 EXPECT_TRUE(ThumbnailEqualsBytes(thumbnail, out.get()));
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);
1210 EXPECT_FALSE(top_sites()->IsBlacklisted(GURL("http://bbc.com/")));
1212 // Blacklist google.com.
1213 top_sites()->AddBlacklistedURL(GURL("http://google.com/"));
1215 GURL prepopulate_url = GetPrepopulatePages()[0].url;
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));
1222 // Make sure the blacklisted site isn't returned in the results.
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));
1231 // Recreate top sites and make sure blacklisted url was correctly read.
1232 RecreateTopSitesAndBlock();
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));
1241 // Blacklist one of the prepopulate urls.
1242 top_sites()->AddBlacklistedURL(prepopulate_url);
1243 EXPECT_TRUE(top_sites()->HasBlacklistedItems());
1245 // Make sure the blacklisted prepopulate url isn't returned.
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());
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/")));
1260 // Make sure google is returned now.
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());
1272 EXPECT_EQ(1u, GetPrepopulatePages().size());
1275 // Remove all blacklisted sites.
1276 top_sites()->ClearBlacklistedURLs();
1277 EXPECT_FALSE(top_sites()->HasBlacklistedItems());
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));
1289 // Makes sure prepopulated pages exist.
1290 TEST_F(TopSitesImplTest, AddPrepopulatedPages) {
1292 q.QueryTopSites(top_sites(), true);
1293 EXPECT_EQ(GetPrepopulatePages().size(), q.urls().size());
1294 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(q, 0));
1296 MostVisitedURLList pages = q.urls();
1297 EXPECT_FALSE(AddPrepopulatedPages(&pages));
1299 EXPECT_EQ(GetPrepopulatePages().size(), pages.size());
1301 ASSERT_NO_FATAL_FAILURE(ContainsPrepopulatePages(q, 0));
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;
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);
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()));
1343 url << "http://newnonforced/" << i;
1344 AppendMostVisitedURL(&new_url_list, GURL(url.str()));
1347 // Set the initial list of URLs.
1348 SetTopSites(old_url_list);
1349 EXPECT_EQ(kNumOldForcedURLs + kNumNonForcedURLs, last_num_urls_changed());
1351 TopSitesQuerier querier;
1352 // Query only non-forced URLs first.
1353 querier.QueryTopSites(top_sites(), false);
1354 ASSERT_EQ(kNumNonForcedURLs, querier.urls().size());
1357 EXPECT_EQ("http://oldnonforced/0", querier.urls()[0].url.spec());
1360 querier.QueryAllTopSites(top_sites(), false, true);
1361 EXPECT_EQ(kNumOldForcedURLs + kNumNonForcedURLs, querier.urls().size());
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());
1368 // Set the new list of URLs.
1369 SetTopSites(new_url_list);
1372 querier.QueryAllTopSites(top_sites(), false, true);
1374 // We should have reached the maximum of 20 forced URLs.
1375 ASSERT_EQ(20 + kNumNonForcedURLs, querier.urls().size());
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());
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());
1427 TEST_F(TopSitesImplTest, SetForcedTopSitesWithCollisions) {
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);
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"),
1448 AppendMostVisitedURL(&new_url_list, GURL("http://collision/2"));
1449 AppendMostVisitedURL(&new_url_list, GURL("http://url/3"));
1450 SetTopSites(new_url_list);
1453 TopSitesQuerier querier;
1454 querier.QueryAllTopSites(top_sites(), false, true);
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));
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);
1483 // Set the new list of URLs to be exactly the same.
1484 SetTopSites(MostVisitedURLList(url_list));
1487 TopSitesQuerier querier;
1488 querier.QueryAllTopSites(top_sites(), false, true);
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));
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);
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);
1514 TopSitesQuerier querier;
1515 querier.QueryAllTopSites(top_sites(), false, true);
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));
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);
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)));
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));
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)));
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());
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());
1598 EXPECT_EQ("http://forced/5", querier.urls()[3].url.spec());
1599 EXPECT_EQ("http://forced/3", querier.urls()[4].url.spec());
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()));
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"));
1611 EXPECT_TRUE(AddForcedURL(GURL("http://forced/5"),
1612 base::Time::FromJsTime(6000)));
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();
1628 } // namespace history