| Index: content/browser/download/download_item_impl_unittest.cc
|
| diff --git a/content/browser/download/download_item_impl_unittest.cc b/content/browser/download/download_item_impl_unittest.cc
|
| index 1291ce11350ca19f80de32eacc34b4a6c0c27790..7891b94b3cfd19eaad4fa25359cf53fd75d82f6a 100644
|
| --- a/content/browser/download/download_item_impl_unittest.cc
|
| +++ b/content/browser/download/download_item_impl_unittest.cc
|
| @@ -5,6 +5,7 @@
|
| #include "base/callback.h"
|
| #include "base/command_line.h"
|
| #include "base/message_loop/message_loop.h"
|
| +#include "base/run_loop.h"
|
| #include "base/stl_util.h"
|
| #include "base/threading/thread.h"
|
| #include "content/browser/byte_stream.h"
|
| @@ -14,12 +15,17 @@
|
| #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/browser_thread.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/browser/site_instance.h"
|
| +#include "content/public/browser/web_contents.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 "content/public/test/test_browser_context.h"
|
| +#include "content/public/test/test_browser_thread_bundle.h"
|
| +#include "content/public/test/web_contents_tester.h"
|
| #include "testing/gmock/include/gmock/gmock.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| @@ -92,9 +98,10 @@ class MockRequestHandle : public DownloadRequestHandleInterface {
|
| MOCK_CONST_METHOD0(DebugString, std::string());
|
| };
|
|
|
| -// Schedules a task to invoke the RenameCompletionCallback with |new_path| on
|
| -// the UI thread. Should only be used as the action for
|
| +// Schedules a task to invoke the DownloadFile::RenameCompletionCallback with
|
| +// |new_path| on the UI thread. Should only be used as the action for
|
| // MockDownloadFile::Rename as follows:
|
| +//
|
| // EXPECT_CALL(download_file, Rename*(_,_))
|
| // .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
|
| // new_path));
|
| @@ -104,6 +111,16 @@ ACTION_P2(ScheduleRenameCallback, interrupt_reason, new_path) {
|
| base::Bind(arg1, interrupt_reason, new_path));
|
| }
|
|
|
| +// Schedules a task to invoke DownloadFile::InitializedCallback with
|
| +// |interrupt_reason| on the UI thread. Should be used as the action for
|
| +// MockDownloadFile::Initialize as follows:
|
| +// EXPECT_CALL(download_file, Initialize(_))
|
| +// .WillOnce(ScheduleInitializeCallback(DOWNLOAD_INTERRUPT_REASON_NONE));
|
| +ACTION_P(ScheduleInitializeCallback, interrupt_reason) {
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI, FROM_HERE, base::Bind(arg0, interrupt_reason));
|
| +}
|
| +
|
| } // namespace
|
|
|
| class DownloadItemTest : public testing::Test {
|
| @@ -193,9 +210,14 @@ class DownloadItemTest : public testing::Test {
|
| };
|
|
|
| DownloadItemTest()
|
| - : ui_thread_(BrowserThread::UI, &loop_),
|
| - file_thread_(BrowserThread::FILE, &loop_),
|
| - delegate_() {
|
| + : delegate_(),
|
| + next_download_id_(DownloadItem::kInvalidId + 1) {
|
| + create_info_.reset(new DownloadCreateInfo());
|
| + create_info_->save_info =
|
| + scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo());
|
| + create_info_->save_info->prompt_for_save_location = false;
|
| + create_info_->url_chain.push_back(GURL());
|
| + create_info_->etag = "SomethingToSatisfyResumption";
|
| }
|
|
|
| ~DownloadItemTest() {
|
| @@ -205,7 +227,8 @@ class DownloadItemTest : public testing::Test {
|
| }
|
|
|
| virtual void TearDown() {
|
| - ui_thread_.DeprecatedGetThreadObject()->message_loop()->RunUntilIdle();
|
| + base::RunLoop run_loop;
|
| + run_loop.RunUntilIdle();
|
| STLDeleteElements(&allocated_downloads_);
|
| allocated_downloads_.clear();
|
| }
|
| @@ -214,21 +237,11 @@ class DownloadItemTest : public testing::Test {
|
| // be torn down at the end of the test unless DestroyDownloadItem is
|
| // called.
|
| DownloadItemImpl* CreateDownloadItem() {
|
| - // Normally, the download system takes ownership of info, and is
|
| - // responsible for deleting it. In these unit tests, however, we
|
| - // don't call the function that deletes it, so we do so ourselves.
|
| - 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());
|
| + create_info_->download_id = ++next_download_id_;
|
| + DownloadItemImpl* download = new DownloadItemImpl(&delegate_,
|
| + create_info_->download_id,
|
| + *create_info_,
|
| + net::BoundNetLog());
|
| allocated_downloads_.insert(download);
|
| return download;
|
| }
|
| @@ -237,9 +250,8 @@ class DownloadItemTest : public testing::Test {
|
| 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(_));
|
| + MockDownloadFile* mock_download_file = NULL;
|
| + scoped_ptr<DownloadFile> download_file;
|
| if (callback) {
|
| // Save the callback.
|
| EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _))
|
| @@ -249,10 +261,24 @@ class DownloadItemTest : public testing::Test {
|
| EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _));
|
| }
|
|
|
| - scoped_ptr<DownloadRequestHandleInterface> request_handle(
|
| + // Only create a DownloadFile if the request was successful.
|
| + if (create_info_->interrupt_reason == DOWNLOAD_INTERRUPT_REASON_NONE) {
|
| + mock_download_file = new StrictMock<MockDownloadFile>;
|
| + download_file.reset(mock_download_file);
|
| + EXPECT_CALL(*mock_download_file, Initialize(_))
|
| + .WillOnce(ScheduleInitializeCallback(DOWNLOAD_INTERRUPT_REASON_NONE));
|
| + EXPECT_CALL(*mock_download_file, FullPath())
|
| + .WillRepeatedly(Return(base::FilePath()));
|
| + }
|
| +
|
| + scoped_ptr<MockRequestHandle> request_handle(
|
| new NiceMock<MockRequestHandle>);
|
| - item->Start(download_file.Pass(), request_handle.Pass());
|
| - loop_.RunUntilIdle();
|
| + EXPECT_CALL(*request_handle, GetWebContents())
|
| + .WillRepeatedly(Return(GetWebContents()));
|
| + item->Start(download_file.Pass(),
|
| + request_handle.PassAs<DownloadRequestHandleInterface>(),
|
| + *create_info_);
|
| + base::RunLoop().RunUntilIdle();
|
|
|
| // So that we don't have a function writing to a stack variable
|
| // lying around if the above failed.
|
| @@ -299,7 +325,7 @@ class DownloadItemTest : public testing::Test {
|
| if (expected_state == DownloadItem::IN_PROGRESS) {
|
| EXPECT_CALL(*download_file, Cancel());
|
| item->Cancel(true);
|
| - loop_.RunUntilIdle();
|
| + base::RunLoop().RunUntilIdle();
|
| }
|
| }
|
|
|
| @@ -310,7 +336,7 @@ class DownloadItemTest : public testing::Test {
|
| }
|
|
|
| void RunAllPendingInMessageLoops() {
|
| - loop_.RunUntilIdle();
|
| + base::RunLoop().RunUntilIdle();
|
| }
|
|
|
| MockDelegate* mock_delegate() {
|
| @@ -322,12 +348,51 @@ class DownloadItemTest : public testing::Test {
|
| *return_path = path;
|
| }
|
|
|
| + DownloadCreateInfo* create_info() {
|
| + return create_info_.get();
|
| + }
|
| +
|
| + virtual WebContents* GetWebContents() {
|
| + return NULL;
|
| + }
|
| +
|
| private:
|
| - base::MessageLoopForUI loop_;
|
| - TestBrowserThread ui_thread_; // UI thread
|
| - TestBrowserThread file_thread_; // FILE thread
|
| StrictMock<MockDelegate> delegate_;
|
| std::set<DownloadItem*> allocated_downloads_;
|
| + scoped_ptr<DownloadCreateInfo> create_info_;
|
| + uint32 next_download_id_;
|
| + TestBrowserThreadBundle thread_bundle_;
|
| +};
|
| +
|
| +// Test fixture for resumption tests. These currently require a WebContents().
|
| +// Therefore a TestBrowserContext() and a test WebContents() need to be created
|
| +// for these tests.
|
| +class DownloadItemTestWithResumption : public DownloadItemTest {
|
| + public:
|
| + virtual void SetUp() OVERRIDE {
|
| + CommandLine::ForCurrentProcess()->AppendSwitch(
|
| + switches::kEnableDownloadResumption);
|
| + browser_context_.reset(new TestBrowserContext);
|
| + scoped_refptr<SiteInstance> site_instance(
|
| + SiteInstance::Create(browser_context_.get()));
|
| + web_contents_.reset(WebContentsTester::CreateTestWebContents(
|
| + browser_context_.get(), site_instance.get()));
|
| + DownloadItemTest::SetUp();
|
| + }
|
| +
|
| + virtual void TearDown() OVERRIDE {
|
| + web_contents_.reset();
|
| + browser_context_.reset();
|
| + DownloadItemTest::TearDown();
|
| + }
|
| +
|
| + virtual WebContents* GetWebContents() OVERRIDE {
|
| + return web_contents_.get();
|
| + }
|
| +
|
| + private:
|
| + scoped_ptr<TestBrowserContext> browser_context_;
|
| + scoped_ptr<WebContents> web_contents_;
|
| };
|
|
|
| // Tests to ensure calls that change a DownloadItem generate an update to
|
| @@ -408,10 +473,8 @@ TEST_F(DownloadItemTest, NotificationAfterDestroyed) {
|
| ASSERT_TRUE(observer.CheckDestroyed());
|
| }
|
|
|
| -TEST_F(DownloadItemTest, ContinueAfterInterrupted) {
|
| - CommandLine::ForCurrentProcess()->AppendSwitch(
|
| - switches::kEnableDownloadResumption);
|
| -
|
| +// Test that a download is resumed automatcially after a continuable interrupt.
|
| +TEST_F(DownloadItemTestWithResumption, ContinueAfterInterrupted) {
|
| DownloadItemImpl* item = CreateDownloadItem();
|
| MockObserver observer(item);
|
| DownloadItemImplDelegate::DownloadTargetCallback callback;
|
| @@ -422,12 +485,12 @@ TEST_F(DownloadItemTest, ContinueAfterInterrupted) {
|
| EXPECT_CALL(*download_file, FullPath())
|
| .WillOnce(Return(base::FilePath()));
|
| EXPECT_CALL(*download_file, Detach());
|
| + EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _));
|
| item->DestinationObserverAsWeakPtr()->DestinationError(
|
| DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR);
|
| ASSERT_TRUE(observer.CheckUpdated());
|
| - // Should attempt to auto-resume. Because we don't have a mock WebContents,
|
| - // ResumeInterruptedDownload() will abort early, with another interrupt,
|
| - // which will be ignored.
|
| + // Should attempt to auto-resume. This is verified by the
|
| + // MockResumeInterruptedDownload() test expectation above.
|
| ASSERT_EQ(1, observer.GetInterruptCount());
|
| ASSERT_EQ(0, observer.GetResumeCount());
|
| RunAllPendingInMessageLoops();
|
| @@ -435,11 +498,9 @@ TEST_F(DownloadItemTest, ContinueAfterInterrupted) {
|
| CleanupItem(item, download_file, DownloadItem::INTERRUPTED);
|
| }
|
|
|
| -// Same as above, but with a non-continuable interrupt.
|
| -TEST_F(DownloadItemTest, RestartAfterInterrupted) {
|
| - CommandLine::ForCurrentProcess()->AppendSwitch(
|
| - switches::kEnableDownloadResumption);
|
| -
|
| +// Test that automatic resumption doesn't happen after a non-continuable
|
| +// interrupt.
|
| +TEST_F(DownloadItemTestWithResumption, RestartAfterInterrupted) {
|
| DownloadItemImpl* item = CreateDownloadItem();
|
| MockObserver observer(item);
|
| DownloadItemImplDelegate::DownloadTargetCallback callback;
|
| @@ -490,68 +551,101 @@ TEST_F(DownloadItemTest, UnresumableInterrupt) {
|
| CleanupItem(item, download_file, DownloadItem::INTERRUPTED);
|
| }
|
|
|
| -TEST_F(DownloadItemTest, LimitRestartsAfterInterrupted) {
|
| - CommandLine::ForCurrentProcess()->AppendSwitch(
|
| - switches::kEnableDownloadResumption);
|
| -
|
| +// Test that automatic resumption only happens a limited number of times. The
|
| +// limit is currently hardcoded as DownloadItemImpl::kMaxAutoResumeAttempts.
|
| +TEST_F(DownloadItemTestWithResumption, LimitRestartsAfterInterrupted) {
|
| 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;
|
| + base::FilePath target_path(kDummyPath);
|
| + base::FilePath intermediate_path(target_path.InsertBeforeExtensionASCII("x"));
|
|
|
| - 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()));
|
| -
|
| - // It's too complicated to set up a WebContents instance that would cause
|
| - // the MockDownloadItemDelegate's ResumeInterruptedDownload() function
|
| - // to be callled, so we simply verify that GetWebContents() is called.
|
| - if (i < (DownloadItemImpl::kMaxAutoResumeAttempts - 1)) {
|
| - EXPECT_CALL(*mock_request_handle, GetWebContents())
|
| - .WillRepeatedly(Return(static_cast<WebContents*>(NULL)));
|
| - }
|
| -
|
| - // Copied key parts of DoIntermediateRename & AddDownloadFileToDownloadItem
|
| - // to allow for holding onto the request handle.
|
| - item->Start(download_file.Pass(), request_handle.Pass());
|
| - RunAllPendingInMessageLoops();
|
| - if (i == 0) {
|
| - // Target determination is only done the first time through.
|
| - base::FilePath target_path(kDummyPath);
|
| - base::FilePath intermediate_path(
|
| - target_path.InsertBeforeExtensionASCII("x"));
|
| - EXPECT_CALL(*mock_download_file, RenameAndUniquify(intermediate_path, _))
|
| + DownloadItemImplDelegate::DownloadTargetCallback callback;
|
| + MockDownloadFile* download_file =
|
| + AddDownloadFileToDownloadItem(item, &callback);
|
| + EXPECT_FALSE(callback.is_null());
|
| + if (i == 0)
|
| + EXPECT_CALL(*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());
|
| + else
|
| + EXPECT_EQ(intermediate_path, item->GetFullPath());
|
|
|
| - // Use a continuable interrupt.
|
| + callback.Run(target_path,
|
| + DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
| + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
| + intermediate_path);
|
| + RunAllPendingInMessageLoops();
|
| + ASSERT_EQ(i, observer.GetResumeCount());
|
| + EXPECT_CALL(*download_file, Detach());
|
| + // FILE_TRANSIENT_ERROR is a continuable interrupt that causes the download
|
| + // to be resumed automatically. However, it should only attempt to resume if
|
| + // the number of conesecutive automatic resumptions is less than
|
| + // kMaxAutoResumeAttempts.
|
| + EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _))
|
| + .Times(i < DownloadItemImpl::kMaxAutoResumeAttempts ? 1 : 0);
|
| item->DestinationObserverAsWeakPtr()->DestinationError(
|
| DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR);
|
| -
|
| ASSERT_EQ(i + 1, observer.GetInterruptCount());
|
| - ::testing::Mock::VerifyAndClearExpectations(mock_download_file);
|
| }
|
| + EXPECT_EQ(DownloadItemImpl::kMaxAutoResumeAttempts,
|
| + observer.GetResumeCount());
|
| +}
|
| +
|
| +// If the download attempts to resume and the resumption request fails, the
|
| +// subsequent Start() call shouldn't update the origin state (URL redirect
|
| +// chains, Content-Disposition, download URL, etc..)
|
| +TEST_F(DownloadItemTestWithResumption,
|
| + FailedResumptionDoesntUpdateOriginState) {
|
| + const char* kContentDisposition = "attachment; filename=foo";
|
| + const char* kFirstETag = "ABC";
|
| + const char* kFirstLastModified = "Yesterday";
|
| + const char* kFirstURL = "http://www.example.com/download";
|
| + create_info()->content_disposition = kContentDisposition;
|
| + create_info()->etag = kFirstETag;
|
| + create_info()->last_modified = kFirstLastModified;
|
| + create_info()->url_chain.push_back(GURL(kFirstURL));
|
|
|
| - CleanupItem(item, mock_download_file, DownloadItem::INTERRUPTED);
|
| + DownloadItemImpl* item = CreateDownloadItem();
|
| + MockDownloadFile* download_file =
|
| + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
|
| + EXPECT_EQ(kContentDisposition, item->GetContentDisposition());
|
| + EXPECT_EQ(kFirstETag, item->GetETag());
|
| + EXPECT_EQ(kFirstLastModified, item->GetLastModifiedTime());
|
| + EXPECT_EQ(kFirstURL, item->GetURL().spec());
|
| +
|
| + EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _));
|
| + EXPECT_CALL(*download_file, Detach());
|
| + item->DestinationObserverAsWeakPtr()->DestinationError(
|
| + DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR);
|
| + EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
|
| +
|
| + // Now change the create info. The changes should not cause the DownloadItem
|
| + // to be updated.
|
| + const char* kSecondContentDisposition = "attachment; filename=bar";
|
| + const char* kSecondETag = "123";
|
| + const char* kSecondLastModified = "Today";
|
| + const char* kSecondURL = "http://example.com/another-download";
|
| + create_info()->content_disposition = kSecondContentDisposition;
|
| + create_info()->etag = kSecondETag;
|
| + create_info()->last_modified = kSecondLastModified;
|
| + create_info()->url_chain.clear();
|
| + create_info()->url_chain.push_back(GURL(kSecondURL));
|
| + create_info()->interrupt_reason = DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED;
|
| +
|
| + // The following ends up calling DownloadItem::Start(), but shouldn't result
|
| + // in an origin update.
|
| + DownloadItemImplDelegate::DownloadTargetCallback download_target_callback;
|
| + download_file =
|
| + AddDownloadFileToDownloadItem(item, &download_target_callback);
|
| +
|
| + EXPECT_EQ(kContentDisposition, item->GetContentDisposition());
|
| + EXPECT_EQ(kFirstETag, item->GetETag());
|
| + EXPECT_EQ(kFirstLastModified, item->GetLastModifiedTime());
|
| + EXPECT_EQ(kFirstURL, item->GetURL().spec());
|
| + EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
|
| + EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, item->GetLastReason());
|
| }
|
|
|
| TEST_F(DownloadItemTest, NotificationAfterRemove) {
|
| @@ -577,8 +671,7 @@ TEST_F(DownloadItemTest, NotificationAfterOnContentCheckCompleted) {
|
| EXPECT_TRUE(safe_observer.CheckUpdated());
|
|
|
| // Setting to unsafe url or unsafe file should trigger a notification.
|
| - DownloadItemImpl* unsafeurl_item =
|
| - CreateDownloadItem();
|
| + DownloadItemImpl* unsafeurl_item = CreateDownloadItem();
|
| MockObserver unsafeurl_observer(unsafeurl_item);
|
|
|
| unsafeurl_item->OnAllDataSaved(std::string());
|
| @@ -589,8 +682,7 @@ TEST_F(DownloadItemTest, NotificationAfterOnContentCheckCompleted) {
|
| unsafeurl_item->ValidateDangerousDownload();
|
| EXPECT_TRUE(unsafeurl_observer.CheckUpdated());
|
|
|
| - DownloadItemImpl* unsafefile_item =
|
| - CreateDownloadItem();
|
| + DownloadItemImpl* unsafefile_item = CreateDownloadItem();
|
| MockObserver unsafefile_observer(unsafefile_item);
|
|
|
| unsafefile_item->OnAllDataSaved(std::string());
|
| @@ -643,7 +735,7 @@ TEST_F(DownloadItemTest, NotificationAfterTogglePause) {
|
|
|
| EXPECT_CALL(*mock_download_file, Initialize(_));
|
| EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _));
|
| - item->Start(download_file.Pass(), request_handle.Pass());
|
| + item->Start(download_file.Pass(), request_handle.Pass(), *create_info());
|
|
|
| item->Pause();
|
| ASSERT_TRUE(observer.CheckUpdated());
|
| @@ -690,12 +782,47 @@ TEST_F(DownloadItemTest, Start) {
|
| scoped_ptr<DownloadRequestHandleInterface> request_handle(
|
| new NiceMock<MockRequestHandle>);
|
| EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _));
|
| - item->Start(download_file.Pass(), request_handle.Pass());
|
| + item->Start(download_file.Pass(), request_handle.Pass(), *create_info());
|
| RunAllPendingInMessageLoops();
|
|
|
| CleanupItem(item, mock_download_file, DownloadItem::IN_PROGRESS);
|
| }
|
|
|
| +// Handling of downloads initiated via a failed request. In this case, Start()
|
| +// will get called with a DownloadCreateInfo with a non-zero interrupt_reason.
|
| +TEST_F(DownloadItemTest, StartFailedDownload) {
|
| + create_info()->interrupt_reason = DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED;
|
| + DownloadItemImpl* item = CreateDownloadItem();
|
| + // The download is considered to be IN_PROGRESS even though there's an
|
| + // interrupt reason. It will transition to INTERRUPTED once Start() is called.
|
| + EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
|
| +
|
| + // DownloadFile and DownloadRequestHandleInterface objects aren't created for
|
| + // failed downloads.
|
| + scoped_ptr<DownloadFile> null_download_file;
|
| + scoped_ptr<DownloadRequestHandleInterface> null_request_handle;
|
| + DownloadItemImplDelegate::DownloadTargetCallback download_target_callback;
|
| + EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _))
|
| + .WillOnce(SaveArg<1>(&download_target_callback));
|
| + item->Start(
|
| + null_download_file.Pass(), null_request_handle.Pass(), *create_info());
|
| + RunAllPendingInMessageLoops();
|
| +
|
| + // The DownloadItemImpl should attempt to determine a target path even if the
|
| + // download was interrupted.
|
| + ASSERT_FALSE(download_target_callback.is_null());
|
| + ASSERT_EQ(DownloadItem::INTERRUPTED, item->GetState());
|
| + base::FilePath target_path(FILE_PATH_LITERAL("foo"));
|
| + download_target_callback.Run(target_path,
|
| + DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
| + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
| + target_path);
|
| + RunAllPendingInMessageLoops();
|
| +
|
| + EXPECT_EQ(target_path, item->GetTargetFilePath());
|
| + CleanupItem(item, NULL, DownloadItem::INTERRUPTED);
|
| +}
|
| +
|
| // Test that the delegate is invoked after the download file is renamed.
|
| TEST_F(DownloadItemTest, CallbackAfterRename) {
|
| DownloadItemImpl* item = CreateDownloadItem();
|
| @@ -812,9 +939,8 @@ TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Restart) {
|
| // As above. But if the download can be resumed by continuing, then the
|
| // intermediate path should be retained when the download is interrupted after
|
| // the intermediate rename succeeds.
|
| -TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Continue) {
|
| - CommandLine::ForCurrentProcess()->AppendSwitch(
|
| - switches::kEnableDownloadResumption);
|
| +TEST_F(DownloadItemTestWithResumption,
|
| + InterruptedBeforeIntermediateRename_Continue) {
|
| DownloadItemImpl* item = CreateDownloadItem();
|
| DownloadItemImplDelegate::DownloadTargetCallback callback;
|
| MockDownloadFile* download_file =
|
| @@ -847,9 +973,8 @@ TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Continue) {
|
|
|
| // As above. If the intermediate rename fails, then the interrupt reason should
|
| // be set to the destination error and the intermediate path should be empty.
|
| -TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Failed) {
|
| - CommandLine::ForCurrentProcess()->AppendSwitch(
|
| - switches::kEnableDownloadResumption);
|
| +TEST_F(DownloadItemTestWithResumption,
|
| + InterruptedBeforeIntermediateRename_Failed) {
|
| DownloadItemImpl* item = CreateDownloadItem();
|
| DownloadItemImplDelegate::DownloadTargetCallback callback;
|
| MockDownloadFile* download_file =
|
| @@ -1247,9 +1372,7 @@ TEST_F(DownloadItemTest, StealDangerousDownload) {
|
| EXPECT_EQ(full_path, returned_path);
|
| }
|
|
|
| -TEST_F(DownloadItemTest, StealInterruptedDangerousDownload) {
|
| - CommandLine::ForCurrentProcess()->AppendSwitch(
|
| - switches::kEnableDownloadResumption);
|
| +TEST_F(DownloadItemTestWithResumption, StealInterruptedDangerousDownload) {
|
| base::FilePath returned_path;
|
| DownloadItemImpl* item = CreateDownloadItem();
|
| MockDownloadFile* download_file =
|
| @@ -1273,9 +1396,8 @@ TEST_F(DownloadItemTest, StealInterruptedDangerousDownload) {
|
| EXPECT_EQ(full_path, returned_path);
|
| }
|
|
|
| -TEST_F(DownloadItemTest, StealInterruptedNonResumableDangerousDownload) {
|
| - CommandLine::ForCurrentProcess()->AppendSwitch(
|
| - switches::kEnableDownloadResumption);
|
| +TEST_F(DownloadItemTestWithResumption,
|
| + StealInterruptedNonResumableDangerousDownload) {
|
| base::FilePath returned_path;
|
| DownloadItemImpl* item = CreateDownloadItem();
|
| MockDownloadFile* download_file =
|
|
|