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"
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
{
25 class MessageCenterImplTest
: public testing::Test
,
26 public MessageCenterObserver
{
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
{
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_
; }
57 Notification
* CreateSimpleNotification(const std::string
& id
) {
58 return CreateNotificationWithNotifierId(
61 NOTIFICATION_TYPE_SIMPLE
);
64 Notification
* CreateSimpleNotificationWithNotifierId(
65 const std::string
& id
, const std::string
& notifier_id
) {
66 return CreateNotificationWithNotifierId(
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
,
88 gfx::Image() /* icon */,
89 base::string16() /* display_source */,
90 NotifierId(NotifierId::APPLICATION
, notifier_id
),
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
{
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_
;
126 bool notifications_enabled_
;
128 DISALLOW_COPY_AND_ASSIGN(ToggledNotificationBlocker
);
131 class PopupNotificationBlocker
: public ToggledNotificationBlocker
{
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
);
147 NotifierId allowed_notifier_
;
149 DISALLOW_COPY_AND_ASSIGN(PopupNotificationBlocker
);
152 class TotalNotificationBlocker
: public PopupNotificationBlocker
{
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
);
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
)
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
)
195 class MockPopupTimersController
: public PopupTimersController
{
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;
210 bool timer_finished() const { return timer_finished_
; }
211 const std::string
& last_id() const { return last_id_
; }
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
=
235 new MockPopupTimersController(message_center(), closure()));
236 popup_timers_controller
->StartTimer("test",
237 base::TimeDelta::FromMilliseconds(1));
239 EXPECT_TRUE(popup_timers_controller
->timer_finished());
242 TEST_F(MessageCenterImplTest
, PopupTimersControllerPauseTimer
) {
243 scoped_ptr
<MockPopupTimersController
> popup_timers_controller
=
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
=
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
=
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
=
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();
288 EXPECT_TRUE(popup_timers_controller
->timer_finished());
291 TEST_F(MessageCenterImplTest
, PopupTimersControllerStartMultipleTimers
) {
292 scoped_ptr
<MockPopupTimersController
> popup_timers_controller
=
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();
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
=
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");
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
=
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));
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
351 ToggledNotificationBlocker
blocker1(message_center());
352 ToggledNotificationBlocker
blocker2(message_center());
354 message_center()->AddNotification(scoped_ptr
<Notification
>(new Notification(
355 NOTIFICATION_TYPE_SIMPLE
,
357 UTF8ToUTF16("title"),
358 UTF8ToUTF16("message"),
359 gfx::Image() /* icon */,
360 base::string16() /* display_source */,
362 RichNotificationData(),
364 message_center()->AddNotification(scoped_ptr
<Notification
>(new Notification(
365 NOTIFICATION_TYPE_SIMPLE
,
367 UTF8ToUTF16("title"),
368 UTF8ToUTF16("message"),
369 gfx::Image() /* icon */,
370 base::string16() /* display_source */,
372 RichNotificationData(),
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
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
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
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
,
413 UTF8ToUTF16("title"),
414 UTF8ToUTF16("message"),
415 gfx::Image() /* icon */,
416 base::string16() /* display_source */,
418 RichNotificationData(),
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
,
428 UTF8ToUTF16("title"),
429 UTF8ToUTF16("message"),
430 gfx::Image() /* icon */,
431 base::string16() /* display_source */,
433 RichNotificationData(),
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
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
,
457 UTF8ToUTF16("title"),
458 UTF8ToUTF16("message"),
459 gfx::Image() /* icon */,
460 base::string16() /* display_source */,
462 RichNotificationData(),
464 message_center()->AddNotification(scoped_ptr
<Notification
>(new Notification(
465 NOTIFICATION_TYPE_SIMPLE
,
467 UTF8ToUTF16("title"),
468 UTF8ToUTF16("message"),
469 gfx::Image() /* icon */,
470 base::string16() /* display_source */,
472 RichNotificationData(),
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
,
486 UTF8ToUTF16("title"),
487 UTF8ToUTF16("message"),
488 gfx::Image() /* icon */,
489 base::string16() /* display_source */,
491 RichNotificationData(),
493 message_center()->AddNotification(scoped_ptr
<Notification
>(new Notification(
494 NOTIFICATION_TYPE_SIMPLE
,
496 UTF8ToUTF16("title"),
497 UTF8ToUTF16("message"),
498 gfx::Image() /* icon */,
499 base::string16() /* display_source */,
501 RichNotificationData(),
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
,
529 UTF8ToUTF16("title"),
530 UTF8ToUTF16("message"),
531 gfx::Image() /* icon */,
532 base::string16() /* display_source */,
534 RichNotificationData(),
536 message_center()->AddNotification(scoped_ptr
<Notification
>(new Notification(
537 NOTIFICATION_TYPE_SIMPLE
,
539 UTF8ToUTF16("title"),
540 UTF8ToUTF16("message"),
541 gfx::Image() /* icon */,
542 base::string16() /* display_source */,
544 RichNotificationData(),
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
,
558 UTF8ToUTF16("title"),
559 UTF8ToUTF16("message"),
560 gfx::Image() /* icon */,
561 base::string16() /* display_source */,
563 RichNotificationData(),
565 message_center()->AddNotification(scoped_ptr
<Notification
>(new Notification(
566 NOTIFICATION_TYPE_SIMPLE
,
568 UTF8ToUTF16("title"),
569 UTF8ToUTF16("message"),
570 gfx::Image() /* icon */,
571 base::string16() /* display_source */,
573 RichNotificationData(),
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
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
[5] = {"0", "1", "2", "3", "4p"};
639 NotifierId
notifier_id1(NotifierId::APPLICATION
, "app1");
641 scoped_ptr
<Notification
> notification
;
642 // Add some notifications
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
]));
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 notification
.reset(CreateSimpleNotification(ids
[4]));
667 message_center()->UpdateNotification(ids
[4], notification
.Pass());
669 notification
.reset(CreateNotification(ids
[4], NOTIFICATION_TYPE_PROGRESS
));
670 message_center()->UpdateNotification(ids
[4], notification
.Pass());
672 // This should update notification "3" to a new ID after we go TRANSIENT.
673 notification
.reset(CreateSimpleNotification("New id"));
674 message_center()->UpdateNotification(ids
[3], notification
.Pass());
676 // This should create a new "3", that doesn't overwrite the update to 3
678 notification
.reset(CreateSimpleNotification(ids
[3]));
679 message_center()->AddNotification(notification
.Pass());
681 // The NL should still be the same: ["0", "1", "2", "4p"]
682 EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids
[0]));
683 EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids
[1]));
684 EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids
[2]));
685 EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids
[3]));
686 EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids
[4]));
687 EXPECT_EQ(message_center()->GetVisibleNotifications().size(), 4u);
688 message_center()->SetVisibility(VISIBILITY_TRANSIENT
);
690 EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids
[0]));
691 EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids
[1]));
692 EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids
[2]));
693 EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids
[3]));
694 EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids
[4]));
695 EXPECT_TRUE(message_center()->FindVisibleNotificationById("New id"));
696 EXPECT_EQ(message_center()->GetVisibleNotifications().size(), 5u);
699 TEST_F(MessageCenterImplTest
, QueuedDirectUpdates
) {
700 std::string
id("id1");
701 std::string
id2("id2");
702 NotifierId
notifier_id1(NotifierId::APPLICATION
, "app1");
704 gfx::Size
original_size(0, 0);
705 // Open the message center to prevent adding notifications
706 message_center()->SetVisibility(VISIBILITY_MESSAGE_CENTER
);
708 // Create new notification to be added to the queue; images all have the same
710 scoped_ptr
<Notification
> notification(CreateSimpleNotification(id
));
712 // Double-check that sizes all match.
713 const std::vector
<ButtonInfo
>& original_buttons
= notification
->buttons();
714 ASSERT_EQ(2u, original_buttons
.size());
716 EXPECT_EQ(original_size
, notification
->icon().Size());
717 EXPECT_EQ(original_size
, notification
->image().Size());
718 EXPECT_EQ(original_size
, original_buttons
[0].icon
.Size());
719 EXPECT_EQ(original_size
, original_buttons
[1].icon
.Size());
721 message_center()->AddNotification(notification
.Pass());
723 // The notification should be in the queue.
724 EXPECT_FALSE(message_center()->FindVisibleNotificationById(id
));
726 // Now try setting the icon to a different size.
727 gfx::Size
new_size(16, 16);
728 EXPECT_NE(original_size
, new_size
);
730 gfx::Canvas
canvas(new_size
, 1.0f
, true);
731 canvas
.DrawColor(SK_ColorBLUE
);
732 gfx::Image
testImage(gfx::Image(gfx::ImageSkia(canvas
.ExtractImageRep())));
733 message_center()->SetNotificationIcon(id
, testImage
);
734 message_center()->SetNotificationImage(id
, testImage
);
735 message_center()->SetNotificationButtonIcon(id
, 0, testImage
);
736 message_center()->SetNotificationButtonIcon(id
, 1, testImage
);
738 // The notification should be in the queue.
739 EXPECT_FALSE(message_center()->FindVisibleNotificationById(id
));
741 // Close the message center; then the update should have propagated.
742 message_center()->SetVisibility(VISIBILITY_TRANSIENT
);
743 // The notification should no longer be in the queue.
744 EXPECT_TRUE(message_center()->FindVisibleNotificationById(id
));
746 Notification
* mc_notification
=
747 *(message_center()->GetVisibleNotifications().begin());
748 const std::vector
<ButtonInfo
>& buttons
= mc_notification
->buttons();
749 ASSERT_EQ(2u, buttons
.size());
751 EXPECT_EQ(new_size
, mc_notification
->icon().Size());
752 EXPECT_EQ(new_size
, mc_notification
->image().Size());
753 EXPECT_EQ(new_size
, buttons
[0].icon
.Size());
754 EXPECT_EQ(new_size
, buttons
[1].icon
.Size());
757 TEST_F(MessageCenterImplTest
, CachedUnreadCount
) {
758 message_center()->AddNotification(
759 scoped_ptr
<Notification
>(CreateSimpleNotification("id1")));
760 message_center()->AddNotification(
761 scoped_ptr
<Notification
>(CreateSimpleNotification("id2")));
762 message_center()->AddNotification(
763 scoped_ptr
<Notification
>(CreateSimpleNotification("id3")));
764 ASSERT_EQ(3u, message_center()->UnreadNotificationCount());
766 // Mark 'displayed' on all notifications by using for-loop. This shouldn't
767 // recreate |notifications| inside of the loop.
768 const NotificationList::Notifications
& notifications
=
769 message_center()->GetVisibleNotifications();
770 for (NotificationList::Notifications::const_iterator iter
=
771 notifications
.begin(); iter
!= notifications
.end(); ++iter
) {
772 message_center()->DisplayedNotification(
773 (*iter
)->id(), message_center::DISPLAY_SOURCE_MESSAGE_CENTER
);
775 EXPECT_EQ(0u, message_center()->UnreadNotificationCount());
777 // Imitate the timeout, which recovers the unread count. Again, this shouldn't
778 // recreate |notifications| inside of the loop.
779 for (NotificationList::Notifications::const_iterator iter
=
780 notifications
.begin(); iter
!= notifications
.end(); ++iter
) {
781 message_center()->MarkSinglePopupAsShown((*iter
)->id(), false);
783 EXPECT_EQ(3u, message_center()->UnreadNotificationCount());
785 // Opening the message center will reset the unread count.
786 message_center()->SetVisibility(VISIBILITY_MESSAGE_CENTER
);
787 EXPECT_EQ(0u, message_center()->UnreadNotificationCount());
790 TEST_F(MessageCenterImplTest
, DisableNotificationsByNotifier
) {
791 ASSERT_EQ(0u, message_center()->NotificationCount());
792 message_center()->AddNotification(
793 scoped_ptr
<Notification
>(
794 CreateSimpleNotificationWithNotifierId("id1-1", "app1")));
795 message_center()->AddNotification(
796 scoped_ptr
<Notification
>(
797 CreateSimpleNotificationWithNotifierId("id1-2", "app1")));
798 message_center()->AddNotification(
799 scoped_ptr
<Notification
>(
800 CreateSimpleNotificationWithNotifierId("id2-1", "app2")));
801 message_center()->AddNotification(
802 scoped_ptr
<Notification
>(
803 CreateSimpleNotificationWithNotifierId("id2-2", "app2")));
804 message_center()->AddNotification(
805 scoped_ptr
<Notification
>(
806 CreateSimpleNotificationWithNotifierId("id2-3", "app2")));
807 ASSERT_EQ(5u, message_center()->NotificationCount());
809 // Removing all of app1's notifications should only leave app2's.
810 message_center()->DisableNotificationsByNotifier(
811 NotifierId(NotifierId::APPLICATION
, "app1"));
812 ASSERT_EQ(3u, message_center()->NotificationCount());
814 // Now we remove the remaining notifications.
815 message_center()->DisableNotificationsByNotifier(
816 NotifierId(NotifierId::APPLICATION
, "app2"));
817 ASSERT_EQ(0u, message_center()->NotificationCount());
820 TEST_F(MessageCenterImplTest
, NotifierEnabledChanged
) {
821 ASSERT_EQ(0u, message_center()->NotificationCount());
822 message_center()->AddNotification(
823 scoped_ptr
<Notification
>(
824 CreateSimpleNotificationWithNotifierId("id1-1", "app1")));
825 message_center()->AddNotification(
826 scoped_ptr
<Notification
>(
827 CreateSimpleNotificationWithNotifierId("id1-2", "app1")));
828 message_center()->AddNotification(
829 scoped_ptr
<Notification
>(
830 CreateSimpleNotificationWithNotifierId("id1-3", "app1")));
831 message_center()->AddNotification(
832 scoped_ptr
<Notification
>(
833 CreateSimpleNotificationWithNotifierId("id2-1", "app2")));
834 message_center()->AddNotification(
835 scoped_ptr
<Notification
>(
836 CreateSimpleNotificationWithNotifierId("id2-2", "app2")));
837 message_center()->AddNotification(
838 scoped_ptr
<Notification
>(
839 CreateSimpleNotificationWithNotifierId("id2-3", "app2")));
840 message_center()->AddNotification(
841 scoped_ptr
<Notification
>(
842 CreateSimpleNotificationWithNotifierId("id2-4", "app2")));
843 message_center()->AddNotification(
844 scoped_ptr
<Notification
>(
845 CreateSimpleNotificationWithNotifierId("id2-5", "app2")));
846 ASSERT_EQ(8u, message_center()->NotificationCount());
848 // Enabling an extension should have no effect on the count.
849 notifier_settings_observer()->NotifierEnabledChanged(
850 NotifierId(NotifierId::APPLICATION
, "app1"), true);
851 ASSERT_EQ(8u, message_center()->NotificationCount());
853 // Removing all of app2's notifications should only leave app1's.
854 notifier_settings_observer()->NotifierEnabledChanged(
855 NotifierId(NotifierId::APPLICATION
, "app2"), false);
856 ASSERT_EQ(3u, message_center()->NotificationCount());
858 // Removal operations should be idempotent.
859 notifier_settings_observer()->NotifierEnabledChanged(
860 NotifierId(NotifierId::APPLICATION
, "app2"), false);
861 ASSERT_EQ(3u, message_center()->NotificationCount());
863 // Now we remove the remaining notifications.
864 notifier_settings_observer()->NotifierEnabledChanged(
865 NotifierId(NotifierId::APPLICATION
, "app1"), false);
866 ASSERT_EQ(0u, message_center()->NotificationCount());
869 } // namespace internal
870 } // namespace message_center