1 // Copyright (c) 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.
8 #include "base/command_line.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/notifications/message_center_notification_manager.h"
16 #include "chrome/browser/notifications/notification.h"
17 #include "chrome/browser/notifications/notification_ui_manager.h"
18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/ui/browser.h"
20 #include "chrome/test/base/in_process_browser_test.h"
21 #include "chrome/test/base/test_switches.h"
22 #include "ui/message_center/message_center.h"
23 #include "ui/message_center/message_center_types.h"
25 class TestAddObserver
: public message_center::MessageCenterObserver
{
27 explicit TestAddObserver(message_center::MessageCenter
* message_center
)
28 : message_center_(message_center
) {
29 message_center_
->AddObserver(this);
32 ~TestAddObserver() override
{ message_center_
->RemoveObserver(this); }
34 void OnNotificationAdded(const std::string
& id
) override
{
35 std::string log
= logs_
[id
];
38 logs_
[id
] = log
+ "add-" + id
;
41 void OnNotificationUpdated(const std::string
& id
) override
{
42 std::string log
= logs_
[id
];
45 logs_
[id
] = log
+ "update-" + id
;
48 const std::string
log(const std::string
& id
) { return logs_
[id
]; }
49 void reset_logs() { logs_
.clear(); }
52 std::map
<std::string
, std::string
> logs_
;
53 message_center::MessageCenter
* message_center_
;
56 class MessageCenterNotificationsTest
: public InProcessBrowserTest
{
58 MessageCenterNotificationsTest() {}
60 MessageCenterNotificationManager
* manager() {
61 return static_cast<MessageCenterNotificationManager
*>(
62 g_browser_process
->notification_ui_manager());
65 message_center::MessageCenter
* message_center() {
66 return g_browser_process
->message_center();
69 Profile
* profile() { return browser()->profile(); }
71 class TestDelegate
: public NotificationDelegate
{
73 explicit TestDelegate(const std::string
& id
) : id_(id
) {}
75 void Display() override
{ log_
+= "Display_"; }
76 void Close(bool by_user
) override
{
78 log_
+= (by_user
? "by_user_" : "programmatically_");
80 void Click() override
{ log_
+= "Click_"; }
81 void ButtonClick(int button_index
) override
{
82 log_
+= "ButtonClick_";
83 log_
+= base::IntToString(button_index
) + "_";
85 std::string
id() const override
{ return id_
; }
87 const std::string
& log() { return log_
; }
90 ~TestDelegate() override
{}
94 DISALLOW_COPY_AND_ASSIGN(TestDelegate
);
97 Notification
CreateTestNotification(const std::string
& delegate_id
,
98 TestDelegate
** delegate
= NULL
) {
99 TestDelegate
* new_delegate
= new TestDelegate(delegate_id
);
101 *delegate
= new_delegate
;
102 new_delegate
->AddRef();
105 return Notification(GURL("chrome-test://testing/"),
106 base::ASCIIToUTF16("title"),
107 base::ASCIIToUTF16("message"),
109 base::UTF8ToUTF16("chrome-test://testing/"),
114 Notification
CreateRichTestNotification(const std::string
& id
,
115 TestDelegate
** delegate
= NULL
) {
116 TestDelegate
* new_delegate
= new TestDelegate(id
);
118 *delegate
= new_delegate
;
119 new_delegate
->AddRef();
122 message_center::RichNotificationData data
;
125 message_center::NOTIFICATION_TYPE_BASE_FORMAT
,
126 base::ASCIIToUTF16("title"), base::ASCIIToUTF16("message"),
128 message_center::NotifierId(message_center::NotifierId::APPLICATION
,
130 base::UTF8ToUTF16("chrome-test://testing/"),
131 GURL("chrome-test://testing/"), "REPLACE-ME", data
, new_delegate
);
135 // TODO(rsesek): Implement Message Center on Mac and get these tests passing
136 // for real. http://crbug.com/179904
137 #if !defined(OS_MACOSX)
139 IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTest
, RetrieveBaseParts
) {
140 EXPECT_TRUE(manager());
141 EXPECT_TRUE(message_center());
144 IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTest
, BasicAddCancel
) {
145 #if defined(OS_WIN) && defined(USE_ASH)
146 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
147 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
148 switches::kAshBrowserTests
))
152 // Someone may create system notifications like "you're in multi-profile
153 // mode..." or something which may change the expectation.
154 // TODO(mukai): move this to SetUpOnMainThread() after fixing the side-effect
155 // of canceling animation which prevents some Displayed() event.
156 manager()->CancelAll();
157 manager()->Add(CreateTestNotification("hey"), profile());
158 EXPECT_EQ(1u, message_center()->NotificationCount());
159 manager()->CancelById("hey", NotificationUIManager::GetProfileID(profile()));
160 EXPECT_EQ(0u, message_center()->NotificationCount());
163 IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTest
, BasicDelegate
) {
164 #if defined(OS_WIN) && defined(USE_ASH)
165 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
166 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
167 switches::kAshBrowserTests
))
171 TestDelegate
* delegate
;
172 manager()->Add(CreateTestNotification("hey", &delegate
), profile());
173 // Verify that delegate accumulated correct log of events.
174 EXPECT_EQ("Display_", delegate
->log());
175 manager()->CancelById("hey", NotificationUIManager::GetProfileID(profile()));
176 // Verify that delegate accumulated correct log of events.
177 EXPECT_EQ("Display_Close_programmatically_", delegate
->log());
181 IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTest
, ButtonClickedDelegate
) {
182 #if defined(OS_WIN) && defined(USE_ASH)
183 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
184 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
185 switches::kAshBrowserTests
))
189 TestDelegate
* delegate
;
190 manager()->Add(CreateTestNotification("n", &delegate
), profile());
191 const std::string notification_id
=
192 manager()->GetMessageCenterNotificationIdForTest("n", profile());
193 message_center()->ClickOnNotificationButton(notification_id
, 1);
194 // Verify that delegate accumulated correct log of events.
195 EXPECT_EQ("Display_ButtonClick_1_", delegate
->log());
199 IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTest
,
200 UpdateExistingNotification
) {
201 #if defined(OS_WIN) && defined(USE_ASH)
202 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
203 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
204 switches::kAshBrowserTests
))
208 TestDelegate
* delegate
;
209 manager()->Add(CreateTestNotification("n", &delegate
), profile());
210 TestDelegate
* delegate2
;
211 manager()->Add(CreateRichTestNotification("n", &delegate2
), profile());
213 manager()->CancelById("n", NotificationUIManager::GetProfileID(profile()));
214 EXPECT_EQ("Display_", delegate
->log());
215 EXPECT_EQ("Close_programmatically_", delegate2
->log());
218 delegate2
->Release();
221 IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTest
, QueueWhenCenterVisible
) {
222 #if defined(OS_WIN) && defined(USE_ASH)
223 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
224 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
225 switches::kAshBrowserTests
))
229 TestAddObserver
observer(message_center());
231 TestDelegate
* delegate
;
232 TestDelegate
* delegate2
;
234 manager()->Add(CreateTestNotification("n", &delegate
), profile());
235 const std::string id_n
=
236 manager()->GetMessageCenterNotificationIdForTest("n", profile());
237 message_center()->SetVisibility(message_center::VISIBILITY_MESSAGE_CENTER
);
238 manager()->Add(CreateTestNotification("n2", &delegate2
), profile());
239 const std::string id_n2
=
240 manager()->GetMessageCenterNotificationIdForTest("n2", profile());
242 // 'update-n' should happen since SetVisibility updates is_read status of n.
243 // TODO(mukai): fix event handling to happen update-n just once.
244 EXPECT_EQ(base::StringPrintf("add-%s_update-%s_update-%s",
250 message_center()->SetVisibility(message_center::VISIBILITY_TRANSIENT
);
252 EXPECT_EQ(base::StringPrintf("add-%s", id_n2
.c_str()), observer
.log(id_n2
));
255 delegate2
->Release();
258 IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTest
,
259 UpdateNonProgressNotificationWhenCenterVisible
) {
260 #if defined(OS_WIN) && defined(USE_ASH)
261 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
262 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
263 switches::kAshBrowserTests
))
267 TestAddObserver
observer(message_center());
269 TestDelegate
* delegate
;
271 // Add a non-progress notification and update it while the message center
273 Notification notification
= CreateTestNotification("n", &delegate
);
274 manager()->Add(notification
, profile());
275 const std::string notification_id
=
276 manager()->GetMessageCenterNotificationIdForTest("n", profile());
277 message_center()->ClickOnNotification(notification_id
);
278 message_center()->SetVisibility(message_center::VISIBILITY_MESSAGE_CENTER
);
279 observer
.reset_logs();
280 notification
.set_title(base::ASCIIToUTF16("title2"));
281 manager()->Update(notification
, profile());
283 // Expect that the notification update is not done.
284 EXPECT_EQ("", observer
.log(notification_id
));
286 message_center()->SetVisibility(message_center::VISIBILITY_TRANSIENT
);
287 EXPECT_EQ(base::StringPrintf("update-%s", notification_id
.c_str()),
288 observer
.log(notification_id
));
293 IN_PROC_BROWSER_TEST_F(
294 MessageCenterNotificationsTest
,
295 UpdateNonProgressToProgressNotificationWhenCenterVisible
) {
296 #if defined(OS_WIN) && defined(USE_ASH)
297 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
298 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
299 switches::kAshBrowserTests
))
303 TestAddObserver
observer(message_center());
305 TestDelegate
* delegate
;
307 // Add a non-progress notification and change the type to progress while the
308 // message center is visible.
309 Notification notification
= CreateTestNotification("n", &delegate
);
310 manager()->Add(notification
, profile());
311 const std::string notification_id
=
312 manager()->GetMessageCenterNotificationIdForTest("n", profile());
313 message_center()->ClickOnNotification(notification_id
);
314 message_center()->SetVisibility(message_center::VISIBILITY_MESSAGE_CENTER
);
315 observer
.reset_logs();
316 notification
.set_type(message_center::NOTIFICATION_TYPE_PROGRESS
);
317 manager()->Update(notification
, profile());
319 // Expect that the notification update is not done.
320 EXPECT_EQ("", observer
.log(notification_id
));
322 message_center()->SetVisibility(message_center::VISIBILITY_TRANSIENT
);
323 EXPECT_EQ(base::StringPrintf("update-%s", notification_id
.c_str()),
324 observer
.log(notification_id
));
329 IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTest
,
330 UpdateProgressNotificationWhenCenterVisible
) {
331 #if defined(OS_WIN) && defined(USE_ASH)
332 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
333 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
334 switches::kAshBrowserTests
))
338 TestAddObserver
observer(message_center());
340 TestDelegate
* delegate
;
342 // Add a progress notification and update it while the message center
344 Notification notification
= CreateTestNotification("n", &delegate
);
345 notification
.set_type(message_center::NOTIFICATION_TYPE_PROGRESS
);
346 manager()->Add(notification
, profile());
347 const std::string notification_id
=
348 manager()->GetMessageCenterNotificationIdForTest("n", profile());
349 message_center()->ClickOnNotification(notification_id
);
350 message_center()->SetVisibility(message_center::VISIBILITY_MESSAGE_CENTER
);
351 observer
.reset_logs();
352 notification
.set_progress(50);
353 manager()->Update(notification
, profile());
355 // Expect that the progress notification update is performed.
356 EXPECT_EQ(base::StringPrintf("update-%s", notification_id
.c_str()),
357 observer
.log(notification_id
));
362 #endif // !defined(OS_MACOSX)