| Index: chrome/browser/download/download_ui_controller_unittest.cc
|
| diff --git a/chrome/browser/download/download_ui_controller_unittest.cc b/chrome/browser/download/download_ui_controller_unittest.cc
|
| index 7a83aa339cf40c5645d95b0e01968c466dbd4900..d5dc4dec3c02a9c26f9d69bff00a46e0042cedbb 100644
|
| --- a/chrome/browser/download/download_ui_controller_unittest.cc
|
| +++ b/chrome/browser/download/download_ui_controller_unittest.cc
|
| @@ -2,11 +2,20 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| +#include "base/bind.h"
|
| +#include "base/callback.h"
|
| #include "base/files/file_path.h"
|
| #include "base/memory/ref_counted.h"
|
| #include "base/memory/scoped_ptr.h"
|
| #include "base/memory/weak_ptr.h"
|
| +#include "base/observer_list.h"
|
| +#include "chrome/browser/download/download_history.h"
|
| +#include "chrome/browser/download/download_service.h"
|
| +#include "chrome/browser/download/download_service_factory.h"
|
| #include "chrome/browser/download/download_ui_controller.h"
|
| +#include "chrome/browser/history/download_row.h"
|
| +#include "chrome/browser/profiles/profile.h"
|
| +#include "chrome/test/base/chrome_render_view_host_test_harness.h"
|
| #include "content/public/test/mock_download_item.h"
|
| #include "content/public/test/mock_download_manager.h"
|
| #include "testing/gmock/include/gmock/gmock.h"
|
| @@ -31,7 +40,7 @@ class TestDelegate : public DownloadUIController::Delegate {
|
| virtual ~TestDelegate() {}
|
|
|
| private:
|
| - virtual void NotifyDownloadStarting(content::DownloadItem* item) OVERRIDE;
|
| + virtual void OnNewDownloadReady(content::DownloadItem* item) OVERRIDE;
|
|
|
| base::WeakPtr<content::DownloadItem*> receiver_;
|
| };
|
| @@ -40,12 +49,39 @@ TestDelegate::TestDelegate(base::WeakPtr<content::DownloadItem*> receiver)
|
| : receiver_(receiver) {
|
| }
|
|
|
| -void TestDelegate::NotifyDownloadStarting(content::DownloadItem* item) {
|
| +void TestDelegate::OnNewDownloadReady(content::DownloadItem* item) {
|
| if (receiver_.get())
|
| *receiver_ = item;
|
| }
|
|
|
| -class DownloadUIControllerTest : public testing::Test {
|
| +// A DownloadService that returns a custom DownloadHistory.
|
| +class TestDownloadService : public DownloadService {
|
| + public:
|
| + explicit TestDownloadService(Profile* profile);
|
| + virtual ~TestDownloadService();
|
| +
|
| + void set_download_history(scoped_ptr<DownloadHistory> download_history) {
|
| + download_history_.swap(download_history);
|
| + }
|
| + virtual DownloadHistory* GetDownloadHistory() OVERRIDE;
|
| +
|
| + private:
|
| + scoped_ptr<DownloadHistory> download_history_;
|
| +};
|
| +
|
| +TestDownloadService::TestDownloadService(Profile* profile)
|
| + : DownloadService(profile) {
|
| +}
|
| +
|
| +TestDownloadService::~TestDownloadService() {
|
| +}
|
| +
|
| +DownloadHistory* TestDownloadService::GetDownloadHistory() {
|
| + return download_history_.get();
|
| +}
|
| +
|
| +// The test fixture:
|
| +class DownloadUIControllerTest : public ChromeRenderViewHostTestHarness {
|
| public:
|
| DownloadUIControllerTest();
|
|
|
| @@ -53,103 +89,258 @@ class DownloadUIControllerTest : public testing::Test {
|
| // testing::Test
|
| virtual void SetUp() OVERRIDE;
|
|
|
| - // Returns a TestDelegate. Invoking NotifyDownloadStarting on the returned
|
| - // delegate results in the DownloadItem* being stored in |received_item_|.
|
| + // Returns a TestDelegate. Invoking OnNewDownloadReady on the returned
|
| + // delegate results in the DownloadItem* being stored in |notified_item_|.
|
| scoped_ptr<DownloadUIController::Delegate> GetTestDelegate();
|
|
|
| MockDownloadManager* manager() { return manager_.get(); }
|
| +
|
| + // Returns the DownloadManager::Observer registered by a test case. This is
|
| + // the DownloadUIController's observer for all current test cases.
|
| content::DownloadManager::Observer* manager_observer() {
|
| return manager_observer_;
|
| }
|
| - content::DownloadItem* received_item() { return received_item_; }
|
| +
|
| + // The most recent DownloadItem that was passed into OnNewDownloadReady().
|
| + content::DownloadItem* notified_item() { return notified_item_; }
|
| +
|
| + // DownloadHistory performs a query of existing downloads when it is first
|
| + // instantiated. This method returns the completion callback for that query.
|
| + // It can be used to inject history downloads.
|
| + const HistoryService::DownloadQueryCallback& history_query_callback() const {
|
| + return history_adapter_->download_query_callback_;
|
| + }
|
| +
|
| + // DownloadManager::Observer registered by DownloadHistory.
|
| + content::DownloadManager::Observer* download_history_manager_observer() {
|
| + return download_history_manager_observer_;
|
| + }
|
| +
|
| + scoped_ptr<MockDownloadItem> CreateMockInProgressDownload();
|
|
|
| private:
|
| + // A private history adapter that stores the DownloadQueryCallback when
|
| + // QueryDownloads is called.
|
| + class HistoryAdapter : public DownloadHistory::HistoryAdapter {
|
| + public:
|
| + HistoryAdapter() : DownloadHistory::HistoryAdapter(NULL) {}
|
| + HistoryService::DownloadQueryCallback download_query_callback_;
|
| +
|
| + private:
|
| + virtual void QueryDownloads(
|
| + const HistoryService::DownloadQueryCallback& callback) OVERRIDE {
|
| + download_query_callback_ = callback;
|
| + }
|
| + };
|
| +
|
| + // Constructs and returns a TestDownloadService.
|
| + static KeyedService* TestingDownloadServiceFactory(
|
| + content::BrowserContext* brwoser_context);
|
| +
|
| scoped_ptr<MockDownloadManager> manager_;
|
| + content::DownloadManager::Observer* download_history_manager_observer_;
|
| content::DownloadManager::Observer* manager_observer_;
|
| - content::DownloadItem* received_item_;
|
| + content::DownloadItem* notified_item_;
|
| + base::WeakPtrFactory<content::DownloadItem*> notified_item_receiver_factory_;
|
|
|
| - base::WeakPtrFactory<content::DownloadItem*> receiver_factory_;
|
| + HistoryAdapter* history_adapter_;
|
| };
|
|
|
| +// static
|
| +KeyedService* DownloadUIControllerTest::TestingDownloadServiceFactory(
|
| + content::BrowserContext* browser_context) {
|
| + return new TestDownloadService(Profile::FromBrowserContext(browser_context));
|
| +}
|
| +
|
| DownloadUIControllerTest::DownloadUIControllerTest()
|
| - : manager_observer_(NULL),
|
| - received_item_(NULL),
|
| - receiver_factory_(&received_item_) {
|
| + : download_history_manager_observer_(NULL),
|
| + manager_observer_(NULL),
|
| + notified_item_(NULL),
|
| + notified_item_receiver_factory_(¬ified_item_) {
|
| }
|
|
|
| void DownloadUIControllerTest::SetUp() {
|
| + ChromeRenderViewHostTestHarness::SetUp();
|
| +
|
| manager_.reset(new testing::StrictMock<MockDownloadManager>());
|
| EXPECT_CALL(*manager_, AddObserver(_))
|
| + .WillOnce(SaveArg<0>(&download_history_manager_observer_));
|
| + EXPECT_CALL(*manager_,
|
| + RemoveObserver(testing::Eq(
|
| + testing::ByRef(download_history_manager_observer_))))
|
| + .WillOnce(testing::Assign(
|
| + &download_history_manager_observer_,
|
| + static_cast<content::DownloadManager::Observer*>(NULL)));
|
| + EXPECT_CALL(*manager_, GetAllDownloads(_)).Times(AnyNumber());
|
| +
|
| + scoped_ptr<HistoryAdapter> history_adapter(new HistoryAdapter);
|
| + history_adapter_ = history_adapter.get();
|
| + scoped_ptr<DownloadHistory> download_history(new DownloadHistory(
|
| + manager_.get(),
|
| + history_adapter.PassAs<DownloadHistory::HistoryAdapter>()));
|
| + ASSERT_TRUE(download_history_manager_observer_);
|
| +
|
| + EXPECT_CALL(*manager_, AddObserver(_))
|
| .WillOnce(SaveArg<0>(&manager_observer_));
|
| - EXPECT_CALL(*manager_, RemoveObserver(_))
|
| - .WillOnce(Assign(&manager_observer_,
|
| - static_cast<content::DownloadManager::Observer*>(NULL)));
|
| - EXPECT_CALL(*manager_, GetAllDownloads(_));
|
| + EXPECT_CALL(*manager_,
|
| + RemoveObserver(testing::Eq(testing::ByRef(manager_observer_))))
|
| + .WillOnce(testing::Assign(
|
| + &manager_observer_,
|
| + static_cast<content::DownloadManager::Observer*>(NULL)));
|
| + TestDownloadService* download_service = static_cast<TestDownloadService*>(
|
| + DownloadServiceFactory::GetInstance()->SetTestingFactoryAndUse(
|
| + browser_context(), &TestingDownloadServiceFactory));
|
| + ASSERT_TRUE(download_service);
|
| + download_service->set_download_history(download_history.Pass());
|
| +}
|
| +
|
| +scoped_ptr<MockDownloadItem>
|
| +DownloadUIControllerTest::CreateMockInProgressDownload() {
|
| + scoped_ptr<MockDownloadItem> item(
|
| + new testing::StrictMock<MockDownloadItem>());
|
| + EXPECT_CALL(*item, GetBrowserContext())
|
| + .WillRepeatedly(Return(browser_context()));
|
| + EXPECT_CALL(*item, GetId()).WillRepeatedly(Return(1));
|
| + EXPECT_CALL(*item, GetTargetFilePath()).WillRepeatedly(
|
| + ReturnRefOfCopy(base::FilePath(FILE_PATH_LITERAL("foo"))));
|
| + EXPECT_CALL(*item, GetFullPath()).WillRepeatedly(
|
| + ReturnRefOfCopy(base::FilePath(FILE_PATH_LITERAL("foo"))));
|
| + EXPECT_CALL(*item, GetState())
|
| + .WillRepeatedly(Return(content::DownloadItem::IN_PROGRESS));
|
| + EXPECT_CALL(*item, GetUrlChain())
|
| + .WillRepeatedly(testing::ReturnRefOfCopy(std::vector<GURL>()));
|
| + EXPECT_CALL(*item, GetReferrerUrl())
|
| + .WillRepeatedly(testing::ReturnRefOfCopy(GURL()));
|
| + EXPECT_CALL(*item, GetStartTime()).WillRepeatedly(Return(base::Time()));
|
| + EXPECT_CALL(*item, GetEndTime()).WillRepeatedly(Return(base::Time()));
|
| + EXPECT_CALL(*item, GetETag()).WillRepeatedly(ReturnRefOfCopy(std::string()));
|
| + EXPECT_CALL(*item, GetLastModifiedTime())
|
| + .WillRepeatedly(ReturnRefOfCopy(std::string()));
|
| + EXPECT_CALL(*item, GetDangerType())
|
| + .WillRepeatedly(Return(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS));
|
| + EXPECT_CALL(*item, GetLastReason())
|
| + .WillRepeatedly(Return(content::DOWNLOAD_INTERRUPT_REASON_NONE));
|
| + EXPECT_CALL(*item, GetReceivedBytes()).WillRepeatedly(Return(0));
|
| + EXPECT_CALL(*item, GetTotalBytes()).WillRepeatedly(Return(0));
|
| + EXPECT_CALL(*item, GetTargetDisposition()).WillRepeatedly(
|
| + Return(content::DownloadItem::TARGET_DISPOSITION_OVERWRITE));
|
| + EXPECT_CALL(*item, GetOpened()).WillRepeatedly(Return(false));
|
| + EXPECT_CALL(*item, GetMimeType()).WillRepeatedly(Return(std::string()));
|
| + EXPECT_CALL(*item, GetURL()).WillRepeatedly(testing::ReturnRefOfCopy(GURL()));
|
| + EXPECT_CALL(*item, IsTemporary()).WillRepeatedly(Return(false));
|
| + return item.Pass();
|
| }
|
|
|
| scoped_ptr<DownloadUIController::Delegate>
|
| DownloadUIControllerTest::GetTestDelegate() {
|
| scoped_ptr<DownloadUIController::Delegate> delegate(
|
| - new TestDelegate(receiver_factory_.GetWeakPtr()));
|
| + new TestDelegate(notified_item_receiver_factory_.GetWeakPtr()));
|
| return delegate.Pass();
|
| }
|
|
|
| -// Normal downloads that are constructed in the IN_PROGRESS state should be
|
| -// presented to the UI when GetTargetFilePath() returns a non-empty path.
|
| -// I.e. once the download target has been determined.
|
| +// New downloads should be presented to the UI when GetTargetFilePath() returns
|
| +// a non-empty path. I.e. once the download target has been determined.
|
| TEST_F(DownloadUIControllerTest, DownloadUIController_NotifyBasic) {
|
| - scoped_ptr<MockDownloadItem> item(new MockDownloadItem);
|
| + scoped_ptr<MockDownloadItem> item(CreateMockInProgressDownload());
|
| DownloadUIController controller(manager(), GetTestDelegate());
|
| EXPECT_CALL(*item, GetTargetFilePath())
|
| .WillOnce(ReturnRefOfCopy(base::FilePath()));
|
| - EXPECT_CALL(*item, GetState())
|
| - .WillRepeatedly(Return(content::DownloadItem::IN_PROGRESS));
|
|
|
| ASSERT_TRUE(manager_observer());
|
| manager_observer()->OnDownloadCreated(manager(), item.get());
|
|
|
| // The destination for the download hasn't been determined yet. It should not
|
| // be displayed.
|
| - EXPECT_FALSE(received_item());
|
| + EXPECT_FALSE(notified_item());
|
|
|
| // Once the destination has been determined, then it should be displayed.
|
| EXPECT_CALL(*item, GetTargetFilePath())
|
| .WillOnce(ReturnRefOfCopy(base::FilePath(FILE_PATH_LITERAL("foo"))));
|
| item->NotifyObserversDownloadUpdated();
|
|
|
| - EXPECT_EQ(static_cast<content::DownloadItem*>(item.get()), received_item());
|
| + EXPECT_EQ(static_cast<content::DownloadItem*>(item.get()), notified_item());
|
| +}
|
| +
|
| +// A download that's created in an interrupted state should also be displayed.
|
| +TEST_F(DownloadUIControllerTest, DownloadUIController_NotifyBasic_Interrupted) {
|
| + scoped_ptr<MockDownloadItem> item = CreateMockInProgressDownload();
|
| + DownloadUIController controller(manager(), GetTestDelegate());
|
| + EXPECT_CALL(*item, GetState())
|
| + .WillRepeatedly(Return(content::DownloadItem::INTERRUPTED));
|
| +
|
| + ASSERT_TRUE(manager_observer());
|
| + manager_observer()->OnDownloadCreated(manager(), item.get());
|
| + EXPECT_EQ(static_cast<content::DownloadItem*>(item.get()), notified_item());
|
| }
|
|
|
| // Downloads that have a target path on creation and are in the IN_PROGRESS
|
| // state should be displayed in the UI immediately without requiring an
|
| // additional OnDownloadUpdated() notification.
|
| TEST_F(DownloadUIControllerTest, DownloadUIController_NotifyReadyOnCreate) {
|
| - scoped_ptr<MockDownloadItem> item(new MockDownloadItem);
|
| + scoped_ptr<MockDownloadItem> item(CreateMockInProgressDownload());
|
| DownloadUIController controller(manager(), GetTestDelegate());
|
| - EXPECT_CALL(*item, GetTargetFilePath())
|
| - .WillOnce(ReturnRefOfCopy(base::FilePath(FILE_PATH_LITERAL("foo"))));
|
| - EXPECT_CALL(*item, GetState())
|
| - .WillRepeatedly(Return(content::DownloadItem::IN_PROGRESS));
|
|
|
| ASSERT_TRUE(manager_observer());
|
| manager_observer()->OnDownloadCreated(manager(), item.get());
|
| - EXPECT_EQ(static_cast<content::DownloadItem*>(item.get()), received_item());
|
| + EXPECT_EQ(static_cast<content::DownloadItem*>(item.get()), notified_item());
|
| }
|
|
|
| -// History downloads (downloads that are not in IN_PROGRESS on create) should
|
| -// not be displayed on the shelf.
|
| -TEST_F(DownloadUIControllerTest, DownloadUIController_NoNotifyHistory) {
|
| - scoped_ptr<MockDownloadItem> item(new MockDownloadItem);
|
| +// The UI shouldn't be notified of downloads that were restored from history.
|
| +TEST_F(DownloadUIControllerTest, DownloadUIController_HistoryDownload) {
|
| DownloadUIController controller(manager(), GetTestDelegate());
|
| - EXPECT_CALL(*item, GetState())
|
| - .WillRepeatedly(Return(content::DownloadItem::COMPLETE));
|
| + // DownloadHistory should already have been created. It performs a query of
|
| + // existing downloads upon creation. We'll use the callback to inject a
|
| + // history download.
|
| + ASSERT_FALSE(history_query_callback().is_null());
|
| +
|
| + // download_history_manager_observer is the DownloadManager::Observer
|
| + // registered by the DownloadHistory. DownloadHistory relies on the
|
| + // OnDownloadCreated notification to mark a download as having been restored
|
| + // from history.
|
| + ASSERT_TRUE(download_history_manager_observer());
|
| +
|
| + scoped_ptr<std::vector<history::DownloadRow> > history_downloads;
|
| + history_downloads.reset(new std::vector<history::DownloadRow>());
|
| + history_downloads->push_back(history::DownloadRow());
|
| + history_downloads->front().id = 1;
|
|
|
| + std::vector<GURL> url_chain;
|
| + GURL url;
|
| + scoped_ptr<MockDownloadItem> item = CreateMockInProgressDownload();
|
| +
|
| + EXPECT_CALL(*manager(), CheckForHistoryFilesRemoval());
|
| +
|
| + {
|
| + testing::InSequence s;
|
| + testing::MockFunction<void()> mock_function;
|
| + // DownloadHistory will immediately try to create a download using the info
|
| + // we push through the query callback. When DownloadManager::CreateDownload
|
| + // is called, we need to first invoke the OnDownloadCreated callback for
|
| + // DownloadHistory before returning the DownloadItem since that's the
|
| + // sequence of events expected by DownloadHistory.
|
| + base::Closure history_on_created_callback =
|
| + base::Bind(&content::DownloadManager::Observer::OnDownloadCreated,
|
| + base::Unretained(download_history_manager_observer()),
|
| + manager(),
|
| + item.get());
|
| + EXPECT_CALL(*manager(), MockCreateDownloadItem(_)).WillOnce(
|
| + testing::DoAll(testing::InvokeWithoutArgs(&history_on_created_callback,
|
| + &base::Closure::Run),
|
| + Return(item.get())));
|
| + EXPECT_CALL(mock_function, Call());
|
| +
|
| + history_query_callback().Run(history_downloads.Pass());
|
| + mock_function.Call();
|
| + }
|
| +
|
| + // Now pass along the notification to the OnDownloadCreated observer from
|
| + // DownloadUIController. It should ignore the download since it's marked as
|
| + // being restored from history.
|
| ASSERT_TRUE(manager_observer());
|
| manager_observer()->OnDownloadCreated(manager(), item.get());
|
| - EXPECT_FALSE(received_item());
|
|
|
| - item->NotifyObserversDownloadUpdated();
|
| - EXPECT_FALSE(received_item());
|
| + // Finally, the expectation we've been waiting for:
|
| + EXPECT_FALSE(notified_item());
|
| }
|
|
|
| } // namespace
|
|
|