Update ASan/Android runtime and setup script to LLVM r200682.
[chromium-blink-merge.git] / content / browser / download / download_item_impl_unittest.cc
blob9abe3417e7e3546978d2f05cb68ddd35b82cad65
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/callback.h"
6 #include "base/command_line.h"
7 #include "base/message_loop/message_loop.h"
8 #include "base/stl_util.h"
9 #include "base/threading/thread.h"
10 #include "content/browser/byte_stream.h"
11 #include "content/browser/download/download_create_info.h"
12 #include "content/browser/download/download_file_factory.h"
13 #include "content/browser/download/download_item_impl.h"
14 #include "content/browser/download/download_item_impl_delegate.h"
15 #include "content/browser/download/download_request_handle.h"
16 #include "content/browser/download/mock_download_file.h"
17 #include "content/public/browser/download_destination_observer.h"
18 #include "content/public/browser/download_interrupt_reasons.h"
19 #include "content/public/browser/download_url_parameters.h"
20 #include "content/public/common/content_switches.h"
21 #include "content/public/test/mock_download_item.h"
22 #include "content/public/test/test_browser_thread.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h"
26 using ::testing::_;
27 using ::testing::NiceMock;
28 using ::testing::Property;
29 using ::testing::Return;
30 using ::testing::SaveArg;
31 using ::testing::StrictMock;
33 const int kDownloadChunkSize = 1000;
34 const int kDownloadSpeed = 1000;
35 const base::FilePath::CharType kDummyPath[] = FILE_PATH_LITERAL("/testpath");
37 namespace content {
39 namespace {
41 class MockDelegate : public DownloadItemImplDelegate {
42 public:
43 MockDelegate() : DownloadItemImplDelegate() {
44 SetDefaultExpectations();
47 MOCK_METHOD2(DetermineDownloadTarget, void(
48 DownloadItemImpl*, const DownloadTargetCallback&));
49 MOCK_METHOD2(ShouldCompleteDownload,
50 bool(DownloadItemImpl*, const base::Closure&));
51 MOCK_METHOD2(ShouldOpenDownload,
52 bool(DownloadItemImpl*, const ShouldOpenDownloadCallback&));
53 MOCK_METHOD1(ShouldOpenFileBasedOnExtension, bool(const base::FilePath&));
54 MOCK_METHOD1(CheckForFileRemoval, void(DownloadItemImpl*));
56 virtual void ResumeInterruptedDownload(
57 scoped_ptr<DownloadUrlParameters> params, uint32 id) OVERRIDE {
58 MockResumeInterruptedDownload(params.get(), id);
60 MOCK_METHOD2(MockResumeInterruptedDownload,
61 void(DownloadUrlParameters* params, uint32 id));
63 MOCK_CONST_METHOD0(GetBrowserContext, BrowserContext*());
64 MOCK_METHOD1(UpdatePersistence, void(DownloadItemImpl*));
65 MOCK_METHOD1(DownloadOpened, void(DownloadItemImpl*));
66 MOCK_METHOD1(DownloadRemoved, void(DownloadItemImpl*));
67 MOCK_CONST_METHOD1(AssertStateConsistent, void(DownloadItemImpl*));
69 void VerifyAndClearExpectations() {
70 ::testing::Mock::VerifyAndClearExpectations(this);
71 SetDefaultExpectations();
74 private:
75 void SetDefaultExpectations() {
76 EXPECT_CALL(*this, AssertStateConsistent(_))
77 .WillRepeatedly(Return());
78 EXPECT_CALL(*this, ShouldOpenFileBasedOnExtension(_))
79 .WillRepeatedly(Return(false));
80 EXPECT_CALL(*this, ShouldOpenDownload(_, _))
81 .WillRepeatedly(Return(true));
85 class MockRequestHandle : public DownloadRequestHandleInterface {
86 public:
87 MOCK_CONST_METHOD0(GetWebContents, WebContents*());
88 MOCK_CONST_METHOD0(GetDownloadManager, DownloadManager*());
89 MOCK_CONST_METHOD0(PauseRequest, void());
90 MOCK_CONST_METHOD0(ResumeRequest, void());
91 MOCK_CONST_METHOD0(CancelRequest, void());
92 MOCK_CONST_METHOD0(DebugString, std::string());
95 // Schedules a task to invoke the RenameCompletionCallback with |new_path| on
96 // the UI thread. Should only be used as the action for
97 // MockDownloadFile::Rename as follows:
98 // EXPECT_CALL(download_file, Rename*(_,_))
99 // .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
100 // new_path));
101 ACTION_P2(ScheduleRenameCallback, interrupt_reason, new_path) {
102 BrowserThread::PostTask(
103 BrowserThread::UI, FROM_HERE,
104 base::Bind(arg1, interrupt_reason, new_path));
107 } // namespace
109 class DownloadItemTest : public testing::Test {
110 public:
111 class MockObserver : public DownloadItem::Observer {
112 public:
113 explicit MockObserver(DownloadItem* item)
114 : item_(item),
115 last_state_(item->GetState()),
116 removed_(false),
117 destroyed_(false),
118 updated_(false),
119 interrupt_count_(0),
120 resume_count_(0) {
121 item_->AddObserver(this);
124 virtual ~MockObserver() {
125 if (item_) item_->RemoveObserver(this);
128 virtual void OnDownloadRemoved(DownloadItem* download) OVERRIDE {
129 DVLOG(20) << " " << __FUNCTION__
130 << " download = " << download->DebugString(false);
131 removed_ = true;
134 virtual void OnDownloadUpdated(DownloadItem* download) OVERRIDE {
135 DVLOG(20) << " " << __FUNCTION__
136 << " download = " << download->DebugString(false);
137 updated_ = true;
138 DownloadItem::DownloadState new_state = download->GetState();
139 if (last_state_ == DownloadItem::IN_PROGRESS &&
140 new_state == DownloadItem::INTERRUPTED) {
141 interrupt_count_++;
143 if (last_state_ == DownloadItem::INTERRUPTED &&
144 new_state == DownloadItem::IN_PROGRESS) {
145 resume_count_++;
147 last_state_ = new_state;
150 virtual void OnDownloadOpened(DownloadItem* download) OVERRIDE {
151 DVLOG(20) << " " << __FUNCTION__
152 << " download = " << download->DebugString(false);
155 virtual void OnDownloadDestroyed(DownloadItem* download) OVERRIDE {
156 DVLOG(20) << " " << __FUNCTION__
157 << " download = " << download->DebugString(false);
158 destroyed_ = true;
159 item_->RemoveObserver(this);
160 item_ = NULL;
163 bool CheckRemoved() {
164 return removed_;
167 bool CheckDestroyed() {
168 return destroyed_;
171 bool CheckUpdated() {
172 bool was_updated = updated_;
173 updated_ = false;
174 return was_updated;
177 int GetInterruptCount() {
178 return interrupt_count_;
181 int GetResumeCount() {
182 return resume_count_;
185 private:
186 DownloadItem* item_;
187 DownloadItem::DownloadState last_state_;
188 bool removed_;
189 bool destroyed_;
190 bool updated_;
191 int interrupt_count_;
192 int resume_count_;
195 DownloadItemTest()
196 : ui_thread_(BrowserThread::UI, &loop_),
197 file_thread_(BrowserThread::FILE, &loop_),
198 delegate_() {
201 ~DownloadItemTest() {
204 virtual void SetUp() {
207 virtual void TearDown() {
208 ui_thread_.DeprecatedGetThreadObject()->message_loop()->RunUntilIdle();
209 STLDeleteElements(&allocated_downloads_);
210 allocated_downloads_.clear();
213 // This class keeps ownership of the created download item; it will
214 // be torn down at the end of the test unless DestroyDownloadItem is
215 // called.
216 DownloadItemImpl* CreateDownloadItem() {
217 // Normally, the download system takes ownership of info, and is
218 // responsible for deleting it. In these unit tests, however, we
219 // don't call the function that deletes it, so we do so ourselves.
220 scoped_ptr<DownloadCreateInfo> info_;
222 info_.reset(new DownloadCreateInfo());
223 static uint32 next_id = DownloadItem::kInvalidId + 1;
224 info_->save_info = scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo());
225 info_->save_info->prompt_for_save_location = false;
226 info_->url_chain.push_back(GURL());
227 info_->etag = "SomethingToSatisfyResumption";
229 DownloadItemImpl* download =
230 new DownloadItemImpl(
231 &delegate_, next_id++, *(info_.get()), net::BoundNetLog());
232 allocated_downloads_.insert(download);
233 return download;
236 // Add DownloadFile to DownloadItem
237 MockDownloadFile* AddDownloadFileToDownloadItem(
238 DownloadItemImpl* item,
239 DownloadItemImplDelegate::DownloadTargetCallback *callback) {
240 MockDownloadFile* mock_download_file(new StrictMock<MockDownloadFile>);
241 scoped_ptr<DownloadFile> download_file(mock_download_file);
242 EXPECT_CALL(*mock_download_file, Initialize(_));
243 if (callback) {
244 // Save the callback.
245 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _))
246 .WillOnce(SaveArg<1>(callback));
247 } else {
248 // Drop it on the floor.
249 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _));
252 scoped_ptr<DownloadRequestHandleInterface> request_handle(
253 new NiceMock<MockRequestHandle>);
254 item->Start(download_file.Pass(), request_handle.Pass());
255 loop_.RunUntilIdle();
257 // So that we don't have a function writing to a stack variable
258 // lying around if the above failed.
259 mock_delegate()->VerifyAndClearExpectations();
260 EXPECT_CALL(*mock_delegate(), AssertStateConsistent(_))
261 .WillRepeatedly(Return());
262 EXPECT_CALL(*mock_delegate(), ShouldOpenFileBasedOnExtension(_))
263 .WillRepeatedly(Return(false));
264 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(_, _))
265 .WillRepeatedly(Return(true));
267 return mock_download_file;
270 // Perform the intermediate rename for |item|. The target path for the
271 // download will be set to kDummyPath. Returns the MockDownloadFile* that was
272 // added to the DownloadItem.
273 MockDownloadFile* DoIntermediateRename(DownloadItemImpl* item,
274 DownloadDangerType danger_type) {
275 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
276 EXPECT_TRUE(item->GetTargetFilePath().empty());
277 DownloadItemImplDelegate::DownloadTargetCallback callback;
278 MockDownloadFile* download_file =
279 AddDownloadFileToDownloadItem(item, &callback);
280 base::FilePath target_path(kDummyPath);
281 base::FilePath intermediate_path(
282 target_path.InsertBeforeExtensionASCII("x"));
283 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
284 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
285 intermediate_path));
286 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
287 danger_type, intermediate_path);
288 RunAllPendingInMessageLoops();
289 return download_file;
292 // Cleanup a download item (specifically get rid of the DownloadFile on it).
293 // The item must be in the expected state.
294 void CleanupItem(DownloadItemImpl* item,
295 MockDownloadFile* download_file,
296 DownloadItem::DownloadState expected_state) {
297 EXPECT_EQ(expected_state, item->GetState());
299 if (expected_state == DownloadItem::IN_PROGRESS) {
300 EXPECT_CALL(*download_file, Cancel());
301 item->Cancel(true);
302 loop_.RunUntilIdle();
306 // Destroy a previously created download item.
307 void DestroyDownloadItem(DownloadItem* item) {
308 allocated_downloads_.erase(item);
309 delete item;
312 void RunAllPendingInMessageLoops() {
313 loop_.RunUntilIdle();
316 MockDelegate* mock_delegate() {
317 return &delegate_;
320 void OnDownloadFileAcquired(base::FilePath* return_path,
321 const base::FilePath& path) {
322 *return_path = path;
325 private:
326 base::MessageLoopForUI loop_;
327 TestBrowserThread ui_thread_; // UI thread
328 TestBrowserThread file_thread_; // FILE thread
329 StrictMock<MockDelegate> delegate_;
330 std::set<DownloadItem*> allocated_downloads_;
333 // Tests to ensure calls that change a DownloadItem generate an update to
334 // observers.
335 // State changing functions not tested:
336 // void OpenDownload();
337 // void ShowDownloadInShell();
338 // void CompleteDelayedDownload();
339 // set_* mutators
341 TEST_F(DownloadItemTest, NotificationAfterUpdate) {
342 DownloadItemImpl* item = CreateDownloadItem();
343 MockObserver observer(item);
345 item->DestinationUpdate(kDownloadChunkSize, kDownloadSpeed, std::string());
346 ASSERT_TRUE(observer.CheckUpdated());
347 EXPECT_EQ(kDownloadSpeed, item->CurrentSpeed());
350 TEST_F(DownloadItemTest, NotificationAfterCancel) {
351 DownloadItemImpl* user_cancel = CreateDownloadItem();
352 MockDownloadFile* download_file =
353 AddDownloadFileToDownloadItem(user_cancel, NULL);
354 EXPECT_CALL(*download_file, Cancel());
355 MockObserver observer1(user_cancel);
357 user_cancel->Cancel(true);
358 ASSERT_TRUE(observer1.CheckUpdated());
360 DownloadItemImpl* system_cancel = CreateDownloadItem();
361 download_file = AddDownloadFileToDownloadItem(system_cancel, NULL);
362 EXPECT_CALL(*download_file, Cancel());
363 MockObserver observer2(system_cancel);
365 system_cancel->Cancel(false);
366 ASSERT_TRUE(observer2.CheckUpdated());
369 TEST_F(DownloadItemTest, NotificationAfterComplete) {
370 DownloadItemImpl* item = CreateDownloadItem();
371 MockObserver observer(item);
373 item->OnAllDataSaved(DownloadItem::kEmptyFileHash);
374 ASSERT_TRUE(observer.CheckUpdated());
376 item->MarkAsComplete();
377 ASSERT_TRUE(observer.CheckUpdated());
380 TEST_F(DownloadItemTest, NotificationAfterDownloadedFileRemoved) {
381 DownloadItemImpl* item = CreateDownloadItem();
382 MockObserver observer(item);
384 item->OnDownloadedFileRemoved();
385 ASSERT_TRUE(observer.CheckUpdated());
388 TEST_F(DownloadItemTest, NotificationAfterInterrupted) {
389 DownloadItemImpl* item = CreateDownloadItem();
390 MockDownloadFile* download_file =
391 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
392 EXPECT_CALL(*download_file, Cancel());
393 MockObserver observer(item);
395 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_,_))
396 .Times(0);
398 item->DestinationObserverAsWeakPtr()->DestinationError(
399 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
400 ASSERT_TRUE(observer.CheckUpdated());
403 TEST_F(DownloadItemTest, NotificationAfterDestroyed) {
404 DownloadItemImpl* item = CreateDownloadItem();
405 MockObserver observer(item);
407 DestroyDownloadItem(item);
408 ASSERT_TRUE(observer.CheckDestroyed());
411 TEST_F(DownloadItemTest, ContinueAfterInterrupted) {
412 CommandLine::ForCurrentProcess()->AppendSwitch(
413 switches::kEnableDownloadResumption);
415 DownloadItemImpl* item = CreateDownloadItem();
416 MockObserver observer(item);
417 DownloadItemImplDelegate::DownloadTargetCallback callback;
418 MockDownloadFile* download_file =
419 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
421 // Interrupt the download, using a continuable interrupt.
422 EXPECT_CALL(*download_file, FullPath())
423 .WillOnce(Return(base::FilePath()));
424 EXPECT_CALL(*download_file, Detach());
425 item->DestinationObserverAsWeakPtr()->DestinationError(
426 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR);
427 ASSERT_TRUE(observer.CheckUpdated());
428 // Should attempt to auto-resume. Because we don't have a mock WebContents,
429 // ResumeInterruptedDownload() will abort early, with another interrupt,
430 // which will be ignored.
431 ASSERT_EQ(1, observer.GetInterruptCount());
432 ASSERT_EQ(0, observer.GetResumeCount());
433 RunAllPendingInMessageLoops();
435 CleanupItem(item, download_file, DownloadItem::INTERRUPTED);
438 // Same as above, but with a non-continuable interrupt.
439 TEST_F(DownloadItemTest, RestartAfterInterrupted) {
440 CommandLine::ForCurrentProcess()->AppendSwitch(
441 switches::kEnableDownloadResumption);
443 DownloadItemImpl* item = CreateDownloadItem();
444 MockObserver observer(item);
445 DownloadItemImplDelegate::DownloadTargetCallback callback;
446 MockDownloadFile* download_file =
447 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
449 // Interrupt the download, using a restartable interrupt.
450 EXPECT_CALL(*download_file, Cancel());
451 item->DestinationObserverAsWeakPtr()->DestinationError(
452 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
453 ASSERT_TRUE(observer.CheckUpdated());
454 // Should not try to auto-resume.
455 ASSERT_EQ(1, observer.GetInterruptCount());
456 ASSERT_EQ(0, observer.GetResumeCount());
457 RunAllPendingInMessageLoops();
459 CleanupItem(item, download_file, DownloadItem::INTERRUPTED);
462 TEST_F(DownloadItemTest, LimitRestartsAfterInterrupted) {
463 CommandLine::ForCurrentProcess()->AppendSwitch(
464 switches::kEnableDownloadResumption);
466 DownloadItemImpl* item = CreateDownloadItem();
467 base::WeakPtr<DownloadDestinationObserver> as_observer(
468 item->DestinationObserverAsWeakPtr());
469 MockObserver observer(item);
470 MockDownloadFile* mock_download_file(NULL);
471 scoped_ptr<DownloadFile> download_file;
472 MockRequestHandle* mock_request_handle(NULL);
473 scoped_ptr<DownloadRequestHandleInterface> request_handle;
474 DownloadItemImplDelegate::DownloadTargetCallback callback;
476 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _))
477 .WillRepeatedly(SaveArg<1>(&callback));
478 for (int i = 0; i < (DownloadItemImpl::kMaxAutoResumeAttempts + 1); ++i) {
479 DVLOG(20) << "Loop iteration " << i;
481 mock_download_file = new NiceMock<MockDownloadFile>;
482 download_file.reset(mock_download_file);
483 mock_request_handle = new NiceMock<MockRequestHandle>;
484 request_handle.reset(mock_request_handle);
486 ON_CALL(*mock_download_file, FullPath())
487 .WillByDefault(Return(base::FilePath()));
489 // It's too complicated to set up a WebContents instance that would cause
490 // the MockDownloadItemDelegate's ResumeInterruptedDownload() function
491 // to be callled, so we simply verify that GetWebContents() is called.
492 if (i < (DownloadItemImpl::kMaxAutoResumeAttempts - 1)) {
493 EXPECT_CALL(*mock_request_handle, GetWebContents())
494 .WillRepeatedly(Return(static_cast<WebContents*>(NULL)));
497 // Copied key parts of DoIntermediateRename & AddDownloadFileToDownloadItem
498 // to allow for holding onto the request handle.
499 item->Start(download_file.Pass(), request_handle.Pass());
500 RunAllPendingInMessageLoops();
501 if (i == 0) {
502 // Target determination is only done the first time through.
503 base::FilePath target_path(kDummyPath);
504 base::FilePath intermediate_path(
505 target_path.InsertBeforeExtensionASCII("x"));
506 EXPECT_CALL(*mock_download_file, RenameAndUniquify(intermediate_path, _))
507 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
508 intermediate_path));
509 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
510 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
511 RunAllPendingInMessageLoops();
513 ASSERT_EQ(i, observer.GetResumeCount());
515 // Use a continuable interrupt.
516 item->DestinationObserverAsWeakPtr()->DestinationError(
517 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR);
519 ASSERT_EQ(i + 1, observer.GetInterruptCount());
520 ::testing::Mock::VerifyAndClearExpectations(mock_download_file);
523 CleanupItem(item, mock_download_file, DownloadItem::INTERRUPTED);
526 TEST_F(DownloadItemTest, NotificationAfterRemove) {
527 DownloadItemImpl* item = CreateDownloadItem();
528 MockDownloadFile* download_file = AddDownloadFileToDownloadItem(item, NULL);
529 EXPECT_CALL(*download_file, Cancel());
530 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_));
531 MockObserver observer(item);
533 item->Remove();
534 ASSERT_TRUE(observer.CheckUpdated());
535 ASSERT_TRUE(observer.CheckRemoved());
538 TEST_F(DownloadItemTest, NotificationAfterOnContentCheckCompleted) {
539 // Setting to NOT_DANGEROUS does not trigger a notification.
540 DownloadItemImpl* safe_item = CreateDownloadItem();
541 MockObserver safe_observer(safe_item);
543 safe_item->OnAllDataSaved(std::string());
544 EXPECT_TRUE(safe_observer.CheckUpdated());
545 safe_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
546 EXPECT_TRUE(safe_observer.CheckUpdated());
548 // Setting to unsafe url or unsafe file should trigger a notification.
549 DownloadItemImpl* unsafeurl_item =
550 CreateDownloadItem();
551 MockObserver unsafeurl_observer(unsafeurl_item);
553 unsafeurl_item->OnAllDataSaved(std::string());
554 EXPECT_TRUE(unsafeurl_observer.CheckUpdated());
555 unsafeurl_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_DANGEROUS_URL);
556 EXPECT_TRUE(unsafeurl_observer.CheckUpdated());
558 unsafeurl_item->ValidateDangerousDownload();
559 EXPECT_TRUE(unsafeurl_observer.CheckUpdated());
561 DownloadItemImpl* unsafefile_item =
562 CreateDownloadItem();
563 MockObserver unsafefile_observer(unsafefile_item);
565 unsafefile_item->OnAllDataSaved(std::string());
566 EXPECT_TRUE(unsafefile_observer.CheckUpdated());
567 unsafefile_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE);
568 EXPECT_TRUE(unsafefile_observer.CheckUpdated());
570 unsafefile_item->ValidateDangerousDownload();
571 EXPECT_TRUE(unsafefile_observer.CheckUpdated());
574 // DownloadItemImpl::OnDownloadTargetDetermined will schedule a task to run
575 // DownloadFile::Rename(). Once the rename
576 // completes, DownloadItemImpl receives a notification with the new file
577 // name. Check that observers are updated when the new filename is available and
578 // not before.
579 TEST_F(DownloadItemTest, NotificationAfterOnDownloadTargetDetermined) {
580 DownloadItemImpl* item = CreateDownloadItem();
581 DownloadItemImplDelegate::DownloadTargetCallback callback;
582 MockDownloadFile* download_file =
583 AddDownloadFileToDownloadItem(item, &callback);
584 MockObserver observer(item);
585 base::FilePath target_path(kDummyPath);
586 base::FilePath intermediate_path(target_path.InsertBeforeExtensionASCII("x"));
587 base::FilePath new_intermediate_path(
588 target_path.InsertBeforeExtensionASCII("y"));
589 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
590 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
591 new_intermediate_path));
593 // Currently, a notification would be generated if the danger type is anything
594 // other than NOT_DANGEROUS.
595 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
596 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
597 EXPECT_FALSE(observer.CheckUpdated());
598 RunAllPendingInMessageLoops();
599 EXPECT_TRUE(observer.CheckUpdated());
600 EXPECT_EQ(new_intermediate_path, item->GetFullPath());
602 CleanupItem(item, download_file, DownloadItem::IN_PROGRESS);
605 TEST_F(DownloadItemTest, NotificationAfterTogglePause) {
606 DownloadItemImpl* item = CreateDownloadItem();
607 MockObserver observer(item);
608 MockDownloadFile* mock_download_file(new MockDownloadFile);
609 scoped_ptr<DownloadFile> download_file(mock_download_file);
610 scoped_ptr<DownloadRequestHandleInterface> request_handle(
611 new NiceMock<MockRequestHandle>);
613 EXPECT_CALL(*mock_download_file, Initialize(_));
614 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _));
615 item->Start(download_file.Pass(), request_handle.Pass());
617 item->Pause();
618 ASSERT_TRUE(observer.CheckUpdated());
620 ASSERT_TRUE(item->IsPaused());
622 item->Resume();
623 ASSERT_TRUE(observer.CheckUpdated());
625 RunAllPendingInMessageLoops();
627 CleanupItem(item, mock_download_file, DownloadItem::IN_PROGRESS);
630 TEST_F(DownloadItemTest, DisplayName) {
631 DownloadItemImpl* item = CreateDownloadItem();
632 DownloadItemImplDelegate::DownloadTargetCallback callback;
633 MockDownloadFile* download_file =
634 AddDownloadFileToDownloadItem(item, &callback);
635 base::FilePath target_path(base::FilePath(kDummyPath).AppendASCII("foo.bar"));
636 base::FilePath intermediate_path(target_path.InsertBeforeExtensionASCII("x"));
637 EXPECT_EQ(FILE_PATH_LITERAL(""),
638 item->GetFileNameToReportUser().value());
639 EXPECT_CALL(*download_file, RenameAndUniquify(_, _))
640 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
641 intermediate_path));
642 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
643 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
644 RunAllPendingInMessageLoops();
645 EXPECT_EQ(FILE_PATH_LITERAL("foo.bar"),
646 item->GetFileNameToReportUser().value());
647 item->SetDisplayName(base::FilePath(FILE_PATH_LITERAL("new.name")));
648 EXPECT_EQ(FILE_PATH_LITERAL("new.name"),
649 item->GetFileNameToReportUser().value());
650 CleanupItem(item, download_file, DownloadItem::IN_PROGRESS);
653 // Test to make sure that Start method calls DF initialize properly.
654 TEST_F(DownloadItemTest, Start) {
655 MockDownloadFile* mock_download_file(new MockDownloadFile);
656 scoped_ptr<DownloadFile> download_file(mock_download_file);
657 DownloadItemImpl* item = CreateDownloadItem();
658 EXPECT_CALL(*mock_download_file, Initialize(_));
659 scoped_ptr<DownloadRequestHandleInterface> request_handle(
660 new NiceMock<MockRequestHandle>);
661 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _));
662 item->Start(download_file.Pass(), request_handle.Pass());
663 RunAllPendingInMessageLoops();
665 CleanupItem(item, mock_download_file, DownloadItem::IN_PROGRESS);
668 // Test that the delegate is invoked after the download file is renamed.
669 TEST_F(DownloadItemTest, CallbackAfterRename) {
670 DownloadItemImpl* item = CreateDownloadItem();
671 DownloadItemImplDelegate::DownloadTargetCallback callback;
672 MockDownloadFile* download_file =
673 AddDownloadFileToDownloadItem(item, &callback);
674 base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar"));
675 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x"));
676 base::FilePath new_intermediate_path(
677 final_path.InsertBeforeExtensionASCII("y"));
678 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
679 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
680 new_intermediate_path));
682 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
683 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
684 RunAllPendingInMessageLoops();
685 // All the callbacks should have happened by now.
686 ::testing::Mock::VerifyAndClearExpectations(download_file);
687 mock_delegate()->VerifyAndClearExpectations();
689 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
690 .WillOnce(Return(true));
691 EXPECT_CALL(*download_file, RenameAndAnnotate(final_path, _))
692 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
693 final_path));
694 EXPECT_CALL(*download_file, FullPath())
695 .WillOnce(Return(base::FilePath()));
696 EXPECT_CALL(*download_file, Detach());
697 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
698 RunAllPendingInMessageLoops();
699 ::testing::Mock::VerifyAndClearExpectations(download_file);
700 mock_delegate()->VerifyAndClearExpectations();
703 // Test that the delegate is invoked after the download file is renamed and the
704 // download item is in an interrupted state.
705 TEST_F(DownloadItemTest, CallbackAfterInterruptedRename) {
706 DownloadItemImpl* item = CreateDownloadItem();
707 DownloadItemImplDelegate::DownloadTargetCallback callback;
708 MockDownloadFile* download_file =
709 AddDownloadFileToDownloadItem(item, &callback);
710 base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar"));
711 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x"));
712 base::FilePath new_intermediate_path(
713 final_path.InsertBeforeExtensionASCII("y"));
714 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
715 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED,
716 new_intermediate_path));
717 EXPECT_CALL(*download_file, Cancel())
718 .Times(1);
720 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
721 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
722 RunAllPendingInMessageLoops();
723 // All the callbacks should have happened by now.
724 ::testing::Mock::VerifyAndClearExpectations(download_file);
725 mock_delegate()->VerifyAndClearExpectations();
728 TEST_F(DownloadItemTest, Interrupted) {
729 DownloadItemImpl* item = CreateDownloadItem();
730 MockDownloadFile* download_file =
731 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
733 const DownloadInterruptReason reason(
734 DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED);
736 // Confirm interrupt sets state properly.
737 EXPECT_CALL(*download_file, Cancel());
738 item->DestinationObserverAsWeakPtr()->DestinationError(reason);
739 RunAllPendingInMessageLoops();
740 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
741 EXPECT_EQ(reason, item->GetLastReason());
743 // Cancel should kill it.
744 item->Cancel(true);
745 EXPECT_EQ(DownloadItem::CANCELLED, item->GetState());
746 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_USER_CANCELED, item->GetLastReason());
749 // Destination errors that occur before the intermediate rename shouldn't cause
750 // the download to be marked as interrupted until after the intermediate rename.
751 TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Restart) {
752 DownloadItemImpl* item = CreateDownloadItem();
753 DownloadItemImplDelegate::DownloadTargetCallback callback;
754 MockDownloadFile* download_file =
755 AddDownloadFileToDownloadItem(item, &callback);
756 item->DestinationObserverAsWeakPtr()->DestinationError(
757 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
758 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
760 base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar"));
761 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x"));
762 base::FilePath new_intermediate_path(
763 final_path.InsertBeforeExtensionASCII("y"));
764 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
765 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
766 new_intermediate_path));
767 EXPECT_CALL(*download_file, Cancel())
768 .Times(1);
770 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
771 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
772 RunAllPendingInMessageLoops();
773 // All the callbacks should have happened by now.
774 ::testing::Mock::VerifyAndClearExpectations(download_file);
775 mock_delegate()->VerifyAndClearExpectations();
776 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
777 EXPECT_TRUE(item->GetFullPath().empty());
778 EXPECT_EQ(final_path, item->GetTargetFilePath());
781 // As above. But if the download can be resumed by continuing, then the
782 // intermediate path should be retained when the download is interrupted after
783 // the intermediate rename succeeds.
784 TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Continue) {
785 CommandLine::ForCurrentProcess()->AppendSwitch(
786 switches::kEnableDownloadResumption);
787 DownloadItemImpl* item = CreateDownloadItem();
788 DownloadItemImplDelegate::DownloadTargetCallback callback;
789 MockDownloadFile* download_file =
790 AddDownloadFileToDownloadItem(item, &callback);
791 item->DestinationObserverAsWeakPtr()->DestinationError(
792 DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED);
793 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
795 base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar"));
796 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x"));
797 base::FilePath new_intermediate_path(
798 final_path.InsertBeforeExtensionASCII("y"));
799 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
800 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
801 new_intermediate_path));
802 EXPECT_CALL(*download_file, FullPath())
803 .WillOnce(Return(base::FilePath(new_intermediate_path)));
804 EXPECT_CALL(*download_file, Detach());
806 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
807 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
808 RunAllPendingInMessageLoops();
809 // All the callbacks should have happened by now.
810 ::testing::Mock::VerifyAndClearExpectations(download_file);
811 mock_delegate()->VerifyAndClearExpectations();
812 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
813 EXPECT_EQ(new_intermediate_path, item->GetFullPath());
814 EXPECT_EQ(final_path, item->GetTargetFilePath());
817 // As above. If the intermediate rename fails, then the interrupt reason should
818 // be set to the destination error and the intermediate path should be empty.
819 TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Failed) {
820 CommandLine::ForCurrentProcess()->AppendSwitch(
821 switches::kEnableDownloadResumption);
822 DownloadItemImpl* item = CreateDownloadItem();
823 DownloadItemImplDelegate::DownloadTargetCallback callback;
824 MockDownloadFile* download_file =
825 AddDownloadFileToDownloadItem(item, &callback);
826 item->DestinationObserverAsWeakPtr()->DestinationError(
827 DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED);
828 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
830 base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar"));
831 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x"));
832 base::FilePath new_intermediate_path(
833 final_path.InsertBeforeExtensionASCII("y"));
834 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
835 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED,
836 new_intermediate_path));
837 EXPECT_CALL(*download_file, Cancel())
838 .Times(1);
840 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
841 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
842 RunAllPendingInMessageLoops();
843 // All the callbacks should have happened by now.
844 ::testing::Mock::VerifyAndClearExpectations(download_file);
845 mock_delegate()->VerifyAndClearExpectations();
846 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
847 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, item->GetLastReason());
848 EXPECT_TRUE(item->GetFullPath().empty());
849 EXPECT_EQ(final_path, item->GetTargetFilePath());
852 TEST_F(DownloadItemTest, Canceled) {
853 DownloadItemImpl* item = CreateDownloadItem();
854 MockDownloadFile* download_file = AddDownloadFileToDownloadItem(item, NULL);
856 // Confirm cancel sets state properly.
857 EXPECT_CALL(*download_file, Cancel());
858 item->Cancel(true);
859 EXPECT_EQ(DownloadItem::CANCELLED, item->GetState());
862 TEST_F(DownloadItemTest, FileRemoved) {
863 DownloadItemImpl* item = CreateDownloadItem();
865 EXPECT_FALSE(item->GetFileExternallyRemoved());
866 item->OnDownloadedFileRemoved();
867 EXPECT_TRUE(item->GetFileExternallyRemoved());
870 TEST_F(DownloadItemTest, DestinationUpdate) {
871 DownloadItemImpl* item = CreateDownloadItem();
872 base::WeakPtr<DownloadDestinationObserver> as_observer(
873 item->DestinationObserverAsWeakPtr());
874 MockObserver observer(item);
876 EXPECT_EQ(0l, item->CurrentSpeed());
877 EXPECT_EQ("", item->GetHashState());
878 EXPECT_EQ(0l, item->GetReceivedBytes());
879 EXPECT_EQ(0l, item->GetTotalBytes());
880 EXPECT_FALSE(observer.CheckUpdated());
881 item->SetTotalBytes(100l);
882 EXPECT_EQ(100l, item->GetTotalBytes());
884 as_observer->DestinationUpdate(10, 20, "deadbeef");
885 EXPECT_EQ(20l, item->CurrentSpeed());
886 EXPECT_EQ("deadbeef", item->GetHashState());
887 EXPECT_EQ(10l, item->GetReceivedBytes());
888 EXPECT_EQ(100l, item->GetTotalBytes());
889 EXPECT_TRUE(observer.CheckUpdated());
891 as_observer->DestinationUpdate(200, 20, "livebeef");
892 EXPECT_EQ(20l, item->CurrentSpeed());
893 EXPECT_EQ("livebeef", item->GetHashState());
894 EXPECT_EQ(200l, item->GetReceivedBytes());
895 EXPECT_EQ(0l, item->GetTotalBytes());
896 EXPECT_TRUE(observer.CheckUpdated());
899 TEST_F(DownloadItemTest, DestinationError) {
900 DownloadItemImpl* item = CreateDownloadItem();
901 MockDownloadFile* download_file =
902 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
903 base::WeakPtr<DownloadDestinationObserver> as_observer(
904 item->DestinationObserverAsWeakPtr());
905 MockObserver observer(item);
907 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
908 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, item->GetLastReason());
909 EXPECT_FALSE(observer.CheckUpdated());
911 EXPECT_CALL(*download_file, Cancel());
912 as_observer->DestinationError(
913 DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED);
914 mock_delegate()->VerifyAndClearExpectations();
915 EXPECT_TRUE(observer.CheckUpdated());
916 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
917 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED,
918 item->GetLastReason());
921 TEST_F(DownloadItemTest, DestinationCompleted) {
922 DownloadItemImpl* item = CreateDownloadItem();
923 base::WeakPtr<DownloadDestinationObserver> as_observer(
924 item->DestinationObserverAsWeakPtr());
925 MockObserver observer(item);
927 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
928 EXPECT_EQ("", item->GetHash());
929 EXPECT_EQ("", item->GetHashState());
930 EXPECT_FALSE(item->AllDataSaved());
931 EXPECT_FALSE(observer.CheckUpdated());
933 as_observer->DestinationUpdate(10, 20, "deadbeef");
934 EXPECT_TRUE(observer.CheckUpdated());
935 EXPECT_FALSE(observer.CheckUpdated()); // Confirm reset.
936 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
937 EXPECT_EQ("", item->GetHash());
938 EXPECT_EQ("deadbeef", item->GetHashState());
939 EXPECT_FALSE(item->AllDataSaved());
941 as_observer->DestinationCompleted("livebeef");
942 mock_delegate()->VerifyAndClearExpectations();
943 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
944 EXPECT_TRUE(observer.CheckUpdated());
945 EXPECT_EQ("livebeef", item->GetHash());
946 EXPECT_EQ("", item->GetHashState());
947 EXPECT_TRUE(item->AllDataSaved());
950 TEST_F(DownloadItemTest, EnabledActionsForNormalDownload) {
951 DownloadItemImpl* item = CreateDownloadItem();
952 MockDownloadFile* download_file =
953 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
955 // InProgress
956 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
957 ASSERT_FALSE(item->GetTargetFilePath().empty());
958 EXPECT_TRUE(item->CanShowInFolder());
959 EXPECT_TRUE(item->CanOpenDownload());
961 // Complete
962 EXPECT_CALL(*download_file, RenameAndAnnotate(_, _))
963 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
964 base::FilePath(kDummyPath)));
965 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
966 .WillOnce(Return(true));
967 EXPECT_CALL(*download_file, FullPath())
968 .WillOnce(Return(base::FilePath()));
969 EXPECT_CALL(*download_file, Detach());
970 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
971 RunAllPendingInMessageLoops();
973 ASSERT_EQ(DownloadItem::COMPLETE, item->GetState());
974 EXPECT_TRUE(item->CanShowInFolder());
975 EXPECT_TRUE(item->CanOpenDownload());
978 TEST_F(DownloadItemTest, EnabledActionsForTemporaryDownload) {
979 DownloadItemImpl* item = CreateDownloadItem();
980 MockDownloadFile* download_file =
981 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
982 item->SetIsTemporary(true);
984 // InProgress Temporary
985 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
986 ASSERT_FALSE(item->GetTargetFilePath().empty());
987 ASSERT_TRUE(item->IsTemporary());
988 EXPECT_FALSE(item->CanShowInFolder());
989 EXPECT_FALSE(item->CanOpenDownload());
991 // Complete Temporary
992 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
993 .WillOnce(Return(true));
994 EXPECT_CALL(*download_file, RenameAndAnnotate(_, _))
995 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
996 base::FilePath(kDummyPath)));
997 EXPECT_CALL(*download_file, FullPath())
998 .WillOnce(Return(base::FilePath()));
999 EXPECT_CALL(*download_file, Detach());
1000 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
1001 RunAllPendingInMessageLoops();
1003 ASSERT_EQ(DownloadItem::COMPLETE, item->GetState());
1004 EXPECT_FALSE(item->CanShowInFolder());
1005 EXPECT_FALSE(item->CanOpenDownload());
1008 TEST_F(DownloadItemTest, EnabledActionsForInterruptedDownload) {
1009 DownloadItemImpl* item = CreateDownloadItem();
1010 MockDownloadFile* download_file =
1011 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
1013 EXPECT_CALL(*download_file, Cancel());
1014 item->DestinationObserverAsWeakPtr()->DestinationError(
1015 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
1016 RunAllPendingInMessageLoops();
1018 ASSERT_EQ(DownloadItem::INTERRUPTED, item->GetState());
1019 ASSERT_FALSE(item->GetTargetFilePath().empty());
1020 EXPECT_FALSE(item->CanShowInFolder());
1021 EXPECT_FALSE(item->CanOpenDownload());
1024 TEST_F(DownloadItemTest, EnabledActionsForCancelledDownload) {
1025 DownloadItemImpl* item = CreateDownloadItem();
1026 MockDownloadFile* download_file =
1027 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
1029 EXPECT_CALL(*download_file, Cancel());
1030 item->Cancel(true);
1031 RunAllPendingInMessageLoops();
1033 ASSERT_EQ(DownloadItem::CANCELLED, item->GetState());
1034 EXPECT_FALSE(item->CanShowInFolder());
1035 EXPECT_FALSE(item->CanOpenDownload());
1038 // Test various aspects of the delegate completion blocker.
1040 // Just allowing completion.
1041 TEST_F(DownloadItemTest, CompleteDelegate_ReturnTrue) {
1042 // Test to confirm that if we have a callback that returns true,
1043 // we complete immediately.
1044 DownloadItemImpl* item = CreateDownloadItem();
1045 MockDownloadFile* download_file =
1046 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
1048 // Drive the delegate interaction.
1049 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
1050 .WillOnce(Return(true));
1051 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
1052 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
1053 EXPECT_FALSE(item->IsDangerous());
1055 // Make sure the download can complete.
1056 EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyPath), _))
1057 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
1058 base::FilePath(kDummyPath)));
1059 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _))
1060 .WillOnce(Return(true));
1061 EXPECT_CALL(*download_file, FullPath())
1062 .WillOnce(Return(base::FilePath()));
1063 EXPECT_CALL(*download_file, Detach());
1064 RunAllPendingInMessageLoops();
1065 EXPECT_EQ(DownloadItem::COMPLETE, item->GetState());
1068 // Just delaying completion.
1069 TEST_F(DownloadItemTest, CompleteDelegate_BlockOnce) {
1070 // Test to confirm that if we have a callback that returns true,
1071 // we complete immediately.
1072 DownloadItemImpl* item = CreateDownloadItem();
1073 MockDownloadFile* download_file =
1074 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
1076 // Drive the delegate interaction.
1077 base::Closure delegate_callback;
1078 base::Closure copy_delegate_callback;
1079 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
1080 .WillOnce(DoAll(SaveArg<1>(&delegate_callback),
1081 Return(false)))
1082 .WillOnce(Return(true));
1083 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
1084 ASSERT_FALSE(delegate_callback.is_null());
1085 copy_delegate_callback = delegate_callback;
1086 delegate_callback.Reset();
1087 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
1088 copy_delegate_callback.Run();
1089 ASSERT_TRUE(delegate_callback.is_null());
1090 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
1091 EXPECT_FALSE(item->IsDangerous());
1093 // Make sure the download can complete.
1094 EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyPath), _))
1095 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
1096 base::FilePath(kDummyPath)));
1097 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _))
1098 .WillOnce(Return(true));
1099 EXPECT_CALL(*download_file, FullPath())
1100 .WillOnce(Return(base::FilePath()));
1101 EXPECT_CALL(*download_file, Detach());
1102 RunAllPendingInMessageLoops();
1103 EXPECT_EQ(DownloadItem::COMPLETE, item->GetState());
1106 // Delay and set danger.
1107 TEST_F(DownloadItemTest, CompleteDelegate_SetDanger) {
1108 // Test to confirm that if we have a callback that returns true,
1109 // we complete immediately.
1110 DownloadItemImpl* item = CreateDownloadItem();
1111 MockDownloadFile* download_file =
1112 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
1114 // Drive the delegate interaction.
1115 base::Closure delegate_callback;
1116 base::Closure copy_delegate_callback;
1117 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
1118 .WillOnce(DoAll(SaveArg<1>(&delegate_callback),
1119 Return(false)))
1120 .WillOnce(Return(true));
1121 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
1122 ASSERT_FALSE(delegate_callback.is_null());
1123 copy_delegate_callback = delegate_callback;
1124 delegate_callback.Reset();
1125 EXPECT_FALSE(item->IsDangerous());
1126 item->OnContentCheckCompleted(
1127 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE);
1128 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
1129 copy_delegate_callback.Run();
1130 ASSERT_TRUE(delegate_callback.is_null());
1131 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
1132 EXPECT_TRUE(item->IsDangerous());
1134 // Make sure the download doesn't complete until we've validated it.
1135 EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyPath), _))
1136 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
1137 base::FilePath(kDummyPath)));
1138 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _))
1139 .WillOnce(Return(true));
1140 EXPECT_CALL(*download_file, FullPath())
1141 .WillOnce(Return(base::FilePath()));
1142 EXPECT_CALL(*download_file, Detach());
1143 RunAllPendingInMessageLoops();
1144 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
1145 EXPECT_TRUE(item->IsDangerous());
1147 item->ValidateDangerousDownload();
1148 EXPECT_EQ(DOWNLOAD_DANGER_TYPE_USER_VALIDATED, item->GetDangerType());
1149 RunAllPendingInMessageLoops();
1150 EXPECT_EQ(DownloadItem::COMPLETE, item->GetState());
1153 // Just delaying completion twice.
1154 TEST_F(DownloadItemTest, CompleteDelegate_BlockTwice) {
1155 // Test to confirm that if we have a callback that returns true,
1156 // we complete immediately.
1157 DownloadItemImpl* item = CreateDownloadItem();
1158 MockDownloadFile* download_file =
1159 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
1161 // Drive the delegate interaction.
1162 base::Closure delegate_callback;
1163 base::Closure copy_delegate_callback;
1164 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
1165 .WillOnce(DoAll(SaveArg<1>(&delegate_callback),
1166 Return(false)))
1167 .WillOnce(DoAll(SaveArg<1>(&delegate_callback),
1168 Return(false)))
1169 .WillOnce(Return(true));
1170 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
1171 ASSERT_FALSE(delegate_callback.is_null());
1172 copy_delegate_callback = delegate_callback;
1173 delegate_callback.Reset();
1174 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
1175 copy_delegate_callback.Run();
1176 ASSERT_FALSE(delegate_callback.is_null());
1177 copy_delegate_callback = delegate_callback;
1178 delegate_callback.Reset();
1179 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
1180 copy_delegate_callback.Run();
1181 ASSERT_TRUE(delegate_callback.is_null());
1182 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
1183 EXPECT_FALSE(item->IsDangerous());
1185 // Make sure the download can complete.
1186 EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyPath), _))
1187 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
1188 base::FilePath(kDummyPath)));
1189 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _))
1190 .WillOnce(Return(true));
1191 EXPECT_CALL(*download_file, FullPath())
1192 .WillOnce(Return(base::FilePath()));
1193 EXPECT_CALL(*download_file, Detach());
1194 RunAllPendingInMessageLoops();
1195 EXPECT_EQ(DownloadItem::COMPLETE, item->GetState());
1198 TEST_F(DownloadItemTest, StealDangerousDownload) {
1199 DownloadItemImpl* item = CreateDownloadItem();
1200 MockDownloadFile* download_file =
1201 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE);
1202 ASSERT_TRUE(item->IsDangerous());
1203 base::FilePath full_path(FILE_PATH_LITERAL("foo.txt"));
1204 base::FilePath returned_path;
1206 EXPECT_CALL(*download_file, FullPath())
1207 .WillOnce(Return(full_path));
1208 EXPECT_CALL(*download_file, Detach());
1209 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_));
1210 base::WeakPtrFactory<DownloadItemTest> weak_ptr_factory(this);
1211 item->StealDangerousDownload(
1212 base::Bind(&DownloadItemTest::OnDownloadFileAcquired,
1213 weak_ptr_factory.GetWeakPtr(),
1214 base::Unretained(&returned_path)));
1215 RunAllPendingInMessageLoops();
1216 EXPECT_EQ(full_path, returned_path);
1219 TEST_F(DownloadItemTest, StealInterruptedDangerousDownload) {
1220 CommandLine::ForCurrentProcess()->AppendSwitch(
1221 switches::kEnableDownloadResumption);
1222 base::FilePath returned_path;
1223 DownloadItemImpl* item = CreateDownloadItem();
1224 MockDownloadFile* download_file =
1225 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE);
1226 base::FilePath full_path = item->GetFullPath();
1227 EXPECT_FALSE(full_path.empty());
1228 EXPECT_CALL(*download_file, FullPath())
1229 .WillOnce(Return(full_path));
1230 EXPECT_CALL(*download_file, Detach());
1231 item->DestinationObserverAsWeakPtr()->DestinationError(
1232 DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED);
1233 ASSERT_TRUE(item->IsDangerous());
1235 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_));
1236 base::WeakPtrFactory<DownloadItemTest> weak_ptr_factory(this);
1237 item->StealDangerousDownload(
1238 base::Bind(&DownloadItemTest::OnDownloadFileAcquired,
1239 weak_ptr_factory.GetWeakPtr(),
1240 base::Unretained(&returned_path)));
1241 RunAllPendingInMessageLoops();
1242 EXPECT_EQ(full_path, returned_path);
1245 TEST_F(DownloadItemTest, StealInterruptedNonResumableDangerousDownload) {
1246 CommandLine::ForCurrentProcess()->AppendSwitch(
1247 switches::kEnableDownloadResumption);
1248 base::FilePath returned_path;
1249 DownloadItemImpl* item = CreateDownloadItem();
1250 MockDownloadFile* download_file =
1251 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE);
1252 EXPECT_CALL(*download_file, Cancel());
1253 item->DestinationObserverAsWeakPtr()->DestinationError(
1254 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
1255 ASSERT_TRUE(item->IsDangerous());
1257 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_));
1258 base::WeakPtrFactory<DownloadItemTest> weak_ptr_factory(this);
1259 item->StealDangerousDownload(
1260 base::Bind(&DownloadItemTest::OnDownloadFileAcquired,
1261 weak_ptr_factory.GetWeakPtr(),
1262 base::Unretained(&returned_path)));
1263 RunAllPendingInMessageLoops();
1264 EXPECT_TRUE(returned_path.empty());
1267 TEST(MockDownloadItem, Compiles) {
1268 MockDownloadItem mock_item;
1271 } // namespace content