Separate Simple Backend creation from initialization.
[chromium-blink-merge.git] / ui / message_center / notification_list_unittest.cc
blob9a1a6422bb825aa9bdd076db2ebe7d4ac146ffb5
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/message_center/notification_list.h"
7 #include "base/basictypes.h"
8 #include "base/i18n/time_formatting.h"
9 #include "base/stringprintf.h"
10 #include "base/utf_string_conversions.h"
11 #include "base/values.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "ui/message_center/notification_types.h"
15 namespace message_center {
16 namespace {
18 class MockNotificationListDelegate : public NotificationList::Delegate {
19 public:
20 MockNotificationListDelegate() : send_remove_count_(0) {}
21 virtual ~MockNotificationListDelegate() {}
23 size_t GetSendRemoveCountAndReset() {
24 size_t result = send_remove_count_;
25 send_remove_count_ = 0;
26 return result;
29 private:
30 // Overridden from NotificationList::Delegate:
31 virtual void SendRemoveNotification(const std::string& id,
32 bool by_user) OVERRIDE {
33 send_remove_count_++;
36 virtual void OnQuietModeChanged(bool quiet_mode) OVERRIDE {
39 size_t send_remove_count_;
40 DISALLOW_COPY_AND_ASSIGN(MockNotificationListDelegate);
43 class NotificationListTest : public testing::Test {
44 public:
45 NotificationListTest() {}
46 virtual ~NotificationListTest() {}
48 virtual void SetUp() {
49 delegate_.reset(new MockNotificationListDelegate);
50 notification_list_.reset(new NotificationList(delegate_.get()));
51 counter_ = 0;
54 protected:
55 // Currently NotificationListTest doesn't care about some fields like title or
56 // message, so put a simple template on it. Returns the id of the new
57 // notification.
58 std::string AddNotification(const base::DictionaryValue* optional_fields) {
59 std::string new_id = base::StringPrintf(kIdFormat, counter_);
60 notification_list_->AddNotification(
61 message_center::NOTIFICATION_TYPE_SIMPLE, new_id,
62 UTF8ToUTF16(base::StringPrintf(kTitleFormat, counter_)),
63 UTF8ToUTF16(base::StringPrintf(kMessageFormat, counter_)),
64 UTF8ToUTF16(kDisplaySource), kExtensionId,
65 optional_fields);
66 counter_++;
67 return new_id;
70 // Utility methods of AddNotification.
71 std::string AddPriorityNotification(int priority) {
72 base::DictionaryValue optional;
73 optional.SetInteger(message_center::kPriorityKey, priority);
74 return AddNotification(&optional);
76 void SetupTimestampKey(const base::Time& time,
77 base::DictionaryValue* optional) {
78 string16 time_formatted = base::TimeFormatShortDateAndTime(time);
79 optional->SetString(message_center::kTimestampKey, time_formatted);
82 size_t GetPopupCounts() {
83 return notification_list()->GetPopupNotifications().size();
86 MockNotificationListDelegate* delegate() { return delegate_.get(); }
87 NotificationList* notification_list() { return notification_list_.get(); }
89 private:
90 static const char kIdFormat[];
91 static const char kTitleFormat[];
92 static const char kMessageFormat[];
93 static const char kDisplaySource[];
94 static const char kExtensionId[];
96 scoped_ptr<MockNotificationListDelegate> delegate_;
97 scoped_ptr<NotificationList> notification_list_;
98 size_t counter_;
100 DISALLOW_COPY_AND_ASSIGN(NotificationListTest);
103 const char NotificationListTest::kIdFormat[] = "id%ld";
104 const char NotificationListTest::kTitleFormat[] = "id%ld";
105 const char NotificationListTest::kMessageFormat[] = "message%ld";
106 const char NotificationListTest::kDisplaySource[] = "source";
107 const char NotificationListTest::kExtensionId[] = "ext";
109 } // namespace
111 TEST_F(NotificationListTest, Basic) {
112 ASSERT_EQ(0u, notification_list()->NotificationCount());
113 ASSERT_EQ(0u, notification_list()->unread_count());
115 std::string id0 = AddNotification(NULL);
116 EXPECT_EQ(1u, notification_list()->NotificationCount());
117 std::string id1 = AddNotification(NULL);
118 EXPECT_EQ(2u, notification_list()->NotificationCount());
119 EXPECT_EQ(2u, notification_list()->unread_count());
121 EXPECT_TRUE(notification_list()->HasPopupNotifications());
122 EXPECT_TRUE(notification_list()->HasNotification(id0));
123 EXPECT_TRUE(notification_list()->HasNotification(id1));
124 EXPECT_FALSE(notification_list()->HasNotification(id1 + "foo"));
126 EXPECT_EQ(2u, GetPopupCounts());
128 notification_list()->MarkPopupsAsShown(0);
129 EXPECT_EQ(2u, notification_list()->NotificationCount());
130 EXPECT_EQ(0u, GetPopupCounts());
132 notification_list()->RemoveNotification(id0);
133 EXPECT_EQ(1u, notification_list()->NotificationCount());
134 EXPECT_EQ(1u, notification_list()->unread_count());
136 AddNotification(NULL);
137 EXPECT_EQ(2u, notification_list()->NotificationCount());
139 notification_list()->RemoveAllNotifications();
140 EXPECT_EQ(0u, notification_list()->NotificationCount());
141 EXPECT_EQ(0u, notification_list()->unread_count());
144 TEST_F(NotificationListTest, MessageCenterVisible) {
145 AddNotification(NULL);
146 EXPECT_EQ(1u, notification_list()->NotificationCount());
147 ASSERT_EQ(1u, notification_list()->unread_count());
149 // Toggle the message center visibility. It resets the unread count when
150 // hidden.
151 notification_list()->SetMessageCenterVisible(true);
152 ASSERT_EQ(1u, notification_list()->unread_count());
153 notification_list()->SetMessageCenterVisible(false);
154 ASSERT_EQ(0u, notification_list()->unread_count());
157 TEST_F(NotificationListTest, UpdateNotification) {
158 std::string id0 = AddNotification(NULL);
159 std::string replaced = id0 + "_replaced";
160 EXPECT_EQ(1u, notification_list()->NotificationCount());
161 notification_list()->UpdateNotificationMessage(
162 id0, replaced, UTF8ToUTF16("newtitle"), UTF8ToUTF16("newbody"), NULL);
163 EXPECT_EQ(1u, notification_list()->NotificationCount());
164 const NotificationList::Notifications& notifications =
165 notification_list()->GetNotifications();
166 EXPECT_EQ(replaced, (*notifications.begin())->id());
167 EXPECT_EQ(UTF8ToUTF16("newtitle"), (*notifications.begin())->title());
168 EXPECT_EQ(UTF8ToUTF16("newbody"), (*notifications.begin())->message());
171 TEST_F(NotificationListTest, SendRemoveNotifications) {
172 notification_list()->AddNotification(
173 message_center::NOTIFICATION_TYPE_SIMPLE, "id0", UTF8ToUTF16("title0"),
174 UTF8ToUTF16("message0"), UTF8ToUTF16("source0"), "ext0", NULL);
175 notification_list()->AddNotification(
176 message_center::NOTIFICATION_TYPE_SIMPLE, "id1", UTF8ToUTF16("title1"),
177 UTF8ToUTF16("message1"), UTF8ToUTF16("source0"), "ext0", NULL);
178 notification_list()->AddNotification(
179 message_center::NOTIFICATION_TYPE_SIMPLE, "id2", UTF8ToUTF16("title1"),
180 UTF8ToUTF16("message1"), UTF8ToUTF16("source1"), "ext0", NULL);
181 notification_list()->AddNotification(
182 message_center::NOTIFICATION_TYPE_SIMPLE, "id3", UTF8ToUTF16("title1"),
183 UTF8ToUTF16("message1"), UTF8ToUTF16("source2"), "ext1", NULL);
185 notification_list()->SendRemoveNotificationsBySource("id0");
186 EXPECT_EQ(2u, delegate()->GetSendRemoveCountAndReset());
187 notification_list()->SendRemoveNotificationsByExtension("id0");
188 EXPECT_EQ(3u, delegate()->GetSendRemoveCountAndReset());
191 TEST_F(NotificationListTest, OldPopupShouldNotBeHidden) {
192 std::vector<std::string> ids;
193 for (size_t i = 0; i <= NotificationList::kMaxVisiblePopupNotifications;
194 i++) {
195 ids.push_back(AddNotification(NULL));
198 NotificationList::PopupNotifications popups =
199 notification_list()->GetPopupNotifications();
200 // The popup should contain the oldest kMaxVisiblePopupNotifications. Newer
201 // one should come earlier in the popup list. It means, the last element
202 // of |popups| should be the firstly added one, and so on.
203 EXPECT_EQ(NotificationList::kMaxVisiblePopupNotifications, popups.size());
204 NotificationList::PopupNotifications::const_reverse_iterator iter =
205 popups.rbegin();
206 for (size_t i = 0; i < NotificationList::kMaxVisiblePopupNotifications;
207 ++i, ++iter) {
208 EXPECT_EQ(ids[i], (*iter)->id()) << i;
211 notification_list()->MarkPopupsAsShown(message_center::DEFAULT_PRIORITY);
212 popups.clear();
213 popups = notification_list()->GetPopupNotifications();
214 EXPECT_EQ(1u, popups.size());
215 EXPECT_EQ(ids[ids.size() - 1], (*popups.begin())->id());
218 TEST_F(NotificationListTest, Priority) {
219 ASSERT_EQ(0u, notification_list()->NotificationCount());
220 ASSERT_EQ(0u, notification_list()->unread_count());
222 // Default priority has the limit on the number of the popups.
223 for (size_t i = 0; i <= NotificationList::kMaxVisiblePopupNotifications;
224 ++i) {
225 AddNotification(NULL);
227 EXPECT_EQ(NotificationList::kMaxVisiblePopupNotifications + 1,
228 notification_list()->NotificationCount());
229 EXPECT_EQ(NotificationList::kMaxVisiblePopupNotifications, GetPopupCounts());
231 // Low priority: not visible to popups.
232 notification_list()->SetMessageCenterVisible(true);
233 notification_list()->SetMessageCenterVisible(false);
234 EXPECT_EQ(0u, notification_list()->unread_count());
235 AddPriorityNotification(-1);
236 EXPECT_EQ(NotificationList::kMaxVisiblePopupNotifications + 2,
237 notification_list()->NotificationCount());
238 EXPECT_EQ(1u, notification_list()->unread_count());
239 EXPECT_EQ(0u, GetPopupCounts());
241 // Minimum priority: doesn't update the unread count.
242 AddPriorityNotification(-2);
243 EXPECT_EQ(NotificationList::kMaxVisiblePopupNotifications + 3,
244 notification_list()->NotificationCount());
245 EXPECT_EQ(1u, notification_list()->unread_count());
246 EXPECT_EQ(0u, GetPopupCounts());
248 notification_list()->RemoveAllNotifications();
250 // Higher priority: no limits to the number of popups.
251 for (size_t i = 0; i < NotificationList::kMaxVisiblePopupNotifications * 2;
252 ++i) {
253 AddPriorityNotification(1);
255 for (size_t i = 0; i < NotificationList::kMaxVisiblePopupNotifications * 2;
256 ++i) {
257 AddPriorityNotification(2);
259 EXPECT_EQ(NotificationList::kMaxVisiblePopupNotifications * 4,
260 notification_list()->NotificationCount());
261 EXPECT_EQ(NotificationList::kMaxVisiblePopupNotifications * 4,
262 GetPopupCounts());
265 TEST_F(NotificationListTest, HasPopupsWithPriority) {
266 ASSERT_EQ(0u, notification_list()->NotificationCount());
267 ASSERT_EQ(0u, notification_list()->unread_count());
269 AddPriorityNotification(-2);
270 AddPriorityNotification(2);
272 EXPECT_EQ(1u, GetPopupCounts());
275 TEST_F(NotificationListTest, PriorityPromotion) {
276 std::string id0 = AddPriorityNotification(-1);
277 std::string replaced = id0 + "_replaced";
278 EXPECT_EQ(1u, notification_list()->NotificationCount());
279 EXPECT_EQ(0u, GetPopupCounts());
280 base::DictionaryValue optional;
281 optional.SetInteger(message_center::kPriorityKey, 1);
282 notification_list()->UpdateNotificationMessage(
283 id0, replaced, UTF8ToUTF16("newtitle"), UTF8ToUTF16("newbody"),
284 &optional);
285 EXPECT_EQ(1u, notification_list()->NotificationCount());
286 EXPECT_EQ(1u, GetPopupCounts());
287 const NotificationList::Notifications& notifications =
288 notification_list()->GetNotifications();
289 EXPECT_EQ(replaced, (*notifications.begin())->id());
290 EXPECT_EQ(UTF8ToUTF16("newtitle"), (*notifications.begin())->title());
291 EXPECT_EQ(UTF8ToUTF16("newbody"), (*notifications.begin())->message());
292 EXPECT_EQ(1, (*notifications.begin())->priority());
295 TEST_F(NotificationListTest, NotificationOrderAndPriority) {
296 base::Time now = base::Time::Now();
297 base::DictionaryValue optional;
298 SetupTimestampKey(now, &optional);
299 optional.SetInteger(message_center::kPriorityKey, 2);
300 std::string max_id = AddNotification(&optional);
301 now += base::TimeDelta::FromSeconds(1);
302 SetupTimestampKey(now, &optional);
303 optional.SetInteger(message_center::kPriorityKey, 1);
304 std::string high_id = AddNotification(&optional);
305 now += base::TimeDelta::FromSeconds(1);
306 SetupTimestampKey(now, &optional);
307 optional.SetInteger(message_center::kPriorityKey, 0);
308 std::string default_id = AddNotification(&optional);
311 // Popups: latest comes first.
312 NotificationList::PopupNotifications popups =
313 notification_list()->GetPopupNotifications();
314 EXPECT_EQ(3u, popups.size());
315 NotificationList::PopupNotifications::const_iterator iter = popups.begin();
316 EXPECT_EQ(default_id, (*iter)->id());
317 iter++;
318 EXPECT_EQ(high_id, (*iter)->id());
319 iter++;
320 EXPECT_EQ(max_id, (*iter)->id());
323 // Notifications: high priority comes ealier.
324 const NotificationList::Notifications& notifications =
325 notification_list()->GetNotifications();
326 EXPECT_EQ(3u, notifications.size());
327 NotificationList::Notifications::const_iterator iter =
328 notifications.begin();
329 EXPECT_EQ(max_id, (*iter)->id());
330 iter++;
331 EXPECT_EQ(high_id, (*iter)->id());
332 iter++;
333 EXPECT_EQ(default_id, (*iter)->id());
337 TEST_F(NotificationListTest, MarkSinglePopupAsShown) {
338 std::string id1 = AddNotification(NULL);
339 std::string id2 = AddNotification(NULL);
340 std::string id3 = AddNotification(NULL);
341 ASSERT_EQ(3u, notification_list()->NotificationCount());
342 ASSERT_EQ(std::min(static_cast<size_t>(3u),
343 NotificationList::kMaxVisiblePopupNotifications),
344 GetPopupCounts());
346 notification_list()->MarkSinglePopupAsShown(id2, true);
347 notification_list()->MarkSinglePopupAsShown(id3, false);
348 EXPECT_EQ(3u, notification_list()->NotificationCount());
349 EXPECT_EQ(2u, notification_list()->unread_count());
350 EXPECT_EQ(1u, GetPopupCounts());
351 NotificationList::PopupNotifications popups =
352 notification_list()->GetPopupNotifications();
353 EXPECT_EQ(id1, (*popups.begin())->id());
355 // The notifications in the NotificationCenter are unaffected by popups shown.
356 NotificationList::Notifications notifications =
357 notification_list()->GetNotifications();
358 NotificationList::Notifications::const_iterator iter = notifications.begin();
359 EXPECT_EQ(id3, (*iter)->id());
360 iter++;
361 EXPECT_EQ(id2, (*iter)->id());
362 iter++;
363 EXPECT_EQ(id1, (*iter)->id());
365 // Trickier scenario.
366 notification_list()->MarkPopupsAsShown(message_center::DEFAULT_PRIORITY);
367 std::string id4 = AddNotification(NULL);
368 std::string id5 = AddNotification(NULL);
369 std::string id6 = AddNotification(NULL);
370 notification_list()->MarkSinglePopupAsShown(id5, true);
373 popups.clear();
374 popups = notification_list()->GetPopupNotifications();
375 EXPECT_EQ(2u, popups.size());
376 NotificationList::PopupNotifications::const_iterator iter = popups.begin();
377 EXPECT_EQ(id6, (*iter)->id());
378 iter++;
379 EXPECT_EQ(id4, (*iter)->id());
382 notifications.clear();
383 notifications = notification_list()->GetNotifications();
384 EXPECT_EQ(6u, notifications.size());
385 iter = notifications.begin();
386 EXPECT_EQ(id6, (*iter)->id());
387 iter++;
388 EXPECT_EQ(id5, (*iter)->id());
389 iter++;
390 EXPECT_EQ(id4, (*iter)->id());
391 iter++;
392 EXPECT_EQ(id3, (*iter)->id());
393 iter++;
394 EXPECT_EQ(id2, (*iter)->id());
395 iter++;
396 EXPECT_EQ(id1, (*iter)->id());
399 TEST_F(NotificationListTest, QuietMode) {
400 notification_list()->SetQuietMode(true);
401 AddNotification(NULL);
402 AddPriorityNotification(1);
403 AddPriorityNotification(2);
404 EXPECT_EQ(3u, notification_list()->NotificationCount());
405 EXPECT_EQ(0u, GetPopupCounts());
406 // TODO(mukai): fix here when notification_list distinguish dismiss by quiet
407 // mode and by user operation.
408 EXPECT_EQ(0u, notification_list()->unread_count());
410 notification_list()->SetQuietMode(false);
411 AddNotification(NULL);
412 EXPECT_EQ(4u, notification_list()->NotificationCount());
413 EXPECT_EQ(1u, GetPopupCounts());
415 // TODO(mukai): Add test of quiet mode with expiration.
418 } // namespace message_center