Commit 64bec395 authored by Xing Liu's avatar Xing Liu Committed by Commit Bot

Notification scheduler: Add more unit test for NotificationSchedulerTest.

This CL adds test to cover all functions in NotificationScheduler.

Bug: 963304
Change-Id: I9f63cd4ec9e1e3ed761c10ac7f2e0539294e026c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1732289
Commit-Queue: Xing Liu <xingliu@chromium.org>
Reviewed-by: default avatarHesen Zhang <hesen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#684117}
parent b04779b1
...@@ -234,7 +234,10 @@ class NotificationSchedulerImpl : public NotificationScheduler, ...@@ -234,7 +234,10 @@ class NotificationSchedulerImpl : public NotificationScheduler,
} }
// ImpressionHistoryTracker::Delegate implementation. // ImpressionHistoryTracker::Delegate implementation.
void OnImpressionUpdated() override { ScheduleBackgroundTask(); } void OnImpressionUpdated() override {
// TODO(xingliu): Fix duplicate ScheduleBackgroundTask() call.
ScheduleBackgroundTask();
}
void FindNotificationToShow(SchedulerTaskTime task_start_time) { void FindNotificationToShow(SchedulerTaskTime task_start_time) {
DisplayDecider::Results results; DisplayDecider::Results results;
......
...@@ -9,10 +9,14 @@ ...@@ -9,10 +9,14 @@
#include <utility> #include <utility>
#include "base/bind.h" #include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_task_environment.h" #include "base/test/scoped_task_environment.h"
#include "chrome/browser/notifications/scheduler/internal/notification_entry.h"
#include "chrome/browser/notifications/scheduler/internal/notification_scheduler_context.h" #include "chrome/browser/notifications/scheduler/internal/notification_scheduler_context.h"
#include "chrome/browser/notifications/scheduler/internal/scheduler_config.h" #include "chrome/browser/notifications/scheduler/internal/scheduler_config.h"
#include "chrome/browser/notifications/scheduler/public/notification_scheduler_client_registrar.h" #include "chrome/browser/notifications/scheduler/public/notification_scheduler_client_registrar.h"
#include "chrome/browser/notifications/scheduler/public/notification_scheduler_types.h"
#include "chrome/browser/notifications/scheduler/test/mock_background_task_coordinator.h" #include "chrome/browser/notifications/scheduler/test/mock_background_task_coordinator.h"
#include "chrome/browser/notifications/scheduler/test/mock_display_agent.h" #include "chrome/browser/notifications/scheduler/test/mock_display_agent.h"
#include "chrome/browser/notifications/scheduler/test/mock_display_decider.h" #include "chrome/browser/notifications/scheduler/test/mock_display_decider.h"
...@@ -27,17 +31,25 @@ using ::testing::_; ...@@ -27,17 +31,25 @@ using ::testing::_;
using ::testing::Invoke; using ::testing::Invoke;
using ::testing::InvokeWithoutArgs; using ::testing::InvokeWithoutArgs;
using ::testing::NiceMock; using ::testing::NiceMock;
using ::testing::SetArgPointee;
namespace notifications { namespace notifications {
namespace { namespace {
const char kGuid[] = "guid";
const char kTitle[] = "title";
class NotificationSchedulerTest : public testing::Test { class NotificationSchedulerTest : public testing::Test {
public: public:
NotificationSchedulerTest() NotificationSchedulerTest()
: registrar_(nullptr), : registrar_(nullptr),
impression_tracker_(nullptr), impression_tracker_(nullptr),
notification_manager_(nullptr), notification_manager_(nullptr),
client_(nullptr) {} client_(nullptr),
task_coordinator_(nullptr),
display_agent_(nullptr),
display_decider_(nullptr),
notification_manager_delegate_(nullptr) {}
~NotificationSchedulerTest() override = default; ~NotificationSchedulerTest() override = default;
void SetUp() override { void SetUp() override {
...@@ -55,6 +67,9 @@ class NotificationSchedulerTest : public testing::Test { ...@@ -55,6 +67,9 @@ class NotificationSchedulerTest : public testing::Test {
registrar_ = registrar.get(); registrar_ = registrar.get();
impression_tracker_ = impression_tracker.get(); impression_tracker_ = impression_tracker.get();
notification_manager_ = notification_manager.get(); notification_manager_ = notification_manager.get();
task_coordinator_ = task_coordinator.get();
display_agent_ = display_agent.get();
display_decider_ = display_decider.get();
// Register mock clients. // Register mock clients.
auto client = std::make_unique<test::MockNotificationSchedulerClient>(); auto client = std::make_unique<test::MockNotificationSchedulerClient>();
...@@ -70,6 +85,31 @@ class NotificationSchedulerTest : public testing::Test { ...@@ -70,6 +85,31 @@ class NotificationSchedulerTest : public testing::Test {
} }
protected: protected:
void Init() {
EXPECT_CALL(*impression_tracker(), Init(_, _))
.WillOnce(Invoke([&](ImpressionHistoryTracker::Delegate* delegate,
ImpressionHistoryTracker::InitCallback callback) {
std::move(callback).Run(true);
}));
EXPECT_CALL(*notification_manager(), Init(_, _))
.WillOnce(
Invoke([&](ScheduledNotificationManager::Delegate* delegate,
ScheduledNotificationManager::InitCallback callback) {
notification_manager_delegate_ = delegate;
std::move(callback).Run(true);
}));
base::RunLoop run_loop;
scheduler()->Init(
base::BindOnce([](bool success) { EXPECT_TRUE(success); }));
EXPECT_CALL(*client(), OnSchedulerInitialized(true, _))
.WillOnce(InvokeWithoutArgs([&]() { run_loop.Quit(); }));
run_loop.Run();
}
NotificationScheduler* scheduler() { return notification_scheduler_.get(); } NotificationScheduler* scheduler() { return notification_scheduler_.get(); }
test::MockImpressionHistoryTracker* impression_tracker() { test::MockImpressionHistoryTracker* impression_tracker() {
...@@ -82,12 +122,29 @@ class NotificationSchedulerTest : public testing::Test { ...@@ -82,12 +122,29 @@ class NotificationSchedulerTest : public testing::Test {
test::MockNotificationSchedulerClient* client() { return client_; } test::MockNotificationSchedulerClient* client() { return client_; }
test::MockBackgroundTaskCoordinator* task_coordinator() {
return task_coordinator_;
}
test::MockDisplayAgent* display_agent() { return display_agent_; }
test::MockDisplayDecider* display_decider() { return display_decider_; }
ScheduledNotificationManager::Delegate* notification_manager_delegate() {
return notification_manager_delegate_;
}
private: private:
base::test::ScopedTaskEnvironment scoped_task_environment_; base::test::ScopedTaskEnvironment scoped_task_environment_;
NotificationSchedulerClientRegistrar* registrar_; NotificationSchedulerClientRegistrar* registrar_;
test::MockImpressionHistoryTracker* impression_tracker_; test::MockImpressionHistoryTracker* impression_tracker_;
test::MockScheduledNotificationManager* notification_manager_; test::MockScheduledNotificationManager* notification_manager_;
test::MockNotificationSchedulerClient* client_; test::MockNotificationSchedulerClient* client_;
test::MockBackgroundTaskCoordinator* task_coordinator_;
test::MockDisplayAgent* display_agent_;
test::MockDisplayDecider* display_decider_;
ScheduledNotificationManager::Delegate* notification_manager_delegate_;
std::unique_ptr<NotificationScheduler> notification_scheduler_; std::unique_ptr<NotificationScheduler> notification_scheduler_;
DISALLOW_COPY_AND_ASSIGN(NotificationSchedulerTest); DISALLOW_COPY_AND_ASSIGN(NotificationSchedulerTest);
...@@ -95,25 +152,7 @@ class NotificationSchedulerTest : public testing::Test { ...@@ -95,25 +152,7 @@ class NotificationSchedulerTest : public testing::Test {
// Tests successful initialization flow. // Tests successful initialization flow.
TEST_F(NotificationSchedulerTest, InitSuccess) { TEST_F(NotificationSchedulerTest, InitSuccess) {
EXPECT_CALL(*impression_tracker(), Init(_, _)) Init();
.WillOnce(Invoke([](ImpressionHistoryTracker::Delegate* delegate,
ImpressionHistoryTracker::InitCallback callback) {
std::move(callback).Run(true);
}));
EXPECT_CALL(*notification_manager(), Init(_, _))
.WillOnce(Invoke([](ScheduledNotificationManager::Delegate* delegate,
ScheduledNotificationManager::InitCallback callback) {
std::move(callback).Run(true);
}));
base::RunLoop run_loop;
scheduler()->Init(base::BindOnce([](bool success) { EXPECT_TRUE(success); }));
EXPECT_CALL(*client(), OnSchedulerInitialized(true, _))
.WillOnce(InvokeWithoutArgs([&]() { run_loop.Quit(); }));
run_loop.Run();
} }
// Tests the case when impression tracker failed to initialize. // Tests the case when impression tracker failed to initialize.
...@@ -162,5 +201,125 @@ TEST_F(NotificationSchedulerTest, InitScheduledNotificationManagerFailed) { ...@@ -162,5 +201,125 @@ TEST_F(NotificationSchedulerTest, InitScheduledNotificationManagerFailed) {
run_loop.Run(); run_loop.Run();
} }
// Test to schedule a notification.
TEST_F(NotificationSchedulerTest, Schedule) {
Init();
auto param = std::unique_ptr<NotificationParams>();
EXPECT_CALL(*notification_manager(), ScheduleNotification(_));
EXPECT_CALL(*task_coordinator(), ScheduleBackgroundTask(_, _, _));
scheduler()->Schedule(std::move(param));
}
// Test to delete notifications.
TEST_F(NotificationSchedulerTest, DeleteAllNotifications) {
Init();
// Currently we don't reschedule background task even if all the notifications
// are deleted.
EXPECT_CALL(*task_coordinator(), ScheduleBackgroundTask(_, _, _)).Times(0);
EXPECT_CALL(*notification_manager(),
DeleteNotifications(SchedulerClientType::kTest1));
scheduler()->DeleteAllNotifications(SchedulerClientType::kTest1);
}
// Test to get impression details.
TEST_F(NotificationSchedulerTest, GetImpressionDetail) {
Init();
EXPECT_CALL(*impression_tracker(),
GetImpressionDetail(SchedulerClientType::kTest1, _));
scheduler()->GetImpressionDetail(SchedulerClientType::kTest1,
base::DoNothing());
}
// Test to verify user actions are propagated through correctly.
TEST_F(NotificationSchedulerTest, OnUserAction) {
Init();
base::RunLoop loop;
UserActionData action_data(SchedulerClientType::kTest1,
UserActionType::kButtonClick, kGuid);
EXPECT_CALL(*impression_tracker(), OnUserAction(action_data));
EXPECT_CALL(*client(), OnUserAction(_)).WillOnce(InvokeWithoutArgs([&]() {
loop.Quit();
}));
scheduler()->OnUserAction(action_data);
loop.Run();
}
// Test to simulate a background task flow without any notification shown.
TEST_F(NotificationSchedulerTest, BackgroundTaskStartShowNothing) {
Init();
// No notification picked to show.
DisplayDecider::Results result;
EXPECT_CALL(*display_decider(), FindNotificationsToShow(_, _, _, _, _, _, _))
.WillOnce(SetArgPointee<6>(result));
EXPECT_CALL(*display_agent(), ShowNotification(_, _)).Times(0);
EXPECT_CALL(*notification_manager(), DisplayNotification(_)).Times(0);
EXPECT_CALL(*task_coordinator(), ScheduleBackgroundTask(_, _, _));
scheduler()->OnStartTask(SchedulerTaskTime::kMorning, base::DoNothing());
}
MATCHER_P(NotifcationDataEq, title, "Verify notification data.") {
EXPECT_EQ(arg->title, base::UTF8ToUTF16(title));
return true;
}
MATCHER_P2(SystemDataEq, type, guid, "Verify system data.") {
EXPECT_EQ(arg->type, type);
EXPECT_EQ(arg->guid, guid);
return true;
}
// Test to simulate a background task flow with some notifications shown.
TEST_F(NotificationSchedulerTest, BackgroundTaskStartShowNotification) {
Init();
base::RunLoop loop;
// Mock the notification guid to show.
auto entry =
std::make_unique<NotificationEntry>(SchedulerClientType::kTest1, kGuid);
EXPECT_CALL(
*display_agent(),
ShowNotification(NotifcationDataEq(kTitle),
SystemDataEq(SchedulerClientType::kTest1, kGuid)));
DisplayDecider::Results result({kGuid});
EXPECT_CALL(*display_decider(), FindNotificationsToShow(_, _, _, _, _, _, _))
.WillOnce(SetArgPointee<6>(result));
EXPECT_CALL(*impression_tracker(), AddImpression(_, _));
EXPECT_CALL(*client(), BeforeShowNotification(_, _))
.WillOnce(Invoke(
[&](std::unique_ptr<NotificationData> notification_data,
NotificationSchedulerClient::NotificationDataCallback callback) {
// The client updates the notification data here.
notification_data->title = base::UTF8ToUTF16(kTitle);
std::move(callback).Run(std::move(notification_data));
loop.Quit();
}));
EXPECT_CALL(*notification_manager(), DisplayNotification(_))
.WillOnce(InvokeWithoutArgs([&]() {
notification_manager_delegate()->DisplayNotification(std::move(entry));
}));
EXPECT_CALL(*task_coordinator(), ScheduleBackgroundTask(_, _, _));
scheduler()->OnStartTask(SchedulerTaskTime::kMorning, base::DoNothing());
loop.Run();
}
// Test to simulate a background task stopped by the OS.
TEST_F(NotificationSchedulerTest, BackgroundTaskStop) {
Init();
EXPECT_CALL(*task_coordinator(), ScheduleBackgroundTask(_, _, _));
scheduler()->OnStopTask(SchedulerTaskTime::kMorning);
}
} // namespace } // namespace
} // namespace notifications } // namespace notifications
...@@ -15,4 +15,9 @@ UserActionData::UserActionData(const UserActionData& other) = default; ...@@ -15,4 +15,9 @@ UserActionData::UserActionData(const UserActionData& other) = default;
UserActionData::~UserActionData() = default; UserActionData::~UserActionData() = default;
bool UserActionData::operator==(const UserActionData& other) const {
return client_type == other.client_type && action_type == other.action_type &&
guid == other.guid;
}
} // namespace notifications } // namespace notifications
...@@ -120,6 +120,7 @@ struct UserActionData { ...@@ -120,6 +120,7 @@ struct UserActionData {
const std::string& guid); const std::string& guid);
UserActionData(const UserActionData& other); UserActionData(const UserActionData& other);
~UserActionData(); ~UserActionData();
bool operator==(const UserActionData& other) const;
// The type of the client that sent the notification. // The type of the client that sent the notification.
const SchedulerClientType client_type; const SchedulerClientType client_type;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment