blob: c95b8455b93f0ec60bab4a0897e0addea2f99535 [file] [log] [blame]
// Copyright 2015 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 "chrome/browser/download/notification/download_item_notification.h"
#include <stddef.h>
#include <utility>
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/test/test_simple_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/browser/download/notification/download_notification_manager.h"
#include "chrome/browser/notifications/notification_test_util.h"
#include "chrome/browser/notifications/platform_notification_service_impl.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "content/public/test/mock_download_item.h"
#include "content/public/test/mock_download_manager.h"
#include "content/public/test/test_browser_thread.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/message_center/fake_message_center.h"
using testing::NiceMock;
using testing::Return;
using testing::ReturnRefOfCopy;
using testing::_;
namespace {
const base::FilePath::CharType kDownloadItemTargetPathString[] =
FILE_PATH_LITERAL("/tmp/TITLE.bin");
} // anonymouse namespace
namespace test {
class MockMessageCenter : public message_center::FakeMessageCenter {
public:
MockMessageCenter() {}
~MockMessageCenter() override {}
void AddVisibleNotification(message_center::Notification* notification) {
visible_notifications_.insert(notification);
}
const message_center::NotificationList::Notifications&
GetVisibleNotifications() override {
return visible_notifications_;
}
private:
message_center::NotificationList::Notifications visible_notifications_;
DISALLOW_COPY_AND_ASSIGN(MockMessageCenter);
};
class DownloadItemNotificationTest : public testing::Test {
public:
DownloadItemNotificationTest()
: ui_thread_(content::BrowserThread::UI, &message_loop_),
profile_(nullptr) {}
void SetUp() override {
testing::Test::SetUp();
message_center::MessageCenter::Initialize();
profile_manager_.reset(
new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
ASSERT_TRUE(profile_manager_->SetUp());
profile_ = profile_manager_->CreateTestingProfile("test-user");
std::unique_ptr<NotificationUIManager> ui_manager(
new StubNotificationUIManager);
TestingBrowserProcess::GetGlobal()->SetNotificationUIManager(
std::move(ui_manager));
download_notification_manager_.reset(
new DownloadNotificationManagerForProfile(profile_, nullptr));
message_center_.reset(new MockMessageCenter());
download_notification_manager_->OverrideMessageCenterForTest(
message_center_.get());
base::FilePath download_item_target_path(kDownloadItemTargetPathString);
download_item_.reset(new NiceMock<content::MockDownloadItem>());
ON_CALL(*download_item_, GetId()).WillByDefault(Return(12345));
ON_CALL(*download_item_, GetState())
.WillByDefault(Return(content::DownloadItem::IN_PROGRESS));
ON_CALL(*download_item_, IsDangerous()).WillByDefault(Return(false));
ON_CALL(*download_item_, GetFileNameToReportUser())
.WillByDefault(Return(base::FilePath("TITLE.bin")));
ON_CALL(*download_item_, GetTargetFilePath())
.WillByDefault(ReturnRefOfCopy(download_item_target_path));
ON_CALL(*download_item_, GetDangerType())
.WillByDefault(Return(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS));
ON_CALL(*download_item_, IsDone()).WillByDefault(Return(false));
ON_CALL(*download_item_, GetURL()).WillByDefault(ReturnRefOfCopy(
GURL("http://www.example.com/download.bin")));
ON_CALL(*download_item_, GetBrowserContext())
.WillByDefault(Return(profile_));
}
void TearDown() override {
download_item_notification_ = nullptr; // will be free'd in the manager.
download_notification_manager_.reset();
profile_manager_.reset();
message_center::MessageCenter::Shutdown();
testing::Test::TearDown();
}
protected:
message_center::MessageCenter* message_center() const {
return message_center::MessageCenter::Get();
}
NotificationUIManager* ui_manager() const {
return TestingBrowserProcess::GetGlobal()->notification_ui_manager();
}
std::string notification_id() const {
return download_item_notification_->notification_->id();
}
const Notification* notification() const {
return ui_manager()->FindById(
download_item_notification_->watcher()->id(),
NotificationUIManager::GetProfileID(profile_));
}
size_t NotificationCount() const {
return ui_manager()
->GetAllIdsByProfileAndSourceOrigin(
NotificationUIManager::GetProfileID(profile_),
GURL(DownloadItemNotification::kDownloadNotificationOrigin))
.size();
}
void RemoveNotification() {
ui_manager()->CancelById(download_item_notification_->watcher()->id(),
NotificationUIManager::GetProfileID(profile_));
// Waits, since removing a notification may cause an async job.
base::RunLoop().RunUntilIdle();
}
// Trampoline methods to access a private method in DownloadItemNotification.
void NotificationItemClick() {
return download_item_notification_->OnNotificationClick();
}
void NotificationItemButtonClick(int index) {
return download_item_notification_->OnNotificationButtonClick(index);
}
bool ShownAsPopUp() {
return !notification()->shown_as_popup();
}
void CreateDownloadItemNotification() {
download_notification_manager_->OnNewDownloadReady(download_item_.get());
download_item_notification_ =
download_notification_manager_->items_[download_item_.get()].get();
message_center_->AddVisibleNotification(
download_item_notification_->notification_.get());
}
base::MessageLoopForUI message_loop_;
content::TestBrowserThread ui_thread_;
std::unique_ptr<TestingProfileManager> profile_manager_;
Profile* profile_;
std::unique_ptr<NiceMock<content::MockDownloadItem>> download_item_;
std::unique_ptr<DownloadNotificationManagerForProfile>
download_notification_manager_;
std::unique_ptr<MockMessageCenter> message_center_;
DownloadItemNotification* download_item_notification_;
};
TEST_F(DownloadItemNotificationTest, ShowAndCloseNotification) {
EXPECT_EQ(0u, NotificationCount());
// Shows a notification
CreateDownloadItemNotification();
download_item_->NotifyObserversDownloadOpened();
// Confirms that the notification is shown as a popup.
EXPECT_TRUE(ShownAsPopUp());
EXPECT_EQ(1u, NotificationCount());
// Makes sure the DownloadItem::Cancel() is not called.
EXPECT_CALL(*download_item_, Cancel(_)).Times(0);
// Closes it once.
RemoveNotification();
// Confirms that the notification is closed.
EXPECT_EQ(0u, NotificationCount());
// Makes sure the DownloadItem::Cancel() is never called.
EXPECT_CALL(*download_item_, Cancel(_)).Times(0);
}
TEST_F(DownloadItemNotificationTest, PauseAndResumeNotification) {
// Shows a notification
CreateDownloadItemNotification();
download_item_->NotifyObserversDownloadOpened();
// Confirms that the notification is shown as a popup.
EXPECT_EQ(1u, NotificationCount());
// Pauses and makes sure the DownloadItem::Pause() is called.
EXPECT_CALL(*download_item_, Pause()).Times(1);
EXPECT_CALL(*download_item_, IsPaused()).WillRepeatedly(Return(true));
NotificationItemButtonClick(0);
download_item_->NotifyObserversDownloadUpdated();
// Resumes and makes sure the DownloadItem::Resume() is called.
EXPECT_CALL(*download_item_, Resume()).Times(1);
EXPECT_CALL(*download_item_, IsPaused()).WillRepeatedly(Return(false));
NotificationItemButtonClick(0);
download_item_->NotifyObserversDownloadUpdated();
}
TEST_F(DownloadItemNotificationTest, OpenDownload) {
EXPECT_CALL(*download_item_, GetState())
.WillRepeatedly(Return(content::DownloadItem::COMPLETE));
EXPECT_CALL(*download_item_, IsDone()).WillRepeatedly(Return(true));
// Shows a notification.
CreateDownloadItemNotification();
download_item_->NotifyObserversDownloadOpened();
download_item_->NotifyObserversDownloadUpdated();
// Clicks and confirms that the OpenDownload() is called.
EXPECT_CALL(*download_item_, OpenDownload()).Times(1);
EXPECT_CALL(*download_item_, SetOpenWhenComplete(_)).Times(0);
NotificationItemClick();
}
TEST_F(DownloadItemNotificationTest, OpenWhenComplete) {
// Shows a notification
CreateDownloadItemNotification();
download_item_->NotifyObserversDownloadOpened();
EXPECT_CALL(*download_item_, OpenDownload()).Times(0);
// Toggles open-when-complete (new value: true).
EXPECT_CALL(*download_item_, SetOpenWhenComplete(true))
.Times(1)
.WillOnce(Return());
NotificationItemClick();
EXPECT_CALL(*download_item_, GetOpenWhenComplete())
.WillRepeatedly(Return(true));
// Toggles open-when-complete (new value: false).
EXPECT_CALL(*download_item_, SetOpenWhenComplete(false))
.Times(1)
.WillOnce(Return());
NotificationItemClick();
EXPECT_CALL(*download_item_, GetOpenWhenComplete())
.WillRepeatedly(Return(false));
// Sets open-when-complete.
EXPECT_CALL(*download_item_, SetOpenWhenComplete(true))
.Times(1)
.WillOnce(Return());
NotificationItemClick();
EXPECT_CALL(*download_item_, GetOpenWhenComplete())
.WillRepeatedly(Return(true));
// Downloading is completed.
EXPECT_CALL(*download_item_, GetState())
.WillRepeatedly(Return(content::DownloadItem::COMPLETE));
EXPECT_CALL(*download_item_, IsDone()).WillRepeatedly(Return(true));
download_item_->NotifyObserversDownloadUpdated();
// DownloadItem::OpenDownload must not be called since the file opens
// automatically due to the open-when-complete flag.
}
TEST_F(DownloadItemNotificationTest, DisablePopup) {
CreateDownloadItemNotification();
download_item_->NotifyObserversDownloadOpened();
EXPECT_EQ(message_center::DEFAULT_PRIORITY, notification()->priority());
download_item_notification_->DisablePopup();
// Priority is low.
EXPECT_EQ(message_center::LOW_PRIORITY, notification()->priority());
// Downloading is completed.
EXPECT_CALL(*download_item_, GetState())
.WillRepeatedly(Return(content::DownloadItem::COMPLETE));
EXPECT_CALL(*download_item_, IsDone()).WillRepeatedly(Return(true));
download_item_->NotifyObserversDownloadUpdated();
// Priority is updated back to normal.
EXPECT_EQ(message_center::DEFAULT_PRIORITY, notification()->priority());
}
} // namespace test