Fixes bug in html_viewer that could lead to dropping interface requests
[chromium-blink-merge.git] / ui / message_center / message_center_impl_unittest.cc
blobccf86338e8764d26be0d6675e1e1560db758872c
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/message_center/message_center_impl.h"
7 #include "base/bind.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/run_loop.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "ui/gfx/canvas.h"
13 #include "ui/gfx/geometry/size.h"
14 #include "ui/message_center/message_center.h"
15 #include "ui/message_center/message_center_types.h"
16 #include "ui/message_center/notification_blocker.h"
17 #include "ui/message_center/notification_types.h"
18 #include "ui/message_center/notifier_settings.h"
20 using base::UTF8ToUTF16;
22 namespace message_center {
23 namespace {
25 class MessageCenterImplTest : public testing::Test,
26 public MessageCenterObserver {
27 public:
28 MessageCenterImplTest() {}
30 void SetUp() override {
31 MessageCenter::Initialize();
32 message_center_ = MessageCenter::Get();
33 loop_.reset(new base::MessageLoop);
34 run_loop_.reset(new base::RunLoop());
35 closure_ = run_loop_->QuitClosure();
38 void TearDown() override {
39 run_loop_.reset();
40 loop_.reset();
41 message_center_ = NULL;
42 MessageCenter::Shutdown();
45 MessageCenter* message_center() const { return message_center_; }
46 NotifierSettingsObserver* notifier_settings_observer() const {
47 return static_cast<NotifierSettingsObserver*>(message_center_impl());
49 MessageCenterImpl* message_center_impl() const {
50 return reinterpret_cast<MessageCenterImpl*>(message_center_);
53 base::RunLoop* run_loop() const { return run_loop_.get(); }
54 base::Closure closure() const { return closure_; }
56 protected:
57 Notification* CreateSimpleNotification(const std::string& id) {
58 return CreateNotificationWithNotifierId(
59 id,
60 "app1",
61 NOTIFICATION_TYPE_SIMPLE);
64 Notification* CreateSimpleNotificationWithNotifierId(
65 const std::string& id, const std::string& notifier_id) {
66 return CreateNotificationWithNotifierId(
67 id,
68 notifier_id,
69 NOTIFICATION_TYPE_SIMPLE);
72 Notification* CreateNotification(const std::string& id,
73 message_center::NotificationType type) {
74 return CreateNotificationWithNotifierId(id, "app1", type);
77 Notification* CreateNotificationWithNotifierId(
78 const std::string& id,
79 const std::string& notifier_id,
80 message_center::NotificationType type) {
81 RichNotificationData optional_fields;
82 optional_fields.buttons.push_back(ButtonInfo(UTF8ToUTF16("foo")));
83 optional_fields.buttons.push_back(ButtonInfo(UTF8ToUTF16("foo")));
84 return new Notification(type,
85 id,
86 UTF8ToUTF16("title"),
87 UTF8ToUTF16(id),
88 gfx::Image() /* icon */,
89 base::string16() /* display_source */,
90 NotifierId(NotifierId::APPLICATION, notifier_id),
91 optional_fields,
92 NULL);
96 private:
97 MessageCenter* message_center_;
98 scoped_ptr<base::MessageLoop> loop_;
99 scoped_ptr<base::RunLoop> run_loop_;
100 base::Closure closure_;
102 DISALLOW_COPY_AND_ASSIGN(MessageCenterImplTest);
105 class ToggledNotificationBlocker : public NotificationBlocker {
106 public:
107 explicit ToggledNotificationBlocker(MessageCenter* message_center)
108 : NotificationBlocker(message_center),
109 notifications_enabled_(true) {}
110 ~ToggledNotificationBlocker() override {}
112 void SetNotificationsEnabled(bool enabled) {
113 if (notifications_enabled_ != enabled) {
114 notifications_enabled_ = enabled;
115 NotifyBlockingStateChanged();
119 // NotificationBlocker overrides:
120 bool ShouldShowNotificationAsPopup(
121 const message_center::NotifierId& notifier_id) const override {
122 return notifications_enabled_;
125 private:
126 bool notifications_enabled_;
128 DISALLOW_COPY_AND_ASSIGN(ToggledNotificationBlocker);
131 class PopupNotificationBlocker : public ToggledNotificationBlocker {
132 public:
133 PopupNotificationBlocker(MessageCenter* message_center,
134 const NotifierId& allowed_notifier)
135 : ToggledNotificationBlocker(message_center),
136 allowed_notifier_(allowed_notifier) {}
137 ~PopupNotificationBlocker() override {}
139 // NotificationBlocker overrides:
140 bool ShouldShowNotificationAsPopup(
141 const NotifierId& notifier_id) const override {
142 return (notifier_id == allowed_notifier_) ||
143 ToggledNotificationBlocker::ShouldShowNotificationAsPopup(notifier_id);
146 private:
147 NotifierId allowed_notifier_;
149 DISALLOW_COPY_AND_ASSIGN(PopupNotificationBlocker);
152 class TotalNotificationBlocker : public PopupNotificationBlocker {
153 public:
154 TotalNotificationBlocker(MessageCenter* message_center,
155 const NotifierId& allowed_notifier)
156 : PopupNotificationBlocker(message_center, allowed_notifier) {}
157 ~TotalNotificationBlocker() override {}
159 // NotificationBlocker overrides:
160 bool ShouldShowNotification(const NotifierId& notifier_id) const override {
161 return ShouldShowNotificationAsPopup(notifier_id);
164 private:
165 DISALLOW_COPY_AND_ASSIGN(TotalNotificationBlocker);
168 bool PopupNotificationsContain(
169 const NotificationList::PopupNotifications& popups,
170 const std::string& id) {
171 for (NotificationList::PopupNotifications::const_iterator iter =
172 popups.begin(); iter != popups.end(); ++iter) {
173 if ((*iter)->id() == id)
174 return true;
176 return false;
179 // Right now, MessageCenter::HasNotification() returns regardless of blockers.
180 bool NotificationsContain(
181 const NotificationList::Notifications& notifications,
182 const std::string& id) {
183 for (NotificationList::Notifications::const_iterator iter =
184 notifications.begin(); iter != notifications.end(); ++iter) {
185 if ((*iter)->id() == id)
186 return true;
188 return false;
191 } // namespace
193 namespace internal {
195 class MockPopupTimersController : public PopupTimersController {
196 public:
197 MockPopupTimersController(MessageCenter* message_center,
198 base::Closure quit_closure)
199 : PopupTimersController(message_center),
200 timer_finished_(false),
201 quit_closure_(quit_closure) {}
202 ~MockPopupTimersController() override {}
204 void TimerFinished(const std::string& id) override {
205 base::MessageLoop::current()->PostTask(FROM_HERE, quit_closure_);
206 timer_finished_ = true;
207 last_id_ = id;
210 bool timer_finished() const { return timer_finished_; }
211 const std::string& last_id() const { return last_id_; }
213 private:
214 bool timer_finished_;
215 std::string last_id_;
216 base::Closure quit_closure_;
219 TEST_F(MessageCenterImplTest, PopupTimersEmptyController) {
220 scoped_ptr<PopupTimersController> popup_timers_controller =
221 make_scoped_ptr(new PopupTimersController(message_center()));
223 // Test that all functions succed without any timers created.
224 popup_timers_controller->PauseAll();
225 popup_timers_controller->StartAll();
226 popup_timers_controller->CancelAll();
227 popup_timers_controller->TimerFinished("unknown");
228 popup_timers_controller->PauseTimer("unknown");
229 popup_timers_controller->CancelTimer("unknown");
232 TEST_F(MessageCenterImplTest, PopupTimersControllerStartTimer) {
233 scoped_ptr<MockPopupTimersController> popup_timers_controller =
234 make_scoped_ptr(
235 new MockPopupTimersController(message_center(), closure()));
236 popup_timers_controller->StartTimer("test",
237 base::TimeDelta::FromMilliseconds(1));
238 run_loop()->Run();
239 EXPECT_TRUE(popup_timers_controller->timer_finished());
242 TEST_F(MessageCenterImplTest, PopupTimersControllerPauseTimer) {
243 scoped_ptr<MockPopupTimersController> popup_timers_controller =
244 make_scoped_ptr(
245 new MockPopupTimersController(message_center(), closure()));
246 popup_timers_controller->StartTimer("test",
247 base::TimeDelta::FromMilliseconds(1));
248 popup_timers_controller->PauseTimer("test");
249 run_loop()->RunUntilIdle();
251 EXPECT_FALSE(popup_timers_controller->timer_finished());
254 TEST_F(MessageCenterImplTest, PopupTimersControllerCancelTimer) {
255 scoped_ptr<MockPopupTimersController> popup_timers_controller =
256 make_scoped_ptr(
257 new MockPopupTimersController(message_center(), closure()));
258 popup_timers_controller->StartTimer("test",
259 base::TimeDelta::FromMilliseconds(1));
260 popup_timers_controller->CancelTimer("test");
261 run_loop()->RunUntilIdle();
263 EXPECT_FALSE(popup_timers_controller->timer_finished());
266 TEST_F(MessageCenterImplTest, PopupTimersControllerPauseAllTimers) {
267 scoped_ptr<MockPopupTimersController> popup_timers_controller =
268 make_scoped_ptr(
269 new MockPopupTimersController(message_center(), closure()));
270 popup_timers_controller->StartTimer("test",
271 base::TimeDelta::FromMilliseconds(1));
272 popup_timers_controller->PauseAll();
273 run_loop()->RunUntilIdle();
275 EXPECT_FALSE(popup_timers_controller->timer_finished());
278 TEST_F(MessageCenterImplTest, PopupTimersControllerStartAllTimers) {
279 scoped_ptr<MockPopupTimersController> popup_timers_controller =
280 make_scoped_ptr(
281 new MockPopupTimersController(message_center(), closure()));
282 popup_timers_controller->StartTimer("test",
283 base::TimeDelta::FromMilliseconds(1));
284 popup_timers_controller->PauseAll();
285 popup_timers_controller->StartAll();
286 run_loop()->Run();
288 EXPECT_TRUE(popup_timers_controller->timer_finished());
291 TEST_F(MessageCenterImplTest, PopupTimersControllerStartMultipleTimers) {
292 scoped_ptr<MockPopupTimersController> popup_timers_controller =
293 make_scoped_ptr(
294 new MockPopupTimersController(message_center(), closure()));
295 popup_timers_controller->StartTimer("test",
296 base::TimeDelta::FromMilliseconds(5));
297 popup_timers_controller->StartTimer("test2",
298 base::TimeDelta::FromMilliseconds(1));
299 popup_timers_controller->StartTimer("test3",
300 base::TimeDelta::FromMilliseconds(3));
301 popup_timers_controller->PauseAll();
302 popup_timers_controller->StartAll();
303 run_loop()->Run();
305 EXPECT_EQ(popup_timers_controller->last_id(), "test2");
306 EXPECT_TRUE(popup_timers_controller->timer_finished());
309 TEST_F(MessageCenterImplTest, PopupTimersControllerStartMultipleTimersPause) {
310 scoped_ptr<MockPopupTimersController> popup_timers_controller =
311 make_scoped_ptr(
312 new MockPopupTimersController(message_center(), closure()));
313 popup_timers_controller->StartTimer("test",
314 base::TimeDelta::FromMilliseconds(5));
315 popup_timers_controller->StartTimer("test2",
316 base::TimeDelta::FromMilliseconds(1));
317 popup_timers_controller->StartTimer("test3",
318 base::TimeDelta::FromMilliseconds(3));
319 popup_timers_controller->PauseTimer("test2");
321 run_loop()->Run();
323 EXPECT_EQ(popup_timers_controller->last_id(), "test3");
324 EXPECT_TRUE(popup_timers_controller->timer_finished());
327 TEST_F(MessageCenterImplTest, PopupTimersControllerResetTimer) {
328 scoped_ptr<MockPopupTimersController> popup_timers_controller =
329 make_scoped_ptr(
330 new MockPopupTimersController(message_center(), closure()));
331 popup_timers_controller->StartTimer("test",
332 base::TimeDelta::FromMilliseconds(5));
333 popup_timers_controller->StartTimer("test2",
334 base::TimeDelta::FromMilliseconds(1));
335 popup_timers_controller->StartTimer("test3",
336 base::TimeDelta::FromMilliseconds(3));
337 popup_timers_controller->PauseTimer("test2");
338 popup_timers_controller->ResetTimer("test",
339 base::TimeDelta::FromMilliseconds(2));
341 run_loop()->Run();
343 EXPECT_EQ(popup_timers_controller->last_id(), "test");
344 EXPECT_TRUE(popup_timers_controller->timer_finished());
347 TEST_F(MessageCenterImplTest, NotificationBlocker) {
348 NotifierId notifier_id(NotifierId::APPLICATION, "app1");
349 // Multiple blockers to verify the case that one blocker blocks but another
350 // doesn't.
351 ToggledNotificationBlocker blocker1(message_center());
352 ToggledNotificationBlocker blocker2(message_center());
354 message_center()->AddNotification(scoped_ptr<Notification>(new Notification(
355 NOTIFICATION_TYPE_SIMPLE,
356 "id1",
357 UTF8ToUTF16("title"),
358 UTF8ToUTF16("message"),
359 gfx::Image() /* icon */,
360 base::string16() /* display_source */,
361 notifier_id,
362 RichNotificationData(),
363 NULL)));
364 message_center()->AddNotification(scoped_ptr<Notification>(new Notification(
365 NOTIFICATION_TYPE_SIMPLE,
366 "id2",
367 UTF8ToUTF16("title"),
368 UTF8ToUTF16("message"),
369 gfx::Image() /* icon */,
370 base::string16() /* display_source */,
371 notifier_id,
372 RichNotificationData(),
373 NULL)));
374 EXPECT_EQ(2u, message_center()->GetPopupNotifications().size());
375 EXPECT_EQ(2u, message_center()->GetVisibleNotifications().size());
377 // Block all notifications. All popups are gone and message center should be
378 // hidden.
379 blocker1.SetNotificationsEnabled(false);
380 EXPECT_TRUE(message_center()->GetPopupNotifications().empty());
381 EXPECT_EQ(2u, message_center()->GetVisibleNotifications().size());
383 // Updates |blocker2| state, which doesn't affect the global state.
384 blocker2.SetNotificationsEnabled(false);
385 EXPECT_TRUE(message_center()->GetPopupNotifications().empty());
386 EXPECT_EQ(2u, message_center()->GetVisibleNotifications().size());
388 blocker2.SetNotificationsEnabled(true);
389 EXPECT_TRUE(message_center()->GetPopupNotifications().empty());
390 EXPECT_EQ(2u, message_center()->GetVisibleNotifications().size());
392 // If |blocker2| blocks, then unblocking blocker1 doesn't change the global
393 // state.
394 blocker2.SetNotificationsEnabled(false);
395 blocker1.SetNotificationsEnabled(true);
396 EXPECT_TRUE(message_center()->GetPopupNotifications().empty());
397 EXPECT_EQ(2u, message_center()->GetVisibleNotifications().size());
399 // Unblock both blockers, which recovers the global state, but the popups
400 // aren't shown.
401 blocker2.SetNotificationsEnabled(true);
402 EXPECT_TRUE(message_center()->GetPopupNotifications().empty());
403 EXPECT_EQ(2u, message_center()->GetVisibleNotifications().size());
406 TEST_F(MessageCenterImplTest, NotificationsDuringBlocked) {
407 NotifierId notifier_id(NotifierId::APPLICATION, "app1");
408 ToggledNotificationBlocker blocker(message_center());
410 message_center()->AddNotification(scoped_ptr<Notification>(new Notification(
411 NOTIFICATION_TYPE_SIMPLE,
412 "id1",
413 UTF8ToUTF16("title"),
414 UTF8ToUTF16("message"),
415 gfx::Image() /* icon */,
416 base::string16() /* display_source */,
417 notifier_id,
418 RichNotificationData(),
419 NULL)));
420 EXPECT_EQ(1u, message_center()->GetPopupNotifications().size());
421 EXPECT_EQ(1u, message_center()->GetVisibleNotifications().size());
423 // Create a notification during blocked. Still no popups.
424 blocker.SetNotificationsEnabled(false);
425 message_center()->AddNotification(scoped_ptr<Notification>(new Notification(
426 NOTIFICATION_TYPE_SIMPLE,
427 "id2",
428 UTF8ToUTF16("title"),
429 UTF8ToUTF16("message"),
430 gfx::Image() /* icon */,
431 base::string16() /* display_source */,
432 notifier_id,
433 RichNotificationData(),
434 NULL)));
435 EXPECT_TRUE(message_center()->GetPopupNotifications().empty());
436 EXPECT_EQ(2u, message_center()->GetVisibleNotifications().size());
438 // Unblock notifications, the id1 should appear as a popup.
439 blocker.SetNotificationsEnabled(true);
440 NotificationList::PopupNotifications popups =
441 message_center()->GetPopupNotifications();
442 EXPECT_EQ(1u, popups.size());
443 EXPECT_TRUE(PopupNotificationsContain(popups, "id2"));
444 EXPECT_EQ(2u, message_center()->GetVisibleNotifications().size());
447 // Similar to other blocker cases but this test case allows |notifier_id2| even
448 // in blocked.
449 TEST_F(MessageCenterImplTest, NotificationBlockerAllowsPopups) {
450 NotifierId notifier_id1(NotifierId::APPLICATION, "app1");
451 NotifierId notifier_id2(NotifierId::APPLICATION, "app2");
452 PopupNotificationBlocker blocker(message_center(), notifier_id2);
454 message_center()->AddNotification(scoped_ptr<Notification>(new Notification(
455 NOTIFICATION_TYPE_SIMPLE,
456 "id1",
457 UTF8ToUTF16("title"),
458 UTF8ToUTF16("message"),
459 gfx::Image() /* icon */,
460 base::string16() /* display_source */,
461 notifier_id1,
462 RichNotificationData(),
463 NULL)));
464 message_center()->AddNotification(scoped_ptr<Notification>(new Notification(
465 NOTIFICATION_TYPE_SIMPLE,
466 "id2",
467 UTF8ToUTF16("title"),
468 UTF8ToUTF16("message"),
469 gfx::Image() /* icon */,
470 base::string16() /* display_source */,
471 notifier_id2,
472 RichNotificationData(),
473 NULL)));
475 // "id1" is closed but "id2" is still visible as a popup.
476 blocker.SetNotificationsEnabled(false);
477 NotificationList::PopupNotifications popups =
478 message_center()->GetPopupNotifications();
479 EXPECT_EQ(1u, popups.size());
480 EXPECT_TRUE(PopupNotificationsContain(popups, "id2"));
481 EXPECT_EQ(2u, message_center()->GetVisibleNotifications().size());
483 message_center()->AddNotification(scoped_ptr<Notification>(new Notification(
484 NOTIFICATION_TYPE_SIMPLE,
485 "id3",
486 UTF8ToUTF16("title"),
487 UTF8ToUTF16("message"),
488 gfx::Image() /* icon */,
489 base::string16() /* display_source */,
490 notifier_id1,
491 RichNotificationData(),
492 NULL)));
493 message_center()->AddNotification(scoped_ptr<Notification>(new Notification(
494 NOTIFICATION_TYPE_SIMPLE,
495 "id4",
496 UTF8ToUTF16("title"),
497 UTF8ToUTF16("message"),
498 gfx::Image() /* icon */,
499 base::string16() /* display_source */,
500 notifier_id2,
501 RichNotificationData(),
502 NULL)));
503 popups = message_center()->GetPopupNotifications();
504 EXPECT_EQ(2u, popups.size());
505 EXPECT_TRUE(PopupNotificationsContain(popups, "id2"));
506 EXPECT_TRUE(PopupNotificationsContain(popups, "id4"));
507 EXPECT_EQ(4u, message_center()->GetVisibleNotifications().size());
509 blocker.SetNotificationsEnabled(true);
510 popups = message_center()->GetPopupNotifications();
511 EXPECT_EQ(3u, popups.size());
512 EXPECT_TRUE(PopupNotificationsContain(popups, "id2"));
513 EXPECT_TRUE(PopupNotificationsContain(popups, "id3"));
514 EXPECT_TRUE(PopupNotificationsContain(popups, "id4"));
515 EXPECT_EQ(4u, message_center()->GetVisibleNotifications().size());
518 // TotalNotificationBlocker suppresses showing notifications even from the list.
519 // This would provide the feature to 'separated' message centers per-profile for
520 // ChromeOS multi-login.
521 TEST_F(MessageCenterImplTest, TotalNotificationBlocker) {
522 NotifierId notifier_id1(NotifierId::APPLICATION, "app1");
523 NotifierId notifier_id2(NotifierId::APPLICATION, "app2");
524 TotalNotificationBlocker blocker(message_center(), notifier_id2);
526 message_center()->AddNotification(scoped_ptr<Notification>(new Notification(
527 NOTIFICATION_TYPE_SIMPLE,
528 "id1",
529 UTF8ToUTF16("title"),
530 UTF8ToUTF16("message"),
531 gfx::Image() /* icon */,
532 base::string16() /* display_source */,
533 notifier_id1,
534 RichNotificationData(),
535 NULL)));
536 message_center()->AddNotification(scoped_ptr<Notification>(new Notification(
537 NOTIFICATION_TYPE_SIMPLE,
538 "id2",
539 UTF8ToUTF16("title"),
540 UTF8ToUTF16("message"),
541 gfx::Image() /* icon */,
542 base::string16() /* display_source */,
543 notifier_id2,
544 RichNotificationData(),
545 NULL)));
547 // "id1" becomes invisible while "id2" is still visible.
548 blocker.SetNotificationsEnabled(false);
549 EXPECT_EQ(1u, message_center()->NotificationCount());
550 NotificationList::Notifications notifications =
551 message_center()->GetVisibleNotifications();
552 EXPECT_FALSE(NotificationsContain(notifications, "id1"));
553 EXPECT_TRUE(NotificationsContain(notifications, "id2"));
555 message_center()->AddNotification(scoped_ptr<Notification>(new Notification(
556 NOTIFICATION_TYPE_SIMPLE,
557 "id3",
558 UTF8ToUTF16("title"),
559 UTF8ToUTF16("message"),
560 gfx::Image() /* icon */,
561 base::string16() /* display_source */,
562 notifier_id1,
563 RichNotificationData(),
564 NULL)));
565 message_center()->AddNotification(scoped_ptr<Notification>(new Notification(
566 NOTIFICATION_TYPE_SIMPLE,
567 "id4",
568 UTF8ToUTF16("title"),
569 UTF8ToUTF16("message"),
570 gfx::Image() /* icon */,
571 base::string16() /* display_source */,
572 notifier_id2,
573 RichNotificationData(),
574 NULL)));
575 EXPECT_EQ(2u, message_center()->NotificationCount());
576 notifications = message_center()->GetVisibleNotifications();
577 EXPECT_FALSE(NotificationsContain(notifications, "id1"));
578 EXPECT_TRUE(NotificationsContain(notifications, "id2"));
579 EXPECT_FALSE(NotificationsContain(notifications, "id3"));
580 EXPECT_TRUE(NotificationsContain(notifications, "id4"));
582 blocker.SetNotificationsEnabled(true);
583 EXPECT_EQ(4u, message_center()->NotificationCount());
584 notifications = message_center()->GetVisibleNotifications();
585 EXPECT_TRUE(NotificationsContain(notifications, "id1"));
586 EXPECT_TRUE(NotificationsContain(notifications, "id2"));
587 EXPECT_TRUE(NotificationsContain(notifications, "id3"));
588 EXPECT_TRUE(NotificationsContain(notifications, "id4"));
590 // RemoveAllVisibleNotifications should remove just visible notifications.
591 blocker.SetNotificationsEnabled(false);
592 message_center()->RemoveAllVisibleNotifications(false /* by_user */);
593 EXPECT_EQ(0u, message_center()->NotificationCount());
594 blocker.SetNotificationsEnabled(true);
595 EXPECT_EQ(2u, message_center()->NotificationCount());
596 notifications = message_center()->GetVisibleNotifications();
597 EXPECT_TRUE(NotificationsContain(notifications, "id1"));
598 EXPECT_FALSE(NotificationsContain(notifications, "id2"));
599 EXPECT_TRUE(NotificationsContain(notifications, "id3"));
600 EXPECT_FALSE(NotificationsContain(notifications, "id4"));
602 // And RemoveAllNotifications should remove all.
603 blocker.SetNotificationsEnabled(false);
604 message_center()->RemoveAllNotifications(false /* by_user */);
605 EXPECT_EQ(0u, message_center()->NotificationCount());
608 TEST_F(MessageCenterImplTest, QueueUpdatesWithCenterVisible) {
609 std::string id("id1");
610 std::string id2("id2");
611 NotifierId notifier_id1(NotifierId::APPLICATION, "app1");
613 // First, add and update a notification to ensure updates happen
614 // normally.
615 scoped_ptr<Notification> notification(CreateSimpleNotification(id));
616 message_center()->AddNotification(notification.Pass());
617 notification.reset(CreateSimpleNotification(id2));
618 message_center()->UpdateNotification(id, notification.Pass());
619 EXPECT_TRUE(message_center()->FindVisibleNotificationById(id2));
620 EXPECT_FALSE(message_center()->FindVisibleNotificationById(id));
622 // Then open the message center.
623 message_center()->SetVisibility(VISIBILITY_MESSAGE_CENTER);
625 // Then update a notification; nothing should have happened.
626 notification.reset(CreateSimpleNotification(id));
627 message_center()->UpdateNotification(id2, notification.Pass());
628 EXPECT_TRUE(message_center()->FindVisibleNotificationById(id2));
629 EXPECT_FALSE(message_center()->FindVisibleNotificationById(id));
631 // Close the message center; then the update should have propagated.
632 message_center()->SetVisibility(VISIBILITY_TRANSIENT);
633 EXPECT_FALSE(message_center()->FindVisibleNotificationById(id2));
634 EXPECT_TRUE(message_center()->FindVisibleNotificationById(id));
637 TEST_F(MessageCenterImplTest, ComplexQueueing) {
638 std::string ids[6] = {"0", "1", "2", "3", "4p", "5"};
639 NotifierId notifier_id1(NotifierId::APPLICATION, "app1");
641 scoped_ptr<Notification> notification;
642 // Add some notifications
643 int i = 0;
644 for (; i < 3; i++) {
645 notification.reset(CreateSimpleNotification(ids[i]));
646 message_center()->AddNotification(notification.Pass());
648 for (i = 0; i < 3; i++) {
649 EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[i]));
651 for (; i < 6; i++) {
652 EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[i]));
655 notification.reset(CreateNotification(ids[4], NOTIFICATION_TYPE_PROGRESS));
656 message_center()->AddNotification(notification.Pass());
658 // Now start queueing.
659 // NL: ["0", "1", "2", "4p"]
660 message_center()->SetVisibility(VISIBILITY_MESSAGE_CENTER);
662 // This should update notification "1" to have id "3".
663 notification.reset(CreateSimpleNotification(ids[3]));
664 message_center()->UpdateNotification(ids[1], notification.Pass());
666 // Change the ID: "4p" -> "5", "5" -> "1", "1" -> "4p". They shouldn't
667 // override the previous change ("1" -> "3") nor the next one ("3" -> "5").
668 notification.reset(CreateSimpleNotification(ids[5]));
669 message_center()->UpdateNotification(ids[4], notification.Pass());
670 notification.reset(CreateSimpleNotification(ids[1]));
671 message_center()->UpdateNotification(ids[5], notification.Pass());
672 notification.reset(CreateNotification(ids[4], NOTIFICATION_TYPE_PROGRESS));
673 message_center()->UpdateNotification(ids[1], notification.Pass());
675 // This should update notification "3" to "5" after we go TRANSIENT.
676 notification.reset(CreateSimpleNotification(ids[5]));
677 message_center()->UpdateNotification(ids[3], notification.Pass());
679 // This should create a new "3", that doesn't overwrite the update to 3
680 // before.
681 notification.reset(CreateSimpleNotification(ids[3]));
682 message_center()->AddNotification(notification.Pass());
684 // The NL should still be the same: ["0", "1", "2", "4p"]
685 EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[0]));
686 EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[1]));
687 EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[2]));
688 EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[3]));
689 EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[4]));
690 EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[5]));
691 EXPECT_EQ(message_center()->GetVisibleNotifications().size(), 4u);
692 message_center()->SetVisibility(VISIBILITY_TRANSIENT);
694 EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[0]));
695 EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[1]));
696 EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[2]));
697 EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[3]));
698 EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[4]));
699 EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[5]));
700 EXPECT_EQ(message_center()->GetVisibleNotifications().size(), 5u);
703 TEST_F(MessageCenterImplTest, UpdateWhileQueueing) {
704 std::string ids[11] =
705 {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10p"};
706 NotifierId notifier_id1(NotifierId::APPLICATION, "app1");
708 scoped_ptr<Notification> notification;
709 // Add some notifications
710 int i = 0;
711 for (; i < 6; i++) {
712 notification.reset(CreateSimpleNotification(ids[i]));
713 notification->set_title(base::ASCIIToUTF16("ORIGINAL TITLE"));
714 message_center()->AddNotification(notification.Pass());
716 for (i = 0; i < 6; i++) {
717 EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[i]));
719 for (; i < 8; i++) {
720 EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[i]));
723 notification.reset(CreateNotification(ids[10], NOTIFICATION_TYPE_PROGRESS));
724 notification->set_progress(10);
725 message_center()->AddNotification(notification.Pass());
727 // Now start queueing.
728 message_center()->SetVisibility(VISIBILITY_MESSAGE_CENTER);
730 // Notification 0: (Exists) -> Removed
731 message_center()->RemoveNotification(ids[0], false);
733 // Notification 1: (Exists) -> Removed (by user)
734 message_center()->RemoveNotification(ids[1], true); // removed immediately
736 // Notification 2: (Exists) -> Removed -> Added
737 message_center()->RemoveNotification(ids[2], false);
738 notification.reset(CreateSimpleNotification(ids[2]));
739 notification->set_title(base::ASCIIToUTF16("NEW TITLE 2"));
740 message_center()->UpdateNotification(ids[2], notification.Pass());
742 // Notification 3: (Exists) -> Removed -> Updated
743 message_center()->RemoveNotification(ids[3], false);
744 notification.reset(CreateSimpleNotification(ids[3]));
745 notification->set_title(base::ASCIIToUTF16("NEW TITLE 3"));
746 message_center()->UpdateNotification(ids[3], notification.Pass());
748 // Notification 4: (Exists) -> Removed -> Added -> Removed
749 message_center()->RemoveNotification(ids[4], false);
750 notification.reset(CreateSimpleNotification(ids[4]));
751 message_center()->AddNotification(notification.Pass());
752 message_center()->RemoveNotification(ids[4], false);
754 // Notification 5: (Exists) -> Updated
755 notification.reset(CreateSimpleNotification(ids[5]));
756 notification->set_title(base::ASCIIToUTF16("NEW TITLE 5"));
757 message_center()->UpdateNotification(ids[5], notification.Pass());
759 // Notification 6: Updated
760 notification.reset(CreateSimpleNotification(ids[6]));
761 message_center()->UpdateNotification(ids[6], notification.Pass());
763 // Notification 7: Updated -> Removed
764 notification.reset(CreateSimpleNotification(ids[7]));
765 message_center()->UpdateNotification(ids[7], notification.Pass());
766 message_center()->RemoveNotification(ids[7], false);
768 // Notification 8: Added -> Updated
769 notification.reset(CreateSimpleNotification(ids[8]));
770 notification->set_title(base::ASCIIToUTF16("UPDATING 8-1"));
771 message_center()->AddNotification(notification.Pass());
772 notification.reset(CreateSimpleNotification(ids[8]));
773 notification->set_title(base::ASCIIToUTF16("NEW TITLE 8"));
774 message_center()->UpdateNotification(ids[8], notification.Pass());
776 // Notification 9: Added -> Updated -> Removed
777 notification.reset(CreateSimpleNotification(ids[9]));
778 message_center()->AddNotification(notification.Pass());
779 notification.reset(CreateSimpleNotification(ids[9]));
780 message_center()->UpdateNotification(ids[9], notification.Pass());
781 message_center()->RemoveNotification(ids[9], false);
783 // Notification 10 (TYPE_PROGRESS): Updated -> Removed -> Added -> Updated
784 // Step 1) Progress is updated immediately before removed.
785 notification.reset(CreateNotification(ids[10], NOTIFICATION_TYPE_PROGRESS));
786 notification->set_progress(20);
787 message_center()->UpdateNotification(ids[10], notification.Pass());
788 EXPECT_EQ(20,
789 message_center()->FindVisibleNotificationById(ids[10])->progress());
790 message_center()->RemoveNotification(ids[10], false);
791 // Step 2) Progress isn't updated after removed.
792 notification.reset(CreateSimpleNotification(ids[10]));
793 message_center()->AddNotification(notification.Pass());
794 EXPECT_EQ(20,
795 message_center()->FindVisibleNotificationById(ids[10])->progress());
796 notification.reset(CreateSimpleNotification(ids[10]));
797 notification->set_progress(40);
798 message_center()->UpdateNotification(ids[10], notification.Pass());
799 EXPECT_EQ(20,
800 message_center()->FindVisibleNotificationById(ids[10])->progress());
802 // All changes except the notification 1 and 10 are not refrected.
803 EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[0]));
804 EXPECT_EQ(base::ASCIIToUTF16("ORIGINAL TITLE"),
805 message_center()->FindVisibleNotificationById(ids[0])->title());
806 EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[1]));
807 EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[2]));
808 EXPECT_EQ(base::ASCIIToUTF16("ORIGINAL TITLE"),
809 message_center()->FindVisibleNotificationById(ids[2])->title());
810 EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[3]));
811 EXPECT_EQ(base::ASCIIToUTF16("ORIGINAL TITLE"),
812 message_center()->FindVisibleNotificationById(ids[3])->title());
813 EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[4]));
814 EXPECT_EQ(base::ASCIIToUTF16("ORIGINAL TITLE"),
815 message_center()->FindVisibleNotificationById(ids[4])->title());
816 EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[5]));
817 EXPECT_EQ(base::ASCIIToUTF16("ORIGINAL TITLE"),
818 message_center()->FindVisibleNotificationById(ids[5])->title());
819 EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[6]));
820 EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[7]));
821 EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[8]));
822 EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[9]));
823 EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[10]));
824 EXPECT_EQ(message_center()->GetVisibleNotifications().size(), 6u);
826 message_center()->SetVisibility(VISIBILITY_TRANSIENT);
828 EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[0]));
829 EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[1]));
830 EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[2]));
831 EXPECT_EQ(base::ASCIIToUTF16("NEW TITLE 2"),
832 message_center()->FindVisibleNotificationById(ids[2])->title());
833 EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[3]));
834 EXPECT_EQ(base::ASCIIToUTF16("NEW TITLE 3"),
835 message_center()->FindVisibleNotificationById(ids[3])->title());
836 EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[4]));
837 EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[5]));
838 EXPECT_EQ(base::ASCIIToUTF16("NEW TITLE 5"),
839 message_center()->FindVisibleNotificationById(ids[5])->title());
840 EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[6]));
841 EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[7]));
842 EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[8]));
843 EXPECT_EQ(base::ASCIIToUTF16("NEW TITLE 8"),
844 message_center()->FindVisibleNotificationById(ids[8])->title());
845 EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[9]));
846 EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[10]));
847 EXPECT_EQ(40,
848 message_center()->FindVisibleNotificationById(ids[10])->progress());
849 EXPECT_EQ(message_center()->GetVisibleNotifications().size(), 5u);
852 TEST_F(MessageCenterImplTest, QueuedDirectUpdates) {
853 std::string id("id1");
854 std::string id2("id2");
855 NotifierId notifier_id1(NotifierId::APPLICATION, "app1");
857 gfx::Size original_size(0, 0);
858 // Open the message center to prevent adding notifications
859 message_center()->SetVisibility(VISIBILITY_MESSAGE_CENTER);
861 // Create new notification to be added to the queue; images all have the same
862 // original size.
863 scoped_ptr<Notification> notification(CreateSimpleNotification(id));
865 // Double-check that sizes all match.
866 const std::vector<ButtonInfo>& original_buttons = notification->buttons();
867 ASSERT_EQ(2u, original_buttons.size());
869 EXPECT_EQ(original_size, notification->icon().Size());
870 EXPECT_EQ(original_size, notification->image().Size());
871 EXPECT_EQ(original_size, original_buttons[0].icon.Size());
872 EXPECT_EQ(original_size, original_buttons[1].icon.Size());
874 message_center()->AddNotification(notification.Pass());
876 // The notification should be in the queue.
877 EXPECT_FALSE(message_center()->FindVisibleNotificationById(id));
879 // Now try setting the icon to a different size.
880 gfx::Size new_size(16, 16);
881 EXPECT_NE(original_size, new_size);
883 gfx::Canvas canvas(new_size, 1.0f, true);
884 canvas.DrawColor(SK_ColorBLUE);
885 gfx::Image testImage(gfx::Image(gfx::ImageSkia(canvas.ExtractImageRep())));
886 message_center()->SetNotificationIcon(id, testImage);
887 message_center()->SetNotificationImage(id, testImage);
888 message_center()->SetNotificationButtonIcon(id, 0, testImage);
889 message_center()->SetNotificationButtonIcon(id, 1, testImage);
891 // The notification should be in the queue.
892 EXPECT_FALSE(message_center()->FindVisibleNotificationById(id));
894 // Close the message center; then the update should have propagated.
895 message_center()->SetVisibility(VISIBILITY_TRANSIENT);
896 // The notification should no longer be in the queue.
897 EXPECT_TRUE(message_center()->FindVisibleNotificationById(id));
899 Notification* mc_notification =
900 *(message_center()->GetVisibleNotifications().begin());
901 const std::vector<ButtonInfo>& buttons = mc_notification->buttons();
902 ASSERT_EQ(2u, buttons.size());
904 EXPECT_EQ(new_size, mc_notification->icon().Size());
905 EXPECT_EQ(new_size, mc_notification->image().Size());
906 EXPECT_EQ(new_size, buttons[0].icon.Size());
907 EXPECT_EQ(new_size, buttons[1].icon.Size());
910 TEST_F(MessageCenterImplTest, CachedUnreadCount) {
911 message_center()->AddNotification(
912 scoped_ptr<Notification>(CreateSimpleNotification("id1")));
913 message_center()->AddNotification(
914 scoped_ptr<Notification>(CreateSimpleNotification("id2")));
915 message_center()->AddNotification(
916 scoped_ptr<Notification>(CreateSimpleNotification("id3")));
917 ASSERT_EQ(3u, message_center()->UnreadNotificationCount());
919 // Mark 'displayed' on all notifications by using for-loop. This shouldn't
920 // recreate |notifications| inside of the loop.
921 const NotificationList::Notifications& notifications =
922 message_center()->GetVisibleNotifications();
923 for (NotificationList::Notifications::const_iterator iter =
924 notifications.begin(); iter != notifications.end(); ++iter) {
925 message_center()->DisplayedNotification(
926 (*iter)->id(), message_center::DISPLAY_SOURCE_MESSAGE_CENTER);
928 EXPECT_EQ(0u, message_center()->UnreadNotificationCount());
930 // Imitate the timeout, which recovers the unread count. Again, this shouldn't
931 // recreate |notifications| inside of the loop.
932 for (NotificationList::Notifications::const_iterator iter =
933 notifications.begin(); iter != notifications.end(); ++iter) {
934 message_center()->MarkSinglePopupAsShown((*iter)->id(), false);
936 EXPECT_EQ(3u, message_center()->UnreadNotificationCount());
938 // Opening the message center will reset the unread count.
939 message_center()->SetVisibility(VISIBILITY_MESSAGE_CENTER);
940 EXPECT_EQ(0u, message_center()->UnreadNotificationCount());
943 TEST_F(MessageCenterImplTest, DisableNotificationsByNotifier) {
944 ASSERT_EQ(0u, message_center()->NotificationCount());
945 message_center()->AddNotification(
946 scoped_ptr<Notification>(
947 CreateSimpleNotificationWithNotifierId("id1-1", "app1")));
948 message_center()->AddNotification(
949 scoped_ptr<Notification>(
950 CreateSimpleNotificationWithNotifierId("id1-2", "app1")));
951 message_center()->AddNotification(
952 scoped_ptr<Notification>(
953 CreateSimpleNotificationWithNotifierId("id2-1", "app2")));
954 message_center()->AddNotification(
955 scoped_ptr<Notification>(
956 CreateSimpleNotificationWithNotifierId("id2-2", "app2")));
957 message_center()->AddNotification(
958 scoped_ptr<Notification>(
959 CreateSimpleNotificationWithNotifierId("id2-3", "app2")));
960 ASSERT_EQ(5u, message_center()->NotificationCount());
962 // Removing all of app1's notifications should only leave app2's.
963 message_center()->DisableNotificationsByNotifier(
964 NotifierId(NotifierId::APPLICATION, "app1"));
965 ASSERT_EQ(3u, message_center()->NotificationCount());
967 // Now we remove the remaining notifications.
968 message_center()->DisableNotificationsByNotifier(
969 NotifierId(NotifierId::APPLICATION, "app2"));
970 ASSERT_EQ(0u, message_center()->NotificationCount());
973 TEST_F(MessageCenterImplTest, NotifierEnabledChanged) {
974 ASSERT_EQ(0u, message_center()->NotificationCount());
975 message_center()->AddNotification(
976 scoped_ptr<Notification>(
977 CreateSimpleNotificationWithNotifierId("id1-1", "app1")));
978 message_center()->AddNotification(
979 scoped_ptr<Notification>(
980 CreateSimpleNotificationWithNotifierId("id1-2", "app1")));
981 message_center()->AddNotification(
982 scoped_ptr<Notification>(
983 CreateSimpleNotificationWithNotifierId("id1-3", "app1")));
984 message_center()->AddNotification(
985 scoped_ptr<Notification>(
986 CreateSimpleNotificationWithNotifierId("id2-1", "app2")));
987 message_center()->AddNotification(
988 scoped_ptr<Notification>(
989 CreateSimpleNotificationWithNotifierId("id2-2", "app2")));
990 message_center()->AddNotification(
991 scoped_ptr<Notification>(
992 CreateSimpleNotificationWithNotifierId("id2-3", "app2")));
993 message_center()->AddNotification(
994 scoped_ptr<Notification>(
995 CreateSimpleNotificationWithNotifierId("id2-4", "app2")));
996 message_center()->AddNotification(
997 scoped_ptr<Notification>(
998 CreateSimpleNotificationWithNotifierId("id2-5", "app2")));
999 ASSERT_EQ(8u, message_center()->NotificationCount());
1001 // Enabling an extension should have no effect on the count.
1002 notifier_settings_observer()->NotifierEnabledChanged(
1003 NotifierId(NotifierId::APPLICATION, "app1"), true);
1004 ASSERT_EQ(8u, message_center()->NotificationCount());
1006 // Removing all of app2's notifications should only leave app1's.
1007 notifier_settings_observer()->NotifierEnabledChanged(
1008 NotifierId(NotifierId::APPLICATION, "app2"), false);
1009 ASSERT_EQ(3u, message_center()->NotificationCount());
1011 // Removal operations should be idempotent.
1012 notifier_settings_observer()->NotifierEnabledChanged(
1013 NotifierId(NotifierId::APPLICATION, "app2"), false);
1014 ASSERT_EQ(3u, message_center()->NotificationCount());
1016 // Now we remove the remaining notifications.
1017 notifier_settings_observer()->NotifierEnabledChanged(
1018 NotifierId(NotifierId::APPLICATION, "app1"), false);
1019 ASSERT_EQ(0u, message_center()->NotificationCount());
1022 } // namespace internal
1023 } // namespace message_center