// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/history/history_backend.h"

#include <algorithm>
#include <set>
#include <vector>

#include "base/basictypes.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/strings/string16.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/bookmarks/bookmark_model_factory.h"
#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
#include "chrome/browser/bookmarks/bookmark_utils.h"
#include "chrome/browser/history/history_notifications.h"
#include "chrome/browser/history/history_service.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/history/in_memory_database.h"
#include "chrome/browser/history/in_memory_history_backend.h"
#include "chrome/browser/history/visit_filter.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/importer/imported_favicon_usage.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
#include "content/public/test/test_browser_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

using base::Time;
using base::TimeDelta;

// This file only tests functionality where it is most convenient to call the
// backend directly. Most of the history backend functions are tested by the
// history unit test. Because of the elaborate callbacks involved, this is no
// harder than calling it directly for many things.

namespace {

static const gfx::Size kTinySize = gfx::Size(10, 10);
static const gfx::Size kSmallSize = gfx::Size(16, 16);
static const gfx::Size kLargeSize = gfx::Size(32, 32);

// Comparison functions as to make it easier to check results of
// GetFaviconBitmaps() and GetIconMappingsForPageURL().
bool IconMappingLessThan(const history::IconMapping& a,
                         const history::IconMapping& b) {
  return a.icon_url < b.icon_url;
}

bool FaviconBitmapLessThan(const history::FaviconBitmap& a,
                           const history::FaviconBitmap& b) {
  return a.pixel_size.GetArea() < b.pixel_size.GetArea();
}

}  // namespace

namespace history {

class HistoryBackendTest;

// This must be a separate object since HistoryBackend manages its lifetime.
// This just forwards the messages we're interested in to the test object.
class HistoryBackendTestDelegate : public HistoryBackend::Delegate {
 public:
  explicit HistoryBackendTestDelegate(HistoryBackendTest* test) : test_(test) {}

  virtual void NotifyProfileError(int backend_id,
                                  sql::InitStatus init_status) OVERRIDE {}
  virtual void SetInMemoryBackend(int backend_id,
                                  InMemoryHistoryBackend* backend) OVERRIDE;
  virtual void BroadcastNotifications(int type,
                                      HistoryDetails* details) OVERRIDE;
  virtual void DBLoaded(int backend_id) OVERRIDE;
  virtual void NotifyVisitDBObserversOnAddVisit(
      const BriefVisitInfo& info) OVERRIDE {}

 private:
  // Not owned by us.
  HistoryBackendTest* test_;

  DISALLOW_COPY_AND_ASSIGN(HistoryBackendTestDelegate);
};

class HistoryBackendCancelableRequest
    : public CancelableRequestProvider,
      public CancelableRequestConsumerTSimple<int> {
 public:
  HistoryBackendCancelableRequest() {}

  template<class RequestType>
  CancelableRequestProvider::Handle MockScheduleOfRequest(
      RequestType* request) {
    AddRequest(request, this);
    return request->handle();
  }
};

class HistoryBackendTest : public testing::Test {
 public:
  HistoryBackendTest()
      : bookmark_model_(NULL),
        loaded_(false),
        num_broadcasted_notifications_(0),
        ui_thread_(content::BrowserThread::UI, &message_loop_) {
  }

  virtual ~HistoryBackendTest() {
  }

  // Callback for QueryMostVisited.
  void OnQueryMostVisited(CancelableRequestProvider::Handle handle,
                          history::MostVisitedURLList data) {
    most_visited_list_.swap(data);
  }

  // Callback for QueryFiltered.
  void OnQueryFiltered(CancelableRequestProvider::Handle handle,
                       const history::FilteredURLList& data) {
    filtered_list_ = data;
  }

  const history::MostVisitedURLList& get_most_visited_list() const {
    return most_visited_list_;
  }

  const history::FilteredURLList& get_filtered_list() const {
    return filtered_list_;
  }

  int num_broadcasted_notifications() const {
    return num_broadcasted_notifications_;
  }

 protected:
  scoped_refptr<HistoryBackend> backend_;  // Will be NULL on init failure.
  scoped_ptr<InMemoryHistoryBackend> mem_backend_;

  void AddRedirectChain(const char* sequence[], int page_id) {
    AddRedirectChainWithTransitionAndTime(sequence, page_id,
                                          content::PAGE_TRANSITION_LINK,
                                          Time::Now());
  }

  void AddRedirectChainWithTransitionAndTime(
      const char* sequence[],
      int page_id,
      content::PageTransition transition,
      base::Time time) {
    history::RedirectList redirects;
    for (int i = 0; sequence[i] != NULL; ++i)
      redirects.push_back(GURL(sequence[i]));

    int int_scope = 1;
    void* scope = 0;
    memcpy(&scope, &int_scope, sizeof(int_scope));
    history::HistoryAddPageArgs request(
        redirects.back(), time, scope, page_id, GURL(),
        redirects, transition, history::SOURCE_BROWSED,
        true);
    backend_->AddPage(request);
  }

  // Adds CLIENT_REDIRECT page transition.
  // |url1| is the source URL and |url2| is the destination.
  // |did_replace| is true if the transition is non-user initiated and the
  // navigation entry for |url2| has replaced that for |url1|. The possibly
  // updated transition code of the visit records for |url1| and |url2| is
  // returned by filling in |*transition1| and |*transition2|, respectively.
  // |time| is a time of the redirect.
  void  AddClientRedirect(const GURL& url1, const GURL& url2, bool did_replace,
                          base::Time time,
                          int* transition1, int* transition2) {
    void* const dummy_scope = reinterpret_cast<void*>(0x87654321);
    history::RedirectList redirects;
    if (url1.is_valid())
      redirects.push_back(url1);
    if (url2.is_valid())
      redirects.push_back(url2);
    HistoryAddPageArgs request(
        url2, time, dummy_scope, 0, url1,
        redirects, content::PAGE_TRANSITION_CLIENT_REDIRECT,
        history::SOURCE_BROWSED, did_replace);
    backend_->AddPage(request);

    *transition1 = getTransition(url1);
    *transition2 = getTransition(url2);
  }

  int getTransition(const GURL& url) {
    if (!url.is_valid())
      return 0;
    URLRow row;
    URLID id = backend_->db()->GetRowForURL(url, &row);
    VisitVector visits;
    EXPECT_TRUE(backend_->db()->GetVisitsForURL(id, &visits));
    return visits[0].transition;
  }

  base::FilePath getTestDir() {
    return test_dir_;
  }

  // Returns a gfx::Size vector with small size.
  const std::vector<gfx::Size> GetSizesSmall() {
    std::vector<gfx::Size> sizes_small;
    sizes_small.push_back(kSmallSize);
    return sizes_small;
  }

  // Returns a gfx::Size vector with large size.
  const std::vector<gfx::Size> GetSizesLarge() {
    std::vector<gfx::Size> sizes_large;
    sizes_large.push_back(kLargeSize);
    return sizes_large;
  }

  // Returns a gfx::Size vector with small and large sizes.
  const std::vector<gfx::Size> GetSizesSmallAndLarge() {
    std::vector<gfx::Size> sizes_small_and_large;
    sizes_small_and_large.push_back(kSmallSize);
    sizes_small_and_large.push_back(kLargeSize);
    return sizes_small_and_large;
  }

  // Returns a gfx::Size vector with tiny, small and large sizes.
  const std::vector<gfx::Size> GetSizesTinySmallAndLarge() {
    std::vector<gfx::Size> sizes_tiny_small_and_large;
    sizes_tiny_small_and_large.push_back(kTinySize);
    sizes_tiny_small_and_large.push_back(kSmallSize);
    sizes_tiny_small_and_large.push_back(kLargeSize);
    return sizes_tiny_small_and_large;
  }

  // Returns 1x and 2x scale factors.
  const std::vector<ui::ScaleFactor> GetScaleFactors1x2x() {
    std::vector<ui::ScaleFactor> scale_factors_1x_2x;
    scale_factors_1x_2x.push_back(ui::SCALE_FACTOR_100P);
    scale_factors_1x_2x.push_back(ui::SCALE_FACTOR_200P);
    return scale_factors_1x_2x;
  }

  // Returns the number of icon mappings of |icon_type| to |page_url|.
  size_t NumIconMappingsForPageURL(const GURL& page_url,
                                   chrome::IconType icon_type) {
    std::vector<IconMapping> icon_mappings;
    backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url, icon_type,
                                                       &icon_mappings);
    return icon_mappings.size();
  }

  // Returns the icon mappings for |page_url| sorted alphabetically by icon
  // URL in ascending order. Returns true if there is at least one icon
  // mapping.
  bool GetSortedIconMappingsForPageURL(
      const GURL& page_url,
      std::vector<IconMapping>* icon_mappings) {
    if (!backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
        icon_mappings)) {
      return false;
    }
    std::sort(icon_mappings->begin(), icon_mappings->end(),
              IconMappingLessThan);
    return true;
  }

  // Returns the favicon bitmaps for |icon_id| sorted by pixel size in
  // ascending order. Returns true if there is at least one favicon bitmap.
  bool GetSortedFaviconBitmaps(chrome::FaviconID icon_id,
                               std::vector<FaviconBitmap>* favicon_bitmaps) {
    if (!backend_->thumbnail_db_->GetFaviconBitmaps(icon_id, favicon_bitmaps))
      return false;
    std::sort(favicon_bitmaps->begin(), favicon_bitmaps->end(),
              FaviconBitmapLessThan);
    return true;
  }

  // Returns true if there is exactly one favicon bitmap associated to
  // |favicon_id|. If true, returns favicon bitmap in output parameter.
  bool GetOnlyFaviconBitmap(const chrome::FaviconID icon_id,
                            FaviconBitmap* favicon_bitmap) {
    std::vector<FaviconBitmap> favicon_bitmaps;
    if (!backend_->thumbnail_db_->GetFaviconBitmaps(icon_id, &favicon_bitmaps))
      return false;
    if (favicon_bitmaps.size() != 1)
      return false;
    *favicon_bitmap = favicon_bitmaps[0];
    return true;
  }

  // Generates |favicon_bitmap_data| with entries for the icon_urls and sizes
  // specified. The bitmap_data for entries are lowercase letters of the
  // alphabet starting at 'a' for the entry at index 0.
  void GenerateFaviconBitmapData(
      const GURL& icon_url1,
      const std::vector<gfx::Size>& icon_url1_sizes,
      std::vector<chrome::FaviconBitmapData>* favicon_bitmap_data) {
    GenerateFaviconBitmapData(icon_url1, icon_url1_sizes, GURL(),
                              std::vector<gfx::Size>(), favicon_bitmap_data);
  }

  void GenerateFaviconBitmapData(
      const GURL& icon_url1,
      const std::vector<gfx::Size>& icon_url1_sizes,
      const GURL& icon_url2,
      const std::vector<gfx::Size>& icon_url2_sizes,
      std::vector<chrome::FaviconBitmapData>* favicon_bitmap_data) {
    favicon_bitmap_data->clear();

    char bitmap_char = 'a';
    for (size_t i = 0; i < icon_url1_sizes.size(); ++i) {
      std::vector<unsigned char> data;
      data.push_back(bitmap_char);
      chrome::FaviconBitmapData bitmap_data_element;
      bitmap_data_element.bitmap_data =
          base::RefCountedBytes::TakeVector(&data);
      bitmap_data_element.pixel_size = icon_url1_sizes[i];
      bitmap_data_element.icon_url = icon_url1;
      favicon_bitmap_data->push_back(bitmap_data_element);

      ++bitmap_char;
    }

    for (size_t i = 0; i < icon_url2_sizes.size(); ++i) {
      std::vector<unsigned char> data;
      data.push_back(bitmap_char);
      chrome::FaviconBitmapData bitmap_data_element;
      bitmap_data_element.bitmap_data =
          base::RefCountedBytes::TakeVector(&data);
      bitmap_data_element.pixel_size = icon_url2_sizes[i];
      bitmap_data_element.icon_url = icon_url2;
      favicon_bitmap_data->push_back(bitmap_data_element);

      ++bitmap_char;
    }
  }

  // Returns true if |bitmap_data| is equal to |expected_data|.
  bool BitmapDataEqual(char expected_data,
                       scoped_refptr<base::RefCountedMemory> bitmap_data) {
    return bitmap_data.get() &&
           bitmap_data->size() == 1u &&
           *bitmap_data->front() == expected_data;
  }

  BookmarkModel bookmark_model_;

 protected:
  // testing::Test
  virtual void SetUp() {
    if (!base::CreateNewTempDirectory(FILE_PATH_LITERAL("BackendTest"),
                                      &test_dir_))
      return;
    backend_ = new HistoryBackend(test_dir_,
                                  0,
                                  new HistoryBackendTestDelegate(this),
                                  &bookmark_model_);
    backend_->Init(std::string(), false);
  }

  bool loaded_;

 private:
  friend class HistoryBackendTestDelegate;

  virtual void TearDown() {
    if (backend_.get())
      backend_->Closing();
    backend_ = NULL;
    mem_backend_.reset();
    base::DeleteFile(test_dir_, true);
    base::RunLoop().RunUntilIdle();
  }

  void SetInMemoryBackend(int backend_id, InMemoryHistoryBackend* backend) {
    mem_backend_.reset(backend);
  }

  void BroadcastNotifications(int type,
                              HistoryDetails* details) {
    ++num_broadcasted_notifications_;

    // Send the notifications directly to the in-memory database.
    content::Details<HistoryDetails> det(details);
    mem_backend_->Observe(type, content::Source<HistoryBackendTest>(NULL), det);

    // The backend passes ownership of the details pointer to us.
    delete details;
  }

  // The number of notifications which were broadcasted.
  int num_broadcasted_notifications_;

  base::MessageLoop message_loop_;
  base::FilePath test_dir_;
  history::MostVisitedURLList most_visited_list_;
  history::FilteredURLList filtered_list_;
  content::TestBrowserThread ui_thread_;
};

void HistoryBackendTestDelegate::SetInMemoryBackend(int backend_id,
    InMemoryHistoryBackend* backend) {
  test_->SetInMemoryBackend(backend_id, backend);
}

void HistoryBackendTestDelegate::BroadcastNotifications(
    int type,
    HistoryDetails* details) {
  test_->BroadcastNotifications(type, details);
}

void HistoryBackendTestDelegate::DBLoaded(int backend_id) {
  test_->loaded_ = true;
}

// http://crbug.com/114287
#if defined(OS_WIN)
#define MAYBE_Loaded DISABLED_Loaded
#else
#define MAYBE_Loaded Loaded
#endif // defined(OS_WIN)
TEST_F(HistoryBackendTest, MAYBE_Loaded) {
  ASSERT_TRUE(backend_.get());
  ASSERT_TRUE(loaded_);
}

TEST_F(HistoryBackendTest, DeleteAll) {
  ASSERT_TRUE(backend_.get());

  // Add two favicons, each with two bitmaps. Note that we add favicon2 before
  // adding favicon1. This is so that favicon1 one gets ID 2 autoassigned to
  // the database, which will change when the other one is deleted. This way
  // we can test that updating works properly.
  GURL favicon_url1("http://www.google.com/favicon.ico");
  GURL favicon_url2("http://news.google.com/favicon.ico");
  chrome::FaviconID favicon2 = backend_->thumbnail_db_->AddFavicon(favicon_url2,
      chrome::FAVICON);
  chrome::FaviconID favicon1 = backend_->thumbnail_db_->AddFavicon(favicon_url1,
      chrome::FAVICON);

  std::vector<unsigned char> data;
  data.push_back('a');
  EXPECT_TRUE(backend_->thumbnail_db_->AddFaviconBitmap(favicon1,
      new base::RefCountedBytes(data), Time::Now(), kSmallSize));
  data[0] = 'b';
  EXPECT_TRUE(backend_->thumbnail_db_->AddFaviconBitmap(favicon1,
     new base::RefCountedBytes(data), Time::Now(), kLargeSize));

  data[0] = 'c';
  EXPECT_TRUE(backend_->thumbnail_db_->AddFaviconBitmap(favicon2,
      new base::RefCountedBytes(data), Time::Now(), kSmallSize));
  data[0] = 'd';
  EXPECT_TRUE(backend_->thumbnail_db_->AddFaviconBitmap(favicon2,
     new base::RefCountedBytes(data), Time::Now(), kLargeSize));

  // First visit two URLs.
  URLRow row1(GURL("http://www.google.com/"));
  row1.set_visit_count(2);
  row1.set_typed_count(1);
  row1.set_last_visit(Time::Now());
  backend_->thumbnail_db_->AddIconMapping(row1.url(), favicon1);

  URLRow row2(GURL("http://news.google.com/"));
  row2.set_visit_count(1);
  row2.set_last_visit(Time::Now());
  backend_->thumbnail_db_->AddIconMapping(row2.url(), favicon2);

  URLRows rows;
  rows.push_back(row2);  // Reversed order for the same reason as favicons.
  rows.push_back(row1);
  backend_->AddPagesWithDetails(rows, history::SOURCE_BROWSED);

  URLID row1_id = backend_->db_->GetRowForURL(row1.url(), NULL);
  URLID row2_id = backend_->db_->GetRowForURL(row2.url(), NULL);

  // Get the two visits for the URLs we just added.
  VisitVector visits;
  backend_->db_->GetVisitsForURL(row1_id, &visits);
  ASSERT_EQ(1U, visits.size());

  visits.clear();
  backend_->db_->GetVisitsForURL(row2_id, &visits);
  ASSERT_EQ(1U, visits.size());

  // The in-memory backend should have been set and it should have gotten the
  // typed URL.
  ASSERT_TRUE(mem_backend_.get());
  URLRow outrow1;
  EXPECT_TRUE(mem_backend_->db_->GetRowForURL(row1.url(), NULL));

  // Star row1.
  bookmark_model_.AddURL(
      bookmark_model_.bookmark_bar_node(), 0, base::string16(), row1.url());

  // Now finally clear all history.
  backend_->DeleteAllHistory();

  // The first URL should be preserved but the time should be cleared.
  EXPECT_TRUE(backend_->db_->GetRowForURL(row1.url(), &outrow1));
  EXPECT_EQ(row1.url(), outrow1.url());
  EXPECT_EQ(0, outrow1.visit_count());
  EXPECT_EQ(0, outrow1.typed_count());
  EXPECT_TRUE(Time() == outrow1.last_visit());

  // The second row should be deleted.
  URLRow outrow2;
  EXPECT_FALSE(backend_->db_->GetRowForURL(row2.url(), &outrow2));

  // All visits should be deleted for both URLs.
  VisitVector all_visits;
  backend_->db_->GetAllVisitsInRange(Time(), Time(), 0, &all_visits);
  ASSERT_EQ(0U, all_visits.size());

  // We should have a favicon and favicon bitmaps for the first URL only. We
  // look them up by favicon URL since the IDs may have changed.
  chrome::FaviconID out_favicon1 = backend_->thumbnail_db_->
      GetFaviconIDForFaviconURL(favicon_url1, chrome::FAVICON, NULL);
  EXPECT_TRUE(out_favicon1);

  std::vector<FaviconBitmap> favicon_bitmaps;
  EXPECT_TRUE(backend_->thumbnail_db_->GetFaviconBitmaps(
      out_favicon1, &favicon_bitmaps));
  ASSERT_EQ(2u, favicon_bitmaps.size());

  FaviconBitmap favicon_bitmap1 = favicon_bitmaps[0];
  FaviconBitmap favicon_bitmap2 = favicon_bitmaps[1];

  // Favicon bitmaps do not need to be in particular order.
  if (favicon_bitmap1.pixel_size == kLargeSize) {
    FaviconBitmap tmp_favicon_bitmap = favicon_bitmap1;
    favicon_bitmap1 = favicon_bitmap2;
    favicon_bitmap2 = tmp_favicon_bitmap;
  }

  EXPECT_TRUE(BitmapDataEqual('a', favicon_bitmap1.bitmap_data));
  EXPECT_EQ(kSmallSize, favicon_bitmap1.pixel_size);

  EXPECT_TRUE(BitmapDataEqual('b', favicon_bitmap2.bitmap_data));
  EXPECT_EQ(kLargeSize, favicon_bitmap2.pixel_size);

  chrome::FaviconID out_favicon2 = backend_->thumbnail_db_->
      GetFaviconIDForFaviconURL(favicon_url2, chrome::FAVICON, NULL);
  EXPECT_FALSE(out_favicon2) << "Favicon not deleted";

  // The remaining URL should still reference the same favicon, even if its
  // ID has changed.
  std::vector<IconMapping> mappings;
  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(
      outrow1.url(), chrome::FAVICON, &mappings));
  EXPECT_EQ(1u, mappings.size());
  EXPECT_EQ(out_favicon1, mappings[0].icon_id);

  // The first URL should still be bookmarked.
  EXPECT_TRUE(bookmark_model_.IsBookmarked(row1.url()));
}

// Checks that adding a visit, then calling DeleteAll, and then trying to add
// data for the visited page works.  This can happen when clearing the history
// immediately after visiting a page.
TEST_F(HistoryBackendTest, DeleteAllThenAddData) {
  ASSERT_TRUE(backend_.get());

  Time visit_time = Time::Now();
  GURL url("http://www.google.com/");
  HistoryAddPageArgs request(url, visit_time, NULL, 0, GURL(),
                             history::RedirectList(),
                             content::PAGE_TRANSITION_KEYWORD_GENERATED,
                             history::SOURCE_BROWSED, false);
  backend_->AddPage(request);

  // Check that a row was added.
  URLRow outrow;
  EXPECT_TRUE(backend_->db_->GetRowForURL(url, &outrow));

  // Check that the visit was added.
  VisitVector all_visits;
  backend_->db_->GetAllVisitsInRange(Time(), Time(), 0, &all_visits);
  ASSERT_EQ(1U, all_visits.size());

  // Clear all history.
  backend_->DeleteAllHistory();

  // The row should be deleted.
  EXPECT_FALSE(backend_->db_->GetRowForURL(url, &outrow));

  // The visit should be deleted.
  backend_->db_->GetAllVisitsInRange(Time(), Time(), 0, &all_visits);
  ASSERT_EQ(0U, all_visits.size());

  // Try and set the title.
  backend_->SetPageTitle(url, UTF8ToUTF16("Title"));

  // The row should still be deleted.
  EXPECT_FALSE(backend_->db_->GetRowForURL(url, &outrow));

  // The visit should still be deleted.
  backend_->db_->GetAllVisitsInRange(Time(), Time(), 0, &all_visits);
  ASSERT_EQ(0U, all_visits.size());
}

TEST_F(HistoryBackendTest, URLsNoLongerBookmarked) {
  GURL favicon_url1("http://www.google.com/favicon.ico");
  GURL favicon_url2("http://news.google.com/favicon.ico");

  std::vector<unsigned char> data;
  data.push_back('1');
  chrome::FaviconID favicon1 = backend_->thumbnail_db_->AddFavicon(
      favicon_url1,
      chrome::FAVICON,
      new base::RefCountedBytes(data),
      Time::Now(),
      gfx::Size());

  data[0] = '2';
  chrome::FaviconID favicon2 = backend_->thumbnail_db_->AddFavicon(
      favicon_url2,
      chrome::FAVICON,
      new base::RefCountedBytes(data),
      Time::Now(),
      gfx::Size());

  // First visit two URLs.
  URLRow row1(GURL("http://www.google.com/"));
  row1.set_visit_count(2);
  row1.set_typed_count(1);
  row1.set_last_visit(Time::Now());
  EXPECT_TRUE(backend_->thumbnail_db_->AddIconMapping(row1.url(), favicon1));

  URLRow row2(GURL("http://news.google.com/"));
  row2.set_visit_count(1);
  row2.set_last_visit(Time::Now());
  EXPECT_TRUE(backend_->thumbnail_db_->AddIconMapping(row2.url(), favicon2));

  URLRows rows;
  rows.push_back(row2);  // Reversed order for the same reason as favicons.
  rows.push_back(row1);
  backend_->AddPagesWithDetails(rows, history::SOURCE_BROWSED);

  URLID row1_id = backend_->db_->GetRowForURL(row1.url(), NULL);
  URLID row2_id = backend_->db_->GetRowForURL(row2.url(), NULL);

  // Star the two URLs.
  bookmark_utils::AddIfNotBookmarked(&bookmark_model_, row1.url(),
                                     base::string16());
  bookmark_utils::AddIfNotBookmarked(&bookmark_model_, row2.url(),
                                     base::string16());

  // Delete url 2. Because url 2 is starred this won't delete the URL, only
  // the visits.
  backend_->expirer_.DeleteURL(row2.url());

  // Make sure url 2 is still valid, but has no visits.
  URLRow tmp_url_row;
  EXPECT_EQ(row2_id, backend_->db_->GetRowForURL(row2.url(), NULL));
  VisitVector visits;
  backend_->db_->GetVisitsForURL(row2_id, &visits);
  EXPECT_EQ(0U, visits.size());
  // The favicon should still be valid.
  EXPECT_EQ(favicon2,
      backend_->thumbnail_db_->GetFaviconIDForFaviconURL(favicon_url2,
                                                         chrome::FAVICON,
                                                         NULL));

  // Unstar row2.
  bookmark_utils::RemoveAllBookmarks(&bookmark_model_, row2.url());

  // Tell the backend it was unstarred. We have to explicitly do this as
  // BookmarkModel isn't wired up to the backend during testing.
  std::set<GURL> unstarred_urls;
  unstarred_urls.insert(row2.url());
  backend_->URLsNoLongerBookmarked(unstarred_urls);

  // The URL should no longer exist.
  EXPECT_FALSE(backend_->db_->GetRowForURL(row2.url(), &tmp_url_row));
  // And the favicon should be deleted.
  EXPECT_EQ(0,
      backend_->thumbnail_db_->GetFaviconIDForFaviconURL(favicon_url2,
                                                         chrome::FAVICON,
                                                         NULL));

  // Unstar row 1.
  bookmark_utils::RemoveAllBookmarks(&bookmark_model_, row1.url());
  // Tell the backend it was unstarred. We have to explicitly do this as
  // BookmarkModel isn't wired up to the backend during testing.
  unstarred_urls.clear();
  unstarred_urls.insert(row1.url());
  backend_->URLsNoLongerBookmarked(unstarred_urls);

  // The URL should still exist (because there were visits).
  EXPECT_EQ(row1_id, backend_->db_->GetRowForURL(row1.url(), NULL));

  // There should still be visits.
  visits.clear();
  backend_->db_->GetVisitsForURL(row1_id, &visits);
  EXPECT_EQ(1U, visits.size());

  // The favicon should still be valid.
  EXPECT_EQ(favicon1,
      backend_->thumbnail_db_->GetFaviconIDForFaviconURL(favicon_url1,
                                                         chrome::FAVICON,
                                                         NULL));
}

// Tests a handful of assertions for a navigation with a type of
// KEYWORD_GENERATED.
TEST_F(HistoryBackendTest, KeywordGenerated) {
  ASSERT_TRUE(backend_.get());

  GURL url("http://google.com");

  Time visit_time = Time::Now() - base::TimeDelta::FromDays(1);
  HistoryAddPageArgs request(url, visit_time, NULL, 0, GURL(),
                             history::RedirectList(),
                             content::PAGE_TRANSITION_KEYWORD_GENERATED,
                             history::SOURCE_BROWSED, false);
  backend_->AddPage(request);

  // A row should have been added for the url.
  URLRow row;
  URLID url_id = backend_->db()->GetRowForURL(url, &row);
  ASSERT_NE(0, url_id);

  // The typed count should be 1.
  ASSERT_EQ(1, row.typed_count());

  // KEYWORD_GENERATED urls should not be added to the segment db.
  std::string segment_name = VisitSegmentDatabase::ComputeSegmentName(url);
  EXPECT_EQ(0, backend_->db()->GetSegmentNamed(segment_name));

  // One visit should be added.
  VisitVector visits;
  EXPECT_TRUE(backend_->db()->GetVisitsForURL(url_id, &visits));
  EXPECT_EQ(1U, visits.size());

  // But no visible visits.
  visits.clear();
  QueryOptions query_options;
  query_options.max_count = 1;
  backend_->db()->GetVisibleVisitsInRange(query_options, &visits);
  EXPECT_TRUE(visits.empty());

  // Expire the visits.
  std::set<GURL> restrict_urls;
  backend_->expire_backend()->ExpireHistoryBetween(restrict_urls,
                                                   visit_time, Time::Now());

  // The visit should have been nuked.
  visits.clear();
  EXPECT_TRUE(backend_->db()->GetVisitsForURL(url_id, &visits));
  EXPECT_TRUE(visits.empty());

  // As well as the url.
  ASSERT_EQ(0, backend_->db()->GetRowForURL(url, &row));
}

TEST_F(HistoryBackendTest, ClientRedirect) {
  ASSERT_TRUE(backend_.get());

  int transition1;
  int transition2;

  // Initial transition to page A.
  GURL url_a("http://google.com/a");
  AddClientRedirect(GURL(), url_a, false, base::Time(),
                    &transition1, &transition2);
  EXPECT_TRUE(transition2 & content::PAGE_TRANSITION_CHAIN_END);

  // User initiated redirect to page B.
  GURL url_b("http://google.com/b");
  AddClientRedirect(url_a, url_b, false, base::Time(),
                    &transition1, &transition2);
  EXPECT_TRUE(transition1 & content::PAGE_TRANSITION_CHAIN_END);
  EXPECT_TRUE(transition2 & content::PAGE_TRANSITION_CHAIN_END);

  // Non-user initiated redirect to page C.
  GURL url_c("http://google.com/c");
  AddClientRedirect(url_b, url_c, true, base::Time(),
                    &transition1, &transition2);
  EXPECT_FALSE(transition1 & content::PAGE_TRANSITION_CHAIN_END);
  EXPECT_TRUE(transition2 & content::PAGE_TRANSITION_CHAIN_END);
}

TEST_F(HistoryBackendTest, ImportedFaviconsTest) {
  // Setup test data - two Urls in the history, one with favicon assigned and
  // one without.
  GURL favicon_url1("http://www.google.com/favicon.ico");
  std::vector<unsigned char> data;
  data.push_back('1');
  chrome::FaviconID favicon1 = backend_->thumbnail_db_->AddFavicon(
      favicon_url1,
      chrome::FAVICON,
      base::RefCountedBytes::TakeVector(&data),
      Time::Now(),
      gfx::Size());
  URLRow row1(GURL("http://www.google.com/"));
  row1.set_visit_count(1);
  row1.set_last_visit(Time::Now());
  EXPECT_TRUE(backend_->thumbnail_db_->AddIconMapping(row1.url(), favicon1));

  URLRow row2(GURL("http://news.google.com/"));
  row2.set_visit_count(1);
  row2.set_last_visit(Time::Now());
  URLRows rows;
  rows.push_back(row1);
  rows.push_back(row2);
  backend_->AddPagesWithDetails(rows, history::SOURCE_BROWSED);
  URLRow url_row1, url_row2;
  EXPECT_FALSE(backend_->db_->GetRowForURL(row1.url(), &url_row1) == 0);
  EXPECT_FALSE(backend_->db_->GetRowForURL(row2.url(), &url_row2) == 0);
  EXPECT_EQ(1u, NumIconMappingsForPageURL(row1.url(), chrome::FAVICON));
  EXPECT_EQ(0u, NumIconMappingsForPageURL(row2.url(), chrome::FAVICON));

  // Now provide one imported favicon for both URLs already in the registry.
  // The new favicon should only be used with the URL that doesn't already have
  // a favicon.
  std::vector<ImportedFaviconUsage> favicons;
  ImportedFaviconUsage favicon;
  favicon.favicon_url = GURL("http://news.google.com/favicon.ico");
  favicon.png_data.push_back('2');
  favicon.urls.insert(row1.url());
  favicon.urls.insert(row2.url());
  favicons.push_back(favicon);
  backend_->SetImportedFavicons(favicons);
  EXPECT_FALSE(backend_->db_->GetRowForURL(row1.url(), &url_row1) == 0);
  EXPECT_FALSE(backend_->db_->GetRowForURL(row2.url(), &url_row2) == 0);

  std::vector<IconMapping> mappings;
  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(
      row1.url(), chrome::FAVICON, &mappings));
  EXPECT_EQ(1u, mappings.size());
  EXPECT_EQ(favicon1, mappings[0].icon_id);
  EXPECT_EQ(favicon_url1, mappings[0].icon_url);

  mappings.clear();
  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(
    row2.url(), chrome::FAVICON, &mappings));
  EXPECT_EQ(1u, mappings.size());
  EXPECT_EQ(favicon.favicon_url, mappings[0].icon_url);

  // A URL should not be added to history (to store favicon), if
  // the URL is not bookmarked.
  GURL url3("http://mail.google.com");
  favicons.clear();
  favicon.favicon_url = GURL("http://mail.google.com/favicon.ico");
  favicon.png_data.push_back('3');
  favicon.urls.insert(url3);
  favicons.push_back(favicon);
  backend_->SetImportedFavicons(favicons);
  URLRow url_row3;
  EXPECT_TRUE(backend_->db_->GetRowForURL(url3, &url_row3) == 0);

  // If the URL is bookmarked, it should get added to history with 0 visits.
  bookmark_model_.AddURL(bookmark_model_.bookmark_bar_node(), 0,
                         base::string16(), url3);
  backend_->SetImportedFavicons(favicons);
  EXPECT_FALSE(backend_->db_->GetRowForURL(url3, &url_row3) == 0);
  EXPECT_TRUE(url_row3.visit_count() == 0);
}

TEST_F(HistoryBackendTest, StripUsernamePasswordTest) {
  ASSERT_TRUE(backend_.get());

  GURL url("http://anyuser:anypass@www.google.com");
  GURL stripped_url("http://www.google.com");

  // Clear all history.
  backend_->DeleteAllHistory();

  // Visit the url with username, password.
  backend_->AddPageVisit(url, base::Time::Now(), 0,
      content::PageTransitionFromInt(
          content::PageTransitionGetQualifier(content::PAGE_TRANSITION_TYPED)),
      history::SOURCE_BROWSED);

  // Fetch the row information about stripped url from history db.
  VisitVector visits;
  URLID row_id = backend_->db_->GetRowForURL(stripped_url, NULL);
  backend_->db_->GetVisitsForURL(row_id, &visits);

  // Check if stripped url is stored in database.
  ASSERT_EQ(1U, visits.size());
}

TEST_F(HistoryBackendTest, AddPageVisitSource) {
  ASSERT_TRUE(backend_.get());

  GURL url("http://www.google.com");

  // Clear all history.
  backend_->DeleteAllHistory();

  // Assume visiting the url from an externsion.
  backend_->AddPageVisit(
      url, base::Time::Now(), 0, content::PAGE_TRANSITION_TYPED,
      history::SOURCE_EXTENSION);
  // Assume the url is imported from Firefox.
  backend_->AddPageVisit(url, base::Time::Now(), 0,
                         content::PAGE_TRANSITION_TYPED,
                         history::SOURCE_FIREFOX_IMPORTED);
  // Assume this url is also synced.
  backend_->AddPageVisit(url, base::Time::Now(), 0,
                         content::PAGE_TRANSITION_TYPED,
                         history::SOURCE_SYNCED);

  // Fetch the row information about the url from history db.
  VisitVector visits;
  URLID row_id = backend_->db_->GetRowForURL(url, NULL);
  backend_->db_->GetVisitsForURL(row_id, &visits);

  // Check if all the visits to the url are stored in database.
  ASSERT_EQ(3U, visits.size());
  VisitSourceMap visit_sources;
  ASSERT_TRUE(backend_->GetVisitsSource(visits, &visit_sources));
  ASSERT_EQ(3U, visit_sources.size());
  int sources = 0;
  for (int i = 0; i < 3; i++) {
    switch (visit_sources[visits[i].visit_id]) {
      case history::SOURCE_EXTENSION:
        sources |= 0x1;
        break;
      case history::SOURCE_FIREFOX_IMPORTED:
        sources |= 0x2;
        break;
      case history::SOURCE_SYNCED:
        sources |= 0x4;
      default:
        break;
    }
  }
  EXPECT_EQ(0x7, sources);
}

TEST_F(HistoryBackendTest, AddPageVisitNotLastVisit) {
  ASSERT_TRUE(backend_.get());

  GURL url("http://www.google.com");

  // Clear all history.
  backend_->DeleteAllHistory();

  // Create visit times
  base::Time recent_time = base::Time::Now();
  base::TimeDelta visit_age = base::TimeDelta::FromDays(3);
  base::Time older_time = recent_time - visit_age;

  // Visit the url with recent time.
  backend_->AddPageVisit(url, recent_time, 0,
      content::PageTransitionFromInt(
          content::PageTransitionGetQualifier(content::PAGE_TRANSITION_TYPED)),
      history::SOURCE_BROWSED);

  // Add to the url a visit with older time (could be syncing from another
  // client, etc.).
  backend_->AddPageVisit(url, older_time, 0,
      content::PageTransitionFromInt(
          content::PageTransitionGetQualifier(content::PAGE_TRANSITION_TYPED)),
      history::SOURCE_SYNCED);

  // Fetch the row information about url from history db.
  VisitVector visits;
  URLRow row;
  URLID row_id = backend_->db_->GetRowForURL(url, &row);
  backend_->db_->GetVisitsForURL(row_id, &visits);

  // Last visit time should be the most recent time, not the most recently added
  // visit.
  ASSERT_EQ(2U, visits.size());
  ASSERT_EQ(recent_time, row.last_visit());
}

TEST_F(HistoryBackendTest, AddPageArgsSource) {
  ASSERT_TRUE(backend_.get());

  GURL url("http://testpageargs.com");

  // Assume this page is browsed by user.
  HistoryAddPageArgs request1(url, base::Time::Now(), NULL, 0, GURL(),
                             history::RedirectList(),
                             content::PAGE_TRANSITION_KEYWORD_GENERATED,
                             history::SOURCE_BROWSED, false);
  backend_->AddPage(request1);
  // Assume this page is synced.
  HistoryAddPageArgs request2(url, base::Time::Now(), NULL, 0, GURL(),
                             history::RedirectList(),
                             content::PAGE_TRANSITION_LINK,
                             history::SOURCE_SYNCED, false);
  backend_->AddPage(request2);
  // Assume this page is browsed again.
  HistoryAddPageArgs request3(url, base::Time::Now(), NULL, 0, GURL(),
                             history::RedirectList(),
                             content::PAGE_TRANSITION_TYPED,
                             history::SOURCE_BROWSED, false);
  backend_->AddPage(request3);

  // Three visits should be added with proper sources.
  VisitVector visits;
  URLRow row;
  URLID id = backend_->db()->GetRowForURL(url, &row);
  ASSERT_TRUE(backend_->db()->GetVisitsForURL(id, &visits));
  ASSERT_EQ(3U, visits.size());
  VisitSourceMap visit_sources;
  ASSERT_TRUE(backend_->GetVisitsSource(visits, &visit_sources));
  ASSERT_EQ(1U, visit_sources.size());
  EXPECT_EQ(history::SOURCE_SYNCED, visit_sources.begin()->second);
}

TEST_F(HistoryBackendTest, AddVisitsSource) {
  ASSERT_TRUE(backend_.get());

  GURL url1("http://www.cnn.com");
  std::vector<VisitInfo> visits1, visits2;
  visits1.push_back(VisitInfo(
      Time::Now() - base::TimeDelta::FromDays(5),
      content::PAGE_TRANSITION_LINK));
  visits1.push_back(VisitInfo(
      Time::Now() - base::TimeDelta::FromDays(1),
      content::PAGE_TRANSITION_LINK));
  visits1.push_back(VisitInfo(
      Time::Now(), content::PAGE_TRANSITION_LINK));

  GURL url2("http://www.example.com");
  visits2.push_back(VisitInfo(
      Time::Now() - base::TimeDelta::FromDays(10),
      content::PAGE_TRANSITION_LINK));
  visits2.push_back(VisitInfo(Time::Now(), content::PAGE_TRANSITION_LINK));

  // Clear all history.
  backend_->DeleteAllHistory();

  // Add the visits.
  backend_->AddVisits(url1, visits1, history::SOURCE_IE_IMPORTED);
  backend_->AddVisits(url2, visits2, history::SOURCE_SYNCED);

  // Verify the visits were added with their sources.
  VisitVector visits;
  URLRow row;
  URLID id = backend_->db()->GetRowForURL(url1, &row);
  ASSERT_TRUE(backend_->db()->GetVisitsForURL(id, &visits));
  ASSERT_EQ(3U, visits.size());
  VisitSourceMap visit_sources;
  ASSERT_TRUE(backend_->GetVisitsSource(visits, &visit_sources));
  ASSERT_EQ(3U, visit_sources.size());
  for (int i = 0; i < 3; i++)
    EXPECT_EQ(history::SOURCE_IE_IMPORTED, visit_sources[visits[i].visit_id]);
  id = backend_->db()->GetRowForURL(url2, &row);
  ASSERT_TRUE(backend_->db()->GetVisitsForURL(id, &visits));
  ASSERT_EQ(2U, visits.size());
  ASSERT_TRUE(backend_->GetVisitsSource(visits, &visit_sources));
  ASSERT_EQ(2U, visit_sources.size());
  for (int i = 0; i < 2; i++)
    EXPECT_EQ(history::SOURCE_SYNCED, visit_sources[visits[i].visit_id]);
}

TEST_F(HistoryBackendTest, GetMostRecentVisits) {
  ASSERT_TRUE(backend_.get());

  GURL url1("http://www.cnn.com");
  std::vector<VisitInfo> visits1;
  visits1.push_back(VisitInfo(
      Time::Now() - base::TimeDelta::FromDays(5),
      content::PAGE_TRANSITION_LINK));
  visits1.push_back(VisitInfo(
      Time::Now() - base::TimeDelta::FromDays(1),
      content::PAGE_TRANSITION_LINK));
  visits1.push_back(VisitInfo(
      Time::Now(), content::PAGE_TRANSITION_LINK));

  // Clear all history.
  backend_->DeleteAllHistory();

  // Add the visits.
  backend_->AddVisits(url1, visits1, history::SOURCE_IE_IMPORTED);

  // Verify the visits were added with their sources.
  VisitVector visits;
  URLRow row;
  URLID id = backend_->db()->GetRowForURL(url1, &row);
  ASSERT_TRUE(backend_->db()->GetMostRecentVisitsForURL(id, 1, &visits));
  ASSERT_EQ(1U, visits.size());
  EXPECT_EQ(visits1[2].first, visits[0].visit_time);
}

TEST_F(HistoryBackendTest, RemoveVisitsTransitions) {
  ASSERT_TRUE(backend_.get());

  // Clear all history.
  backend_->DeleteAllHistory();

  GURL url1("http://www.cnn.com");
  VisitInfo typed_visit(
      Time::Now() - base::TimeDelta::FromDays(6),
      content::PAGE_TRANSITION_TYPED);
  VisitInfo reload_visit(
      Time::Now() - base::TimeDelta::FromDays(5),
      content::PAGE_TRANSITION_RELOAD);
  VisitInfo link_visit(
      Time::Now() - base::TimeDelta::FromDays(4),
      content::PAGE_TRANSITION_LINK);
  std::vector<VisitInfo> visits_to_add;
  visits_to_add.push_back(typed_visit);
  visits_to_add.push_back(reload_visit);
  visits_to_add.push_back(link_visit);

  // Add the visits.
  backend_->AddVisits(url1, visits_to_add, history::SOURCE_SYNCED);

  // Verify that the various counts are what we expect.
  VisitVector visits;
  URLRow row;
  URLID id = backend_->db()->GetRowForURL(url1, &row);
  ASSERT_TRUE(backend_->db()->GetVisitsForURL(id, &visits));
  ASSERT_EQ(3U, visits.size());
  ASSERT_EQ(1, row.typed_count());
  ASSERT_EQ(2, row.visit_count());

  // Now, delete the typed visit and verify that typed_count is updated.
  ASSERT_TRUE(backend_->RemoveVisits(VisitVector(1, visits[0])));
  id = backend_->db()->GetRowForURL(url1, &row);
  ASSERT_TRUE(backend_->db()->GetVisitsForURL(id, &visits));
  ASSERT_EQ(2U, visits.size());
  ASSERT_EQ(0, row.typed_count());
  ASSERT_EQ(1, row.visit_count());

  // Delete the reload visit now and verify that none of the counts have
  // changed.
  ASSERT_TRUE(backend_->RemoveVisits(VisitVector(1, visits[0])));
  id = backend_->db()->GetRowForURL(url1, &row);
  ASSERT_TRUE(backend_->db()->GetVisitsForURL(id, &visits));
  ASSERT_EQ(1U, visits.size());
  ASSERT_EQ(0, row.typed_count());
  ASSERT_EQ(1, row.visit_count());

  // Delete the last visit and verify that we delete the URL.
  ASSERT_TRUE(backend_->RemoveVisits(VisitVector(1, visits[0])));
  ASSERT_EQ(0, backend_->db()->GetRowForURL(url1, &row));
}

TEST_F(HistoryBackendTest, RemoveVisitsSource) {
  ASSERT_TRUE(backend_.get());

  GURL url1("http://www.cnn.com");
  std::vector<VisitInfo> visits1, visits2;
  visits1.push_back(VisitInfo(
      Time::Now() - base::TimeDelta::FromDays(5),
      content::PAGE_TRANSITION_LINK));
  visits1.push_back(VisitInfo(Time::Now(),
    content::PAGE_TRANSITION_LINK));

  GURL url2("http://www.example.com");
  visits2.push_back(VisitInfo(
      Time::Now() - base::TimeDelta::FromDays(10),
      content::PAGE_TRANSITION_LINK));
  visits2.push_back(VisitInfo(Time::Now(), content::PAGE_TRANSITION_LINK));

  // Clear all history.
  backend_->DeleteAllHistory();

  // Add the visits.
  backend_->AddVisits(url1, visits1, history::SOURCE_IE_IMPORTED);
  backend_->AddVisits(url2, visits2, history::SOURCE_SYNCED);

  // Verify the visits of url1 were added.
  VisitVector visits;
  URLRow row;
  URLID id = backend_->db()->GetRowForURL(url1, &row);
  ASSERT_TRUE(backend_->db()->GetVisitsForURL(id, &visits));
  ASSERT_EQ(2U, visits.size());
  // Remove these visits.
  ASSERT_TRUE(backend_->RemoveVisits(visits));

  // Now check only url2's source in visit_source table.
  VisitSourceMap visit_sources;
  ASSERT_TRUE(backend_->GetVisitsSource(visits, &visit_sources));
  ASSERT_EQ(0U, visit_sources.size());
  id = backend_->db()->GetRowForURL(url2, &row);
  ASSERT_TRUE(backend_->db()->GetVisitsForURL(id, &visits));
  ASSERT_EQ(2U, visits.size());
  ASSERT_TRUE(backend_->GetVisitsSource(visits, &visit_sources));
  ASSERT_EQ(2U, visit_sources.size());
  for (int i = 0; i < 2; i++)
    EXPECT_EQ(history::SOURCE_SYNCED, visit_sources[visits[i].visit_id]);
}

// Test for migration of adding visit_source table.
TEST_F(HistoryBackendTest, MigrationVisitSource) {
  ASSERT_TRUE(backend_.get());
  backend_->Closing();
  backend_ = NULL;

  base::FilePath old_history_path;
  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &old_history_path));
  old_history_path = old_history_path.AppendASCII("History");
  old_history_path = old_history_path.AppendASCII("HistoryNoSource");

  // Copy history database file to current directory so that it will be deleted
  // in Teardown.
  base::FilePath new_history_path(getTestDir());
  base::DeleteFile(new_history_path, true);
  base::CreateDirectory(new_history_path);
  base::FilePath new_history_file =
      new_history_path.Append(chrome::kHistoryFilename);
  ASSERT_TRUE(base::CopyFile(old_history_path, new_history_file));

  backend_ = new HistoryBackend(new_history_path,
                                0,
                                new HistoryBackendTestDelegate(this),
                                &bookmark_model_);
  backend_->Init(std::string(), false);
  backend_->Closing();
  backend_ = NULL;

  // Now the database should already be migrated.
  // Check version first.
  int cur_version = HistoryDatabase::GetCurrentVersion();
  sql::Connection db;
  ASSERT_TRUE(db.Open(new_history_file));
  sql::Statement s(db.GetUniqueStatement(
      "SELECT value FROM meta WHERE key = 'version'"));
  ASSERT_TRUE(s.Step());
  int file_version = s.ColumnInt(0);
  EXPECT_EQ(cur_version, file_version);

  // Check visit_source table is created and empty.
  s.Assign(db.GetUniqueStatement(
      "SELECT name FROM sqlite_master WHERE name=\"visit_source\""));
  ASSERT_TRUE(s.Step());
  s.Assign(db.GetUniqueStatement("SELECT * FROM visit_source LIMIT 10"));
  EXPECT_FALSE(s.Step());
}

// Test that SetFaviconMappingsForPageAndRedirects correctly updates icon
// mappings based on redirects, icon URLs and icon types.
TEST_F(HistoryBackendTest, SetFaviconMappingsForPageAndRedirects) {
  // Init recent_redirects_
  const GURL url1("http://www.google.com");
  const GURL url2("http://www.google.com/m");
  URLRow url_info1(url1);
  url_info1.set_visit_count(0);
  url_info1.set_typed_count(0);
  url_info1.set_last_visit(base::Time());
  url_info1.set_hidden(false);
  backend_->db_->AddURL(url_info1);

  URLRow url_info2(url2);
  url_info2.set_visit_count(0);
  url_info2.set_typed_count(0);
  url_info2.set_last_visit(base::Time());
  url_info2.set_hidden(false);
  backend_->db_->AddURL(url_info2);

  history::RedirectList redirects;
  redirects.push_back(url2);
  redirects.push_back(url1);
  backend_->recent_redirects_.Put(url1, redirects);

  const GURL icon_url1("http://www.google.com/icon");
  const GURL icon_url2("http://www.google.com/icon2");

  // Generate bitmap data for a page with two favicons.
  std::vector<chrome::FaviconBitmapData> two_favicon_bitmap_data;
  GenerateFaviconBitmapData(icon_url1, GetSizesSmallAndLarge(),
      icon_url2, GetSizesSmallAndLarge(), &two_favicon_bitmap_data);

  // Generate bitmap data for a page with a single favicon.
  std::vector<chrome::FaviconBitmapData> one_favicon_bitmap_data;
  GenerateFaviconBitmapData(icon_url1, GetSizesSmallAndLarge(),
                            &one_favicon_bitmap_data);

  // Add two favicons
  backend_->SetFavicons(url1, chrome::FAVICON, two_favicon_bitmap_data);
  EXPECT_EQ(2u, NumIconMappingsForPageURL(url1, chrome::FAVICON));
  EXPECT_EQ(2u, NumIconMappingsForPageURL(url2, chrome::FAVICON));

  // Add one touch_icon
  backend_->SetFavicons(url1, chrome::TOUCH_ICON, one_favicon_bitmap_data);
  EXPECT_EQ(1u, NumIconMappingsForPageURL(url1, chrome::TOUCH_ICON));
  EXPECT_EQ(1u, NumIconMappingsForPageURL(url2, chrome::TOUCH_ICON));
  EXPECT_EQ(2u, NumIconMappingsForPageURL(url1, chrome::FAVICON));

  // Add one TOUCH_PRECOMPOSED_ICON
  backend_->SetFavicons(
      url1, chrome::TOUCH_PRECOMPOSED_ICON, one_favicon_bitmap_data);
  // The touch_icon was replaced.
  EXPECT_EQ(0u, NumIconMappingsForPageURL(url1, chrome::TOUCH_ICON));
  EXPECT_EQ(2u, NumIconMappingsForPageURL(url1, chrome::FAVICON));
  EXPECT_EQ(1u,
            NumIconMappingsForPageURL(url1, chrome::TOUCH_PRECOMPOSED_ICON));
  EXPECT_EQ(1u,
            NumIconMappingsForPageURL(url2, chrome::TOUCH_PRECOMPOSED_ICON));

  // Add a touch_icon.
  backend_->SetFavicons(url1, chrome::TOUCH_ICON, one_favicon_bitmap_data);
  EXPECT_EQ(1u, NumIconMappingsForPageURL(url1, chrome::TOUCH_ICON));
  EXPECT_EQ(2u, NumIconMappingsForPageURL(url1, chrome::FAVICON));
  // The TOUCH_PRECOMPOSED_ICON was replaced.
  EXPECT_EQ(0u,
            NumIconMappingsForPageURL(url1, chrome::TOUCH_PRECOMPOSED_ICON));

  // Add a single favicon.
  backend_->SetFavicons(url1, chrome::FAVICON, one_favicon_bitmap_data);
  EXPECT_EQ(1u, NumIconMappingsForPageURL(url1, chrome::TOUCH_ICON));
  EXPECT_EQ(1u, NumIconMappingsForPageURL(url1, chrome::FAVICON));
  EXPECT_EQ(1u, NumIconMappingsForPageURL(url2, chrome::FAVICON));

  // Add two favicons.
  backend_->SetFavicons(url1, chrome::FAVICON, two_favicon_bitmap_data);
  EXPECT_EQ(1u, NumIconMappingsForPageURL(url1, chrome::TOUCH_ICON));
  EXPECT_EQ(2u, NumIconMappingsForPageURL(url1, chrome::FAVICON));
}

// Test that there is no churn in icon mappings from calling
// SetFavicons() twice with the same |favicon_bitmap_data| parameter.
TEST_F(HistoryBackendTest, SetFaviconMappingsForPageDuplicates) {
  const GURL url("http://www.google.com/");
  const GURL icon_url("http://www.google.com/icon");

  std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
  GenerateFaviconBitmapData(icon_url, GetSizesSmallAndLarge(),
                            &favicon_bitmap_data);

  backend_->SetFavicons(url, chrome::FAVICON, favicon_bitmap_data);

  std::vector<IconMapping> icon_mappings;
  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(
      url, chrome::FAVICON, &icon_mappings));
  EXPECT_EQ(1u, icon_mappings.size());
  IconMappingID mapping_id = icon_mappings[0].mapping_id;

  backend_->SetFavicons(url, chrome::FAVICON, favicon_bitmap_data);

  icon_mappings.clear();
  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(
      url, chrome::FAVICON, &icon_mappings));
  EXPECT_EQ(1u, icon_mappings.size());

  // The same row in the icon_mapping table should be used for the mapping as
  // before.
  EXPECT_EQ(mapping_id, icon_mappings[0].mapping_id);
}

// Test that calling SetFavicons() with FaviconBitmapData of different pixel
// sizes than the initially passed in FaviconBitmapData deletes the no longer
// used favicon bitmaps.
TEST_F(HistoryBackendTest, SetFaviconsDeleteBitmaps) {
  const GURL page_url("http://www.google.com/");
  const GURL icon_url("http://www.google.com/icon");

  std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
  GenerateFaviconBitmapData(icon_url, GetSizesSmallAndLarge(),
                            &favicon_bitmap_data);
  backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);

  // Test initial state.
  std::vector<IconMapping> icon_mappings;
  EXPECT_TRUE(GetSortedIconMappingsForPageURL(page_url, &icon_mappings));
  EXPECT_EQ(1u, icon_mappings.size());
  EXPECT_EQ(icon_url, icon_mappings[0].icon_url);
  EXPECT_EQ(chrome::FAVICON, icon_mappings[0].icon_type);
  chrome::FaviconID favicon_id = icon_mappings[0].icon_id;

  std::vector<FaviconBitmap> favicon_bitmaps;
  EXPECT_TRUE(GetSortedFaviconBitmaps(favicon_id, &favicon_bitmaps));
  EXPECT_EQ(2u, favicon_bitmaps.size());
  FaviconBitmapID small_bitmap_id = favicon_bitmaps[0].bitmap_id;
  EXPECT_NE(0, small_bitmap_id);
  EXPECT_TRUE(BitmapDataEqual('a', favicon_bitmaps[0].bitmap_data));
  EXPECT_EQ(kSmallSize, favicon_bitmaps[0].pixel_size);
  FaviconBitmapID large_bitmap_id = favicon_bitmaps[1].bitmap_id;
  EXPECT_NE(0, large_bitmap_id);
  EXPECT_TRUE(BitmapDataEqual('b', favicon_bitmaps[1].bitmap_data));
  EXPECT_EQ(kLargeSize, favicon_bitmaps[1].pixel_size);

  // Call SetFavicons() with bitmap data for only the large bitmap. Check that
  // the small bitmap is in fact deleted.
  GenerateFaviconBitmapData(icon_url, GetSizesLarge(), &favicon_bitmap_data);
  backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);

  scoped_refptr<base::RefCountedMemory> bitmap_data_out;
  gfx::Size pixel_size_out;
  EXPECT_FALSE(backend_->thumbnail_db_->GetFaviconBitmap(small_bitmap_id,
      NULL, &bitmap_data_out, &pixel_size_out));
  EXPECT_TRUE(backend_->thumbnail_db_->GetFaviconBitmap(large_bitmap_id,
      NULL, &bitmap_data_out, &pixel_size_out));
  EXPECT_TRUE(BitmapDataEqual('a', bitmap_data_out));
  EXPECT_EQ(kLargeSize, pixel_size_out);

  icon_mappings.clear();
  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
      &icon_mappings));
  EXPECT_EQ(1u, icon_mappings.size());
  EXPECT_EQ(favicon_id, icon_mappings[0].icon_id);

  // Call SetFavicons() with no bitmap data. Check that the bitmaps and icon
  // mappings are deleted.
  favicon_bitmap_data.clear();
  backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);

  EXPECT_FALSE(backend_->thumbnail_db_->GetFaviconBitmap(large_bitmap_id, NULL,
      NULL, NULL));
  icon_mappings.clear();
  EXPECT_FALSE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
      &icon_mappings));

  // Notifications should have been broadcast for each call to SetFavicons().
  EXPECT_EQ(3, num_broadcasted_notifications());
}

// Test updating a single favicon bitmap's data via SetFavicons.
TEST_F(HistoryBackendTest, SetFaviconsReplaceBitmapData) {
  const GURL page_url("http://www.google.com/");
  const GURL icon_url("http://www.google.com/icon");

  std::vector<unsigned char> data_initial;
  data_initial.push_back('a');

  chrome::FaviconBitmapData bitmap_data_element;
  bitmap_data_element.bitmap_data =
      base::RefCountedBytes::TakeVector(&data_initial);
  bitmap_data_element.pixel_size = kSmallSize;
  bitmap_data_element.icon_url = icon_url;
  std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
  favicon_bitmap_data.push_back(bitmap_data_element);

  // Add bitmap to the database.
  backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);

  chrome::FaviconID original_favicon_id =
      backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
          icon_url, chrome::FAVICON, NULL);
  EXPECT_NE(0, original_favicon_id);
  FaviconBitmap original_favicon_bitmap;
  EXPECT_TRUE(
      GetOnlyFaviconBitmap(original_favicon_id, &original_favicon_bitmap));
  EXPECT_TRUE(BitmapDataEqual('a', original_favicon_bitmap.bitmap_data));

  EXPECT_EQ(1, num_broadcasted_notifications());

  // Call SetFavicons() with completely identical data.
  std::vector<unsigned char> updated_data;
  updated_data.push_back('a');
  favicon_bitmap_data[0].bitmap_data = new base::RefCountedBytes(updated_data);
  backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);

  chrome::FaviconID updated_favicon_id =
      backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
          icon_url, chrome::FAVICON, NULL);
  EXPECT_NE(0, updated_favicon_id);
  FaviconBitmap updated_favicon_bitmap;
  EXPECT_TRUE(
      GetOnlyFaviconBitmap(updated_favicon_id, &updated_favicon_bitmap));
  EXPECT_TRUE(BitmapDataEqual('a', updated_favicon_bitmap.bitmap_data));

  // Because the bitmap data is byte equivalent, no notifications should have
  // been broadcasted.
  EXPECT_EQ(1, num_broadcasted_notifications());

  // Call SetFavicons() with identical data but a different bitmap.
  updated_data[0] = 'b';
  favicon_bitmap_data[0].bitmap_data = new base::RefCountedBytes(updated_data);
  backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);

  updated_favicon_id =
      backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
          icon_url, chrome::FAVICON, NULL);
  EXPECT_NE(0, updated_favicon_id);
  EXPECT_TRUE(
      GetOnlyFaviconBitmap(updated_favicon_id, &updated_favicon_bitmap));
  EXPECT_TRUE(BitmapDataEqual('b', updated_favicon_bitmap.bitmap_data));

  // There should be no churn in FaviconIDs or FaviconBitmapIds even though
  // the bitmap data changed.
  EXPECT_EQ(original_favicon_bitmap.icon_id, updated_favicon_bitmap.icon_id);
  EXPECT_EQ(original_favicon_bitmap.bitmap_id,
            updated_favicon_bitmap.bitmap_id);

  // A notification should have been broadcasted as the favicon bitmap data has
  // changed.
  EXPECT_EQ(2, num_broadcasted_notifications());
}

// Test that if two pages share the same FaviconID, changing the favicon for
// one page does not affect the other.
TEST_F(HistoryBackendTest, SetFaviconsSameFaviconURLForTwoPages) {
  GURL icon_url("http://www.google.com/favicon.ico");
  GURL icon_url_new("http://www.google.com/favicon2.ico");
  GURL page_url1("http://www.google.com");
  GURL page_url2("http://www.google.ca");

  std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
  GenerateFaviconBitmapData(icon_url, GetSizesSmallAndLarge(),
                            &favicon_bitmap_data);

  backend_->SetFavicons(page_url1, chrome::FAVICON, favicon_bitmap_data);

  std::vector<GURL> icon_urls;
  icon_urls.push_back(icon_url);

  std::vector<chrome::FaviconBitmapResult> bitmap_results;
  backend_->UpdateFaviconMappingsAndFetch(
      page_url2, icon_urls, chrome::FAVICON, kSmallSize.width(),
      GetScaleFactors1x2x(), &bitmap_results);

  // Check that the same FaviconID is mapped to both page URLs.
  std::vector<IconMapping> icon_mappings;
  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(
      page_url1, &icon_mappings));
  EXPECT_EQ(1u, icon_mappings.size());
  chrome::FaviconID favicon_id = icon_mappings[0].icon_id;
  EXPECT_NE(0, favicon_id);

  icon_mappings.clear();
  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(
      page_url2, &icon_mappings));
  EXPECT_EQ(1u, icon_mappings.size());
  EXPECT_EQ(favicon_id, icon_mappings[0].icon_id);

  // Change the icon URL that |page_url1| is mapped to.
  GenerateFaviconBitmapData(icon_url_new, GetSizesSmall(),
                            &favicon_bitmap_data);
  backend_->SetFavicons(page_url1, chrome::FAVICON, favicon_bitmap_data);

  // |page_url1| should map to a new FaviconID and have valid bitmap data.
  icon_mappings.clear();
  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(
      page_url1, &icon_mappings));
  EXPECT_EQ(1u, icon_mappings.size());
  EXPECT_EQ(icon_url_new, icon_mappings[0].icon_url);
  EXPECT_NE(favicon_id, icon_mappings[0].icon_id);

  std::vector<FaviconBitmap> favicon_bitmaps;
  EXPECT_TRUE(backend_->thumbnail_db_->GetFaviconBitmaps(
      icon_mappings[0].icon_id, &favicon_bitmaps));
  EXPECT_EQ(1u, favicon_bitmaps.size());

  // |page_url2| should still map to the same FaviconID and have valid bitmap
  // data.
  icon_mappings.clear();
  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(
      page_url2, &icon_mappings));
  EXPECT_EQ(1u, icon_mappings.size());
  EXPECT_EQ(favicon_id, icon_mappings[0].icon_id);

  favicon_bitmaps.clear();
  EXPECT_TRUE(backend_->thumbnail_db_->GetFaviconBitmaps(favicon_id,
                                                         &favicon_bitmaps));
  EXPECT_EQ(2u, favicon_bitmaps.size());

  // A notification should have been broadcast for each call to SetFavicons()
  // and each call to UpdateFaviconMappingsAndFetch().
  EXPECT_EQ(3, num_broadcasted_notifications());
}

// Test that no notifications are broadcast as a result of calling
// UpdateFaviconMappingsAndFetch() for an icon URL which is already
// mapped to the passed in page URL.
TEST_F(HistoryBackendTest, UpdateFaviconMappingsAndFetchNoChange) {
  GURL page_url("http://www.google.com");
  GURL icon_url("http://www.google.com/favicon.ico");
  std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
  GenerateFaviconBitmapData(icon_url, GetSizesSmall(), &favicon_bitmap_data);

  backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);

  chrome::FaviconID icon_id =
    backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
        icon_url, chrome::FAVICON, NULL);
  EXPECT_NE(0, icon_id);
  EXPECT_EQ(1, num_broadcasted_notifications());

  std::vector<GURL> icon_urls;
  icon_urls.push_back(icon_url);

  std::vector<chrome::FaviconBitmapResult> bitmap_results;
  backend_->UpdateFaviconMappingsAndFetch(
      page_url, icon_urls, chrome::FAVICON, kSmallSize.width(),
      GetScaleFactors1x2x(), &bitmap_results);

  EXPECT_EQ(icon_id, backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
      icon_url, chrome::FAVICON, NULL));

  // No notification should have been broadcast as no icon mapping, favicon,
  // or favicon bitmap was updated, added or removed.
  EXPECT_EQ(1, num_broadcasted_notifications());
}

// Test repeatedly calling MergeFavicon(). |page_url| is initially not known
// to the database.
TEST_F(HistoryBackendTest, MergeFaviconPageURLNotInDB) {
  GURL page_url("http://www.google.com");
  GURL icon_url("http:/www.google.com/favicon.ico");

  std::vector<unsigned char> data;
  data.push_back('a');
  scoped_refptr<base::RefCountedBytes> bitmap_data(
      new base::RefCountedBytes(data));

  backend_->MergeFavicon(
      page_url, icon_url, chrome::FAVICON, bitmap_data, kSmallSize);

  // |page_url| should now be mapped to |icon_url| and the favicon bitmap should
  // not be expired.
  std::vector<IconMapping> icon_mappings;
  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
      &icon_mappings));
  EXPECT_EQ(1u, icon_mappings.size());
  EXPECT_EQ(icon_url, icon_mappings[0].icon_url);

  FaviconBitmap favicon_bitmap;
  EXPECT_TRUE(GetOnlyFaviconBitmap(icon_mappings[0].icon_id, &favicon_bitmap));
  EXPECT_NE(base::Time(), favicon_bitmap.last_updated);
  EXPECT_TRUE(BitmapDataEqual('a', favicon_bitmap.bitmap_data));
  EXPECT_EQ(kSmallSize, favicon_bitmap.pixel_size);

  data[0] = 'b';
  bitmap_data = new base::RefCountedBytes(data);
  backend_->MergeFavicon(
      page_url, icon_url, chrome::FAVICON, bitmap_data, kSmallSize);

  // |page_url| should still have a single favicon bitmap. The bitmap data
  // should be updated.
  icon_mappings.clear();
  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
      &icon_mappings));
  EXPECT_EQ(1u, icon_mappings.size());
  EXPECT_EQ(icon_url, icon_mappings[0].icon_url);

  EXPECT_TRUE(GetOnlyFaviconBitmap(icon_mappings[0].icon_id, &favicon_bitmap));
  EXPECT_NE(base::Time(), favicon_bitmap.last_updated);
  EXPECT_TRUE(BitmapDataEqual('b', favicon_bitmap.bitmap_data));
  EXPECT_EQ(kSmallSize, favicon_bitmap.pixel_size);
}

// Test calling MergeFavicon() when |page_url| is known to the database.
TEST_F(HistoryBackendTest, MergeFaviconPageURLInDB) {
  GURL page_url("http://www.google.com");
  GURL icon_url1("http:/www.google.com/favicon.ico");
  GURL icon_url2("http://www.google.com/favicon2.ico");

  std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
  GenerateFaviconBitmapData(icon_url1, GetSizesSmall(),
                            &favicon_bitmap_data);

  backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);

  // Test initial state.
  std::vector<IconMapping> icon_mappings;
  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
      &icon_mappings));
  EXPECT_EQ(1u, icon_mappings.size());
  EXPECT_EQ(icon_url1, icon_mappings[0].icon_url);

  FaviconBitmap favicon_bitmap;
  EXPECT_TRUE(GetOnlyFaviconBitmap(icon_mappings[0].icon_id, &favicon_bitmap));
  EXPECT_NE(base::Time(), favicon_bitmap.last_updated);
  EXPECT_TRUE(BitmapDataEqual('a', favicon_bitmap.bitmap_data));
  EXPECT_EQ(kSmallSize, favicon_bitmap.pixel_size);

  EXPECT_EQ(1, num_broadcasted_notifications());

  // 1) Merge identical favicon bitmap.
  std::vector<unsigned char> data;
  data.push_back('a');
  scoped_refptr<base::RefCountedBytes> bitmap_data(
      new base::RefCountedBytes(data));
  backend_->MergeFavicon(
      page_url, icon_url1, chrome::FAVICON, bitmap_data, kSmallSize);

  // All the data should stay the same and no notifications should have been
  // sent.
  icon_mappings.clear();
  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
      &icon_mappings));
  EXPECT_EQ(1u, icon_mappings.size());
  EXPECT_EQ(icon_url1, icon_mappings[0].icon_url);

  EXPECT_TRUE(GetOnlyFaviconBitmap(icon_mappings[0].icon_id, &favicon_bitmap));
  EXPECT_NE(base::Time(), favicon_bitmap.last_updated);
  EXPECT_TRUE(BitmapDataEqual('a', favicon_bitmap.bitmap_data));
  EXPECT_EQ(kSmallSize, favicon_bitmap.pixel_size);

  EXPECT_EQ(1, num_broadcasted_notifications());

  // 2) Merge favicon bitmap of the same size.
  data[0] = 'b';
  bitmap_data = new base::RefCountedBytes(data);
  backend_->MergeFavicon(
      page_url, icon_url1, chrome::FAVICON, bitmap_data, kSmallSize);

  // The small favicon bitmap at |icon_url1| should be overwritten.
  icon_mappings.clear();
  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
      &icon_mappings));
  EXPECT_EQ(1u, icon_mappings.size());
  EXPECT_EQ(icon_url1, icon_mappings[0].icon_url);

  EXPECT_TRUE(GetOnlyFaviconBitmap(icon_mappings[0].icon_id, &favicon_bitmap));
  EXPECT_NE(base::Time(), favicon_bitmap.last_updated);
  EXPECT_TRUE(BitmapDataEqual('b', favicon_bitmap.bitmap_data));
  EXPECT_EQ(kSmallSize, favicon_bitmap.pixel_size);

  // 3) Merge favicon for the same icon URL, but a pixel size for which there is
  // no favicon bitmap.
  data[0] = 'c';
  bitmap_data = new base::RefCountedBytes(data);
  backend_->MergeFavicon(
      page_url, icon_url1, chrome::FAVICON, bitmap_data, kTinySize);

  // A new favicon bitmap should be created and the preexisting favicon bitmap
  // ('b') should be expired.
  icon_mappings.clear();
  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
      &icon_mappings));
  EXPECT_EQ(1u, icon_mappings.size());
  EXPECT_EQ(icon_url1, icon_mappings[0].icon_url);

  std::vector<FaviconBitmap> favicon_bitmaps;
  EXPECT_TRUE(GetSortedFaviconBitmaps(icon_mappings[0].icon_id,
                                      &favicon_bitmaps));
  EXPECT_NE(base::Time(), favicon_bitmaps[0].last_updated);
  EXPECT_TRUE(BitmapDataEqual('c', favicon_bitmaps[0].bitmap_data));
  EXPECT_EQ(kTinySize, favicon_bitmaps[0].pixel_size);
  EXPECT_EQ(base::Time(), favicon_bitmaps[1].last_updated);
  EXPECT_TRUE(BitmapDataEqual('b', favicon_bitmaps[1].bitmap_data));
  EXPECT_EQ(kSmallSize, favicon_bitmaps[1].pixel_size);

  // 4) Merge favicon for an icon URL different from the icon URLs already
  // mapped to page URL.
  data[0] = 'd';
  bitmap_data = new base::RefCountedBytes(data);
  backend_->MergeFavicon(
      page_url, icon_url2, chrome::FAVICON, bitmap_data, kSmallSize);

  // The existing favicon bitmaps should be copied over to the newly created
  // favicon at |icon_url2|. |page_url| should solely be mapped to |icon_url2|.
  icon_mappings.clear();
  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
      &icon_mappings));
  EXPECT_EQ(1u, icon_mappings.size());
  EXPECT_EQ(icon_url2, icon_mappings[0].icon_url);

  favicon_bitmaps.clear();
  EXPECT_TRUE(GetSortedFaviconBitmaps(icon_mappings[0].icon_id,
                                      &favicon_bitmaps));
  EXPECT_EQ(base::Time(), favicon_bitmaps[0].last_updated);
  EXPECT_TRUE(BitmapDataEqual('c', favicon_bitmaps[0].bitmap_data));
  EXPECT_EQ(kTinySize, favicon_bitmaps[0].pixel_size);
  // The favicon being merged should take precedence over the preexisting
  // favicon bitmaps.
  EXPECT_NE(base::Time(), favicon_bitmaps[1].last_updated);
  EXPECT_TRUE(BitmapDataEqual('d', favicon_bitmaps[1].bitmap_data));
  EXPECT_EQ(kSmallSize, favicon_bitmaps[1].pixel_size);

  // A notification should have been broadcast for each call to SetFavicons()
  // and MergeFavicon().
  EXPECT_EQ(4, num_broadcasted_notifications());
}

// Test calling MergeFavicon() when |icon_url| is known to the database but not
// mapped to |page_url|.
TEST_F(HistoryBackendTest, MergeFaviconIconURLMappedToDifferentPageURL) {
  GURL page_url1("http://www.google.com");
  GURL page_url2("http://news.google.com");
  GURL page_url3("http://maps.google.com");
  GURL icon_url("http:/www.google.com/favicon.ico");

  std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
  GenerateFaviconBitmapData(icon_url, GetSizesSmall(),
                            &favicon_bitmap_data);

  backend_->SetFavicons(page_url1, chrome::FAVICON, favicon_bitmap_data);

  // Test initial state.
  std::vector<IconMapping> icon_mappings;
  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url1,
      &icon_mappings));
  EXPECT_EQ(1u, icon_mappings.size());
  EXPECT_EQ(icon_url, icon_mappings[0].icon_url);

  FaviconBitmap favicon_bitmap;
  EXPECT_TRUE(GetOnlyFaviconBitmap(icon_mappings[0].icon_id, &favicon_bitmap));
  EXPECT_NE(base::Time(), favicon_bitmap.last_updated);
  EXPECT_TRUE(BitmapDataEqual('a', favicon_bitmap.bitmap_data));
  EXPECT_EQ(kSmallSize, favicon_bitmap.pixel_size);

  // 1) Merge in an identical favicon bitmap data but for a different page URL.
  std::vector<unsigned char> data;
  data.push_back('a');
  scoped_refptr<base::RefCountedBytes> bitmap_data(
      new base::RefCountedBytes(data));

  backend_->MergeFavicon(
      page_url2, icon_url, chrome::FAVICON, bitmap_data, kSmallSize);

  chrome::FaviconID favicon_id =
    backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
        icon_url, chrome::FAVICON, NULL);
  EXPECT_NE(0, favicon_id);

  EXPECT_TRUE(GetOnlyFaviconBitmap(favicon_id, &favicon_bitmap));
  EXPECT_NE(base::Time(), favicon_bitmap.last_updated);
  EXPECT_TRUE(BitmapDataEqual('a', favicon_bitmap.bitmap_data));
  EXPECT_EQ(kSmallSize, favicon_bitmap.pixel_size);

  // 2) Merging a favicon bitmap with different bitmap data for the same icon
  // URL should overwrite the small favicon bitmap at |icon_url|.
  bitmap_data->data()[0] = 'b';
  backend_->MergeFavicon(
      page_url3, icon_url, chrome::FAVICON, bitmap_data, kSmallSize);

  favicon_id = backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
      icon_url, chrome::FAVICON, NULL);
  EXPECT_NE(0, favicon_id);

  EXPECT_TRUE(GetOnlyFaviconBitmap(favicon_id, &favicon_bitmap));
  EXPECT_NE(base::Time(), favicon_bitmap.last_updated);
  EXPECT_TRUE(BitmapDataEqual('b', favicon_bitmap.bitmap_data));
  EXPECT_EQ(kSmallSize, favicon_bitmap.pixel_size);

  // |icon_url| should be mapped to all three page URLs.
  icon_mappings.clear();
  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url1,
      &icon_mappings));
  EXPECT_EQ(1u, icon_mappings.size());
  EXPECT_EQ(favicon_id, icon_mappings[0].icon_id);

  icon_mappings.clear();
  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url2,
      &icon_mappings));
  EXPECT_EQ(1u, icon_mappings.size());
  EXPECT_EQ(favicon_id, icon_mappings[0].icon_id);

  icon_mappings.clear();
  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url3,
      &icon_mappings));
  EXPECT_EQ(1u, icon_mappings.size());
  EXPECT_EQ(favicon_id, icon_mappings[0].icon_id);

  // A notification should have been broadcast for each call to SetFavicons()
  // and MergeFavicon().
  EXPECT_EQ(3, num_broadcasted_notifications());
}

// Test that MergeFavicon() does not add more than
// |kMaxFaviconBitmapsPerIconURL| to a favicon.
TEST_F(HistoryBackendTest, MergeFaviconMaxFaviconBitmapsPerIconURL) {
  GURL page_url("http://www.google.com");
  std::string icon_url_string("http://www.google.com/favicon.ico");
  size_t replace_index = icon_url_string.size() - 1;

  std::vector<unsigned char> data;
  data.push_back('a');
  scoped_refptr<base::RefCountedMemory> bitmap_data =
      base::RefCountedBytes::TakeVector(&data);

  int pixel_size = 1;
  for (size_t i = 0; i < kMaxFaviconBitmapsPerIconURL + 1; ++i) {
    icon_url_string[replace_index] = '0' + i;
    GURL icon_url(icon_url_string);

    backend_->MergeFavicon(page_url, icon_url, chrome::FAVICON, bitmap_data,
                           gfx::Size(pixel_size, pixel_size));
    ++pixel_size;
  }

  // There should be a single favicon mapped to |page_url| with exactly
  // kMaxFaviconBitmapsPerIconURL favicon bitmaps.
  std::vector<IconMapping> icon_mappings;
  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
      &icon_mappings));
  EXPECT_EQ(1u, icon_mappings.size());
  std::vector<FaviconBitmap> favicon_bitmaps;
  EXPECT_TRUE(backend_->thumbnail_db_->GetFaviconBitmaps(
      icon_mappings[0].icon_id, &favicon_bitmaps));
  EXPECT_EQ(kMaxFaviconBitmapsPerIconURL, favicon_bitmaps.size());
}

// Tests that the favicon set by MergeFavicon() shows up in the result of
// GetFaviconsForURL().
TEST_F(HistoryBackendTest, MergeFaviconShowsUpInGetFaviconsForURLResult) {
  GURL page_url("http://www.google.com");
  GURL icon_url("http://www.google.com/favicon.ico");
  GURL merged_icon_url("http://wwww.google.com/favicon2.ico");

  std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
  GenerateFaviconBitmapData(icon_url, GetSizesSmallAndLarge(),
                            &favicon_bitmap_data);

  // Set some preexisting favicons for |page_url|.
  backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);

  // Merge small favicon.
  std::vector<unsigned char> data;
  data.push_back('c');
  scoped_refptr<base::RefCountedBytes> bitmap_data(
      new base::RefCountedBytes(data));
  backend_->MergeFavicon(
      page_url, merged_icon_url, chrome::FAVICON, bitmap_data, kSmallSize);

  // Request favicon bitmaps for both 1x and 2x to simulate request done by
  // BookmarkModel::GetFavicon().
  std::vector<chrome::FaviconBitmapResult> bitmap_results;
  backend_->GetFaviconsForURL(page_url, chrome::FAVICON, kSmallSize.width(),
                              GetScaleFactors1x2x(), &bitmap_results);

  EXPECT_EQ(2u, bitmap_results.size());
  const chrome::FaviconBitmapResult& first_result = bitmap_results[0];
  const chrome::FaviconBitmapResult& result =
      (first_result.pixel_size == kSmallSize) ? first_result
                                              : bitmap_results[1];
  EXPECT_TRUE(BitmapDataEqual('c', result.bitmap_data));
}

// Tests GetFaviconsForURL with icon_types priority,
TEST_F(HistoryBackendTest, TestGetFaviconsForURLWithIconTypesPriority) {
  GURL page_url("http://www.google.com");
  GURL icon_url("http://www.google.com/favicon.ico");
  GURL touch_icon_url("http://wwww.google.com/touch_icon.ico");

  std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
  std::vector<gfx::Size> favicon_size;
  favicon_size.push_back(gfx::Size(16, 16));
  favicon_size.push_back(gfx::Size(32, 32));
  GenerateFaviconBitmapData(icon_url, favicon_size, &favicon_bitmap_data);
  ASSERT_EQ(2u, favicon_bitmap_data.size());

  std::vector<chrome::FaviconBitmapData> touch_icon_bitmap_data;
  std::vector<gfx::Size> touch_icon_size;
  touch_icon_size.push_back(gfx::Size(64, 64));
  GenerateFaviconBitmapData(icon_url, touch_icon_size, &touch_icon_bitmap_data);
  ASSERT_EQ(1u, touch_icon_bitmap_data.size());

  // Set some preexisting favicons for |page_url|.
  backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);
  backend_->SetFavicons(page_url, chrome::TOUCH_ICON, touch_icon_bitmap_data);

  chrome::FaviconBitmapResult result;
  std::vector<int> icon_types;
  icon_types.push_back(chrome::FAVICON);
  icon_types.push_back(chrome::TOUCH_ICON);

  backend_->GetLargestFaviconForURL(page_url, icon_types, 16, &result);

  // Verify the result icon is 32x32 favicon.
  EXPECT_EQ(gfx::Size(32, 32), result.pixel_size);
  EXPECT_EQ(chrome::FAVICON, result.icon_type);

  // Change Minimal size to 32x32 and verify the 64x64 touch icon returned.
  backend_->GetLargestFaviconForURL(page_url, icon_types, 32, &result);
  EXPECT_EQ(gfx::Size(64, 64), result.pixel_size);
  EXPECT_EQ(chrome::TOUCH_ICON, result.icon_type);
}

// Test the the first types of icon is returned if its size equal to the
// second types icon.
TEST_F(HistoryBackendTest, TestGetFaviconsForURLReturnFavicon) {
  GURL page_url("http://www.google.com");
  GURL icon_url("http://www.google.com/favicon.ico");
  GURL touch_icon_url("http://wwww.google.com/touch_icon.ico");

  std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
  std::vector<gfx::Size> favicon_size;
  favicon_size.push_back(gfx::Size(16, 16));
  favicon_size.push_back(gfx::Size(32, 32));
  GenerateFaviconBitmapData(icon_url, favicon_size, &favicon_bitmap_data);
  ASSERT_EQ(2u, favicon_bitmap_data.size());

  std::vector<chrome::FaviconBitmapData> touch_icon_bitmap_data;
  std::vector<gfx::Size> touch_icon_size;
  touch_icon_size.push_back(gfx::Size(32, 32));
  GenerateFaviconBitmapData(icon_url, touch_icon_size, &touch_icon_bitmap_data);
  ASSERT_EQ(1u, touch_icon_bitmap_data.size());

  // Set some preexisting favicons for |page_url|.
  backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);
  backend_->SetFavicons(page_url, chrome::TOUCH_ICON, touch_icon_bitmap_data);

  chrome::FaviconBitmapResult result;
  std::vector<int> icon_types;
  icon_types.push_back(chrome::FAVICON);
  icon_types.push_back(chrome::TOUCH_ICON);

  backend_->GetLargestFaviconForURL(page_url, icon_types, 16, &result);

  // Verify the result icon is 32x32 favicon.
  EXPECT_EQ(gfx::Size(32, 32), result.pixel_size);
  EXPECT_EQ(chrome::FAVICON, result.icon_type);

  // Change minimal size to 32x32 and verify the 32x32 favicon returned.
  chrome::FaviconBitmapResult result1;
  backend_->GetLargestFaviconForURL(page_url, icon_types, 32, &result1);
  EXPECT_EQ(gfx::Size(32, 32), result1.pixel_size);
  EXPECT_EQ(chrome::FAVICON, result1.icon_type);
}

// Test the favicon is returned if its size is smaller than minimal size,
// because it is only one available.
TEST_F(HistoryBackendTest, TestGetFaviconsForURLReturnFaviconEvenItSmaller) {
  GURL page_url("http://www.google.com");
  GURL icon_url("http://www.google.com/favicon.ico");

  std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
  std::vector<gfx::Size> favicon_size;
  favicon_size.push_back(gfx::Size(16, 16));
  GenerateFaviconBitmapData(icon_url, favicon_size, &favicon_bitmap_data);
  ASSERT_EQ(1u, favicon_bitmap_data.size());

  // Set preexisting favicons for |page_url|.
  backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);

  chrome::FaviconBitmapResult result;
  std::vector<int> icon_types;
  icon_types.push_back(chrome::FAVICON);
  icon_types.push_back(chrome::TOUCH_ICON);

  backend_->GetLargestFaviconForURL(page_url, icon_types, 32, &result);

  // Verify 16x16 icon is returned, even it small than minimal_size.
  EXPECT_EQ(gfx::Size(16, 16), result.pixel_size);
  EXPECT_EQ(chrome::FAVICON, result.icon_type);
}

// Test UpdateFaviconMapingsAndFetch() when multiple icon types are passed in.
TEST_F(HistoryBackendTest, UpdateFaviconMappingsAndFetchMultipleIconTypes) {
  GURL page_url1("http://www.google.com");
  GURL page_url2("http://news.google.com");
  GURL page_url3("http://mail.google.com");
  GURL icon_urla("http://www.google.com/favicon1.ico");
  GURL icon_urlb("http://www.google.com/favicon2.ico");
  GURL icon_urlc("http://www.google.com/favicon3.ico");

  // |page_url1| is mapped to |icon_urla| which if of type TOUCH_ICON.
  std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
  GenerateFaviconBitmapData(icon_urla, GetSizesSmall(), &favicon_bitmap_data);
  backend_->SetFavicons(page_url1, chrome::TOUCH_ICON, favicon_bitmap_data);

  // |page_url2| is mapped to |icon_urlb| and |icon_urlc| which are of type
  // TOUCH_PRECOMPOSED_ICON.
  GenerateFaviconBitmapData(icon_urlb, GetSizesSmall(), icon_urlc,
                            GetSizesSmall(), &favicon_bitmap_data);
  backend_->SetFavicons(
      page_url2, chrome::TOUCH_PRECOMPOSED_ICON, favicon_bitmap_data);

  std::vector<GURL> icon_urls;
  icon_urls.push_back(icon_urla);
  icon_urls.push_back(icon_urlb);
  icon_urls.push_back(icon_urlc);

  std::vector<chrome::FaviconBitmapResult> bitmap_results;
  backend_->UpdateFaviconMappingsAndFetch(
      page_url3,
      icon_urls,
      (chrome::TOUCH_ICON | chrome::TOUCH_PRECOMPOSED_ICON),
      kSmallSize.width(),
      GetScaleFactors1x2x(),
      &bitmap_results);

  // |page_url1| and |page_url2| should still be mapped to the same icon URLs.
  std::vector<IconMapping> icon_mappings;
  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url1,
      &icon_mappings));
  EXPECT_EQ(1u, icon_mappings.size());
  EXPECT_EQ(icon_urla, icon_mappings[0].icon_url);
  EXPECT_EQ(chrome::TOUCH_ICON, icon_mappings[0].icon_type);

  icon_mappings.clear();
  EXPECT_TRUE(GetSortedIconMappingsForPageURL(page_url2, &icon_mappings));
  EXPECT_EQ(2u, icon_mappings.size());
  EXPECT_EQ(icon_urlb, icon_mappings[0].icon_url);
  EXPECT_EQ(chrome::TOUCH_PRECOMPOSED_ICON, icon_mappings[0].icon_type);
  EXPECT_EQ(icon_urlc, icon_mappings[1].icon_url);
  EXPECT_EQ(chrome::TOUCH_PRECOMPOSED_ICON, icon_mappings[1].icon_type);

  // |page_url3| should be mapped only to |icon_urlb| and |icon_urlc| as
  // TOUCH_PRECOMPOSED_ICON is the largest IconType.
  icon_mappings.clear();
  EXPECT_TRUE(GetSortedIconMappingsForPageURL(page_url3, &icon_mappings));
  EXPECT_EQ(2u, icon_mappings.size());
  EXPECT_EQ(icon_urlb, icon_mappings[0].icon_url);
  EXPECT_EQ(chrome::TOUCH_PRECOMPOSED_ICON, icon_mappings[0].icon_type);
  EXPECT_EQ(icon_urlc, icon_mappings[1].icon_url);
  EXPECT_EQ(chrome::TOUCH_PRECOMPOSED_ICON, icon_mappings[1].icon_type);
}

// Test the results of GetFaviconsFromDB() when there are no found
// favicons.
TEST_F(HistoryBackendTest, GetFaviconsFromDBEmpty) {
  const GURL page_url("http://www.google.com/");

  std::vector<chrome::FaviconBitmapResult> bitmap_results;
  EXPECT_FALSE(backend_->GetFaviconsFromDB(page_url, chrome::FAVICON,
      kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results));
  EXPECT_TRUE(bitmap_results.empty());
}

// Test the results of GetFaviconsFromDB() when there are matching favicons
// but there are no associated favicon bitmaps.
TEST_F(HistoryBackendTest, GetFaviconsFromDBNoFaviconBitmaps) {
  const GURL page_url("http://www.google.com/");
  const GURL icon_url("http://www.google.com/icon1");

  chrome::FaviconID icon_id = backend_->thumbnail_db_->AddFavicon(
      icon_url, chrome::FAVICON);
  EXPECT_NE(0, icon_id);
  EXPECT_NE(0, backend_->thumbnail_db_->AddIconMapping(page_url, icon_id));

  std::vector<chrome::FaviconBitmapResult> bitmap_results_out;
  EXPECT_FALSE(backend_->GetFaviconsFromDB(page_url, chrome::FAVICON,
      kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out));
  EXPECT_TRUE(bitmap_results_out.empty());
}

// Test that GetFaviconsFromDB() returns results for the bitmaps which most
// closely match the passed in desired size and scale factors.
TEST_F(HistoryBackendTest, GetFaviconsFromDBSelectClosestMatch) {
  const GURL page_url("http://www.google.com/");
  const GURL icon_url("http://www.google.com/icon1");

  std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
  GenerateFaviconBitmapData(icon_url, GetSizesTinySmallAndLarge(),
                            &favicon_bitmap_data);

  backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);

  std::vector<chrome::FaviconBitmapResult> bitmap_results_out;
  EXPECT_TRUE(backend_->GetFaviconsFromDB(page_url,
                                          chrome::FAVICON,
                                          kSmallSize.width(),
                                          GetScaleFactors1x2x(),
                                          &bitmap_results_out));

  // The bitmap data for the small and large bitmaps should be returned as their
  // sizes match exactly.
  EXPECT_EQ(2u, bitmap_results_out.size());
  // No required order for results.
  if (bitmap_results_out[0].pixel_size == kLargeSize) {
    chrome::FaviconBitmapResult tmp_result = bitmap_results_out[0];
    bitmap_results_out[0] = bitmap_results_out[1];
    bitmap_results_out[1] = tmp_result;
  }

  EXPECT_FALSE(bitmap_results_out[0].expired);
  EXPECT_TRUE(BitmapDataEqual('b', bitmap_results_out[0].bitmap_data));
  EXPECT_EQ(kSmallSize, bitmap_results_out[0].pixel_size);
  EXPECT_EQ(icon_url, bitmap_results_out[0].icon_url);
  EXPECT_EQ(chrome::FAVICON, bitmap_results_out[0].icon_type);

  EXPECT_FALSE(bitmap_results_out[1].expired);
  EXPECT_TRUE(BitmapDataEqual('c', bitmap_results_out[1].bitmap_data));
  EXPECT_EQ(kLargeSize, bitmap_results_out[1].pixel_size);
  EXPECT_EQ(icon_url, bitmap_results_out[1].icon_url);
  EXPECT_EQ(chrome::FAVICON, bitmap_results_out[1].icon_type);
}

// Test that GetFaviconsFromDB() returns results from the icon URL whose
// bitmaps most closely match the passed in desired size and scale factors.
TEST_F(HistoryBackendTest, GetFaviconsFromDBSingleIconURL) {
  const GURL page_url("http://www.google.com/");

  const GURL icon_url1("http://www.google.com/icon1");
  const GURL icon_url2("http://www.google.com/icon2");

  std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
  GenerateFaviconBitmapData(icon_url1, GetSizesSmall(), icon_url2,
                            GetSizesLarge(), &favicon_bitmap_data);

  backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);

  std::vector<chrome::FaviconBitmapResult> bitmap_results_out;
  EXPECT_TRUE(backend_->GetFaviconsFromDB(page_url,
                                          chrome::FAVICON,
                                          kSmallSize.width(),
                                          GetScaleFactors1x2x(),
                                          &bitmap_results_out));

  // The results should have results for the icon URL with the large bitmap as
  // downscaling is preferred to upscaling.
  EXPECT_EQ(1u, bitmap_results_out.size());
  EXPECT_EQ(kLargeSize, bitmap_results_out[0].pixel_size);
  EXPECT_EQ(icon_url2, bitmap_results_out[0].icon_url);
}

// Test the results of GetFaviconsFromDB() when called with different
// |icon_types|.
TEST_F(HistoryBackendTest, GetFaviconsFromDBIconType) {
  const GURL page_url("http://www.google.com/");
  const GURL icon_url1("http://www.google.com/icon1.png");
  const GURL icon_url2("http://www.google.com/icon2.png");

  std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
  GenerateFaviconBitmapData(icon_url1, GetSizesSmall(),  &favicon_bitmap_data);
  backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);

  GenerateFaviconBitmapData(icon_url2, GetSizesSmall(), &favicon_bitmap_data);
  backend_->SetFavicons(page_url, chrome::TOUCH_ICON, favicon_bitmap_data);

  std::vector<chrome::FaviconBitmapResult> bitmap_results_out;
  EXPECT_TRUE(backend_->GetFaviconsFromDB(page_url, chrome::FAVICON,
      kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out));

  EXPECT_EQ(1u, bitmap_results_out.size());
  EXPECT_EQ(chrome::FAVICON, bitmap_results_out[0].icon_type);
  EXPECT_EQ(icon_url1, bitmap_results_out[0].icon_url);

  bitmap_results_out.clear();
  EXPECT_TRUE(backend_->GetFaviconsFromDB(page_url, chrome::TOUCH_ICON,
      kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out));

  EXPECT_EQ(1u, bitmap_results_out.size());
  EXPECT_EQ(chrome::TOUCH_ICON, bitmap_results_out[0].icon_type);
  EXPECT_EQ(icon_url2, bitmap_results_out[0].icon_url);
}

// Test that GetFaviconsFromDB() correctly sets the expired flag for bitmap
// reults.
TEST_F(HistoryBackendTest, GetFaviconsFromDBExpired) {
  const GURL page_url("http://www.google.com/");
  const GURL icon_url("http://www.google.com/icon.png");

  std::vector<unsigned char> data;
  data.push_back('a');
  scoped_refptr<base::RefCountedBytes> bitmap_data(
      base::RefCountedBytes::TakeVector(&data));
  base::Time last_updated = base::Time::FromTimeT(0);
  chrome::FaviconID icon_id =
      backend_->thumbnail_db_->AddFavicon(icon_url,
                                          chrome::FAVICON,
                                          bitmap_data,
                                          last_updated,
                                          kSmallSize);
  EXPECT_NE(0, icon_id);
  EXPECT_NE(0, backend_->thumbnail_db_->AddIconMapping(page_url, icon_id));

  std::vector<chrome::FaviconBitmapResult> bitmap_results_out;
  EXPECT_TRUE(backend_->GetFaviconsFromDB(page_url, chrome::FAVICON,
      kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out));

  EXPECT_EQ(1u, bitmap_results_out.size());
  EXPECT_TRUE(bitmap_results_out[0].expired);
}

// Check that UpdateFaviconMappingsAndFetch() call back to the UI when there is
// no valid thumbnail database.
TEST_F(HistoryBackendTest, UpdateFaviconMappingsAndFetchNoDB) {
  // Make the thumbnail database invalid.
  backend_->thumbnail_db_.reset();

  std::vector<chrome::FaviconBitmapResult> bitmap_results;

  backend_->UpdateFaviconMappingsAndFetch(
      GURL(), std::vector<GURL>(), chrome::FAVICON, kSmallSize.width(),
      GetScaleFactors1x2x(), &bitmap_results);

  EXPECT_TRUE(bitmap_results.empty());
}

TEST_F(HistoryBackendTest, CloneFaviconIsRestrictedToSameDomain) {
  const GURL url("http://www.google.com/");
  const GURL same_domain_url("http://www.google.com/subdir/index.html");
  const GURL foreign_domain_url("http://www.not-google.com/");
  const GURL icon_url("http://www.google.com/icon.png");

  // Add a favicon
  std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
  GenerateFaviconBitmapData(icon_url, GetSizesSmall(),  &favicon_bitmap_data);
  backend_->SetFavicons(url, chrome::FAVICON, favicon_bitmap_data);
  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(
      url, chrome::FAVICON, NULL));

  // Validate starting state.
  std::vector<chrome::FaviconBitmapResult> bitmap_results_out;
  EXPECT_TRUE(backend_->GetFaviconsFromDB(url, chrome::FAVICON,
      kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out));
  EXPECT_FALSE(backend_->GetFaviconsFromDB(same_domain_url, chrome::FAVICON,
      kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out));
  EXPECT_FALSE(backend_->GetFaviconsFromDB(foreign_domain_url, chrome::FAVICON,
      kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out));

  // Same-domain cloning should work.
  backend_->CloneFavicons(url, same_domain_url);
  EXPECT_TRUE(backend_->GetFaviconsFromDB(same_domain_url, chrome::FAVICON,
      kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out));

  // Foreign-domain cloning is forbidden.
  backend_->CloneFavicons(url, foreign_domain_url);
  EXPECT_FALSE(backend_->GetFaviconsFromDB(foreign_domain_url, chrome::FAVICON,
      kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out));
}

TEST_F(HistoryBackendTest, QueryFilteredURLs) {
  const char* google = "http://www.google.com/";
  const char* yahoo = "http://www.yahoo.com/";
  const char* yahoo_sports = "http://sports.yahoo.com/";
  const char* yahoo_sports_with_article1 =
      "http://sports.yahoo.com/article1.htm";
  const char* yahoo_sports_with_article2 =
      "http://sports.yahoo.com/article2.htm";
  const char* yahoo_sports_soccer = "http://sports.yahoo.com/soccer";
  const char* apple = "http://www.apple.com/";

  // Clear all history.
  backend_->DeleteAllHistory();

  Time tested_time = Time::Now().LocalMidnight() +
                     base::TimeDelta::FromHours(4);
  base::TimeDelta half_an_hour = base::TimeDelta::FromMinutes(30);
  base::TimeDelta one_hour = base::TimeDelta::FromHours(1);
  base::TimeDelta one_day = base::TimeDelta::FromDays(1);

  const content::PageTransition kTypedTransition =
      content::PAGE_TRANSITION_TYPED;
  const content::PageTransition kKeywordGeneratedTransition =
      content::PAGE_TRANSITION_KEYWORD_GENERATED;

  const char* redirect_sequence[2];
  redirect_sequence[1] = NULL;

  redirect_sequence[0] = google;
  AddRedirectChainWithTransitionAndTime(
      redirect_sequence, 0, kTypedTransition,
      tested_time - one_day - half_an_hour * 2);
  AddRedirectChainWithTransitionAndTime(
      redirect_sequence, 0,
      kTypedTransition, tested_time - one_day);
  AddRedirectChainWithTransitionAndTime(
      redirect_sequence, 0,
      kTypedTransition, tested_time - half_an_hour / 2);
  AddRedirectChainWithTransitionAndTime(
      redirect_sequence, 0,
      kTypedTransition, tested_time);

  // Add a visit with a transition that will make sure that no segment gets
  // created for this page (so the subsequent entries will have different URLIDs
  // and SegmentIDs).
  redirect_sequence[0] = apple;
  AddRedirectChainWithTransitionAndTime(
      redirect_sequence, 0, kKeywordGeneratedTransition,
      tested_time - one_day + one_hour * 6);

  redirect_sequence[0] = yahoo;
  AddRedirectChainWithTransitionAndTime(
      redirect_sequence, 0, kTypedTransition,
      tested_time - one_day + half_an_hour);
  AddRedirectChainWithTransitionAndTime(
      redirect_sequence, 0, kTypedTransition,
      tested_time - one_day + half_an_hour * 2);

  redirect_sequence[0] = yahoo_sports;
  AddRedirectChainWithTransitionAndTime(
      redirect_sequence, 0, kTypedTransition,
      tested_time - one_day - half_an_hour * 2);
  AddRedirectChainWithTransitionAndTime(
      redirect_sequence, 0, kTypedTransition,
      tested_time - one_day);
  int transition1, transition2;
  AddClientRedirect(GURL(yahoo_sports), GURL(yahoo_sports_with_article1), false,
                    tested_time - one_day + half_an_hour,
                    &transition1, &transition2);
  AddClientRedirect(GURL(yahoo_sports_with_article1),
                    GURL(yahoo_sports_with_article2),
                    false,
                    tested_time - one_day + half_an_hour * 2,
                    &transition1, &transition2);

  redirect_sequence[0] = yahoo_sports_soccer;
  AddRedirectChainWithTransitionAndTime(redirect_sequence, 0,
                                        kTypedTransition,
                                        tested_time - half_an_hour);
  backend_->Commit();

  scoped_refptr<QueryFilteredURLsRequest> request1 =
      new history::QueryFilteredURLsRequest(
          base::Bind(&HistoryBackendTest::OnQueryFiltered,
                     base::Unretained(static_cast<HistoryBackendTest*>(this))));
  HistoryBackendCancelableRequest cancellable_request;
  cancellable_request.MockScheduleOfRequest<QueryFilteredURLsRequest>(
      request1.get());

  VisitFilter filter;
  // Time limit is |tested_time| +/- 45 min.
  base::TimeDelta three_quarters_of_an_hour = base::TimeDelta::FromMinutes(45);
  filter.SetFilterTime(tested_time);
  filter.SetFilterWidth(three_quarters_of_an_hour);
  backend_->QueryFilteredURLs(request1, 100, filter, false);

  ASSERT_EQ(4U, get_filtered_list().size());
  EXPECT_EQ(std::string(google), get_filtered_list()[0].url.spec());
  EXPECT_EQ(std::string(yahoo_sports_soccer),
            get_filtered_list()[1].url.spec());
  EXPECT_EQ(std::string(yahoo), get_filtered_list()[2].url.spec());
  EXPECT_EQ(std::string(yahoo_sports),
            get_filtered_list()[3].url.spec());

  // Time limit is between |tested_time| and |tested_time| + 2 hours.
  scoped_refptr<QueryFilteredURLsRequest> request2 =
      new history::QueryFilteredURLsRequest(
          base::Bind(&HistoryBackendTest::OnQueryFiltered,
                     base::Unretained(static_cast<HistoryBackendTest*>(this))));
  cancellable_request.MockScheduleOfRequest<QueryFilteredURLsRequest>(
      request2.get());
  filter.SetFilterTime(tested_time + one_hour);
  filter.SetFilterWidth(one_hour);
  backend_->QueryFilteredURLs(request2, 100, filter, false);

  ASSERT_EQ(3U, get_filtered_list().size());
  EXPECT_EQ(std::string(google), get_filtered_list()[0].url.spec());
  EXPECT_EQ(std::string(yahoo), get_filtered_list()[1].url.spec());
  EXPECT_EQ(std::string(yahoo_sports), get_filtered_list()[2].url.spec());

  // Time limit is between |tested_time| - 2 hours and |tested_time|.
  scoped_refptr<QueryFilteredURLsRequest> request3 =
      new history::QueryFilteredURLsRequest(
          base::Bind(&HistoryBackendTest::OnQueryFiltered,
                     base::Unretained(static_cast<HistoryBackendTest*>(this))));
  cancellable_request.MockScheduleOfRequest<QueryFilteredURLsRequest>(
      request3.get());
  filter.SetFilterTime(tested_time - one_hour);
  filter.SetFilterWidth(one_hour);
  backend_->QueryFilteredURLs(request3, 100, filter, false);

  ASSERT_EQ(3U, get_filtered_list().size());
  EXPECT_EQ(std::string(google), get_filtered_list()[0].url.spec());
  EXPECT_EQ(std::string(yahoo_sports_soccer),
            get_filtered_list()[1].url.spec());
  EXPECT_EQ(std::string(yahoo_sports), get_filtered_list()[2].url.spec());

  filter.ClearFilters();
  base::Time::Exploded exploded_time;
  tested_time.LocalExplode(&exploded_time);

  // Today.
  scoped_refptr<QueryFilteredURLsRequest> request4 =
      new history::QueryFilteredURLsRequest(
          base::Bind(&HistoryBackendTest::OnQueryFiltered,
                     base::Unretained(static_cast<HistoryBackendTest*>(this))));
  cancellable_request.MockScheduleOfRequest<QueryFilteredURLsRequest>(
      request4.get());
  filter.SetFilterTime(tested_time);
  filter.SetDayOfTheWeekFilter(static_cast<int>(exploded_time.day_of_week));
  backend_->QueryFilteredURLs(request4, 100, filter, false);

  ASSERT_EQ(2U, get_filtered_list().size());
  EXPECT_EQ(std::string(google), get_filtered_list()[0].url.spec());
  EXPECT_EQ(std::string(yahoo_sports_soccer),
            get_filtered_list()[1].url.spec());

  // Today + time limit - only yahoo_sports_soccer should fit.
  scoped_refptr<QueryFilteredURLsRequest> request5 =
      new history::QueryFilteredURLsRequest(
          base::Bind(&HistoryBackendTest::OnQueryFiltered,
                     base::Unretained(static_cast<HistoryBackendTest*>(this))));
  cancellable_request.MockScheduleOfRequest<QueryFilteredURLsRequest>(
      request5.get());
  filter.SetFilterTime(tested_time - base::TimeDelta::FromMinutes(40));
  filter.SetFilterWidth(base::TimeDelta::FromMinutes(20));
  backend_->QueryFilteredURLs(request5, 100, filter, false);

  ASSERT_EQ(1U, get_filtered_list().size());
  EXPECT_EQ(std::string(yahoo_sports_soccer),
            get_filtered_list()[0].url.spec());

  // Make sure we get debug data if we request it.
  scoped_refptr<QueryFilteredURLsRequest> request6 =
      new history::QueryFilteredURLsRequest(
          base::Bind(&HistoryBackendTest::OnQueryFiltered,
                     base::Unretained(static_cast<HistoryBackendTest*>(this))));
  cancellable_request.MockScheduleOfRequest<QueryFilteredURLsRequest>(
      request6.get());
  filter.SetFilterTime(tested_time);
  filter.SetFilterWidth(one_hour * 2);
  backend_->QueryFilteredURLs(request6, 100, filter, true);

  // If the SegmentID is used by QueryFilteredURLs when generating the debug
  // data instead of the URLID, the |total_visits| for the |yahoo_sports_soccer|
  // entry will be zero instead of 1.
  ASSERT_GE(get_filtered_list().size(), 2U);
  EXPECT_EQ(std::string(google), get_filtered_list()[0].url.spec());
  EXPECT_EQ(std::string(yahoo_sports_soccer),
      get_filtered_list()[1].url.spec());
  EXPECT_EQ(4U, get_filtered_list()[0].extended_info.total_visits);
  EXPECT_EQ(1U, get_filtered_list()[1].extended_info.total_visits);
}

TEST_F(HistoryBackendTest, UpdateVisitDuration) {
  // This unit test will test adding and deleting visit details information.
  ASSERT_TRUE(backend_.get());

  GURL url1("http://www.cnn.com");
  std::vector<VisitInfo> visit_info1, visit_info2;
  Time start_ts = Time::Now() - base::TimeDelta::FromDays(5);
  Time end_ts = start_ts + base::TimeDelta::FromDays(2);
  visit_info1.push_back(VisitInfo(start_ts, content::PAGE_TRANSITION_LINK));

  GURL url2("http://www.example.com");
  visit_info2.push_back(VisitInfo(Time::Now() - base::TimeDelta::FromDays(10),
                                  content::PAGE_TRANSITION_LINK));

  // Clear all history.
  backend_->DeleteAllHistory();

  // Add the visits.
  backend_->AddVisits(url1, visit_info1, history::SOURCE_BROWSED);
  backend_->AddVisits(url2, visit_info2, history::SOURCE_BROWSED);

  // Verify the entries for both visits were added in visit_details.
  VisitVector visits1, visits2;
  URLRow row;
  URLID url_id1 = backend_->db()->GetRowForURL(url1, &row);
  ASSERT_TRUE(backend_->db()->GetVisitsForURL(url_id1, &visits1));
  ASSERT_EQ(1U, visits1.size());
  EXPECT_EQ(0, visits1[0].visit_duration.ToInternalValue());

  URLID url_id2 = backend_->db()->GetRowForURL(url2, &row);
  ASSERT_TRUE(backend_->db()->GetVisitsForURL(url_id2, &visits2));
  ASSERT_EQ(1U, visits2.size());
  EXPECT_EQ(0, visits2[0].visit_duration.ToInternalValue());

  // Update the visit to cnn.com.
  backend_->UpdateVisitDuration(visits1[0].visit_id, end_ts);

  // Check the duration for visiting cnn.com was correctly updated.
  ASSERT_TRUE(backend_->db()->GetVisitsForURL(url_id1, &visits1));
  ASSERT_EQ(1U, visits1.size());
  base::TimeDelta expected_duration = end_ts - start_ts;
  EXPECT_EQ(expected_duration.ToInternalValue(),
            visits1[0].visit_duration.ToInternalValue());

  // Remove the visit to cnn.com.
  ASSERT_TRUE(backend_->RemoveVisits(visits1));
}

// Test for migration of adding visit_duration column.
TEST_F(HistoryBackendTest, MigrationVisitDuration) {
  ASSERT_TRUE(backend_.get());
  backend_->Closing();
  backend_ = NULL;

  base::FilePath old_history_path, old_history, old_archived;
  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &old_history_path));
  old_history_path = old_history_path.AppendASCII("History");
  old_history = old_history_path.AppendASCII("HistoryNoDuration");
  old_archived = old_history_path.AppendASCII("ArchivedNoDuration");

  // Copy history database file to current directory so that it will be deleted
  // in Teardown.
  base::FilePath new_history_path(getTestDir());
  base::DeleteFile(new_history_path, true);
  base::CreateDirectory(new_history_path);
  base::FilePath new_history_file =
      new_history_path.Append(chrome::kHistoryFilename);
  base::FilePath new_archived_file =
      new_history_path.Append(chrome::kArchivedHistoryFilename);
  ASSERT_TRUE(base::CopyFile(old_history, new_history_file));
  ASSERT_TRUE(base::CopyFile(old_archived, new_archived_file));

  backend_ = new HistoryBackend(new_history_path,
                                0,
                                new HistoryBackendTestDelegate(this),
                                &bookmark_model_);
  backend_->Init(std::string(), false);
  backend_->Closing();
  backend_ = NULL;

  // Now both history and archived_history databases should already be migrated.

  // Check version in history database first.
  int cur_version = HistoryDatabase::GetCurrentVersion();
  sql::Connection db;
  ASSERT_TRUE(db.Open(new_history_file));
  sql::Statement s(db.GetUniqueStatement(
      "SELECT value FROM meta WHERE key = 'version'"));
  ASSERT_TRUE(s.Step());
  int file_version = s.ColumnInt(0);
  EXPECT_EQ(cur_version, file_version);

  // Check visit_duration column in visits table is created and set to 0.
  s.Assign(db.GetUniqueStatement(
      "SELECT visit_duration FROM visits LIMIT 1"));
  ASSERT_TRUE(s.Step());
  EXPECT_EQ(0, s.ColumnInt(0));

  // Repeat version and visit_duration checks in archived history database
  // also.
  cur_version = ArchivedDatabase::GetCurrentVersion();
  sql::Connection archived_db;
  ASSERT_TRUE(archived_db.Open(new_archived_file));
  sql::Statement s1(archived_db.GetUniqueStatement(
      "SELECT value FROM meta WHERE key = 'version'"));
  ASSERT_TRUE(s1.Step());
  file_version = s1.ColumnInt(0);
  EXPECT_EQ(cur_version, file_version);

  // Check visit_duration column in visits table is created and set to 0.
  s1.Assign(archived_db.GetUniqueStatement(
      "SELECT visit_duration FROM visits LIMIT 1"));
  ASSERT_TRUE(s1.Step());
  EXPECT_EQ(0, s1.ColumnInt(0));
}

TEST_F(HistoryBackendTest, AddPageNoVisitForBookmark) {
  ASSERT_TRUE(backend_.get());

  GURL url("http://www.google.com");
  base::string16 title(UTF8ToUTF16("Bookmark title"));
  backend_->AddPageNoVisitForBookmark(url, title);

  URLRow row;
  backend_->GetURL(url, &row);
  EXPECT_EQ(url, row.url());
  EXPECT_EQ(title, row.title());
  EXPECT_EQ(0, row.visit_count());

  backend_->DeleteURL(url);
  backend_->AddPageNoVisitForBookmark(url, base::string16());
  backend_->GetURL(url, &row);
  EXPECT_EQ(url, row.url());
  EXPECT_EQ(UTF8ToUTF16(url.spec()), row.title());
  EXPECT_EQ(0, row.visit_count());
}

TEST_F(HistoryBackendTest, ExpireHistoryForTimes) {
  ASSERT_TRUE(backend_.get());

  HistoryAddPageArgs args[10];
  for (size_t i = 0; i < arraysize(args); ++i) {
    args[i].url = GURL("http://example" +
                       std::string((i % 2 == 0 ? ".com" : ".net")));
    args[i].time = base::Time::FromInternalValue(i);
    backend_->AddPage(args[i]);
  }
  EXPECT_EQ(base::Time(), backend_->GetFirstRecordedTimeForTest());

  URLRow row;
  for (size_t i = 0; i < arraysize(args); ++i) {
    EXPECT_TRUE(backend_->GetURL(args[i].url, &row));
  }

  std::set<base::Time> times;
  times.insert(args[5].time);
  backend_->ExpireHistoryForTimes(times,
                                  base::Time::FromInternalValue(2),
                                  base::Time::FromInternalValue(8));

  EXPECT_EQ(base::Time::FromInternalValue(0),
            backend_->GetFirstRecordedTimeForTest());

  // Visits to http://example.com are untouched.
  VisitVector visit_vector;
  EXPECT_TRUE(backend_->GetVisitsForURL(
      backend_->db_->GetRowForURL(GURL("http://example.com"), NULL),
      &visit_vector));
  ASSERT_EQ(5u, visit_vector.size());
  EXPECT_EQ(base::Time::FromInternalValue(0), visit_vector[0].visit_time);
  EXPECT_EQ(base::Time::FromInternalValue(2), visit_vector[1].visit_time);
  EXPECT_EQ(base::Time::FromInternalValue(4), visit_vector[2].visit_time);
  EXPECT_EQ(base::Time::FromInternalValue(6), visit_vector[3].visit_time);
  EXPECT_EQ(base::Time::FromInternalValue(8), visit_vector[4].visit_time);

  // Visits to http://example.net between [2,8] are removed.
  visit_vector.clear();
  EXPECT_TRUE(backend_->GetVisitsForURL(
      backend_->db_->GetRowForURL(GURL("http://example.net"), NULL),
      &visit_vector));
  ASSERT_EQ(2u, visit_vector.size());
  EXPECT_EQ(base::Time::FromInternalValue(1), visit_vector[0].visit_time);
  EXPECT_EQ(base::Time::FromInternalValue(9), visit_vector[1].visit_time);

  EXPECT_EQ(base::Time::FromInternalValue(0),
            backend_->GetFirstRecordedTimeForTest());
}

TEST_F(HistoryBackendTest, ExpireHistory) {
  ASSERT_TRUE(backend_.get());
  // Since history operations are dependent on the local timezone, make all
  // entries relative to a fixed, local reference time.
  base::Time reference_time = base::Time::UnixEpoch().LocalMidnight() +
                              base::TimeDelta::FromHours(12);

  // Insert 4 entries into the database.
  HistoryAddPageArgs args[4];
  for (size_t i = 0; i < arraysize(args); ++i) {
    args[i].url = GURL("http://example" + base::IntToString(i) + ".com");
    args[i].time = reference_time + base::TimeDelta::FromDays(i);
    backend_->AddPage(args[i]);
  }

  URLRow url_rows[4];
  for (unsigned int i = 0; i < arraysize(args); ++i)
    ASSERT_TRUE(backend_->GetURL(args[i].url, &url_rows[i]));

  std::vector<ExpireHistoryArgs> expire_list;
  VisitVector visits;

  // Passing an empty map should be a no-op.
  backend_->ExpireHistory(expire_list);
  backend_->db()->GetAllVisitsInRange(base::Time(), base::Time(), 0, &visits);
  EXPECT_EQ(4U, visits.size());

  // Trying to delete an unknown URL with the time of the first visit should
  // also be a no-op.
  expire_list.resize(expire_list.size() + 1);
  expire_list[0].SetTimeRangeForOneDay(args[0].time);
  expire_list[0].urls.insert(GURL("http://google.does-not-exist"));
  backend_->ExpireHistory(expire_list);
  backend_->db()->GetAllVisitsInRange(base::Time(), base::Time(), 0, &visits);
  EXPECT_EQ(4U, visits.size());

  // Now add the first URL with the same time -- it should get deleted.
  expire_list.back().urls.insert(url_rows[0].url());
  backend_->ExpireHistory(expire_list);

  backend_->db()->GetAllVisitsInRange(base::Time(), base::Time(), 0, &visits);
  ASSERT_EQ(3U, visits.size());
  EXPECT_EQ(visits[0].url_id, url_rows[1].id());
  EXPECT_EQ(visits[1].url_id, url_rows[2].id());
  EXPECT_EQ(visits[2].url_id, url_rows[3].id());

  // The first recorded time should also get updated.
  EXPECT_EQ(backend_->GetFirstRecordedTimeForTest(), args[1].time);

  // Now delete the rest of the visits in one call.
  for (unsigned int i = 1; i < arraysize(args); ++i) {
    expire_list.resize(expire_list.size() + 1);
    expire_list[i].SetTimeRangeForOneDay(args[i].time);
    expire_list[i].urls.insert(args[i].url);
  }
  backend_->ExpireHistory(expire_list);

  backend_->db()->GetAllVisitsInRange(base::Time(), base::Time(), 0, &visits);
  ASSERT_EQ(0U, visits.size());
}

class HistoryBackendSegmentDurationTest : public HistoryBackendTest {
 public:
  HistoryBackendSegmentDurationTest() {}

  virtual void SetUp() {
    CommandLine::ForCurrentProcess()->AppendSwitch(
        switches::kTrackActiveVisitTime);
    HistoryBackendTest::SetUp();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(HistoryBackendSegmentDurationTest);
};

// Assertions around segment durations.
TEST_F(HistoryBackendSegmentDurationTest, SegmentDuration) {
  const GURL url1("http://www.google.com");
  const GURL url2("http://www.foo.com/m");
  const std::string segment1(VisitSegmentDatabase::ComputeSegmentName(url1));
  const std::string segment2(VisitSegmentDatabase::ComputeSegmentName(url2));

  Time segment_time(VisitSegmentDatabase::SegmentTime(Time::Now()));
  URLRow url_info1(url1);
  url_info1.set_visit_count(0);
  url_info1.set_typed_count(0);
  url_info1.set_last_visit(segment_time);
  url_info1.set_hidden(false);
  const URLID url1_id = backend_->db()->AddURL(url_info1);
  EXPECT_NE(0, url1_id);

  URLRow url_info2(url2);
  url_info2.set_visit_count(0);
  url_info2.set_typed_count(0);
  url_info2.set_last_visit(Time());
  url_info2.set_hidden(false);
  const URLID url2_id = backend_->db()->AddURL(url_info2);
  EXPECT_NE(0, url2_id);
  EXPECT_NE(url1_id, url2_id);

  // Should not have any segments for the urls.
  EXPECT_EQ(0, backend_->db()->GetSegmentNamed(segment1));
  EXPECT_EQ(0, backend_->db()->GetSegmentNamed(segment2));

  // Update the duration, which should implicitly create the segments.
  const TimeDelta segment1_time_delta(TimeDelta::FromHours(1));
  const TimeDelta segment2_time_delta(TimeDelta::FromHours(2));
  backend_->IncreaseSegmentDuration(url1, segment_time, segment1_time_delta);
  backend_->IncreaseSegmentDuration(url2, segment_time, segment2_time_delta);

  // Get the ids of the segments that were created.
  const SegmentID segment1_id = backend_->db()->GetSegmentNamed(segment1);
  EXPECT_NE(0, segment1_id);
  const SegmentID segment2_id = backend_->db()->GetSegmentNamed(segment2);
  EXPECT_NE(0, segment2_id);
  EXPECT_NE(segment1_id, segment2_id);

  // Make sure the values made it to the db.
  SegmentDurationID segment1_duration_id;
  TimeDelta fetched_delta;
  EXPECT_TRUE(backend_->db()->GetSegmentDuration(
                  segment1_id, segment_time, &segment1_duration_id,
                  &fetched_delta));
  EXPECT_NE(0, segment1_duration_id);
  EXPECT_EQ(segment1_time_delta.InHours(), fetched_delta.InHours());

  SegmentDurationID segment2_duration_id;
  EXPECT_TRUE(backend_->db()->GetSegmentDuration(
                  segment2_id, segment_time, &segment2_duration_id,
                  &fetched_delta));
  EXPECT_NE(0, segment2_duration_id);
  EXPECT_NE(segment1_duration_id, segment2_duration_id);
  EXPECT_EQ(segment2_time_delta.InHours(), fetched_delta.InHours());

  // Query by duration. |url2| should be first as it has a longer view time.
  ScopedVector<PageUsageData> data;
  backend_->db()->QuerySegmentDuration(segment_time, 10, &data.get());
  ASSERT_EQ(2u, data.size());
  EXPECT_EQ(url2.spec(), data[0]->GetURL().spec());
  EXPECT_EQ(url2_id, data[0]->GetID());
  EXPECT_EQ(segment2_time_delta.InHours(), data[0]->duration().InHours());

  EXPECT_EQ(url1.spec(), data[1]->GetURL().spec());
  EXPECT_EQ(url1_id, data[1]->GetID());
  EXPECT_EQ(segment1_time_delta.InHours(), data[1]->duration().InHours());
}

// Simple test that removes a bookmark. This test exercises the code paths in
// History that block till bookmark bar model is loaded.
TEST_F(HistoryBackendTest, RemoveNotification) {
  scoped_ptr<TestingProfile> profile(new TestingProfile());

  ASSERT_TRUE(profile->CreateHistoryService(false, false));
  profile->CreateBookmarkModel(true);
  BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile.get());
  test::WaitForBookmarkModelToLoad(model);

  // Add a URL.
  GURL url("http://www.google.com");
  bookmark_utils::AddIfNotBookmarked(model, url, base::string16());

  HistoryService* service = HistoryServiceFactory::GetForProfile(
      profile.get(), Profile::EXPLICIT_ACCESS);

  service->AddPage(
      url, base::Time::Now(), NULL, 1, GURL(), RedirectList(),
      content::PAGE_TRANSITION_TYPED, SOURCE_BROWSED, false);

  // This won't actually delete the URL, rather it'll empty out the visits.
  // This triggers blocking on the BookmarkModel.
  service->DeleteURL(url);
}

// Test DeleteFTSIndexDatabases deletes expected files.
TEST_F(HistoryBackendTest, DeleteFTSIndexDatabases) {
  ASSERT_TRUE(backend_.get());

  base::FilePath history_path(getTestDir());
  base::FilePath db1(history_path.AppendASCII("History Index 2013-05"));
  base::FilePath db1_journal(db1.InsertBeforeExtensionASCII("-journal"));
  base::FilePath db1_wal(db1.InsertBeforeExtensionASCII("-wal"));
  base::FilePath db2_symlink(history_path.AppendASCII("History Index 2013-06"));
  base::FilePath db2_actual(history_path.AppendASCII("Underlying DB"));

  // Setup dummy index database files.
  const char* data = "Dummy";
  const size_t data_len = 5;
  ASSERT_TRUE(file_util::WriteFile(db1, data, data_len));
  ASSERT_TRUE(file_util::WriteFile(db1_journal, data, data_len));
  ASSERT_TRUE(file_util::WriteFile(db1_wal, data, data_len));
  ASSERT_TRUE(file_util::WriteFile(db2_actual, data, data_len));
#if defined(OS_POSIX)
  EXPECT_TRUE(base::CreateSymbolicLink(db2_actual, db2_symlink));
#endif

  // Delete all DTS index databases.
  backend_->DeleteFTSIndexDatabases();
  EXPECT_FALSE(base::PathExists(db1));
  EXPECT_FALSE(base::PathExists(db1_wal));
  EXPECT_FALSE(base::PathExists(db1_journal));
  EXPECT_FALSE(base::PathExists(db2_symlink));
  EXPECT_TRUE(base::PathExists(db2_actual));  // Symlinks shouldn't be followed.
}

}  // namespace history
