| Index: chrome/browser/download/download_history_unittest.cc
|
| diff --git a/chrome/browser/download/download_history_unittest.cc b/chrome/browser/download/download_history_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..b3ca216bcbb001f166d99dbf46ee52441e2f7cde
|
| --- /dev/null
|
| +++ b/chrome/browser/download/download_history_unittest.cc
|
| @@ -0,0 +1,351 @@
|
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "base/rand_util.h"
|
| +#include "chrome/browser/download/download_history.h"
|
| +#include "chrome/browser/history/history.h"
|
| +#include "chrome/test/base/in_process_browser_test.h"
|
| +#include "content/public/browser/download_persistent_store_info.h"
|
| +#include "content/public/test/mock_download_item.h"
|
| +#include "content/public/test/mock_download_manager.h"
|
| +#include "content/public/test/test_utils.h"
|
| +
|
| +using ::testing::Return;
|
| +using ::testing::ReturnRef;
|
| +using ::testing::NiceMock;
|
| +using ::testing::_;
|
| +using content::BrowserThread;
|
| +using content::DownloadItem;
|
| +using content::DownloadManager;
|
| +using content::DownloadPersistentStoreInfo;
|
| +using content::MockDownloadItem;
|
| +using content::MockDownloadManager;
|
| +
|
| +namespace {
|
| +
|
| +bool InfoEqual(const DownloadPersistentStoreInfo& left,
|
| + const DownloadPersistentStoreInfo& right) {
|
| + if (left.path != right.path) {
|
| + LOG(ERROR) << __FUNCTION__ << " " << left.path.value() << " " << right.path.value();
|
| + return false;
|
| + } else if (left.url != right.url) {
|
| + LOG(ERROR) << __FUNCTION__ << " " << left.url.spec() << " " << right.url.spec();
|
| + return false;
|
| + } else if (left.referrer_url != right.referrer_url) {
|
| + LOG(ERROR) << __FUNCTION__ << " " << left.referrer_url.spec() << " " << right.referrer_url.spec();
|
| + return false;
|
| + } else if (left.start_time != right.start_time) {
|
| + LOG(ERROR) << __FUNCTION__ << " " << left.start_time.ToTimeT() << " " << right.start_time.ToTimeT();
|
| + return false;
|
| + } else if (left.end_time != right.end_time) {
|
| + LOG(ERROR) << __FUNCTION__ << " " << left.end_time.ToTimeT() << " " << right.end_time.ToTimeT();
|
| + return false;
|
| + } else if (left.received_bytes != right.received_bytes) {
|
| + LOG(ERROR) << __FUNCTION__ << " " << left.received_bytes << " " << right.received_bytes;
|
| + return false;
|
| + } else if (left.total_bytes != right.total_bytes) {
|
| + LOG(ERROR) << __FUNCTION__ << " " << left.total_bytes << " " << right.total_bytes;
|
| + return false;
|
| + } else if (left.state != right.state) {
|
| + LOG(ERROR) << __FUNCTION__ << " " << left.state << " " << right.state;
|
| + return false;
|
| + } else if (left.db_handle != right.db_handle) {
|
| + LOG(ERROR) << __FUNCTION__ << " " << left.db_handle << " " << right.db_handle;
|
| + return false;
|
| + } else if (left.opened != right.opened) {
|
| + LOG(ERROR) << __FUNCTION__ << " " << left.opened << " " << right.opened;
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +class DownloadHistoryTest : public InProcessBrowserTest,
|
| + public HistoryServiceDownloadInterface {
|
| + public:
|
| + DownloadHistoryTest()
|
| + : manager_(new MockDownloadManager()),
|
| + download_history_(NULL),
|
| + expect_query_downloads_(NULL),
|
| + handle_counter_(0),
|
| + create_download_id_(-1) {
|
| + }
|
| + virtual ~DownloadHistoryTest() {}
|
| +
|
| + // HistoryServiceDownloadInterface
|
| + virtual void QueryDownloads(
|
| + const HistoryService::DownloadQueryCallback& callback) OVERRIDE {
|
| + CHECK(expect_query_downloads_);
|
| + for (DownloadHistory::InfoVector::const_iterator it =
|
| + expect_query_downloads_->begin();
|
| + it != expect_query_downloads_->end();
|
| + ++it) {
|
| + LOG(INFO) << "occam " << __FUNCTION__ << " " << it->db_handle;
|
| + }
|
| + callback.Run(expect_query_downloads_);
|
| + expect_query_downloads_ = NULL;
|
| + }
|
| +
|
| + virtual HistoryService::Handle GetVisibleVisitCountToHost(
|
| + const GURL& referrer_url,
|
| + const HistoryService::GetVisibleVisitCountToHostCallback&
|
| + callback) OVERRIDE {
|
| + NOTIMPLEMENTED();
|
| + return 0;
|
| + }
|
| +
|
| + virtual void CreateDownload(
|
| + int32 id,
|
| + const content::DownloadPersistentStoreInfo& info,
|
| + const HistoryService::DownloadCreateCallback& callback) OVERRIDE {
|
| + LOG(INFO) << "occam " << __FUNCTION__ << " " << id;
|
| + create_download_id_ = id;
|
| + create_download_info_ = info;
|
| + callback.Run(id, handle_counter_++);
|
| + }
|
| +
|
| + virtual void UpdateDownload(
|
| + const content::DownloadPersistentStoreInfo& info) OVERRIDE {
|
| + LOG(INFO) << "occam " << __FUNCTION__ << " " << info.path.value()
|
| + << " " << info.db_handle;
|
| + update_download_ = info;
|
| + }
|
| +
|
| + virtual void RemoveDownloads(
|
| + const DownloadHistory::HandleSet& handles) OVERRIDE {
|
| + LOG(INFO) << "occam " << __FUNCTION__ << " " << handles.size();
|
| + for (DownloadHistory::HandleSet::const_iterator it = handles.begin();
|
| + it != handles.end(); ++it) {
|
| + LOG(INFO) << "occam " << __FUNCTION__ << " " << *it;
|
| + remove_downloads_.insert(*it);
|
| + }
|
| + }
|
| +
|
| + virtual void OnDownloadHistoryDestroyed() OVERRIDE {
|
| + }
|
| +
|
| + protected:
|
| + virtual void SetUpOnMainThread() OVERRIDE {
|
| + EXPECT_CALL(manager(), AddObserver(_));
|
| + EXPECT_CALL(manager(), RemoveObserver(_));
|
| + download_history_.reset(new DownloadHistory(&manager(), this));
|
| + }
|
| +
|
| + virtual void CleanUpOnMainThread() OVERRIDE {
|
| + download_history_.reset();
|
| + }
|
| +
|
| + DownloadHistory* download_history() { return download_history_.get(); }
|
| +
|
| + MockDownloadManager& manager() { return *manager_.get(); }
|
| + MockDownloadItem& item() { return item_; }
|
| +
|
| + HistoryService::DownloadQueryCallback query_callback() {
|
| + return base::Bind(&DownloadHistoryTest::QueryCallback,
|
| + base::Unretained(this));
|
| + }
|
| +
|
| + void ExpectQueryDownloads(DownloadHistory::InfoVector* infos) {
|
| + expect_query_downloads_ = infos;
|
| + }
|
| +
|
| + void ExpectQueryDownloadsDone() {
|
| + CHECK(NULL == expect_query_downloads_);
|
| + }
|
| +
|
| + void ExpectCreateDownload(
|
| + const DownloadPersistentStoreInfo& info) {
|
| + CHECK_EQ(item().GetId(), create_download_id_);
|
| + create_download_id_ = -1;
|
| + CHECK(InfoEqual(info, create_download_info_));
|
| + create_download_info_ = DownloadPersistentStoreInfo();
|
| + }
|
| +
|
| + void ExpectNoCreateDownload() {
|
| + CHECK_EQ(-1, create_download_id_);
|
| + CHECK(InfoEqual(DownloadPersistentStoreInfo(), create_download_info_));
|
| + }
|
| +
|
| + void ExpectUpdateDownload(const DownloadPersistentStoreInfo& info) {
|
| + CHECK(InfoEqual(update_download_, info));
|
| + update_download_ = DownloadPersistentStoreInfo();
|
| + }
|
| +
|
| + void ExpectNoUpdateDownload() {
|
| + CHECK(InfoEqual(DownloadPersistentStoreInfo(), update_download_));
|
| + }
|
| +
|
| + void ExpectRemoveDownloads(const DownloadHistory::HandleSet& handles) {
|
| + content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
|
| + for (DownloadHistory::HandleSet::const_iterator it = handles.begin();
|
| + it != handles.end(); ++it) {
|
| + LOG(INFO) << "occam " << __FUNCTION__ << " expected handle " << *it;
|
| + }
|
| + for (DownloadHistory::HandleSet::const_iterator it = remove_downloads_.begin();
|
| + it != remove_downloads_.end(); ++it) {
|
| + LOG(INFO) << "occam " << __FUNCTION__ << " actual handle " << *it;
|
| + }
|
| + DownloadHistory::HandleSet difference;
|
| + std::insert_iterator<DownloadHistory::HandleSet> insert_it(
|
| + difference, difference.begin());
|
| + std::set_difference(handles.begin(), handles.end(),
|
| + remove_downloads_.begin(),
|
| + remove_downloads_.end(),
|
| + insert_it);
|
| + CHECK(difference.empty());
|
| + remove_downloads_.clear();
|
| + }
|
| +
|
| + void InitItem(
|
| + int32 id,
|
| + const FilePath& path,
|
| + const GURL& url,
|
| + const GURL& referrer,
|
| + const base::Time& start_time,
|
| + const base::Time& end_time,
|
| + int64 received_bytes,
|
| + int64 total_bytes,
|
| + DownloadItem::DownloadState state,
|
| + int64 db_handle,
|
| + bool opened,
|
| + DownloadPersistentStoreInfo* info) {
|
| + info->path = path;
|
| + info->url = url;
|
| + info->referrer_url = referrer;
|
| + info->start_time = start_time;
|
| + info->end_time = end_time;
|
| + info->received_bytes = received_bytes;
|
| + info->total_bytes = total_bytes;
|
| + info->state = state;
|
| + info->db_handle = db_handle;
|
| + info->opened = opened;
|
| + EXPECT_CALL(item(), GetId()).WillRepeatedly(Return(id));
|
| + EXPECT_CALL(item(), GetFullPath()).WillRepeatedly(ReturnRef(path));
|
| + EXPECT_CALL(item(), GetURL()).WillRepeatedly(ReturnRef(url));
|
| + EXPECT_CALL(item(), GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
|
| + EXPECT_CALL(item(), GetStartTime()).WillRepeatedly(Return(start_time));
|
| + EXPECT_CALL(item(), GetEndTime()).WillRepeatedly(Return(end_time));
|
| + EXPECT_CALL(item(), GetReceivedBytes())
|
| + .WillRepeatedly(Return(received_bytes));
|
| + EXPECT_CALL(item(), GetTotalBytes()).WillRepeatedly(Return(total_bytes));
|
| + EXPECT_CALL(item(), GetState()).WillRepeatedly(Return(state));
|
| + EXPECT_CALL(item(), GetOpened()).WillRepeatedly(Return(opened));
|
| + EXPECT_CALL(manager(), GetDownload(id))
|
| + .WillRepeatedly(Return(&item()));
|
| + EXPECT_CALL(item(), AddObserver(_));
|
| + EXPECT_CALL(item(), RemoveObserver(_));
|
| + }
|
| +
|
| + private:
|
| + void QueryCallback(DownloadHistory::InfoVector* infos) {
|
| + }
|
| +
|
| + testing::NiceMock<content::MockDownloadItem> item_;
|
| + scoped_refptr<content::MockDownloadManager> manager_;
|
| + scoped_ptr<DownloadHistory> download_history_;
|
| + DownloadHistory::InfoVector* expect_query_downloads_;
|
| + int handle_counter_;
|
| + DownloadPersistentStoreInfo update_download_;
|
| + int32 create_download_id_;
|
| + DownloadPersistentStoreInfo create_download_info_;
|
| + DownloadHistory::HandleSet remove_downloads_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(DownloadHistoryTest);
|
| +};
|
| +
|
| +} // anonymous namespace
|
| +
|
| +IN_PROC_BROWSER_TEST_F(DownloadHistoryTest, DownloadHistoryTest_Load) {
|
| + // Load a download from history, create the item, OnDownloadCreated,
|
| + // OnDownloadUpdated, OnDownloadRemoved, OnDownloadDestroyed.
|
| + DownloadPersistentStoreInfo info;
|
| + InitItem(base::RandInt(0, 1 << 20),
|
| + FilePath(FILE_PATH_LITERAL("/foo/bar.pdf")),
|
| + GURL("http://example.com/bar.pdf"),
|
| + GURL("http://example.com/referrer.html"),
|
| + (base::Time::Now() - base::TimeDelta::FromMinutes(10)),
|
| + (base::Time::Now() - base::TimeDelta::FromMinutes(1)),
|
| + 100,
|
| + 100,
|
| + DownloadItem::COMPLETE,
|
| + base::RandInt(0, 1 << 20),
|
| + false,
|
| + &info);
|
| + DownloadHistory::InfoVector infos;
|
| + infos.push_back(info);
|
| + ExpectQueryDownloads(&infos);
|
| + download_history()->Load(query_callback());
|
| + ExpectQueryDownloadsDone();
|
| +
|
| + // Pretend the manager just created |item| in response to
|
| + // OnPersistentStoreQueryComplete.
|
| + download_history()->OnDownloadCreated(&manager(), &item());
|
| + ExpectNoCreateDownload();
|
| +
|
| + // Pretend that something changed on the item.
|
| + EXPECT_CALL(item(), GetOpened()).WillRepeatedly(Return(true));
|
| + download_history()->OnDownloadUpdated(&item());
|
| + info.opened = true;
|
| + ExpectUpdateDownload(info);
|
| +
|
| + // Pretend that the user removed the item.
|
| + DownloadHistory::HandleSet handles;
|
| + handles.insert(info.db_handle);
|
| + download_history()->OnDownloadRemoved(&item());
|
| + ExpectRemoveDownloads(handles);
|
| +
|
| + // Pretend that the browser is closing.
|
| + download_history()->ManagerGoingDown(&manager());
|
| + download_history()->OnDownloadDestroyed(&item());
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(DownloadHistoryTest, DownloadHistoryTest_Create) {
|
| + // Create a fresh item not from history, OnDownloadCreated, OnDownloadUpdated,
|
| + // OnDownloadRemoved, OnDownloadDestroyed.
|
| + DownloadHistory::InfoVector infos;
|
| + ExpectQueryDownloads(&infos);
|
| + download_history()->Load(query_callback());
|
| + ExpectQueryDownloadsDone();
|
| +
|
| + // Note that db_handle must be -1 at first because it isn't in the db yet.
|
| + DownloadPersistentStoreInfo info;
|
| + InitItem(base::RandInt(0, 1 << 20),
|
| + FilePath(FILE_PATH_LITERAL("/foo/bar.pdf")),
|
| + GURL("http://example.com/bar.pdf"),
|
| + GURL("http://example.com/referrer.html"),
|
| + (base::Time::Now() - base::TimeDelta::FromMinutes(10)),
|
| + (base::Time::Now() - base::TimeDelta::FromMinutes(1)),
|
| + 100,
|
| + 100,
|
| + DownloadItem::COMPLETE,
|
| + -1,
|
| + false,
|
| + &info);
|
| +
|
| + // Pretend the manager just created |item| in response to
|
| + // OnPersistentStoreQueryComplete.
|
| + download_history()->OnDownloadCreated(&manager(), &item());
|
| + ExpectCreateDownload(info);
|
| + info.db_handle = 0;
|
| +
|
| + // Pretend that something changed on the item.
|
| + EXPECT_CALL(item(), GetOpened()).WillRepeatedly(Return(true));
|
| + download_history()->OnDownloadUpdated(&item());
|
| + info.opened = true;
|
| + ExpectUpdateDownload(info);
|
| +
|
| + // Pretend that the user removed the item.
|
| + DownloadHistory::HandleSet handles;
|
| + handles.insert(info.db_handle);
|
| + download_history()->OnDownloadRemoved(&item());
|
| + ExpectRemoveDownloads(handles);
|
| +
|
| + // Pretend that the browser is closing.
|
| + download_history()->ManagerGoingDown(&manager());
|
| + download_history()->OnDownloadDestroyed(&item());
|
| +}
|
| +
|
| + // TODO Create a fresh item, change it to temporary after it's been added.
|
| +
|
| + // TODO Test that OnDownloadCreated does not match up items if a field is off,
|
| + // except for state=IN_PROGRESS->CANCELLED.
|
|
|