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. |