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