This source file includes following definitions.
- ResumeInterruptedDownload
- VerifyAndClearExpectations
- SetDefaultExpectations
- ACTION_P2
- resume_count_
- OnDownloadRemoved
- OnDownloadUpdated
- OnDownloadOpened
- OnDownloadDestroyed
- CheckRemoved
- CheckDestroyed
- CheckUpdated
- GetInterruptCount
- GetResumeCount
- delegate_
- SetUp
- TearDown
- CreateDownloadItem
- AddDownloadFileToDownloadItem
- DoIntermediateRename
- CleanupItem
- DestroyDownloadItem
- RunAllPendingInMessageLoops
- mock_delegate
- OnDownloadFileAcquired
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST
#include "base/callback.h"
#include "base/command_line.h"
#include "base/message_loop/message_loop.h"
#include "base/stl_util.h"
#include "base/threading/thread.h"
#include "content/browser/byte_stream.h"
#include "content/browser/download/download_create_info.h"
#include "content/browser/download/download_file_factory.h"
#include "content/browser/download/download_item_impl.h"
#include "content/browser/download/download_item_impl_delegate.h"
#include "content/browser/download/download_request_handle.h"
#include "content/browser/download/mock_download_file.h"
#include "content/public/browser/download_destination_observer.h"
#include "content/public/browser/download_interrupt_reasons.h"
#include "content/public/browser/download_url_parameters.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/mock_download_item.h"
#include "content/public/test/test_browser_thread.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using ::testing::_;
using ::testing::NiceMock;
using ::testing::Property;
using ::testing::Return;
using ::testing::SaveArg;
using ::testing::StrictMock;
const int kDownloadChunkSize = 1000;
const int kDownloadSpeed = 1000;
const base::FilePath::CharType kDummyPath[] = FILE_PATH_LITERAL("/testpath");
namespace content {
namespace {
class MockDelegate : public DownloadItemImplDelegate {
public:
MockDelegate() : DownloadItemImplDelegate() {
SetDefaultExpectations();
}
MOCK_METHOD2(DetermineDownloadTarget, void(
DownloadItemImpl*, const DownloadTargetCallback&));
MOCK_METHOD2(ShouldCompleteDownload,
bool(DownloadItemImpl*, const base::Closure&));
MOCK_METHOD2(ShouldOpenDownload,
bool(DownloadItemImpl*, const ShouldOpenDownloadCallback&));
MOCK_METHOD1(ShouldOpenFileBasedOnExtension, bool(const base::FilePath&));
MOCK_METHOD1(CheckForFileRemoval, void(DownloadItemImpl*));
virtual void ResumeInterruptedDownload(
scoped_ptr<DownloadUrlParameters> params, uint32 id) OVERRIDE {
MockResumeInterruptedDownload(params.get(), id);
}
MOCK_METHOD2(MockResumeInterruptedDownload,
void(DownloadUrlParameters* params, uint32 id));
MOCK_CONST_METHOD0(GetBrowserContext, BrowserContext*());
MOCK_METHOD1(UpdatePersistence, void(DownloadItemImpl*));
MOCK_METHOD1(DownloadOpened, void(DownloadItemImpl*));
MOCK_METHOD1(DownloadRemoved, void(DownloadItemImpl*));
MOCK_CONST_METHOD1(AssertStateConsistent, void(DownloadItemImpl*));
void VerifyAndClearExpectations() {
::testing::Mock::VerifyAndClearExpectations(this);
SetDefaultExpectations();
}
private:
void SetDefaultExpectations() {
EXPECT_CALL(*this, AssertStateConsistent(_))
.WillRepeatedly(Return());
EXPECT_CALL(*this, ShouldOpenFileBasedOnExtension(_))
.WillRepeatedly(Return(false));
EXPECT_CALL(*this, ShouldOpenDownload(_, _))
.WillRepeatedly(Return(true));
}
};
class MockRequestHandle : public DownloadRequestHandleInterface {
public:
MOCK_CONST_METHOD0(GetWebContents, WebContents*());
MOCK_CONST_METHOD0(GetDownloadManager, DownloadManager*());
MOCK_CONST_METHOD0(PauseRequest, void());
MOCK_CONST_METHOD0(ResumeRequest, void());
MOCK_CONST_METHOD0(CancelRequest, void());
MOCK_CONST_METHOD0(DebugString, std::string());
};
ACTION_P2(ScheduleRenameCallback, interrupt_reason, new_path) {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(arg1, interrupt_reason, new_path));
}
}
class DownloadItemTest : public testing::Test {
public:
class MockObserver : public DownloadItem::Observer {
public:
explicit MockObserver(DownloadItem* item)
: item_(item),
last_state_(item->GetState()),
removed_(false),
destroyed_(false),
updated_(false),
interrupt_count_(0),
resume_count_(0) {
item_->AddObserver(this);
}
virtual ~MockObserver() {
if (item_) item_->RemoveObserver(this);
}
virtual void OnDownloadRemoved(DownloadItem* download) OVERRIDE {
DVLOG(20) << " " << __FUNCTION__
<< " download = " << download->DebugString(false);
removed_ = true;
}
virtual void OnDownloadUpdated(DownloadItem* download) OVERRIDE {
DVLOG(20) << " " << __FUNCTION__
<< " download = " << download->DebugString(false);
updated_ = true;
DownloadItem::DownloadState new_state = download->GetState();
if (last_state_ == DownloadItem::IN_PROGRESS &&
new_state == DownloadItem::INTERRUPTED) {
interrupt_count_++;
}
if (last_state_ == DownloadItem::INTERRUPTED &&
new_state == DownloadItem::IN_PROGRESS) {
resume_count_++;
}
last_state_ = new_state;
}
virtual void OnDownloadOpened(DownloadItem* download) OVERRIDE {
DVLOG(20) << " " << __FUNCTION__
<< " download = " << download->DebugString(false);
}
virtual void OnDownloadDestroyed(DownloadItem* download) OVERRIDE {
DVLOG(20) << " " << __FUNCTION__
<< " download = " << download->DebugString(false);
destroyed_ = true;
item_->RemoveObserver(this);
item_ = NULL;
}
bool CheckRemoved() {
return removed_;
}
bool CheckDestroyed() {
return destroyed_;
}
bool CheckUpdated() {
bool was_updated = updated_;
updated_ = false;
return was_updated;
}
int GetInterruptCount() {
return interrupt_count_;
}
int GetResumeCount() {
return resume_count_;
}
private:
DownloadItem* item_;
DownloadItem::DownloadState last_state_;
bool removed_;
bool destroyed_;
bool updated_;
int interrupt_count_;
int resume_count_;
};
DownloadItemTest()
: ui_thread_(BrowserThread::UI, &loop_),
file_thread_(BrowserThread::FILE, &loop_),
delegate_() {
}
~DownloadItemTest() {
}
virtual void SetUp() {
}
virtual void TearDown() {
ui_thread_.DeprecatedGetThreadObject()->message_loop()->RunUntilIdle();
STLDeleteElements(&allocated_downloads_);
allocated_downloads_.clear();
}
DownloadItemImpl* CreateDownloadItem() {
scoped_ptr<DownloadCreateInfo> info_;
info_.reset(new DownloadCreateInfo());
static uint32 next_id = DownloadItem::kInvalidId + 1;
info_->save_info = scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo());
info_->save_info->prompt_for_save_location = false;
info_->url_chain.push_back(GURL());
info_->etag = "SomethingToSatisfyResumption";
DownloadItemImpl* download =
new DownloadItemImpl(
&delegate_, next_id++, *(info_.get()), net::BoundNetLog());
allocated_downloads_.insert(download);
return download;
}
MockDownloadFile* AddDownloadFileToDownloadItem(
DownloadItemImpl* item,
DownloadItemImplDelegate::DownloadTargetCallback *callback) {
MockDownloadFile* mock_download_file(new StrictMock<MockDownloadFile>);
scoped_ptr<DownloadFile> download_file(mock_download_file);
EXPECT_CALL(*mock_download_file, Initialize(_));
if (callback) {
EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _))
.WillOnce(SaveArg<1>(callback));
} else {
EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _));
}
scoped_ptr<DownloadRequestHandleInterface> request_handle(
new NiceMock<MockRequestHandle>);
item->Start(download_file.Pass(), request_handle.Pass());
loop_.RunUntilIdle();
mock_delegate()->VerifyAndClearExpectations();
EXPECT_CALL(*mock_delegate(), AssertStateConsistent(_))
.WillRepeatedly(Return());
EXPECT_CALL(*mock_delegate(), ShouldOpenFileBasedOnExtension(_))
.WillRepeatedly(Return(false));
EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(_, _))
.WillRepeatedly(Return(true));
return mock_download_file;
}
MockDownloadFile* DoIntermediateRename(DownloadItemImpl* item,
DownloadDangerType danger_type) {
EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
EXPECT_TRUE(item->GetTargetFilePath().empty());
DownloadItemImplDelegate::DownloadTargetCallback callback;
MockDownloadFile* download_file =
AddDownloadFileToDownloadItem(item, &callback);
base::FilePath target_path(kDummyPath);
base::FilePath intermediate_path(
target_path.InsertBeforeExtensionASCII("x"));
EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
.WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
intermediate_path));
callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
danger_type, intermediate_path);
RunAllPendingInMessageLoops();
return download_file;
}
void CleanupItem(DownloadItemImpl* item,
MockDownloadFile* download_file,
DownloadItem::DownloadState expected_state) {
EXPECT_EQ(expected_state, item->GetState());
if (expected_state == DownloadItem::IN_PROGRESS) {
EXPECT_CALL(*download_file, Cancel());
item->Cancel(true);
loop_.RunUntilIdle();
}
}
void DestroyDownloadItem(DownloadItem* item) {
allocated_downloads_.erase(item);
delete item;
}
void RunAllPendingInMessageLoops() {
loop_.RunUntilIdle();
}
MockDelegate* mock_delegate() {
return &delegate_;
}
void OnDownloadFileAcquired(base::FilePath* return_path,
const base::FilePath& path) {
*return_path = path;
}
private:
base::MessageLoopForUI loop_;
TestBrowserThread ui_thread_;
TestBrowserThread file_thread_;
StrictMock<MockDelegate> delegate_;
std::set<DownloadItem*> allocated_downloads_;
};
TEST_F(DownloadItemTest, NotificationAfterUpdate) {
DownloadItemImpl* item = CreateDownloadItem();
MockObserver observer(item);
item->DestinationUpdate(kDownloadChunkSize, kDownloadSpeed, std::string());
ASSERT_TRUE(observer.CheckUpdated());
EXPECT_EQ(kDownloadSpeed, item->CurrentSpeed());
}
TEST_F(DownloadItemTest, NotificationAfterCancel) {
DownloadItemImpl* user_cancel = CreateDownloadItem();
MockDownloadFile* download_file =
AddDownloadFileToDownloadItem(user_cancel, NULL);
EXPECT_CALL(*download_file, Cancel());
MockObserver observer1(user_cancel);
user_cancel->Cancel(true);
ASSERT_TRUE(observer1.CheckUpdated());
DownloadItemImpl* system_cancel = CreateDownloadItem();
download_file = AddDownloadFileToDownloadItem(system_cancel, NULL);
EXPECT_CALL(*download_file, Cancel());
MockObserver observer2(system_cancel);
system_cancel->Cancel(false);
ASSERT_TRUE(observer2.CheckUpdated());
}
TEST_F(DownloadItemTest, NotificationAfterComplete) {
DownloadItemImpl* item = CreateDownloadItem();
MockObserver observer(item);
item->OnAllDataSaved(DownloadItem::kEmptyFileHash);
ASSERT_TRUE(observer.CheckUpdated());
item->MarkAsComplete();
ASSERT_TRUE(observer.CheckUpdated());
}
TEST_F(DownloadItemTest, NotificationAfterDownloadedFileRemoved) {
DownloadItemImpl* item = CreateDownloadItem();
MockObserver observer(item);
item->OnDownloadedFileRemoved();
ASSERT_TRUE(observer.CheckUpdated());
}
TEST_F(DownloadItemTest, NotificationAfterInterrupted) {
DownloadItemImpl* item = CreateDownloadItem();
MockDownloadFile* download_file =
DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
EXPECT_CALL(*download_file, Cancel());
MockObserver observer(item);
EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_,_))
.Times(0);
item->DestinationObserverAsWeakPtr()->DestinationError(
DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
ASSERT_TRUE(observer.CheckUpdated());
}
TEST_F(DownloadItemTest, NotificationAfterDestroyed) {
DownloadItemImpl* item = CreateDownloadItem();
MockObserver observer(item);
DestroyDownloadItem(item);
ASSERT_TRUE(observer.CheckDestroyed());
}
TEST_F(DownloadItemTest, ContinueAfterInterrupted) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
DownloadItemImpl* item = CreateDownloadItem();
MockObserver observer(item);
DownloadItemImplDelegate::DownloadTargetCallback callback;
MockDownloadFile* download_file =
DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
EXPECT_CALL(*download_file, FullPath())
.WillOnce(Return(base::FilePath()));
EXPECT_CALL(*download_file, Detach());
item->DestinationObserverAsWeakPtr()->DestinationError(
DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR);
ASSERT_TRUE(observer.CheckUpdated());
ASSERT_EQ(1, observer.GetInterruptCount());
ASSERT_EQ(0, observer.GetResumeCount());
RunAllPendingInMessageLoops();
CleanupItem(item, download_file, DownloadItem::INTERRUPTED);
}
TEST_F(DownloadItemTest, RestartAfterInterrupted) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
DownloadItemImpl* item = CreateDownloadItem();
MockObserver observer(item);
DownloadItemImplDelegate::DownloadTargetCallback callback;
MockDownloadFile* download_file =
DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
EXPECT_CALL(*download_file, Cancel());
item->DestinationObserverAsWeakPtr()->DestinationError(
DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
ASSERT_TRUE(observer.CheckUpdated());
ASSERT_EQ(1, observer.GetInterruptCount());
ASSERT_EQ(0, observer.GetResumeCount());
RunAllPendingInMessageLoops();
CleanupItem(item, download_file, DownloadItem::INTERRUPTED);
}
TEST_F(DownloadItemTest, UnresumableInterrupt) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
DownloadItemImpl* item = CreateDownloadItem();
MockObserver observer(item);
DownloadItemImplDelegate::DownloadTargetCallback callback;
MockDownloadFile* download_file =
DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
.WillOnce(Return(true));
EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyPath), _))
.WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED,
base::FilePath(kDummyPath)));
EXPECT_CALL(*download_file, Cancel());
item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
RunAllPendingInMessageLoops();
ASSERT_TRUE(observer.CheckUpdated());
ASSERT_EQ(1, observer.GetInterruptCount());
ASSERT_EQ(0, observer.GetResumeCount());
CleanupItem(item, download_file, DownloadItem::INTERRUPTED);
}
TEST_F(DownloadItemTest, LimitRestartsAfterInterrupted) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
DownloadItemImpl* item = CreateDownloadItem();
base::WeakPtr<DownloadDestinationObserver> as_observer(
item->DestinationObserverAsWeakPtr());
MockObserver observer(item);
MockDownloadFile* mock_download_file(NULL);
scoped_ptr<DownloadFile> download_file;
MockRequestHandle* mock_request_handle(NULL);
scoped_ptr<DownloadRequestHandleInterface> request_handle;
DownloadItemImplDelegate::DownloadTargetCallback callback;
EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _))
.WillRepeatedly(SaveArg<1>(&callback));
for (int i = 0; i < (DownloadItemImpl::kMaxAutoResumeAttempts + 1); ++i) {
DVLOG(20) << "Loop iteration " << i;
mock_download_file = new NiceMock<MockDownloadFile>;
download_file.reset(mock_download_file);
mock_request_handle = new NiceMock<MockRequestHandle>;
request_handle.reset(mock_request_handle);
ON_CALL(*mock_download_file, FullPath())
.WillByDefault(Return(base::FilePath()));
if (i < (DownloadItemImpl::kMaxAutoResumeAttempts - 1)) {
EXPECT_CALL(*mock_request_handle, GetWebContents())
.WillRepeatedly(Return(static_cast<WebContents*>(NULL)));
}
item->Start(download_file.Pass(), request_handle.Pass());
RunAllPendingInMessageLoops();
if (i == 0) {
base::FilePath target_path(kDummyPath);
base::FilePath intermediate_path(
target_path.InsertBeforeExtensionASCII("x"));
EXPECT_CALL(*mock_download_file, RenameAndUniquify(intermediate_path, _))
.WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
intermediate_path));
callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
RunAllPendingInMessageLoops();
}
ASSERT_EQ(i, observer.GetResumeCount());
item->DestinationObserverAsWeakPtr()->DestinationError(
DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR);
ASSERT_EQ(i + 1, observer.GetInterruptCount());
::testing::Mock::VerifyAndClearExpectations(mock_download_file);
}
CleanupItem(item, mock_download_file, DownloadItem::INTERRUPTED);
}
TEST_F(DownloadItemTest, NotificationAfterRemove) {
DownloadItemImpl* item = CreateDownloadItem();
MockDownloadFile* download_file = AddDownloadFileToDownloadItem(item, NULL);
EXPECT_CALL(*download_file, Cancel());
EXPECT_CALL(*mock_delegate(), DownloadRemoved(_));
MockObserver observer(item);
item->Remove();
ASSERT_TRUE(observer.CheckUpdated());
ASSERT_TRUE(observer.CheckRemoved());
}
TEST_F(DownloadItemTest, NotificationAfterOnContentCheckCompleted) {
DownloadItemImpl* safe_item = CreateDownloadItem();
MockObserver safe_observer(safe_item);
safe_item->OnAllDataSaved(std::string());
EXPECT_TRUE(safe_observer.CheckUpdated());
safe_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
EXPECT_TRUE(safe_observer.CheckUpdated());
DownloadItemImpl* unsafeurl_item =
CreateDownloadItem();
MockObserver unsafeurl_observer(unsafeurl_item);
unsafeurl_item->OnAllDataSaved(std::string());
EXPECT_TRUE(unsafeurl_observer.CheckUpdated());
unsafeurl_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_DANGEROUS_URL);
EXPECT_TRUE(unsafeurl_observer.CheckUpdated());
unsafeurl_item->ValidateDangerousDownload();
EXPECT_TRUE(unsafeurl_observer.CheckUpdated());
DownloadItemImpl* unsafefile_item =
CreateDownloadItem();
MockObserver unsafefile_observer(unsafefile_item);
unsafefile_item->OnAllDataSaved(std::string());
EXPECT_TRUE(unsafefile_observer.CheckUpdated());
unsafefile_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE);
EXPECT_TRUE(unsafefile_observer.CheckUpdated());
unsafefile_item->ValidateDangerousDownload();
EXPECT_TRUE(unsafefile_observer.CheckUpdated());
}
TEST_F(DownloadItemTest, NotificationAfterOnDownloadTargetDetermined) {
DownloadItemImpl* item = CreateDownloadItem();
DownloadItemImplDelegate::DownloadTargetCallback callback;
MockDownloadFile* download_file =
AddDownloadFileToDownloadItem(item, &callback);
MockObserver observer(item);
base::FilePath target_path(kDummyPath);
base::FilePath intermediate_path(target_path.InsertBeforeExtensionASCII("x"));
base::FilePath new_intermediate_path(
target_path.InsertBeforeExtensionASCII("y"));
EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
.WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
new_intermediate_path));
callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
EXPECT_FALSE(observer.CheckUpdated());
RunAllPendingInMessageLoops();
EXPECT_TRUE(observer.CheckUpdated());
EXPECT_EQ(new_intermediate_path, item->GetFullPath());
CleanupItem(item, download_file, DownloadItem::IN_PROGRESS);
}
TEST_F(DownloadItemTest, NotificationAfterTogglePause) {
DownloadItemImpl* item = CreateDownloadItem();
MockObserver observer(item);
MockDownloadFile* mock_download_file(new MockDownloadFile);
scoped_ptr<DownloadFile> download_file(mock_download_file);
scoped_ptr<DownloadRequestHandleInterface> request_handle(
new NiceMock<MockRequestHandle>);
EXPECT_CALL(*mock_download_file, Initialize(_));
EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _));
item->Start(download_file.Pass(), request_handle.Pass());
item->Pause();
ASSERT_TRUE(observer.CheckUpdated());
ASSERT_TRUE(item->IsPaused());
item->Resume();
ASSERT_TRUE(observer.CheckUpdated());
RunAllPendingInMessageLoops();
CleanupItem(item, mock_download_file, DownloadItem::IN_PROGRESS);
}
TEST_F(DownloadItemTest, DisplayName) {
DownloadItemImpl* item = CreateDownloadItem();
DownloadItemImplDelegate::DownloadTargetCallback callback;
MockDownloadFile* download_file =
AddDownloadFileToDownloadItem(item, &callback);
base::FilePath target_path(base::FilePath(kDummyPath).AppendASCII("foo.bar"));
base::FilePath intermediate_path(target_path.InsertBeforeExtensionASCII("x"));
EXPECT_EQ(FILE_PATH_LITERAL(""),
item->GetFileNameToReportUser().value());
EXPECT_CALL(*download_file, RenameAndUniquify(_, _))
.WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
intermediate_path));
callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
RunAllPendingInMessageLoops();
EXPECT_EQ(FILE_PATH_LITERAL("foo.bar"),
item->GetFileNameToReportUser().value());
item->SetDisplayName(base::FilePath(FILE_PATH_LITERAL("new.name")));
EXPECT_EQ(FILE_PATH_LITERAL("new.name"),
item->GetFileNameToReportUser().value());
CleanupItem(item, download_file, DownloadItem::IN_PROGRESS);
}
TEST_F(DownloadItemTest, Start) {
MockDownloadFile* mock_download_file(new MockDownloadFile);
scoped_ptr<DownloadFile> download_file(mock_download_file);
DownloadItemImpl* item = CreateDownloadItem();
EXPECT_CALL(*mock_download_file, Initialize(_));
scoped_ptr<DownloadRequestHandleInterface> request_handle(
new NiceMock<MockRequestHandle>);
EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _));
item->Start(download_file.Pass(), request_handle.Pass());
RunAllPendingInMessageLoops();
CleanupItem(item, mock_download_file, DownloadItem::IN_PROGRESS);
}
TEST_F(DownloadItemTest, CallbackAfterRename) {
DownloadItemImpl* item = CreateDownloadItem();
DownloadItemImplDelegate::DownloadTargetCallback callback;
MockDownloadFile* download_file =
AddDownloadFileToDownloadItem(item, &callback);
base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar"));
base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x"));
base::FilePath new_intermediate_path(
final_path.InsertBeforeExtensionASCII("y"));
EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
.WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
new_intermediate_path));
callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
RunAllPendingInMessageLoops();
::testing::Mock::VerifyAndClearExpectations(download_file);
mock_delegate()->VerifyAndClearExpectations();
EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
.WillOnce(Return(true));
EXPECT_CALL(*download_file, RenameAndAnnotate(final_path, _))
.WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
final_path));
EXPECT_CALL(*download_file, FullPath())
.WillOnce(Return(base::FilePath()));
EXPECT_CALL(*download_file, Detach());
item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
RunAllPendingInMessageLoops();
::testing::Mock::VerifyAndClearExpectations(download_file);
mock_delegate()->VerifyAndClearExpectations();
}
TEST_F(DownloadItemTest, CallbackAfterInterruptedRename) {
DownloadItemImpl* item = CreateDownloadItem();
DownloadItemImplDelegate::DownloadTargetCallback callback;
MockDownloadFile* download_file =
AddDownloadFileToDownloadItem(item, &callback);
base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar"));
base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x"));
base::FilePath new_intermediate_path(
final_path.InsertBeforeExtensionASCII("y"));
EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
.WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED,
new_intermediate_path));
EXPECT_CALL(*download_file, Cancel())
.Times(1);
callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
RunAllPendingInMessageLoops();
::testing::Mock::VerifyAndClearExpectations(download_file);
mock_delegate()->VerifyAndClearExpectations();
}
TEST_F(DownloadItemTest, Interrupted) {
DownloadItemImpl* item = CreateDownloadItem();
MockDownloadFile* download_file =
DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
const DownloadInterruptReason reason(
DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED);
EXPECT_CALL(*download_file, Cancel());
item->DestinationObserverAsWeakPtr()->DestinationError(reason);
RunAllPendingInMessageLoops();
EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
EXPECT_EQ(reason, item->GetLastReason());
item->Cancel(true);
EXPECT_EQ(DownloadItem::CANCELLED, item->GetState());
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_USER_CANCELED, item->GetLastReason());
}
TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Restart) {
DownloadItemImpl* item = CreateDownloadItem();
DownloadItemImplDelegate::DownloadTargetCallback callback;
MockDownloadFile* download_file =
AddDownloadFileToDownloadItem(item, &callback);
item->DestinationObserverAsWeakPtr()->DestinationError(
DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar"));
base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x"));
base::FilePath new_intermediate_path(
final_path.InsertBeforeExtensionASCII("y"));
EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
.WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
new_intermediate_path));
EXPECT_CALL(*download_file, Cancel())
.Times(1);
callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
RunAllPendingInMessageLoops();
::testing::Mock::VerifyAndClearExpectations(download_file);
mock_delegate()->VerifyAndClearExpectations();
EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
EXPECT_TRUE(item->GetFullPath().empty());
EXPECT_EQ(final_path, item->GetTargetFilePath());
}
TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Continue) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
DownloadItemImpl* item = CreateDownloadItem();
DownloadItemImplDelegate::DownloadTargetCallback callback;
MockDownloadFile* download_file =
AddDownloadFileToDownloadItem(item, &callback);
item->DestinationObserverAsWeakPtr()->DestinationError(
DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED);
ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar"));
base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x"));
base::FilePath new_intermediate_path(
final_path.InsertBeforeExtensionASCII("y"));
EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
.WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
new_intermediate_path));
EXPECT_CALL(*download_file, FullPath())
.WillOnce(Return(base::FilePath(new_intermediate_path)));
EXPECT_CALL(*download_file, Detach());
callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
RunAllPendingInMessageLoops();
::testing::Mock::VerifyAndClearExpectations(download_file);
mock_delegate()->VerifyAndClearExpectations();
EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
EXPECT_EQ(new_intermediate_path, item->GetFullPath());
EXPECT_EQ(final_path, item->GetTargetFilePath());
}
TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Failed) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
DownloadItemImpl* item = CreateDownloadItem();
DownloadItemImplDelegate::DownloadTargetCallback callback;
MockDownloadFile* download_file =
AddDownloadFileToDownloadItem(item, &callback);
item->DestinationObserverAsWeakPtr()->DestinationError(
DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED);
ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar"));
base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x"));
base::FilePath new_intermediate_path(
final_path.InsertBeforeExtensionASCII("y"));
EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
.WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED,
new_intermediate_path));
EXPECT_CALL(*download_file, Cancel())
.Times(1);
callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
RunAllPendingInMessageLoops();
::testing::Mock::VerifyAndClearExpectations(download_file);
mock_delegate()->VerifyAndClearExpectations();
EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, item->GetLastReason());
EXPECT_TRUE(item->GetFullPath().empty());
EXPECT_EQ(final_path, item->GetTargetFilePath());
}
TEST_F(DownloadItemTest, Canceled) {
DownloadItemImpl* item = CreateDownloadItem();
MockDownloadFile* download_file = AddDownloadFileToDownloadItem(item, NULL);
EXPECT_CALL(*download_file, Cancel());
item->Cancel(true);
EXPECT_EQ(DownloadItem::CANCELLED, item->GetState());
}
TEST_F(DownloadItemTest, FileRemoved) {
DownloadItemImpl* item = CreateDownloadItem();
EXPECT_FALSE(item->GetFileExternallyRemoved());
item->OnDownloadedFileRemoved();
EXPECT_TRUE(item->GetFileExternallyRemoved());
}
TEST_F(DownloadItemTest, DestinationUpdate) {
DownloadItemImpl* item = CreateDownloadItem();
base::WeakPtr<DownloadDestinationObserver> as_observer(
item->DestinationObserverAsWeakPtr());
MockObserver observer(item);
EXPECT_EQ(0l, item->CurrentSpeed());
EXPECT_EQ("", item->GetHashState());
EXPECT_EQ(0l, item->GetReceivedBytes());
EXPECT_EQ(0l, item->GetTotalBytes());
EXPECT_FALSE(observer.CheckUpdated());
item->SetTotalBytes(100l);
EXPECT_EQ(100l, item->GetTotalBytes());
as_observer->DestinationUpdate(10, 20, "deadbeef");
EXPECT_EQ(20l, item->CurrentSpeed());
EXPECT_EQ("deadbeef", item->GetHashState());
EXPECT_EQ(10l, item->GetReceivedBytes());
EXPECT_EQ(100l, item->GetTotalBytes());
EXPECT_TRUE(observer.CheckUpdated());
as_observer->DestinationUpdate(200, 20, "livebeef");
EXPECT_EQ(20l, item->CurrentSpeed());
EXPECT_EQ("livebeef", item->GetHashState());
EXPECT_EQ(200l, item->GetReceivedBytes());
EXPECT_EQ(0l, item->GetTotalBytes());
EXPECT_TRUE(observer.CheckUpdated());
}
TEST_F(DownloadItemTest, DestinationError) {
DownloadItemImpl* item = CreateDownloadItem();
MockDownloadFile* download_file =
DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
base::WeakPtr<DownloadDestinationObserver> as_observer(
item->DestinationObserverAsWeakPtr());
MockObserver observer(item);
EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, item->GetLastReason());
EXPECT_FALSE(observer.CheckUpdated());
EXPECT_CALL(*download_file, Cancel());
as_observer->DestinationError(
DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED);
mock_delegate()->VerifyAndClearExpectations();
EXPECT_TRUE(observer.CheckUpdated());
EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED,
item->GetLastReason());
}
TEST_F(DownloadItemTest, DestinationCompleted) {
DownloadItemImpl* item = CreateDownloadItem();
base::WeakPtr<DownloadDestinationObserver> as_observer(
item->DestinationObserverAsWeakPtr());
MockObserver observer(item);
EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
EXPECT_EQ("", item->GetHash());
EXPECT_EQ("", item->GetHashState());
EXPECT_FALSE(item->AllDataSaved());
EXPECT_FALSE(observer.CheckUpdated());
as_observer->DestinationUpdate(10, 20, "deadbeef");
EXPECT_TRUE(observer.CheckUpdated());
EXPECT_FALSE(observer.CheckUpdated());
EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
EXPECT_EQ("", item->GetHash());
EXPECT_EQ("deadbeef", item->GetHashState());
EXPECT_FALSE(item->AllDataSaved());
as_observer->DestinationCompleted("livebeef");
mock_delegate()->VerifyAndClearExpectations();
EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
EXPECT_TRUE(observer.CheckUpdated());
EXPECT_EQ("livebeef", item->GetHash());
EXPECT_EQ("", item->GetHashState());
EXPECT_TRUE(item->AllDataSaved());
}
TEST_F(DownloadItemTest, EnabledActionsForNormalDownload) {
DownloadItemImpl* item = CreateDownloadItem();
MockDownloadFile* download_file =
DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
ASSERT_FALSE(item->GetTargetFilePath().empty());
EXPECT_TRUE(item->CanShowInFolder());
EXPECT_TRUE(item->CanOpenDownload());
EXPECT_CALL(*download_file, RenameAndAnnotate(_, _))
.WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
base::FilePath(kDummyPath)));
EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
.WillOnce(Return(true));
EXPECT_CALL(*download_file, FullPath())
.WillOnce(Return(base::FilePath()));
EXPECT_CALL(*download_file, Detach());
item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
RunAllPendingInMessageLoops();
ASSERT_EQ(DownloadItem::COMPLETE, item->GetState());
EXPECT_TRUE(item->CanShowInFolder());
EXPECT_TRUE(item->CanOpenDownload());
}
TEST_F(DownloadItemTest, EnabledActionsForTemporaryDownload) {
DownloadItemImpl* item = CreateDownloadItem();
MockDownloadFile* download_file =
DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
item->SetIsTemporary(true);
ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
ASSERT_FALSE(item->GetTargetFilePath().empty());
ASSERT_TRUE(item->IsTemporary());
EXPECT_FALSE(item->CanShowInFolder());
EXPECT_FALSE(item->CanOpenDownload());
EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
.WillOnce(Return(true));
EXPECT_CALL(*download_file, RenameAndAnnotate(_, _))
.WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
base::FilePath(kDummyPath)));
EXPECT_CALL(*download_file, FullPath())
.WillOnce(Return(base::FilePath()));
EXPECT_CALL(*download_file, Detach());
item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
RunAllPendingInMessageLoops();
ASSERT_EQ(DownloadItem::COMPLETE, item->GetState());
EXPECT_FALSE(item->CanShowInFolder());
EXPECT_FALSE(item->CanOpenDownload());
}
TEST_F(DownloadItemTest, EnabledActionsForInterruptedDownload) {
DownloadItemImpl* item = CreateDownloadItem();
MockDownloadFile* download_file =
DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
EXPECT_CALL(*download_file, Cancel());
item->DestinationObserverAsWeakPtr()->DestinationError(
DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
RunAllPendingInMessageLoops();
ASSERT_EQ(DownloadItem::INTERRUPTED, item->GetState());
ASSERT_FALSE(item->GetTargetFilePath().empty());
EXPECT_FALSE(item->CanShowInFolder());
EXPECT_FALSE(item->CanOpenDownload());
}
TEST_F(DownloadItemTest, EnabledActionsForCancelledDownload) {
DownloadItemImpl* item = CreateDownloadItem();
MockDownloadFile* download_file =
DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
EXPECT_CALL(*download_file, Cancel());
item->Cancel(true);
RunAllPendingInMessageLoops();
ASSERT_EQ(DownloadItem::CANCELLED, item->GetState());
EXPECT_FALSE(item->CanShowInFolder());
EXPECT_FALSE(item->CanOpenDownload());
}
TEST_F(DownloadItemTest, CompleteDelegate_ReturnTrue) {
DownloadItemImpl* item = CreateDownloadItem();
MockDownloadFile* download_file =
DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
.WillOnce(Return(true));
item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
EXPECT_FALSE(item->IsDangerous());
EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyPath), _))
.WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
base::FilePath(kDummyPath)));
EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _))
.WillOnce(Return(true));
EXPECT_CALL(*download_file, FullPath())
.WillOnce(Return(base::FilePath()));
EXPECT_CALL(*download_file, Detach());
RunAllPendingInMessageLoops();
EXPECT_EQ(DownloadItem::COMPLETE, item->GetState());
}
TEST_F(DownloadItemTest, CompleteDelegate_BlockOnce) {
DownloadItemImpl* item = CreateDownloadItem();
MockDownloadFile* download_file =
DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
base::Closure delegate_callback;
base::Closure copy_delegate_callback;
EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
.WillOnce(DoAll(SaveArg<1>(&delegate_callback),
Return(false)))
.WillOnce(Return(true));
item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
ASSERT_FALSE(delegate_callback.is_null());
copy_delegate_callback = delegate_callback;
delegate_callback.Reset();
EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
copy_delegate_callback.Run();
ASSERT_TRUE(delegate_callback.is_null());
EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
EXPECT_FALSE(item->IsDangerous());
EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyPath), _))
.WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
base::FilePath(kDummyPath)));
EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _))
.WillOnce(Return(true));
EXPECT_CALL(*download_file, FullPath())
.WillOnce(Return(base::FilePath()));
EXPECT_CALL(*download_file, Detach());
RunAllPendingInMessageLoops();
EXPECT_EQ(DownloadItem::COMPLETE, item->GetState());
}
TEST_F(DownloadItemTest, CompleteDelegate_SetDanger) {
DownloadItemImpl* item = CreateDownloadItem();
MockDownloadFile* download_file =
DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
base::Closure delegate_callback;
base::Closure copy_delegate_callback;
EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
.WillOnce(DoAll(SaveArg<1>(&delegate_callback),
Return(false)))
.WillOnce(Return(true));
item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
ASSERT_FALSE(delegate_callback.is_null());
copy_delegate_callback = delegate_callback;
delegate_callback.Reset();
EXPECT_FALSE(item->IsDangerous());
item->OnContentCheckCompleted(
content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE);
EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
copy_delegate_callback.Run();
ASSERT_TRUE(delegate_callback.is_null());
EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
EXPECT_TRUE(item->IsDangerous());
EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyPath), _))
.WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
base::FilePath(kDummyPath)));
EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _))
.WillOnce(Return(true));
EXPECT_CALL(*download_file, FullPath())
.WillOnce(Return(base::FilePath()));
EXPECT_CALL(*download_file, Detach());
RunAllPendingInMessageLoops();
EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
EXPECT_TRUE(item->IsDangerous());
item->ValidateDangerousDownload();
EXPECT_EQ(DOWNLOAD_DANGER_TYPE_USER_VALIDATED, item->GetDangerType());
RunAllPendingInMessageLoops();
EXPECT_EQ(DownloadItem::COMPLETE, item->GetState());
}
TEST_F(DownloadItemTest, CompleteDelegate_BlockTwice) {
DownloadItemImpl* item = CreateDownloadItem();
MockDownloadFile* download_file =
DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
base::Closure delegate_callback;
base::Closure copy_delegate_callback;
EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
.WillOnce(DoAll(SaveArg<1>(&delegate_callback),
Return(false)))
.WillOnce(DoAll(SaveArg<1>(&delegate_callback),
Return(false)))
.WillOnce(Return(true));
item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
ASSERT_FALSE(delegate_callback.is_null());
copy_delegate_callback = delegate_callback;
delegate_callback.Reset();
EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
copy_delegate_callback.Run();
ASSERT_FALSE(delegate_callback.is_null());
copy_delegate_callback = delegate_callback;
delegate_callback.Reset();
EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
copy_delegate_callback.Run();
ASSERT_TRUE(delegate_callback.is_null());
EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
EXPECT_FALSE(item->IsDangerous());
EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyPath), _))
.WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
base::FilePath(kDummyPath)));
EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _))
.WillOnce(Return(true));
EXPECT_CALL(*download_file, FullPath())
.WillOnce(Return(base::FilePath()));
EXPECT_CALL(*download_file, Detach());
RunAllPendingInMessageLoops();
EXPECT_EQ(DownloadItem::COMPLETE, item->GetState());
}
TEST_F(DownloadItemTest, StealDangerousDownload) {
DownloadItemImpl* item = CreateDownloadItem();
MockDownloadFile* download_file =
DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE);
ASSERT_TRUE(item->IsDangerous());
base::FilePath full_path(FILE_PATH_LITERAL("foo.txt"));
base::FilePath returned_path;
EXPECT_CALL(*download_file, FullPath())
.WillOnce(Return(full_path));
EXPECT_CALL(*download_file, Detach());
EXPECT_CALL(*mock_delegate(), DownloadRemoved(_));
base::WeakPtrFactory<DownloadItemTest> weak_ptr_factory(this);
item->StealDangerousDownload(
base::Bind(&DownloadItemTest::OnDownloadFileAcquired,
weak_ptr_factory.GetWeakPtr(),
base::Unretained(&returned_path)));
RunAllPendingInMessageLoops();
EXPECT_EQ(full_path, returned_path);
}
TEST_F(DownloadItemTest, StealInterruptedDangerousDownload) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
base::FilePath returned_path;
DownloadItemImpl* item = CreateDownloadItem();
MockDownloadFile* download_file =
DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE);
base::FilePath full_path = item->GetFullPath();
EXPECT_FALSE(full_path.empty());
EXPECT_CALL(*download_file, FullPath())
.WillOnce(Return(full_path));
EXPECT_CALL(*download_file, Detach());
item->DestinationObserverAsWeakPtr()->DestinationError(
DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED);
ASSERT_TRUE(item->IsDangerous());
EXPECT_CALL(*mock_delegate(), DownloadRemoved(_));
base::WeakPtrFactory<DownloadItemTest> weak_ptr_factory(this);
item->StealDangerousDownload(
base::Bind(&DownloadItemTest::OnDownloadFileAcquired,
weak_ptr_factory.GetWeakPtr(),
base::Unretained(&returned_path)));
RunAllPendingInMessageLoops();
EXPECT_EQ(full_path, returned_path);
}
TEST_F(DownloadItemTest, StealInterruptedNonResumableDangerousDownload) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
base::FilePath returned_path;
DownloadItemImpl* item = CreateDownloadItem();
MockDownloadFile* download_file =
DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE);
EXPECT_CALL(*download_file, Cancel());
item->DestinationObserverAsWeakPtr()->DestinationError(
DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
ASSERT_TRUE(item->IsDangerous());
EXPECT_CALL(*mock_delegate(), DownloadRemoved(_));
base::WeakPtrFactory<DownloadItemTest> weak_ptr_factory(this);
item->StealDangerousDownload(
base::Bind(&DownloadItemTest::OnDownloadFileAcquired,
weak_ptr_factory.GetWeakPtr(),
base::Unretained(&returned_path)));
RunAllPendingInMessageLoops();
EXPECT_TRUE(returned_path.empty());
}
TEST(MockDownloadItem, Compiles) {
MockDownloadItem mock_item;
}
}