- add sources.
[platform/framework/web/crosswalk.git] / src / ui / message_center / notification_list_unittest.cc
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.
4
5 #include "ui/message_center/notification_list.h"
6
7 #include "base/basictypes.h"
8 #include "base/i18n/time_formatting.h"
9 #include "base/strings/stringprintf.h"
10 #include "base/strings/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_blocker.h"
15 #include "ui/message_center/notification_types.h"
16 #include "ui/message_center/notifier_settings.h"
17
18 namespace message_center {
19
20 class NotificationListTest : public testing::Test {
21  public:
22   NotificationListTest() {}
23   virtual ~NotificationListTest() {}
24
25   virtual void SetUp() {
26     notification_list_.reset(new NotificationList());
27     counter_ = 0;
28   }
29
30  protected:
31   // Currently NotificationListTest doesn't care about some fields like title or
32   // message, so put a simple template on it. Returns the id of the new
33   // notification.
34   std::string AddNotification(
35       const message_center::RichNotificationData& optional_fields) {
36     std::string new_id;
37     scoped_ptr<Notification> notification(
38         MakeNotification(optional_fields, &new_id));
39     notification_list_->AddNotification(notification.Pass());
40     counter_++;
41     return new_id;
42   }
43
44   std::string AddNotification() {
45     return AddNotification(message_center::RichNotificationData());
46   }
47
48   // Construct a new notification for testing, but don't add it to the list yet.
49   scoped_ptr<Notification> MakeNotification(
50       const message_center::RichNotificationData& optional_fields,
51       std::string* id_out) {
52     *id_out = base::StringPrintf(kIdFormat, counter_);
53     scoped_ptr<Notification> notification(new Notification(
54         message_center::NOTIFICATION_TYPE_SIMPLE,
55         *id_out,
56         UTF8ToUTF16(base::StringPrintf(kTitleFormat, counter_)),
57         UTF8ToUTF16(base::StringPrintf(kMessageFormat, counter_)),
58         gfx::Image(),
59         UTF8ToUTF16(kDisplaySource),
60         NotifierId(NotifierId::APPLICATION, kExtensionId),
61         optional_fields,
62         NULL));
63     return notification.Pass();
64   }
65
66   scoped_ptr<Notification> MakeNotification(std::string* id_out) {
67     return MakeNotification(message_center::RichNotificationData(), id_out);
68   }
69
70   // Utility methods of AddNotification.
71   std::string AddPriorityNotification(NotificationPriority priority) {
72     message_center::RichNotificationData optional;
73     optional.priority = priority;
74     return AddNotification(optional);
75   }
76
77   NotificationList::PopupNotifications GetPopups() {
78     return notification_list()->GetPopupNotifications(
79         std::vector<NotificationBlocker*>(), NULL);
80   }
81
82   size_t GetPopupCounts() {
83     return GetPopups().size();
84   }
85
86   Notification* GetNotification(const std::string& id) {
87     NotificationList::Notifications::iterator iter =
88         notification_list()->GetNotification(id);
89     if (iter == notification_list()->GetNotifications().end())
90       return NULL;
91     return *iter;
92   }
93
94   NotificationList* notification_list() { return notification_list_.get(); }
95
96   static const char kIdFormat[];
97   static const char kTitleFormat[];
98   static const char kMessageFormat[];
99   static const char kDisplaySource[];
100   static const char kExtensionId[];
101
102  private:
103   scoped_ptr<NotificationList> notification_list_;
104   size_t counter_;
105
106   DISALLOW_COPY_AND_ASSIGN(NotificationListTest);
107 };
108
109 bool IsInNotifications(const NotificationList::Notifications& notifications,
110                        const std::string& id) {
111   for (NotificationList::Notifications::const_iterator iter =
112            notifications.begin(); iter != notifications.end(); ++iter) {
113     if ((*iter)->id() == id)
114       return true;
115   }
116   return false;
117 }
118
119 const char NotificationListTest::kIdFormat[] = "id%ld";
120 const char NotificationListTest::kTitleFormat[] = "id%ld";
121 const char NotificationListTest::kMessageFormat[] = "message%ld";
122 const char NotificationListTest::kDisplaySource[] = "source";
123 const char NotificationListTest::kExtensionId[] = "ext";
124
125 TEST_F(NotificationListTest, Basic) {
126   ASSERT_EQ(0u, notification_list()->NotificationCount());
127   ASSERT_EQ(0u, notification_list()->unread_count());
128
129   std::string id0 = AddNotification();
130   EXPECT_EQ(1u, notification_list()->NotificationCount());
131   std::string id1 = AddNotification();
132   EXPECT_EQ(2u, notification_list()->NotificationCount());
133   EXPECT_EQ(2u, notification_list()->unread_count());
134
135   EXPECT_TRUE(notification_list()->HasPopupNotifications(
136       std::vector<NotificationBlocker*>()));
137   EXPECT_TRUE(notification_list()->HasNotification(id0));
138   EXPECT_TRUE(notification_list()->HasNotification(id1));
139   EXPECT_FALSE(notification_list()->HasNotification(id1 + "foo"));
140
141   EXPECT_EQ(2u, GetPopupCounts());
142
143   notification_list()->MarkSinglePopupAsShown(id0, true);
144   notification_list()->MarkSinglePopupAsShown(id1, true);
145   EXPECT_EQ(2u, notification_list()->NotificationCount());
146   EXPECT_EQ(0u, GetPopupCounts());
147
148   notification_list()->RemoveNotification(id0);
149   EXPECT_EQ(1u, notification_list()->NotificationCount());
150   EXPECT_EQ(1u, notification_list()->unread_count());
151
152   AddNotification();
153   EXPECT_EQ(2u, notification_list()->NotificationCount());
154
155   notification_list()->RemoveAllNotifications();
156   EXPECT_EQ(0u, notification_list()->NotificationCount());
157   EXPECT_EQ(0u, notification_list()->unread_count());
158 }
159
160 TEST_F(NotificationListTest, MessageCenterVisible) {
161   AddNotification();
162   EXPECT_EQ(1u, notification_list()->NotificationCount());
163   ASSERT_EQ(1u, notification_list()->unread_count());
164   ASSERT_EQ(1u, GetPopupCounts());
165
166   // Make the message center visible. It resets the unread count and popup
167   // counts.
168   notification_list()->SetMessageCenterVisible(true, NULL);
169   ASSERT_EQ(0u, notification_list()->unread_count());
170   ASSERT_EQ(0u, GetPopupCounts());
171 }
172
173 TEST_F(NotificationListTest, UnreadCount) {
174   std::string id0 = AddNotification();
175   std::string id1 = AddNotification();
176   ASSERT_EQ(2u, notification_list()->unread_count());
177
178   notification_list()->MarkSinglePopupAsDisplayed(id0);
179   EXPECT_EQ(1u, notification_list()->unread_count());
180   notification_list()->MarkSinglePopupAsDisplayed(id0);
181   EXPECT_EQ(1u, notification_list()->unread_count());
182   notification_list()->MarkSinglePopupAsDisplayed(id1);
183   EXPECT_EQ(0u, notification_list()->unread_count());
184 }
185
186 TEST_F(NotificationListTest, UpdateNotification) {
187   std::string id0 = AddNotification();
188   std::string replaced = id0 + "_replaced";
189   EXPECT_EQ(1u, notification_list()->NotificationCount());
190   scoped_ptr<Notification> notification(
191       new Notification(message_center::NOTIFICATION_TYPE_SIMPLE,
192                        replaced,
193                        UTF8ToUTF16("newtitle"),
194                        UTF8ToUTF16("newbody"),
195                        gfx::Image(),
196                        UTF8ToUTF16(kDisplaySource),
197                        NotifierId(NotifierId::APPLICATION, kExtensionId),
198                        message_center::RichNotificationData(),
199                        NULL));
200   notification_list()->UpdateNotificationMessage(id0, notification.Pass());
201   EXPECT_EQ(1u, notification_list()->NotificationCount());
202   const NotificationList::Notifications& notifications =
203       notification_list()->GetNotifications();
204   EXPECT_EQ(replaced, (*notifications.begin())->id());
205   EXPECT_EQ(UTF8ToUTF16("newtitle"), (*notifications.begin())->title());
206   EXPECT_EQ(UTF8ToUTF16("newbody"), (*notifications.begin())->message());
207 }
208
209 TEST_F(NotificationListTest, GetNotificationsByNotifierId) {
210   NotifierId id0(NotifierId::APPLICATION, "ext0");
211   NotifierId id1(NotifierId::APPLICATION, "ext1");
212   NotifierId id2(GURL("http://example.com"));
213   NotifierId id3(0);
214   scoped_ptr<Notification> notification(
215       new Notification(message_center::NOTIFICATION_TYPE_SIMPLE,
216                        "id0",
217                        UTF8ToUTF16("title0"),
218                        UTF8ToUTF16("message0"),
219                        gfx::Image(),
220                        UTF8ToUTF16("source0"),
221                        id0,
222                        message_center::RichNotificationData(),
223                        NULL));
224   notification_list()->AddNotification(notification.Pass());
225   notification.reset(new Notification(message_center::NOTIFICATION_TYPE_SIMPLE,
226                                       "id1",
227                                       UTF8ToUTF16("title1"),
228                                       UTF8ToUTF16("message1"),
229                                       gfx::Image(),
230                                       UTF8ToUTF16("source0"),
231                                       id0,
232                                       message_center::RichNotificationData(),
233                                       NULL));
234   notification_list()->AddNotification(notification.Pass());
235   notification.reset(new Notification(message_center::NOTIFICATION_TYPE_SIMPLE,
236                                       "id2",
237                                       UTF8ToUTF16("title1"),
238                                       UTF8ToUTF16("message1"),
239                                       gfx::Image(),
240                                       UTF8ToUTF16("source1"),
241                                       id0,
242                                       message_center::RichNotificationData(),
243                                       NULL));
244   notification_list()->AddNotification(notification.Pass());
245   notification.reset(new Notification(message_center::NOTIFICATION_TYPE_SIMPLE,
246                                       "id3",
247                                       UTF8ToUTF16("title1"),
248                                       UTF8ToUTF16("message1"),
249                                       gfx::Image(),
250                                       UTF8ToUTF16("source2"),
251                                       id1,
252                                       message_center::RichNotificationData(),
253                                       NULL));
254   notification_list()->AddNotification(notification.Pass());
255   notification.reset(new Notification(message_center::NOTIFICATION_TYPE_SIMPLE,
256                                       "id4",
257                                       UTF8ToUTF16("title1"),
258                                       UTF8ToUTF16("message1"),
259                                       gfx::Image(),
260                                       UTF8ToUTF16("source2"),
261                                       id2,
262                                       message_center::RichNotificationData(),
263                                       NULL));
264   notification_list()->AddNotification(notification.Pass());
265   notification.reset(new Notification(message_center::NOTIFICATION_TYPE_SIMPLE,
266                                       "id5",
267                                       UTF8ToUTF16("title1"),
268                                       UTF8ToUTF16("message1"),
269                                       gfx::Image(),
270                                       UTF8ToUTF16("source2"),
271                                       id3,
272                                       message_center::RichNotificationData(),
273                                       NULL));
274   notification_list()->AddNotification(notification.Pass());
275
276   NotificationList::Notifications by_notifier_id =
277       notification_list()->GetNotificationsByNotifierId(id0);
278   EXPECT_TRUE(IsInNotifications(by_notifier_id, "id0"));
279   EXPECT_TRUE(IsInNotifications(by_notifier_id, "id1"));
280   EXPECT_TRUE(IsInNotifications(by_notifier_id, "id2"));
281   EXPECT_FALSE(IsInNotifications(by_notifier_id, "id3"));
282   EXPECT_FALSE(IsInNotifications(by_notifier_id, "id4"));
283   EXPECT_FALSE(IsInNotifications(by_notifier_id, "id5"));
284
285   by_notifier_id = notification_list()->GetNotificationsByNotifierId(id1);
286   EXPECT_FALSE(IsInNotifications(by_notifier_id, "id0"));
287   EXPECT_FALSE(IsInNotifications(by_notifier_id, "id1"));
288   EXPECT_FALSE(IsInNotifications(by_notifier_id, "id2"));
289   EXPECT_TRUE(IsInNotifications(by_notifier_id, "id3"));
290   EXPECT_FALSE(IsInNotifications(by_notifier_id, "id4"));
291   EXPECT_FALSE(IsInNotifications(by_notifier_id, "id5"));
292
293   by_notifier_id = notification_list()->GetNotificationsByNotifierId(id2);
294   EXPECT_FALSE(IsInNotifications(by_notifier_id, "id0"));
295   EXPECT_FALSE(IsInNotifications(by_notifier_id, "id1"));
296   EXPECT_FALSE(IsInNotifications(by_notifier_id, "id2"));
297   EXPECT_FALSE(IsInNotifications(by_notifier_id, "id3"));
298   EXPECT_TRUE(IsInNotifications(by_notifier_id, "id4"));
299   EXPECT_FALSE(IsInNotifications(by_notifier_id, "id5"));
300
301   by_notifier_id = notification_list()->GetNotificationsByNotifierId(id3);
302   EXPECT_FALSE(IsInNotifications(by_notifier_id, "id0"));
303   EXPECT_FALSE(IsInNotifications(by_notifier_id, "id1"));
304   EXPECT_FALSE(IsInNotifications(by_notifier_id, "id2"));
305   EXPECT_FALSE(IsInNotifications(by_notifier_id, "id3"));
306   EXPECT_FALSE(IsInNotifications(by_notifier_id, "id4"));
307   EXPECT_TRUE(IsInNotifications(by_notifier_id, "id5"));
308 }
309
310 TEST_F(NotificationListTest, OldPopupShouldNotBeHidden) {
311   std::vector<std::string> ids;
312   for (size_t i = 0; i <= kMaxVisiblePopupNotifications; i++)
313     ids.push_back(AddNotification());
314
315   NotificationList::PopupNotifications popups = GetPopups();
316   // The popup should contain the oldest kMaxVisiblePopupNotifications. Newer
317   // one should come earlier in the popup list. It means, the last element
318   // of |popups| should be the firstly added one, and so on.
319   EXPECT_EQ(kMaxVisiblePopupNotifications, popups.size());
320   NotificationList::PopupNotifications::const_reverse_iterator iter =
321       popups.rbegin();
322   for (size_t i = 0; i < kMaxVisiblePopupNotifications; ++i, ++iter) {
323     EXPECT_EQ(ids[i], (*iter)->id()) << i;
324   }
325
326   for (NotificationList::PopupNotifications::const_iterator iter =
327            popups.begin(); iter != popups.end(); ++iter) {
328     notification_list()->MarkSinglePopupAsShown((*iter)->id(), false);
329   }
330   popups.clear();
331   popups = GetPopups();
332   EXPECT_EQ(1u, popups.size());
333   EXPECT_EQ(ids[ids.size() - 1], (*popups.begin())->id());
334 }
335
336 TEST_F(NotificationListTest, Priority) {
337   ASSERT_EQ(0u, notification_list()->NotificationCount());
338   ASSERT_EQ(0u, notification_list()->unread_count());
339
340   // Default priority has the limit on the number of the popups.
341   for (size_t i = 0; i <= kMaxVisiblePopupNotifications; ++i)
342     AddNotification();
343   EXPECT_EQ(kMaxVisiblePopupNotifications + 1,
344             notification_list()->NotificationCount());
345   EXPECT_EQ(kMaxVisiblePopupNotifications, GetPopupCounts());
346
347   // Low priority: not visible to popups.
348   notification_list()->SetMessageCenterVisible(true, NULL);
349   notification_list()->SetMessageCenterVisible(false, NULL);
350   EXPECT_EQ(0u, notification_list()->unread_count());
351   AddPriorityNotification(LOW_PRIORITY);
352   EXPECT_EQ(kMaxVisiblePopupNotifications + 2,
353             notification_list()->NotificationCount());
354   EXPECT_EQ(1u, notification_list()->unread_count());
355   EXPECT_EQ(0u, GetPopupCounts());
356
357   // Minimum priority: doesn't update the unread count.
358   AddPriorityNotification(MIN_PRIORITY);
359   EXPECT_EQ(kMaxVisiblePopupNotifications + 3,
360             notification_list()->NotificationCount());
361   EXPECT_EQ(1u, notification_list()->unread_count());
362   EXPECT_EQ(0u, GetPopupCounts());
363
364   notification_list()->RemoveAllNotifications();
365
366   // Higher priority: no limits to the number of popups.
367   for (size_t i = 0; i < kMaxVisiblePopupNotifications * 2; ++i)
368     AddPriorityNotification(HIGH_PRIORITY);
369   for (size_t i = 0; i < kMaxVisiblePopupNotifications * 2; ++i)
370     AddPriorityNotification(MAX_PRIORITY);
371   EXPECT_EQ(kMaxVisiblePopupNotifications * 4,
372             notification_list()->NotificationCount());
373   EXPECT_EQ(kMaxVisiblePopupNotifications * 4, GetPopupCounts());
374 }
375
376 TEST_F(NotificationListTest, HasPopupsWithPriority) {
377   ASSERT_EQ(0u, notification_list()->NotificationCount());
378   ASSERT_EQ(0u, notification_list()->unread_count());
379
380   AddPriorityNotification(MIN_PRIORITY);
381   AddPriorityNotification(MAX_PRIORITY);
382
383   EXPECT_EQ(1u, GetPopupCounts());
384 }
385
386 TEST_F(NotificationListTest, HasPopupsWithSystemPriority) {
387   ASSERT_EQ(0u, notification_list()->NotificationCount());
388   ASSERT_EQ(0u, notification_list()->unread_count());
389
390   std::string normal_id = AddPriorityNotification(DEFAULT_PRIORITY);
391   std::string system_id = AddNotification();
392   GetNotification(system_id)->SetSystemPriority();
393
394   EXPECT_EQ(2u, GetPopupCounts());
395
396   notification_list()->MarkSinglePopupAsDisplayed(normal_id);
397   notification_list()->MarkSinglePopupAsDisplayed(system_id);
398
399   notification_list()->MarkSinglePopupAsShown(normal_id, false);
400   notification_list()->MarkSinglePopupAsShown(system_id, false);
401
402   notification_list()->SetMessageCenterVisible(true, NULL);
403   notification_list()->SetMessageCenterVisible(false, NULL);
404   EXPECT_EQ(1u, GetPopupCounts());
405
406   // Mark as read -- emulation of mouse click.
407   notification_list()->MarkSinglePopupAsShown(system_id, true);
408   EXPECT_EQ(0u, GetPopupCounts());
409 }
410
411 TEST_F(NotificationListTest, PriorityPromotion) {
412   std::string id0 = AddPriorityNotification(LOW_PRIORITY);
413   std::string replaced = id0 + "_replaced";
414   EXPECT_EQ(1u, notification_list()->NotificationCount());
415   EXPECT_EQ(0u, GetPopupCounts());
416   message_center::RichNotificationData optional;
417   optional.priority = 1;
418   scoped_ptr<Notification> notification(
419       new Notification(message_center::NOTIFICATION_TYPE_SIMPLE,
420                        replaced,
421                        UTF8ToUTF16("newtitle"),
422                        UTF8ToUTF16("newbody"),
423                        gfx::Image(),
424                        UTF8ToUTF16(kDisplaySource),
425                        NotifierId(NotifierId::APPLICATION, kExtensionId),
426                        optional,
427                        NULL));
428   notification_list()->UpdateNotificationMessage(id0, notification.Pass());
429   EXPECT_EQ(1u, notification_list()->NotificationCount());
430   EXPECT_EQ(1u, GetPopupCounts());
431   const NotificationList::Notifications& notifications =
432       notification_list()->GetNotifications();
433   EXPECT_EQ(replaced, (*notifications.begin())->id());
434   EXPECT_EQ(UTF8ToUTF16("newtitle"), (*notifications.begin())->title());
435   EXPECT_EQ(UTF8ToUTF16("newbody"), (*notifications.begin())->message());
436   EXPECT_EQ(1, (*notifications.begin())->priority());
437 }
438
439 TEST_F(NotificationListTest, PriorityPromotionWithPopups) {
440   std::string id0 = AddPriorityNotification(LOW_PRIORITY);
441   std::string id1 = AddPriorityNotification(DEFAULT_PRIORITY);
442   EXPECT_EQ(1u, GetPopupCounts());
443   notification_list()->MarkSinglePopupAsShown(id1, true);
444   EXPECT_EQ(0u, GetPopupCounts());
445
446   // id0 promoted to LOW->DEFAULT, it'll appear as toast (popup).
447   message_center::RichNotificationData priority;
448   priority.priority = DEFAULT_PRIORITY;
449   scoped_ptr<Notification> notification(
450       new Notification(message_center::NOTIFICATION_TYPE_SIMPLE,
451                        id0,
452                        UTF8ToUTF16("newtitle"),
453                        UTF8ToUTF16("newbody"),
454                        gfx::Image(),
455                        UTF8ToUTF16(kDisplaySource),
456                        NotifierId(NotifierId::APPLICATION, kExtensionId),
457                        priority,
458                        NULL));
459   notification_list()->UpdateNotificationMessage(id0, notification.Pass());
460   EXPECT_EQ(1u, GetPopupCounts());
461   notification_list()->MarkSinglePopupAsShown(id0, true);
462   EXPECT_EQ(0u, GetPopupCounts());
463
464   // update with no promotion change for id0, it won't appear as a toast.
465   notification.reset(new Notification(message_center::NOTIFICATION_TYPE_SIMPLE,
466                                       id0,
467                                       UTF8ToUTF16("newtitle2"),
468                                       UTF8ToUTF16("newbody2"),
469                                       gfx::Image(),
470                                       UTF8ToUTF16(kDisplaySource),
471                                       NotifierId(NotifierId::APPLICATION,
472                                                  kExtensionId),
473                                       priority,
474                                       NULL));
475   notification_list()->UpdateNotificationMessage(id0, notification.Pass());
476   EXPECT_EQ(0u, GetPopupCounts());
477
478   // id1 promoted to DEFAULT->HIGH, it'll appear as toast (popup).
479   priority.priority = HIGH_PRIORITY;
480   notification.reset(new Notification(message_center::NOTIFICATION_TYPE_SIMPLE,
481                                       id1,
482                                       UTF8ToUTF16("newtitle"),
483                                       UTF8ToUTF16("newbody"),
484                                       gfx::Image(),
485                                       UTF8ToUTF16(kDisplaySource),
486                                       NotifierId(NotifierId::APPLICATION,
487                                                  kExtensionId),
488                                       priority,
489                                       NULL));
490   notification_list()->UpdateNotificationMessage(id1, notification.Pass());
491   EXPECT_EQ(1u, GetPopupCounts());
492   notification_list()->MarkSinglePopupAsShown(id1, true);
493   EXPECT_EQ(0u, GetPopupCounts());
494
495   // id1 promoted to HIGH->MAX, it'll appear as toast again.
496   priority.priority = MAX_PRIORITY;
497   notification.reset(new Notification(message_center::NOTIFICATION_TYPE_SIMPLE,
498                                       id1,
499                                       UTF8ToUTF16("newtitle2"),
500                                       UTF8ToUTF16("newbody2"),
501                                       gfx::Image(),
502                                       UTF8ToUTF16(kDisplaySource),
503                                       NotifierId(NotifierId::APPLICATION,
504                                                  kExtensionId),
505                                       priority,
506                                       NULL));
507   notification_list()->UpdateNotificationMessage(id1, notification.Pass());
508   EXPECT_EQ(1u, GetPopupCounts());
509   notification_list()->MarkSinglePopupAsShown(id1, true);
510   EXPECT_EQ(0u, GetPopupCounts());
511
512   // id1 demoted to MAX->DEFAULT, no appearing as toast.
513   priority.priority = DEFAULT_PRIORITY;
514   notification.reset(new Notification(message_center::NOTIFICATION_TYPE_SIMPLE,
515                                       id1,
516                                       UTF8ToUTF16("newtitle3"),
517                                       UTF8ToUTF16("newbody3"),
518                                       gfx::Image(),
519                                       UTF8ToUTF16(kDisplaySource),
520                                       NotifierId(NotifierId::APPLICATION,
521                                                  kExtensionId),
522                                       priority,
523                                       NULL));
524   notification_list()->UpdateNotificationMessage(id1, notification.Pass());
525   EXPECT_EQ(0u, GetPopupCounts());
526 }
527
528 TEST_F(NotificationListTest, NotificationOrderAndPriority) {
529   base::Time now = base::Time::Now();
530   message_center::RichNotificationData optional;
531   optional.timestamp = now;
532   optional.priority = 2;
533   std::string max_id = AddNotification(optional);
534
535   now += base::TimeDelta::FromSeconds(1);
536   optional.timestamp = now;
537   optional.priority = 1;
538   std::string high_id = AddNotification(optional);
539
540   now += base::TimeDelta::FromSeconds(1);
541   optional.timestamp = now;
542   optional.priority = 0;
543   std::string default_id = AddNotification(optional);
544
545   {
546     // Popups: latest comes first.
547     NotificationList::PopupNotifications popups = GetPopups();
548     EXPECT_EQ(3u, popups.size());
549     NotificationList::PopupNotifications::const_iterator iter = popups.begin();
550     EXPECT_EQ(default_id, (*iter)->id());
551     iter++;
552     EXPECT_EQ(high_id, (*iter)->id());
553     iter++;
554     EXPECT_EQ(max_id, (*iter)->id());
555   }
556   {
557     // Notifications: high priority comes ealier.
558     const NotificationList::Notifications& notifications =
559         notification_list()->GetNotifications();
560     EXPECT_EQ(3u, notifications.size());
561     NotificationList::Notifications::const_iterator iter =
562         notifications.begin();
563     EXPECT_EQ(max_id, (*iter)->id());
564     iter++;
565     EXPECT_EQ(high_id, (*iter)->id());
566     iter++;
567     EXPECT_EQ(default_id, (*iter)->id());
568   }
569 }
570
571 TEST_F(NotificationListTest, MarkSinglePopupAsShown) {
572   std::string id1 = AddNotification();
573   std::string id2 = AddNotification();
574   std::string id3 = AddNotification();
575   ASSERT_EQ(3u, notification_list()->NotificationCount());
576   ASSERT_EQ(std::min(static_cast<size_t>(3u), kMaxVisiblePopupNotifications),
577             GetPopupCounts());
578   notification_list()->MarkSinglePopupAsDisplayed(id1);
579   notification_list()->MarkSinglePopupAsDisplayed(id2);
580   notification_list()->MarkSinglePopupAsDisplayed(id3);
581
582   notification_list()->MarkSinglePopupAsShown(id2, true);
583   notification_list()->MarkSinglePopupAsShown(id3, false);
584   EXPECT_EQ(3u, notification_list()->NotificationCount());
585   EXPECT_EQ(1u, notification_list()->unread_count());
586   EXPECT_EQ(1u, GetPopupCounts());
587   NotificationList::PopupNotifications popups = GetPopups();
588   EXPECT_EQ(id1, (*popups.begin())->id());
589
590   // The notifications in the NotificationCenter are unaffected by popups shown.
591   NotificationList::Notifications notifications =
592       notification_list()->GetNotifications();
593   NotificationList::Notifications::const_iterator iter = notifications.begin();
594   EXPECT_EQ(id3, (*iter)->id());
595   iter++;
596   EXPECT_EQ(id2, (*iter)->id());
597   iter++;
598   EXPECT_EQ(id1, (*iter)->id());
599 }
600
601 TEST_F(NotificationListTest, UpdateAfterMarkedAsShown) {
602   std::string id1 = AddNotification();
603   std::string id2 = AddNotification();
604   notification_list()->MarkSinglePopupAsDisplayed(id1);
605   notification_list()->MarkSinglePopupAsDisplayed(id2);
606
607   EXPECT_EQ(2u, GetPopupCounts());
608
609   const Notification* n1 = GetNotification(id1);
610   EXPECT_FALSE(n1->shown_as_popup());
611   EXPECT_TRUE(n1->is_read());
612
613   notification_list()->MarkSinglePopupAsShown(id1, true);
614
615   n1 = GetNotification(id1);
616   EXPECT_TRUE(n1->shown_as_popup());
617   EXPECT_TRUE(n1->is_read());
618
619   const std::string replaced("test-replaced-id");
620   scoped_ptr<Notification> notification(
621       new Notification(message_center::NOTIFICATION_TYPE_SIMPLE,
622                        replaced,
623                        UTF8ToUTF16("newtitle"),
624                        UTF8ToUTF16("newbody"),
625                        gfx::Image(),
626                        UTF8ToUTF16(kDisplaySource),
627                        NotifierId(NotifierId::APPLICATION, kExtensionId),
628                        message_center::RichNotificationData(),
629                        NULL));
630   notification_list()->UpdateNotificationMessage(id1, notification.Pass());
631   n1 = GetNotification(id1);
632   EXPECT_TRUE(n1 == NULL);
633   const Notification* nr = GetNotification(replaced);
634   EXPECT_TRUE(nr->shown_as_popup());
635   EXPECT_TRUE(nr->is_read());
636 }
637
638 TEST_F(NotificationListTest, QuietMode) {
639   notification_list()->SetQuietMode(true);
640   AddNotification();
641   AddPriorityNotification(HIGH_PRIORITY);
642   AddPriorityNotification(MAX_PRIORITY);
643   EXPECT_EQ(3u, notification_list()->NotificationCount());
644   EXPECT_EQ(0u, GetPopupCounts());
645
646   notification_list()->SetQuietMode(false);
647   AddNotification();
648   EXPECT_EQ(4u, notification_list()->NotificationCount());
649   EXPECT_EQ(1u, GetPopupCounts());
650
651   // TODO(mukai): Add test of quiet mode with expiration.
652 }
653
654 // Verifies that unread_count doesn't become negative.
655 TEST_F(NotificationListTest, UnreadCountNoNegative) {
656   std::string id = AddNotification();
657   EXPECT_EQ(1u, notification_list()->unread_count());
658
659   notification_list()->MarkSinglePopupAsDisplayed(id);
660   EXPECT_EQ(0u, notification_list()->unread_count());
661   notification_list()->MarkSinglePopupAsShown(
662       id, false /* mark_notification_as_read */);
663   EXPECT_EQ(1u, notification_list()->unread_count());
664
665   // Updates the notification  and verifies unread_count doesn't change.
666   scoped_ptr<Notification> updated_notification(new Notification(
667       message_center::NOTIFICATION_TYPE_SIMPLE,
668       id,
669       UTF8ToUTF16("updated"),
670       UTF8ToUTF16("updated"),
671       gfx::Image(),
672       base::string16(),
673       NotifierId(),
674       RichNotificationData(),
675       NULL));
676   notification_list()->AddNotification(updated_notification.Pass());
677   EXPECT_EQ(1u, notification_list()->unread_count());
678 }
679
680 TEST_F(NotificationListTest, TestPushingShownNotification) {
681   // Create a notification and mark it as shown.
682   std::string id1;
683   scoped_ptr<Notification> notification(MakeNotification(&id1));
684   notification->set_shown_as_popup(true);
685
686   // Call PushNotification on this notification.
687   notification_list()->PushNotification(notification.Pass());
688
689   // Ensure it is still marked as shown.
690   EXPECT_TRUE(GetNotification(id1)->shown_as_popup());
691 }
692
693 TEST_F(NotificationListTest, TestHasNotificationOfType) {
694   std::string id = AddNotification();
695
696   EXPECT_TRUE(notification_list()->HasNotificationOfType(
697       id, message_center::NOTIFICATION_TYPE_SIMPLE));
698   EXPECT_FALSE(notification_list()->HasNotificationOfType(
699       id, message_center::NOTIFICATION_TYPE_PROGRESS));
700
701   scoped_ptr<Notification> updated_notification(new Notification(
702       message_center::NOTIFICATION_TYPE_PROGRESS,
703       id,
704       UTF8ToUTF16("updated"),
705       UTF8ToUTF16("updated"),
706       gfx::Image(),
707       base::string16(),
708       NotifierId(),
709       RichNotificationData(),
710       NULL));
711   notification_list()->AddNotification(updated_notification.Pass());
712
713   EXPECT_FALSE(notification_list()->HasNotificationOfType(
714       id, message_center::NOTIFICATION_TYPE_SIMPLE));
715   EXPECT_TRUE(notification_list()->HasNotificationOfType(
716       id, message_center::NOTIFICATION_TYPE_PROGRESS));
717 }
718
719 }  // namespace message_center