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