Simple Cache: a few tests for rare corner cases with CRC check missing.
[chromium-blink-merge.git] / ui / message_center / notification_list_unittest.cc
blob02e3a5d288f95634f9deafedac9a53115a246729
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/message_center_style.h"
14 #include "ui/message_center/notification_types.h"
16 namespace message_center {
17 namespace test {
19 class NotificationListTest : public testing::Test {
20 public:
21 NotificationListTest() {}
22 virtual ~NotificationListTest() {}
24 virtual void SetUp() {
25 notification_list_.reset(new NotificationList());
26 counter_ = 0;
29 protected:
30 // Currently NotificationListTest doesn't care about some fields like title or
31 // message, so put a simple template on it. Returns the id of the new
32 // notification.
33 std::string AddNotification(const base::DictionaryValue* optional_fields) {
34 std::string new_id = base::StringPrintf(kIdFormat, counter_);
35 notification_list_->AddNotification(
36 message_center::NOTIFICATION_TYPE_SIMPLE,
37 new_id,
38 UTF8ToUTF16(base::StringPrintf(kTitleFormat, counter_)),
39 UTF8ToUTF16(base::StringPrintf(kMessageFormat, counter_)),
40 UTF8ToUTF16(kDisplaySource),
41 kExtensionId,
42 optional_fields,
43 NULL);
44 counter_++;
45 return new_id;
48 // Utility methods of AddNotification.
49 std::string AddPriorityNotification(NotificationPriority priority) {
50 base::DictionaryValue optional;
51 optional.SetInteger(message_center::kPriorityKey,
52 static_cast<int>(priority));
53 return AddNotification(&optional);
55 void SetupTimestampKey(const base::Time& time,
56 base::DictionaryValue* optional) {
57 string16 time_formatted = base::TimeFormatShortDateAndTime(time);
58 optional->SetString(message_center::kTimestampKey, time_formatted);
61 size_t GetPopupCounts() {
62 return notification_list()->GetPopupNotifications().size();
65 Notification* GetNotification(const std::string& id) {
66 NotificationList::Notifications::iterator iter =
67 notification_list()->GetNotification(id);
68 if (iter == notification_list()->GetNotifications().end())
69 return NULL;
70 return *iter;
73 NotificationList* notification_list() { return notification_list_.get(); }
75 private:
76 static const char kIdFormat[];
77 static const char kTitleFormat[];
78 static const char kMessageFormat[];
79 static const char kDisplaySource[];
80 static const char kExtensionId[];
82 scoped_ptr<NotificationList> notification_list_;
83 size_t counter_;
85 DISALLOW_COPY_AND_ASSIGN(NotificationListTest);
88 bool IsInNotifications(const NotificationList::Notifications& notifications,
89 const std::string& id) {
90 for (NotificationList::Notifications::const_iterator iter =
91 notifications.begin(); iter != notifications.end(); ++iter) {
92 if ((*iter)->id() == id)
93 return true;
95 return false;
98 const char NotificationListTest::kIdFormat[] = "id%ld";
99 const char NotificationListTest::kTitleFormat[] = "id%ld";
100 const char NotificationListTest::kMessageFormat[] = "message%ld";
101 const char NotificationListTest::kDisplaySource[] = "source";
102 const char NotificationListTest::kExtensionId[] = "ext";
104 TEST_F(NotificationListTest, Basic) {
105 ASSERT_EQ(0u, notification_list()->NotificationCount());
106 ASSERT_EQ(0u, notification_list()->unread_count());
108 std::string id0 = AddNotification(NULL);
109 EXPECT_EQ(1u, notification_list()->NotificationCount());
110 std::string id1 = AddNotification(NULL);
111 EXPECT_EQ(2u, notification_list()->NotificationCount());
112 EXPECT_EQ(2u, notification_list()->unread_count());
114 EXPECT_TRUE(notification_list()->HasPopupNotifications());
115 EXPECT_TRUE(notification_list()->HasNotification(id0));
116 EXPECT_TRUE(notification_list()->HasNotification(id1));
117 EXPECT_FALSE(notification_list()->HasNotification(id1 + "foo"));
119 EXPECT_EQ(2u, GetPopupCounts());
121 notification_list()->MarkPopupsAsShown(0);
122 EXPECT_EQ(2u, notification_list()->NotificationCount());
123 EXPECT_EQ(0u, GetPopupCounts());
125 notification_list()->RemoveNotification(id0);
126 EXPECT_EQ(1u, notification_list()->NotificationCount());
127 EXPECT_EQ(1u, notification_list()->unread_count());
129 AddNotification(NULL);
130 EXPECT_EQ(2u, notification_list()->NotificationCount());
132 notification_list()->RemoveAllNotifications();
133 EXPECT_EQ(0u, notification_list()->NotificationCount());
134 EXPECT_EQ(0u, notification_list()->unread_count());
137 TEST_F(NotificationListTest, MessageCenterVisible) {
138 AddNotification(NULL);
139 EXPECT_EQ(1u, notification_list()->NotificationCount());
140 ASSERT_EQ(1u, notification_list()->unread_count());
141 ASSERT_EQ(1u, GetPopupCounts());
143 // Make the message center visible. It resets the unread count and popup
144 // counts.
145 notification_list()->SetMessageCenterVisible(true, NULL);
146 ASSERT_EQ(0u, notification_list()->unread_count());
147 ASSERT_EQ(0u, GetPopupCounts());
150 TEST_F(NotificationListTest, UnreadCount) {
151 std::string id0 = AddNotification(NULL);
152 std::string id1 = AddNotification(NULL);
153 ASSERT_EQ(2u, notification_list()->unread_count());
155 notification_list()->MarkSinglePopupAsDisplayed(id0);
156 EXPECT_EQ(1u, notification_list()->unread_count());
157 notification_list()->MarkSinglePopupAsDisplayed(id0);
158 EXPECT_EQ(1u, notification_list()->unread_count());
159 notification_list()->MarkSinglePopupAsDisplayed(id1);
160 EXPECT_EQ(0u, notification_list()->unread_count());
163 TEST_F(NotificationListTest, UpdateNotification) {
164 std::string id0 = AddNotification(NULL);
165 std::string replaced = id0 + "_replaced";
166 EXPECT_EQ(1u, notification_list()->NotificationCount());
167 notification_list()->UpdateNotificationMessage(id0,
168 replaced,
169 UTF8ToUTF16("newtitle"),
170 UTF8ToUTF16("newbody"),
171 NULL,
172 NULL);
173 EXPECT_EQ(1u, notification_list()->NotificationCount());
174 const NotificationList::Notifications& notifications =
175 notification_list()->GetNotifications();
176 EXPECT_EQ(replaced, (*notifications.begin())->id());
177 EXPECT_EQ(UTF8ToUTF16("newtitle"), (*notifications.begin())->title());
178 EXPECT_EQ(UTF8ToUTF16("newbody"), (*notifications.begin())->message());
181 TEST_F(NotificationListTest, GetNotificationsBySourceOrExtensions) {
182 notification_list()->AddNotification(message_center::NOTIFICATION_TYPE_SIMPLE,
183 "id0",
184 UTF8ToUTF16("title0"),
185 UTF8ToUTF16("message0"),
186 UTF8ToUTF16("source0"),
187 "ext0",
188 NULL,
189 NULL);
190 notification_list()->AddNotification(message_center::NOTIFICATION_TYPE_SIMPLE,
191 "id1",
192 UTF8ToUTF16("title1"),
193 UTF8ToUTF16("message1"),
194 UTF8ToUTF16("source0"),
195 "ext0",
196 NULL,
197 NULL);
198 notification_list()->AddNotification(message_center::NOTIFICATION_TYPE_SIMPLE,
199 "id2",
200 UTF8ToUTF16("title1"),
201 UTF8ToUTF16("message1"),
202 UTF8ToUTF16("source1"),
203 "ext0",
204 NULL,
205 NULL);
206 notification_list()->AddNotification(message_center::NOTIFICATION_TYPE_SIMPLE,
207 "id3",
208 UTF8ToUTF16("title1"),
209 UTF8ToUTF16("message1"),
210 UTF8ToUTF16("source2"),
211 "ext1",
212 NULL,
213 NULL);
215 NotificationList::Notifications by_source =
216 notification_list()->GetNotificationsBySource("id0");
217 EXPECT_TRUE(IsInNotifications(by_source, "id0"));
218 EXPECT_TRUE(IsInNotifications(by_source, "id1"));
219 EXPECT_FALSE(IsInNotifications(by_source, "id2"));
220 EXPECT_FALSE(IsInNotifications(by_source, "id3"));
222 NotificationList::Notifications by_extension =
223 notification_list()->GetNotificationsByExtension("id0");
224 EXPECT_TRUE(IsInNotifications(by_extension, "id0"));
225 EXPECT_TRUE(IsInNotifications(by_extension, "id1"));
226 EXPECT_TRUE(IsInNotifications(by_extension, "id2"));
227 EXPECT_FALSE(IsInNotifications(by_extension, "id3"));
230 TEST_F(NotificationListTest, OldPopupShouldNotBeHidden) {
231 std::vector<std::string> ids;
232 for (size_t i = 0; i <= kMaxVisiblePopupNotifications; i++)
233 ids.push_back(AddNotification(NULL));
235 NotificationList::PopupNotifications popups =
236 notification_list()->GetPopupNotifications();
237 // The popup should contain the oldest kMaxVisiblePopupNotifications. Newer
238 // one should come earlier in the popup list. It means, the last element
239 // of |popups| should be the firstly added one, and so on.
240 EXPECT_EQ(kMaxVisiblePopupNotifications, popups.size());
241 NotificationList::PopupNotifications::const_reverse_iterator iter =
242 popups.rbegin();
243 for (size_t i = 0; i < kMaxVisiblePopupNotifications; ++i, ++iter) {
244 EXPECT_EQ(ids[i], (*iter)->id()) << i;
247 notification_list()->MarkPopupsAsShown(message_center::DEFAULT_PRIORITY);
248 popups.clear();
249 popups = notification_list()->GetPopupNotifications();
250 EXPECT_EQ(1u, popups.size());
251 EXPECT_EQ(ids[ids.size() - 1], (*popups.begin())->id());
254 TEST_F(NotificationListTest, Priority) {
255 ASSERT_EQ(0u, notification_list()->NotificationCount());
256 ASSERT_EQ(0u, notification_list()->unread_count());
258 // Default priority has the limit on the number of the popups.
259 for (size_t i = 0; i <= kMaxVisiblePopupNotifications; ++i)
260 AddNotification(NULL);
261 EXPECT_EQ(kMaxVisiblePopupNotifications + 1,
262 notification_list()->NotificationCount());
263 EXPECT_EQ(kMaxVisiblePopupNotifications, GetPopupCounts());
265 // Low priority: not visible to popups.
266 notification_list()->SetMessageCenterVisible(true, NULL);
267 notification_list()->SetMessageCenterVisible(false, NULL);
268 EXPECT_EQ(0u, notification_list()->unread_count());
269 AddPriorityNotification(LOW_PRIORITY);
270 EXPECT_EQ(kMaxVisiblePopupNotifications + 2,
271 notification_list()->NotificationCount());
272 EXPECT_EQ(1u, notification_list()->unread_count());
273 EXPECT_EQ(0u, GetPopupCounts());
275 // Minimum priority: doesn't update the unread count.
276 AddPriorityNotification(MIN_PRIORITY);
277 EXPECT_EQ(kMaxVisiblePopupNotifications + 3,
278 notification_list()->NotificationCount());
279 EXPECT_EQ(1u, notification_list()->unread_count());
280 EXPECT_EQ(0u, GetPopupCounts());
282 notification_list()->RemoveAllNotifications();
284 // Higher priority: no limits to the number of popups.
285 for (size_t i = 0; i < kMaxVisiblePopupNotifications * 2; ++i)
286 AddPriorityNotification(HIGH_PRIORITY);
287 for (size_t i = 0; i < kMaxVisiblePopupNotifications * 2; ++i)
288 AddPriorityNotification(MAX_PRIORITY);
289 EXPECT_EQ(kMaxVisiblePopupNotifications * 4,
290 notification_list()->NotificationCount());
291 EXPECT_EQ(kMaxVisiblePopupNotifications * 4, GetPopupCounts());
294 TEST_F(NotificationListTest, HasPopupsWithPriority) {
295 ASSERT_EQ(0u, notification_list()->NotificationCount());
296 ASSERT_EQ(0u, notification_list()->unread_count());
298 AddPriorityNotification(MIN_PRIORITY);
299 AddPriorityNotification(MAX_PRIORITY);
301 EXPECT_EQ(1u, GetPopupCounts());
304 TEST_F(NotificationListTest, PriorityPromotion) {
305 std::string id0 = AddPriorityNotification(LOW_PRIORITY);
306 std::string replaced = id0 + "_replaced";
307 EXPECT_EQ(1u, notification_list()->NotificationCount());
308 EXPECT_EQ(0u, GetPopupCounts());
309 base::DictionaryValue optional;
310 optional.SetInteger(message_center::kPriorityKey, 1);
311 notification_list()->UpdateNotificationMessage(id0,
312 replaced,
313 UTF8ToUTF16("newtitle"),
314 UTF8ToUTF16("newbody"),
315 &optional,
316 NULL);
317 EXPECT_EQ(1u, notification_list()->NotificationCount());
318 EXPECT_EQ(1u, GetPopupCounts());
319 const NotificationList::Notifications& notifications =
320 notification_list()->GetNotifications();
321 EXPECT_EQ(replaced, (*notifications.begin())->id());
322 EXPECT_EQ(UTF8ToUTF16("newtitle"), (*notifications.begin())->title());
323 EXPECT_EQ(UTF8ToUTF16("newbody"), (*notifications.begin())->message());
324 EXPECT_EQ(1, (*notifications.begin())->priority());
327 TEST_F(NotificationListTest, PriorityPromotionWithPopups) {
328 std::string id0 = AddPriorityNotification(LOW_PRIORITY);
329 std::string id1 = AddPriorityNotification(DEFAULT_PRIORITY);
330 EXPECT_EQ(1u, GetPopupCounts());
331 notification_list()->MarkSinglePopupAsShown(id1, true);
332 EXPECT_EQ(0u, GetPopupCounts());
334 // id0 promoted to LOW->DEFAULT, it'll appear as toast (popup).
335 base::DictionaryValue priority_default;
336 priority_default.SetInteger(message_center::kPriorityKey,
337 static_cast<int>(DEFAULT_PRIORITY));
338 notification_list()->UpdateNotificationMessage(id0,
339 id0,
340 UTF8ToUTF16("newtitle"),
341 UTF8ToUTF16("newbody"),
342 &priority_default,
343 NULL);
344 EXPECT_EQ(1u, GetPopupCounts());
345 notification_list()->MarkSinglePopupAsShown(id0, true);
346 EXPECT_EQ(0u, GetPopupCounts());
348 // update with no promotion change for id0, it won't appear as a toast.
349 notification_list()->UpdateNotificationMessage(
350 id0, id0, UTF8ToUTF16("newtitle2"), UTF8ToUTF16("newbody2"), NULL, NULL);
351 EXPECT_EQ(0u, GetPopupCounts());
353 // id1 promoted to DEFAULT->HIGH, it'll appear as toast (popup).
354 base::DictionaryValue priority_high;
355 priority_high.SetInteger(message_center::kPriorityKey,
356 static_cast<int>(HIGH_PRIORITY));
357 notification_list()->UpdateNotificationMessage(id1,
358 id1,
359 UTF8ToUTF16("newtitle"),
360 UTF8ToUTF16("newbody"),
361 &priority_high,
362 NULL);
363 EXPECT_EQ(1u, GetPopupCounts());
364 notification_list()->MarkSinglePopupAsShown(id1, true);
365 EXPECT_EQ(0u, GetPopupCounts());
367 // id1 promoted to HIGH->MAX, it'll appear as toast again.
368 base::DictionaryValue priority_max;
369 priority_max.SetInteger(message_center::kPriorityKey,
370 static_cast<int>(MAX_PRIORITY));
371 notification_list()->UpdateNotificationMessage(id1,
372 id1,
373 UTF8ToUTF16("newtitle2"),
374 UTF8ToUTF16("newbody2"),
375 &priority_max,
376 NULL);
377 EXPECT_EQ(1u, GetPopupCounts());
378 notification_list()->MarkSinglePopupAsShown(id1, true);
379 EXPECT_EQ(0u, GetPopupCounts());
381 // id1 demoted to MAX->DEFAULT, no appearing as toast.
382 notification_list()->UpdateNotificationMessage(id1,
383 id1,
384 UTF8ToUTF16("newtitle3"),
385 UTF8ToUTF16("newbody3"),
386 &priority_default,
387 NULL);
388 EXPECT_EQ(0u, GetPopupCounts());
391 TEST_F(NotificationListTest, NotificationOrderAndPriority) {
392 base::Time now = base::Time::Now();
393 base::DictionaryValue optional;
394 SetupTimestampKey(now, &optional);
395 optional.SetInteger(message_center::kPriorityKey, 2);
396 std::string max_id = AddNotification(&optional);
397 now += base::TimeDelta::FromSeconds(1);
398 SetupTimestampKey(now, &optional);
399 optional.SetInteger(message_center::kPriorityKey, 1);
400 std::string high_id = AddNotification(&optional);
401 now += base::TimeDelta::FromSeconds(1);
402 SetupTimestampKey(now, &optional);
403 optional.SetInteger(message_center::kPriorityKey, 0);
404 std::string default_id = AddNotification(&optional);
407 // Popups: latest comes first.
408 NotificationList::PopupNotifications popups =
409 notification_list()->GetPopupNotifications();
410 EXPECT_EQ(3u, popups.size());
411 NotificationList::PopupNotifications::const_iterator iter = popups.begin();
412 EXPECT_EQ(default_id, (*iter)->id());
413 iter++;
414 EXPECT_EQ(high_id, (*iter)->id());
415 iter++;
416 EXPECT_EQ(max_id, (*iter)->id());
419 // Notifications: high priority comes ealier.
420 const NotificationList::Notifications& notifications =
421 notification_list()->GetNotifications();
422 EXPECT_EQ(3u, notifications.size());
423 NotificationList::Notifications::const_iterator iter =
424 notifications.begin();
425 EXPECT_EQ(max_id, (*iter)->id());
426 iter++;
427 EXPECT_EQ(high_id, (*iter)->id());
428 iter++;
429 EXPECT_EQ(default_id, (*iter)->id());
433 TEST_F(NotificationListTest, MarkSinglePopupAsShown) {
434 std::string id1 = AddNotification(NULL);
435 std::string id2 = AddNotification(NULL);
436 std::string id3 = AddNotification(NULL);
437 ASSERT_EQ(3u, notification_list()->NotificationCount());
438 ASSERT_EQ(std::min(static_cast<size_t>(3u), kMaxVisiblePopupNotifications),
439 GetPopupCounts());
440 notification_list()->MarkSinglePopupAsDisplayed(id1);
441 notification_list()->MarkSinglePopupAsDisplayed(id2);
442 notification_list()->MarkSinglePopupAsDisplayed(id3);
444 notification_list()->MarkSinglePopupAsShown(id2, true);
445 notification_list()->MarkSinglePopupAsShown(id3, false);
446 EXPECT_EQ(3u, notification_list()->NotificationCount());
447 EXPECT_EQ(1u, notification_list()->unread_count());
448 EXPECT_EQ(1u, GetPopupCounts());
449 NotificationList::PopupNotifications popups =
450 notification_list()->GetPopupNotifications();
451 EXPECT_EQ(id1, (*popups.begin())->id());
453 // The notifications in the NotificationCenter are unaffected by popups shown.
454 NotificationList::Notifications notifications =
455 notification_list()->GetNotifications();
456 NotificationList::Notifications::const_iterator iter = notifications.begin();
457 EXPECT_EQ(id3, (*iter)->id());
458 iter++;
459 EXPECT_EQ(id2, (*iter)->id());
460 iter++;
461 EXPECT_EQ(id1, (*iter)->id());
463 // Trickier scenario.
464 notification_list()->MarkPopupsAsShown(message_center::DEFAULT_PRIORITY);
465 std::string id4 = AddNotification(NULL);
466 std::string id5 = AddNotification(NULL);
467 std::string id6 = AddNotification(NULL);
468 notification_list()->MarkSinglePopupAsShown(id5, true);
471 popups.clear();
472 popups = notification_list()->GetPopupNotifications();
473 EXPECT_EQ(2u, popups.size());
474 NotificationList::PopupNotifications::const_iterator iter = popups.begin();
475 EXPECT_EQ(id6, (*iter)->id());
476 iter++;
477 EXPECT_EQ(id4, (*iter)->id());
480 notifications.clear();
481 notifications = notification_list()->GetNotifications();
482 EXPECT_EQ(6u, notifications.size());
483 iter = notifications.begin();
484 EXPECT_EQ(id6, (*iter)->id());
485 iter++;
486 EXPECT_EQ(id5, (*iter)->id());
487 iter++;
488 EXPECT_EQ(id4, (*iter)->id());
489 iter++;
490 EXPECT_EQ(id3, (*iter)->id());
491 iter++;
492 EXPECT_EQ(id2, (*iter)->id());
493 iter++;
494 EXPECT_EQ(id1, (*iter)->id());
497 TEST_F(NotificationListTest, UpdateAfterMarkedAsShown) {
498 std::string id1 = AddNotification(NULL);
499 std::string id2 = AddNotification(NULL);
500 notification_list()->MarkSinglePopupAsDisplayed(id1);
501 notification_list()->MarkSinglePopupAsDisplayed(id2);
503 EXPECT_EQ(2u, GetPopupCounts());
505 const Notification* n1 = GetNotification(id1);
506 EXPECT_FALSE(n1->shown_as_popup());
507 EXPECT_TRUE(n1->is_read());
509 notification_list()->MarkSinglePopupAsShown(id1, true);
511 n1 = GetNotification(id1);
512 EXPECT_TRUE(n1->shown_as_popup());
513 EXPECT_TRUE(n1->is_read());
515 const std::string replaced("test-replaced-id");
516 notification_list()->UpdateNotificationMessage(id1,
517 replaced,
518 UTF8ToUTF16("newtitle"),
519 UTF8ToUTF16("newbody"),
520 NULL,
521 NULL);
522 n1 = GetNotification(id1);
523 EXPECT_TRUE(n1 == NULL);
524 const Notification* nr = GetNotification(replaced);
525 EXPECT_TRUE(nr->shown_as_popup());
526 EXPECT_TRUE(nr->is_read());
529 TEST_F(NotificationListTest, QuietMode) {
530 notification_list()->SetQuietMode(true);
531 AddNotification(NULL);
532 AddPriorityNotification(HIGH_PRIORITY);
533 AddPriorityNotification(MAX_PRIORITY);
534 EXPECT_EQ(3u, notification_list()->NotificationCount());
535 EXPECT_EQ(0u, GetPopupCounts());
536 // TODO(mukai): fix here when notification_list distinguish dismiss by quiet
537 // mode and by user operation.
538 EXPECT_EQ(0u, notification_list()->unread_count());
540 notification_list()->SetQuietMode(false);
541 AddNotification(NULL);
542 EXPECT_EQ(4u, notification_list()->NotificationCount());
543 EXPECT_EQ(1u, GetPopupCounts());
545 // TODO(mukai): Add test of quiet mode with expiration.
548 } // namespace test
549 } // namespace message_center