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,
}
// ImpressionHistoryTracker::Delegate implementation.
void OnImpressionUpdated() override { ScheduleBackgroundTask(); }
void OnImpressionUpdated() override {
// TODO(xingliu): Fix duplicate ScheduleBackgroundTask() call.
ScheduleBackgroundTask();
}
void FindNotificationToShow(SchedulerTaskTime task_start_time) {
DisplayDecider::Results results;
......
......@@ -9,10 +9,14 @@
#include <utility>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/strings/utf_string_conversions.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/scheduler_config.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_display_agent.h"
#include "chrome/browser/notifications/scheduler/test/mock_display_decider.h"
......@@ -27,17 +31,25 @@ using ::testing::_;
using ::testing::Invoke;
using ::testing::InvokeWithoutArgs;
using ::testing::NiceMock;
using ::testing::SetArgPointee;
namespace notifications {
namespace {
const char kGuid[] = "guid";
const char kTitle[] = "title";
class NotificationSchedulerTest : public testing::Test {
public:
NotificationSchedulerTest()
: registrar_(nullptr),
impression_tracker_(nullptr),
notification_manager_(nullptr),
client_(nullptr) {}
client_(nullptr),
task_coordinator_(nullptr),
display_agent_(nullptr),
display_decider_(nullptr),
notification_manager_delegate_(nullptr) {}
~NotificationSchedulerTest() override = default;
void SetUp() override {
......@@ -55,6 +67,9 @@ class NotificationSchedulerTest : public testing::Test {
registrar_ = registrar.get();
impression_tracker_ = impression_tracker.get();
notification_manager_ = notification_manager.get();
task_coordinator_ = task_coordinator.get();
display_agent_ = display_agent.get();
display_decider_ = display_decider.get();
// Register mock clients.
auto client = std::make_unique<test::MockNotificationSchedulerClient>();
......@@ -70,6 +85,31 @@ class NotificationSchedulerTest : public testing::Test {
}
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(); }
test::MockImpressionHistoryTracker* impression_tracker() {
......@@ -82,12 +122,29 @@ class NotificationSchedulerTest : public testing::Test {
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:
base::test::ScopedTaskEnvironment scoped_task_environment_;
NotificationSchedulerClientRegistrar* registrar_;
test::MockImpressionHistoryTracker* impression_tracker_;
test::MockScheduledNotificationManager* notification_manager_;
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_;
DISALLOW_COPY_AND_ASSIGN(NotificationSchedulerTest);
......@@ -95,25 +152,7 @@ class NotificationSchedulerTest : public testing::Test {
// Tests successful initialization flow.
TEST_F(NotificationSchedulerTest, InitSuccess) {
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) {
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();
Init();
}
// Tests the case when impression tracker failed to initialize.
......@@ -162,5 +201,125 @@ TEST_F(NotificationSchedulerTest, InitScheduledNotificationManagerFailed) {
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 notifications
......@@ -15,4 +15,9 @@ UserActionData::UserActionData(const UserActionData& other) = 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
......@@ -120,6 +120,7 @@ struct UserActionData {
const std::string& guid);
UserActionData(const UserActionData& other);
~UserActionData();
bool operator==(const UserActionData& other) const;
// The type of the client that sent the notification.
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