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)// History unit tests come in two flavors:
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1. The more complicated style is that the unit test creates a full history
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    service. This spawns a background thread for the history backend, and
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    all communication is asynchronous. This is useful for testing more
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    complicated things or end-to-end behavior.
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2. The simpler style is to create a history backend on this thread and
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    access it directly without a HistoryService object. This is much simpler
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    because communication is synchronous. Generally, sets should go through
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    the history backend (since there is a lot of logic) but gets can come
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    directly from the HistoryDatabase. This is because the backend generally
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    has no logic in the getter except threading stuff, which we don't want
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    to run.
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <time.h>
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/compiler_specific.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h"
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/scoped_temp_dir.h"
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_vector.h"
379ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/task/cancelable_task_tracker.h"
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/platform_thread.h"
44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/download_row.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_backend.h"
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_database.h"
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/history_db_task.h"
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_notifications.h"
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/history_service.h"
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/history_unittest_base.h"
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/in_memory_database.h"
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/in_memory_history_backend.h"
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/page_usage_data.h"
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_constants.h"
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths.h"
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/tools/profiles/thumbnail-inl.h"
58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "components/history/core/common/thumbnail_score.h"
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/download_item.h"
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_details.h"
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h"
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sql/connection.h"
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sql/statement.h"
64a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "sync/api/attachments/attachment_id.h"
65a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "sync/api/attachments/attachment_service_proxy_for_test.h"
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "sync/api/fake_sync_change_processor.h"
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sync/api/sync_change.h"
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sync/api/sync_change_processor.h"
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "sync/api/sync_change_processor_wrapper_for_test.h"
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sync/api/sync_error.h"
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sync/api/sync_error_factory.h"
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sync/api/sync_merge_result.h"
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sync/protocol/history_delete_directive_specifics.pb.h"
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sync/protocol/sync.pb.h"
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h"
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/codec/jpeg_codec.h"
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Time;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::DownloadItem;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace history {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HistoryBackendDBTest;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Delegate class for when we create a backend without a HistoryService.
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This must be outside the anonymous namespace for the friend statement in
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HistoryBackendDBTest to work.
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BackendDelegate : public HistoryBackend::Delegate {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit BackendDelegate(HistoryBackendDBTest* history_test)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : history_test_(history_test) {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void NotifyProfileError(sql::InitStatus init_status) OVERRIDE {}
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void SetInMemoryBackend(
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      scoped_ptr<InMemoryHistoryBackend> backend) OVERRIDE;
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void BroadcastNotifications(
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      int type,
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      scoped_ptr<HistoryDetails> details) OVERRIDE;
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void DBLoaded() OVERRIDE {}
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void NotifyVisitDBObserversOnAddVisit(
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const BriefVisitInfo& info) OVERRIDE {}
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HistoryBackendDBTest* history_test_;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This must be outside the anonymous namespace for the friend statement in
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HistoryBackend to work.
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class HistoryBackendDBTest : public HistoryUnitTestBase {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HistoryBackendDBTest() : db_(NULL) {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~HistoryBackendDBTest() {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class BackendDelegate;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates the HistoryBackend and HistoryDatabase on the current thread,
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // assigning the values to backend_ and db_.
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CreateBackendAndDatabase() {
125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    backend_ =
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        new HistoryBackend(history_dir_, new BackendDelegate(this), NULL);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend_->Init(std::string(), false);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    db_ = backend_->db_.get();
129b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    DCHECK(in_mem_backend_) << "Mem backend should have been set by "
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "HistoryBackend::Init";
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void CreateDBVersion(int version) {
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath data_path;
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_path));
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data_path = data_path.AppendASCII("History");
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data_path =
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          data_path.AppendASCII(base::StringPrintf("history.%d.sql", version));
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_NO_FATAL_FAILURE(
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ExecuteSQLScript(data_path, history_dir_.Append(
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            chrome::kHistoryFilename)));
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void CreateArchivedDB() {
14546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    base::FilePath data_path;
14646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_path));
14746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    data_path = data_path.AppendASCII("History");
14846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    data_path = data_path.AppendASCII("archived_history.4.sql");
14946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_NO_FATAL_FAILURE(
15046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        ExecuteSQLScript(data_path, history_dir_.Append(
15146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            chrome::kArchivedHistoryFilename)));
15246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
15346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // testing::Test
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history_dir_ = temp_dir_.path().AppendASCII("HistoryBackendDBTest");
158a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ASSERT_TRUE(base::CreateDirectory(history_dir_));
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DeleteBackend() {
162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (backend_.get()) {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      backend_->Closing();
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      backend_ = NULL;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DeleteBackend();
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure we don't have any event pending that could disrupt the next
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // test.
17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(FROM_HERE,
17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                           base::MessageLoop::QuitClosure());
17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->Run();
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  bool AddDownload(uint32 id,
1797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                   DownloadItem::DownloadState state,
1807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                   const Time& time) {
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::vector<GURL> url_chain;
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    url_chain.push_back(GURL("foo-url"));
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    DownloadRow download(base::FilePath(FILE_PATH_LITERAL("current-path")),
185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                         base::FilePath(FILE_PATH_LITERAL("target-path")),
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         url_chain,
187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                         GURL("http://referrer.com/"),
188f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                         "application/vnd.oasis.opendocument.text",
189f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                         "application/octet-stream",
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         time,
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         time,
192ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                         std::string(),
193ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                         std::string(),
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         0,
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         512,
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         state,
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         content::DOWNLOAD_INTERRUPT_REASON_NONE,
1997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                         id,
200a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                         false,
201a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                         "by_ext_id",
202a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                         "by_ext_name");
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return db_->CreateDownload(download);
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir temp_dir_;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoopForUI message_loop_;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // names of the database files
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath history_dir_;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Created via CreateBackendAndDatabase.
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<HistoryBackend> backend_;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<InMemoryHistoryBackend> in_mem_backend_;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HistoryDatabase* db_;  // Cached reference to the backend's database.
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BackendDelegate::SetInMemoryBackend(
220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    scoped_ptr<InMemoryHistoryBackend> backend) {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Save the in-memory backend to the history test object, this happens
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // synchronously, so we don't have to do anything fancy.
223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  history_test_->in_mem_backend_.swap(backend);
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BackendDelegate::BroadcastNotifications(
227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int type,
228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    scoped_ptr<HistoryDetails> details) {
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Currently, just send the notifications directly to the in-memory database.
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We may want do do something more fancy in the future.
231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  content::Details<HistoryDetails> det(details.get());
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_test_->in_mem_backend_->Observe(type,
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<HistoryBackendDBTest>(NULL), det);
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendDBTest, ClearBrowsingData_Downloads) {
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateBackendAndDatabase();
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initially there should be nothing in the downloads database.
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<DownloadRow> downloads;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  db_->QueryDownloads(&downloads);
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, downloads.size());
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
244eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Add a download, test that it was added correctly, remove it, test that it
245eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // was removed.
246eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Time now = Time();
2477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  uint32 id = 1;
2487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(AddDownload(id, DownloadItem::COMPLETE, Time()));
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  db_->QueryDownloads(&downloads);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1U, downloads.size());
251eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
252eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(base::FilePath(FILE_PATH_LITERAL("current-path")),
253eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            downloads[0].current_path);
254eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(base::FilePath(FILE_PATH_LITERAL("target-path")),
255eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            downloads[0].target_path);
256eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(1UL, downloads[0].url_chain.size());
257eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(GURL("foo-url"), downloads[0].url_chain[0]);
258eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(std::string("http://referrer.com/"),
259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            std::string(downloads[0].referrer_url.spec()));
260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(now, downloads[0].start_time);
261eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(now, downloads[0].end_time);
262eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(0, downloads[0].received_bytes);
263eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(512, downloads[0].total_bytes);
264eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(DownloadItem::COMPLETE, downloads[0].state);
265eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
266eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            downloads[0].danger_type);
267eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(content::DOWNLOAD_INTERRUPT_REASON_NONE,
268eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            downloads[0].interrupt_reason);
269eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_FALSE(downloads[0].opened);
270a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ("by_ext_id", downloads[0].by_ext_id);
271a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ("by_ext_name", downloads[0].by_ext_name);
272f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ("application/vnd.oasis.opendocument.text", downloads[0].mime_type);
273f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ("application/octet-stream", downloads[0].original_mime_type);
274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  db_->QueryDownloads(&downloads);
2767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_EQ(1U, downloads.size());
2777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  db_->RemoveDownload(id);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  db_->QueryDownloads(&downloads);
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, downloads.size());
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryBackendDBTest, MigrateDownloadsState) {
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create the db we want.
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(CreateDBVersion(22));
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Open the db for manual manipulation.
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sql::Connection db;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(db.Open(history_dir_.Append(chrome::kHistoryFilename)));
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Manually insert corrupted rows; there's infrastructure in place now to
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // make this impossible, at least according to the test above.
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int state = 0; state < 5; ++state) {
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sql::Statement s(db.GetUniqueStatement(
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "INSERT INTO downloads (id, full_path, url, start_time, "
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "received_bytes, total_bytes, state, end_time, opened) VALUES "
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "(?, ?, ?, ?, ?, ?, ?, ?, ?)"));
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      s.BindInt64(0, 1 + state);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      s.BindString(1, "path");
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      s.BindString(2, "url");
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      s.BindInt64(3, base::Time::Now().ToTimeT());
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      s.BindInt64(4, 100);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      s.BindInt64(5, 100);
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      s.BindInt(6, state);
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      s.BindInt64(7, base::Time::Now().ToTimeT());
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      s.BindInt(8, state % 2);
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_TRUE(s.Run());
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Re-open the db using the HistoryDatabase, which should migrate from version
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 22 to the current version, fixing just the row whose state was 3.
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Then close the db so that we can re-open it directly.
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateBackendAndDatabase();
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DeleteBackend();
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Re-open the db for manual manipulation.
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sql::Connection db;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(db.Open(history_dir_.Append(chrome::kHistoryFilename)));
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // The version should have been updated.
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int cur_version = HistoryDatabase::GetCurrentVersion();
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_LT(22, cur_version);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sql::Statement s(db.GetUniqueStatement(
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "SELECT value FROM meta WHERE key = 'version'"));
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_TRUE(s.Step());
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(cur_version, s.ColumnInt(0));
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sql::Statement statement(db.GetUniqueStatement(
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "SELECT id, state, opened "
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "FROM downloads "
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "ORDER BY id"));
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int counter = 0;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      while (statement.Step()) {
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_EQ(1 + counter, statement.ColumnInt64(0));
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // The only thing that migration should have changed was state from 3 to
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // 4.
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_EQ(((counter == 3) ? 4 : counter), statement.ColumnInt(1));
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_EQ(counter % 2, statement.ColumnInt(2));
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ++counter;
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(5, counter);
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(HistoryBackendDBTest, MigrateDownloadsReasonPathsAndDangerType) {
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Time now(base::Time::Now());
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create the db we want.  The schema didn't change from 22->23, so just
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // re-use the v22 file.
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(CreateDBVersion(22));
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Re-open the db for manual manipulation.
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sql::Connection db;
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(db.Open(history_dir_.Append(chrome::kHistoryFilename)));
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Manually insert some rows.
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sql::Statement s(db.GetUniqueStatement(
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "INSERT INTO downloads (id, full_path, url, start_time, "
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "received_bytes, total_bytes, state, end_time, opened) VALUES "
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "(?, ?, ?, ?, ?, ?, ?, ?, ?)"));
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    int64 id = 0;
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Null path.
3667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    s.BindInt64(0, ++id);
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    s.BindString(1, std::string());
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    s.BindString(2, "http://whatever.com/index.html");
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    s.BindInt64(3, now.ToTimeT());
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    s.BindInt64(4, 100);
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    s.BindInt64(5, 100);
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    s.BindInt(6, 1);
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    s.BindInt64(7, now.ToTimeT());
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    s.BindInt(8, 1);
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(s.Run());
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    s.Reset(true);
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Non-null path.
3797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    s.BindInt64(0, ++id);
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    s.BindString(1, "/path/to/some/file");
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    s.BindString(2, "http://whatever.com/index1.html");
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    s.BindInt64(3, now.ToTimeT());
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    s.BindInt64(4, 100);
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    s.BindInt64(5, 100);
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    s.BindInt(6, 1);
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    s.BindInt64(7, now.ToTimeT());
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    s.BindInt(8, 1);
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(s.Run());
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Re-open the db using the HistoryDatabase, which should migrate from version
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 23 to 24, creating the new tables and creating the new path, reason,
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // and danger columns.
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CreateBackendAndDatabase();
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeleteBackend();
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Re-open the db for manual manipulation.
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sql::Connection db;
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(db.Open(history_dir_.Append(chrome::kHistoryFilename)));
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // The version should have been updated.
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int cur_version = HistoryDatabase::GetCurrentVersion();
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ASSERT_LT(23, cur_version);
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      sql::Statement s(db.GetUniqueStatement(
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          "SELECT value FROM meta WHERE key = 'version'"));
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_TRUE(s.Step());
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(cur_version, s.ColumnInt(0));
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Time nowish(base::Time::FromTimeT(now.ToTimeT()));
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Confirm downloads table is valid.
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      sql::Statement statement(db.GetUniqueStatement(
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          "SELECT id, interrupt_reason, current_path, target_path, "
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          "       danger_type, start_time, end_time "
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          "FROM downloads ORDER BY id"));
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_TRUE(statement.Step());
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(1, statement.ColumnInt64(0));
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(content::DOWNLOAD_INTERRUPT_REASON_NONE,
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                statement.ColumnInt(1));
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ("", statement.ColumnString(2));
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ("", statement.ColumnString(3));
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Implicit dependence on value of kDangerTypeNotDangerous from
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // download_database.cc.
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(0, statement.ColumnInt(4));
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(nowish.ToInternalValue(), statement.ColumnInt64(5));
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(nowish.ToInternalValue(), statement.ColumnInt64(6));
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_TRUE(statement.Step());
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(2, statement.ColumnInt64(0));
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(content::DOWNLOAD_INTERRUPT_REASON_NONE,
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                statement.ColumnInt(1));
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ("/path/to/some/file", statement.ColumnString(2));
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ("/path/to/some/file", statement.ColumnString(3));
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(0, statement.ColumnInt(4));
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(nowish.ToInternalValue(), statement.ColumnInt64(5));
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(nowish.ToInternalValue(), statement.ColumnInt64(6));
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_FALSE(statement.Step());
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Confirm downloads_url_chains table is valid.
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      sql::Statement statement(db.GetUniqueStatement(
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          "SELECT id, chain_index, url FROM downloads_url_chains "
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          " ORDER BY id, chain_index"));
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_TRUE(statement.Step());
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(1, statement.ColumnInt64(0));
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(0, statement.ColumnInt(1));
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ("http://whatever.com/index.html", statement.ColumnString(2));
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_TRUE(statement.Step());
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(2, statement.ColumnInt64(0));
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(0, statement.ColumnInt(1));
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ("http://whatever.com/index1.html", statement.ColumnString(2));
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_FALSE(statement.Step());
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
461eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_F(HistoryBackendDBTest, MigrateReferrer) {
462eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Time now(base::Time::Now());
463eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_NO_FATAL_FAILURE(CreateDBVersion(22));
464eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  {
465eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    sql::Connection db;
466eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ASSERT_TRUE(db.Open(history_dir_.Append(chrome::kHistoryFilename)));
467eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    sql::Statement s(db.GetUniqueStatement(
468eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        "INSERT INTO downloads (id, full_path, url, start_time, "
469eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        "received_bytes, total_bytes, state, end_time, opened) VALUES "
470eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        "(?, ?, ?, ?, ?, ?, ?, ?, ?)"));
471eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    int64 db_handle = 0;
472eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    s.BindInt64(0, ++db_handle);
473eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    s.BindString(1, "full_path");
474eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    s.BindString(2, "http://whatever.com/index.html");
475eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    s.BindInt64(3, now.ToTimeT());
476eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    s.BindInt64(4, 100);
477eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    s.BindInt64(5, 100);
478eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    s.BindInt(6, 1);
479eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    s.BindInt64(7, now.ToTimeT());
480eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    s.BindInt(8, 1);
481eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ASSERT_TRUE(s.Run());
482eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
483eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Re-open the db using the HistoryDatabase, which should migrate to version
484eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // 26, creating the referrer column.
485eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  CreateBackendAndDatabase();
486eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DeleteBackend();
487eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  {
488eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Re-open the db for manual manipulation.
489eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    sql::Connection db;
490eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ASSERT_TRUE(db.Open(history_dir_.Append(chrome::kHistoryFilename)));
491eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // The version should have been updated.
492eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    int cur_version = HistoryDatabase::GetCurrentVersion();
493eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ASSERT_LE(26, cur_version);
494eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    {
495eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      sql::Statement s(db.GetUniqueStatement(
496eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          "SELECT value FROM meta WHERE key = 'version'"));
497eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      EXPECT_TRUE(s.Step());
498eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      EXPECT_EQ(cur_version, s.ColumnInt(0));
499eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
500eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    {
501eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      sql::Statement s(db.GetUniqueStatement(
502eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          "SELECT referrer from downloads"));
503eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      EXPECT_TRUE(s.Step());
504eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      EXPECT_EQ(std::string(), s.ColumnString(0));
505eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
506eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
507eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
508eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
509a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(HistoryBackendDBTest, MigrateDownloadedByExtension) {
510a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Time now(base::Time::Now());
511a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(CreateDBVersion(26));
512a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  {
513a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    sql::Connection db;
514a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    ASSERT_TRUE(db.Open(history_dir_.Append(chrome::kHistoryFilename)));
515a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    {
516a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      sql::Statement s(db.GetUniqueStatement(
517a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          "INSERT INTO downloads (id, current_path, target_path, start_time, "
518a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          "received_bytes, total_bytes, state, danger_type, interrupt_reason, "
519a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          "end_time, opened, referrer) VALUES "
520a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"));
521a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      s.BindInt64(0, 1);
522a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      s.BindString(1, "current_path");
523a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      s.BindString(2, "target_path");
524a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      s.BindInt64(3, now.ToTimeT());
525a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      s.BindInt64(4, 100);
526a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      s.BindInt64(5, 100);
527a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      s.BindInt(6, 1);
528a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      s.BindInt(7, 0);
529a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      s.BindInt(8, 0);
530a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      s.BindInt64(9, now.ToTimeT());
531a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      s.BindInt(10, 1);
532a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      s.BindString(11, "referrer");
533a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      ASSERT_TRUE(s.Run());
534a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
535a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    {
536a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      sql::Statement s(db.GetUniqueStatement(
537a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          "INSERT INTO downloads_url_chains (id, chain_index, url) VALUES "
538a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          "(?, ?, ?)"));
539a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      s.BindInt64(0, 4);
540a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      s.BindInt64(1, 0);
541a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      s.BindString(2, "url");
542a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      ASSERT_TRUE(s.Run());
543a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
544a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
545a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Re-open the db using the HistoryDatabase, which should migrate to version
546a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // 27, creating the by_ext_id and by_ext_name columns.
547a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CreateBackendAndDatabase();
548a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DeleteBackend();
549a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  {
550a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // Re-open the db for manual manipulation.
551a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    sql::Connection db;
552a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    ASSERT_TRUE(db.Open(history_dir_.Append(chrome::kHistoryFilename)));
553a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // The version should have been updated.
554a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    int cur_version = HistoryDatabase::GetCurrentVersion();
555a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    ASSERT_LE(27, cur_version);
556a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    {
557a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      sql::Statement s(db.GetUniqueStatement(
558a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          "SELECT value FROM meta WHERE key = 'version'"));
559a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      EXPECT_TRUE(s.Step());
560a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      EXPECT_EQ(cur_version, s.ColumnInt(0));
561a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
562a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    {
563a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      sql::Statement s(db.GetUniqueStatement(
564a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          "SELECT by_ext_id, by_ext_name from downloads"));
565a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      EXPECT_TRUE(s.Step());
566a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      EXPECT_EQ(std::string(), s.ColumnString(0));
567a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      EXPECT_EQ(std::string(), s.ColumnString(1));
568a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
569a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
570a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
571a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
572ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_F(HistoryBackendDBTest, MigrateDownloadValidators) {
573ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  Time now(base::Time::Now());
574ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ASSERT_NO_FATAL_FAILURE(CreateDBVersion(27));
575ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  {
576ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    sql::Connection db;
577ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    ASSERT_TRUE(db.Open(history_dir_.Append(chrome::kHistoryFilename)));
578ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    {
579ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      sql::Statement s(db.GetUniqueStatement(
580ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          "INSERT INTO downloads (id, current_path, target_path, start_time, "
581ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          "received_bytes, total_bytes, state, danger_type, interrupt_reason, "
582ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          "end_time, opened, referrer, by_ext_id, by_ext_name) VALUES "
583ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"));
584ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      s.BindInt64(0, 1);
585ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      s.BindString(1, "current_path");
586ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      s.BindString(2, "target_path");
587ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      s.BindInt64(3, now.ToTimeT());
588ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      s.BindInt64(4, 100);
589ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      s.BindInt64(5, 100);
590ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      s.BindInt(6, 1);
591ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      s.BindInt(7, 0);
592ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      s.BindInt(8, 0);
593ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      s.BindInt64(9, now.ToTimeT());
594ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      s.BindInt(10, 1);
595ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      s.BindString(11, "referrer");
596ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      s.BindString(12, "by extension ID");
597ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      s.BindString(13, "by extension name");
598ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      ASSERT_TRUE(s.Run());
599ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    }
600ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    {
601ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      sql::Statement s(db.GetUniqueStatement(
602ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          "INSERT INTO downloads_url_chains (id, chain_index, url) VALUES "
603ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          "(?, ?, ?)"));
604ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      s.BindInt64(0, 4);
605ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      s.BindInt64(1, 0);
606ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      s.BindString(2, "url");
607ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      ASSERT_TRUE(s.Run());
608ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    }
609ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
610ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Re-open the db using the HistoryDatabase, which should migrate to the
611ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // current version, creating the etag and last_modified columns.
612ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  CreateBackendAndDatabase();
613ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  DeleteBackend();
614ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  {
615ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    // Re-open the db for manual manipulation.
616ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    sql::Connection db;
617ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    ASSERT_TRUE(db.Open(history_dir_.Append(chrome::kHistoryFilename)));
618ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    // The version should have been updated.
619ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    int cur_version = HistoryDatabase::GetCurrentVersion();
620ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    ASSERT_LE(28, cur_version);
621ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    {
622ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      sql::Statement s(db.GetUniqueStatement(
623ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          "SELECT value FROM meta WHERE key = 'version'"));
624ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      EXPECT_TRUE(s.Step());
625ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      EXPECT_EQ(cur_version, s.ColumnInt(0));
626ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    }
627ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    {
628ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      sql::Statement s(db.GetUniqueStatement(
629ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          "SELECT etag, last_modified from downloads"));
630ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      EXPECT_TRUE(s.Step());
631ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      EXPECT_EQ(std::string(), s.ColumnString(0));
632ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      EXPECT_EQ(std::string(), s.ColumnString(1));
633ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    }
634ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
635ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
636ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
63746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(HistoryBackendDBTest, PurgeArchivedDatabase) {
63846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(CreateDBVersion(27));
63946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(CreateArchivedDB());
64046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
64146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_TRUE(base::PathExists(
64246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      history_dir_.Append(chrome::kArchivedHistoryFilename)));
64346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
64446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  CreateBackendAndDatabase();
64546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DeleteBackend();
64646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
64746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // We do not retain expired history entries in an archived database as of M37.
64846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Verify that any legacy archived database is deleted on start-up.
64946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_FALSE(base::PathExists(
65046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      history_dir_.Append(chrome::kArchivedHistoryFilename)));
65146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
65246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
653f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(HistoryBackendDBTest, MigrateDownloadMimeType) {
654f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Time now(base::Time::Now());
655f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(CreateDBVersion(28));
656f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  {
657f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    sql::Connection db;
658f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    ASSERT_TRUE(db.Open(history_dir_.Append(chrome::kHistoryFilename)));
659f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    {
660f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      sql::Statement s(db.GetUniqueStatement(
661f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          "INSERT INTO downloads (id, current_path, target_path, start_time, "
662f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          "received_bytes, total_bytes, state, danger_type, interrupt_reason, "
663f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          "end_time, opened, referrer, by_ext_id, by_ext_name, etag, "
664f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          "last_modified) VALUES "
665f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"));
666f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      s.BindInt64(0, 1);
667f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      s.BindString(1, "current_path");
668f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      s.BindString(2, "target_path");
669f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      s.BindInt64(3, now.ToTimeT());
670f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      s.BindInt64(4, 100);
671f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      s.BindInt64(5, 100);
672f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      s.BindInt(6, 1);
673f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      s.BindInt(7, 0);
674f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      s.BindInt(8, 0);
675f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      s.BindInt64(9, now.ToTimeT());
676f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      s.BindInt(10, 1);
677f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      s.BindString(11, "referrer");
678f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      s.BindString(12, "by extension ID");
679f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      s.BindString(13, "by extension name");
680f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      s.BindString(14, "etag");
681f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      s.BindInt64(15, now.ToTimeT());
682f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      ASSERT_TRUE(s.Run());
683f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
684f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    {
685f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      sql::Statement s(db.GetUniqueStatement(
686f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          "INSERT INTO downloads_url_chains (id, chain_index, url) VALUES "
687f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          "(?, ?, ?)"));
688f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      s.BindInt64(0, 4);
689f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      s.BindInt64(1, 0);
690f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      s.BindString(2, "url");
691f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      ASSERT_TRUE(s.Run());
692f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
693f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
694f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Re-open the db using the HistoryDatabase, which should migrate to the
695f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // current version, creating themime_type abd original_mime_type columns.
696f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CreateBackendAndDatabase();
697f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DeleteBackend();
698f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  {
699f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // Re-open the db for manual manipulation.
700f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    sql::Connection db;
701f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    ASSERT_TRUE(db.Open(history_dir_.Append(chrome::kHistoryFilename)));
702f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // The version should have been updated.
703f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int cur_version = HistoryDatabase::GetCurrentVersion();
704f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    ASSERT_LE(29, cur_version);
705f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    {
706f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      sql::Statement s(db.GetUniqueStatement(
707f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          "SELECT value FROM meta WHERE key = 'version'"));
708f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      EXPECT_TRUE(s.Step());
709f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      EXPECT_EQ(cur_version, s.ColumnInt(0));
710f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
711f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    {
712f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      sql::Statement s(db.GetUniqueStatement(
713f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          "SELECT mime_type, original_mime_type from downloads"));
714f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      EXPECT_TRUE(s.Step());
715f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      EXPECT_EQ(std::string(), s.ColumnString(0));
716f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      EXPECT_EQ(std::string(), s.ColumnString(1));
717f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
718f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
719f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
720f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(HistoryBackendDBTest, ConfirmDownloadRowCreateAndDelete) {
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create the DB.
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CreateBackendAndDatabase();
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::Time now(base::Time::Now());
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Add some downloads.
7287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  uint32 id1 = 1, id2 = 2, id3 = 3;
7297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  AddDownload(id1, DownloadItem::COMPLETE, now);
7307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  AddDownload(id2, DownloadItem::COMPLETE, now + base::TimeDelta::FromDays(2));
7317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  AddDownload(id3, DownloadItem::COMPLETE, now - base::TimeDelta::FromDays(2));
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Confirm that resulted in the correct number of rows in the DB.
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeleteBackend();
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sql::Connection db;
7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(db.Open(history_dir_.Append(chrome::kHistoryFilename)));
7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sql::Statement statement(db.GetUniqueStatement(
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "Select Count(*) from downloads"));
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(statement.Step());
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(3, statement.ColumnInt(0));
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sql::Statement statement1(db.GetUniqueStatement(
7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "Select Count(*) from downloads_url_chains"));
7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(statement1.Step());
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(3, statement1.ColumnInt(0));
7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Delete some rows and make sure the results are still correct.
7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CreateBackendAndDatabase();
7517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  db_->RemoveDownload(id2);
7527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  db_->RemoveDownload(id3);
7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeleteBackend();
7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sql::Connection db;
7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(db.Open(history_dir_.Append(chrome::kHistoryFilename)));
7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sql::Statement statement(db.GetUniqueStatement(
7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "Select Count(*) from downloads"));
7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(statement.Step());
7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, statement.ColumnInt(0));
7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sql::Statement statement1(db.GetUniqueStatement(
7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "Select Count(*) from downloads_url_chains"));
7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(statement1.Step());
7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, statement1.ColumnInt(0));
7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
769c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(HistoryBackendDBTest, DownloadNukeRecordsMissingURLs) {
770c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CreateBackendAndDatabase();
771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::Time now(base::Time::Now());
772c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector<GURL> url_chain;
773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DownloadRow download(base::FilePath(FILE_PATH_LITERAL("foo-path")),
774c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       base::FilePath(FILE_PATH_LITERAL("foo-path")),
775c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       url_chain,
776c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       GURL(std::string()),
777f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                       "application/octet-stream",
778f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                       "application/octet-stream",
779c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       now,
780c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       now,
781ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                       std::string(),
782ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                       std::string(),
783c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       0,
784c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       512,
785c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       DownloadItem::COMPLETE,
786c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
787c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       content::DOWNLOAD_INTERRUPT_REASON_NONE,
7887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                       1,
789a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                       0,
790a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                       "by_ext_id",
791a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                       "by_ext_name");
792c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
793c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Creating records without any urls should fail.
7947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(db_->CreateDownload(download));
795c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
796c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  download.url_chain.push_back(GURL("foo-url"));
7977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(db_->CreateDownload(download));
798c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
799c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Pretend that the URLs were dropped.
800c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DeleteBackend();
801c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  {
802c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    sql::Connection db;
803c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_TRUE(db.Open(history_dir_.Append(chrome::kHistoryFilename)));
804c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    sql::Statement statement(db.GetUniqueStatement(
805c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        "DELETE FROM downloads_url_chains WHERE id=1"));
806c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_TRUE(statement.Run());
807c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
808c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CreateBackendAndDatabase();
809c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector<DownloadRow> downloads;
810c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  db_->QueryDownloads(&downloads);
811c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0U, downloads.size());
812c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
813c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // QueryDownloads should have nuked the corrupt record.
814c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DeleteBackend();
815c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  {
816c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    sql::Connection db;
817c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_TRUE(db.Open(history_dir_.Append(chrome::kHistoryFilename)));
818c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    {
819c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      sql::Statement statement(db.GetUniqueStatement(
820c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            "SELECT count(*) from downloads"));
821c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ASSERT_TRUE(statement.Step());
822c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      EXPECT_EQ(0, statement.ColumnInt(0));
823c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
824c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
825c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
826c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
827c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(HistoryBackendDBTest, ConfirmDownloadInProgressCleanup) {
828c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create the DB.
829c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CreateBackendAndDatabase();
830c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
831c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::Time now(base::Time::Now());
832c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
833c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Put an IN_PROGRESS download in the DB.
8347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  AddDownload(1, DownloadItem::IN_PROGRESS, now);
835c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
836c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Confirm that they made it into the DB unchanged.
837c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DeleteBackend();
838c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  {
839c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    sql::Connection db;
840c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_TRUE(db.Open(history_dir_.Append(chrome::kHistoryFilename)));
841c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    sql::Statement statement(db.GetUniqueStatement(
842c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        "Select Count(*) from downloads"));
843c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(statement.Step());
844c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(1, statement.ColumnInt(0));
845c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
846c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    sql::Statement statement1(db.GetUniqueStatement(
847c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        "Select state, interrupt_reason from downloads"));
848c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(statement1.Step());
849c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(DownloadDatabase::kStateInProgress, statement1.ColumnInt(0));
850c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(content::DOWNLOAD_INTERRUPT_REASON_NONE, statement1.ColumnInt(1));
851c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_FALSE(statement1.Step());
852c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
853c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
854c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Read in the DB through query downloads, then test that the
855c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // right transformation was returned.
856c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CreateBackendAndDatabase();
857c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector<DownloadRow> results;
858c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  db_->QueryDownloads(&results);
859c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(1u, results.size());
860c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(content::DownloadItem::INTERRUPTED, results[0].state);
861c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(content::DOWNLOAD_INTERRUPT_REASON_CRASH,
862c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            results[0].interrupt_reason);
863c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
864c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Allow the update to propagate, shut down the DB, and confirm that
865c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // the query updated the on disk database as well.
86690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
867c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DeleteBackend();
868c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  {
869c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    sql::Connection db;
870c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_TRUE(db.Open(history_dir_.Append(chrome::kHistoryFilename)));
871c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    sql::Statement statement(db.GetUniqueStatement(
872c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        "Select Count(*) from downloads"));
873c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(statement.Step());
874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(1, statement.ColumnInt(0));
875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
876c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    sql::Statement statement1(db.GetUniqueStatement(
877c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        "Select state, interrupt_reason from downloads"));
878c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(statement1.Step());
879c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(DownloadDatabase::kStateInterrupted, statement1.ColumnInt(0));
880c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(content::DOWNLOAD_INTERRUPT_REASON_CRASH,
881c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              statement1.ColumnInt(1));
882c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_FALSE(statement1.Step());
883c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
884c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
885c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct InterruptReasonAssociation {
8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string name;
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int value;
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test is dependent on interrupt reasons being listed in header file
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// in order.
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const InterruptReasonAssociation current_reasons[] = {
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define INTERRUPT_REASON(a, b) { #a, b },
8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/download_interrupt_reason_values.h"
8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#undef INTERRUPT_REASON
8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This represents a list of all reasons we've previously used;
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Do Not Remove Any Entries From This List.
9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const InterruptReasonAssociation historical_reasons[] = {
9022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {"FILE_FAILED",  1},
9032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {"FILE_ACCESS_DENIED",  2},
9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {"FILE_NO_SPACE",  3},
9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {"FILE_NAME_TOO_LONG",  5},
9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {"FILE_TOO_LARGE",  6},
9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {"FILE_VIRUS_INFECTED",  7},
9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {"FILE_TRANSIENT_ERROR",  10},
9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {"FILE_BLOCKED",  11},
9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {"FILE_SECURITY_CHECK_FAILED",  12},
9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {"FILE_TOO_SHORT", 13},
9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {"NETWORK_FAILED",  20},
9132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {"NETWORK_TIMEOUT",  21},
9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {"NETWORK_DISCONNECTED",  22},
9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {"NETWORK_SERVER_DOWN",  23},
9165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  {"NETWORK_INVALID_REQUEST", 24},
9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {"SERVER_FAILED",  30},
9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {"SERVER_NO_RANGE",  31},
9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {"SERVER_PRECONDITION",  32},
9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {"SERVER_BAD_CONTENT",  33},
9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {"USER_CANCELED",  40},
9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {"USER_SHUTDOWN",  41},
9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {"CRASH",  50},
9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Make sure no one has changed a DownloadInterruptReason we've previously
9272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// persisted.
9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(HistoryBackendDBTest,
9292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ConfirmDownloadInterruptReasonBackwardsCompatible) {
9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Are there any cases in which a historical number has been repurposed
9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // for an error other than it's original?
9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < arraysize(current_reasons); i++) {
9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const InterruptReasonAssociation& cur_reason(current_reasons[i]);
9342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool found = false;
9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t j = 0; j < arraysize(historical_reasons); ++j) {
9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const InterruptReasonAssociation& hist_reason(historical_reasons[j]);
9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (hist_reason.value == cur_reason.value) {
9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        EXPECT_EQ(cur_reason.name, hist_reason.name)
9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            << "Same integer value used for old error \""
9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            << hist_reason.name
9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            << "\" as for new error \""
9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            << cur_reason.name
9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            << "\"." << std::endl
9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            << "**This will cause database conflicts with persisted values**"
9472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            << std::endl
9482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            << "Please assign a new, non-conflicting value for the new error.";
9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
9502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (hist_reason.name == cur_reason.name) {
9522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        EXPECT_EQ(cur_reason.value, hist_reason.value)
9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            << "Same name (\"" << hist_reason.name
9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            << "\") maps to a different value historically ("
9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            << hist_reason.value << ") and currently ("
9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            << cur_reason.value << ")" << std::endl
9572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            << "This may cause database conflicts with persisted values"
9582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            << std::endl
9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            << "If this error is the same as the old one, you should"
9602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            << std::endl
9612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            << "use the old value, and if it is different, you should"
9622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            << std::endl
9632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            << "use a new name.";
9642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        found = true;
9662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
9672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(found)
9702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << "Error \"" << cur_reason.name << "\" not found in historical list."
9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << std::endl
9722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << "Please add it.";
9732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HistoryTest : public testing::Test {
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HistoryTest()
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : got_thumbnail_callback_(false),
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        redirect_query_success_(false),
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        query_url_success_(false) {
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~HistoryTest() {
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnSegmentUsageAvailable(CancelableRequestProvider::Handle handle,
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               std::vector<PageUsageData*>* data) {
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    page_usage_data_.swap(*data);
99090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->Quit();
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnDeleteURLsDone(CancelableRequestProvider::Handle handle) {
99490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->Quit();
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnMostVisitedURLsAvailable(CancelableRequestProvider::Handle handle,
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  MostVisitedURLList url_list) {
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    most_visited_urls_.swap(url_list);
100090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->Quit();
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class BackendDelegate;
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // testing::Test
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history_dir_ = temp_dir_.path().AppendASCII("HistoryTest");
1010a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ASSERT_TRUE(base::CreateDirectory(history_dir_));
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history_service_.reset(new HistoryService);
101246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (!history_service_->Init(history_dir_)) {
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history_service_.reset();
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ADD_FAILURE();
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() {
1019b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    if (history_service_)
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CleanupHistoryService();
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure we don't have any event pending that could disrupt the next
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // test.
102490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(FROM_HERE,
102590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                           base::MessageLoop::QuitClosure());
102690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->Run();
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CleanupHistoryService() {
1030b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    DCHECK(history_service_);
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1032f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    history_service_->ClearCachedDataForContextID(0);
103390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    history_service_->SetOnBackendDestroyTask(base::MessageLoop::QuitClosure());
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history_service_->Cleanup();
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history_service_.reset();
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Wait for the backend class to terminate before deleting the files and
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // moving to the next test. Note: if this never terminates, somebody is
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // probably leaking a reference to the history backend, so it never calls
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // our destroy task.
104190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->Run();
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fills the query_url_row_ and query_url_visits_ structures with the
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // information about the given URL and returns true. If the URL was not
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // found, this will return false and those structures will not be changed.
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool QueryURL(HistoryService* history, const GURL& url) {
1048f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    history_service_->QueryURL(
1049f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        url,
1050f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        true,
1051f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        base::Bind(&HistoryTest::SaveURLAndQuit, base::Unretained(this)),
1052f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        &tracker_);
105390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->Run();  // Will be exited in SaveURLAndQuit.
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return query_url_success_;
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Callback for HistoryService::QueryURL.
1058f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void SaveURLAndQuit(bool success,
1059f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                      const URLRow& url_row,
1060f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                      const VisitVector& visits) {
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    query_url_success_ = success;
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (query_url_success_) {
1063f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      query_url_row_ = url_row;
1064f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      query_url_visits_ = visits;
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      query_url_row_ = URLRow();
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      query_url_visits_.clear();
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
106990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->Quit();
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fills in saved_redirects_ with the redirect information for the given URL,
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // returning true on success. False means the URL was not found.
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool QueryRedirectsFrom(HistoryService* history, const GURL& url) {
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history_service_->QueryRedirectsFrom(
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url, &consumer_,
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&HistoryTest::OnRedirectQueryComplete,
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this)));
107990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->Run();  // Will be exited in *QueryComplete.
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return redirect_query_success_;
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Callback for QueryRedirects.
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnRedirectQueryComplete(HistoryService::Handle handle,
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               GURL url,
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               bool success,
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               history::RedirectList* redirects) {
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    redirect_query_success_ = success;
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (redirect_query_success_)
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      saved_redirects_.swap(*redirects);
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      saved_redirects_.clear();
109390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->Quit();
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir temp_dir_;
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoopForUI message_loop_;
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PageUsageData vector to test segments.
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedVector<PageUsageData> page_usage_data_;
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MostVisitedURLList most_visited_urls_;
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When non-NULL, this will be deleted on tear down and we will block until
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the backend thread has completed. This allows tests for the history
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // service to use this feature, but other tests to ignore this.
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HistoryService> history_service_;
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // names of the database files
11112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath history_dir_;
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set by the thumbnail callback when we get data, you should be sure to
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // clear this before issuing a thumbnail request.
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool got_thumbnail_callback_;
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<unsigned char> thumbnail_data_;
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set by the redirect callback when we get data. You should be sure to
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // clear this before issuing a redirect request.
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::RedirectList saved_redirects_;
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool redirect_query_success_;
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For history requests.
1124f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::CancelableTaskTracker tracker_;
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CancelableRequestConsumer consumer_;
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For saving URL info after a call to QueryURL
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool query_url_success_;
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRow query_url_row_;
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitVector query_url_visits_;
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryTest, AddPage) {
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(history_service_.get());
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add the page once from a child frame.
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL test_url("http://www.google.com/");
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->AddPage(test_url, base::Time::Now(), NULL, 0, GURL(),
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            history::RedirectList(),
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            content::PAGE_TRANSITION_MANUAL_SUBFRAME,
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            history::SOURCE_BROWSED, false);
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(QueryURL(history_service_.get(), test_url));
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, query_url_row_.visit_count());
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, query_url_row_.typed_count());
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(query_url_row_.hidden());  // Hidden because of child frame.
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add the page once from the main frame (should unhide it).
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->AddPage(test_url, base::Time::Now(), NULL, 0, GURL(),
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   history::RedirectList(), content::PAGE_TRANSITION_LINK,
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   history::SOURCE_BROWSED, false);
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(QueryURL(history_service_.get(), test_url));
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, query_url_row_.visit_count());  // Added twice.
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, query_url_row_.typed_count());  // Never typed.
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(query_url_row_.hidden());  // Because loaded in main frame.
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryTest, AddRedirect) {
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(history_service_.get());
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* first_sequence[] = {
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "http://first.page.com/",
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "http://second.page.com/"};
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int first_count = arraysize(first_sequence);
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::RedirectList first_redirects;
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < first_count; i++)
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    first_redirects.push_back(GURL(first_sequence[i]));
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add the sequence of pages as a server with no referrer. Note that we need
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to have a non-NULL page ID scope.
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->AddPage(
1169f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      first_redirects.back(), base::Time::Now(),
1170f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      reinterpret_cast<ContextID>(1), 0, GURL(), first_redirects,
1171f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      content::PAGE_TRANSITION_LINK, history::SOURCE_BROWSED, true);
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first page should be added once with a link visit type (because we set
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // LINK when we added the original URL, and a referrer of nowhere (0).
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(QueryURL(history_service_.get(), first_redirects[0]));
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, query_url_row_.visit_count());
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, query_url_visits_.size());
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 first_visit = query_url_visits_[0].visit_id;
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(content::PAGE_TRANSITION_LINK |
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            content::PAGE_TRANSITION_CHAIN_START,
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            query_url_visits_[0].transition);
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, query_url_visits_[0].referring_visit);  // No referrer.
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The second page should be a server redirect type with a referrer of the
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // first page.
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(QueryURL(history_service_.get(), first_redirects[1]));
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, query_url_row_.visit_count());
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, query_url_visits_.size());
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 second_visit = query_url_visits_[0].visit_id;
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(content::PAGE_TRANSITION_SERVER_REDIRECT |
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            content::PAGE_TRANSITION_CHAIN_END,
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            query_url_visits_[0].transition);
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(first_visit, query_url_visits_[0].referring_visit);
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the redirect finding function successfully reports it.
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  saved_redirects_.clear();
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryRedirectsFrom(history_service_.get(), first_redirects[0]);
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, saved_redirects_.size());
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(first_redirects[1], saved_redirects_[0]);
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now add a client redirect from that second visit to a third, client
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // redirects are tracked by the RenderView prior to updating history,
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so we pass in a CLIENT_REDIRECT qualifier to mock that behavior.
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::RedirectList second_redirects;
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  second_redirects.push_back(first_redirects[1]);
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  second_redirects.push_back(GURL("http://last.page.com/"));
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->AddPage(second_redirects[1], base::Time::Now(),
1208f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                   reinterpret_cast<ContextID>(1), 1,
1209f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                   second_redirects[0], second_redirects,
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   static_cast<content::PageTransition>(
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       content::PAGE_TRANSITION_LINK |
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       content::PAGE_TRANSITION_CLIENT_REDIRECT),
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   history::SOURCE_BROWSED, true);
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The last page (source of the client redirect) should NOT have an
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // additional visit added, because it was a client redirect (normally it
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // would). We should only have 1 left over from the first sequence.
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(QueryURL(history_service_.get(), second_redirects[0]));
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, query_url_row_.visit_count());
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The final page should be set as a client redirect from the previous visit.
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(QueryURL(history_service_.get(), second_redirects[1]));
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, query_url_row_.visit_count());
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, query_url_visits_.size());
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(content::PAGE_TRANSITION_CLIENT_REDIRECT |
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            content::PAGE_TRANSITION_CHAIN_END,
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            query_url_visits_[0].transition);
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(second_visit, query_url_visits_[0].referring_visit);
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryTest, MakeIntranetURLsTyped) {
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(history_service_.get());
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a non-typed visit to an intranet URL on an unvisited host.  This should
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // get promoted to a typed visit.
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL test_url("http://intranet_host/path");
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->AddPage(
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_url, base::Time::Now(), NULL, 0, GURL(),
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::RedirectList(), content::PAGE_TRANSITION_LINK,
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::SOURCE_BROWSED, false);
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(QueryURL(history_service_.get(), test_url));
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, query_url_row_.visit_count());
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, query_url_row_.typed_count());
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, query_url_visits_.size());
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(content::PAGE_TRANSITION_TYPED,
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::PageTransitionStripQualifier(query_url_visits_[0].transition));
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add more visits on the same host.  None of these should be promoted since
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // there is already a typed visit.
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Different path.
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL test_url2("http://intranet_host/different_path");
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->AddPage(
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_url2, base::Time::Now(), NULL, 0, GURL(),
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::RedirectList(), content::PAGE_TRANSITION_LINK,
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::SOURCE_BROWSED, false);
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(QueryURL(history_service_.get(), test_url2));
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, query_url_row_.visit_count());
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, query_url_row_.typed_count());
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, query_url_visits_.size());
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(content::PAGE_TRANSITION_LINK,
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::PageTransitionStripQualifier(query_url_visits_[0].transition));
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No path.
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL test_url3("http://intranet_host/");
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->AddPage(
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_url3, base::Time::Now(), NULL, 0, GURL(),
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::RedirectList(), content::PAGE_TRANSITION_LINK,
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::SOURCE_BROWSED, false);
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(QueryURL(history_service_.get(), test_url3));
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, query_url_row_.visit_count());
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, query_url_row_.typed_count());
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, query_url_visits_.size());
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(content::PAGE_TRANSITION_LINK,
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::PageTransitionStripQualifier(query_url_visits_[0].transition));
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Different scheme.
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL test_url4("https://intranet_host/");
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->AddPage(
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_url4, base::Time::Now(), NULL, 0, GURL(),
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::RedirectList(), content::PAGE_TRANSITION_LINK,
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::SOURCE_BROWSED, false);
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(QueryURL(history_service_.get(), test_url4));
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, query_url_row_.visit_count());
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, query_url_row_.typed_count());
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, query_url_visits_.size());
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(content::PAGE_TRANSITION_LINK,
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::PageTransitionStripQualifier(query_url_visits_[0].transition));
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Different transition.
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL test_url5("http://intranet_host/another_path");
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->AddPage(
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_url5, base::Time::Now(), NULL, 0, GURL(),
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::RedirectList(),
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::PAGE_TRANSITION_AUTO_BOOKMARK,
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::SOURCE_BROWSED, false);
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(QueryURL(history_service_.get(), test_url5));
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, query_url_row_.visit_count());
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, query_url_row_.typed_count());
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, query_url_visits_.size());
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(content::PAGE_TRANSITION_AUTO_BOOKMARK,
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::PageTransitionStripQualifier(query_url_visits_[0].transition));
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Original URL.
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->AddPage(
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_url, base::Time::Now(), NULL, 0, GURL(),
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::RedirectList(), content::PAGE_TRANSITION_LINK,
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::SOURCE_BROWSED, false);
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(QueryURL(history_service_.get(), test_url));
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, query_url_row_.visit_count());
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, query_url_row_.typed_count());
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2U, query_url_visits_.size());
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(content::PAGE_TRANSITION_LINK,
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::PageTransitionStripQualifier(query_url_visits_[1].transition));
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryTest, Typed) {
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(history_service_.get());
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add the page once as typed.
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL test_url("http://www.google.com/");
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->AddPage(
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_url, base::Time::Now(), NULL, 0, GURL(),
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::RedirectList(), content::PAGE_TRANSITION_TYPED,
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::SOURCE_BROWSED, false);
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(QueryURL(history_service_.get(), test_url));
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should have the same typed & visit count.
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, query_url_row_.visit_count());
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, query_url_row_.typed_count());
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add the page again not typed.
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->AddPage(
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_url, base::Time::Now(), NULL, 0, GURL(),
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::RedirectList(), content::PAGE_TRANSITION_LINK,
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::SOURCE_BROWSED, false);
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(QueryURL(history_service_.get(), test_url));
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The second time should not have updated the typed count.
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, query_url_row_.visit_count());
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, query_url_row_.typed_count());
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add the page again as a generated URL.
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->AddPage(
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_url, base::Time::Now(), NULL, 0, GURL(),
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::RedirectList(), content::PAGE_TRANSITION_GENERATED,
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::SOURCE_BROWSED, false);
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(QueryURL(history_service_.get(), test_url));
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This should have worked like a link click.
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, query_url_row_.visit_count());
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, query_url_row_.typed_count());
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add the page again as a reload.
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->AddPage(
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_url, base::Time::Now(), NULL, 0, GURL(),
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::RedirectList(), content::PAGE_TRANSITION_RELOAD,
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::SOURCE_BROWSED, false);
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(QueryURL(history_service_.get(), test_url));
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This should not have incremented any visit counts.
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, query_url_row_.visit_count());
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, query_url_row_.typed_count());
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryTest, SetTitle) {
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(history_service_.get());
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a URL.
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL existing_url("http://www.google.com/");
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->AddPage(
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      existing_url, base::Time::Now(), history::SOURCE_BROWSED);
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set some title.
13755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::string16 existing_title = base::UTF8ToUTF16("Google");
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->SetPageTitle(existing_url, existing_title);
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the title got set.
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(QueryURL(history_service_.get(), existing_url));
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(existing_title, query_url_row_.title());
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // set a title on a nonexistent page
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL nonexistent_url("http://news.google.com/");
13845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::string16 nonexistent_title = base::UTF8ToUTF16("Google News");
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->SetPageTitle(nonexistent_url, nonexistent_title);
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure nothing got written.
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(QueryURL(history_service_.get(), nonexistent_url));
13895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::string16(), query_url_row_.title());
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(brettw) this should also test redirects, which get the title of the
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // destination page.
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// crbug.com/159387: This test fails when daylight savings time ends.
13962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(HistoryTest, DISABLED_Segments) {
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(history_service_.get());
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1399f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  static ContextID context_id = static_cast<ContextID>(this);
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a URL.
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL existing_url("http://www.google.com/");
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->AddPage(
1404f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      existing_url, base::Time::Now(), context_id, 0, GURL(),
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::RedirectList(), content::PAGE_TRANSITION_TYPED,
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::SOURCE_BROWSED, false);
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure a segment was created.
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->QuerySegmentUsageSince(
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &consumer_, Time::Now() - TimeDelta::FromDays(1), 10,
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&HistoryTest::OnSegmentUsageAvailable,
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)));
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait for processing.
141590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->Run();
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, page_usage_data_.size());
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(page_usage_data_[0]->GetURL() == existing_url);
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_DOUBLE_EQ(3.0, page_usage_data_[0]->GetScore());
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a URL which doesn't create a segment.
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL link_url("http://yahoo.com/");
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->AddPage(
1424f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      link_url, base::Time::Now(), context_id, 0, GURL(),
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::RedirectList(), content::PAGE_TRANSITION_LINK,
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::SOURCE_BROWSED, false);
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Query again
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->QuerySegmentUsageSince(
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &consumer_, Time::Now() - TimeDelta::FromDays(1), 10,
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&HistoryTest::OnSegmentUsageAvailable,
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)));
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait for processing.
143590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->Run();
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure we still have one segment.
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, page_usage_data_.size());
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(page_usage_data_[0]->GetURL() == existing_url);
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a page linked from existing_url.
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->AddPage(
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL("http://www.google.com/foo"), base::Time::Now(),
1444f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      context_id, 3, existing_url, history::RedirectList(),
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::PAGE_TRANSITION_LINK, history::SOURCE_BROWSED,
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false);
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Query again
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->QuerySegmentUsageSince(
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &consumer_, Time::Now() - TimeDelta::FromDays(1), 10,
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&HistoryTest::OnSegmentUsageAvailable,
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)));
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait for processing.
145590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->Run();
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure we still have one segment.
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, page_usage_data_.size());
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(page_usage_data_[0]->GetURL() == existing_url);
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // However, the score should have increased.
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(page_usage_data_[0]->GetScore(), 5.0);
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryTest, MostVisitedURLs) {
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(history_service_.get());
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url0("http://www.google.com/url0/");
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://www.google.com/url1/");
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://www.google.com/url2/");
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url3("http://www.google.com/url3/");
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url4("http://www.google.com/url4/");
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1474f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  static ContextID context_id = static_cast<ContextID>(this);
14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add two pages.
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->AddPage(
1478f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      url0, base::Time::Now(), context_id, 0, GURL(),
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::RedirectList(), content::PAGE_TRANSITION_TYPED,
14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::SOURCE_BROWSED, false);
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->AddPage(
1482f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      url1, base::Time::Now(), context_id, 0, GURL(),
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::RedirectList(), content::PAGE_TRANSITION_TYPED,
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::SOURCE_BROWSED, false);
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->QueryMostVisitedURLs(
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      20, 90, &consumer_,
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &HistoryTest::OnMostVisitedURLsAvailable,
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Unretained(this)));
149090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->Run();
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2U, most_visited_urls_.size());
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url0, most_visited_urls_[0].url);
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1, most_visited_urls_[1].url);
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add another page.
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->AddPage(
1498f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      url2, base::Time::Now(), context_id, 0, GURL(),
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::RedirectList(), content::PAGE_TRANSITION_TYPED,
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::SOURCE_BROWSED, false);
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->QueryMostVisitedURLs(
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      20, 90, &consumer_,
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &HistoryTest::OnMostVisitedURLsAvailable,
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Unretained(this)));
150690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->Run();
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3U, most_visited_urls_.size());
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url0, most_visited_urls_[0].url);
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1, most_visited_urls_[1].url);
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url2, most_visited_urls_[2].url);
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Revisit url2, making it the top URL.
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->AddPage(
1515f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      url2, base::Time::Now(), context_id, 0, GURL(),
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::RedirectList(), content::PAGE_TRANSITION_TYPED,
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::SOURCE_BROWSED, false);
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->QueryMostVisitedURLs(
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      20, 90, &consumer_,
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &HistoryTest::OnMostVisitedURLsAvailable,
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Unretained(this)));
152390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->Run();
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3U, most_visited_urls_.size());
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url2, most_visited_urls_[0].url);
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url0, most_visited_urls_[1].url);
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1, most_visited_urls_[2].url);
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Revisit url1, making it the top URL.
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->AddPage(
1532f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      url1, base::Time::Now(), context_id, 0, GURL(),
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::RedirectList(), content::PAGE_TRANSITION_TYPED,
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::SOURCE_BROWSED, false);
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->QueryMostVisitedURLs(
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      20, 90, &consumer_,
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &HistoryTest::OnMostVisitedURLsAvailable,
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Unretained(this)));
154090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->Run();
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3U, most_visited_urls_.size());
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1, most_visited_urls_[0].url);
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url2, most_visited_urls_[1].url);
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url0, most_visited_urls_[2].url);
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Redirects
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::RedirectList redirects;
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  redirects.push_back(url3);
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  redirects.push_back(url4);
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Visit url4 using redirects.
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->AddPage(
1554f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      url4, base::Time::Now(), context_id, 0, GURL(),
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      redirects, content::PAGE_TRANSITION_TYPED,
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::SOURCE_BROWSED, false);
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->QueryMostVisitedURLs(
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      20, 90, &consumer_,
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &HistoryTest::OnMostVisitedURLsAvailable,
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Unretained(this)));
156290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->Run();
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4U, most_visited_urls_.size());
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1, most_visited_urls_[0].url);
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url2, most_visited_urls_[1].url);
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url0, most_visited_urls_[2].url);
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url3, most_visited_urls_[3].url);
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2U, most_visited_urls_[3].redirects.size());
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A HistoryDBTask implementation. Each time RunOnDBThread is invoked
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// invoke_count is increment. When invoked kWantInvokeCount times, true is
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// returned from RunOnDBThread which should stop RunOnDBThread from being
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// invoked again. When DoneRunOnMainThread is invoked, done_invoked is set to
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// true.
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HistoryDBTaskImpl : public HistoryDBTask {
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kWantInvokeCount;
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HistoryDBTaskImpl() : invoke_count(0), done_invoked(false) {}
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool RunOnDBThread(HistoryBackend* backend,
15862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             HistoryDatabase* db) OVERRIDE {
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (++invoke_count == kWantInvokeCount);
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void DoneRunOnMainThread() OVERRIDE {
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    done_invoked = true;
159290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->Quit();
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int invoke_count;
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool done_invoked;
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~HistoryDBTaskImpl() {}
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(HistoryDBTaskImpl);
16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int HistoryDBTaskImpl::kWantInvokeCount = 2;
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryTest, HistoryDBTask) {
16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(history_service_.get());
16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CancelableRequestConsumerT<int, 0> request_consumer;
16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<HistoryDBTaskImpl> task(new HistoryDBTaskImpl());
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->ScheduleDBTask(task.get(), &request_consumer);
16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run the message loop. When HistoryDBTaskImpl::DoneRunOnMainThread runs,
16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it will stop the message loop. If the test hangs here, it means
16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DoneRunOnMainThread isn't being invoked correctly.
161790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->Run();
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CleanupHistoryService();
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // WARNING: history has now been deleted.
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_.reset();
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(HistoryDBTaskImpl::kWantInvokeCount, task->invoke_count);
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(task->done_invoked);
16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryTest, HistoryDBTaskCanceled) {
16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(history_service_.get());
16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CancelableRequestConsumerT<int, 0> request_consumer;
16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<HistoryDBTaskImpl> task(new HistoryDBTaskImpl());
16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_->ScheduleDBTask(task.get(), &request_consumer);
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_consumer.CancelAllRequests();
16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CleanupHistoryService();
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // WARNING: history has now been deleted.
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_service_.reset();
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(task->done_invoked);
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Create a local delete directive and process it while sync is
16382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// online, and then when offline. The delete directive should be sent to sync,
16392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// no error should be returned for the first time, and an error should be
16402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// returned for the second time.
16412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(HistoryTest, ProcessLocalDeleteDirectiveSyncOnline) {
16422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(history_service_.get());
16432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL test_url("http://www.google.com/");
16452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int64 i = 1; i <= 10; ++i) {
16462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::Time t =
16472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Time::UnixEpoch() + base::TimeDelta::FromMicroseconds(i);
16482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    history_service_->AddPage(test_url, t, NULL, 0, GURL(),
16492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              history::RedirectList(),
16502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              content::PAGE_TRANSITION_LINK,
16512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              history::SOURCE_BROWSED, false);
16522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
16532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sync_pb::HistoryDeleteDirectiveSpecifics delete_directive;
16552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sync_pb::GlobalIdDirective* global_id_directive =
16562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      delete_directive.mutable_global_id_directive();
16572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  global_id_directive->add_global_id(
16582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (base::Time::UnixEpoch() + base::TimeDelta::FromMicroseconds(1))
16592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .ToInternalValue());
16602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1661a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  syncer::FakeSyncChangeProcessor change_processor;
16622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(
16642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      history_service_->MergeDataAndStartSyncing(
1665a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            syncer::HISTORY_DELETE_DIRECTIVES,
1666a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            syncer::SyncDataList(),
1667a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            scoped_ptr<syncer::SyncChangeProcessor>(
1668a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                new syncer::SyncChangeProcessorWrapperForTest(
1669a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                    &change_processor)),
1670a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            scoped_ptr<syncer::SyncErrorFactory>())
1671a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          .error()
1672a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          .IsSet());
16732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncError err =
16752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      history_service_->ProcessLocalDeleteDirective(delete_directive);
16762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(err.IsSet());
1677a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1u, change_processor.changes().size());
16782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  history_service_->StopSyncing(syncer::HISTORY_DELETE_DIRECTIVES);
16802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  err = history_service_->ProcessLocalDeleteDirective(delete_directive);
16812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(err.IsSet());
1682a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1u, change_processor.changes().size());
16832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
16842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Closure function that runs periodically to check result of delete directive
16862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// processing. Stop when timeout or processing ends indicated by the creation
16872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// of sync changes.
16882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CheckDirectiveProcessingResult(
1689a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    Time timeout,
1690a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const syncer::FakeSyncChangeProcessor* change_processor,
16912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uint32 num_changes) {
16922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (base::Time::Now() > timeout ||
1693a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      change_processor->changes().size() >= num_changes) {
16942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
16952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
16962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
169890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
16992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
17002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&CheckDirectiveProcessingResult, timeout,
17012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 change_processor, num_changes));
17022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
17032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Create a delete directive for a few specific history entries,
17052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// including ones that don't exist. The expected entries should be
17062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// deleted.
17072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(HistoryTest, ProcessGlobalIdDeleteDirective) {
17082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(history_service_.get());
17092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL test_url("http://www.google.com/");
17102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int64 i = 1; i <= 20; i++) {
17112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::Time t =
17122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Time::UnixEpoch() + base::TimeDelta::FromMicroseconds(i);
17132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    history_service_->AddPage(test_url, t, NULL, 0, GURL(),
17142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              history::RedirectList(),
17152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              content::PAGE_TRANSITION_LINK,
17162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              history::SOURCE_BROWSED, false);
17172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
17182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(QueryURL(history_service_.get(), test_url));
17202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(20, query_url_row_.visit_count());
17212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncDataList directives;
17232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 1st directive.
17242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sync_pb::EntitySpecifics entity_specs;
17252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sync_pb::GlobalIdDirective* global_id_directive =
17262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      entity_specs.mutable_history_delete_directive()
17272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          ->mutable_global_id_directive();
17282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  global_id_directive->add_global_id(
17292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (base::Time::UnixEpoch() + base::TimeDelta::FromMicroseconds(6))
17302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .ToInternalValue());
17312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  global_id_directive->set_start_time_usec(3);
17322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  global_id_directive->set_end_time_usec(10);
1733a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  directives.push_back(syncer::SyncData::CreateRemoteData(
1734a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      1,
1735a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      entity_specs,
1736a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::Time(),
1737a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentIdList(),
1738a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentServiceProxyForTest::Create()));
17392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 2nd directive.
17412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  global_id_directive->Clear();
17422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  global_id_directive->add_global_id(
17432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (base::Time::UnixEpoch() + base::TimeDelta::FromMicroseconds(17))
17442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .ToInternalValue());
17452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  global_id_directive->set_start_time_usec(13);
17462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  global_id_directive->set_end_time_usec(19);
1747a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  directives.push_back(syncer::SyncData::CreateRemoteData(
1748a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      2,
1749a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      entity_specs,
1750a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::Time(),
1751a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentIdList(),
1752a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentServiceProxyForTest::Create()));
17532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1754a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  syncer::FakeSyncChangeProcessor change_processor;
17552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(
17562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      history_service_->MergeDataAndStartSyncing(
1757a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            syncer::HISTORY_DELETE_DIRECTIVES,
1758a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            directives,
1759a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            scoped_ptr<syncer::SyncChangeProcessor>(
1760a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                new syncer::SyncChangeProcessorWrapperForTest(
1761a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                    &change_processor)),
1762a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            scoped_ptr<syncer::SyncErrorFactory>())
1763a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          .error()
1764a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          .IsSet());
17652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Inject a task to check status and keep message loop filled before directive
17672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // processing finishes.
176890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
17692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
17702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&CheckDirectiveProcessingResult,
17712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Time::Now() + base::TimeDelta::FromSeconds(10),
17722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 &change_processor, 2));
177390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
17742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(QueryURL(history_service_.get(), test_url));
17752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(5, query_url_row_.visit_count());
17762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(base::Time::UnixEpoch() + base::TimeDelta::FromMicroseconds(1),
17772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            query_url_visits_[0].visit_time);
17782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(base::Time::UnixEpoch() + base::TimeDelta::FromMicroseconds(2),
17792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            query_url_visits_[1].visit_time);
17802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(base::Time::UnixEpoch() + base::TimeDelta::FromMicroseconds(11),
17812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            query_url_visits_[2].visit_time);
17822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(base::Time::UnixEpoch() + base::TimeDelta::FromMicroseconds(12),
17832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            query_url_visits_[3].visit_time);
17842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(base::Time::UnixEpoch() + base::TimeDelta::FromMicroseconds(20),
17852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            query_url_visits_[4].visit_time);
17862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Expect two sync changes for deleting processed directives.
1788a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const syncer::SyncChangeList& sync_changes = change_processor.changes();
17892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(2u, sync_changes.size());
17902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_DELETE, sync_changes[0].change_type());
1791e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(1, syncer::SyncDataRemote(sync_changes[0].sync_data()).GetId());
17922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_DELETE, sync_changes[1].change_type());
1793e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(2, syncer::SyncDataRemote(sync_changes[1].sync_data()).GetId());
17942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
17952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Create delete directives for time ranges.  The expected entries should be
17972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// deleted.
17982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(HistoryTest, ProcessTimeRangeDeleteDirective) {
17992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(history_service_.get());
18002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL test_url("http://www.google.com/");
18012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int64 i = 1; i <= 10; ++i) {
18022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::Time t =
18032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Time::UnixEpoch() + base::TimeDelta::FromMicroseconds(i);
18042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    history_service_->AddPage(test_url, t, NULL, 0, GURL(),
18052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              history::RedirectList(),
18062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              content::PAGE_TRANSITION_LINK,
18072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              history::SOURCE_BROWSED, false);
18082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
18092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(QueryURL(history_service_.get(), test_url));
18112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(10, query_url_row_.visit_count());
18122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncDataList directives;
18142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 1st directive.
18152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sync_pb::EntitySpecifics entity_specs;
18162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sync_pb::TimeRangeDirective* time_range_directive =
18172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      entity_specs.mutable_history_delete_directive()
18182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          ->mutable_time_range_directive();
18192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  time_range_directive->set_start_time_usec(2);
18202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  time_range_directive->set_end_time_usec(5);
1821a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  directives.push_back(syncer::SyncData::CreateRemoteData(
1822a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      1,
1823a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      entity_specs,
1824a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::Time(),
1825a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentIdList(),
1826a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentServiceProxyForTest::Create()));
18272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 2nd directive.
18292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  time_range_directive->Clear();
18302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  time_range_directive->set_start_time_usec(8);
18312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  time_range_directive->set_end_time_usec(10);
1832a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  directives.push_back(syncer::SyncData::CreateRemoteData(
1833a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      2,
1834a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      entity_specs,
1835a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::Time(),
1836a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentIdList(),
1837a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      syncer::AttachmentServiceProxyForTest::Create()));
18382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1839a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  syncer::FakeSyncChangeProcessor change_processor;
18402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(
18412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      history_service_->MergeDataAndStartSyncing(
1842a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            syncer::HISTORY_DELETE_DIRECTIVES,
1843a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            directives,
1844a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            scoped_ptr<syncer::SyncChangeProcessor>(
1845a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                new syncer::SyncChangeProcessorWrapperForTest(
1846a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                    &change_processor)),
1847a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            scoped_ptr<syncer::SyncErrorFactory>())
1848a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          .error()
1849a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          .IsSet());
18502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Inject a task to check status and keep message loop filled before
18522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // directive processing finishes.
185390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
18542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
18552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&CheckDirectiveProcessingResult,
18562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Time::Now() + base::TimeDelta::FromSeconds(10),
18572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 &change_processor, 2));
185890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
18592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(QueryURL(history_service_.get(), test_url));
18602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(3, query_url_row_.visit_count());
18612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(base::Time::UnixEpoch() + base::TimeDelta::FromMicroseconds(1),
18622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            query_url_visits_[0].visit_time);
18632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(base::Time::UnixEpoch() + base::TimeDelta::FromMicroseconds(6),
18642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            query_url_visits_[1].visit_time);
18652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(base::Time::UnixEpoch() + base::TimeDelta::FromMicroseconds(7),
18662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            query_url_visits_[2].visit_time);
18672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Expect two sync changes for deleting processed directives.
1869a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const syncer::SyncChangeList& sync_changes = change_processor.changes();
18702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(2u, sync_changes.size());
18712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_DELETE, sync_changes[0].change_type());
1872e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(1, syncer::SyncDataRemote(sync_changes[0].sync_data()).GetId());
18732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_DELETE, sync_changes[1].change_type());
1874e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(2, syncer::SyncDataRemote(sync_changes[1].sync_data()).GetId());
18752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
18762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(HistoryBackendDBTest, MigratePresentations) {
18782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create the db we want. Use 22 since segments didn't change in that time
18792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // frame.
18802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(CreateDBVersion(22));
18812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const SegmentID segment_id = 2;
18832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const URLID url_id = 3;
18842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL url("http://www.foo.com");
18852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::string url_name(VisitSegmentDatabase::ComputeSegmentName(url));
18865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::string16 title(base::ASCIIToUTF16("Title1"));
18872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Time segment_time(Time::Now());
18882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
18902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Re-open the db for manual manipulation.
18912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sql::Connection db;
18922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(db.Open(history_dir_.Append(chrome::kHistoryFilename)));
18932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Add an entry to urls.
18952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {
18962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      sql::Statement s(db.GetUniqueStatement(
18972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           "INSERT INTO urls "
18982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           "(id, url, title, last_visit_time) VALUES "
18992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           "(?, ?, ?, ?)"));
19002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      s.BindInt64(0, url_id);
19012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      s.BindString(1, url.spec());
19022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      s.BindString16(2, title);
19032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      s.BindInt64(3, segment_time.ToInternalValue());
19042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ASSERT_TRUE(s.Run());
19052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
19062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Add an entry to segments.
19082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {
19092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      sql::Statement s(db.GetUniqueStatement(
19102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           "INSERT INTO segments "
19112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           "(id, name, url_id, pres_index) VALUES "
19122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           "(?, ?, ?, ?)"));
19132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      s.BindInt64(0, segment_id);
19142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      s.BindString(1, url_name);
19152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      s.BindInt64(2, url_id);
19162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      s.BindInt(3, 4);  // pres_index
19172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ASSERT_TRUE(s.Run());
19182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
19192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // And one to segment_usage.
19212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {
19222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      sql::Statement s(db.GetUniqueStatement(
19232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           "INSERT INTO segment_usage "
19242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           "(id, segment_id, time_slot, visit_count) VALUES "
19252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           "(?, ?, ?, ?)"));
19262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      s.BindInt64(0, 4);  // id.
19272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      s.BindInt64(1, segment_id);
19282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      s.BindInt64(2, segment_time.ToInternalValue());
19292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      s.BindInt(3, 5);  // visit count.
19302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ASSERT_TRUE(s.Run());
19312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
19322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
19332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Re-open the db, triggering migration.
19352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CreateBackendAndDatabase();
19362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<PageUsageData*> results;
19382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  db_->QuerySegmentUsage(segment_time, 10, &results);
19392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(1u, results.size());
19402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(url, results[0]->GetURL());
19412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(segment_id, results[0]->GetID());
19422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(title, results[0]->GetTitle());
19432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  STLDeleteElements(&results);
19442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
19452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace history
1947