Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(28)

Unified Diff: chrome/browser/download/download_history_unittest.cc

Issue 10915180: Make DownloadHistory observe manager, items (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: @r168573 Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/download/download_history.cc ('k') | chrome/browser/download/download_service.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..319c0de3151d1f337716d79f410e7170f2def5d6
--- /dev/null
+++ b/chrome/browser/download/download_history_unittest.cc
@@ -0,0 +1,741 @@
+// 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 <set>
+#include <vector>
+
+#include "base/rand_util.h"
+#include "base/stl_util.h"
+#include "chrome/browser/download/download_history.h"
+#include "chrome/browser/history/download_database.h"
+#include "chrome/browser/history/download_row.h"
+#include "chrome/browser/history/history.h"
+#include "content/public/test/mock_download_item.h"
+#include "content/public/test/mock_download_manager.h"
+#include "content/public/test/test_browser_thread.h"
+#include "content/public/test/test_utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::DoAll;
+using testing::Invoke;
+using testing::Return;
+using testing::ReturnRef;
+using testing::SetArgPointee;
+using testing::WithArg;
+using testing::_;
+
+namespace {
+
+void CheckInfoEqual(const history::DownloadRow& left,
+ const history::DownloadRow& right) {
+ EXPECT_EQ(left.path.value(), right.path.value());
+ EXPECT_EQ(left.url.spec(), right.url.spec());
+ EXPECT_EQ(left.referrer_url.spec(), right.referrer_url.spec());
+ EXPECT_EQ(left.start_time.ToTimeT(), right.start_time.ToTimeT());
+ EXPECT_EQ(left.end_time.ToTimeT(), right.end_time.ToTimeT());
+ EXPECT_EQ(left.received_bytes, right.received_bytes);
+ EXPECT_EQ(left.total_bytes, right.total_bytes);
+ EXPECT_EQ(left.state, right.state);
+ EXPECT_EQ(left.db_handle, right.db_handle);
+ EXPECT_EQ(left.opened, right.opened);
+}
+
+typedef std::set<int64> HandleSet;
+typedef std::vector<history::DownloadRow> InfoVector;
+typedef testing::NiceMock<content::MockDownloadItem> NiceMockDownloadItem;
+
+class FakeHistoryAdapter : public DownloadHistory::HistoryAdapter {
+ public:
+ FakeHistoryAdapter()
+ : DownloadHistory::HistoryAdapter(NULL),
+ slow_create_download_(false),
+ fail_create_download_(false),
+ handle_counter_(0) {
+ }
+
+ virtual ~FakeHistoryAdapter() {}
+
+ virtual void QueryDownloads(
+ const HistoryService::DownloadQueryCallback& callback) OVERRIDE {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
+ base::Bind(&FakeHistoryAdapter::QueryDownloadsDone,
+ base::Unretained(this), callback));
+ }
+
+ void QueryDownloadsDone(
+ const HistoryService::DownloadQueryCallback& callback) {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ CHECK(expect_query_downloads_.get());
+ callback.Run(expect_query_downloads_.get());
+ expect_query_downloads_.reset();
+ }
+
+ void set_slow_create_download(bool slow) { slow_create_download_ = slow; }
+
+ virtual void CreateDownload(
+ const history::DownloadRow& info,
+ const HistoryService::DownloadCreateCallback& callback) OVERRIDE {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ create_download_info_ = info;
+ // Must not call CreateDownload() again before FinishCreateDownload()!
+ DCHECK(create_download_callback_.is_null());
+ create_download_callback_ = base::Bind(
+ callback,
+ (fail_create_download_ ?
+ history::DownloadDatabase::kUninitializedHandle :
+ handle_counter_++));
+ fail_create_download_ = false;
+ if (!slow_create_download_)
+ FinishCreateDownload();
+ }
+
+ void FinishCreateDownload() {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ create_download_callback_.Run();
+ create_download_callback_.Reset();
+ }
+
+ virtual void UpdateDownload(
+ const history::DownloadRow& info) OVERRIDE {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ update_download_ = info;
+ }
+
+ virtual void RemoveDownloads(const HandleSet& handles) OVERRIDE {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ for (HandleSet::const_iterator it = handles.begin();
+ it != handles.end(); ++it) {
+ remove_downloads_.insert(*it);
+ }
+ }
+
+ void ExpectWillQueryDownloads(scoped_ptr<InfoVector> infos) {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ expect_query_downloads_ = infos.Pass();
+ }
+
+ void ExpectQueryDownloadsDone() {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ EXPECT_TRUE(NULL == expect_query_downloads_.get());
+ }
+
+ void FailCreateDownload() {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ fail_create_download_ = true;
+ }
+
+ void ExpectDownloadCreated(
+ const history::DownloadRow& info) {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
+ CheckInfoEqual(info, create_download_info_);
+ create_download_info_ = history::DownloadRow();
+ }
+
+ void ExpectNoDownloadCreated() {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
+ CheckInfoEqual(history::DownloadRow(), create_download_info_);
+ }
+
+ void ExpectDownloadUpdated(const history::DownloadRow& info) {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
+ CheckInfoEqual(update_download_, info);
+ update_download_ = history::DownloadRow();
+ }
+
+ void ExpectNoDownloadUpdated() {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
+ CheckInfoEqual(history::DownloadRow(), update_download_);
+ }
+
+ void ExpectNoDownloadsRemoved() {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
+ EXPECT_EQ(0, static_cast<int>(remove_downloads_.size()));
+ }
+
+ void ExpectDownloadsRemoved(const HandleSet& handles) {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
+ HandleSet differences;
+ std::insert_iterator<HandleSet> differences_iter(
+ differences, differences.begin());
+ std::set_difference(handles.begin(), handles.end(),
+ remove_downloads_.begin(),
+ remove_downloads_.end(),
+ differences_iter);
+ for (HandleSet::const_iterator different = differences.begin();
+ different != differences.end(); ++different) {
+ EXPECT_TRUE(false) << *different;
+ }
+ remove_downloads_.clear();
+ }
+
+ private:
+ bool slow_create_download_;
+ bool fail_create_download_;
+ base::Closure create_download_callback_;
+ int handle_counter_;
+ history::DownloadRow update_download_;
+ scoped_ptr<InfoVector> expect_query_downloads_;
+ HandleSet remove_downloads_;
+ history::DownloadRow create_download_info_;
+
+ DISALLOW_COPY_AND_ASSIGN(FakeHistoryAdapter);
+};
+
+class DownloadHistoryTest : public testing::Test {
+ public:
+ DownloadHistoryTest()
+ : ui_thread_(content::BrowserThread::UI, &loop_),
+ manager_(new content::MockDownloadManager()),
+ history_(NULL),
+ download_history_(NULL),
+ manager_observer_(NULL),
+ item_observer_(NULL),
+ download_created_index_(0) {
+ }
+ virtual ~DownloadHistoryTest() {
+ STLDeleteElements(&items_);
+ }
+
+ protected:
+ virtual void TearDown() OVERRIDE {
+ download_history_.reset();
+ }
+
+ content::MockDownloadManager& manager() { return *manager_.get(); }
+ content::MockDownloadItem& item(size_t index) { return *items_[index]; }
+
+ void SetManagerObserver(
+ content::DownloadManager::Observer* manager_observer) {
+ manager_observer_ = manager_observer;
+ }
+ content::DownloadManager::Observer* manager_observer() {
+ return manager_observer_;
+ }
+ void SetItemObserver(
+ content::DownloadItem::Observer* item_observer) {
+ item_observer_ = item_observer;
+ }
+ content::DownloadItem::Observer* item_observer() {
+ return item_observer_;
+ }
+
+ void ExpectWillQueryDownloads(scoped_ptr<InfoVector> infos) {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ CHECK(infos.get());
+ EXPECT_CALL(manager(), AddObserver(_)).WillOnce(WithArg<0>(Invoke(
+ this, &DownloadHistoryTest::SetManagerObserver)));
+ EXPECT_CALL(manager(), RemoveObserver(_));
+ download_created_index_ = 0;
+ for (size_t index = 0; index < infos->size(); ++index) {
+ EXPECT_CALL(manager(), CreateDownloadItem(
+ infos->at(index).path,
+ infos->at(index).url,
+ infos->at(index).referrer_url,
+ infos->at(index).start_time,
+ infos->at(index).end_time,
+ infos->at(index).received_bytes,
+ infos->at(index).total_bytes,
+ infos->at(index).state,
+ infos->at(index).opened))
+ .WillOnce(DoAll(
+ InvokeWithoutArgs(
+ this, &DownloadHistoryTest::CallOnDownloadCreatedInOrder),
+ Return(&item(index))));
+ }
+ EXPECT_CALL(manager(), CheckForHistoryFilesRemoval());
+ history_ = new FakeHistoryAdapter();
+ history_->ExpectWillQueryDownloads(infos.Pass());
+ EXPECT_CALL(*manager_.get(), GetAllDownloads(_)).WillRepeatedly(Return());
+ download_history_.reset(new DownloadHistory(
+ &manager(), scoped_ptr<DownloadHistory::HistoryAdapter>(history_)));
+ content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
+ history_->ExpectQueryDownloadsDone();
+ }
+
+ void CallOnDownloadCreated(size_t index) {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ manager_observer()->OnDownloadCreated(&manager(), &item(index));
+ }
+
+ void CallOnDownloadCreatedInOrder() {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ // Gmock doesn't appear to support something like InvokeWithTheseArgs. Maybe
+ // gmock needs to learn about base::Callback.
+ CallOnDownloadCreated(download_created_index_++);
+ }
+
+ void set_slow_create_download(bool slow) {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ history_->set_slow_create_download(slow);
+ }
+
+ void FinishCreateDownload() {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ history_->FinishCreateDownload();
+ }
+
+ void FailCreateDownload() {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ history_->FailCreateDownload();
+ }
+
+ void ExpectDownloadCreated(
+ const history::DownloadRow& info) {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ history_->ExpectDownloadCreated(info);
+ }
+
+ void ExpectNoDownloadCreated() {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ history_->ExpectNoDownloadCreated();
+ }
+
+ void ExpectDownloadUpdated(const history::DownloadRow& info) {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ history_->ExpectDownloadUpdated(info);
+ }
+
+ void ExpectNoDownloadUpdated() {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ history_->ExpectNoDownloadUpdated();
+ }
+
+ void ExpectNoDownloadsRemoved() {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ history_->ExpectNoDownloadsRemoved();
+ }
+
+ void ExpectDownloadsRemoved(const HandleSet& handles) {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ history_->ExpectDownloadsRemoved(handles);
+ }
+
+ 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,
+ content::DownloadItem::DownloadState state,
+ int64 db_handle,
+ bool opened,
+ history::DownloadRow* info) {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ int32 index = items_.size();
+ NiceMockDownloadItem* mock_item = new NiceMockDownloadItem();
+ items_.push_back(mock_item);
+
+ 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(index), GetId()).WillRepeatedly(Return(id));
+ EXPECT_CALL(item(index), GetFullPath()).WillRepeatedly(ReturnRef(path));
Randy Smith (Not in Mondays) 2012/12/04 21:48:32 Apologies for not catching this on the first time
Randy Smith (Not in Mondays) 2012/12/05 13:00:30 Whoops, I see; the argument to the function is a r
+ EXPECT_CALL(item(index), GetURL()).WillRepeatedly(ReturnRef(url));
+ EXPECT_CALL(item(index), GetMimeType()).WillRepeatedly(Return(
+ "application/octet-stream"));
+ EXPECT_CALL(item(index), GetReferrerUrl()).WillRepeatedly(ReturnRef(
+ referrer));
+ EXPECT_CALL(item(index), GetStartTime()).WillRepeatedly(Return(start_time));
+ EXPECT_CALL(item(index), GetEndTime()).WillRepeatedly(Return(end_time));
+ EXPECT_CALL(item(index), GetReceivedBytes())
+ .WillRepeatedly(Return(received_bytes));
+ EXPECT_CALL(item(index), GetTotalBytes()).WillRepeatedly(Return(
+ total_bytes));
+ EXPECT_CALL(item(index), GetState()).WillRepeatedly(Return(state));
+ EXPECT_CALL(item(index), GetOpened()).WillRepeatedly(Return(opened));
+ EXPECT_CALL(item(index), GetTargetDisposition()).WillRepeatedly(Return(
+ content::DownloadItem::TARGET_DISPOSITION_OVERWRITE));
+ EXPECT_CALL(manager(), GetDownload(id))
+ .WillRepeatedly(Return(&item(index)));
+ EXPECT_CALL(item(index), AddObserver(_)).WillOnce(WithArg<0>(Invoke(
+ this, &DownloadHistoryTest::SetItemObserver)));
+ EXPECT_CALL(item(index), RemoveObserver(_));
+
+ std::vector<content::DownloadItem*> items;
+ for (size_t i = 0; i < items_.size(); ++i) {
+ items.push_back(&item(i));
+ }
+ EXPECT_CALL(*manager_.get(), GetAllDownloads(_))
+ .WillRepeatedly(SetArgPointee<0>(items));
+ }
+
+ private:
+ MessageLoopForUI loop_;
+ content::TestBrowserThread ui_thread_;
+ std::vector<NiceMockDownloadItem*> items_;
+ scoped_refptr<content::MockDownloadManager> manager_;
+ FakeHistoryAdapter* history_;
+ scoped_ptr<DownloadHistory> download_history_;
+ content::DownloadManager::Observer* manager_observer_;
+ content::DownloadItem::Observer* item_observer_;
+ size_t download_created_index_;
+
+ DISALLOW_COPY_AND_ASSIGN(DownloadHistoryTest);
+};
+
+} // anonymous namespace
+
+// Test loading an item from the database, changing it, saving it back, removing
+// it.
+TEST_F(DownloadHistoryTest, DownloadHistoryTest_Load) {
+ // Load a download from history, create the item, OnDownloadCreated,
+ // OnDownloadUpdated, OnDownloadRemoved.
+ history::DownloadRow info;
+ FilePath path(FILE_PATH_LITERAL("/foo/bar.pdf"));
+ GURL url("http://example.com/bar.pdf");
+ GURL referrer("http://example.com/referrer.html");
+ InitItem(base::RandInt(0, 1 << 20),
+ path,
+ url,
+ referrer,
+ (base::Time::Now() - base::TimeDelta::FromMinutes(10)),
+ (base::Time::Now() - base::TimeDelta::FromMinutes(1)),
+ 100,
+ 100,
+ content::DownloadItem::COMPLETE,
+ base::RandInt(0, 1 << 20),
+ false,
+ &info);
+ {
+ scoped_ptr<InfoVector> infos(new InfoVector());
+ infos->push_back(info);
+ ExpectWillQueryDownloads(infos.Pass());
+ ExpectNoDownloadCreated();
+ }
+ EXPECT_TRUE(DownloadHistory::IsPersisted(&item(0)));
+
+ // Pretend that something changed on the item.
+ EXPECT_CALL(item(0), GetOpened()).WillRepeatedly(Return(true));
+ item_observer()->OnDownloadUpdated(&item(0));
+ info.opened = true;
+ ExpectDownloadUpdated(info);
+
+ // Pretend that the user removed the item.
+ HandleSet handles;
+ handles.insert(info.db_handle);
+ item_observer()->OnDownloadRemoved(&item(0));
+ ExpectDownloadsRemoved(handles);
+}
+
+// Test creating an item, saving it to the database, changing it, saving it
+// back, removing it.
+TEST_F(DownloadHistoryTest, DownloadHistoryTest_Create) {
+ // Create a fresh item not from history, OnDownloadCreated, OnDownloadUpdated,
+ // OnDownloadRemoved.
+ ExpectWillQueryDownloads(scoped_ptr<InfoVector>(new InfoVector()));
+
+ // Note that db_handle must be -1 at first because it isn't in the db yet.
+ history::DownloadRow info;
+ FilePath path(FILE_PATH_LITERAL("/foo/bar.pdf"));
+ GURL url("http://example.com/bar.pdf");
+ GURL referrer("http://example.com/referrer.html");
+ InitItem(base::RandInt(0, 1 << 20),
+ path,
+ url,
+ referrer,
+ (base::Time::Now() - base::TimeDelta::FromMinutes(10)),
+ (base::Time::Now() - base::TimeDelta::FromMinutes(1)),
+ 100,
+ 100,
+ content::DownloadItem::COMPLETE,
+ -1,
+ false,
+ &info);
+
+ // Pretend the manager just created |item|.
+ CallOnDownloadCreated(0);
+ // CreateDownload() always gets db_handle=-1.
+ ExpectDownloadCreated(info);
+ info.db_handle = 0;
+ EXPECT_TRUE(DownloadHistory::IsPersisted(&item(0)));
+
+ // Pretend that something changed on the item.
+ EXPECT_CALL(item(0), GetOpened()).WillRepeatedly(Return(true));
+ item_observer()->OnDownloadUpdated(&item(0));
+ info.opened = true;
+ ExpectDownloadUpdated(info);
+
+ // Pretend that the user removed the item.
+ HandleSet handles;
+ handles.insert(info.db_handle);
+ item_observer()->OnDownloadRemoved(&item(0));
+ ExpectDownloadsRemoved(handles);
+}
+
+// Test creating a new item, saving it, removing it by setting it Temporary,
+// changing it without saving it back because it's Temporary, clearing
+// IsTemporary, saving it back, changing it, saving it back because it isn't
+// Temporary anymore.
+TEST_F(DownloadHistoryTest, DownloadHistoryTest_Temporary) {
+ // Create a fresh item not from history, OnDownloadCreated, OnDownloadUpdated,
+ // OnDownloadRemoved.
+ ExpectWillQueryDownloads(scoped_ptr<InfoVector>(new InfoVector()));
+
+ // Note that db_handle must be -1 at first because it isn't in the db yet.
+ history::DownloadRow info;
+ FilePath path(FILE_PATH_LITERAL("/foo/bar.pdf"));
+ GURL url("http://example.com/bar.pdf");
+ GURL referrer("http://example.com/referrer.html");
+ InitItem(base::RandInt(0, 1 << 20),
+ path,
+ url,
+ referrer,
+ (base::Time::Now() - base::TimeDelta::FromMinutes(10)),
+ (base::Time::Now() - base::TimeDelta::FromMinutes(1)),
+ 100,
+ 100,
+ content::DownloadItem::COMPLETE,
+ -1,
+ false,
+ &info);
+
+ // Pretend the manager just created |item|.
+ CallOnDownloadCreated(0);
+ // CreateDownload() always gets db_handle=-1.
+ ExpectDownloadCreated(info);
+ info.db_handle = 0;
+ EXPECT_TRUE(DownloadHistory::IsPersisted(&item(0)));
+
+ // Pretend the item was marked temporary. DownloadHistory should remove it
+ // from history and start ignoring it.
+ EXPECT_CALL(item(0), IsTemporary()).WillRepeatedly(Return(true));
+ item_observer()->OnDownloadUpdated(&item(0));
+ HandleSet handles;
+ handles.insert(info.db_handle);
+ ExpectDownloadsRemoved(handles);
+
+ // Change something that would make DownloadHistory call UpdateDownload if the
+ // item weren't temporary.
+ EXPECT_CALL(item(0), GetReceivedBytes()).WillRepeatedly(Return(4200));
+ item_observer()->OnDownloadUpdated(&item(0));
+ ExpectNoDownloadUpdated();
+
+ // Changing a temporary item back to a non-temporary item should make
+ // DownloadHistory call CreateDownload.
+ EXPECT_CALL(item(0), IsTemporary()).WillRepeatedly(Return(false));
+ item_observer()->OnDownloadUpdated(&item(0));
+ info.received_bytes = 4200;
+ info.db_handle = -1;
+ // CreateDownload() always gets db_handle=-1.
+ ExpectDownloadCreated(info);
+ info.db_handle = 1;
+ EXPECT_TRUE(DownloadHistory::IsPersisted(&item(0)));
+
+ EXPECT_CALL(item(0), GetReceivedBytes()).WillRepeatedly(Return(100));
+ item_observer()->OnDownloadUpdated(&item(0));
+ info.received_bytes = 100;
+ ExpectDownloadUpdated(info);
+}
+
+// Test removing downloads while they're still being added.
+TEST_F(DownloadHistoryTest,
+ DownloadHistoryTest_RemoveWhileAdding) {
+ ExpectWillQueryDownloads(scoped_ptr<InfoVector>(new InfoVector()));
+
+ // Note that db_handle must be -1 at first because it isn't in the db yet.
+ history::DownloadRow info;
+ FilePath path(FILE_PATH_LITERAL("/foo/bar.pdf"));
+ GURL url("http://example.com/bar.pdf");
+ GURL referrer("http://example.com/referrer.html");
+ InitItem(base::RandInt(0, 1 << 20),
+ path,
+ url,
+ referrer,
+ (base::Time::Now() - base::TimeDelta::FromMinutes(10)),
+ (base::Time::Now() - base::TimeDelta::FromMinutes(1)),
+ 100,
+ 100,
+ content::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|.
+ CallOnDownloadCreated(0);
+ // CreateDownload() always gets db_handle=-1.
+ ExpectDownloadCreated(info);
+ info.db_handle = 0;
+ EXPECT_FALSE(DownloadHistory::IsPersisted(&item(0)));
+
+ // Call OnDownloadRemoved before calling back to DownloadHistory::ItemAdded().
+ // Instead of calling RemoveDownloads() immediately, DownloadHistory should
+ // add the item's id to removed_while_adding_. Then, ItemAdded should
+ // immediately remove the item's record from history.
+ item_observer()->OnDownloadRemoved(&item(0));
+ EXPECT_CALL(manager(), GetDownload(item(0).GetId()))
+ .WillRepeatedly(Return(static_cast<content::DownloadItem*>(NULL)));
+ ExpectNoDownloadsRemoved();
+ EXPECT_FALSE(DownloadHistory::IsPersisted(&item(0)));
+
+ // 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);
+ ExpectDownloadsRemoved(handles);
+ EXPECT_FALSE(DownloadHistory::IsPersisted(&item(0)));
+}
+
+// Test loading multiple items from the database and removing them all.
+TEST_F(DownloadHistoryTest, DownloadHistoryTest_Multiple) {
+ // Load a download from history, create the item, OnDownloadCreated,
+ // OnDownloadUpdated, OnDownloadRemoved.
+ history::DownloadRow info0, info1;
+ FilePath path0(FILE_PATH_LITERAL("/foo/bar.pdf"));
+ GURL url0("http://example.com/bar.pdf");
+ GURL referrer0("http://example.com/referrer.html");
+ InitItem(base::RandInt(0, 1 << 10),
+ path0,
+ url0,
+ referrer0,
+ (base::Time::Now() - base::TimeDelta::FromMinutes(11)),
+ (base::Time::Now() - base::TimeDelta::FromMinutes(2)),
+ 100,
+ 100,
+ content::DownloadItem::COMPLETE,
+ base::RandInt(0, 1 << 10),
+ false,
+ &info0);
+ FilePath path1(FILE_PATH_LITERAL("/foo/qux.pdf"));
+ GURL url1("http://example.com/qux.pdf");
+ GURL referrer1("http://example.com/referrer.html");
+ InitItem(item(0).GetId() + base::RandInt(1, 1 << 10),
+ path1,
+ url1,
+ referrer1,
+ (base::Time::Now() - base::TimeDelta::FromMinutes(10)),
+ (base::Time::Now() - base::TimeDelta::FromMinutes(1)),
+ 200,
+ 200,
+ content::DownloadItem::COMPLETE,
+ info0.db_handle + base::RandInt(1, 1 << 10),
+ false,
+ &info1);
+ {
+ scoped_ptr<InfoVector> infos(new InfoVector());
+ infos->push_back(info0);
+ infos->push_back(info1);
+ ExpectWillQueryDownloads(infos.Pass());
+ ExpectNoDownloadCreated();
+ }
+
+ EXPECT_TRUE(DownloadHistory::IsPersisted(&item(0)));
+ EXPECT_TRUE(DownloadHistory::IsPersisted(&item(1)));
+
+ // Pretend that the user removed both items.
+ HandleSet handles;
+ handles.insert(info0.db_handle);
+ handles.insert(info1.db_handle);
+ item_observer()->OnDownloadRemoved(&item(0));
+ item_observer()->OnDownloadRemoved(&item(1));
+ ExpectDownloadsRemoved(handles);
+}
+
+// Test what happens when HistoryService/CreateDownload::CreateDownload() fails.
+TEST_F(DownloadHistoryTest, DownloadHistoryTest_CreateFailed) {
+ // Create a fresh item not from history, OnDownloadCreated, OnDownloadUpdated,
+ // OnDownloadRemoved.
+ ExpectWillQueryDownloads(scoped_ptr<InfoVector>(new InfoVector()));
+
+ // Note that db_handle must be -1 at first because it isn't in the db yet.
+ history::DownloadRow info;
+ FilePath path(FILE_PATH_LITERAL("/foo/bar.pdf"));
+ GURL url("http://example.com/bar.pdf");
+ GURL referrer("http://example.com/referrer.html");
+ InitItem(base::RandInt(0, 1 << 20),
+ path,
+ url,
+ referrer,
+ (base::Time::Now() - base::TimeDelta::FromMinutes(10)),
+ (base::Time::Now() - base::TimeDelta::FromMinutes(1)),
+ 100,
+ 100,
+ content::DownloadItem::COMPLETE,
+ -1,
+ false,
+ &info);
+
+ FailCreateDownload();
+ // Pretend the manager just created |item|.
+ CallOnDownloadCreated(0);
+ // CreateDownload() always gets db_handle=-1.
+ ExpectDownloadCreated(info);
+ EXPECT_FALSE(DownloadHistory::IsPersisted(&item(0)));
+
+ EXPECT_CALL(item(0), GetReceivedBytes()).WillRepeatedly(Return(100));
+ item_observer()->OnDownloadUpdated(&item(0));
+ info.received_bytes = 100;
+ ExpectDownloadCreated(info);
+ EXPECT_TRUE(DownloadHistory::IsPersisted(&item(0)));
+}
+
+TEST_F(DownloadHistoryTest,
+ DownloadHistoryTest_UpdateWhileAdding) {
+ // Create a fresh item not from history, OnDownloadCreated, OnDownloadUpdated,
+ // OnDownloadRemoved.
+ ExpectWillQueryDownloads(scoped_ptr<InfoVector>(new InfoVector()));
+
+ // Note that db_handle must be -1 at first because it isn't in the db yet.
+ history::DownloadRow info;
+ FilePath path(FILE_PATH_LITERAL("/foo/bar.pdf"));
+ GURL url("http://example.com/bar.pdf");
+ GURL referrer("http://example.com/referrer.html");
+ InitItem(base::RandInt(0, 1 << 20),
+ path,
+ url,
+ referrer,
+ (base::Time::Now() - base::TimeDelta::FromMinutes(10)),
+ (base::Time::Now() - base::TimeDelta::FromMinutes(1)),
+ 100,
+ 100,
+ content::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|.
+ CallOnDownloadCreated(0);
+ // CreateDownload() always gets db_handle=-1.
+ ExpectDownloadCreated(info);
+ info.db_handle = 0;
+ EXPECT_FALSE(DownloadHistory::IsPersisted(&item(0)));
+
+ // Pretend that something changed on the item.
+ EXPECT_CALL(item(0), GetOpened()).WillRepeatedly(Return(true));
+ item_observer()->OnDownloadUpdated(&item(0));
+
+ FinishCreateDownload();
+ EXPECT_TRUE(DownloadHistory::IsPersisted(&item(0)));
+
+ // ItemAdded should call OnDownloadUpdated, which should detect that the item
+ // changed while it was being added and call UpdateDownload immediately.
+ info.opened = true;
+ ExpectDownloadUpdated(info);
+}
« no previous file with comments | « chrome/browser/download/download_history.cc ('k') | chrome/browser/download/download_service.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698