blob: f0818324d8445dba23c76033e319943859bdf15f [file] [log] [blame]
// 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 "ui/message_center/notification_list.h"
#include <stddef.h>
#include <utility>
#include "base/i18n/time_formatting.h"
#include "base/macros.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/message_center/fake_message_center.h"
#include "ui/message_center/notification_blocker.h"
#include "ui/message_center/public/cpp/message_center_constants.h"
#include "ui/message_center/public/cpp/notification_types.h"
#include "ui/message_center/public/cpp/notifier_id.h"
using base::UTF8ToUTF16;
namespace message_center {
using NotificationState = NotificationList::NotificationState;
class NotificationListTest : public testing::Test {
public:
NotificationListTest() {}
~NotificationListTest() override {}
void SetUp() override {
message_center_.reset(new FakeMessageCenter());
notification_list_.reset(new NotificationList(message_center_.get()));
counter_ = 0;
}
protected:
// Currently NotificationListTest doesn't care about some fields like title or
// message, so put a simple template on it. Returns the id of the new
// notification.
std::string AddNotification(const RichNotificationData& optional_fields) {
std::string new_id;
std::unique_ptr<Notification> notification(
MakeNotification(optional_fields, &new_id));
notification_list_->AddNotification(std::move(notification));
counter_++;
return new_id;
}
std::string AddNotification() {
return AddNotification(RichNotificationData());
}
// Construct a new notification for testing, but don't add it to the list yet.
std::unique_ptr<Notification> MakeNotification(
const RichNotificationData& optional_fields,
std::string* id_out) {
*id_out = base::StringPrintf(kIdFormat, counter_);
std::unique_ptr<Notification> notification(new Notification(
NOTIFICATION_TYPE_SIMPLE, *id_out,
UTF8ToUTF16(base::StringPrintf(kTitleFormat, counter_)),
UTF8ToUTF16(base::StringPrintf(kMessageFormat, counter_)), gfx::Image(),
UTF8ToUTF16(kDisplaySource), GURL(),
NotifierId(NotifierType::APPLICATION, kExtensionId), optional_fields,
NULL));
return notification;
}
std::unique_ptr<Notification> MakeNotification(std::string* id_out) {
return MakeNotification(RichNotificationData(), id_out);
}
// Utility methods of AddNotification.
std::string AddPriorityNotification(NotificationPriority priority) {
RichNotificationData optional;
optional.priority = priority;
return AddNotification(optional);
}
NotificationList::PopupNotifications GetPopups() {
return notification_list_->GetPopupNotifications(blockers_, NULL);
}
size_t GetPopupCounts() {
return GetPopups().size();
}
Notification* GetNotification(const std::string& id) {
auto iter = notification_list_->GetNotification(id);
if (iter == notification_list_->notifications_.end())
return NULL;
return iter->first.get();
}
NotificationState GetNotificationState(const std::string& id) {
auto iter = notification_list_->GetNotification(id);
EXPECT_FALSE(iter == notification_list_->notifications_.end());
return iter->second;
}
static const char kIdFormat[];
static const char kTitleFormat[];
static const char kMessageFormat[];
static const char kDisplaySource[];
static const char kExtensionId[];
std::unique_ptr<FakeMessageCenter> message_center_;
std::unique_ptr<NotificationList> notification_list_;
NotificationBlockers blockers_;
size_t counter_;
private:
DISALLOW_COPY_AND_ASSIGN(NotificationListTest);
};
bool IsInNotifications(const NotificationList::Notifications& notifications,
const std::string& id) {
for (auto iter = notifications.begin(); iter != notifications.end(); ++iter) {
if ((*iter)->id() == id)
return true;
}
return false;
}
const char NotificationListTest::kIdFormat[] = "id%ld";
const char NotificationListTest::kTitleFormat[] = "id%ld";
const char NotificationListTest::kMessageFormat[] = "message%ld";
const char NotificationListTest::kDisplaySource[] = "source";
const char NotificationListTest::kExtensionId[] = "ext";
TEST_F(NotificationListTest, Basic) {
ASSERT_EQ(0u, notification_list_->NotificationCount(blockers_));
std::string id0 = AddNotification();
EXPECT_EQ(1u, notification_list_->NotificationCount(blockers_));
std::string id1 = AddNotification();
EXPECT_EQ(2u, notification_list_->NotificationCount(blockers_));
EXPECT_TRUE(notification_list_->HasPopupNotifications(blockers_));
EXPECT_TRUE(notification_list_->GetNotificationById(id0));
EXPECT_TRUE(notification_list_->GetNotificationById(id1));
EXPECT_FALSE(notification_list_->GetNotificationById(id1 + "foo"));
EXPECT_EQ(2u, GetPopupCounts());
notification_list_->MarkSinglePopupAsShown(id0, true);
notification_list_->MarkSinglePopupAsShown(id1, true);
EXPECT_EQ(2u, notification_list_->NotificationCount(blockers_));
EXPECT_EQ(0u, GetPopupCounts());
notification_list_->RemoveNotification(id0);
EXPECT_EQ(1u, notification_list_->NotificationCount(blockers_));
AddNotification();
EXPECT_EQ(2u, notification_list_->NotificationCount(blockers_));
}
TEST_F(NotificationListTest, MessageCenterVisible) {
AddNotification();
EXPECT_EQ(1u, notification_list_->NotificationCount(blockers_));
ASSERT_EQ(1u, GetPopupCounts());
// Resets the unread count and popup counts.
notification_list_->SetNotificationsShown(blockers_, NULL);
ASSERT_EQ(0u, GetPopupCounts());
}
TEST_F(NotificationListTest, UpdateNotification) {
std::string id0 = AddNotification();
std::string replaced = id0 + "_replaced";
EXPECT_EQ(1u, notification_list_->NotificationCount(blockers_));
std::unique_ptr<Notification> notification(new Notification(
NOTIFICATION_TYPE_SIMPLE, replaced, UTF8ToUTF16("newtitle"),
UTF8ToUTF16("newbody"), gfx::Image(), UTF8ToUTF16(kDisplaySource), GURL(),
NotifierId(NotifierType::APPLICATION, kExtensionId),
RichNotificationData(), NULL));
notification_list_->UpdateNotificationMessage(id0, std::move(notification));
EXPECT_EQ(1u, notification_list_->NotificationCount(blockers_));
const NotificationList::Notifications notifications =
notification_list_->GetVisibleNotifications(blockers_);
EXPECT_EQ(replaced, (*notifications.begin())->id());
EXPECT_EQ(UTF8ToUTF16("newtitle"), (*notifications.begin())->title());
EXPECT_EQ(UTF8ToUTF16("newbody"), (*notifications.begin())->message());
}
TEST_F(NotificationListTest, UpdateNotificationWithRenotifyAndQuietMode) {
for (size_t quiet_mode = 0u; quiet_mode < 2u; ++quiet_mode) {
// Set Do Not Disturb mode.
notification_list_->SetQuietMode(static_cast<bool>(quiet_mode));
// Create notification.
std::string old_id;
auto old_notification = MakeNotification(&old_id);
notification_list_->AddNotification(std::move(old_notification));
notification_list_->MarkSinglePopupAsShown(old_id, true);
EXPECT_EQ(1u, notification_list_->NotificationCount(blockers_));
std::string new_id;
auto new_notification = MakeNotification(&new_id);
// Set the renotify flag and update.
new_notification->set_renotify(true);
notification_list_->UpdateNotificationMessage(old_id,
std::move(new_notification));
const NotificationList::Notifications notifications =
notification_list_->GetVisibleNotifications(blockers_);
EXPECT_EQ(1u, notification_list_->NotificationCount(blockers_));
EXPECT_EQ(new_id, (*notifications.begin())->id());
// Normally, |shown_as_popup| should be reset in order to show the popup
// again.
// In quiet mode, |shown_as_popup| should not be reset, as popup should not
// be shown even though renotify was set.
const NotificationList::PopupNotifications popup_notifications =
notification_list_->GetPopupNotifications(blockers_, nullptr);
if (quiet_mode) {
ASSERT_EQ(0U, popup_notifications.size());
} else {
ASSERT_EQ(1U, popup_notifications.size());
EXPECT_EQ(new_id, (*popup_notifications.begin())->id());
}
}
}
TEST_F(NotificationListTest, GetNotificationsByNotifierId) {
NotifierId id0(NotifierType::APPLICATION, "ext0");
NotifierId id1(NotifierType::APPLICATION, "ext1");
NotifierId id2(GURL("http://example.com"));
NotifierId id3(NotifierType::SYSTEM_COMPONENT, "system-notifier");
std::unique_ptr<Notification> notification(new Notification(
NOTIFICATION_TYPE_SIMPLE, "id0", UTF8ToUTF16("title0"),
UTF8ToUTF16("message0"), gfx::Image(), UTF8ToUTF16("source0"), GURL(),
id0, RichNotificationData(), NULL));
notification_list_->AddNotification(std::move(notification));
notification.reset(new Notification(
NOTIFICATION_TYPE_SIMPLE, "id1", UTF8ToUTF16("title1"),
UTF8ToUTF16("message1"), gfx::Image(), UTF8ToUTF16("source0"), GURL(),
id0, RichNotificationData(), NULL));
notification_list_->AddNotification(std::move(notification));
notification.reset(new Notification(
NOTIFICATION_TYPE_SIMPLE, "id2", UTF8ToUTF16("title1"),
UTF8ToUTF16("message1"), gfx::Image(), UTF8ToUTF16("source1"), GURL(),
id0, RichNotificationData(), NULL));
notification_list_->AddNotification(std::move(notification));
notification.reset(new Notification(
NOTIFICATION_TYPE_SIMPLE, "id3", UTF8ToUTF16("title1"),
UTF8ToUTF16("message1"), gfx::Image(), UTF8ToUTF16("source2"), GURL(),
id1, RichNotificationData(), NULL));
notification_list_->AddNotification(std::move(notification));
notification.reset(new Notification(
NOTIFICATION_TYPE_SIMPLE, "id4", UTF8ToUTF16("title1"),
UTF8ToUTF16("message1"), gfx::Image(), UTF8ToUTF16("source2"), GURL(),
id2, RichNotificationData(), NULL));
notification_list_->AddNotification(std::move(notification));
notification.reset(new Notification(
NOTIFICATION_TYPE_SIMPLE, "id5", UTF8ToUTF16("title1"),
UTF8ToUTF16("message1"), gfx::Image(), UTF8ToUTF16("source2"), GURL(),
id3, RichNotificationData(), NULL));
notification_list_->AddNotification(std::move(notification));
NotificationList::Notifications by_notifier_id =
notification_list_->GetNotificationsByNotifierId(id0);
EXPECT_TRUE(IsInNotifications(by_notifier_id, "id0"));
EXPECT_TRUE(IsInNotifications(by_notifier_id, "id1"));
EXPECT_TRUE(IsInNotifications(by_notifier_id, "id2"));
EXPECT_FALSE(IsInNotifications(by_notifier_id, "id3"));
EXPECT_FALSE(IsInNotifications(by_notifier_id, "id4"));
EXPECT_FALSE(IsInNotifications(by_notifier_id, "id5"));
by_notifier_id = notification_list_->GetNotificationsByNotifierId(id1);
EXPECT_FALSE(IsInNotifications(by_notifier_id, "id0"));
EXPECT_FALSE(IsInNotifications(by_notifier_id, "id1"));
EXPECT_FALSE(IsInNotifications(by_notifier_id, "id2"));
EXPECT_TRUE(IsInNotifications(by_notifier_id, "id3"));
EXPECT_FALSE(IsInNotifications(by_notifier_id, "id4"));
EXPECT_FALSE(IsInNotifications(by_notifier_id, "id5"));
by_notifier_id = notification_list_->GetNotificationsByNotifierId(id2);
EXPECT_FALSE(IsInNotifications(by_notifier_id, "id0"));
EXPECT_FALSE(IsInNotifications(by_notifier_id, "id1"));
EXPECT_FALSE(IsInNotifications(by_notifier_id, "id2"));
EXPECT_FALSE(IsInNotifications(by_notifier_id, "id3"));
EXPECT_TRUE(IsInNotifications(by_notifier_id, "id4"));
EXPECT_FALSE(IsInNotifications(by_notifier_id, "id5"));
by_notifier_id = notification_list_->GetNotificationsByNotifierId(id3);
EXPECT_FALSE(IsInNotifications(by_notifier_id, "id0"));
EXPECT_FALSE(IsInNotifications(by_notifier_id, "id1"));
EXPECT_FALSE(IsInNotifications(by_notifier_id, "id2"));
EXPECT_FALSE(IsInNotifications(by_notifier_id, "id3"));
EXPECT_FALSE(IsInNotifications(by_notifier_id, "id4"));
EXPECT_TRUE(IsInNotifications(by_notifier_id, "id5"));
}
TEST_F(NotificationListTest, OldPopupShouldNotBeHidden) {
std::vector<std::string> ids;
for (size_t i = 0; i <= kMaxVisiblePopupNotifications; i++)
ids.push_back(AddNotification());
NotificationList::PopupNotifications popups = GetPopups();
// The popup should contain the oldest kMaxVisiblePopupNotifications. Newer
// one should come earlier in the popup list. It means, the last element
// of |popups| should be the firstly added one, and so on.
EXPECT_EQ(kMaxVisiblePopupNotifications, popups.size());
auto iter = popups.rbegin();
for (size_t i = 0; i < kMaxVisiblePopupNotifications; ++i, ++iter) {
EXPECT_EQ(ids[i], (*iter)->id()) << i;
}
for (auto iter = popups.begin(); iter != popups.end(); ++iter) {
notification_list_->MarkSinglePopupAsShown((*iter)->id(), false);
}
popups.clear();
popups = GetPopups();
ASSERT_EQ(1u, popups.size());
EXPECT_EQ(ids.back(), (*popups.begin())->id());
}
TEST_F(NotificationListTest, Priority) {
ASSERT_EQ(0u, notification_list_->NotificationCount(blockers_));
// Default priority has the limit on the number of the popups.
for (size_t i = 0; i <= kMaxVisiblePopupNotifications; ++i)
AddNotification();
EXPECT_EQ(kMaxVisiblePopupNotifications + 1,
notification_list_->NotificationCount(blockers_));
EXPECT_EQ(kMaxVisiblePopupNotifications, GetPopupCounts());
// Low priority: not visible to popups.
notification_list_->SetNotificationsShown(blockers_, NULL);
AddPriorityNotification(LOW_PRIORITY);
EXPECT_EQ(kMaxVisiblePopupNotifications + 2,
notification_list_->NotificationCount(blockers_));
EXPECT_EQ(0u, GetPopupCounts());
// Minimum priority: doesn't update the unread count.
AddPriorityNotification(MIN_PRIORITY);
EXPECT_EQ(kMaxVisiblePopupNotifications + 3,
notification_list_->NotificationCount(blockers_));
EXPECT_EQ(0u, GetPopupCounts());
NotificationList::Notifications notifications =
notification_list_->GetVisibleNotifications(blockers_);
for (auto iter = notifications.begin(); iter != notifications.end(); ++iter) {
notification_list_->RemoveNotification((*iter)->id());
}
// Higher priority: no limits to the number of popups.
for (size_t i = 0; i < kMaxVisiblePopupNotifications * 2; ++i)
AddPriorityNotification(HIGH_PRIORITY);
for (size_t i = 0; i < kMaxVisiblePopupNotifications * 2; ++i)
AddPriorityNotification(MAX_PRIORITY);
EXPECT_EQ(kMaxVisiblePopupNotifications * 4,
notification_list_->NotificationCount(blockers_));
EXPECT_EQ(kMaxVisiblePopupNotifications * 4, GetPopupCounts());
}
// Tests that GetNotificationsByAppId returns notifications regardless of their
// visibility.
TEST_F(NotificationListTest, GetNotificationsByAppId) {
// Add a notification for |app_id1|.
const std::string app_id1("app_id1");
const std::string id1("id1");
std::unique_ptr<Notification> notification(
new Notification(NOTIFICATION_TYPE_PROGRESS, id1, UTF8ToUTF16("updated"),
UTF8ToUTF16("updated"), gfx::Image(), base::string16(),
GURL(), NotifierId(NotifierType::APPLICATION, app_id1),
RichNotificationData(), NULL));
notification_list_->AddNotification(std::move(notification));
EXPECT_EQ(1u, notification_list_->GetNotificationsByAppId(app_id1).size());
// Mark the popup as shown but not read.
notification_list_->MarkSinglePopupAsShown(id1, false);
EXPECT_EQ(1u, notification_list_->GetNotificationsByAppId(app_id1).size());
// Mark the popup as shown and read.
notification_list_->MarkSinglePopupAsShown(id1, true);
EXPECT_EQ(1u, notification_list_->GetNotificationsByAppId(app_id1).size());
// Remove the notification.
notification_list_->RemoveNotification(id1);
EXPECT_EQ(0u, notification_list_->GetNotificationsByAppId(app_id1).size());
// Add two notifications for |app_id1| and one for |app_id2|.
notification.reset(
new Notification(NOTIFICATION_TYPE_PROGRESS, id1, UTF8ToUTF16("updated"),
UTF8ToUTF16("updated"), gfx::Image(), base::string16(),
GURL(), NotifierId(NotifierType::APPLICATION, app_id1),
RichNotificationData(), NULL));
notification_list_->AddNotification(std::move(notification));
const std::string id2("id2");
notification.reset(
new Notification(NOTIFICATION_TYPE_PROGRESS, id2, UTF8ToUTF16("updated"),
UTF8ToUTF16("updated"), gfx::Image(), base::string16(),
GURL(), NotifierId(NotifierType::APPLICATION, app_id1),
RichNotificationData(), NULL));
notification_list_->AddNotification(std::move(notification));
EXPECT_EQ(2u, notification_list_->GetNotificationsByAppId(app_id1).size());
const std::string id3("id3");
const std::string app_id2("app_id2");
notification.reset(
new Notification(NOTIFICATION_TYPE_PROGRESS, id3, UTF8ToUTF16("updated"),
UTF8ToUTF16("updated"), gfx::Image(), base::string16(),
GURL(), NotifierId(NotifierType::APPLICATION, app_id2),
RichNotificationData(), NULL));
notification_list_->AddNotification(std::move(notification));
EXPECT_EQ(2u, notification_list_->GetNotificationsByAppId(app_id1).size());
EXPECT_EQ(1u, notification_list_->GetNotificationsByAppId(app_id2).size());
for (std::string app_id : {app_id1, app_id2}) {
for (auto* notification :
notification_list_->GetNotificationsByAppId(app_id)) {
EXPECT_EQ(app_id, notification->notifier_id().id);
}
}
}
TEST_F(NotificationListTest, HasPopupsWithPriority) {
ASSERT_EQ(0u, notification_list_->NotificationCount(blockers_));
AddPriorityNotification(MIN_PRIORITY);
AddPriorityNotification(MAX_PRIORITY);
EXPECT_EQ(1u, GetPopupCounts());
}
TEST_F(NotificationListTest, HasPopupsWithSystemPriority) {
ASSERT_EQ(0u, notification_list_->NotificationCount(blockers_));
std::string normal_id = AddPriorityNotification(DEFAULT_PRIORITY);
std::string system_id = AddNotification();
GetNotification(system_id)->SetSystemPriority();
EXPECT_EQ(2u, GetPopupCounts());
notification_list_->MarkSinglePopupAsDisplayed(normal_id);
notification_list_->MarkSinglePopupAsDisplayed(system_id);
notification_list_->MarkSinglePopupAsShown(normal_id, false);
notification_list_->MarkSinglePopupAsShown(system_id, false);
notification_list_->SetNotificationsShown(blockers_, NULL);
EXPECT_EQ(1u, GetPopupCounts());
// Mark as read -- emulation of mouse click.
notification_list_->MarkSinglePopupAsShown(system_id, true);
EXPECT_EQ(0u, GetPopupCounts());
}
// Verifies that notification updates will re-show the toast when there is no
// message center view (i.e. the bubble anchored to the status bar).
TEST_F(NotificationListTest, UpdateWithoutMessageCenterView) {
auto run_test = [this](bool has_message_center_view) {
message_center_->SetHasMessageCenterView(has_message_center_view);
std::string id0 = AddNotification();
std::string replaced = id0 + "_replaced";
notification_list_->MarkSinglePopupAsShown(id0, false);
EXPECT_EQ(1u, notification_list_->NotificationCount(blockers_));
EXPECT_EQ(0u, GetPopupCounts());
RichNotificationData optional;
std::unique_ptr<Notification> notification(new Notification(
NOTIFICATION_TYPE_SIMPLE, replaced, UTF8ToUTF16("newtitle"),
UTF8ToUTF16("newbody"), gfx::Image(), UTF8ToUTF16(kDisplaySource),
GURL(), NotifierId(NotifierType::APPLICATION, kExtensionId), optional,
NULL));
notification_list_->UpdateNotificationMessage(id0, std::move(notification));
EXPECT_EQ(1u, notification_list_->NotificationCount(blockers_));
EXPECT_EQ(has_message_center_view ? 0U : 1U, GetPopupCounts());
const NotificationList::Notifications notifications =
notification_list_->GetVisibleNotifications(blockers_);
EXPECT_EQ(replaced, (*notifications.begin())->id());
EXPECT_EQ(UTF8ToUTF16("newtitle"), (*notifications.begin())->title());
EXPECT_EQ(UTF8ToUTF16("newbody"), (*notifications.begin())->message());
notification_list_->RemoveNotification(replaced);
EXPECT_EQ(0U,
notification_list_->GetVisibleNotifications(blockers_).size());
};
run_test(false);
run_test(true);
}
TEST_F(NotificationListTest, Renotify) {
std::string id0 = AddNotification();
std::string replaced = id0 + "_replaced";
notification_list_->MarkSinglePopupAsShown(id0, false);
EXPECT_EQ(1u, notification_list_->NotificationCount(blockers_));
EXPECT_EQ(0u, GetPopupCounts());
RichNotificationData optional;
optional.renotify = true;
std::unique_ptr<Notification> notification(new Notification(
NOTIFICATION_TYPE_SIMPLE, replaced, UTF8ToUTF16("newtitle"),
UTF8ToUTF16("newbody"), gfx::Image(), UTF8ToUTF16(kDisplaySource), GURL(),
NotifierId(NotifierType::APPLICATION, kExtensionId), optional, NULL));
notification_list_->UpdateNotificationMessage(id0, std::move(notification));
EXPECT_EQ(1u, notification_list_->NotificationCount(blockers_));
EXPECT_EQ(1u, GetPopupCounts());
const NotificationList::Notifications notifications =
notification_list_->GetVisibleNotifications(blockers_);
EXPECT_EQ(replaced, (*notifications.begin())->id());
EXPECT_EQ(UTF8ToUTF16("newtitle"), (*notifications.begin())->title());
EXPECT_EQ(UTF8ToUTF16("newbody"), (*notifications.begin())->message());
}
TEST_F(NotificationListTest, PriorityAndRenotify) {
std::string id0 = AddPriorityNotification(LOW_PRIORITY);
std::string id1 = AddPriorityNotification(DEFAULT_PRIORITY);
EXPECT_EQ(1u, GetPopupCounts());
notification_list_->MarkSinglePopupAsShown(id1, true);
EXPECT_EQ(0u, GetPopupCounts());
// id0 promoted to LOW->DEFAULT, it'll appear as toast (popup).
RichNotificationData priority;
priority.priority = DEFAULT_PRIORITY;
std::unique_ptr<Notification> notification(new Notification(
NOTIFICATION_TYPE_SIMPLE, id0, UTF8ToUTF16("newtitle"),
UTF8ToUTF16("newbody"), gfx::Image(), UTF8ToUTF16(kDisplaySource), GURL(),
NotifierId(NotifierType::APPLICATION, kExtensionId), priority, NULL));
notification_list_->UpdateNotificationMessage(id0, std::move(notification));
EXPECT_EQ(1u, GetPopupCounts());
notification_list_->MarkSinglePopupAsShown(id0, true);
EXPECT_EQ(0u, GetPopupCounts());
// update with no promotion change for id0, it won't appear as a toast.
notification.reset(new Notification(
NOTIFICATION_TYPE_SIMPLE, id0, UTF8ToUTF16("newtitle2"),
UTF8ToUTF16("newbody2"), gfx::Image(), UTF8ToUTF16(kDisplaySource),
GURL(), NotifierId(NotifierType::APPLICATION, kExtensionId), priority,
NULL));
notification_list_->UpdateNotificationMessage(id0, std::move(notification));
EXPECT_EQ(0u, GetPopupCounts());
// id1 promoted to DEFAULT->HIGH, it won't reappear as a toast (popup).
priority.priority = HIGH_PRIORITY;
notification.reset(new Notification(
NOTIFICATION_TYPE_SIMPLE, id1, UTF8ToUTF16("newtitle"),
UTF8ToUTF16("newbody"), gfx::Image(), UTF8ToUTF16(kDisplaySource), GURL(),
NotifierId(NotifierType::APPLICATION, kExtensionId), priority, NULL));
notification_list_->UpdateNotificationMessage(id1, std::move(notification));
EXPECT_EQ(0u, GetPopupCounts());
// |renotify| will make it reappear as a toast (popup).
priority.renotify = true;
notification.reset(new Notification(
NOTIFICATION_TYPE_SIMPLE, id1, UTF8ToUTF16("newtitle"),
UTF8ToUTF16("newbody"), gfx::Image(), UTF8ToUTF16(kDisplaySource), GURL(),
NotifierId(NotifierType::APPLICATION, kExtensionId), priority, NULL));
notification_list_->UpdateNotificationMessage(id1, std::move(notification));
EXPECT_EQ(1u, GetPopupCounts());
notification_list_->MarkSinglePopupAsShown(id1, true);
EXPECT_EQ(0u, GetPopupCounts());
}
TEST_F(NotificationListTest, NotificationOrderAndPriority) {
base::Time now = base::Time::Now();
RichNotificationData optional;
optional.timestamp = now;
optional.priority = 2;
std::string max_id = AddNotification(optional);
now += base::TimeDelta::FromSeconds(1);
optional.timestamp = now;
optional.priority = 1;
std::string high_id = AddNotification(optional);
now += base::TimeDelta::FromSeconds(1);
optional.timestamp = now;
optional.priority = 0;
std::string default_id = AddNotification(optional);
{
// Popups: latest comes first.
NotificationList::PopupNotifications popups = GetPopups();
EXPECT_EQ(3u, popups.size());
auto iter = popups.begin();
EXPECT_EQ(default_id, (*iter)->id());
iter++;
EXPECT_EQ(high_id, (*iter)->id());
iter++;
EXPECT_EQ(max_id, (*iter)->id());
}
{
// Notifications: high priority comes earlier.
const NotificationList::Notifications notifications =
notification_list_->GetVisibleNotifications(blockers_);
EXPECT_EQ(3u, notifications.size());
auto iter = notifications.begin();
EXPECT_EQ(max_id, (*iter)->id());
iter++;
EXPECT_EQ(high_id, (*iter)->id());
iter++;
EXPECT_EQ(default_id, (*iter)->id());
}
}
TEST_F(NotificationListTest, MarkSinglePopupAsShown) {
std::string id1 = AddNotification();
std::string id2 = AddNotification();
std::string id3 = AddNotification();
ASSERT_EQ(3u, notification_list_->NotificationCount(blockers_));
ASSERT_EQ(std::min(static_cast<size_t>(3u), kMaxVisiblePopupNotifications),
GetPopupCounts());
notification_list_->MarkSinglePopupAsDisplayed(id1);
notification_list_->MarkSinglePopupAsDisplayed(id2);
notification_list_->MarkSinglePopupAsDisplayed(id3);
notification_list_->MarkSinglePopupAsShown(id2, true);
notification_list_->MarkSinglePopupAsShown(id3, false);
EXPECT_EQ(3u, notification_list_->NotificationCount(blockers_));
EXPECT_EQ(1u, GetPopupCounts());
NotificationList::PopupNotifications popups = GetPopups();
EXPECT_EQ(id1, (*popups.begin())->id());
// The notifications in the NotificationCenter are unaffected by popups shown.
NotificationList::Notifications notifications =
notification_list_->GetVisibleNotifications(blockers_);
auto iter = notifications.begin();
EXPECT_EQ(id3, (*iter)->id());
iter++;
EXPECT_EQ(id2, (*iter)->id());
iter++;
EXPECT_EQ(id1, (*iter)->id());
}
TEST_F(NotificationListTest, UpdateAfterMarkedAsShown) {
std::string id1 = AddNotification();
std::string id2 = AddNotification();
notification_list_->MarkSinglePopupAsDisplayed(id1);
notification_list_->MarkSinglePopupAsDisplayed(id2);
EXPECT_EQ(2u, GetPopupCounts());
NotificationState n1_state = GetNotificationState(id1);
EXPECT_FALSE(n1_state.shown_as_popup);
EXPECT_TRUE(n1_state.is_read);
notification_list_->MarkSinglePopupAsShown(id1, true);
n1_state = GetNotificationState(id1);
EXPECT_TRUE(n1_state.shown_as_popup);
EXPECT_TRUE(n1_state.is_read);
const std::string replaced("test-replaced-id");
std::unique_ptr<Notification> notification(new Notification(
NOTIFICATION_TYPE_SIMPLE, replaced, UTF8ToUTF16("newtitle"),
UTF8ToUTF16("newbody"), gfx::Image(), UTF8ToUTF16(kDisplaySource), GURL(),
NotifierId(NotifierType::APPLICATION, kExtensionId),
RichNotificationData(), NULL));
notification_list_->UpdateNotificationMessage(id1, std::move(notification));
Notification* n1 = GetNotification(id1);
EXPECT_TRUE(n1 == NULL);
const NotificationState nr_state = GetNotificationState(replaced);
EXPECT_TRUE(nr_state.shown_as_popup);
EXPECT_TRUE(nr_state.is_read);
}
TEST_F(NotificationListTest, QuietMode) {
notification_list_->SetQuietMode(true);
AddNotification();
AddPriorityNotification(HIGH_PRIORITY);
AddPriorityNotification(MAX_PRIORITY);
EXPECT_EQ(3u, notification_list_->NotificationCount(blockers_));
EXPECT_EQ(0u, GetPopupCounts());
notification_list_->SetQuietMode(false);
AddNotification();
EXPECT_EQ(4u, notification_list_->NotificationCount(blockers_));
EXPECT_EQ(1u, GetPopupCounts());
// TODO(mukai): Add test of quiet mode with expiration.
}
TEST_F(NotificationListTest, TestHasNotificationOfType) {
std::string id = AddNotification();
EXPECT_TRUE(
notification_list_->HasNotificationOfType(id, NOTIFICATION_TYPE_SIMPLE));
EXPECT_FALSE(notification_list_->HasNotificationOfType(
id, NOTIFICATION_TYPE_PROGRESS));
std::unique_ptr<Notification> updated_notification(
new Notification(NOTIFICATION_TYPE_PROGRESS, id, UTF8ToUTF16("updated"),
UTF8ToUTF16("updated"), gfx::Image(), base::string16(),
GURL(), NotifierId(), RichNotificationData(), NULL));
notification_list_->AddNotification(std::move(updated_notification));
EXPECT_FALSE(
notification_list_->HasNotificationOfType(id, NOTIFICATION_TYPE_SIMPLE));
EXPECT_TRUE(notification_list_->HasNotificationOfType(
id, NOTIFICATION_TYPE_PROGRESS));
}
} // namespace message_center