| 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 0afad1bfca248fea496ee1801387afca60fc2572..b3088866d223f28d45deb07968192ebb37d5e275 100644
|
| --- a/content/browser/download/download_item_impl_unittest.cc
|
| +++ b/content/browser/download/download_item_impl_unittest.cc
|
| @@ -10,6 +10,7 @@
|
| #include "base/callback.h"
|
| #include "base/feature_list.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"
|
| @@ -18,13 +19,20 @@
|
| #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_features.h"
|
| #include "content/public/test/mock_download_item.h"
|
| +#include "content/public/test/mock_download_item.h"
|
| +#include "content/public/test/test_browser_context.h"
|
| #include "content/public/test/test_browser_context.h"
|
| #include "content/public/test/test_browser_thread.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"
|
|
|
| @@ -66,7 +74,6 @@ class MockDelegate : public DownloadItemImplDelegate {
|
| void(DownloadUrlParameters* params, uint32_t 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*));
|
| @@ -97,6 +104,27 @@ class MockRequestHandle : public DownloadRequestHandleInterface {
|
| MOCK_CONST_METHOD0(DebugString, std::string());
|
| };
|
|
|
| +// |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));
|
| +ACTION_P2(ScheduleRenameCallback, interrupt_reason, new_path) {
|
| + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
| + 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));
|
| +}
|
| +
|
| class TestDownloadItemObserver : public DownloadItem::Observer {
|
| public:
|
| explicit TestDownloadItemObserver(DownloadItem* item)
|
| @@ -128,8 +156,8 @@ class TestDownloadItemObserver : public DownloadItem::Observer {
|
|
|
| private:
|
| void OnDownloadRemoved(DownloadItem* download) override {
|
| - DVLOG(20) << " " << __FUNCTION__
|
| - << " download = " << download->DebugString(false);
|
| + SCOPED_TRACE(::testing::Message() << " " << __FUNCTION__ << " download = "
|
| + << download->DebugString(false));
|
| removed_ = true;
|
| }
|
|
|
| @@ -171,25 +199,18 @@ class TestDownloadItemObserver : public DownloadItem::Observer {
|
| int resume_count_;
|
| };
|
|
|
| -// Schedules a task to invoke the 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));
|
| -ACTION_P2(ScheduleRenameCallback, interrupt_reason, new_path) {
|
| - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
| - base::Bind(arg1, interrupt_reason, new_path));
|
| -}
|
| -
|
| } // namespace
|
|
|
| class DownloadItemTest : public testing::Test {
|
| public:
|
| 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() {
|
| @@ -204,7 +225,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_);
|
| }
|
|
|
| @@ -212,21 +234,10 @@ class DownloadItemTest : public testing::Test {
|
| // be torn down at the end of the test unless DestroyDownloadItem is
|
| // called.
|
| DownloadItemImpl* CreateDownloadItem() {
|
| - scoped_ptr<DownloadCreateInfo> info;
|
| -
|
| - info.reset(new DownloadCreateInfo());
|
| - 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";
|
| -
|
| - return CreateDownloadItemWithCreateInfo(std::move(info));
|
| - }
|
| -
|
| - DownloadItemImpl* CreateDownloadItemWithCreateInfo(
|
| - scoped_ptr<DownloadCreateInfo> info) {
|
| - DownloadItemImpl* download = new DownloadItemImpl(
|
| - &delegate_, next_download_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;
|
| }
|
| @@ -235,9 +246,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 = nullptr;
|
| + scoped_ptr<DownloadFile> download_file;
|
| if (callback) {
|
| // Save the callback.
|
| EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _))
|
| @@ -247,10 +257,23 @@ 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_->result == 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(std::move(download_file), std::move(request_handle));
|
| - loop_.RunUntilIdle();
|
| + EXPECT_CALL(*request_handle, GetWebContents())
|
| + .WillRepeatedly(Return(GetWebContents()));
|
| + item->Start(std::move(download_file), std::move(request_handle),
|
| + *create_info_);
|
| + base::RunLoop().RunUntilIdle();
|
|
|
| // So that we don't have a function writing to a stack variable
|
| // lying around if the above failed.
|
| @@ -298,7 +321,7 @@ class DownloadItemTest : public testing::Test {
|
| if (download_file)
|
| EXPECT_CALL(*download_file, Cancel());
|
| item->Cancel(true);
|
| - loop_.RunUntilIdle();
|
| + base::RunLoop().RunUntilIdle();
|
| }
|
| }
|
|
|
| @@ -308,9 +331,7 @@ class DownloadItemTest : public testing::Test {
|
| delete item;
|
| }
|
|
|
| - void RunAllPendingInMessageLoops() {
|
| - loop_.RunUntilIdle();
|
| - }
|
| + void RunAllPendingInMessageLoops() { base::RunLoop().RunUntilIdle(); }
|
|
|
| MockDelegate* mock_delegate() {
|
| return &delegate_;
|
| @@ -321,15 +342,57 @@ class DownloadItemTest : public testing::Test {
|
| *return_path = path;
|
| }
|
|
|
| + DownloadCreateInfo* create_info() { return create_info_.get(); }
|
| +
|
| + virtual WebContents* GetWebContents() { return nullptr; }
|
| +
|
| private:
|
| - int next_download_id_ = DownloadItem::kInvalidId + 1;
|
| - 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_t next_download_id_;
|
| + TestBrowserThreadBundle thread_bundle_;
|
| +};
|
| +
|
| +// Test fixture for resumption tests. The fixture takes a GTest parameter of
|
| +// type 'bool'. If the parameter is true, then the DownloadItem has a valid
|
| +// WebContents. It would have a null WebContents otherwise. Whether or not a
|
| +// WebContents exists has a bearing on the code path used for resumption. Hence
|
| +// it's important to exercise both possibilities for these tests.
|
| +class DownloadItemTestWithResumption
|
| + : public DownloadItemTest,
|
| + public ::testing::WithParamInterface<bool> {
|
| + public:
|
| + void SetUp() override {
|
| + browser_context_.reset(new TestBrowserContext);
|
| + if (GetParam()) {
|
| + scoped_refptr<SiteInstance> site_instance(
|
| + SiteInstance::Create(browser_context_.get()));
|
| + web_contents_.reset(WebContentsTester::CreateTestWebContents(
|
| + browser_context_.get(), site_instance.get()));
|
| + }
|
| + DownloadItemTest::SetUp();
|
| + }
|
| +
|
| + void TearDown() override {
|
| + DownloadItemTest::TearDown();
|
| + web_contents_.reset();
|
| + browser_context_.reset();
|
| + }
|
| +
|
| + WebContents* GetWebContents() override { return web_contents_.get(); }
|
| +
|
| + BrowserContext* GetBrowserContext() { return browser_context_.get(); }
|
| +
|
| + private:
|
| + scoped_ptr<TestBrowserContext> browser_context_;
|
| + scoped_ptr<WebContents> web_contents_;
|
| };
|
|
|
| +INSTANTIATE_TEST_CASE_P(WithAndWithoutWebContents,
|
| + DownloadItemTestWithResumption,
|
| + ::testing::Bool());
|
| +
|
| // Tests to ensure calls that change a DownloadItem generate an update to
|
| // observers.
|
| // State changing functions not tested:
|
| @@ -408,8 +471,8 @@ TEST_F(DownloadItemTest, NotificationAfterDestroyed) {
|
| ASSERT_TRUE(observer.download_destroyed());
|
| }
|
|
|
| -TEST_F(DownloadItemTest, ContinueAfterInterrupted) {
|
| - TestBrowserContext test_browser_context;
|
| +// Test that a download is resumed automatcially after a continuable interrupt.
|
| +TEST_P(DownloadItemTestWithResumption, ContinueAfterInterrupted) {
|
| DownloadItemImpl* item = CreateDownloadItem();
|
| TestDownloadItemObserver observer(item);
|
| MockDownloadFile* download_file =
|
| @@ -420,7 +483,7 @@ TEST_F(DownloadItemTest, ContinueAfterInterrupted) {
|
| .WillOnce(Return(base::FilePath()));
|
| EXPECT_CALL(*download_file, Detach());
|
| EXPECT_CALL(*mock_delegate(), GetBrowserContext())
|
| - .WillRepeatedly(Return(&test_browser_context));
|
| + .WillRepeatedly(Return(GetBrowserContext()));
|
| EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _)).Times(1);
|
| item->DestinationObserverAsWeakPtr()->DestinationError(
|
| DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR);
|
| @@ -441,8 +504,9 @@ TEST_F(DownloadItemTest, ContinueAfterInterrupted) {
|
| CleanupItem(item, nullptr, DownloadItem::IN_PROGRESS);
|
| }
|
|
|
| -// Same as above, but with a non-continuable interrupt.
|
| -TEST_F(DownloadItemTest, RestartAfterInterrupted) {
|
| +// Test that automatic resumption doesn't happen after a non-continuable
|
| +// interrupt.
|
| +TEST_P(DownloadItemTestWithResumption, RestartAfterInterrupted) {
|
| DownloadItemImpl* item = CreateDownloadItem();
|
| TestDownloadItemObserver observer(item);
|
| MockDownloadFile* download_file =
|
| @@ -488,8 +552,7 @@ TEST_F(DownloadItemTest, UnresumableInterrupt) {
|
| CleanupItem(item, nullptr, DownloadItem::INTERRUPTED);
|
| }
|
|
|
| -TEST_F(DownloadItemTest, LimitRestartsAfterInterrupted) {
|
| - TestBrowserContext test_browser_context;
|
| +TEST_P(DownloadItemTestWithResumption, LimitRestartsAfterInterrupted) {
|
| DownloadItemImpl* item = CreateDownloadItem();
|
| base::WeakPtr<DownloadDestinationObserver> as_observer(
|
| item->DestinationObserverAsWeakPtr());
|
| @@ -503,11 +566,11 @@ TEST_F(DownloadItemTest, LimitRestartsAfterInterrupted) {
|
| EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _))
|
| .WillRepeatedly(SaveArg<1>(&callback));
|
| EXPECT_CALL(*mock_delegate(), GetBrowserContext())
|
| - .WillRepeatedly(Return(&test_browser_context));
|
| + .WillRepeatedly(Return(GetBrowserContext()));
|
| EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _))
|
| .Times(DownloadItemImpl::kMaxAutoResumeAttempts);
|
| for (int i = 0; i < (DownloadItemImpl::kMaxAutoResumeAttempts + 1); ++i) {
|
| - DVLOG(20) << "Loop iteration " << i;
|
| + SCOPED_TRACE(::testing::Message() << "Iteration " << i);
|
|
|
| mock_download_file = new NiceMock<MockDownloadFile>;
|
| download_file.reset(mock_download_file);
|
| @@ -519,7 +582,8 @@ TEST_F(DownloadItemTest, LimitRestartsAfterInterrupted) {
|
|
|
| // Copied key parts of DoIntermediateRename & AddDownloadFileToDownloadItem
|
| // to allow for holding onto the request handle.
|
| - item->Start(std::move(download_file), std::move(request_handle));
|
| + item->Start(std::move(download_file), std::move(request_handle),
|
| + *create_info());
|
| RunAllPendingInMessageLoops();
|
| if (i == 0) {
|
| // Target determination is only done the first time through.
|
| @@ -538,6 +602,7 @@ TEST_F(DownloadItemTest, LimitRestartsAfterInterrupted) {
|
| item->DestinationObserverAsWeakPtr()->DestinationError(
|
| DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR);
|
|
|
| + RunAllPendingInMessageLoops();
|
| ::testing::Mock::VerifyAndClearExpectations(mock_download_file);
|
| }
|
|
|
| @@ -545,19 +610,73 @@ TEST_F(DownloadItemTest, LimitRestartsAfterInterrupted) {
|
| CleanupItem(item, nullptr, DownloadItem::INTERRUPTED);
|
| }
|
|
|
| +// 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_P(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));
|
| +
|
| + 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(*mock_delegate(), GetBrowserContext())
|
| + .WillRepeatedly(Return(GetBrowserContext()));
|
| + EXPECT_CALL(*download_file, Detach());
|
| + item->DestinationObserverAsWeakPtr()->DestinationError(
|
| + DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR);
|
| + RunAllPendingInMessageLoops();
|
| + EXPECT_EQ(DownloadItem::IN_PROGRESS, 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()->result = 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 that resumption uses the final URL in a URL chain when resuming.
|
| -TEST_F(DownloadItemTest, ResumeUsingFinalURL) {
|
| - TestBrowserContext test_browser_context;
|
| - scoped_ptr<DownloadCreateInfo> create_info(new DownloadCreateInfo);
|
| - create_info->save_info = scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo());
|
| - create_info->save_info->prompt_for_save_location = false;
|
| - create_info->etag = "SomethingToSatisfyResumption";
|
| - create_info->url_chain.push_back(GURL("http://example.com/a"));
|
| - create_info->url_chain.push_back(GURL("http://example.com/b"));
|
| - create_info->url_chain.push_back(GURL("http://example.com/c"));
|
| -
|
| - DownloadItemImpl* item =
|
| - CreateDownloadItemWithCreateInfo(std::move(create_info));
|
| +TEST_P(DownloadItemTestWithResumption, ResumeUsingFinalURL) {
|
| + create_info()->save_info->prompt_for_save_location = false;
|
| + create_info()->url_chain.clear();
|
| + create_info()->url_chain.push_back(GURL("http://example.com/a"));
|
| + create_info()->url_chain.push_back(GURL("http://example.com/b"));
|
| + create_info()->url_chain.push_back(GURL("http://example.com/c"));
|
| +
|
| + DownloadItemImpl* item = CreateDownloadItem();
|
| TestDownloadItemObserver observer(item);
|
| MockDownloadFile* download_file =
|
| DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
|
| @@ -566,7 +685,7 @@ TEST_F(DownloadItemTest, ResumeUsingFinalURL) {
|
| EXPECT_CALL(*download_file, FullPath()).WillOnce(Return(base::FilePath()));
|
| EXPECT_CALL(*download_file, Detach());
|
| EXPECT_CALL(*mock_delegate(), GetBrowserContext())
|
| - .WillRepeatedly(Return(&test_browser_context));
|
| + .WillRepeatedly(Return(GetBrowserContext()));
|
| EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(
|
| Property(&DownloadUrlParameters::url,
|
| GURL("http://example.com/c")),
|
| @@ -609,8 +728,7 @@ TEST_F(DownloadItemTest, NotificationAfterOnContentCheckCompleted) {
|
| EXPECT_TRUE(safe_observer.CheckAndResetDownloadUpdated());
|
|
|
| // Setting to unsafe url or unsafe file should trigger a notification.
|
| - DownloadItemImpl* unsafeurl_item =
|
| - CreateDownloadItem();
|
| + DownloadItemImpl* unsafeurl_item = CreateDownloadItem();
|
| TestDownloadItemObserver unsafeurl_observer(unsafeurl_item);
|
|
|
| unsafeurl_item->OnAllDataSaved(std::string());
|
| @@ -621,8 +739,7 @@ TEST_F(DownloadItemTest, NotificationAfterOnContentCheckCompleted) {
|
| unsafeurl_item->ValidateDangerousDownload();
|
| EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated());
|
|
|
| - DownloadItemImpl* unsafefile_item =
|
| - CreateDownloadItem();
|
| + DownloadItemImpl* unsafefile_item = CreateDownloadItem();
|
| TestDownloadItemObserver unsafefile_observer(unsafefile_item);
|
|
|
| unsafefile_item->OnAllDataSaved(std::string());
|
| @@ -675,7 +792,8 @@ TEST_F(DownloadItemTest, NotificationAfterTogglePause) {
|
|
|
| EXPECT_CALL(*mock_download_file, Initialize(_));
|
| EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _));
|
| - item->Start(std::move(download_file), std::move(request_handle));
|
| + item->Start(std::move(download_file), std::move(request_handle),
|
| + *create_info());
|
|
|
| item->Pause();
|
| ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
|
| @@ -722,12 +840,45 @@ TEST_F(DownloadItemTest, Start) {
|
| scoped_ptr<DownloadRequestHandleInterface> request_handle(
|
| new NiceMock<MockRequestHandle>);
|
| EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _));
|
| - item->Start(std::move(download_file), std::move(request_handle));
|
| + item->Start(std::move(download_file), std::move(request_handle),
|
| + *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()->result = DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED;
|
| + DownloadItemImpl* item = CreateDownloadItem();
|
| + EXPECT_EQ(DownloadItem::INTERRUPTED, 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(std::move(null_download_file), std::move(null_request_handle),
|
| + *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();
|
| @@ -844,7 +995,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) {
|
| +TEST_P(DownloadItemTestWithResumption,
|
| + InterruptedBeforeIntermediateRename_Continue) {
|
| DownloadItemImpl* item = CreateDownloadItem();
|
| DownloadItemImplDelegate::DownloadTargetCallback callback;
|
| MockDownloadFile* download_file =
|
| @@ -877,7 +1029,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) {
|
| +TEST_P(DownloadItemTestWithResumption,
|
| + InterruptedBeforeIntermediateRename_Failed) {
|
| DownloadItemImpl* item = CreateDownloadItem();
|
| DownloadItemImplDelegate::DownloadTargetCallback callback;
|
| MockDownloadFile* download_file =
|
| @@ -1275,7 +1428,7 @@ TEST_F(DownloadItemTest, StealDangerousDownload) {
|
| EXPECT_EQ(full_path, returned_path);
|
| }
|
|
|
| -TEST_F(DownloadItemTest, StealInterruptedDangerousDownload) {
|
| +TEST_P(DownloadItemTestWithResumption, StealInterruptedDangerousDownload) {
|
| base::FilePath returned_path;
|
| DownloadItemImpl* item = CreateDownloadItem();
|
| MockDownloadFile* download_file =
|
| @@ -1299,7 +1452,8 @@ TEST_F(DownloadItemTest, StealInterruptedDangerousDownload) {
|
| EXPECT_EQ(full_path, returned_path);
|
| }
|
|
|
| -TEST_F(DownloadItemTest, StealInterruptedNonResumableDangerousDownload) {
|
| +TEST_P(DownloadItemTestWithResumption,
|
| + StealInterruptedNonResumableDangerousDownload) {
|
| base::FilePath returned_path;
|
| DownloadItemImpl* item = CreateDownloadItem();
|
| MockDownloadFile* download_file =
|
|
|