| 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..878c1463a8fa002321207189b49f3005e03950f7
|
| --- /dev/null
|
| +++ b/chrome/browser/download/download_history_unittest.cc
|
| @@ -0,0 +1,487 @@
|
| +// 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/download/download_persistent_store_info.h"
|
| +#include "chrome/browser/history/history.h"
|
| +#include "chrome/test/base/in_process_browser_test.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 content::BrowserThread;
|
| +using content::DownloadItem;
|
| +using content::DownloadManager;
|
| +using content::MockDownloadItem;
|
| +using content::MockDownloadManager;
|
| +using testing::DoAll;
|
| +using testing::Invoke;
|
| +using testing::NiceMock;
|
| +using testing::Return;
|
| +using testing::ReturnRef;
|
| +using testing::_;
|
| +
|
| +namespace {
|
| +
|
| +bool InfoEqual(const DownloadPersistentStoreInfo& left,
|
| + const DownloadPersistentStoreInfo& right) {
|
| + if (left.path != right.path) {
|
| + LOG(ERROR) << left.path.value() << " != " << right.path.value();
|
| + return false;
|
| + } else if (left.url != right.url) {
|
| + LOG(ERROR) << left.url.spec() << " != " << right.url.spec();
|
| + return false;
|
| + } else if (left.referrer_url != right.referrer_url) {
|
| + LOG(ERROR) << left.referrer_url.spec() << " != "
|
| + << right.referrer_url.spec();
|
| + return false;
|
| + } else if (left.start_time != right.start_time) {
|
| + LOG(ERROR) << left.start_time.ToTimeT() << " != "
|
| + << right.start_time.ToTimeT();
|
| + return false;
|
| + } else if (left.end_time != right.end_time) {
|
| + LOG(ERROR) << left.end_time.ToTimeT() << " != " << right.end_time.ToTimeT();
|
| + return false;
|
| + } else if (left.received_bytes != right.received_bytes) {
|
| + LOG(ERROR) << left.received_bytes << " != " << right.received_bytes;
|
| + return false;
|
| + } else if (left.total_bytes != right.total_bytes) {
|
| + LOG(ERROR) << left.total_bytes << " != " << right.total_bytes;
|
| + return false;
|
| + } else if (left.state != right.state) {
|
| + LOG(ERROR) << left.state << " != " << right.state;
|
| + return false;
|
| + } else if (left.db_handle != right.db_handle) {
|
| + LOG(ERROR) << left.db_handle << " != " << right.db_handle;
|
| + return false;
|
| + } else if (left.opened != right.opened) {
|
| + LOG(ERROR) << left.opened << " != " << right.opened;
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +class DownloadHistoryTest : public InProcessBrowserTest,
|
| + public HistoryServiceDownloadAdapter {
|
| + public:
|
| + typedef std::set<int64> HandleSet;
|
| + typedef std::vector<DownloadPersistentStoreInfo> InfoVector;
|
| +
|
| + DownloadHistoryTest()
|
| + : HistoryServiceDownloadAdapter(NULL),
|
| + manager_(new MockDownloadManager()),
|
| + download_history_(NULL),
|
| + expect_query_downloads_(NULL),
|
| + slow_create_download_(false),
|
| + handle_counter_(0),
|
| + create_download_id_(-1) {
|
| + }
|
| + virtual ~DownloadHistoryTest() {}
|
| +
|
| + // HistoryServiceDownloadAdapter
|
| + virtual void QueryDownloads(
|
| + const HistoryService::DownloadQueryCallback& callback) OVERRIDE {
|
| + CHECK(expect_query_downloads_);
|
| + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
| + base::Bind(&DownloadHistoryTest::QueryDownloadsDone, this, callback));
|
| + }
|
| +
|
| + void QueryDownloadsDone(
|
| + const HistoryService::DownloadQueryCallback& callback) {
|
| + 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;
|
| + }
|
| +
|
| + void set_slow_create_download(bool slow) { slow_create_download_ = slow; }
|
| +
|
| + virtual void CreateDownload(
|
| + int32 id,
|
| + const DownloadPersistentStoreInfo& info,
|
| + const HistoryService::DownloadCreateCallback& callback) OVERRIDE {
|
| + create_download_id_ = id;
|
| + create_download_info_ = info;
|
| + create_download_callback_ = base::Bind(callback, id, handle_counter_++);
|
| + if (!slow_create_download_) {
|
| + FinishCreateDownload();
|
| + }
|
| + }
|
| +
|
| + void FinishCreateDownload() {
|
| + create_download_callback_.Run();
|
| + create_download_callback_.Reset();
|
| + }
|
| +
|
| + virtual void UpdateDownload(
|
| + const DownloadPersistentStoreInfo& info) OVERRIDE {
|
| + update_download_ = info;
|
| + }
|
| +
|
| + virtual void RemoveDownloads(
|
| + const HandleSet& handles) OVERRIDE {
|
| + for (HandleSet::const_iterator it = handles.begin();
|
| + it != handles.end(); ++it) {
|
| + remove_downloads_.insert(*it);
|
| + }
|
| + }
|
| +
|
| + virtual void OnDownloadHistoryDestroyed() OVERRIDE {
|
| + }
|
| +
|
| + protected:
|
| + 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(InfoVector* infos) {
|
| + expect_query_downloads_ = infos;
|
| + EXPECT_CALL(manager(), AddObserver(_));
|
| + EXPECT_CALL(manager(), RemoveObserver(_));
|
| + if (infos->size() != 0) {
|
| + EXPECT_EQ(1, static_cast<int>(infos->size()));
|
| + EXPECT_CALL(manager(), CreateDownloadItem(
|
| + infos->at(0).path,
|
| + infos->at(0).url,
|
| + infos->at(0).referrer_url,
|
| + infos->at(0).start_time,
|
| + infos->at(0).end_time,
|
| + infos->at(0).received_bytes,
|
| + infos->at(0).total_bytes,
|
| + infos->at(0).state,
|
| + infos->at(0).opened))
|
| + .WillOnce(DoAll(
|
| + InvokeWithoutArgs(
|
| + this, &DownloadHistoryTest::CallOnDownloadCreated),
|
| + Return(&item())));
|
| + }
|
| + download_history_.reset(new DownloadHistory(&manager(), this));
|
| + content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
|
| + CHECK(NULL == expect_query_downloads_);
|
| + }
|
| +
|
| + void CallOnDownloadCreated() {
|
| + download_history_->OnDownloadCreated(&manager(), &item());
|
| + }
|
| +
|
| + void ExpectCreateDownload(
|
| + const DownloadPersistentStoreInfo& info) {
|
| + content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
|
| + CHECK_EQ(item().GetId(), create_download_id_);
|
| + create_download_id_ = -1;
|
| + CHECK(InfoEqual(info, create_download_info_));
|
| + create_download_info_ = DownloadPersistentStoreInfo();
|
| + }
|
| +
|
| + void ExpectNoCreateDownload() {
|
| + content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
|
| + CHECK_EQ(-1, create_download_id_);
|
| + CHECK(InfoEqual(DownloadPersistentStoreInfo(), create_download_info_));
|
| + }
|
| +
|
| + void ExpectUpdateDownload(const DownloadPersistentStoreInfo& info) {
|
| + content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
|
| + CHECK(InfoEqual(update_download_, info));
|
| + update_download_ = DownloadPersistentStoreInfo();
|
| + }
|
| +
|
| + void ExpectNoUpdateDownload() {
|
| + content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
|
| + CHECK(InfoEqual(DownloadPersistentStoreInfo(), update_download_));
|
| + }
|
| +
|
| + void ExpectNoRemoveDownloads() {
|
| + content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
|
| + CHECK_EQ(0, static_cast<int>(remove_downloads_.size()));
|
| + }
|
| +
|
| + void ExpectRemoveDownloads(const HandleSet& handles) {
|
| + content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
|
| + HandleSet difference;
|
| + std::insert_iterator<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(item(), GetTargetDisposition()).WillRepeatedly(Return(
|
| + DownloadItem::TARGET_DISPOSITION_OVERWRITE));
|
| + EXPECT_CALL(manager(), GetDownload(id))
|
| + .WillRepeatedly(Return(&item()));
|
| + EXPECT_CALL(item(), AddObserver(_));
|
| + EXPECT_CALL(item(), RemoveObserver(_));
|
| + }
|
| +
|
| + private:
|
| + void QueryCallback(InfoVector* infos) {
|
| + }
|
| +
|
| + testing::NiceMock<content::MockDownloadItem> item_;
|
| + scoped_refptr<content::MockDownloadManager> manager_;
|
| + scoped_ptr<DownloadHistory> download_history_;
|
| + InfoVector* expect_query_downloads_;
|
| + bool slow_create_download_;
|
| + base::Closure create_download_callback_;
|
| + int handle_counter_;
|
| + DownloadPersistentStoreInfo update_download_;
|
| + int32 create_download_id_;
|
| + DownloadPersistentStoreInfo create_download_info_;
|
| + 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);
|
| + InfoVector infos;
|
| + infos.push_back(info);
|
| + ExpectQueryDownloads(&infos);
|
| + 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.
|
| + 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.
|
| + InfoVector infos;
|
| + ExpectQueryDownloads(&infos);
|
| +
|
| + // 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|.
|
| + download_history()->OnDownloadCreated(&manager(), &item());
|
| + // CreateDownload() always gets db_handle=-1.
|
| + 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.
|
| + 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_Temporary) {
|
| + // Create a fresh item not from history, OnDownloadCreated, OnDownloadUpdated,
|
| + // OnDownloadRemoved, OnDownloadDestroyed.
|
| + InfoVector infos;
|
| + ExpectQueryDownloads(&infos);
|
| +
|
| + // 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|.
|
| + download_history()->OnDownloadCreated(&manager(), &item());
|
| + // CreateDownload() always gets db_handle=-1.
|
| + ExpectCreateDownload(info);
|
| + info.db_handle = 0;
|
| +
|
| + // Pretend the item was marked temporary. DownloadHistory should remove it
|
| + // from history and start ignoring it.
|
| + EXPECT_CALL(item(), IsTemporary()).WillRepeatedly(Return(true));
|
| + download_history()->OnDownloadUpdated(&item());
|
| + HandleSet handles;
|
| + handles.insert(info.db_handle);
|
| + ExpectRemoveDownloads(handles);
|
| +
|
| + // Change something that would make DownloadHistory call UpdateDownload if the
|
| + // item weren't temporary.
|
| + EXPECT_CALL(item(), GetReceivedBytes()).WillRepeatedly(Return(4200));
|
| + download_history()->OnDownloadUpdated(&item());
|
| + ExpectNoUpdateDownload();
|
| +
|
| + // Changing a temporary item back to a non-temporary item should make
|
| + // DownloadHistory call CreateDownload.
|
| + EXPECT_CALL(item(), IsTemporary()).WillRepeatedly(Return(false));
|
| + download_history()->OnDownloadUpdated(&item());
|
| + info.received_bytes = 4200;
|
| + info.db_handle = -1;
|
| + // CreateDownload() always gets db_handle=-1.
|
| + ExpectCreateDownload(info);
|
| + info.db_handle = 1;
|
| +
|
| + EXPECT_CALL(item(), GetReceivedBytes()).WillRepeatedly(Return(100));
|
| + download_history()->OnDownloadUpdated(&item());
|
| + info.received_bytes = 100;
|
| + ExpectUpdateDownload(info);
|
| +
|
| + // Pretend that the browser is closing.
|
| + download_history()->ManagerGoingDown(&manager());
|
| + download_history()->OnDownloadDestroyed(&item());
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(DownloadHistoryTest,
|
| + DownloadHistoryTest_RemoveWhileAdding) {
|
| + InfoVector infos;
|
| + ExpectQueryDownloads(&infos);
|
| +
|
| + // 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);
|
| +
|
| + // Instruct CreateDownload() to not callback to DownloadHistory immediately,
|
| + // but to wait for FinishCreateDownload().
|
| + set_slow_create_download(true);
|
| +
|
| + // Pretend the manager just created |item|.
|
| + download_history()->OnDownloadCreated(&manager(), &item());
|
| + // CreateDownload() always gets db_handle=-1.
|
| + ExpectCreateDownload(info);
|
| + info.db_handle = 0;
|
| +
|
| + // Call OnDownloadRemoved before calling back to DownloadHistory::ItemAdded().
|
| + // Instead of calling RemoveDownloads() immediately, it should
|
| + download_history()->OnDownloadRemoved(&item());
|
| + EXPECT_CALL(manager(), GetDownload(item().GetId()))
|
| + .WillRepeatedly(Return(static_cast<DownloadItem*>(NULL)));
|
| + ExpectNoRemoveDownloads();
|
| +
|
| + // Now callback to DownloadHistory::ItemAdded(), and expect a call to
|
| + // RemoveDownloads() for the item that was removed while it was being added.
|
| + FinishCreateDownload();
|
| + HandleSet handles;
|
| + handles.insert(info.db_handle);
|
| + ExpectRemoveDownloads(handles);
|
| +
|
| + // Pretend that the browser is closing.
|
| + download_history()->ManagerGoingDown(&manager());
|
| + download_history()->OnDownloadDestroyed(&item());
|
| +}
|
| +
|
| +// TODO(benjhayden): Test Disable.
|
|
|