15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set>
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind_helpers.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
18bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "base/platform_file.h"
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_model.h"
2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_model_factory.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_utils.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_backend.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_notifications.h"
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/history/history_service.h"
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/history/history_service_factory.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/in_memory_database.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/in_memory_history_backend.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/visit_filter.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_constants.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths.h"
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/chrome_switches.h"
35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/common/importer/imported_favicon_usage.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/thumbnail_score.h"
3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/test/base/testing_profile.h"
3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/test/base/ui_test_utils.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/tools/profiles/thumbnail-inl.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_details.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h"
4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/public/test/test_browser_thread.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/codec/jpeg_codec.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image.h"
47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Time;
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using base::TimeDelta;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file only tests functionality where it is most convenient to call the
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// backend directly. Most of the history backend functions are tested by the
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// history unit test. Because of the elaborate callbacks involved, this is no
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// harder than calling it directly for many things.
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// data we'll put into the thumbnail database
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const unsigned char blob1[] =
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "12346102356120394751634516591348710478123649165419234519234512349134";
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const gfx::Size kTinySize = gfx::Size(10, 10);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const gfx::Size kSmallSize = gfx::Size(16, 16);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const gfx::Size kLargeSize = gfx::Size(32, 32);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Comparison functions as to make it easier to check results of
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// GetFaviconBitmaps() and GetIconMappingsForPageURL().
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IconMappingLessThan(const history::IconMapping& a,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const history::IconMapping& b) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return a.icon_url < b.icon_url;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FaviconBitmapLessThan(const history::FaviconBitmap& a,
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const history::FaviconBitmap& b) {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return a.pixel_size.GetArea() < b.pixel_size.GetArea();
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // namespace
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace history {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HistoryBackendTest;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This must be a separate object since HistoryBackend manages its lifetime.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This just forwards the messages we're interested in to the test object.
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HistoryBackendTestDelegate : public HistoryBackend::Delegate {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit HistoryBackendTestDelegate(HistoryBackendTest* test) : test_(test) {}
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void NotifyProfileError(int backend_id,
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  sql::InitStatus init_status) OVERRIDE {}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetInMemoryBackend(int backend_id,
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  InMemoryHistoryBackend* backend) OVERRIDE;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void BroadcastNotifications(int type,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      HistoryDetails* details) OVERRIDE;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void DBLoaded(int backend_id) OVERRIDE;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void StartTopSitesMigration(int backend_id) OVERRIDE;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void NotifyVisitDBObserversOnAddVisit(
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const BriefVisitInfo& info) OVERRIDE {}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Not owned by us.
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HistoryBackendTest* test_;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(HistoryBackendTestDelegate);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HistoryBackendCancelableRequest
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public CancelableRequestProvider,
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      public CancelableRequestConsumerTSimple<int> {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HistoryBackendCancelableRequest() {}
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template<class RequestType>
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CancelableRequestProvider::Handle MockScheduleOfRequest(
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RequestType* request) {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddRequest(request, this);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return request->handle();
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HistoryBackendTest : public testing::Test {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HistoryBackendTest()
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : bookmark_model_(NULL),
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        loaded_(false),
12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        num_broadcasted_notifications_(0),
12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        ui_thread_(content::BrowserThread::UI, &message_loop_) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~HistoryBackendTest() {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Callback for QueryMostVisited.
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnQueryMostVisited(CancelableRequestProvider::Handle handle,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          history::MostVisitedURLList data) {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    most_visited_list_.swap(data);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Callback for QueryFiltered.
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnQueryFiltered(CancelableRequestProvider::Handle handle,
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const history::FilteredURLList& data) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    filtered_list_ = data;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const history::MostVisitedURLList& get_most_visited_list() const {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return most_visited_list_;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const history::FilteredURLList& get_filtered_list() const {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return filtered_list_;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num_broadcasted_notifications() const {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return num_broadcasted_notifications_;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<HistoryBackend> backend_;  // Will be NULL on init failure.
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<InMemoryHistoryBackend> mem_backend_;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddRedirectChain(const char* sequence[], int page_id) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddRedirectChainWithTransitionAndTime(sequence, page_id,
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          content::PAGE_TRANSITION_LINK,
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          Time::Now());
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddRedirectChainWithTransitionAndTime(
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const char* sequence[],
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int page_id,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::PageTransition transition,
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Time time) {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history::RedirectList redirects;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; sequence[i] != NULL; ++i)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      redirects.push_back(GURL(sequence[i]));
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int int_scope = 1;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void* scope = 0;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(&scope, &int_scope, sizeof(int_scope));
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history::HistoryAddPageArgs request(
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        redirects.back(), time, scope, page_id, GURL(),
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        redirects, transition, history::SOURCE_BROWSED,
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        true);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend_->AddPage(request);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Adds CLIENT_REDIRECT page transition.
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |url1| is the source URL and |url2| is the destination.
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |did_replace| is true if the transition is non-user initiated and the
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // navigation entry for |url2| has replaced that for |url1|. The possibly
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // updated transition code of the visit records for |url1| and |url2| is
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // returned by filling in |*transition1| and |*transition2|, respectively.
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |time| is a time of the redirect.
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void  AddClientRedirect(const GURL& url1, const GURL& url2, bool did_replace,
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          base::Time time,
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          int* transition1, int* transition2) {
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void* const dummy_scope = reinterpret_cast<void*>(0x87654321);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history::RedirectList redirects;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (url1.is_valid())
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      redirects.push_back(url1);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (url2.is_valid())
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      redirects.push_back(url2);
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HistoryAddPageArgs request(
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url2, time, dummy_scope, 0, url1,
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        redirects, content::PAGE_TRANSITION_CLIENT_REDIRECT,
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        history::SOURCE_BROWSED, did_replace);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend_->AddPage(request);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *transition1 = getTransition(url1);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *transition2 = getTransition(url2);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int getTransition(const GURL& url) {
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!url.is_valid())
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return 0;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    URLRow row;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    URLID id = backend_->db()->GetRowForURL(url, &row);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VisitVector visits;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(backend_->db()->GetVisitsForURL(id, &visits));
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return visits[0].transition;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath getTestDir() {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return test_dir_;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns a gfx::Size vector with small size.
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::vector<gfx::Size> GetSizesSmall() {
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<gfx::Size> sizes_small;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sizes_small.push_back(kSmallSize);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return sizes_small;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns a gfx::Size vector with large size.
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::vector<gfx::Size> GetSizesLarge() {
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<gfx::Size> sizes_large;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sizes_large.push_back(kLargeSize);
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return sizes_large;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns a gfx::Size vector with small and large sizes.
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::vector<gfx::Size> GetSizesSmallAndLarge() {
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<gfx::Size> sizes_small_and_large;
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sizes_small_and_large.push_back(kSmallSize);
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sizes_small_and_large.push_back(kLargeSize);
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return sizes_small_and_large;
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns a gfx::Size vector with tiny, small and large sizes.
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::vector<gfx::Size> GetSizesTinySmallAndLarge() {
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<gfx::Size> sizes_tiny_small_and_large;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sizes_tiny_small_and_large.push_back(kTinySize);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sizes_tiny_small_and_large.push_back(kSmallSize);
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sizes_tiny_small_and_large.push_back(kLargeSize);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return sizes_tiny_small_and_large;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns 1x and 2x scale factors.
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::vector<ui::ScaleFactor> GetScaleFactors1x2x() {
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<ui::ScaleFactor> scale_factors_1x_2x;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scale_factors_1x_2x.push_back(ui::SCALE_FACTOR_100P);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scale_factors_1x_2x.push_back(ui::SCALE_FACTOR_200P);
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return scale_factors_1x_2x;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the number of icon mappings of |icon_type| to |page_url|.
26890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  size_t NumIconMappingsForPageURL(const GURL& page_url,
26990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                   chrome::IconType icon_type) {
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<IconMapping> icon_mappings;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url, icon_type,
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                       &icon_mappings);
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return icon_mappings.size();
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the icon mappings for |page_url| sorted alphabetically by icon
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // URL in ascending order. Returns true if there is at least one icon
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // mapping.
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool GetSortedIconMappingsForPageURL(
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GURL& page_url,
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::vector<IconMapping>* icon_mappings) {
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        icon_mappings)) {
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::sort(icon_mappings->begin(), icon_mappings->end(),
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              IconMappingLessThan);
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the favicon bitmaps for |icon_id| sorted by pixel size in
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ascending order. Returns true if there is at least one favicon bitmap.
29390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool GetSortedFaviconBitmaps(chrome::FaviconID icon_id,
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               std::vector<FaviconBitmap>* favicon_bitmaps) {
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!backend_->thumbnail_db_->GetFaviconBitmaps(icon_id, favicon_bitmaps))
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::sort(favicon_bitmaps->begin(), favicon_bitmaps->end(),
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              FaviconBitmapLessThan);
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if there is exactly one favicon bitmap associated to
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |favicon_id|. If true, returns favicon bitmap in output parameter.
30490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool GetOnlyFaviconBitmap(const chrome::FaviconID icon_id,
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            FaviconBitmap* favicon_bitmap) {
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<FaviconBitmap> favicon_bitmaps;
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!backend_->thumbnail_db_->GetFaviconBitmaps(icon_id, &favicon_bitmaps))
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (favicon_bitmaps.size() != 1)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *favicon_bitmap = favicon_bitmaps[0];
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Generates |favicon_bitmap_data| with entries for the icon_urls and sizes
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // specified. The bitmap_data for entries are lowercase letters of the
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // alphabet starting at 'a' for the entry at index 0.
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void GenerateFaviconBitmapData(
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GURL& icon_url1,
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::vector<gfx::Size>& icon_url1_sizes,
32190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      std::vector<chrome::FaviconBitmapData>* favicon_bitmap_data) {
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GenerateFaviconBitmapData(icon_url1, icon_url1_sizes, GURL(),
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              std::vector<gfx::Size>(), favicon_bitmap_data);
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void GenerateFaviconBitmapData(
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GURL& icon_url1,
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::vector<gfx::Size>& icon_url1_sizes,
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GURL& icon_url2,
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::vector<gfx::Size>& icon_url2_sizes,
33190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      std::vector<chrome::FaviconBitmapData>* favicon_bitmap_data) {
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    favicon_bitmap_data->clear();
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char bitmap_char = 'a';
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < icon_url1_sizes.size(); ++i) {
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::vector<unsigned char> data;
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data.push_back(bitmap_char);
33890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      chrome::FaviconBitmapData bitmap_data_element;
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bitmap_data_element.bitmap_data =
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::RefCountedBytes::TakeVector(&data);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bitmap_data_element.pixel_size = icon_url1_sizes[i];
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bitmap_data_element.icon_url = icon_url1;
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      favicon_bitmap_data->push_back(bitmap_data_element);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ++bitmap_char;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < icon_url2_sizes.size(); ++i) {
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::vector<unsigned char> data;
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data.push_back(bitmap_char);
35190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      chrome::FaviconBitmapData bitmap_data_element;
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bitmap_data_element.bitmap_data =
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::RefCountedBytes::TakeVector(&data);
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bitmap_data_element.pixel_size = icon_url2_sizes[i];
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bitmap_data_element.icon_url = icon_url2;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      favicon_bitmap_data->push_back(bitmap_data_element);
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ++bitmap_char;
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if |bitmap_data| is equal to |expected_data|.
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool BitmapDataEqual(char expected_data,
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       scoped_refptr<base::RefCountedMemory> bitmap_data) {
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return bitmap_data.get() &&
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           bitmap_data->size() == 1u &&
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           *bitmap_data->front() == expected_data;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BookmarkModel bookmark_model_;
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // testing::Test
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!file_util::CreateNewTempDirectory(FILE_PATH_LITERAL("BackendTest"),
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           &test_dir_))
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend_ = new HistoryBackend(test_dir_,
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  0,
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  new HistoryBackendTestDelegate(this),
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  &bookmark_model_);
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend_->Init(std::string(), false);
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool loaded_;
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend class HistoryBackendTestDelegate;
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() {
391868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (backend_.get())
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      backend_->Closing();
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend_ = NULL;
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mem_backend_.reset();
3957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    base::DeleteFile(test_dir_, true);
396eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::RunLoop().RunUntilIdle();
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetInMemoryBackend(int backend_id, InMemoryHistoryBackend* backend) {
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mem_backend_.reset(backend);
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void BroadcastNotifications(int type,
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              HistoryDetails* details) {
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++num_broadcasted_notifications_;
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Send the notifications directly to the in-memory database.
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::Details<HistoryDetails> det(details);
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mem_backend_->Observe(type, content::Source<HistoryBackendTest>(NULL), det);
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The backend passes ownership of the details pointer to us.
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete details;
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The number of notifications which were broadcasted.
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num_broadcasted_notifications_;
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop message_loop_;
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath test_dir_;
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::MostVisitedURLList most_visited_list_;
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::FilteredURLList filtered_list_;
42290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  content::TestBrowserThread ui_thread_;
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackendTestDelegate::SetInMemoryBackend(int backend_id,
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InMemoryHistoryBackend* backend) {
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_->SetInMemoryBackend(backend_id, backend);
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackendTestDelegate::BroadcastNotifications(
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int type,
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HistoryDetails* details) {
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_->BroadcastNotifications(type, details);
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackendTestDelegate::DBLoaded(int backend_id) {
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_->loaded_ = true;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackendTestDelegate::StartTopSitesMigration(int backend_id) {
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_->backend_->MigrateThumbnailsDatabase();
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://crbug.com/114287
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_Loaded DISABLED_Loaded
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_Loaded Loaded
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // defined(OS_WIN)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, MAYBE_Loaded) {
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_.get());
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(loaded_);
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, DeleteAll) {
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_.get());
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add two favicons, each with two bitmaps. Note that we add favicon2 before
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // adding favicon1. This is so that favicon1 one gets ID 2 autoassigned to
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the database, which will change when the other one is deleted. This way
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we can test that updating works properly.
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL favicon_url1("http://www.google.com/favicon.ico");
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL favicon_url2("http://news.google.com/favicon.ico");
46490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  chrome::FaviconID favicon2 = backend_->thumbnail_db_->AddFavicon(favicon_url2,
465eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      chrome::FAVICON);
46690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  chrome::FaviconID favicon1 = backend_->thumbnail_db_->AddFavicon(favicon_url1,
467eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      chrome::FAVICON);
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<unsigned char> data;
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.push_back('a');
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->AddFaviconBitmap(favicon1,
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new base::RefCountedBytes(data), Time::Now(), kSmallSize));
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data[0] = 'b';
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->AddFaviconBitmap(favicon1,
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     new base::RefCountedBytes(data), Time::Now(), kLargeSize));
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data[0] = 'c';
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->AddFaviconBitmap(favicon2,
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new base::RefCountedBytes(data), Time::Now(), kSmallSize));
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data[0] = 'd';
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->AddFaviconBitmap(favicon2,
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     new base::RefCountedBytes(data), Time::Now(), kLargeSize));
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First visit two URLs.
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRow row1(GURL("http://www.google.com/"));
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row1.set_visit_count(2);
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row1.set_typed_count(1);
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row1.set_last_visit(Time::Now());
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->thumbnail_db_->AddIconMapping(row1.url(), favicon1);
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRow row2(GURL("http://news.google.com/"));
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row2.set_visit_count(1);
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row2.set_last_visit(Time::Now());
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->thumbnail_db_->AddIconMapping(row2.url(), favicon2);
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRows rows;
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rows.push_back(row2);  // Reversed order for the same reason as favicons.
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rows.push_back(row1);
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->AddPagesWithDetails(rows, history::SOURCE_BROWSED);
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLID row1_id = backend_->db_->GetRowForURL(row1.url(), NULL);
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLID row2_id = backend_->db_->GetRowForURL(row2.url(), NULL);
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the two visits for the URLs we just added.
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitVector visits;
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->db_->GetVisitsForURL(row1_id, &visits);
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, visits.size());
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visits.clear();
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->db_->GetVisitsForURL(row2_id, &visits);
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, visits.size());
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The in-memory backend should have been set and it should have gotten the
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // typed URL.
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(mem_backend_.get());
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRow outrow1;
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(mem_backend_->db_->GetRowForURL(row1.url(), NULL));
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add thumbnails for each page. The |Images| take ownership of SkBitmap
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // created from decoding the images.
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ThumbnailScore score(0.25, true, true);
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SkBitmap> google_bitmap(
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::JPEGCodec::Decode(kGoogleThumbnail, sizeof(kGoogleThumbnail)));
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Image google_image = gfx::Image::CreateFrom1xBitmap(*google_bitmap);
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Time time;
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL gurl;
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->thumbnail_db_->SetPageThumbnail(gurl, row1_id, &google_image,
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            score, time);
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SkBitmap> weewar_bitmap(
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     gfx::JPEGCodec::Decode(kWeewarThumbnail, sizeof(kWeewarThumbnail)));
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Image weewar_image = gfx::Image::CreateFrom1xBitmap(*weewar_bitmap);
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->thumbnail_db_->SetPageThumbnail(gurl, row2_id, &weewar_image,
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            score, time);
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Star row1.
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bookmark_model_.AddURL(
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bookmark_model_.bookmark_bar_node(), 0, string16(), row1.url());
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now finally clear all history.
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->DeleteAllHistory();
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first URL should be preserved but the time should be cleared.
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(backend_->db_->GetRowForURL(row1.url(), &outrow1));
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(row1.url(), outrow1.url());
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, outrow1.visit_count());
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, outrow1.typed_count());
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Time() == outrow1.last_visit());
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The second row should be deleted.
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRow outrow2;
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(backend_->db_->GetRowForURL(row2.url(), &outrow2));
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // All visits should be deleted for both URLs.
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitVector all_visits;
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->db_->GetAllVisitsInRange(Time(), Time(), 0, &all_visits);
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0U, all_visits.size());
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // All thumbnails should be deleted.
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<unsigned char> out_data;
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(backend_->thumbnail_db_->GetPageThumbnail(outrow1.id(),
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         &out_data));
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(backend_->thumbnail_db_->GetPageThumbnail(row2_id, &out_data));
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should have a favicon and favicon bitmaps for the first URL only. We
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // look them up by favicon URL since the IDs may have changed.
56890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  chrome::FaviconID out_favicon1 = backend_->thumbnail_db_->
56990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      GetFaviconIDForFaviconURL(favicon_url1, chrome::FAVICON, NULL);
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(out_favicon1);
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<FaviconBitmap> favicon_bitmaps;
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->GetFaviconBitmaps(
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      out_favicon1, &favicon_bitmaps));
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2u, favicon_bitmaps.size());
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FaviconBitmap favicon_bitmap1 = favicon_bitmaps[0];
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FaviconBitmap favicon_bitmap2 = favicon_bitmaps[1];
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Favicon bitmaps do not need to be in particular order.
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (favicon_bitmap1.pixel_size == kLargeSize) {
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FaviconBitmap tmp_favicon_bitmap = favicon_bitmap1;
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    favicon_bitmap1 = favicon_bitmap2;
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    favicon_bitmap2 = tmp_favicon_bitmap;
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(BitmapDataEqual('a', favicon_bitmap1.bitmap_data));
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kSmallSize, favicon_bitmap1.pixel_size);
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(BitmapDataEqual('b', favicon_bitmap2.bitmap_data));
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kLargeSize, favicon_bitmap2.pixel_size);
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  chrome::FaviconID out_favicon2 = backend_->thumbnail_db_->
59490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      GetFaviconIDForFaviconURL(favicon_url2, chrome::FAVICON, NULL);
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(out_favicon2) << "Favicon not deleted";
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The remaining URL should still reference the same favicon, even if its
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ID has changed.
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<IconMapping> mappings;
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(
60190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      outrow1.url(), chrome::FAVICON, &mappings));
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, mappings.size());
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(out_favicon1, mappings[0].icon_id);
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first URL should still be bookmarked.
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(bookmark_model_.IsBookmarked(row1.url()));
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that adding a visit, then calling DeleteAll, and then trying to add
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// data for the visited page works.  This can happen when clearing the history
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// immediately after visiting a page.
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, DeleteAllThenAddData) {
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_.get());
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Time visit_time = Time::Now();
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url("http://www.google.com/");
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HistoryAddPageArgs request(url, visit_time, NULL, 0, GURL(),
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             history::RedirectList(),
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             content::PAGE_TRANSITION_KEYWORD_GENERATED,
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             history::SOURCE_BROWSED, false);
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->AddPage(request);
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that a row was added.
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRow outrow;
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(backend_->db_->GetRowForURL(url, &outrow));
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the visit was added.
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitVector all_visits;
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->db_->GetAllVisitsInRange(Time(), Time(), 0, &all_visits);
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, all_visits.size());
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear all history.
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->DeleteAllHistory();
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The row should be deleted.
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(backend_->db_->GetRowForURL(url, &outrow));
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The visit should be deleted.
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->db_->GetAllVisitsInRange(Time(), Time(), 0, &all_visits);
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0U, all_visits.size());
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
642bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  // Try and set the title.
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->SetPageTitle(url, UTF8ToUTF16("Title"));
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The row should still be deleted.
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(backend_->db_->GetRowForURL(url, &outrow));
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The visit should still be deleted.
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->db_->GetAllVisitsInRange(Time(), Time(), 0, &all_visits);
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0U, all_visits.size());
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, URLsNoLongerBookmarked) {
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL favicon_url1("http://www.google.com/favicon.ico");
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL favicon_url2("http://news.google.com/favicon.ico");
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<unsigned char> data;
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.push_back('1');
65990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  chrome::FaviconID favicon1 = backend_->thumbnail_db_->AddFavicon(
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      favicon_url1,
66190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      chrome::FAVICON,
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new base::RefCountedBytes(data),
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Time::Now(),
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Size());
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data[0] = '2';
66790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  chrome::FaviconID favicon2 = backend_->thumbnail_db_->AddFavicon(
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      favicon_url2,
66990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      chrome::FAVICON,
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new base::RefCountedBytes(data),
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Time::Now(),
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Size());
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First visit two URLs.
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRow row1(GURL("http://www.google.com/"));
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row1.set_visit_count(2);
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row1.set_typed_count(1);
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row1.set_last_visit(Time::Now());
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->AddIconMapping(row1.url(), favicon1));
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRow row2(GURL("http://news.google.com/"));
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row2.set_visit_count(1);
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row2.set_last_visit(Time::Now());
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->AddIconMapping(row2.url(), favicon2));
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRows rows;
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rows.push_back(row2);  // Reversed order for the same reason as favicons.
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rows.push_back(row1);
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->AddPagesWithDetails(rows, history::SOURCE_BROWSED);
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLID row1_id = backend_->db_->GetRowForURL(row1.url(), NULL);
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLID row2_id = backend_->db_->GetRowForURL(row2.url(), NULL);
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Star the two URLs.
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bookmark_utils::AddIfNotBookmarked(&bookmark_model_, row1.url(), string16());
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bookmark_utils::AddIfNotBookmarked(&bookmark_model_, row2.url(), string16());
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delete url 2. Because url 2 is starred this won't delete the URL, only
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the visits.
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->expirer_.DeleteURL(row2.url());
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure url 2 is still valid, but has no visits.
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRow tmp_url_row;
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(row2_id, backend_->db_->GetRowForURL(row2.url(), NULL));
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitVector visits;
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->db_->GetVisitsForURL(row2_id, &visits);
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, visits.size());
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The favicon should still be valid.
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(favicon2,
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      backend_->thumbnail_db_->GetFaviconIDForFaviconURL(favicon_url2,
71190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                                         chrome::FAVICON,
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         NULL));
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unstar row2.
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bookmark_utils::RemoveAllBookmarks(&bookmark_model_, row2.url());
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Tell the backend it was unstarred. We have to explicitly do this as
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // BookmarkModel isn't wired up to the backend during testing.
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<GURL> unstarred_urls;
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unstarred_urls.insert(row2.url());
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->URLsNoLongerBookmarked(unstarred_urls);
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The URL should no longer exist.
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(backend_->db_->GetRowForURL(row2.url(), &tmp_url_row));
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // And the favicon should be deleted.
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0,
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      backend_->thumbnail_db_->GetFaviconIDForFaviconURL(favicon_url2,
72890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                                         chrome::FAVICON,
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         NULL));
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unstar row 1.
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bookmark_utils::RemoveAllBookmarks(&bookmark_model_, row1.url());
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Tell the backend it was unstarred. We have to explicitly do this as
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // BookmarkModel isn't wired up to the backend during testing.
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unstarred_urls.clear();
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unstarred_urls.insert(row1.url());
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->URLsNoLongerBookmarked(unstarred_urls);
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The URL should still exist (because there were visits).
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(row1_id, backend_->db_->GetRowForURL(row1.url(), NULL));
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There should still be visits.
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visits.clear();
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->db_->GetVisitsForURL(row1_id, &visits);
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1U, visits.size());
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The favicon should still be valid.
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(favicon1,
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      backend_->thumbnail_db_->GetFaviconIDForFaviconURL(favicon_url1,
75090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                                         chrome::FAVICON,
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         NULL));
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests a handful of assertions for a navigation with a type of
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// KEYWORD_GENERATED.
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, KeywordGenerated) {
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_.get());
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url("http://google.com");
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Time visit_time = Time::Now() - base::TimeDelta::FromDays(1);
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HistoryAddPageArgs request(url, visit_time, NULL, 0, GURL(),
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             history::RedirectList(),
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             content::PAGE_TRANSITION_KEYWORD_GENERATED,
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             history::SOURCE_BROWSED, false);
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->AddPage(request);
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A row should have been added for the url.
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRow row;
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLID url_id = backend_->db()->GetRowForURL(url, &row);
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NE(0, url_id);
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The typed count should be 1.
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, row.typed_count());
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // KEYWORD_GENERATED urls should not be added to the segment db.
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string segment_name = VisitSegmentDatabase::ComputeSegmentName(url);
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, backend_->db()->GetSegmentNamed(segment_name));
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // One visit should be added.
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitVector visits;
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(backend_->db()->GetVisitsForURL(url_id, &visits));
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1U, visits.size());
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // But no visible visits.
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visits.clear();
7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QueryOptions query_options;
7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  query_options.max_count = 1;
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  backend_->db()->GetVisibleVisitsInRange(query_options, &visits);
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(visits.empty());
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Expire the visits.
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<GURL> restrict_urls;
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->expire_backend()->ExpireHistoryBetween(restrict_urls,
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   visit_time, Time::Now());
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The visit should have been nuked.
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visits.clear();
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(backend_->db()->GetVisitsForURL(url_id, &visits));
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(visits.empty());
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // As well as the url.
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0, backend_->db()->GetRowForURL(url, &row));
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, ClientRedirect) {
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_.get());
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int transition1;
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int transition2;
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initial transition to page A.
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url_a("http://google.com/a");
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddClientRedirect(GURL(), url_a, false, base::Time(),
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &transition1, &transition2);
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(transition2 & content::PAGE_TRANSITION_CHAIN_END);
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // User initiated redirect to page B.
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url_b("http://google.com/b");
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddClientRedirect(url_a, url_b, false, base::Time(),
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &transition1, &transition2);
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(transition1 & content::PAGE_TRANSITION_CHAIN_END);
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(transition2 & content::PAGE_TRANSITION_CHAIN_END);
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Non-user initiated redirect to page C.
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url_c("http://google.com/c");
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddClientRedirect(url_b, url_c, true, base::Time(),
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &transition1, &transition2);
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(transition1 & content::PAGE_TRANSITION_CHAIN_END);
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(transition2 & content::PAGE_TRANSITION_CHAIN_END);
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, ImportedFaviconsTest) {
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Setup test data - two Urls in the history, one with favicon assigned and
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // one without.
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL favicon_url1("http://www.google.com/favicon.ico");
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<unsigned char> data;
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.push_back('1');
83990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  chrome::FaviconID favicon1 = backend_->thumbnail_db_->AddFavicon(
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      favicon_url1,
84190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      chrome::FAVICON,
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::RefCountedBytes::TakeVector(&data),
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Time::Now(),
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Size());
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRow row1(GURL("http://www.google.com/"));
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row1.set_visit_count(1);
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row1.set_last_visit(Time::Now());
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->AddIconMapping(row1.url(), favicon1));
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRow row2(GURL("http://news.google.com/"));
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row2.set_visit_count(1);
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row2.set_last_visit(Time::Now());
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRows rows;
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rows.push_back(row1);
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rows.push_back(row2);
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->AddPagesWithDetails(rows, history::SOURCE_BROWSED);
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRow url_row1, url_row2;
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(backend_->db_->GetRowForURL(row1.url(), &url_row1) == 0);
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(backend_->db_->GetRowForURL(row2.url(), &url_row2) == 0);
86090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(1u, NumIconMappingsForPageURL(row1.url(), chrome::FAVICON));
86190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(0u, NumIconMappingsForPageURL(row2.url(), chrome::FAVICON));
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now provide one imported favicon for both URLs already in the registry.
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The new favicon should only be used with the URL that doesn't already have
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a favicon.
866a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  std::vector<ImportedFaviconUsage> favicons;
867a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ImportedFaviconUsage favicon;
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  favicon.favicon_url = GURL("http://news.google.com/favicon.ico");
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  favicon.png_data.push_back('2');
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  favicon.urls.insert(row1.url());
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  favicon.urls.insert(row2.url());
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  favicons.push_back(favicon);
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->SetImportedFavicons(favicons);
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(backend_->db_->GetRowForURL(row1.url(), &url_row1) == 0);
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(backend_->db_->GetRowForURL(row2.url(), &url_row2) == 0);
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<IconMapping> mappings;
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(
87990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      row1.url(), chrome::FAVICON, &mappings));
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, mappings.size());
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(favicon1, mappings[0].icon_id);
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(favicon_url1, mappings[0].icon_url);
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mappings.clear();
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(
88690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    row2.url(), chrome::FAVICON, &mappings));
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, mappings.size());
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(favicon.favicon_url, mappings[0].icon_url);
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A URL should not be added to history (to store favicon), if
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the URL is not bookmarked.
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url3("http://mail.google.com");
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  favicons.clear();
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  favicon.favicon_url = GURL("http://mail.google.com/favicon.ico");
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  favicon.png_data.push_back('3');
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  favicon.urls.insert(url3);
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  favicons.push_back(favicon);
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->SetImportedFavicons(favicons);
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRow url_row3;
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(backend_->db_->GetRowForURL(url3, &url_row3) == 0);
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the URL is bookmarked, it should get added to history with 0 visits.
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bookmark_model_.AddURL(bookmark_model_.bookmark_bar_node(), 0, string16(),
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         url3);
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->SetImportedFavicons(favicons);
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(backend_->db_->GetRowForURL(url3, &url_row3) == 0);
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(url_row3.visit_count() == 0);
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, StripUsernamePasswordTest) {
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_.get());
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url("http://anyuser:anypass@www.google.com");
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL stripped_url("http://www.google.com");
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear all history.
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->DeleteAllHistory();
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Visit the url with username, password.
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->AddPageVisit(url, base::Time::Now(), 0,
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::PageTransitionFromInt(
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          content::PageTransitionGetQualifier(content::PAGE_TRANSITION_TYPED)),
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::SOURCE_BROWSED);
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fetch the row information about stripped url from history db.
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitVector visits;
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLID row_id = backend_->db_->GetRowForURL(stripped_url, NULL);
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->db_->GetVisitsForURL(row_id, &visits);
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check if stripped url is stored in database.
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, visits.size());
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, AddPageVisitSource) {
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_.get());
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url("http://www.google.com");
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear all history.
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->DeleteAllHistory();
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Assume visiting the url from an externsion.
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->AddPageVisit(
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, base::Time::Now(), 0, content::PAGE_TRANSITION_TYPED,
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::SOURCE_EXTENSION);
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Assume the url is imported from Firefox.
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->AddPageVisit(url, base::Time::Now(), 0,
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         content::PAGE_TRANSITION_TYPED,
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         history::SOURCE_FIREFOX_IMPORTED);
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Assume this url is also synced.
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->AddPageVisit(url, base::Time::Now(), 0,
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         content::PAGE_TRANSITION_TYPED,
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         history::SOURCE_SYNCED);
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fetch the row information about the url from history db.
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitVector visits;
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLID row_id = backend_->db_->GetRowForURL(url, NULL);
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->db_->GetVisitsForURL(row_id, &visits);
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check if all the visits to the url are stored in database.
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3U, visits.size());
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitSourceMap visit_sources;
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_->GetVisitsSource(visits, &visit_sources));
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3U, visit_sources.size());
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int sources = 0;
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 3; i++) {
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (visit_sources[visits[i].visit_id]) {
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case history::SOURCE_EXTENSION:
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sources |= 0x1;
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case history::SOURCE_FIREFOX_IMPORTED:
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sources |= 0x2;
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case history::SOURCE_SYNCED:
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sources |= 0x4;
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0x7, sources);
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
983c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(HistoryBackendTest, AddPageVisitNotLastVisit) {
984c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(backend_.get());
985c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
986c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GURL url("http://www.google.com");
987c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
988c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Clear all history.
989c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  backend_->DeleteAllHistory();
990c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
991c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create visit times
992c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::Time recent_time = base::Time::Now();
993c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::TimeDelta visit_age = base::TimeDelta::FromDays(3);
994c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::Time older_time = recent_time - visit_age;
995c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
996c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Visit the url with recent time.
997c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  backend_->AddPageVisit(url, recent_time, 0,
998c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      content::PageTransitionFromInt(
999c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          content::PageTransitionGetQualifier(content::PAGE_TRANSITION_TYPED)),
1000c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      history::SOURCE_BROWSED);
1001c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1002c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Add to the url a visit with older time (could be syncing from another
1003c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // client, etc.).
1004c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  backend_->AddPageVisit(url, older_time, 0,
1005c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      content::PageTransitionFromInt(
1006c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          content::PageTransitionGetQualifier(content::PAGE_TRANSITION_TYPED)),
1007c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      history::SOURCE_SYNCED);
1008c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1009c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Fetch the row information about url from history db.
1010c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  VisitVector visits;
1011c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  URLRow row;
1012c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  URLID row_id = backend_->db_->GetRowForURL(url, &row);
1013c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  backend_->db_->GetVisitsForURL(row_id, &visits);
1014c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1015c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Last visit time should be the most recent time, not the most recently added
1016c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // visit.
1017c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(2U, visits.size());
1018c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(recent_time, row.last_visit());
1019c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1020c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, AddPageArgsSource) {
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_.get());
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url("http://testpageargs.com");
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Assume this page is browsed by user.
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HistoryAddPageArgs request1(url, base::Time::Now(), NULL, 0, GURL(),
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             history::RedirectList(),
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             content::PAGE_TRANSITION_KEYWORD_GENERATED,
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             history::SOURCE_BROWSED, false);
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->AddPage(request1);
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Assume this page is synced.
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HistoryAddPageArgs request2(url, base::Time::Now(), NULL, 0, GURL(),
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             history::RedirectList(),
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             content::PAGE_TRANSITION_LINK,
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             history::SOURCE_SYNCED, false);
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->AddPage(request2);
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Assume this page is browsed again.
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HistoryAddPageArgs request3(url, base::Time::Now(), NULL, 0, GURL(),
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             history::RedirectList(),
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             content::PAGE_TRANSITION_TYPED,
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             history::SOURCE_BROWSED, false);
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->AddPage(request3);
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Three visits should be added with proper sources.
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitVector visits;
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRow row;
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLID id = backend_->db()->GetRowForURL(url, &row);
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_->db()->GetVisitsForURL(id, &visits));
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3U, visits.size());
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitSourceMap visit_sources;
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_->GetVisitsSource(visits, &visit_sources));
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, visit_sources.size());
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(history::SOURCE_SYNCED, visit_sources.begin()->second);
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, AddVisitsSource) {
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_.get());
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url1("http://www.cnn.com");
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<VisitInfo> visits1, visits2;
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visits1.push_back(VisitInfo(
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Time::Now() - base::TimeDelta::FromDays(5),
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::PAGE_TRANSITION_LINK));
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visits1.push_back(VisitInfo(
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Time::Now() - base::TimeDelta::FromDays(1),
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::PAGE_TRANSITION_LINK));
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visits1.push_back(VisitInfo(
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Time::Now(), content::PAGE_TRANSITION_LINK));
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url2("http://www.example.com");
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visits2.push_back(VisitInfo(
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Time::Now() - base::TimeDelta::FromDays(10),
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::PAGE_TRANSITION_LINK));
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visits2.push_back(VisitInfo(Time::Now(), content::PAGE_TRANSITION_LINK));
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear all history.
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->DeleteAllHistory();
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add the visits.
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->AddVisits(url1, visits1, history::SOURCE_IE_IMPORTED);
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->AddVisits(url2, visits2, history::SOURCE_SYNCED);
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify the visits were added with their sources.
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitVector visits;
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRow row;
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLID id = backend_->db()->GetRowForURL(url1, &row);
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_->db()->GetVisitsForURL(id, &visits));
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3U, visits.size());
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitSourceMap visit_sources;
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_->GetVisitsSource(visits, &visit_sources));
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3U, visit_sources.size());
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 3; i++)
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(history::SOURCE_IE_IMPORTED, visit_sources[visits[i].visit_id]);
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  id = backend_->db()->GetRowForURL(url2, &row);
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_->db()->GetVisitsForURL(id, &visits));
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2U, visits.size());
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_->GetVisitsSource(visits, &visit_sources));
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2U, visit_sources.size());
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 2; i++)
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(history::SOURCE_SYNCED, visit_sources[visits[i].visit_id]);
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, GetMostRecentVisits) {
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_.get());
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url1("http://www.cnn.com");
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<VisitInfo> visits1;
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visits1.push_back(VisitInfo(
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Time::Now() - base::TimeDelta::FromDays(5),
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::PAGE_TRANSITION_LINK));
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visits1.push_back(VisitInfo(
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Time::Now() - base::TimeDelta::FromDays(1),
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::PAGE_TRANSITION_LINK));
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visits1.push_back(VisitInfo(
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Time::Now(), content::PAGE_TRANSITION_LINK));
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear all history.
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->DeleteAllHistory();
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add the visits.
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->AddVisits(url1, visits1, history::SOURCE_IE_IMPORTED);
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify the visits were added with their sources.
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitVector visits;
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRow row;
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLID id = backend_->db()->GetRowForURL(url1, &row);
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_->db()->GetMostRecentVisitsForURL(id, 1, &visits));
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, visits.size());
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(visits1[2].first, visits[0].visit_time);
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, RemoveVisitsTransitions) {
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_.get());
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear all history.
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->DeleteAllHistory();
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url1("http://www.cnn.com");
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitInfo typed_visit(
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Time::Now() - base::TimeDelta::FromDays(6),
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::PAGE_TRANSITION_TYPED);
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitInfo reload_visit(
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Time::Now() - base::TimeDelta::FromDays(5),
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::PAGE_TRANSITION_RELOAD);
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitInfo link_visit(
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Time::Now() - base::TimeDelta::FromDays(4),
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::PAGE_TRANSITION_LINK);
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<VisitInfo> visits_to_add;
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visits_to_add.push_back(typed_visit);
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visits_to_add.push_back(reload_visit);
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visits_to_add.push_back(link_visit);
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add the visits.
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->AddVisits(url1, visits_to_add, history::SOURCE_SYNCED);
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that the various counts are what we expect.
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitVector visits;
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRow row;
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLID id = backend_->db()->GetRowForURL(url1, &row);
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_->db()->GetVisitsForURL(id, &visits));
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3U, visits.size());
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, row.typed_count());
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, row.visit_count());
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now, delete the typed visit and verify that typed_count is updated.
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_->RemoveVisits(VisitVector(1, visits[0])));
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  id = backend_->db()->GetRowForURL(url1, &row);
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_->db()->GetVisitsForURL(id, &visits));
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2U, visits.size());
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0, row.typed_count());
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, row.visit_count());
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delete the reload visit now and verify that none of the counts have
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // changed.
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_->RemoveVisits(VisitVector(1, visits[0])));
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  id = backend_->db()->GetRowForURL(url1, &row);
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_->db()->GetVisitsForURL(id, &visits));
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, visits.size());
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0, row.typed_count());
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, row.visit_count());
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delete the last visit and verify that we delete the URL.
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_->RemoveVisits(VisitVector(1, visits[0])));
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0, backend_->db()->GetRowForURL(url1, &row));
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, RemoveVisitsSource) {
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_.get());
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url1("http://www.cnn.com");
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<VisitInfo> visits1, visits2;
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visits1.push_back(VisitInfo(
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Time::Now() - base::TimeDelta::FromDays(5),
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::PAGE_TRANSITION_LINK));
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visits1.push_back(VisitInfo(Time::Now(),
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::PAGE_TRANSITION_LINK));
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url2("http://www.example.com");
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visits2.push_back(VisitInfo(
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Time::Now() - base::TimeDelta::FromDays(10),
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::PAGE_TRANSITION_LINK));
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visits2.push_back(VisitInfo(Time::Now(), content::PAGE_TRANSITION_LINK));
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear all history.
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->DeleteAllHistory();
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add the visits.
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->AddVisits(url1, visits1, history::SOURCE_IE_IMPORTED);
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->AddVisits(url2, visits2, history::SOURCE_SYNCED);
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify the visits of url1 were added.
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitVector visits;
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRow row;
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLID id = backend_->db()->GetRowForURL(url1, &row);
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_->db()->GetVisitsForURL(id, &visits));
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2U, visits.size());
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove these visits.
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_->RemoveVisits(visits));
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now check only url2's source in visit_source table.
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitSourceMap visit_sources;
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_->GetVisitsSource(visits, &visit_sources));
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0U, visit_sources.size());
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  id = backend_->db()->GetRowForURL(url2, &row);
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_->db()->GetVisitsForURL(id, &visits));
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2U, visits.size());
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_->GetVisitsSource(visits, &visit_sources));
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2U, visit_sources.size());
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 2; i++)
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(history::SOURCE_SYNCED, visit_sources[visits[i].visit_id]);
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test for migration of adding visit_source table.
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, MigrationVisitSource) {
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_.get());
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->Closing();
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_ = NULL;
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath old_history_path;
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &old_history_path));
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  old_history_path = old_history_path.AppendASCII("History");
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  old_history_path = old_history_path.AppendASCII("HistoryNoSource");
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Copy history database file to current directory so that it will be deleted
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in Teardown.
12472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath new_history_path(getTestDir());
12487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::DeleteFile(new_history_path, true);
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_util::CreateDirectory(new_history_path);
12502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath new_history_file =
12512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new_history_path.Append(chrome::kHistoryFilename);
12527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ASSERT_TRUE(base::CopyFile(old_history_path, new_history_file));
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_ = new HistoryBackend(new_history_path,
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                0,
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                new HistoryBackendTestDelegate(this),
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                &bookmark_model_);
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->Init(std::string(), false);
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->Closing();
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_ = NULL;
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now the database should already be migrated.
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check version first.
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int cur_version = HistoryDatabase::GetCurrentVersion();
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sql::Connection db;
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(db.Open(new_history_file));
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sql::Statement s(db.GetUniqueStatement(
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "SELECT value FROM meta WHERE key = 'version'"));
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(s.Step());
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int file_version = s.ColumnInt(0);
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(cur_version, file_version);
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check visit_source table is created and empty.
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  s.Assign(db.GetUniqueStatement(
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "SELECT name FROM sqlite_master WHERE name=\"visit_source\""));
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(s.Step());
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  s.Assign(db.GetUniqueStatement("SELECT * FROM visit_source LIMIT 10"));
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(s.Step());
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that SetFaviconMappingsForPageAndRedirects correctly updates icon
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// mappings based on redirects, icon URLs and icon types.
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, SetFaviconMappingsForPageAndRedirects) {
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Init recent_redirects_
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://www.google.com");
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://www.google.com/m");
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRow url_info1(url1);
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  url_info1.set_visit_count(0);
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  url_info1.set_typed_count(0);
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  url_info1.set_last_visit(base::Time());
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  url_info1.set_hidden(false);
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->db_->AddURL(url_info1);
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRow url_info2(url2);
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  url_info2.set_visit_count(0);
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  url_info2.set_typed_count(0);
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  url_info2.set_last_visit(base::Time());
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  url_info2.set_hidden(false);
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->db_->AddURL(url_info2);
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::RedirectList redirects;
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  redirects.push_back(url2);
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  redirects.push_back(url1);
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->recent_redirects_.Put(url1, redirects);
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL icon_url1("http://www.google.com/icon");
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL icon_url2("http://www.google.com/icon2");
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Generate bitmap data for a page with two favicons.
131090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<chrome::FaviconBitmapData> two_favicon_bitmap_data;
13112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GenerateFaviconBitmapData(icon_url1, GetSizesSmallAndLarge(),
13122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      icon_url2, GetSizesSmallAndLarge(), &two_favicon_bitmap_data);
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Generate bitmap data for a page with a single favicon.
131590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<chrome::FaviconBitmapData> one_favicon_bitmap_data;
13162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GenerateFaviconBitmapData(icon_url1, GetSizesSmallAndLarge(),
13172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            &one_favicon_bitmap_data);
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add two favicons
132090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->SetFavicons(url1, chrome::FAVICON, two_favicon_bitmap_data);
132190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(2u, NumIconMappingsForPageURL(url1, chrome::FAVICON));
132290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(2u, NumIconMappingsForPageURL(url2, chrome::FAVICON));
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add one touch_icon
132590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->SetFavicons(url1, chrome::TOUCH_ICON, one_favicon_bitmap_data);
132690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(1u, NumIconMappingsForPageURL(url1, chrome::TOUCH_ICON));
132790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(1u, NumIconMappingsForPageURL(url2, chrome::TOUCH_ICON));
132890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(2u, NumIconMappingsForPageURL(url1, chrome::FAVICON));
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add one TOUCH_PRECOMPOSED_ICON
133190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->SetFavicons(
133290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      url1, chrome::TOUCH_PRECOMPOSED_ICON, one_favicon_bitmap_data);
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The touch_icon was replaced.
133490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(0u, NumIconMappingsForPageURL(url1, chrome::TOUCH_ICON));
133590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(2u, NumIconMappingsForPageURL(url1, chrome::FAVICON));
133690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(1u,
133790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            NumIconMappingsForPageURL(url1, chrome::TOUCH_PRECOMPOSED_ICON));
133890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(1u,
133990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            NumIconMappingsForPageURL(url2, chrome::TOUCH_PRECOMPOSED_ICON));
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a touch_icon.
134290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->SetFavicons(url1, chrome::TOUCH_ICON, one_favicon_bitmap_data);
134390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(1u, NumIconMappingsForPageURL(url1, chrome::TOUCH_ICON));
134490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(2u, NumIconMappingsForPageURL(url1, chrome::FAVICON));
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The TOUCH_PRECOMPOSED_ICON was replaced.
134690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(0u,
134790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            NumIconMappingsForPageURL(url1, chrome::TOUCH_PRECOMPOSED_ICON));
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a single favicon.
135090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->SetFavicons(url1, chrome::FAVICON, one_favicon_bitmap_data);
135190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(1u, NumIconMappingsForPageURL(url1, chrome::TOUCH_ICON));
135290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(1u, NumIconMappingsForPageURL(url1, chrome::FAVICON));
135390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(1u, NumIconMappingsForPageURL(url2, chrome::FAVICON));
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add two favicons.
135690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->SetFavicons(url1, chrome::FAVICON, two_favicon_bitmap_data);
135790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(1u, NumIconMappingsForPageURL(url1, chrome::TOUCH_ICON));
135890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(2u, NumIconMappingsForPageURL(url1, chrome::FAVICON));
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that there is no churn in icon mappings from calling
13622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// SetFavicons() twice with the same |favicon_bitmap_data| parameter.
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, SetFaviconMappingsForPageDuplicates) {
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url("http://www.google.com/");
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL icon_url("http://www.google.com/icon");
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
136790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
13682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GenerateFaviconBitmapData(icon_url, GetSizesSmallAndLarge(),
13692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            &favicon_bitmap_data);
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
137190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->SetFavicons(url, chrome::FAVICON, favicon_bitmap_data);
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<IconMapping> icon_mappings;
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(
137590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      url, chrome::FAVICON, &icon_mappings));
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, icon_mappings.size());
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IconMappingID mapping_id = icon_mappings[0].mapping_id;
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
137990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->SetFavicons(url, chrome::FAVICON, favicon_bitmap_data);
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  icon_mappings.clear();
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(
138390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      url, chrome::FAVICON, &icon_mappings));
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, icon_mappings.size());
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The same row in the icon_mapping table should be used for the mapping as
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // before.
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(mapping_id, icon_mappings[0].mapping_id);
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test that calling SetFavicons() with FaviconBitmapData of different pixel
13922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// sizes than the initially passed in FaviconBitmapData deletes the no longer
13932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// used favicon bitmaps.
13942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(HistoryBackendTest, SetFaviconsDeleteBitmaps) {
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL page_url("http://www.google.com/");
13962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL icon_url("http://www.google.com/icon");
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
139890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
13992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GenerateFaviconBitmapData(icon_url, GetSizesSmallAndLarge(),
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            &favicon_bitmap_data);
140190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Test initial state.
14042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<IconMapping> icon_mappings;
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetSortedIconMappingsForPageURL(page_url, &icon_mappings));
14062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1u, icon_mappings.size());
14072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(icon_url, icon_mappings[0].icon_url);
140890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(chrome::FAVICON, icon_mappings[0].icon_type);
140990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  chrome::FaviconID favicon_id = icon_mappings[0].icon_id;
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<FaviconBitmap> favicon_bitmaps;
14122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(GetSortedFaviconBitmaps(favicon_id, &favicon_bitmaps));
14132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2u, favicon_bitmaps.size());
14142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FaviconBitmapID small_bitmap_id = favicon_bitmaps[0].bitmap_id;
14152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(0, small_bitmap_id);
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(BitmapDataEqual('a', favicon_bitmaps[0].bitmap_data));
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kSmallSize, favicon_bitmaps[0].pixel_size);
14182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FaviconBitmapID large_bitmap_id = favicon_bitmaps[1].bitmap_id;
14192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(0, large_bitmap_id);
14202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(BitmapDataEqual('b', favicon_bitmaps[1].bitmap_data));
14212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kLargeSize, favicon_bitmaps[1].pixel_size);
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Call SetFavicons() with bitmap data for only the large bitmap. Check that
14242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the small bitmap is in fact deleted.
14252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GenerateFaviconBitmapData(icon_url, GetSizesLarge(), &favicon_bitmap_data);
142690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<base::RefCountedMemory> bitmap_data_out;
14292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size pixel_size_out;
14302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(backend_->thumbnail_db_->GetFaviconBitmap(small_bitmap_id,
14312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NULL, &bitmap_data_out, &pixel_size_out));
14322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->GetFaviconBitmap(large_bitmap_id,
14332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NULL, &bitmap_data_out, &pixel_size_out));
14342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(BitmapDataEqual('a', bitmap_data_out));
14352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kLargeSize, pixel_size_out);
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  icon_mappings.clear();
14382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
14392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &icon_mappings));
14402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1u, icon_mappings.size());
14412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(favicon_id, icon_mappings[0].icon_id);
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Call SetFavicons() with no bitmap data. Check that the bitmaps and icon
14442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // mappings are deleted.
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  favicon_bitmap_data.clear();
144690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(backend_->thumbnail_db_->GetFaviconBitmap(large_bitmap_id, NULL,
14492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NULL, NULL));
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  icon_mappings.clear();
14512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
14522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &icon_mappings));
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Notifications should have been broadcast for each call to SetFavicons().
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, num_broadcasted_notifications());
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test updating a single favicon bitmap's data via SetFavicons.
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, SetFaviconsReplaceBitmapData) {
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL page_url("http://www.google.com/");
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL icon_url("http://www.google.com/icon");
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<unsigned char> data_initial;
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_initial.push_back('a');
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
146690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  chrome::FaviconBitmapData bitmap_data_element;
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap_data_element.bitmap_data =
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::RefCountedBytes::TakeVector(&data_initial);
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap_data_element.pixel_size = kSmallSize;
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap_data_element.icon_url = icon_url;
147190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  favicon_bitmap_data.push_back(bitmap_data_element);
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add bitmap to the database.
147590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
147790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  chrome::FaviconID original_favicon_id =
147890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
147990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          icon_url, chrome::FAVICON, NULL);
14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(0, original_favicon_id);
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FaviconBitmap original_favicon_bitmap;
14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetOnlyFaviconBitmap(original_favicon_id, &original_favicon_bitmap));
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(BitmapDataEqual('a', original_favicon_bitmap.bitmap_data));
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, num_broadcasted_notifications());
14872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Call SetFavicons() with completely identical data.
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<unsigned char> updated_data;
14902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  updated_data.push_back('a');
14912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  favicon_bitmap_data[0].bitmap_data = new base::RefCountedBytes(updated_data);
149290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
149490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  chrome::FaviconID updated_favicon_id =
149590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
149690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          icon_url, chrome::FAVICON, NULL);
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(0, updated_favicon_id);
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FaviconBitmap updated_favicon_bitmap;
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetOnlyFaviconBitmap(updated_favicon_id, &updated_favicon_bitmap));
15012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(BitmapDataEqual('a', updated_favicon_bitmap.bitmap_data));
15022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Because the bitmap data is byte equivalent, no notifications should have
15042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // been broadcasted.
15052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, num_broadcasted_notifications());
15062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Call SetFavicons() with identical data but a different bitmap.
15082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  updated_data[0] = 'b';
15092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  favicon_bitmap_data[0].bitmap_data = new base::RefCountedBytes(updated_data);
151090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);
15112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  updated_favicon_id =
151390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
151490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          icon_url, chrome::FAVICON, NULL);
15152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(0, updated_favicon_id);
15162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(
15172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetOnlyFaviconBitmap(updated_favicon_id, &updated_favicon_bitmap));
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(BitmapDataEqual('b', updated_favicon_bitmap.bitmap_data));
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // There should be no churn in FaviconIDs or FaviconBitmapIds even though
15212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the bitmap data changed.
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(original_favicon_bitmap.icon_id, updated_favicon_bitmap.icon_id);
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(original_favicon_bitmap.bitmap_id,
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            updated_favicon_bitmap.bitmap_id);
15252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // A notification should have been broadcasted as the favicon bitmap data has
15272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // changed.
15282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, num_broadcasted_notifications());
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that if two pages share the same FaviconID, changing the favicon for
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// one page does not affect the other.
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, SetFaviconsSameFaviconURLForTwoPages) {
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL icon_url("http://www.google.com/favicon.ico");
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL icon_url_new("http://www.google.com/favicon2.ico");
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL page_url1("http://www.google.com");
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL page_url2("http://www.google.ca");
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
153990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GenerateFaviconBitmapData(icon_url, GetSizesSmallAndLarge(),
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            &favicon_bitmap_data);
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
154390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->SetFavicons(page_url1, chrome::FAVICON, favicon_bitmap_data);
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<GURL> icon_urls;
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  icon_urls.push_back(icon_url);
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
154890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<chrome::FaviconBitmapResult> bitmap_results;
15492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  backend_->UpdateFaviconMappingsAndFetch(
155090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      page_url2, icon_urls, chrome::FAVICON, kSmallSize.width(),
15512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetScaleFactors1x2x(), &bitmap_results);
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the same FaviconID is mapped to both page URLs.
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<IconMapping> icon_mappings;
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      page_url1, &icon_mappings));
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, icon_mappings.size());
155890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  chrome::FaviconID favicon_id = icon_mappings[0].icon_id;
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(0, favicon_id);
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  icon_mappings.clear();
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      page_url2, &icon_mappings));
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, icon_mappings.size());
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(favicon_id, icon_mappings[0].icon_id);
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Change the icon URL that |page_url1| is mapped to.
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GenerateFaviconBitmapData(icon_url_new, GetSizesSmall(),
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            &favicon_bitmap_data);
157090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->SetFavicons(page_url1, chrome::FAVICON, favicon_bitmap_data);
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |page_url1| should map to a new FaviconID and have valid bitmap data.
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  icon_mappings.clear();
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      page_url1, &icon_mappings));
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, icon_mappings.size());
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(icon_url_new, icon_mappings[0].icon_url);
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(favicon_id, icon_mappings[0].icon_id);
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<FaviconBitmap> favicon_bitmaps;
15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->GetFaviconBitmaps(
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      icon_mappings[0].icon_id, &favicon_bitmaps));
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, favicon_bitmaps.size());
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |page_url2| should still map to the same FaviconID and have valid bitmap
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // data.
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  icon_mappings.clear();
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      page_url2, &icon_mappings));
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, icon_mappings.size());
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(favicon_id, icon_mappings[0].icon_id);
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  favicon_bitmaps.clear();
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->GetFaviconBitmaps(favicon_id,
15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         &favicon_bitmaps));
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2u, favicon_bitmaps.size());
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A notification should have been broadcast for each call to SetFavicons()
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and each call to UpdateFaviconMappingsAndFetch().
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, num_broadcasted_notifications());
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test that no notifications are broadcast as a result of calling
16042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// UpdateFaviconMappingsAndFetch() for an icon URL which is already
16052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// mapped to the passed in page URL.
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, UpdateFaviconMappingsAndFetchNoChange) {
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL page_url("http://www.google.com");
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL icon_url("http://www.google.com/favicon.ico");
160990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
16102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GenerateFaviconBitmapData(icon_url, GetSizesSmall(), &favicon_bitmap_data);
16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
161290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
161490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  chrome::FaviconID icon_id =
161590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
161690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        icon_url, chrome::FAVICON, NULL);
16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(0, icon_id);
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, num_broadcasted_notifications());
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<GURL> icon_urls;
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  icon_urls.push_back(icon_url);
16222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
162390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<chrome::FaviconBitmapResult> bitmap_results;
16242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  backend_->UpdateFaviconMappingsAndFetch(
162590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      page_url, icon_urls, chrome::FAVICON, kSmallSize.width(),
16262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetScaleFactors1x2x(), &bitmap_results);
16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(icon_id, backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
162990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      icon_url, chrome::FAVICON, NULL));
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No notification should have been broadcast as no icon mapping, favicon,
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // or favicon bitmap was updated, added or removed.
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, num_broadcasted_notifications());
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test repeatedly calling MergeFavicon(). |page_url| is initially not known
16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to the database.
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, MergeFaviconPageURLNotInDB) {
16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL page_url("http://www.google.com");
16402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL icon_url("http:/www.google.com/favicon.ico");
16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<unsigned char> data;
16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.push_back('a');
16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::RefCountedBytes> bitmap_data(
16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new base::RefCountedBytes(data));
16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
164790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->MergeFavicon(
164890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      page_url, icon_url, chrome::FAVICON, bitmap_data, kSmallSize);
16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |page_url| should now be mapped to |icon_url| and the favicon bitmap should
16512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // not be expired.
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<IconMapping> icon_mappings;
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &icon_mappings));
16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, icon_mappings.size());
16562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(icon_url, icon_mappings[0].icon_url);
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FaviconBitmap favicon_bitmap;
16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetOnlyFaviconBitmap(icon_mappings[0].icon_id, &favicon_bitmap));
16602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(base::Time(), favicon_bitmap.last_updated);
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(BitmapDataEqual('a', favicon_bitmap.bitmap_data));
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kSmallSize, favicon_bitmap.pixel_size);
16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data[0] = 'b';
16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap_data = new base::RefCountedBytes(data);
166690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->MergeFavicon(
166790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      page_url, icon_url, chrome::FAVICON, bitmap_data, kSmallSize);
16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |page_url| should still have a single favicon bitmap. The bitmap data
16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should be updated.
16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  icon_mappings.clear();
16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &icon_mappings));
16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, icon_mappings.size());
16752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(icon_url, icon_mappings[0].icon_url);
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetOnlyFaviconBitmap(icon_mappings[0].icon_id, &favicon_bitmap));
16782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(base::Time(), favicon_bitmap.last_updated);
16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(BitmapDataEqual('b', favicon_bitmap.bitmap_data));
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kSmallSize, favicon_bitmap.pixel_size);
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test calling MergeFavicon() when |page_url| is known to the database.
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, MergeFaviconPageURLInDB) {
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL page_url("http://www.google.com");
16862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL icon_url1("http:/www.google.com/favicon.ico");
16872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL icon_url2("http://www.google.com/favicon2.ico");
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
168990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
16902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GenerateFaviconBitmapData(icon_url1, GetSizesSmall(),
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            &favicon_bitmap_data);
16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
169390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);
16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test initial state.
16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<IconMapping> icon_mappings;
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &icon_mappings));
16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, icon_mappings.size());
17002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(icon_url1, icon_mappings[0].icon_url);
17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FaviconBitmap favicon_bitmap;
17032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(GetOnlyFaviconBitmap(icon_mappings[0].icon_id, &favicon_bitmap));
17042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(base::Time(), favicon_bitmap.last_updated);
17052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(BitmapDataEqual('a', favicon_bitmap.bitmap_data));
17062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kSmallSize, favicon_bitmap.pixel_size);
17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, num_broadcasted_notifications());
17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 1) Merge identical favicon bitmap.
17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<unsigned char> data;
17122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.push_back('a');
17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::RefCountedBytes> bitmap_data(
17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new base::RefCountedBytes(data));
171590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->MergeFavicon(
171690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      page_url, icon_url1, chrome::FAVICON, bitmap_data, kSmallSize);
17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // All the data should stay the same and no notifications should have been
17192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // sent.
17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  icon_mappings.clear();
17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &icon_mappings));
17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, icon_mappings.size());
17242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(icon_url1, icon_mappings[0].icon_url);
17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(GetOnlyFaviconBitmap(icon_mappings[0].icon_id, &favicon_bitmap));
17272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(base::Time(), favicon_bitmap.last_updated);
17282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(BitmapDataEqual('a', favicon_bitmap.bitmap_data));
17292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kSmallSize, favicon_bitmap.pixel_size);
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, num_broadcasted_notifications());
17322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 2) Merge favicon bitmap of the same size.
17342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data[0] = 'b';
17352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bitmap_data = new base::RefCountedBytes(data);
173690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->MergeFavicon(
173790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      page_url, icon_url1, chrome::FAVICON, bitmap_data, kSmallSize);
17382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The small favicon bitmap at |icon_url1| should be overwritten.
17402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  icon_mappings.clear();
17412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
17422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &icon_mappings));
17432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1u, icon_mappings.size());
17442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(icon_url1, icon_mappings[0].icon_url);
17452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(GetOnlyFaviconBitmap(icon_mappings[0].icon_id, &favicon_bitmap));
17472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(base::Time(), favicon_bitmap.last_updated);
17482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(BitmapDataEqual('b', favicon_bitmap.bitmap_data));
17492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kSmallSize, favicon_bitmap.pixel_size);
17502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 3) Merge favicon for the same icon URL, but a pixel size for which there is
17522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // no favicon bitmap.
17532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data[0] = 'c';
17542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bitmap_data = new base::RefCountedBytes(data);
175590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->MergeFavicon(
175690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      page_url, icon_url1, chrome::FAVICON, bitmap_data, kTinySize);
17572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // A new favicon bitmap should be created and the preexisting favicon bitmap
17592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // ('b') should be expired.
17602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  icon_mappings.clear();
17612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
17622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &icon_mappings));
17632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1u, icon_mappings.size());
17642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(icon_url1, icon_mappings[0].icon_url);
17652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<FaviconBitmap> favicon_bitmaps;
17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetSortedFaviconBitmaps(icon_mappings[0].icon_id,
17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      &favicon_bitmaps));
17692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(base::Time(), favicon_bitmaps[0].last_updated);
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(BitmapDataEqual('c', favicon_bitmaps[0].bitmap_data));
17712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kTinySize, favicon_bitmaps[0].pixel_size);
17722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(base::Time(), favicon_bitmaps[1].last_updated);
17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(BitmapDataEqual('b', favicon_bitmaps[1].bitmap_data));
17742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kSmallSize, favicon_bitmaps[1].pixel_size);
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 4) Merge favicon for an icon URL different from the icon URLs already
17772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // mapped to page URL.
17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data[0] = 'd';
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap_data = new base::RefCountedBytes(data);
178090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->MergeFavicon(
178190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      page_url, icon_url2, chrome::FAVICON, bitmap_data, kSmallSize);
17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The existing favicon bitmaps should be copied over to the newly created
17842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // favicon at |icon_url2|. |page_url| should solely be mapped to |icon_url2|.
17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  icon_mappings.clear();
17862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
17872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &icon_mappings));
17882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1u, icon_mappings.size());
17892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(icon_url2, icon_mappings[0].icon_url);
17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  favicon_bitmaps.clear();
17922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(GetSortedFaviconBitmaps(icon_mappings[0].icon_id,
17932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      &favicon_bitmaps));
17942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(base::Time(), favicon_bitmaps[0].last_updated);
17952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(BitmapDataEqual('c', favicon_bitmaps[0].bitmap_data));
17962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kTinySize, favicon_bitmaps[0].pixel_size);
17972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The favicon being merged should take precedence over the preexisting
17982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // favicon bitmaps.
17992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(base::Time(), favicon_bitmaps[1].last_updated);
18002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(BitmapDataEqual('d', favicon_bitmaps[1].bitmap_data));
18012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kSmallSize, favicon_bitmaps[1].pixel_size);
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A notification should have been broadcast for each call to SetFavicons()
18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and MergeFavicon().
18052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(4, num_broadcasted_notifications());
18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test calling MergeFavicon() when |icon_url| is known to the database but not
18092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// mapped to |page_url|.
18102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(HistoryBackendTest, MergeFaviconIconURLMappedToDifferentPageURL) {
18112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL page_url1("http://www.google.com");
18122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL page_url2("http://news.google.com");
18132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL page_url3("http://maps.google.com");
18142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL icon_url("http:/www.google.com/favicon.ico");
18152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
181690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
18172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GenerateFaviconBitmapData(icon_url, GetSizesSmall(),
18182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            &favicon_bitmap_data);
18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
182090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->SetFavicons(page_url1, chrome::FAVICON, favicon_bitmap_data);
18212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Test initial state.
18232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<IconMapping> icon_mappings;
18242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url1,
18252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &icon_mappings));
18262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1u, icon_mappings.size());
18272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(icon_url, icon_mappings[0].icon_url);
18282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FaviconBitmap favicon_bitmap;
18302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(GetOnlyFaviconBitmap(icon_mappings[0].icon_id, &favicon_bitmap));
18312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(base::Time(), favicon_bitmap.last_updated);
18322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(BitmapDataEqual('a', favicon_bitmap.bitmap_data));
18332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kSmallSize, favicon_bitmap.pixel_size);
18342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 1) Merge in an identical favicon bitmap data but for a different page URL.
18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<unsigned char> data;
18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.push_back('a');
18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::RefCountedBytes> bitmap_data(
18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new base::RefCountedBytes(data));
18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
184190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->MergeFavicon(
184290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      page_url2, icon_url, chrome::FAVICON, bitmap_data, kSmallSize);
18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
184490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  chrome::FaviconID favicon_id =
184590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
184690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        icon_url, chrome::FAVICON, NULL);
18472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(0, favicon_id);
18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(GetOnlyFaviconBitmap(favicon_id, &favicon_bitmap));
18502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(base::Time(), favicon_bitmap.last_updated);
18512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(BitmapDataEqual('a', favicon_bitmap.bitmap_data));
18522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kSmallSize, favicon_bitmap.pixel_size);
18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 2) Merging a favicon bitmap with different bitmap data for the same icon
18552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // URL should overwrite the small favicon bitmap at |icon_url|.
18562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bitmap_data->data()[0] = 'b';
185790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->MergeFavicon(
185890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      page_url3, icon_url, chrome::FAVICON, bitmap_data, kSmallSize);
18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  favicon_id = backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
186190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      icon_url, chrome::FAVICON, NULL);
18622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(0, favicon_id);
18632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(GetOnlyFaviconBitmap(favicon_id, &favicon_bitmap));
18652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(base::Time(), favicon_bitmap.last_updated);
18662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(BitmapDataEqual('b', favicon_bitmap.bitmap_data));
18672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kSmallSize, favicon_bitmap.pixel_size);
18682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |icon_url| should be mapped to all three page URLs.
18702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  icon_mappings.clear();
18712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url1,
18722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &icon_mappings));
18732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1u, icon_mappings.size());
18742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(favicon_id, icon_mappings[0].icon_id);
18752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  icon_mappings.clear();
18772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url2,
18782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &icon_mappings));
18792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1u, icon_mappings.size());
18802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(favicon_id, icon_mappings[0].icon_id);
18812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  icon_mappings.clear();
18832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url3,
18842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &icon_mappings));
18852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1u, icon_mappings.size());
18862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(favicon_id, icon_mappings[0].icon_id);
18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // A notification should have been broadcast for each call to SetFavicons()
18892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // and MergeFavicon().
18902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3, num_broadcasted_notifications());
18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that MergeFavicon() does not add more than
18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |kMaxFaviconBitmapsPerIconURL| to a favicon.
18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, MergeFaviconMaxFaviconBitmapsPerIconURL) {
18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL page_url("http://www.google.com");
18972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string icon_url_string("http://www.google.com/favicon.ico");
18982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t replace_index = icon_url_string.size() - 1;
18992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<unsigned char> data;
19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.push_back('a');
19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::RefCountedMemory> bitmap_data =
19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::RefCountedBytes::TakeVector(&data);
19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pixel_size = 1;
19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < kMaxFaviconBitmapsPerIconURL + 1; ++i) {
19072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    icon_url_string[replace_index] = '0' + i;
19082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GURL icon_url(icon_url_string);
19092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
191090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    backend_->MergeFavicon(page_url, icon_url, chrome::FAVICON, bitmap_data,
19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           gfx::Size(pixel_size, pixel_size));
19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++pixel_size;
19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // There should be a single favicon mapped to |page_url| with exactly
19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // kMaxFaviconBitmapsPerIconURL favicon bitmaps.
19172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<IconMapping> icon_mappings;
19182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
19192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &icon_mappings));
19202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1u, icon_mappings.size());
19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<FaviconBitmap> favicon_bitmaps;
19222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->GetFaviconBitmaps(
19232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      icon_mappings[0].icon_id, &favicon_bitmaps));
19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kMaxFaviconBitmapsPerIconURL, favicon_bitmaps.size());
19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that the favicon set by MergeFavicon() shows up in the result of
19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// GetFaviconsForURL().
19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, MergeFaviconShowsUpInGetFaviconsForURLResult) {
19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL page_url("http://www.google.com");
19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL icon_url("http://www.google.com/favicon.ico");
19322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL merged_icon_url("http://wwww.google.com/favicon2.ico");
19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
193490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GenerateFaviconBitmapData(icon_url, GetSizesSmallAndLarge(),
19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            &favicon_bitmap_data);
19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set some preexisting favicons for |page_url|.
193990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);
19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Merge small favicon.
19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<unsigned char> data;
19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.push_back('c');
19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::RefCountedBytes> bitmap_data(
19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new base::RefCountedBytes(data));
194690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->MergeFavicon(
194790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      page_url, merged_icon_url, chrome::FAVICON, bitmap_data, kSmallSize);
19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Request favicon bitmaps for both 1x and 2x to simulate request done by
19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // BookmarkModel::GetFavicon().
195190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<chrome::FaviconBitmapResult> bitmap_results;
195290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->GetFaviconsForURL(page_url, chrome::FAVICON, kSmallSize.width(),
19532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              GetScaleFactors1x2x(), &bitmap_results);
19542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2u, bitmap_results.size());
195690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const chrome::FaviconBitmapResult& first_result = bitmap_results[0];
195790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const chrome::FaviconBitmapResult& result =
19582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (first_result.pixel_size == kSmallSize) ? first_result
19592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              : bitmap_results[1];
19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(BitmapDataEqual('c', result.bitmap_data));
19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test UpdateFaviconMapingsAndFetch() when multiple icon types are passed in.
19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, UpdateFaviconMappingsAndFetchMultipleIconTypes) {
19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL page_url1("http://www.google.com");
19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL page_url2("http://news.google.com");
19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL page_url3("http://mail.google.com");
19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL icon_urla("http://www.google.com/favicon1.ico");
19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL icon_urlb("http://www.google.com/favicon2.ico");
19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL icon_urlc("http://www.google.com/favicon3.ico");
19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |page_url1| is mapped to |icon_urla| which if of type TOUCH_ICON.
197390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GenerateFaviconBitmapData(icon_urla, GetSizesSmall(), &favicon_bitmap_data);
197590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->SetFavicons(page_url1, chrome::TOUCH_ICON, favicon_bitmap_data);
19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |page_url2| is mapped to |icon_urlb| and |icon_urlc| which are of type
19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TOUCH_PRECOMPOSED_ICON.
19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GenerateFaviconBitmapData(icon_urlb, GetSizesSmall(), icon_urlc,
19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            GetSizesSmall(), &favicon_bitmap_data);
198190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->SetFavicons(
198290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      page_url2, chrome::TOUCH_PRECOMPOSED_ICON, favicon_bitmap_data);
19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<GURL> icon_urls;
19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  icon_urls.push_back(icon_urla);
19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  icon_urls.push_back(icon_urlb);
19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  icon_urls.push_back(icon_urlc);
19882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
198990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<chrome::FaviconBitmapResult> bitmap_results;
19902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  backend_->UpdateFaviconMappingsAndFetch(
199190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      page_url3,
199290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      icon_urls,
199390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      (chrome::TOUCH_ICON | chrome::TOUCH_PRECOMPOSED_ICON),
199490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      kSmallSize.width(),
199590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      GetScaleFactors1x2x(),
199690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      &bitmap_results);
19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |page_url1| and |page_url2| should still be mapped to the same icon URLs.
19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<IconMapping> icon_mappings;
20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url1,
20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &icon_mappings));
20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, icon_mappings.size());
20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(icon_urla, icon_mappings[0].icon_url);
200490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(chrome::TOUCH_ICON, icon_mappings[0].icon_type);
20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  icon_mappings.clear();
20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetSortedIconMappingsForPageURL(page_url2, &icon_mappings));
20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2u, icon_mappings.size());
20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(icon_urlb, icon_mappings[0].icon_url);
201090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(chrome::TOUCH_PRECOMPOSED_ICON, icon_mappings[0].icon_type);
20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(icon_urlc, icon_mappings[1].icon_url);
201290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(chrome::TOUCH_PRECOMPOSED_ICON, icon_mappings[1].icon_type);
20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |page_url3| should be mapped only to |icon_urlb| and |icon_urlc| as
20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TOUCH_PRECOMPOSED_ICON is the largest IconType.
20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  icon_mappings.clear();
20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetSortedIconMappingsForPageURL(page_url3, &icon_mappings));
20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2u, icon_mappings.size());
20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(icon_urlb, icon_mappings[0].icon_url);
202090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(chrome::TOUCH_PRECOMPOSED_ICON, icon_mappings[0].icon_type);
20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(icon_urlc, icon_mappings[1].icon_url);
202290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(chrome::TOUCH_PRECOMPOSED_ICON, icon_mappings[1].icon_type);
20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the results of GetFaviconsFromDB() when there are no found
20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// favicons.
20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, GetFaviconsFromDBEmpty) {
20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL page_url("http://www.google.com/");
20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
203090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<chrome::FaviconBitmapResult> bitmap_results;
203190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(backend_->GetFaviconsFromDB(page_url, chrome::FAVICON,
20322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results));
20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(bitmap_results.empty());
20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the results of GetFaviconsFromDB() when there are matching favicons
20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// but there are no associated favicon bitmaps.
20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, GetFaviconsFromDBNoFaviconBitmaps) {
20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL page_url("http://www.google.com/");
20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL icon_url("http://www.google.com/icon1");
20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
204290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  chrome::FaviconID icon_id = backend_->thumbnail_db_->AddFavicon(
2043eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      icon_url, chrome::FAVICON);
20442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(0, icon_id);
20452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(0, backend_->thumbnail_db_->AddIconMapping(page_url, icon_id));
20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
204790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<chrome::FaviconBitmapResult> bitmap_results_out;
204890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(backend_->GetFaviconsFromDB(page_url, chrome::FAVICON,
20492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out));
20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(bitmap_results_out.empty());
20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that GetFaviconsFromDB() returns results for the bitmaps which most
20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// closely match the passed in desired size and scale factors.
20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, GetFaviconsFromDBSelectClosestMatch) {
20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL page_url("http://www.google.com/");
20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL icon_url("http://www.google.com/icon1");
20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GenerateFaviconBitmapData(icon_url, GetSizesTinySmallAndLarge(),
20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            &favicon_bitmap_data);
20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
206390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);
20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
206590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<chrome::FaviconBitmapResult> bitmap_results_out;
206690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(backend_->GetFaviconsFromDB(page_url,
206790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          chrome::FAVICON,
206890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          kSmallSize.width(),
206990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          GetScaleFactors1x2x(),
207090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          &bitmap_results_out));
20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The bitmap data for the small and large bitmaps should be returned as their
20732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // sizes match exactly.
20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2u, bitmap_results_out.size());
20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No required order for results.
20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bitmap_results_out[0].pixel_size == kLargeSize) {
207790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    chrome::FaviconBitmapResult tmp_result = bitmap_results_out[0];
20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bitmap_results_out[0] = bitmap_results_out[1];
20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bitmap_results_out[1] = tmp_result;
20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(bitmap_results_out[0].expired);
20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(BitmapDataEqual('b', bitmap_results_out[0].bitmap_data));
20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kSmallSize, bitmap_results_out[0].pixel_size);
20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(icon_url, bitmap_results_out[0].icon_url);
208690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(chrome::FAVICON, bitmap_results_out[0].icon_type);
20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(bitmap_results_out[1].expired);
20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(BitmapDataEqual('c', bitmap_results_out[1].bitmap_data));
20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kLargeSize, bitmap_results_out[1].pixel_size);
20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(icon_url, bitmap_results_out[1].icon_url);
209290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(chrome::FAVICON, bitmap_results_out[1].icon_type);
20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that GetFaviconsFromDB() returns results from the icon URL whose
20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// bitmaps most closely match the passed in desired size and scale factors.
20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, GetFaviconsFromDBSingleIconURL) {
20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL page_url("http://www.google.com/");
20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL icon_url1("http://www.google.com/icon1");
21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL icon_url2("http://www.google.com/icon2");
21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
210390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GenerateFaviconBitmapData(icon_url1, GetSizesSmall(), icon_url2,
21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            GetSizesLarge(), &favicon_bitmap_data);
21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
210790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);
21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
210990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<chrome::FaviconBitmapResult> bitmap_results_out;
211090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(backend_->GetFaviconsFromDB(page_url,
211190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          chrome::FAVICON,
211290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          kSmallSize.width(),
211390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          GetScaleFactors1x2x(),
211490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          &bitmap_results_out));
21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The results should have results for the icon URL with the large bitmap as
21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // downscaling is preferred to upscaling.
21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, bitmap_results_out.size());
21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kLargeSize, bitmap_results_out[0].pixel_size);
21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(icon_url2, bitmap_results_out[0].icon_url);
21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the results of GetFaviconsFromDB() when called with different
21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |icon_types|.
21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, GetFaviconsFromDBIconType) {
21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL page_url("http://www.google.com/");
21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL icon_url1("http://www.google.com/icon1.png");
21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL icon_url2("http://www.google.com/icon2.png");
21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
213090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GenerateFaviconBitmapData(icon_url1, GetSizesSmall(),  &favicon_bitmap_data);
213290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);
21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GenerateFaviconBitmapData(icon_url2, GetSizesSmall(), &favicon_bitmap_data);
213590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->SetFavicons(page_url, chrome::TOUCH_ICON, favicon_bitmap_data);
21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
213790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<chrome::FaviconBitmapResult> bitmap_results_out;
213890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(backend_->GetFaviconsFromDB(page_url, chrome::FAVICON,
21392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out));
21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, bitmap_results_out.size());
214290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(chrome::FAVICON, bitmap_results_out[0].icon_type);
21432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(icon_url1, bitmap_results_out[0].icon_url);
21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap_results_out.clear();
214690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(backend_->GetFaviconsFromDB(page_url, chrome::TOUCH_ICON,
21472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out));
21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, bitmap_results_out.size());
215090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(chrome::TOUCH_ICON, bitmap_results_out[0].icon_type);
21512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(icon_url2, bitmap_results_out[0].icon_url);
21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that GetFaviconsFromDB() correctly sets the expired flag for bitmap
21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reults.
21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, GetFaviconsFromDBExpired) {
21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL page_url("http://www.google.com/");
21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL icon_url("http://www.google.com/icon.png");
21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<unsigned char> data;
21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.push_back('a');
21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::RefCountedBytes> bitmap_data(
21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::RefCountedBytes::TakeVector(&data));
21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time last_updated = base::Time::FromTimeT(0);
216590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  chrome::FaviconID icon_id =
216690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      backend_->thumbnail_db_->AddFavicon(icon_url,
216790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          chrome::FAVICON,
216890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          bitmap_data,
216990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          last_updated,
217090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          kSmallSize);
21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(0, icon_id);
21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(0, backend_->thumbnail_db_->AddIconMapping(page_url, icon_id));
21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
217490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<chrome::FaviconBitmapResult> bitmap_results_out;
217590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(backend_->GetFaviconsFromDB(page_url, chrome::FAVICON,
21762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out));
21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, bitmap_results_out.size());
21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(bitmap_results_out[0].expired);
21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Check that UpdateFaviconMappingsAndFetch() call back to the UI when there is
21832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// no valid thumbnail database.
21842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(HistoryBackendTest, UpdateFaviconMappingsAndFetchNoDB) {
21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make the thumbnail database invalid.
21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->thumbnail_db_.reset();
21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
218890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<chrome::FaviconBitmapResult> bitmap_results;
21892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  backend_->UpdateFaviconMappingsAndFetch(
219190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      GURL(), std::vector<GURL>(), chrome::FAVICON, kSmallSize.width(),
21922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetScaleFactors1x2x(), &bitmap_results);
21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(bitmap_results.empty());
21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, CloneFaviconIsRestrictedToSameDomain) {
21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url("http://www.google.com/");
21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL same_domain_url("http://www.google.com/subdir/index.html");
22005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL foreign_domain_url("http://www.not-google.com/");
22015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL icon_url("http://www.google.com/icon.png");
22025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a favicon
220490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GenerateFaviconBitmapData(icon_url, GetSizesSmall(),  &favicon_bitmap_data);
220690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  backend_->SetFavicons(url, chrome::FAVICON, favicon_bitmap_data);
22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(
220890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      url, chrome::FAVICON, NULL));
22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Validate starting state.
221190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<chrome::FaviconBitmapResult> bitmap_results_out;
221290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(backend_->GetFaviconsFromDB(url, chrome::FAVICON,
22132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out));
221490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(backend_->GetFaviconsFromDB(same_domain_url, chrome::FAVICON,
22152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out));
221690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(backend_->GetFaviconsFromDB(foreign_domain_url, chrome::FAVICON,
22172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out));
22185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Same-domain cloning should work.
22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->CloneFavicons(url, same_domain_url);
222190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(backend_->GetFaviconsFromDB(same_domain_url, chrome::FAVICON,
22222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out));
22235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Foreign-domain cloning is forbidden.
22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->CloneFavicons(url, foreign_domain_url);
222690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(backend_->GetFaviconsFromDB(foreign_domain_url, chrome::FAVICON,
22272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out));
22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, QueryFilteredURLs) {
22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* google = "http://www.google.com/";
22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* yahoo = "http://www.yahoo.com/";
22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* yahoo_sports = "http://sports.yahoo.com/";
22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* yahoo_sports_with_article1 =
22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://sports.yahoo.com/article1.htm";
22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* yahoo_sports_with_article2 =
22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://sports.yahoo.com/article2.htm";
22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* yahoo_sports_soccer = "http://sports.yahoo.com/soccer";
22395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* apple = "http://www.apple.com/";
22405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear all history.
22425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->DeleteAllHistory();
22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Time tested_time = Time::Now().LocalMidnight() +
22455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     base::TimeDelta::FromHours(4);
22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta half_an_hour = base::TimeDelta::FromMinutes(30);
22475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta one_hour = base::TimeDelta::FromHours(1);
22485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta one_day = base::TimeDelta::FromDays(1);
22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const content::PageTransition kTypedTransition =
22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::PAGE_TRANSITION_TYPED;
22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const content::PageTransition kKeywordGeneratedTransition =
22535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::PAGE_TRANSITION_KEYWORD_GENERATED;
22545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* redirect_sequence[2];
22565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  redirect_sequence[1] = NULL;
22575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  redirect_sequence[0] = google;
22595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddRedirectChainWithTransitionAndTime(
22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      redirect_sequence, 0, kTypedTransition,
22615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tested_time - one_day - half_an_hour * 2);
22625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddRedirectChainWithTransitionAndTime(
22635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      redirect_sequence, 0,
22645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kTypedTransition, tested_time - one_day);
22655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddRedirectChainWithTransitionAndTime(
22665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      redirect_sequence, 0,
22675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kTypedTransition, tested_time - half_an_hour / 2);
22685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddRedirectChainWithTransitionAndTime(
22695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      redirect_sequence, 0,
22705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kTypedTransition, tested_time);
22715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a visit with a transition that will make sure that no segment gets
22735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // created for this page (so the subsequent entries will have different URLIDs
22745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and SegmentIDs).
22755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  redirect_sequence[0] = apple;
22765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddRedirectChainWithTransitionAndTime(
22775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      redirect_sequence, 0, kKeywordGeneratedTransition,
22785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tested_time - one_day + one_hour * 6);
22795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  redirect_sequence[0] = yahoo;
22815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddRedirectChainWithTransitionAndTime(
22825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      redirect_sequence, 0, kTypedTransition,
22835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tested_time - one_day + half_an_hour);
22845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddRedirectChainWithTransitionAndTime(
22855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      redirect_sequence, 0, kTypedTransition,
22865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tested_time - one_day + half_an_hour * 2);
22875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  redirect_sequence[0] = yahoo_sports;
22895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddRedirectChainWithTransitionAndTime(
22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      redirect_sequence, 0, kTypedTransition,
22915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tested_time - one_day - half_an_hour * 2);
22925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddRedirectChainWithTransitionAndTime(
22935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      redirect_sequence, 0, kTypedTransition,
22945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tested_time - one_day);
22955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int transition1, transition2;
22965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddClientRedirect(GURL(yahoo_sports), GURL(yahoo_sports_with_article1), false,
22975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    tested_time - one_day + half_an_hour,
22985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &transition1, &transition2);
22995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddClientRedirect(GURL(yahoo_sports_with_article1),
23005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    GURL(yahoo_sports_with_article2),
23015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    false,
23025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    tested_time - one_day + half_an_hour * 2,
23035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &transition1, &transition2);
23045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  redirect_sequence[0] = yahoo_sports_soccer;
23065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddRedirectChainWithTransitionAndTime(redirect_sequence, 0,
23075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        kTypedTransition,
23085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        tested_time - half_an_hour);
23095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->Commit();
23105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<QueryFilteredURLsRequest> request1 =
23125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new history::QueryFilteredURLsRequest(
23135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(&HistoryBackendTest::OnQueryFiltered,
23145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     base::Unretained(static_cast<HistoryBackendTest*>(this))));
23155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HistoryBackendCancelableRequest cancellable_request;
23165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cancellable_request.MockScheduleOfRequest<QueryFilteredURLsRequest>(
2317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      request1.get());
23185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitFilter filter;
23205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Time limit is |tested_time| +/- 45 min.
23215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta three_quarters_of_an_hour = base::TimeDelta::FromMinutes(45);
23225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  filter.SetFilterTime(tested_time);
23235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  filter.SetFilterWidth(three_quarters_of_an_hour);
23245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->QueryFilteredURLs(request1, 100, filter, false);
23255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(4U, get_filtered_list().size());
23275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(google), get_filtered_list()[0].url.spec());
23285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(yahoo_sports_soccer),
23295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            get_filtered_list()[1].url.spec());
23305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(yahoo), get_filtered_list()[2].url.spec());
23315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(yahoo_sports),
23325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            get_filtered_list()[3].url.spec());
23335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Time limit is between |tested_time| and |tested_time| + 2 hours.
23355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<QueryFilteredURLsRequest> request2 =
23365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new history::QueryFilteredURLsRequest(
23375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(&HistoryBackendTest::OnQueryFiltered,
23385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     base::Unretained(static_cast<HistoryBackendTest*>(this))));
23395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cancellable_request.MockScheduleOfRequest<QueryFilteredURLsRequest>(
2340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      request2.get());
23415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  filter.SetFilterTime(tested_time + one_hour);
23425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  filter.SetFilterWidth(one_hour);
23435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->QueryFilteredURLs(request2, 100, filter, false);
23445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3U, get_filtered_list().size());
23465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(google), get_filtered_list()[0].url.spec());
23475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(yahoo), get_filtered_list()[1].url.spec());
23485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(yahoo_sports), get_filtered_list()[2].url.spec());
23495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Time limit is between |tested_time| - 2 hours and |tested_time|.
23515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<QueryFilteredURLsRequest> request3 =
23525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new history::QueryFilteredURLsRequest(
23535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(&HistoryBackendTest::OnQueryFiltered,
23545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     base::Unretained(static_cast<HistoryBackendTest*>(this))));
23555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cancellable_request.MockScheduleOfRequest<QueryFilteredURLsRequest>(
2356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      request3.get());
23575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  filter.SetFilterTime(tested_time - one_hour);
23585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  filter.SetFilterWidth(one_hour);
23595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->QueryFilteredURLs(request3, 100, filter, false);
23605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3U, get_filtered_list().size());
23625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(google), get_filtered_list()[0].url.spec());
23635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(yahoo_sports_soccer),
23645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            get_filtered_list()[1].url.spec());
23655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(yahoo_sports), get_filtered_list()[2].url.spec());
23665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  filter.ClearFilters();
23685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time::Exploded exploded_time;
23695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tested_time.LocalExplode(&exploded_time);
23705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Today.
23725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<QueryFilteredURLsRequest> request4 =
23735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new history::QueryFilteredURLsRequest(
23745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(&HistoryBackendTest::OnQueryFiltered,
23755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     base::Unretained(static_cast<HistoryBackendTest*>(this))));
23765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cancellable_request.MockScheduleOfRequest<QueryFilteredURLsRequest>(
2377868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      request4.get());
23785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  filter.SetFilterTime(tested_time);
23795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  filter.SetDayOfTheWeekFilter(static_cast<int>(exploded_time.day_of_week));
23805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->QueryFilteredURLs(request4, 100, filter, false);
23815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2U, get_filtered_list().size());
23835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(google), get_filtered_list()[0].url.spec());
23845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(yahoo_sports_soccer),
23855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            get_filtered_list()[1].url.spec());
23865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Today + time limit - only yahoo_sports_soccer should fit.
23885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<QueryFilteredURLsRequest> request5 =
23895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new history::QueryFilteredURLsRequest(
23905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(&HistoryBackendTest::OnQueryFiltered,
23915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     base::Unretained(static_cast<HistoryBackendTest*>(this))));
23925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cancellable_request.MockScheduleOfRequest<QueryFilteredURLsRequest>(
2393868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      request5.get());
23945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  filter.SetFilterTime(tested_time - base::TimeDelta::FromMinutes(40));
23955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  filter.SetFilterWidth(base::TimeDelta::FromMinutes(20));
23965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->QueryFilteredURLs(request5, 100, filter, false);
23975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, get_filtered_list().size());
23995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(yahoo_sports_soccer),
24005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            get_filtered_list()[0].url.spec());
24015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure we get debug data if we request it.
24035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<QueryFilteredURLsRequest> request6 =
24045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new history::QueryFilteredURLsRequest(
24055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(&HistoryBackendTest::OnQueryFiltered,
24065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     base::Unretained(static_cast<HistoryBackendTest*>(this))));
24075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cancellable_request.MockScheduleOfRequest<QueryFilteredURLsRequest>(
2408868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      request6.get());
24095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  filter.SetFilterTime(tested_time);
24105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  filter.SetFilterWidth(one_hour * 2);
24115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->QueryFilteredURLs(request6, 100, filter, true);
24125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the SegmentID is used by QueryFilteredURLs when generating the debug
24145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // data instead of the URLID, the |total_visits| for the |yahoo_sports_soccer|
24155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // entry will be zero instead of 1.
24165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_GE(get_filtered_list().size(), 2U);
24175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(google), get_filtered_list()[0].url.spec());
24185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(yahoo_sports_soccer),
24195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      get_filtered_list()[1].url.spec());
24205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4U, get_filtered_list()[0].extended_info.total_visits);
24215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1U, get_filtered_list()[1].extended_info.total_visits);
24225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, UpdateVisitDuration) {
24255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This unit test will test adding and deleting visit details information.
24265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_.get());
24275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url1("http://www.cnn.com");
24295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<VisitInfo> visit_info1, visit_info2;
24305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Time start_ts = Time::Now() - base::TimeDelta::FromDays(5);
24315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Time end_ts = start_ts + base::TimeDelta::FromDays(2);
24325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visit_info1.push_back(VisitInfo(start_ts, content::PAGE_TRANSITION_LINK));
24335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url2("http://www.example.com");
24355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visit_info2.push_back(VisitInfo(Time::Now() - base::TimeDelta::FromDays(10),
24365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  content::PAGE_TRANSITION_LINK));
24375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear all history.
24395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->DeleteAllHistory();
24405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add the visits.
24425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->AddVisits(url1, visit_info1, history::SOURCE_BROWSED);
24435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->AddVisits(url2, visit_info2, history::SOURCE_BROWSED);
24445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify the entries for both visits were added in visit_details.
24465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitVector visits1, visits2;
24475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRow row;
24485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLID url_id1 = backend_->db()->GetRowForURL(url1, &row);
24495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_->db()->GetVisitsForURL(url_id1, &visits1));
24505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, visits1.size());
24515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visits1[0].visit_duration.ToInternalValue());
24525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLID url_id2 = backend_->db()->GetRowForURL(url2, &row);
24545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_->db()->GetVisitsForURL(url_id2, &visits2));
24555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, visits2.size());
24565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visits2[0].visit_duration.ToInternalValue());
24575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Update the visit to cnn.com.
24595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->UpdateVisitDuration(visits1[0].visit_id, end_ts);
24605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check the duration for visiting cnn.com was correctly updated.
24625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_->db()->GetVisitsForURL(url_id1, &visits1));
24635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, visits1.size());
24645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta expected_duration = end_ts - start_ts;
24655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(expected_duration.ToInternalValue(),
24665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            visits1[0].visit_duration.ToInternalValue());
24675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove the visit to cnn.com.
24695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_->RemoveVisits(visits1));
24705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test for migration of adding visit_duration column.
24735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, MigrationVisitDuration) {
24745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(backend_.get());
24755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->Closing();
24765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_ = NULL;
24775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath old_history_path, old_history, old_archived;
24795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &old_history_path));
24805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  old_history_path = old_history_path.AppendASCII("History");
24815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  old_history = old_history_path.AppendASCII("HistoryNoDuration");
24825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  old_archived = old_history_path.AppendASCII("ArchivedNoDuration");
24835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Copy history database file to current directory so that it will be deleted
24855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in Teardown.
24862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath new_history_path(getTestDir());
24877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::DeleteFile(new_history_path, true);
24885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_util::CreateDirectory(new_history_path);
24892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath new_history_file =
24902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new_history_path.Append(chrome::kHistoryFilename);
24912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath new_archived_file =
24925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_history_path.Append(chrome::kArchivedHistoryFilename);
24937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ASSERT_TRUE(base::CopyFile(old_history, new_history_file));
24947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ASSERT_TRUE(base::CopyFile(old_archived, new_archived_file));
24955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_ = new HistoryBackend(new_history_path,
24975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                0,
24985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                new HistoryBackendTestDelegate(this),
24995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                &bookmark_model_);
25005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->Init(std::string(), false);
25015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->Closing();
25025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_ = NULL;
25035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now both history and archived_history databases should already be migrated.
25055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check version in history database first.
25075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int cur_version = HistoryDatabase::GetCurrentVersion();
25085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sql::Connection db;
25095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(db.Open(new_history_file));
25105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sql::Statement s(db.GetUniqueStatement(
25115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "SELECT value FROM meta WHERE key = 'version'"));
25125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(s.Step());
25135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int file_version = s.ColumnInt(0);
25145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(cur_version, file_version);
25155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check visit_duration column in visits table is created and set to 0.
25175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  s.Assign(db.GetUniqueStatement(
25185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "SELECT visit_duration FROM visits LIMIT 1"));
25195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(s.Step());
25205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, s.ColumnInt(0));
25215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Repeat version and visit_duration checks in archived history database
25235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // also.
25245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cur_version = ArchivedDatabase::GetCurrentVersion();
25255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sql::Connection archived_db;
25265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(archived_db.Open(new_archived_file));
25275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sql::Statement s1(archived_db.GetUniqueStatement(
25285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "SELECT value FROM meta WHERE key = 'version'"));
25295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(s1.Step());
25305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_version = s1.ColumnInt(0);
25315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(cur_version, file_version);
25325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check visit_duration column in visits table is created and set to 0.
25345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  s1.Assign(archived_db.GetUniqueStatement(
25355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "SELECT visit_duration FROM visits LIMIT 1"));
25365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(s1.Step());
25375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, s1.ColumnInt(0));
25385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendTest, AddPageNoVisitForBookmark) {
25412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(backend_.get());
25425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL url("http://www.google.com");
25442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string16 title(UTF8ToUTF16("Bookmark title"));
25452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  backend_->AddPageNoVisitForBookmark(url, title);
25465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  URLRow row;
25482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  backend_->GetURL(url, &row);
25492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(url, row.url());
25502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(title, row.title());
25512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, row.visit_count());
25522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  backend_->DeleteURL(url);
25542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  backend_->AddPageNoVisitForBookmark(url, string16());
25552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  backend_->GetURL(url, &row);
25562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(url, row.url());
25572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(UTF8ToUTF16(url.spec()), row.title());
25582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, row.visit_count());
25592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
25602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(HistoryBackendTest, ExpireHistoryForTimes) {
25622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(backend_.get());
25632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HistoryAddPageArgs args[10];
25652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < arraysize(args); ++i) {
25662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    args[i].url = GURL("http://example" +
25672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       std::string((i % 2 == 0 ? ".com" : ".net")));
25682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    args[i].time = base::Time::FromInternalValue(i);
25692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    backend_->AddPage(args[i]);
25702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
25712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(base::Time(), backend_->GetFirstRecordedTimeForTest());
25722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  URLRow row;
25742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < arraysize(args); ++i) {
25752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(backend_->GetURL(args[i].url, &row));
25762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
25772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::set<base::Time> times;
25792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  times.insert(args[5].time);
25802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  backend_->ExpireHistoryForTimes(times,
25812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  base::Time::FromInternalValue(2),
25822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  base::Time::FromInternalValue(8));
25832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(base::Time::FromInternalValue(0),
25852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            backend_->GetFirstRecordedTimeForTest());
25862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Visits to http://example.com are untouched.
25882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VisitVector visit_vector;
25892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(backend_->GetVisitsForURL(
25902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      backend_->db_->GetRowForURL(GURL("http://example.com"), NULL),
25912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &visit_vector));
25922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(5u, visit_vector.size());
25932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(base::Time::FromInternalValue(0), visit_vector[0].visit_time);
25942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(base::Time::FromInternalValue(2), visit_vector[1].visit_time);
25952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(base::Time::FromInternalValue(4), visit_vector[2].visit_time);
25962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(base::Time::FromInternalValue(6), visit_vector[3].visit_time);
25972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(base::Time::FromInternalValue(8), visit_vector[4].visit_time);
25982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Visits to http://example.net between [2,8] are removed.
26002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  visit_vector.clear();
26012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(backend_->GetVisitsForURL(
26022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      backend_->db_->GetRowForURL(GURL("http://example.net"), NULL),
26032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &visit_vector));
26042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(2u, visit_vector.size());
26052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(base::Time::FromInternalValue(1), visit_vector[0].visit_time);
26062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(base::Time::FromInternalValue(9), visit_vector[1].visit_time);
26072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(base::Time::FromInternalValue(0),
26092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            backend_->GetFirstRecordedTimeForTest());
26102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
26112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(HistoryBackendTest, ExpireHistory) {
26132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(backend_.get());
26142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Since history operations are dependent on the local timezone, make all
26152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // entries relative to a fixed, local reference time.
26162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::Time reference_time = base::Time::UnixEpoch().LocalMidnight() +
26172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              base::TimeDelta::FromHours(12);
26182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Insert 4 entries into the database.
26202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HistoryAddPageArgs args[4];
26212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < arraysize(args); ++i) {
26222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    args[i].url = GURL("http://example" + base::IntToString(i) + ".com");
26232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    args[i].time = reference_time + base::TimeDelta::FromDays(i);
26242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    backend_->AddPage(args[i]);
26252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
26262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  URLRow url_rows[4];
26282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (unsigned int i = 0; i < arraysize(args); ++i)
26292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(backend_->GetURL(args[i].url, &url_rows[i]));
26302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<ExpireHistoryArgs> expire_list;
26322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VisitVector visits;
26332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Passing an empty map should be a no-op.
26352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  backend_->ExpireHistory(expire_list);
26362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  backend_->db()->GetAllVisitsInRange(base::Time(), base::Time(), 0, &visits);
26372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(4U, visits.size());
26382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Trying to delete an unknown URL with the time of the first visit should
26402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // also be a no-op.
26412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  expire_list.resize(expire_list.size() + 1);
26422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  expire_list[0].SetTimeRangeForOneDay(args[0].time);
26432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  expire_list[0].urls.insert(GURL("http://google.does-not-exist"));
26442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  backend_->ExpireHistory(expire_list);
26452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  backend_->db()->GetAllVisitsInRange(base::Time(), base::Time(), 0, &visits);
26462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(4U, visits.size());
26472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now add the first URL with the same time -- it should get deleted.
26492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  expire_list.back().urls.insert(url_rows[0].url());
26502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  backend_->ExpireHistory(expire_list);
26512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  backend_->db()->GetAllVisitsInRange(base::Time(), base::Time(), 0, &visits);
26532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(3U, visits.size());
26542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(visits[0].url_id, url_rows[1].id());
26552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(visits[1].url_id, url_rows[2].id());
26562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(visits[2].url_id, url_rows[3].id());
26572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The first recorded time should also get updated.
26592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(backend_->GetFirstRecordedTimeForTest(), args[1].time);
26602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now delete the rest of the visits in one call.
26622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (unsigned int i = 1; i < arraysize(args); ++i) {
26632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expire_list.resize(expire_list.size() + 1);
26642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expire_list[i].SetTimeRangeForOneDay(args[i].time);
26652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expire_list[i].urls.insert(args[i].url);
26662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
26672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  backend_->ExpireHistory(expire_list);
26682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  backend_->db()->GetAllVisitsInRange(base::Time(), base::Time(), 0, &visits);
26702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(0U, visits.size());
26712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
26722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class HistoryBackendSegmentDurationTest : public HistoryBackendTest {
26742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
26752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HistoryBackendSegmentDurationTest() {}
26762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUp() {
26782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CommandLine::ForCurrentProcess()->AppendSwitch(
26792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        switches::kTrackActiveVisitTime);
26802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    HistoryBackendTest::SetUp();
26812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
26822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
26842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(HistoryBackendSegmentDurationTest);
26852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
26862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Assertions around segment durations.
26882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(HistoryBackendSegmentDurationTest, SegmentDuration) {
26892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL url1("http://www.google.com");
26902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL url2("http://www.foo.com/m");
26912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::string segment1(VisitSegmentDatabase::ComputeSegmentName(url1));
26922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::string segment2(VisitSegmentDatabase::ComputeSegmentName(url2));
26932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Time segment_time(VisitSegmentDatabase::SegmentTime(Time::Now()));
26952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  URLRow url_info1(url1);
26962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  url_info1.set_visit_count(0);
26972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  url_info1.set_typed_count(0);
26982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  url_info1.set_last_visit(segment_time);
26992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  url_info1.set_hidden(false);
27002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const URLID url1_id = backend_->db()->AddURL(url_info1);
27012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(0, url1_id);
27022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  URLRow url_info2(url2);
27042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  url_info2.set_visit_count(0);
27052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  url_info2.set_typed_count(0);
27062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  url_info2.set_last_visit(Time());
27072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  url_info2.set_hidden(false);
27082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const URLID url2_id = backend_->db()->AddURL(url_info2);
27092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(0, url2_id);
27102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(url1_id, url2_id);
27112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Should not have any segments for the urls.
27132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, backend_->db()->GetSegmentNamed(segment1));
27142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, backend_->db()->GetSegmentNamed(segment2));
27152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Update the duration, which should implicitly create the segments.
27172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const TimeDelta segment1_time_delta(TimeDelta::FromHours(1));
27182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const TimeDelta segment2_time_delta(TimeDelta::FromHours(2));
27192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  backend_->IncreaseSegmentDuration(url1, segment_time, segment1_time_delta);
27202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  backend_->IncreaseSegmentDuration(url2, segment_time, segment2_time_delta);
27212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Get the ids of the segments that were created.
27232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const SegmentID segment1_id = backend_->db()->GetSegmentNamed(segment1);
27242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(0, segment1_id);
27252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const SegmentID segment2_id = backend_->db()->GetSegmentNamed(segment2);
27262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(0, segment2_id);
27272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(segment1_id, segment2_id);
27282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Make sure the values made it to the db.
27302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SegmentDurationID segment1_duration_id;
27312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TimeDelta fetched_delta;
27322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(backend_->db()->GetSegmentDuration(
27332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  segment1_id, segment_time, &segment1_duration_id,
27342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  &fetched_delta));
27352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(0, segment1_duration_id);
27362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(segment1_time_delta.InHours(), fetched_delta.InHours());
27372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SegmentDurationID segment2_duration_id;
27392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(backend_->db()->GetSegmentDuration(
27402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  segment2_id, segment_time, &segment2_duration_id,
27412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  &fetched_delta));
27422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(0, segment2_duration_id);
27432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(segment1_duration_id, segment2_duration_id);
27442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(segment2_time_delta.InHours(), fetched_delta.InHours());
27452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Query by duration. |url2| should be first as it has a longer view time.
27472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedVector<PageUsageData> data;
27482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  backend_->db()->QuerySegmentDuration(segment_time, 10, &data.get());
27492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(2u, data.size());
27502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(url2.spec(), data[0]->GetURL().spec());
27512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(url2_id, data[0]->GetID());
27522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(segment2_time_delta.InHours(), data[0]->duration().InHours());
27532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(url1.spec(), data[1]->GetURL().spec());
27552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(url1_id, data[1]->GetID());
27562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(segment1_time_delta.InHours(), data[1]->duration().InHours());
27575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Simple test that removes a bookmark. This test exercises the code paths in
276090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// History that block till bookmark bar model is loaded.
276190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST_F(HistoryBackendTest, RemoveNotification) {
276290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<TestingProfile> profile(new TestingProfile());
276390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2764bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  ASSERT_TRUE(profile->CreateHistoryService(false, false));
276590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  profile->CreateBookmarkModel(true);
276690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile.get());
276790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ui_test_utils::WaitForBookmarkModelToLoad(model);
276890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
276990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Add a URL.
277090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  GURL url("http://www.google.com");
277190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bookmark_utils::AddIfNotBookmarked(model, url, base::string16());
277290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
277390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  HistoryService* service = HistoryServiceFactory::GetForProfile(
277490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      profile.get(), Profile::EXPLICIT_ACCESS);
277590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
277690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  service->AddPage(
277790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      url, base::Time::Now(), NULL, 1, GURL(), RedirectList(),
277890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      content::PAGE_TRANSITION_TYPED, SOURCE_BROWSED, false);
277990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
278090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // This won't actually delete the URL, rather it'll empty out the visits.
278190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // This triggers blocking on the BookmarkModel.
278290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  service->DeleteURL(url);
278390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
278490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2785bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// Test DeleteFTSIndexDatabases deletes expected files.
2786bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochTEST_F(HistoryBackendTest, DeleteFTSIndexDatabases) {
2787bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  ASSERT_TRUE(backend_.get());
2788bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
2789bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  base::FilePath history_path(getTestDir());
2790bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  base::FilePath db1(history_path.AppendASCII("History Index 2013-05"));
2791bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  base::FilePath db1_journal(db1.InsertBeforeExtensionASCII("-journal"));
2792bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  base::FilePath db1_wal(db1.InsertBeforeExtensionASCII("-wal"));
2793bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  base::FilePath db2_symlink(history_path.AppendASCII("History Index 2013-06"));
2794bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  base::FilePath db2_actual(history_path.AppendASCII("Underlying DB"));
2795bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
2796bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  // Setup dummy index database files.
2797c6a03b665d27bf9b307170479657cbbf1b5bfe17Torne (Richard Coles)  const char* data = "Dummy";
2798c6a03b665d27bf9b307170479657cbbf1b5bfe17Torne (Richard Coles)  const size_t data_len = 5;
2799c6a03b665d27bf9b307170479657cbbf1b5bfe17Torne (Richard Coles)  ASSERT_TRUE(file_util::WriteFile(db1, data, data_len));
2800c6a03b665d27bf9b307170479657cbbf1b5bfe17Torne (Richard Coles)  ASSERT_TRUE(file_util::WriteFile(db1_journal, data, data_len));
2801c6a03b665d27bf9b307170479657cbbf1b5bfe17Torne (Richard Coles)  ASSERT_TRUE(file_util::WriteFile(db1_wal, data, data_len));
2802c6a03b665d27bf9b307170479657cbbf1b5bfe17Torne (Richard Coles)  ASSERT_TRUE(file_util::WriteFile(db2_actual, data, data_len));
2803bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#if defined(OS_POSIX)
2804bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_TRUE(file_util::CreateSymbolicLink(db2_actual, db2_symlink));
2805bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#endif
2806bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
2807bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  // Delete all DTS index databases.
2808bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  backend_->DeleteFTSIndexDatabases();
2809bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_FALSE(base::PathExists(db1));
2810bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_FALSE(base::PathExists(db1_wal));
2811bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_FALSE(base::PathExists(db1_journal));
2812bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_FALSE(base::PathExists(db2_symlink));
2813bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_TRUE(base::PathExists(db2_actual));  // Symlinks shouldn't be followed.
2814bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch}
2815bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
28165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace history
2817