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