// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/download/download_item_impl.h"

#include <stdint.h>

#include <iterator>
#include <queue>
#include <utility>

#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"
#include "content/browser/download/download_create_info.h"
#include "content/browser/download/download_file_factory.h"
#include "content/browser/download/download_item_impl_delegate.h"
#include "content/browser/download/download_request_handle.h"
#include "content/browser/download/mock_download_file.h"
#include "content/public/browser/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/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_bundle.h"
#include "content/public/test/web_contents_tester.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::DoAll;
using ::testing::NiceMock;
using ::testing::Property;
using ::testing::Return;
using ::testing::SaveArg;
using ::testing::StrictMock;
using ::testing::WithArg;
using ::testing::_;

const int kDownloadChunkSize = 1000;
const int kDownloadSpeed = 1000;
const base::FilePath::CharType kDummyTargetPath[] =
    FILE_PATH_LITERAL("/testpath");
const base::FilePath::CharType kDummyIntermediatePath[] =
    FILE_PATH_LITERAL("/testpathx");

namespace content {

namespace {

class MockDelegate : public DownloadItemImplDelegate {
 public:
  MockDelegate() : DownloadItemImplDelegate() {
    SetDefaultExpectations();
  }

  MOCK_METHOD2(DetermineDownloadTarget, void(
      DownloadItemImpl*, const DownloadTargetCallback&));
  MOCK_METHOD2(ShouldCompleteDownload,
               bool(DownloadItemImpl*, const base::Closure&));
  MOCK_METHOD2(ShouldOpenDownload,
               bool(DownloadItemImpl*, const ShouldOpenDownloadCallback&));
  MOCK_METHOD1(ShouldOpenFileBasedOnExtension, bool(const base::FilePath&));
  MOCK_METHOD1(CheckForFileRemoval, void(DownloadItemImpl*));

  void ResumeInterruptedDownload(scoped_ptr<DownloadUrlParameters> params,
                                 uint32_t id) override {
    MockResumeInterruptedDownload(params.get(), id);
  }
  MOCK_METHOD2(MockResumeInterruptedDownload,
               void(DownloadUrlParameters* params, uint32_t id));

  MOCK_CONST_METHOD0(GetBrowserContext, BrowserContext*());
  MOCK_METHOD1(DownloadOpened, void(DownloadItemImpl*));
  MOCK_METHOD1(DownloadRemoved, void(DownloadItemImpl*));
  MOCK_CONST_METHOD1(AssertStateConsistent, void(DownloadItemImpl*));

  void VerifyAndClearExpectations() {
    ::testing::Mock::VerifyAndClearExpectations(this);
    SetDefaultExpectations();
  }

 private:
  void SetDefaultExpectations() {
    EXPECT_CALL(*this, AssertStateConsistent(_))
        .WillRepeatedly(Return());
    EXPECT_CALL(*this, ShouldOpenFileBasedOnExtension(_))
        .WillRepeatedly(Return(false));
    EXPECT_CALL(*this, ShouldOpenDownload(_, _))
        .WillRepeatedly(Return(true));
  }
};

class MockRequestHandle : public DownloadRequestHandleInterface {
 public:
  MOCK_CONST_METHOD0(GetWebContents, WebContents*());
  MOCK_CONST_METHOD0(GetDownloadManager, DownloadManager*());
  MOCK_CONST_METHOD0(PauseRequest, void());
  MOCK_CONST_METHOD0(ResumeRequest, void());
  MOCK_CONST_METHOD0(CancelRequest, void());
  MOCK_CONST_METHOD0(DebugString, std::string());
};

class TestDownloadItemObserver : public DownloadItem::Observer {
 public:
  explicit TestDownloadItemObserver(DownloadItem* item)
      : item_(item),
        last_state_(item->GetState()),
        removed_(false),
        destroyed_(false),
        updated_(false),
        interrupt_count_(0),
        resume_count_(0) {
    item_->AddObserver(this);
  }

  ~TestDownloadItemObserver() override {
    if (item_)
      item_->RemoveObserver(this);
  }

  bool download_removed() const { return removed_; }
  bool download_destroyed() const { return destroyed_; }
  int interrupt_count() const { return interrupt_count_; }
  int resume_count() const { return resume_count_; }

  bool CheckAndResetDownloadUpdated() {
    bool was_updated = updated_;
    updated_ = false;
    return was_updated;
  }

 private:
  void OnDownloadRemoved(DownloadItem* download) override {
    SCOPED_TRACE(::testing::Message() << " " << __FUNCTION__ << " download = "
                                      << download->DebugString(false));
    removed_ = true;
  }

  void OnDownloadUpdated(DownloadItem* download) override {
    DVLOG(20) << " " << __FUNCTION__
              << " download = " << download->DebugString(false);
    updated_ = true;
    DownloadItem::DownloadState new_state = download->GetState();
    if (last_state_ == DownloadItem::IN_PROGRESS &&
        new_state == DownloadItem::INTERRUPTED) {
      interrupt_count_++;
    }
    if (last_state_ == DownloadItem::INTERRUPTED &&
        new_state == DownloadItem::IN_PROGRESS) {
      resume_count_++;
    }
    last_state_ = new_state;
  }

  void OnDownloadOpened(DownloadItem* download) override {
    DVLOG(20) << " " << __FUNCTION__
              << " download = " << download->DebugString(false);
  }

  void OnDownloadDestroyed(DownloadItem* download) override {
    DVLOG(20) << " " << __FUNCTION__
              << " download = " << download->DebugString(false);
    destroyed_ = true;
    item_->RemoveObserver(this);
    item_ = nullptr;
  }

  DownloadItem* item_;
  DownloadItem::DownloadState last_state_;
  bool removed_;
  bool destroyed_;
  bool updated_;
  int interrupt_count_;
  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));
}

// Schedules a task to invoke a callback that's bound to the specified
// parameter.
// E.g.:
//
//   EXPECT_CALL(foo, Bar(1, _))
//     .WithArg<1>(ScheduleCallbackWithParam(0));
//
//   .. will invoke the second argument to Bar with 0 as the parameter.
ACTION_P(ScheduleCallbackWithParam, param) {
  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
                          base::Bind(arg0, param));
}

ACTION_P(ScheduleClosure, closure) {
  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, closure);
}

}  // namespace

class DownloadItemTest : public testing::Test {
 public:
  DownloadItemTest()
      : delegate_(), next_download_id_(DownloadItem::kInvalidId + 1) {
    base::FeatureList::ClearInstanceForTesting();
    scoped_ptr<base::FeatureList> feature_list(new base::FeatureList);
    feature_list->InitializeFromCommandLine(features::kDownloadResumption.name,
                                            std::string());
    base::FeatureList::SetInstance(std::move(feature_list));

    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("http://example.com/download"));
    create_info_->etag = "SomethingToSatisfyResumption";
  }

  ~DownloadItemTest() {
    RunAllPendingInMessageLoops();
    STLDeleteElements(&allocated_downloads_);
  }

  DownloadItemImpl* CreateDownloadItemWithCreateInfo(
      scoped_ptr<DownloadCreateInfo> info) {
    DownloadItemImpl* download = new DownloadItemImpl(
        &delegate_, next_download_id_++, *(info.get()), net::BoundNetLog());
    allocated_downloads_.insert(download);
    return download;
  }

  // This class keeps ownership of the created download item; it will
  // be torn down at the end of the test unless DestroyDownloadItem is
  // called.
  DownloadItemImpl* CreateDownloadItem() {
    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;
  }

  // Add DownloadFile to DownloadItem. Set |callback| to nullptr if a download
  // target determination is not expected.
  MockDownloadFile* CallDownloadItemStart(
      DownloadItemImpl* item,
      DownloadItemImplDelegate::DownloadTargetCallback* callback) {
    MockDownloadFile* mock_download_file = nullptr;
    scoped_ptr<DownloadFile> download_file;
    if (callback) {
      EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _))
          .WillOnce(SaveArg<1>(callback));
    } else {
      EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)).Times(0);
    }

    // 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(ScheduleCallbackWithParam(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),
                *create_info_);
    RunAllPendingInMessageLoops();

    // So that we don't have a function writing to a stack variable
    // lying around if the above failed.
    mock_delegate()->VerifyAndClearExpectations();
    EXPECT_CALL(*mock_delegate(), AssertStateConsistent(_))
        .WillRepeatedly(Return());
    EXPECT_CALL(*mock_delegate(), ShouldOpenFileBasedOnExtension(_))
        .WillRepeatedly(Return(false));
    EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(_, _))
        .WillRepeatedly(Return(true));

    return mock_download_file;
  }

  // Perform the intermediate rename for |item|. The target path for the
  // download will be set to kDummyTargetPath. Returns the MockDownloadFile*
  // that was added to the DownloadItem.
  MockDownloadFile* DoIntermediateRename(DownloadItemImpl* item,
                                         DownloadDangerType danger_type) {
    EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
    EXPECT_TRUE(item->GetTargetFilePath().empty());
    DownloadItemImplDelegate::DownloadTargetCallback callback;
    MockDownloadFile* download_file = CallDownloadItemStart(item, &callback);
    base::FilePath target_path(kDummyTargetPath);
    base::FilePath intermediate_path(kDummyIntermediatePath);
    EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
        .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
                                         intermediate_path));
    callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
                 danger_type, intermediate_path);
    RunAllPendingInMessageLoops();
    return download_file;
  }

  void DoDestinationComplete(DownloadItemImpl* item,
                             MockDownloadFile* download_file) {
    EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(_, _))
        .WillOnce(Return(true));
    base::FilePath final_path(kDummyTargetPath);
    EXPECT_CALL(*download_file, RenameAndAnnotate(_, _))
        .WillOnce(
            ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, final_path));
    EXPECT_CALL(*download_file, FullPath())
        .WillRepeatedly(Return(base::FilePath(kDummyTargetPath)));
    EXPECT_CALL(*download_file, Detach());

    item->DestinationObserverAsWeakPtr()->DestinationCompleted("");
    RunAllPendingInMessageLoops();
  }

  // Cleanup a download item (specifically get rid of the DownloadFile on it).
  // The item must be in the expected state.
  void CleanupItem(DownloadItemImpl* item,
                   MockDownloadFile* download_file,
                   DownloadItem::DownloadState expected_state) {
    EXPECT_EQ(expected_state, item->GetState());

    if (expected_state == DownloadItem::IN_PROGRESS) {
      if (download_file)
        EXPECT_CALL(*download_file, Cancel());
      item->Cancel(true);
      RunAllPendingInMessageLoops();
    }
  }

  // Destroy a previously created download item.
  void DestroyDownloadItem(DownloadItem* item) {
    allocated_downloads_.erase(item);
    delete item;
  }

  void RunAllPendingInMessageLoops() { base::RunLoop().RunUntilIdle(); }

  MockDelegate* mock_delegate() {
    return &delegate_;
  }

  void OnDownloadFileAcquired(base::FilePath* return_path,
                              const base::FilePath& path) {
    *return_path = path;
  }

  DownloadCreateInfo* create_info() { return create_info_.get(); }

  BrowserContext* browser_context() { return &browser_context_; }

 private:
  StrictMock<MockDelegate> delegate_;
  std::set<DownloadItem*> allocated_downloads_;
  scoped_ptr<DownloadCreateInfo> create_info_;
  uint32_t next_download_id_ = DownloadItem::kInvalidId + 1;
  TestBrowserContext browser_context_;
  TestBrowserThreadBundle thread_bundle_;
};

// Tests to ensure calls that change a DownloadItem generate an update to
// observers.
// State changing functions not tested:
//  void OpenDownload();
//  void ShowDownloadInShell();
//  void CompleteDelayedDownload();
//  set_* mutators

TEST_F(DownloadItemTest, NotificationAfterUpdate) {
  DownloadItemImpl* item = CreateDownloadItem();
  MockDownloadFile* file =
      DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
  ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
  TestDownloadItemObserver observer(item);

  item->DestinationUpdate(kDownloadChunkSize, kDownloadSpeed, std::string());
  ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
  EXPECT_EQ(kDownloadSpeed, item->CurrentSpeed());
  CleanupItem(item, file, DownloadItem::IN_PROGRESS);
}

TEST_F(DownloadItemTest, NotificationAfterCancel) {
  DownloadItemImpl* user_cancel = CreateDownloadItem();
  DownloadItemImplDelegate::DownloadTargetCallback target_callback;
  MockDownloadFile* download_file =
      CallDownloadItemStart(user_cancel, &target_callback);
  EXPECT_CALL(*download_file, Cancel());

  TestDownloadItemObserver observer1(user_cancel);
  user_cancel->Cancel(true);
  ASSERT_TRUE(observer1.CheckAndResetDownloadUpdated());

  DownloadItemImpl* system_cancel = CreateDownloadItem();
  download_file = CallDownloadItemStart(system_cancel, &target_callback);
  EXPECT_CALL(*download_file, Cancel());

  TestDownloadItemObserver observer2(system_cancel);
  system_cancel->Cancel(false);
  ASSERT_TRUE(observer2.CheckAndResetDownloadUpdated());
}

TEST_F(DownloadItemTest, NotificationAfterComplete) {
  DownloadItemImpl* item = CreateDownloadItem();
  TestDownloadItemObserver observer(item);
  MockDownloadFile* download_file =
      DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
  ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
  DoDestinationComplete(item, download_file);
  ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
}

TEST_F(DownloadItemTest, NotificationAfterDownloadedFileRemoved) {
  DownloadItemImpl* item = CreateDownloadItem();
  TestDownloadItemObserver observer(item);

  item->OnDownloadedFileRemoved();
  ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
}

TEST_F(DownloadItemTest, NotificationAfterInterrupted) {
  DownloadItemImpl* item = CreateDownloadItem();
  MockDownloadFile* download_file =
      DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
  EXPECT_CALL(*download_file, Cancel());
  TestDownloadItemObserver observer(item);

  EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_,_))
      .Times(0);

  item->DestinationObserverAsWeakPtr()->DestinationError(
      DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
  ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
}

TEST_F(DownloadItemTest, NotificationAfterDestroyed) {
  DownloadItemImpl* item = CreateDownloadItem();
  TestDownloadItemObserver observer(item);

  DestroyDownloadItem(item);
  ASSERT_TRUE(observer.download_destroyed());
}

// Test that a download is resumed automatcially after a continuable interrupt.
TEST_F(DownloadItemTest, ContinueAfterInterrupted) {
  DownloadItemImpl* item = CreateDownloadItem();
  TestDownloadItemObserver observer(item);
  MockDownloadFile* download_file =
      DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);

  // Interrupt the download, using a continuable interrupt.
  EXPECT_CALL(*download_file, FullPath())
      .WillOnce(Return(base::FilePath()));
  EXPECT_CALL(*download_file, Detach());
  EXPECT_CALL(*mock_delegate(), GetBrowserContext())
      .WillRepeatedly(Return(browser_context()));
  EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _)).Times(1);
  item->DestinationObserverAsWeakPtr()->DestinationError(
      DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR);
  ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
  // Since the download is resumed automatically, the interrupt count doesn't
  // increase.
  ASSERT_EQ(0, observer.interrupt_count());

  // Test expectations verify that ResumeInterruptedDownload() is called (by way
  // of MockResumeInterruptedDownload) after the download is interrupted. But
  // the mock doesn't follow through with the resumption.
  // ResumeInterruptedDownload() being called is sufficient for verifying that
  // the automatic resumption was triggered.
  RunAllPendingInMessageLoops();

  // The download item is currently in RESUMING_INTERNAL state, which maps to
  // IN_PROGRESS.
  CleanupItem(item, nullptr, DownloadItem::IN_PROGRESS);
}

// Test that automatic resumption doesn't happen after a non-continuable
// interrupt.
TEST_F(DownloadItemTest, RestartAfterInterrupted) {
  DownloadItemImpl* item = CreateDownloadItem();
  TestDownloadItemObserver observer(item);
  MockDownloadFile* download_file =
      DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);

  // Interrupt the download, using a restartable interrupt.
  EXPECT_CALL(*download_file, Cancel());
  item->DestinationObserverAsWeakPtr()->DestinationError(
      DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
  ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
  // Should not try to auto-resume.
  ASSERT_EQ(1, observer.interrupt_count());
  ASSERT_EQ(0, observer.resume_count());
  RunAllPendingInMessageLoops();

  CleanupItem(item, nullptr, DownloadItem::INTERRUPTED);
}

// Check we do correct cleanup for RESUME_MODE_INVALID interrupts.
TEST_F(DownloadItemTest, UnresumableInterrupt) {
  DownloadItemImpl* item = CreateDownloadItem();
  TestDownloadItemObserver observer(item);
  MockDownloadFile* download_file =
      DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);

  // Fail final rename with unresumable reason.
  EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
      .WillOnce(Return(true));
  EXPECT_CALL(*download_file,
              RenameAndAnnotate(base::FilePath(kDummyTargetPath), _))
      .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED,
                                       base::FilePath()));
  EXPECT_CALL(*download_file, Cancel());

  // Complete download to trigger final rename.
  item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
  RunAllPendingInMessageLoops();

  ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
  // Should not try to auto-resume.
  ASSERT_EQ(1, observer.interrupt_count());
  ASSERT_EQ(0, observer.resume_count());

  CleanupItem(item, nullptr, DownloadItem::INTERRUPTED);
}

TEST_F(DownloadItemTest, LimitRestartsAfterInterrupted) {
  DownloadItemImpl* item = CreateDownloadItem();
  base::WeakPtr<DownloadDestinationObserver> as_observer(
      item->DestinationObserverAsWeakPtr());
  TestDownloadItemObserver observer(item);
  MockDownloadFile* mock_download_file(nullptr);
  scoped_ptr<DownloadFile> download_file;
  MockRequestHandle* mock_request_handle(nullptr);
  scoped_ptr<DownloadRequestHandleInterface> request_handle;
  DownloadItemImplDelegate::DownloadTargetCallback callback;

  EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _))
      .WillRepeatedly(SaveArg<1>(&callback));
  EXPECT_CALL(*mock_delegate(), GetBrowserContext())
      .WillRepeatedly(Return(browser_context()));
  EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _))
      .Times(DownloadItemImpl::kMaxAutoResumeAttempts);
  for (int i = 0; i < (DownloadItemImpl::kMaxAutoResumeAttempts + 1); ++i) {
    SCOPED_TRACE(::testing::Message() << "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()));

    // Copied key parts of DoIntermediateRename & CallDownloadItemStart
    // to allow for holding onto the request handle.
    item->Start(std::move(download_file), std::move(request_handle),
                *create_info());
    RunAllPendingInMessageLoops();

    base::FilePath target_path(kDummyTargetPath);
    base::FilePath intermediate_path(kDummyIntermediatePath);
    if (i == 0) {
      // RenameAndUniquify is only called the first time. In all the subsequent
      // iterations, the intermediate file already has the correct name, hence
      // no rename is necessary.
      EXPECT_CALL(*mock_download_file, RenameAndUniquify(intermediate_path, _))
          .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
                                           intermediate_path));
    }
    callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
                 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
    RunAllPendingInMessageLoops();

    // Use a continuable interrupt.
    item->DestinationObserverAsWeakPtr()->DestinationError(
        DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR);

    RunAllPendingInMessageLoops();
    ::testing::Mock::VerifyAndClearExpectations(mock_download_file);
  }

  EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
  EXPECT_EQ(1, observer.interrupt_count());
  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_F(DownloadItemTest, 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(browser_context()));
  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.
  download_file = CallDownloadItemStart(item, nullptr);

  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) {
  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);

  // Interrupt the download, using a continuable interrupt.
  EXPECT_CALL(*download_file, FullPath()).WillOnce(Return(base::FilePath()));
  EXPECT_CALL(*download_file, Detach());
  EXPECT_CALL(*mock_delegate(), GetBrowserContext())
      .WillRepeatedly(Return(browser_context()));
  EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(
                                    Property(&DownloadUrlParameters::url,
                                             GURL("http://example.com/c")),
                                    _))
      .Times(1);
  item->DestinationObserverAsWeakPtr()->DestinationError(
      DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR);

  // Test expectations verify that ResumeInterruptedDownload() is called (by way
  // of MockResumeInterruptedDownload) after the download is interrupted. But
  // the mock doesn't follow through with the resumption.
  // ResumeInterruptedDownload() being called is sufficient for verifying that
  // the resumption was triggered.
  RunAllPendingInMessageLoops();

  // The download is currently in RESUMING_INTERNAL, which maps to IN_PROGRESS.
  CleanupItem(item, nullptr, DownloadItem::IN_PROGRESS);
}

TEST_F(DownloadItemTest, NotificationAfterRemove) {
  DownloadItemImpl* item = CreateDownloadItem();
  DownloadItemImplDelegate::DownloadTargetCallback target_callback;
  MockDownloadFile* download_file =
      CallDownloadItemStart(item, &target_callback);
  EXPECT_CALL(*download_file, Cancel());
  EXPECT_CALL(*mock_delegate(), DownloadRemoved(_));
  TestDownloadItemObserver observer(item);

  item->Remove();
  ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
  ASSERT_TRUE(observer.download_removed());
}

TEST_F(DownloadItemTest, NotificationAfterOnContentCheckCompleted) {
  // Setting to NOT_DANGEROUS does not trigger a notification.
  DownloadItemImpl* safe_item = CreateDownloadItem();
  MockDownloadFile* download_file =
      DoIntermediateRename(safe_item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
  TestDownloadItemObserver safe_observer(safe_item);

  safe_item->OnAllDataSaved(std::string());
  EXPECT_TRUE(safe_observer.CheckAndResetDownloadUpdated());
  safe_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
  EXPECT_TRUE(safe_observer.CheckAndResetDownloadUpdated());
  CleanupItem(safe_item, download_file, DownloadItem::IN_PROGRESS);

  // Setting to unsafe url or unsafe file should trigger a notification.
  DownloadItemImpl* unsafeurl_item =
      CreateDownloadItem();
  download_file =
      DoIntermediateRename(unsafeurl_item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
  TestDownloadItemObserver unsafeurl_observer(unsafeurl_item);

  unsafeurl_item->OnAllDataSaved(std::string());
  EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated());
  unsafeurl_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_DANGEROUS_URL);
  EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated());

  EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(_, _))
      .WillOnce(Return(true));
  EXPECT_CALL(*download_file, RenameAndAnnotate(_, _));
  unsafeurl_item->ValidateDangerousDownload();
  EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated());
  CleanupItem(unsafeurl_item, download_file, DownloadItem::IN_PROGRESS);

  DownloadItemImpl* unsafefile_item =
      CreateDownloadItem();
  download_file =
      DoIntermediateRename(unsafefile_item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
  TestDownloadItemObserver unsafefile_observer(unsafefile_item);

  unsafefile_item->OnAllDataSaved(std::string());
  EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated());
  unsafefile_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE);
  EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated());

  EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(_, _))
      .WillOnce(Return(true));
  EXPECT_CALL(*download_file, RenameAndAnnotate(_, _));
  unsafefile_item->ValidateDangerousDownload();
  EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated());
  CleanupItem(unsafefile_item, download_file, DownloadItem::IN_PROGRESS);
}

// DownloadItemImpl::OnDownloadTargetDetermined will schedule a task to run
// DownloadFile::Rename(). Once the rename
// completes, DownloadItemImpl receives a notification with the new file
// name. Check that observers are updated when the new filename is available and
// not before.
TEST_F(DownloadItemTest, NotificationAfterOnDownloadTargetDetermined) {
  DownloadItemImpl* item = CreateDownloadItem();
  DownloadItemImplDelegate::DownloadTargetCallback callback;
  MockDownloadFile* download_file = CallDownloadItemStart(item, &callback);
  TestDownloadItemObserver observer(item);
  base::FilePath target_path(kDummyTargetPath);
  base::FilePath intermediate_path(target_path.InsertBeforeExtensionASCII("x"));
  base::FilePath new_intermediate_path(
      target_path.InsertBeforeExtensionASCII("y"));
  EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
      .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
                                       new_intermediate_path));

  // Currently, a notification would be generated if the danger type is anything
  // other than NOT_DANGEROUS.
  callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
               DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
  EXPECT_FALSE(observer.CheckAndResetDownloadUpdated());
  RunAllPendingInMessageLoops();
  EXPECT_TRUE(observer.CheckAndResetDownloadUpdated());
  EXPECT_EQ(new_intermediate_path, item->GetFullPath());

  CleanupItem(item, download_file, DownloadItem::IN_PROGRESS);
}

TEST_F(DownloadItemTest, NotificationAfterTogglePause) {
  DownloadItemImpl* item = CreateDownloadItem();
  TestDownloadItemObserver observer(item);
  MockDownloadFile* mock_download_file(new MockDownloadFile);
  scoped_ptr<DownloadFile> download_file(mock_download_file);
  scoped_ptr<DownloadRequestHandleInterface> request_handle(
      new NiceMock<MockRequestHandle>);

  EXPECT_CALL(*mock_download_file, Initialize(_));
  EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _));
  item->Start(std::move(download_file), std::move(request_handle),
              *create_info());

  item->Pause();
  ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());

  ASSERT_TRUE(item->IsPaused());

  item->Resume();
  ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());

  RunAllPendingInMessageLoops();

  CleanupItem(item, mock_download_file, DownloadItem::IN_PROGRESS);
}

TEST_F(DownloadItemTest, DisplayName) {
  DownloadItemImpl* item = CreateDownloadItem();
  DownloadItemImplDelegate::DownloadTargetCallback callback;
  MockDownloadFile* download_file = CallDownloadItemStart(item, &callback);
  base::FilePath target_path(
      base::FilePath(kDummyTargetPath).AppendASCII("foo.bar"));
  base::FilePath intermediate_path(target_path.InsertBeforeExtensionASCII("x"));
  EXPECT_EQ(FILE_PATH_LITERAL(""),
            item->GetFileNameToReportUser().value());
  EXPECT_CALL(*download_file, RenameAndUniquify(_, _))
      .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
                                       intermediate_path));
  callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
               DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
  RunAllPendingInMessageLoops();
  EXPECT_EQ(FILE_PATH_LITERAL("foo.bar"),
            item->GetFileNameToReportUser().value());
  item->SetDisplayName(base::FilePath(FILE_PATH_LITERAL("new.name")));
  EXPECT_EQ(FILE_PATH_LITERAL("new.name"),
            item->GetFileNameToReportUser().value());
  CleanupItem(item, download_file, DownloadItem::IN_PROGRESS);
}

// Test to make sure that Start method calls DF initialize properly.
TEST_F(DownloadItemTest, Start) {
  MockDownloadFile* mock_download_file(new MockDownloadFile);
  scoped_ptr<DownloadFile> download_file(mock_download_file);
  DownloadItemImpl* item = CreateDownloadItem();
  EXPECT_CALL(*mock_download_file, Initialize(_));
  scoped_ptr<DownloadRequestHandleInterface> request_handle(
      new NiceMock<MockRequestHandle>);
  EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _));
  item->Start(std::move(download_file), std::move(request_handle),
              *create_info());
  RunAllPendingInMessageLoops();

  CleanupItem(item, mock_download_file, DownloadItem::IN_PROGRESS);
}

// Download file and the request should be cancelled as a result of download
// file initialization failing.
TEST_F(DownloadItemTest, InitDownloadFileFails) {
  DownloadItemImpl* item = CreateDownloadItem();
  scoped_ptr<MockDownloadFile> file(new MockDownloadFile());
  scoped_ptr<MockRequestHandle> request_handle(new MockRequestHandle());
  EXPECT_CALL(*file, Cancel());
  EXPECT_CALL(*request_handle, CancelRequest());
  EXPECT_CALL(*file, Initialize(_))
      .WillOnce(ScheduleCallbackWithParam(
          DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED));

  base::RunLoop start_download_loop;
  DownloadItemImplDelegate::DownloadTargetCallback download_target_callback;
  EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _))
      .WillOnce(DoAll(SaveArg<1>(&download_target_callback),
                      ScheduleClosure(start_download_loop.QuitClosure())));

  item->Start(std::move(file), std::move(request_handle), *create_info());
  start_download_loop.Run();

  download_target_callback.Run(base::FilePath(kDummyTargetPath),
                               DownloadItem::TARGET_DISPOSITION_OVERWRITE,
                               DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
                               base::FilePath(kDummyIntermediatePath));
  RunAllPendingInMessageLoops();

  EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
  EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED,
            item->GetLastReason());
}

// 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();

  // 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());
  EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
  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::IN_PROGRESS, 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();
  DownloadItemImplDelegate::DownloadTargetCallback callback;
  MockDownloadFile* download_file = CallDownloadItemStart(item, &callback);
  base::FilePath final_path(
      base::FilePath(kDummyTargetPath).AppendASCII("foo.bar"));
  base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x"));
  base::FilePath new_intermediate_path(
      final_path.InsertBeforeExtensionASCII("y"));
  EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
      .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
                                       new_intermediate_path));

  callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
               DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
  RunAllPendingInMessageLoops();
  // All the callbacks should have happened by now.
  ::testing::Mock::VerifyAndClearExpectations(download_file);
  mock_delegate()->VerifyAndClearExpectations();

  EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
      .WillOnce(Return(true));
  EXPECT_CALL(*download_file, RenameAndAnnotate(final_path, _))
      .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
                                       final_path));
  EXPECT_CALL(*download_file, FullPath())
      .WillOnce(Return(base::FilePath()));
  EXPECT_CALL(*download_file, Detach());
  item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
  RunAllPendingInMessageLoops();
  ::testing::Mock::VerifyAndClearExpectations(download_file);
  mock_delegate()->VerifyAndClearExpectations();
}

// Test that the delegate is invoked after the download file is renamed and the
// download item is in an interrupted state.
TEST_F(DownloadItemTest, CallbackAfterInterruptedRename) {
  DownloadItemImpl* item = CreateDownloadItem();
  DownloadItemImplDelegate::DownloadTargetCallback callback;
  MockDownloadFile* download_file = CallDownloadItemStart(item, &callback);
  base::FilePath final_path(
      base::FilePath(kDummyTargetPath).AppendASCII("foo.bar"));
  base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x"));
  base::FilePath new_intermediate_path(
      final_path.InsertBeforeExtensionASCII("y"));
  EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
      .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED,
                                       new_intermediate_path));
  EXPECT_CALL(*download_file, Cancel())
      .Times(1);

  callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
               DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
  RunAllPendingInMessageLoops();
  // All the callbacks should have happened by now.
  ::testing::Mock::VerifyAndClearExpectations(download_file);
  mock_delegate()->VerifyAndClearExpectations();
}

TEST_F(DownloadItemTest, Interrupted) {
  DownloadItemImpl* item = CreateDownloadItem();
  MockDownloadFile* download_file =
      DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);

  const DownloadInterruptReason reason(
      DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED);

  // Confirm interrupt sets state properly.
  EXPECT_CALL(*download_file, Cancel());
  item->DestinationObserverAsWeakPtr()->DestinationError(reason);
  RunAllPendingInMessageLoops();
  EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
  EXPECT_EQ(reason, item->GetLastReason());

  // Cancel should kill it.
  item->Cancel(true);
  EXPECT_EQ(DownloadItem::CANCELLED, item->GetState());
  EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_USER_CANCELED, item->GetLastReason());
}

// Destination errors that occur before the intermediate rename shouldn't cause
// the download to be marked as interrupted until after the intermediate rename.
TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Restart) {
  DownloadItemImpl* item = CreateDownloadItem();
  DownloadItemImplDelegate::DownloadTargetCallback callback;
  MockDownloadFile* download_file = CallDownloadItemStart(item, &callback);
  item->DestinationObserverAsWeakPtr()->DestinationError(
      DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
  ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());

  base::FilePath final_path(
      base::FilePath(kDummyTargetPath).AppendASCII("foo.bar"));
  base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x"));
  base::FilePath new_intermediate_path(
      final_path.InsertBeforeExtensionASCII("y"));
  EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
      .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
                                       new_intermediate_path));
  EXPECT_CALL(*download_file, Cancel())
      .Times(1);

  callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
               DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
  RunAllPendingInMessageLoops();
  // All the callbacks should have happened by now.
  ::testing::Mock::VerifyAndClearExpectations(download_file);
  mock_delegate()->VerifyAndClearExpectations();
  EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
  EXPECT_TRUE(item->GetFullPath().empty());
  EXPECT_EQ(final_path, item->GetTargetFilePath());
}

// 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) {
  DownloadItemImpl* item = CreateDownloadItem();
  DownloadItemImplDelegate::DownloadTargetCallback callback;
  MockDownloadFile* download_file = CallDownloadItemStart(item, &callback);
  item->DestinationObserverAsWeakPtr()->DestinationError(
      DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED);
  ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());

  base::FilePath final_path(
      base::FilePath(kDummyTargetPath).AppendASCII("foo.bar"));
  base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x"));
  base::FilePath new_intermediate_path(
      final_path.InsertBeforeExtensionASCII("y"));
  EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
      .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
                                       new_intermediate_path));
  EXPECT_CALL(*download_file, FullPath())
      .WillOnce(Return(base::FilePath(new_intermediate_path)));
  EXPECT_CALL(*download_file, Detach());

  callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
               DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
  RunAllPendingInMessageLoops();
  // All the callbacks should have happened by now.
  ::testing::Mock::VerifyAndClearExpectations(download_file);
  mock_delegate()->VerifyAndClearExpectations();
  EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
  EXPECT_EQ(new_intermediate_path, item->GetFullPath());
  EXPECT_EQ(final_path, item->GetTargetFilePath());
}

// 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) {
  DownloadItemImpl* item = CreateDownloadItem();
  DownloadItemImplDelegate::DownloadTargetCallback callback;
  MockDownloadFile* download_file = CallDownloadItemStart(item, &callback);
  item->DestinationObserverAsWeakPtr()->DestinationError(
      DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED);
  ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());

  base::FilePath final_path(
      base::FilePath(kDummyTargetPath).AppendASCII("foo.bar"));
  base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x"));
  base::FilePath new_intermediate_path(
      final_path.InsertBeforeExtensionASCII("y"));
  EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
      .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED,
                                       new_intermediate_path));
  EXPECT_CALL(*download_file, Cancel())
      .Times(1);

  callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
               DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
  RunAllPendingInMessageLoops();
  // All the callbacks should have happened by now.
  ::testing::Mock::VerifyAndClearExpectations(download_file);
  mock_delegate()->VerifyAndClearExpectations();
  EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
  EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, item->GetLastReason());
  EXPECT_TRUE(item->GetFullPath().empty());
  EXPECT_EQ(final_path, item->GetTargetFilePath());
}

TEST_F(DownloadItemTest, Canceled) {
  DownloadItemImpl* item = CreateDownloadItem();
  DownloadItemImplDelegate::DownloadTargetCallback target_callback;
  MockDownloadFile* download_file =
      CallDownloadItemStart(item, &target_callback);

  // Confirm cancel sets state properly.
  EXPECT_CALL(*download_file, Cancel());
  item->Cancel(true);
  EXPECT_EQ(DownloadItem::CANCELLED, item->GetState());
}

TEST_F(DownloadItemTest, FileRemoved) {
  DownloadItemImpl* item = CreateDownloadItem();

  EXPECT_FALSE(item->GetFileExternallyRemoved());
  item->OnDownloadedFileRemoved();
  EXPECT_TRUE(item->GetFileExternallyRemoved());
}

TEST_F(DownloadItemTest, DestinationUpdate) {
  DownloadItemImpl* item = CreateDownloadItem();
  MockDownloadFile* file =
      DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
  base::WeakPtr<DownloadDestinationObserver> as_observer(
      item->DestinationObserverAsWeakPtr());
  TestDownloadItemObserver observer(item);

  EXPECT_EQ(0l, item->CurrentSpeed());
  EXPECT_EQ("", item->GetHashState());
  EXPECT_EQ(0l, item->GetReceivedBytes());
  EXPECT_EQ(0l, item->GetTotalBytes());
  EXPECT_FALSE(observer.CheckAndResetDownloadUpdated());
  item->SetTotalBytes(100l);
  EXPECT_EQ(100l, item->GetTotalBytes());

  as_observer->DestinationUpdate(10, 20, "deadbeef");
  EXPECT_EQ(20l, item->CurrentSpeed());
  EXPECT_EQ("deadbeef", item->GetHashState());
  EXPECT_EQ(10l, item->GetReceivedBytes());
  EXPECT_EQ(100l, item->GetTotalBytes());
  EXPECT_TRUE(observer.CheckAndResetDownloadUpdated());

  as_observer->DestinationUpdate(200, 20, "livebeef");
  EXPECT_EQ(20l, item->CurrentSpeed());
  EXPECT_EQ("livebeef", item->GetHashState());
  EXPECT_EQ(200l, item->GetReceivedBytes());
  EXPECT_EQ(0l, item->GetTotalBytes());
  EXPECT_TRUE(observer.CheckAndResetDownloadUpdated());

  CleanupItem(item, file, DownloadItem::IN_PROGRESS);
}

TEST_F(DownloadItemTest, DestinationError) {
  DownloadItemImpl* item = CreateDownloadItem();
  MockDownloadFile* download_file =
      DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
  base::WeakPtr<DownloadDestinationObserver> as_observer(
      item->DestinationObserverAsWeakPtr());
  TestDownloadItemObserver observer(item);

  EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
  EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, item->GetLastReason());
  EXPECT_FALSE(observer.CheckAndResetDownloadUpdated());

  EXPECT_CALL(*download_file, Cancel());
  as_observer->DestinationError(
      DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED);
  mock_delegate()->VerifyAndClearExpectations();
  EXPECT_TRUE(observer.CheckAndResetDownloadUpdated());
  EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
  EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED,
            item->GetLastReason());
}

TEST_F(DownloadItemTest, DestinationCompleted) {
  DownloadItemImpl* item = CreateDownloadItem();
  MockDownloadFile* download_file =
      DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
  base::WeakPtr<DownloadDestinationObserver> as_observer(
      item->DestinationObserverAsWeakPtr());
  TestDownloadItemObserver observer(item);

  EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
  EXPECT_EQ("", item->GetHash());
  EXPECT_EQ("", item->GetHashState());
  EXPECT_FALSE(item->AllDataSaved());
  EXPECT_FALSE(observer.CheckAndResetDownloadUpdated());

  as_observer->DestinationUpdate(10, 20, "deadbeef");
  EXPECT_TRUE(observer.CheckAndResetDownloadUpdated());
  EXPECT_FALSE(observer.CheckAndResetDownloadUpdated());  // Confirm reset.
  EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
  EXPECT_EQ("", item->GetHash());
  EXPECT_EQ("deadbeef", item->GetHashState());
  EXPECT_FALSE(item->AllDataSaved());

  EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(_, _));
  as_observer->DestinationCompleted("livebeef");
  mock_delegate()->VerifyAndClearExpectations();
  EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
  EXPECT_TRUE(observer.CheckAndResetDownloadUpdated());
  EXPECT_EQ("livebeef", item->GetHash());
  EXPECT_EQ("", item->GetHashState());
  EXPECT_TRUE(item->AllDataSaved());

  // Even though the DownloadItem receives a DestinationCompleted() event,
  // target determination hasn't completed, hence the download item is stuck in
  // TARGET_PENDING.
  CleanupItem(item, download_file, DownloadItem::IN_PROGRESS);
}

TEST_F(DownloadItemTest, EnabledActionsForNormalDownload) {
  DownloadItemImpl* item = CreateDownloadItem();
  MockDownloadFile* download_file =
      DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);

  // InProgress
  ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
  ASSERT_FALSE(item->GetTargetFilePath().empty());
  EXPECT_TRUE(item->CanShowInFolder());
  EXPECT_TRUE(item->CanOpenDownload());

  // Complete
  EXPECT_CALL(*download_file, RenameAndAnnotate(_, _))
      .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
                                       base::FilePath(kDummyTargetPath)));
  EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
      .WillOnce(Return(true));
  EXPECT_CALL(*download_file, FullPath())
      .WillOnce(Return(base::FilePath()));
  EXPECT_CALL(*download_file, Detach());
  item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
  RunAllPendingInMessageLoops();

  ASSERT_EQ(DownloadItem::COMPLETE, item->GetState());
  EXPECT_TRUE(item->CanShowInFolder());
  EXPECT_TRUE(item->CanOpenDownload());
}

TEST_F(DownloadItemTest, EnabledActionsForTemporaryDownload) {
  DownloadItemImpl* item = CreateDownloadItem();
  MockDownloadFile* download_file =
      DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
  item->SetIsTemporary(true);

  // InProgress Temporary
  ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
  ASSERT_FALSE(item->GetTargetFilePath().empty());
  ASSERT_TRUE(item->IsTemporary());
  EXPECT_FALSE(item->CanShowInFolder());
  EXPECT_FALSE(item->CanOpenDownload());

  // Complete Temporary
  EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
      .WillOnce(Return(true));
  EXPECT_CALL(*download_file, RenameAndAnnotate(_, _))
      .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
                                       base::FilePath(kDummyTargetPath)));
  EXPECT_CALL(*download_file, FullPath())
      .WillOnce(Return(base::FilePath()));
  EXPECT_CALL(*download_file, Detach());
  item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
  RunAllPendingInMessageLoops();

  ASSERT_EQ(DownloadItem::COMPLETE, item->GetState());
  EXPECT_FALSE(item->CanShowInFolder());
  EXPECT_FALSE(item->CanOpenDownload());
}

TEST_F(DownloadItemTest, EnabledActionsForInterruptedDownload) {
  DownloadItemImpl* item = CreateDownloadItem();
  MockDownloadFile* download_file =
      DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);

  EXPECT_CALL(*download_file, Cancel());
  item->DestinationObserverAsWeakPtr()->DestinationError(
      DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
  RunAllPendingInMessageLoops();

  ASSERT_EQ(DownloadItem::INTERRUPTED, item->GetState());
  ASSERT_FALSE(item->GetTargetFilePath().empty());
  EXPECT_FALSE(item->CanShowInFolder());
  EXPECT_TRUE(item->CanOpenDownload());
}

TEST_F(DownloadItemTest, EnabledActionsForCancelledDownload) {
  DownloadItemImpl* item = CreateDownloadItem();
  MockDownloadFile* download_file =
      DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);

  EXPECT_CALL(*download_file, Cancel());
  item->Cancel(true);
  RunAllPendingInMessageLoops();

  ASSERT_EQ(DownloadItem::CANCELLED, item->GetState());
  EXPECT_FALSE(item->CanShowInFolder());
  EXPECT_FALSE(item->CanOpenDownload());
}

// Test various aspects of the delegate completion blocker.

// Just allowing completion.
TEST_F(DownloadItemTest, CompleteDelegate_ReturnTrue) {
  // Test to confirm that if we have a callback that returns true,
  // we complete immediately.
  DownloadItemImpl* item = CreateDownloadItem();
  MockDownloadFile* download_file =
      DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);

  // Drive the delegate interaction.
  EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
      .WillOnce(Return(true));
  item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
  EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
  EXPECT_FALSE(item->IsDangerous());

  // Make sure the download can complete.
  EXPECT_CALL(*download_file,
              RenameAndAnnotate(base::FilePath(kDummyTargetPath), _))
      .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
                                       base::FilePath(kDummyTargetPath)));
  EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _))
      .WillOnce(Return(true));
  EXPECT_CALL(*download_file, FullPath())
      .WillOnce(Return(base::FilePath()));
  EXPECT_CALL(*download_file, Detach());
  RunAllPendingInMessageLoops();
  EXPECT_EQ(DownloadItem::COMPLETE, item->GetState());
}

// Just delaying completion.
TEST_F(DownloadItemTest, CompleteDelegate_BlockOnce) {
  // Test to confirm that if we have a callback that returns true,
  // we complete immediately.
  DownloadItemImpl* item = CreateDownloadItem();
  MockDownloadFile* download_file =
      DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);

  // Drive the delegate interaction.
  base::Closure delegate_callback;
  base::Closure copy_delegate_callback;
  EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
      .WillOnce(DoAll(SaveArg<1>(&delegate_callback),
                      Return(false)))
      .WillOnce(Return(true));
  item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
  ASSERT_FALSE(delegate_callback.is_null());
  copy_delegate_callback = delegate_callback;
  delegate_callback.Reset();
  EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
  copy_delegate_callback.Run();
  ASSERT_TRUE(delegate_callback.is_null());
  EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
  EXPECT_FALSE(item->IsDangerous());

  // Make sure the download can complete.
  EXPECT_CALL(*download_file,
              RenameAndAnnotate(base::FilePath(kDummyTargetPath), _))
      .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
                                       base::FilePath(kDummyTargetPath)));
  EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _))
      .WillOnce(Return(true));
  EXPECT_CALL(*download_file, FullPath())
      .WillOnce(Return(base::FilePath()));
  EXPECT_CALL(*download_file, Detach());
  RunAllPendingInMessageLoops();
  EXPECT_EQ(DownloadItem::COMPLETE, item->GetState());
}

// Delay and set danger.
TEST_F(DownloadItemTest, CompleteDelegate_SetDanger) {
  // Test to confirm that if we have a callback that returns true,
  // we complete immediately.
  DownloadItemImpl* item = CreateDownloadItem();
  MockDownloadFile* download_file =
      DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);

  // Drive the delegate interaction.
  base::Closure delegate_callback;
  base::Closure copy_delegate_callback;
  EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
      .WillOnce(DoAll(SaveArg<1>(&delegate_callback),
                      Return(false)))
      .WillOnce(Return(true));
  item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
  ASSERT_FALSE(delegate_callback.is_null());
  copy_delegate_callback = delegate_callback;
  delegate_callback.Reset();
  EXPECT_FALSE(item->IsDangerous());
  item->OnContentCheckCompleted(
      content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE);
  EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
  copy_delegate_callback.Run();
  ASSERT_TRUE(delegate_callback.is_null());
  EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
  EXPECT_TRUE(item->IsDangerous());

  // Make sure the download doesn't complete until we've validated it.
  EXPECT_CALL(*download_file,
              RenameAndAnnotate(base::FilePath(kDummyTargetPath), _))
      .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
                                       base::FilePath(kDummyTargetPath)));
  EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _))
      .WillOnce(Return(true));
  EXPECT_CALL(*download_file, FullPath())
      .WillOnce(Return(base::FilePath()));
  EXPECT_CALL(*download_file, Detach());
  RunAllPendingInMessageLoops();
  EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
  EXPECT_TRUE(item->IsDangerous());

  item->ValidateDangerousDownload();
  EXPECT_EQ(DOWNLOAD_DANGER_TYPE_USER_VALIDATED, item->GetDangerType());
  RunAllPendingInMessageLoops();
  EXPECT_EQ(DownloadItem::COMPLETE, item->GetState());
}

// Just delaying completion twice.
TEST_F(DownloadItemTest, CompleteDelegate_BlockTwice) {
  // Test to confirm that if we have a callback that returns true,
  // we complete immediately.
  DownloadItemImpl* item = CreateDownloadItem();
  MockDownloadFile* download_file =
      DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);

  // Drive the delegate interaction.
  base::Closure delegate_callback;
  base::Closure copy_delegate_callback;
  EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
      .WillOnce(DoAll(SaveArg<1>(&delegate_callback),
                      Return(false)))
      .WillOnce(DoAll(SaveArg<1>(&delegate_callback),
                      Return(false)))
      .WillOnce(Return(true));
  item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
  ASSERT_FALSE(delegate_callback.is_null());
  copy_delegate_callback = delegate_callback;
  delegate_callback.Reset();
  EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
  copy_delegate_callback.Run();
  ASSERT_FALSE(delegate_callback.is_null());
  copy_delegate_callback = delegate_callback;
  delegate_callback.Reset();
  EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
  copy_delegate_callback.Run();
  ASSERT_TRUE(delegate_callback.is_null());
  EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
  EXPECT_FALSE(item->IsDangerous());

  // Make sure the download can complete.
  EXPECT_CALL(*download_file,
              RenameAndAnnotate(base::FilePath(kDummyTargetPath), _))
      .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
                                       base::FilePath(kDummyTargetPath)));
  EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _))
      .WillOnce(Return(true));
  EXPECT_CALL(*download_file, FullPath())
      .WillOnce(Return(base::FilePath()));
  EXPECT_CALL(*download_file, Detach());
  RunAllPendingInMessageLoops();
  EXPECT_EQ(DownloadItem::COMPLETE, item->GetState());
}

TEST_F(DownloadItemTest, StealDangerousDownload) {
  DownloadItemImpl* item = CreateDownloadItem();
  MockDownloadFile* download_file =
      DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE);
  ASSERT_TRUE(item->IsDangerous());
  base::FilePath full_path(FILE_PATH_LITERAL("foo.txt"));
  base::FilePath returned_path;

  EXPECT_CALL(*download_file, FullPath())
      .WillOnce(Return(full_path));
  EXPECT_CALL(*download_file, Detach());
  EXPECT_CALL(*mock_delegate(), DownloadRemoved(_));
  base::WeakPtrFactory<DownloadItemTest> weak_ptr_factory(this);
  item->StealDangerousDownload(
      base::Bind(&DownloadItemTest::OnDownloadFileAcquired,
                 weak_ptr_factory.GetWeakPtr(),
                 base::Unretained(&returned_path)));
  RunAllPendingInMessageLoops();
  EXPECT_EQ(full_path, returned_path);
}

TEST_F(DownloadItemTest, StealInterruptedDangerousDownload) {
  base::FilePath returned_path;
  DownloadItemImpl* item = CreateDownloadItem();
  MockDownloadFile* download_file =
      DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE);
  base::FilePath full_path = item->GetFullPath();
  EXPECT_FALSE(full_path.empty());
  EXPECT_CALL(*download_file, FullPath())
      .WillOnce(Return(full_path));
  EXPECT_CALL(*download_file, Detach());
  item->DestinationObserverAsWeakPtr()->DestinationError(
      DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED);
  ASSERT_TRUE(item->IsDangerous());

  EXPECT_CALL(*mock_delegate(), DownloadRemoved(_));
  base::WeakPtrFactory<DownloadItemTest> weak_ptr_factory(this);
  item->StealDangerousDownload(
      base::Bind(&DownloadItemTest::OnDownloadFileAcquired,
                 weak_ptr_factory.GetWeakPtr(),
                 base::Unretained(&returned_path)));
  RunAllPendingInMessageLoops();
  EXPECT_EQ(full_path, returned_path);
}

TEST_F(DownloadItemTest, StealInterruptedNonResumableDangerousDownload) {
  base::FilePath returned_path;
  DownloadItemImpl* item = CreateDownloadItem();
  MockDownloadFile* download_file =
      DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE);
  EXPECT_CALL(*download_file, Cancel());
  item->DestinationObserverAsWeakPtr()->DestinationError(
      DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
  ASSERT_TRUE(item->IsDangerous());

  EXPECT_CALL(*mock_delegate(), DownloadRemoved(_));
  base::WeakPtrFactory<DownloadItemTest> weak_ptr_factory(this);
  item->StealDangerousDownload(
      base::Bind(&DownloadItemTest::OnDownloadFileAcquired,
                 weak_ptr_factory.GetWeakPtr(),
                 base::Unretained(&returned_path)));
  RunAllPendingInMessageLoops();
  EXPECT_TRUE(returned_path.empty());
}

namespace {

// The DownloadItemDestinationUpdateRaceTest fixture (defined below) is used to
// test for race conditions between download destination events received via the
// DownloadDestinationObserver interface, and the target determination logic.
//
// The general control flow for DownloadItemImpl looks like this:
//
// * Start() called, which in turn calls DownloadFile::Initialize().
//
//   Even though OnDownloadFileInitialized hasn't been called, there could now
//   be destination observer calls queued prior to the task that calls
//   OnDownloadFileInitialized. Let's call this point in the workflow "A".
//
// * DownloadItemImpl::OnDownloadFileInitialized() called.
//
// * Assuming the result is successful, DII now invokes the delegate's
//   DetermineDownloadTarget method.
//
//   At this point DonwnloadFile acts as the source of
//   DownloadDestinationObserver events, and may invoke callbacks. Let's call
//   this point in the workflow "B".
//
// * DII::OnDownloadTargetDetermined() invoked after delegate is done with
//   target determination.
//
// * DII attempts to rename the DownloadFile to its intermediate name.
//
//   More DownloadDestinationObserver events can happen here. Let's call this
//   point in the workflow "C".
//
// * DII::OnDownloadRenamedToIntermediateName() invoked. Assuming all went well,
//   DII is now in IN_PROGRESS state.
//
//   More DownloadDestinationObserver events can happen here. Let's call this
//   point in the workflow "D".
//
// The DownloadItemDestinationUpdateRaceTest works by generating various
// combinations of DownloadDestinationObserver events that might occur at the
// points "A", "B", "C", and "D" above. Each test in this suite cranks a
// DownloadItemImpl through the states listed above and invokes the events
// assigned to each position.

// This type of callback represents a call to a DownloadDestinationObserver
// method that's missing the DownloadDestinationObserver object. Currying this
// way allows us to bind a call prior to constructing the object on which the
// method would be invoked.  This is necessary since we are going to construct
// various permutations of observer calls that will then be applied to a
// DownloadItem in a state as yet undetermined.
using CurriedObservation =
    base::Callback<void(base::WeakPtr<DownloadDestinationObserver>)>;

// A list of observations that are to be made during some event in the
// DownloadItemImpl control flow. Ordering of the observations is significant.
using ObservationList = std::deque<CurriedObservation>;

// An ordered list of events.
//
// An "event" in this context refers to some stage in the DownloadItemImpl's
// workflow described as "A", "B", "C", or "D" above. An EventList is expected
// to always contains kEventCount events.
using EventList = std::deque<ObservationList>;

// Number of events in an EventList. This is always 4 for now as described
// above.
const int kEventCount = 4;

// The following functions help us with currying the calls to
// DownloadDestinationObserver. If std::bind was allowed along with
// std::placeholders, it is possible to avoid these functions, but currently
// Chromium doesn't allow using std::bind for good reasons.
void DestinationUpdateInvoker(
    int64_t bytes_so_far,
    int64_t bytes_per_sec,
    const std::string& hash_state,
    base::WeakPtr<DownloadDestinationObserver> observer) {
  DVLOG(20) << "DestinationUpdate(bytes_so_far:" << bytes_so_far
            << ", bytes_per_sec:" << bytes_per_sec
            << ", hash_state:" << hash_state << ") observer:" << !!observer;
  if (observer)
    observer->DestinationUpdate(bytes_so_far, bytes_per_sec, hash_state);
}

void DestinationErrorInvoker(
    DownloadInterruptReason reason,
    base::WeakPtr<DownloadDestinationObserver> observer) {
  DVLOG(20) << "DestinationError(reason:"
            << DownloadInterruptReasonToString(reason)
            << ") observer:" << !!observer;
  if (observer)
    observer->DestinationError(reason);
}

void DestinationCompletedInvoker(
    const std::string& final_hash,
    base::WeakPtr<DownloadDestinationObserver> observer) {
  DVLOG(20) << "DestinationComplete(final_hash:" << final_hash
            << ") observer:" << !!observer;
  if (observer)
    observer->DestinationCompleted(final_hash);
}

// Given a set of observations (via the range |begin|..|end|), constructs a list
// of EventLists such that:
//
// * There are exactly |event_count| ObservationSets in each EventList.
//
// * Each ObservationList in each EventList contains a subrange (possibly empty)
//   of observations from the input range, in the same order as the input range.
//
// * The ordering of the ObservationList in each EventList is such that all
//   observations in one ObservationList occur earlier than all observations in
//   an ObservationList that follows it.
//
// * The list of EventLists together describe all the possible ways in which the
//   list of observations can be distributed into |event_count| events.
std::vector<EventList> DistributeObservationsIntoEvents(
    const std::vector<CurriedObservation>::iterator begin,
    const std::vector<CurriedObservation>::iterator end,
    int event_count) {
  std::vector<EventList> all_event_lists;
  for (auto partition = begin;; ++partition) {
    ObservationList first_group_of_observations(begin, partition);
    if (event_count > 1) {
      std::vector<EventList> list_of_subsequent_events =
          DistributeObservationsIntoEvents(partition, end, event_count - 1);
      for (const auto& subsequent_events : list_of_subsequent_events) {
        EventList event_list;
        event_list = subsequent_events;
        event_list.push_front(first_group_of_observations);
        all_event_lists.push_back(event_list);
      }
    } else {
      EventList event_list;
      event_list.push_front(first_group_of_observations);
      all_event_lists.push_back(event_list);
    }
    if (partition == end)
      break;
  }
  return all_event_lists;
}

// For the purpose of this tests, we are only concerned with 3 events:
//
// 1. Immediately after the DownloadFile is initialized.
// 2. Immediately after the DownloadTargetCallback is invoked.
// 3. Immediately after the intermediate file is renamed.
//
// We are going to take a couple of sets of DownloadDestinationObserver events
// and distribute them into the three events described above. And then we are
// going to invoke the observations while a DownloadItemImpl is carefully
// stepped through its stages.

std::vector<EventList> GenerateSuccessfulEventLists() {
  std::vector<CurriedObservation> all_observations;
  all_observations.push_back(
      base::Bind(&DestinationUpdateInvoker, 100, 100, "abc"));
  all_observations.push_back(
      base::Bind(&DestinationUpdateInvoker, 200, 100, "def"));
  all_observations.push_back(
      base::Bind(&DestinationCompletedInvoker, "final-hash-1"));
  return DistributeObservationsIntoEvents(all_observations.begin(),
                                          all_observations.end(), kEventCount);
}

std::vector<EventList> GenerateFailingEventLists() {
  std::vector<CurriedObservation> all_observations;
  all_observations.push_back(
      base::Bind(&DestinationUpdateInvoker, 100, 100, "abc"));
  all_observations.push_back(base::Bind(
      &DestinationErrorInvoker, DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED));
  return DistributeObservationsIntoEvents(all_observations.begin(),
                                          all_observations.end(), kEventCount);
}

class DownloadItemDestinationUpdateRaceTest
    : public DownloadItemTest,
      public ::testing::WithParamInterface<EventList> {
 public:
  DownloadItemDestinationUpdateRaceTest()
      : DownloadItemTest(),
        item_(CreateDownloadItem()),
        file_(new ::testing::StrictMock<MockDownloadFile>()),
        request_handle_(new ::testing::StrictMock<MockRequestHandle>()) {
    DCHECK_EQ(GetParam().size(), static_cast<unsigned>(kEventCount));
    EXPECT_CALL(*request_handle_, GetWebContents())
        .WillRepeatedly(Return(nullptr));
  }

 protected:
  const ObservationList& PreInitializeFileObservations() {
    return GetParam().front();
  }
  const ObservationList& PostInitializeFileObservations() {
    return *(GetParam().begin() + 1);
  }
  const ObservationList& PostTargetDeterminationObservations() {
    return *(GetParam().begin() + 2);
  }
  const ObservationList& PostIntermediateRenameObservations() {
    return *(GetParam().begin() + 3);
  }

  // Apply all the observations in |observations| to |observer|, but do so
  // asynchronously so that the events are applied in order behind any tasks
  // that are already scheduled.
  void ScheduleObservations(
      const ObservationList& observations,
      base::WeakPtr<DownloadDestinationObserver> observer) {
    for (const auto action : observations)
      BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
                              base::Bind(action, observer));
  }

  DownloadItemImpl* item_;
  scoped_ptr<MockDownloadFile> file_;
  scoped_ptr<MockRequestHandle> request_handle_;

  std::queue<base::Closure> successful_update_events_;
  std::queue<base::Closure> failing_update_events_;
};

INSTANTIATE_TEST_CASE_P(Success,
                        DownloadItemDestinationUpdateRaceTest,
                        ::testing::ValuesIn(GenerateSuccessfulEventLists()));

INSTANTIATE_TEST_CASE_P(Failure,
                        DownloadItemDestinationUpdateRaceTest,
                        ::testing::ValuesIn(GenerateFailingEventLists()));

}  // namespace

// Run through the DII workflow but the embedder cancels the download at target
// determination.
TEST_P(DownloadItemDestinationUpdateRaceTest, DownloadCancelledByUser) {
  // Expect that the download file and the request will be cancelled as a
  // result.
  EXPECT_CALL(*file_, Cancel());
  EXPECT_CALL(*request_handle_, CancelRequest());

  base::RunLoop download_start_loop;
  DownloadFile::InitializeCallback initialize_callback;
  EXPECT_CALL(*file_, Initialize(_))
      .WillOnce(DoAll(SaveArg<0>(&initialize_callback),
                      ScheduleClosure(download_start_loop.QuitClosure())));
  item_->Start(std::move(file_), std::move(request_handle_), *create_info());
  download_start_loop.Run();

  base::WeakPtr<DownloadDestinationObserver> destination_observer =
      item_->DestinationObserverAsWeakPtr();

  ScheduleObservations(PreInitializeFileObservations(), destination_observer);
  RunAllPendingInMessageLoops();

  base::RunLoop initialize_completion_loop;
  DownloadItemImplDelegate::DownloadTargetCallback target_callback;
  EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _))
      .WillOnce(
          DoAll(SaveArg<1>(&target_callback),
                ScheduleClosure(initialize_completion_loop.QuitClosure())));
  ScheduleObservations(PostInitializeFileObservations(), destination_observer);
  initialize_callback.Run(DOWNLOAD_INTERRUPT_REASON_NONE);
  initialize_completion_loop.Run();

  RunAllPendingInMessageLoops();

  ASSERT_FALSE(target_callback.is_null());
  ScheduleObservations(PostTargetDeterminationObservations(),
                       destination_observer);
  target_callback.Run(base::FilePath(),
                      DownloadItem::TARGET_DISPOSITION_OVERWRITE,
                      DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, base::FilePath());
  EXPECT_EQ(DownloadItem::CANCELLED, item_->GetState());
  RunAllPendingInMessageLoops();
}

// Run through the DII workflow, but the intermediate rename fails.
TEST_P(DownloadItemDestinationUpdateRaceTest, IntermediateRenameFails) {
  // Expect that the download file and the request will be cancelled as a
  // result.
  EXPECT_CALL(*file_, Cancel());
  EXPECT_CALL(*request_handle_, CancelRequest());

  // Intermediate rename loop is not used immediately, but let's set up the
  // DownloadFile expectations since we are about to transfer its ownership to
  // the DownloadItem.
  base::RunLoop intermediate_rename_loop;
  DownloadFile::RenameCompletionCallback intermediate_rename_callback;
  EXPECT_CALL(*file_, RenameAndUniquify(_, _))
      .WillOnce(DoAll(SaveArg<1>(&intermediate_rename_callback),
                      ScheduleClosure(intermediate_rename_loop.QuitClosure())));

  base::RunLoop download_start_loop;
  DownloadFile::InitializeCallback initialize_callback;
  EXPECT_CALL(*file_, Initialize(_))
      .WillOnce(DoAll(SaveArg<0>(&initialize_callback),
                      ScheduleClosure(download_start_loop.QuitClosure())));

  item_->Start(std::move(file_), std::move(request_handle_), *create_info());
  download_start_loop.Run();
  base::WeakPtr<DownloadDestinationObserver> destination_observer =
      item_->DestinationObserverAsWeakPtr();

  ScheduleObservations(PreInitializeFileObservations(), destination_observer);
  RunAllPendingInMessageLoops();

  base::RunLoop initialize_completion_loop;
  DownloadItemImplDelegate::DownloadTargetCallback target_callback;
  EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _))
      .WillOnce(
          DoAll(SaveArg<1>(&target_callback),
                ScheduleClosure(initialize_completion_loop.QuitClosure())));
  ScheduleObservations(PostInitializeFileObservations(), destination_observer);
  initialize_callback.Run(DOWNLOAD_INTERRUPT_REASON_NONE);
  initialize_completion_loop.Run();

  RunAllPendingInMessageLoops();
  ASSERT_FALSE(target_callback.is_null());

  ScheduleObservations(PostTargetDeterminationObservations(),
                       destination_observer);
  target_callback.Run(base::FilePath(kDummyTargetPath),
                      DownloadItem::TARGET_DISPOSITION_OVERWRITE,
                      DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
                      base::FilePath(kDummyIntermediatePath));

  intermediate_rename_loop.Run();
  ASSERT_FALSE(intermediate_rename_callback.is_null());

  ScheduleObservations(PostIntermediateRenameObservations(),
                       destination_observer);
  intermediate_rename_callback.Run(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED,
                                   base::FilePath());
  RunAllPendingInMessageLoops();

  EXPECT_EQ(DownloadItem::INTERRUPTED, item_->GetState());
}

// Run through the DII workflow. Download file initialization, target
// determination and intermediate rename all succeed.
TEST_P(DownloadItemDestinationUpdateRaceTest, IntermediateRenameSucceeds) {
  // We expect either that the download will fail (in which case the request and
  // the download file will be cancelled), or it will succeed (in which case the
  // DownloadFile will Detach()). It depends on the list of observations that
  // are given to us.
  EXPECT_CALL(*file_, Cancel()).Times(::testing::AnyNumber());
  EXPECT_CALL(*request_handle_, CancelRequest()).Times(::testing::AnyNumber());
  EXPECT_CALL(*file_, Detach()).Times(::testing::AnyNumber());

  EXPECT_CALL(*file_, FullPath())
      .WillRepeatedly(Return(base::FilePath(kDummyIntermediatePath)));

  // Intermediate rename loop is not used immediately, but let's set up the
  // DownloadFile expectations since we are about to transfer its ownership to
  // the DownloadItem.
  base::RunLoop intermediate_rename_loop;
  DownloadFile::RenameCompletionCallback intermediate_rename_callback;
  EXPECT_CALL(*file_, RenameAndUniquify(_, _))
      .WillOnce(DoAll(SaveArg<1>(&intermediate_rename_callback),
                      ScheduleClosure(intermediate_rename_loop.QuitClosure())));

  base::RunLoop download_start_loop;
  DownloadFile::InitializeCallback initialize_callback;
  EXPECT_CALL(*file_, Initialize(_))
      .WillOnce(DoAll(SaveArg<0>(&initialize_callback),
                      ScheduleClosure(download_start_loop.QuitClosure())));

  item_->Start(std::move(file_), std::move(request_handle_), *create_info());
  download_start_loop.Run();
  base::WeakPtr<DownloadDestinationObserver> destination_observer =
      item_->DestinationObserverAsWeakPtr();

  ScheduleObservations(PreInitializeFileObservations(), destination_observer);
  RunAllPendingInMessageLoops();

  base::RunLoop initialize_completion_loop;
  DownloadItemImplDelegate::DownloadTargetCallback target_callback;
  EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _))
      .WillOnce(
          DoAll(SaveArg<1>(&target_callback),
                ScheduleClosure(initialize_completion_loop.QuitClosure())));
  ScheduleObservations(PostInitializeFileObservations(), destination_observer);
  initialize_callback.Run(DOWNLOAD_INTERRUPT_REASON_NONE);
  initialize_completion_loop.Run();

  RunAllPendingInMessageLoops();
  ASSERT_FALSE(target_callback.is_null());

  ScheduleObservations(PostTargetDeterminationObservations(),
                       destination_observer);
  target_callback.Run(base::FilePath(kDummyTargetPath),
                      DownloadItem::TARGET_DISPOSITION_OVERWRITE,
                      DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
                      base::FilePath(kDummyIntermediatePath));

  intermediate_rename_loop.Run();
  ASSERT_FALSE(intermediate_rename_callback.is_null());

  // This may or may not be called, depending on whether there are any errors in
  // our action list.
  EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(_, _))
      .Times(::testing::AnyNumber());

  ScheduleObservations(PostIntermediateRenameObservations(),
                       destination_observer);
  intermediate_rename_callback.Run(DOWNLOAD_INTERRUPT_REASON_NONE,
                                   base::FilePath(kDummyIntermediatePath));
  RunAllPendingInMessageLoops();

  // The state of the download depends on the observer events that were played
  // back to the DownloadItemImpl. Hence we can't establish a single expectation
  // here. On Debug builds, the DCHECKs will verify that the state transitions
  // were correct. On Release builds, tests are expected to run to completion
  // without crashing on success.
  EXPECT_TRUE(item_->GetState() == DownloadItem::IN_PROGRESS ||
              item_->GetState() == DownloadItem::INTERRUPTED);
  if (item_->GetState() == DownloadItem::INTERRUPTED)
    EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, item_->GetLastReason());

  item_->Cancel(true);
  RunAllPendingInMessageLoops();
}

TEST(MockDownloadItem, Compiles) {
  MockDownloadItem mock_item;
}

}  // namespace content
