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. 4 5#include <string> 6 7#include "base/command_line.h" 8#include "base/message_loop/message_loop.h" 9#include "base/strings/string_number_conversions.h" 10#include "base/strings/string_util.h" 11#include "base/strings/utf_string_conversions.h" 12#include "chrome/browser/browser_process.h" 13#include "chrome/browser/chrome_notification_types.h" 14#include "chrome/browser/notifications/message_center_notification_manager.h" 15#include "chrome/browser/notifications/notification.h" 16#include "chrome/browser/notifications/notification_ui_manager.h" 17#include "chrome/browser/profiles/profile.h" 18#include "chrome/browser/ui/browser.h" 19#include "chrome/test/base/in_process_browser_test.h" 20#include "chrome/test/base/test_switches.h" 21#include "content/public/browser/notification_details.h" 22#include "content/public/browser/notification_observer.h" 23#include "content/public/browser/notification_source.h" 24#include "ui/message_center/message_center.h" 25#include "ui/message_center/message_center_switches.h" 26#include "ui/message_center/message_center_types.h" 27#include "ui/message_center/message_center_util.h" 28 29class TestAddObserver : public message_center::MessageCenterObserver { 30 public: 31 explicit TestAddObserver(message_center::MessageCenter* message_center) 32 : message_center_(message_center) { 33 message_center_->AddObserver(this); 34 } 35 36 virtual ~TestAddObserver() { message_center_->RemoveObserver(this); } 37 38 virtual void OnNotificationAdded(const std::string& id) OVERRIDE { 39 if (log_ != "") 40 log_ += "_"; 41 log_ += "add-" + id; 42 } 43 44 virtual void OnNotificationUpdated(const std::string& id) OVERRIDE { 45 if (log_ != "") 46 log_ += "_"; 47 log_ += "update-" + id; 48 } 49 50 const std::string log() const { return log_; } 51 void reset_log() { log_ = ""; } 52 53 private: 54 std::string log_; 55 message_center::MessageCenter* message_center_; 56}; 57 58class MessageCenterNotificationsTest : public InProcessBrowserTest { 59 public: 60 MessageCenterNotificationsTest() {} 61 62 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 63 // This switch enables the new piping of Notifications through Message 64 // Center. 65 command_line->AppendSwitch( 66 message_center::switches::kEnableRichNotifications); 67 } 68 69 MessageCenterNotificationManager* manager() { 70 return static_cast<MessageCenterNotificationManager*>( 71 g_browser_process->notification_ui_manager()); 72 } 73 74 message_center::MessageCenter* message_center() { 75 return g_browser_process->message_center(); 76 } 77 78 Profile* profile() { return browser()->profile(); } 79 80 class TestDelegate : public NotificationDelegate { 81 public: 82 explicit TestDelegate(const std::string& id) : id_(id) {} 83 84 virtual void Display() OVERRIDE { log_ += "Display_"; } 85 virtual void Error() OVERRIDE { log_ += "Error_"; } 86 virtual void Close(bool by_user) OVERRIDE { 87 log_ += "Close_"; 88 log_ += ( by_user ? "by_user_" : "programmatically_"); 89 } 90 virtual void Click() OVERRIDE { log_ += "Click_"; } 91 virtual void ButtonClick(int button_index) OVERRIDE { 92 log_ += "ButtonClick_"; 93 log_ += base::IntToString(button_index) + "_"; 94 } 95 virtual std::string id() const OVERRIDE { return id_; } 96 virtual content::RenderViewHost* GetRenderViewHost() const OVERRIDE { 97 return NULL; 98 } 99 100 const std::string& log() { return log_; } 101 102 private: 103 virtual ~TestDelegate() {} 104 std::string id_; 105 std::string log_; 106 107 DISALLOW_COPY_AND_ASSIGN(TestDelegate); 108 }; 109 110 Notification CreateTestNotification(const std::string& id, 111 TestDelegate** delegate = NULL) { 112 TestDelegate* new_delegate = new TestDelegate(id); 113 if (delegate) { 114 *delegate = new_delegate; 115 new_delegate->AddRef(); 116 } 117 118 return Notification(GURL("chrome-test://testing/"), 119 GURL(), 120 ASCIIToUTF16("title"), 121 ASCIIToUTF16("message"), 122 blink::WebTextDirectionDefault, 123 UTF8ToUTF16("chrome-test://testing/"), 124 UTF8ToUTF16("REPLACE-ME"), 125 new_delegate); 126 } 127 128 Notification CreateRichTestNotification(const std::string& id, 129 TestDelegate** delegate = NULL) { 130 TestDelegate* new_delegate = new TestDelegate(id); 131 if (delegate) { 132 *delegate = new_delegate; 133 new_delegate->AddRef(); 134 } 135 136 message_center::RichNotificationData data; 137 138 return Notification(message_center::NOTIFICATION_TYPE_BASE_FORMAT, 139 GURL("chrome-test://testing/"), 140 ASCIIToUTF16("title"), 141 ASCIIToUTF16("message"), 142 gfx::Image(), 143 blink::WebTextDirectionDefault, 144 message_center::NotifierId( 145 message_center::NotifierId::APPLICATION, 146 "extension_id"), 147 UTF8ToUTF16("chrome-test://testing/"), 148 UTF8ToUTF16("REPLACE-ME"), 149 data, 150 new_delegate); 151 } 152}; 153 154// TODO(rsesek): Implement Message Center on Mac and get these tests passing 155// for real. http://crbug.com/179904 156#if !defined(OS_MACOSX) 157 158IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTest, RetrieveBaseParts) { 159 // Make sure comamnd-line switch has an effect. 160 EXPECT_EQ(NotificationUIManager::DelegatesToMessageCenter(), 161 message_center::IsRichNotificationEnabled()); 162 EXPECT_TRUE(manager()); 163 EXPECT_TRUE(message_center()); 164} 165 166// MessaceCenter-specific test. 167#if defined(RUN_MESSAGE_CENTER_TESTS) 168#define MAYBE_BasicAddCancel BasicAddCancel 169#else 170#define MAYBE_BasicAddCancel DISABLED_BasicAddCancel 171#endif 172 173IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTest, MAYBE_BasicAddCancel) { 174#if defined(OS_WIN) && defined(USE_ASH) 175 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 176 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 177 return; 178#endif 179 180 EXPECT_TRUE(NotificationUIManager::DelegatesToMessageCenter()); 181 manager()->Add(CreateTestNotification("hey"), profile()); 182 EXPECT_EQ(1u, message_center()->NotificationCount()); 183 manager()->CancelById("hey"); 184 EXPECT_EQ(0u, message_center()->NotificationCount()); 185} 186 187// MessaceCenter-specific test. 188#if defined(RUN_MESSAGE_CENTER_TESTS) 189#define MAYBE_BasicDelegate BasicDelegate 190#else 191#define MAYBE_BasicDelegate DISABLED_BasicDelegate 192#endif 193 194IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTest, MAYBE_BasicDelegate) { 195#if defined(OS_WIN) && defined(USE_ASH) 196 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 197 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 198 return; 199#endif 200 201 EXPECT_TRUE(NotificationUIManager::DelegatesToMessageCenter()); 202 TestDelegate* delegate; 203 manager()->Add(CreateTestNotification("hey", &delegate), profile()); 204 // Verify that delegate accumulated correct log of events. 205 EXPECT_EQ("Display_", delegate->log()); 206 manager()->CancelById("hey"); 207 // Verify that delegate accumulated correct log of events. 208 EXPECT_EQ("Display_Close_programmatically_", delegate->log()); 209 delegate->Release(); 210} 211 212// MessaceCenter-specific test. 213#if defined(RUN_MESSAGE_CENTER_TESTS) 214#define MAYBE_ButtonClickedDelegate ButtonClickedDelegate 215#else 216#define MAYBE_ButtonClickedDelegate DISABLED_ButtonClickedDelegate 217#endif 218 219IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTest, 220 MAYBE_ButtonClickedDelegate) { 221#if defined(OS_WIN) && defined(USE_ASH) 222 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 223 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 224 return; 225#endif 226 227 EXPECT_TRUE(NotificationUIManager::DelegatesToMessageCenter()); 228 TestDelegate* delegate; 229 manager()->Add(CreateTestNotification("n", &delegate), profile()); 230 message_center()->ClickOnNotificationButton("n", 1); 231 // Verify that delegate accumulated correct log of events. 232 EXPECT_EQ("Display_ButtonClick_1_", delegate->log()); 233 delegate->Release(); 234} 235 236// MessaceCenter-specific test. 237#if defined(RUN_MESSAGE_CENTER_TESTS) 238#define MAYBE_UpdateExistingNotification UpdateExistingNotification 239#else 240#define MAYBE_UpdateExistingNotification DISABLED_UpdateExistingNotification 241#endif 242 243IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTest, 244 MAYBE_UpdateExistingNotification) { 245#if defined(OS_WIN) && defined(USE_ASH) 246 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 247 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 248 return; 249#endif 250 251 EXPECT_TRUE(NotificationUIManager::DelegatesToMessageCenter()); 252 TestDelegate* delegate; 253 manager()->Add(CreateTestNotification("n", &delegate), profile()); 254 TestDelegate* delegate2; 255 manager()->Add(CreateRichTestNotification("n", &delegate2), profile()); 256 257 manager()->CancelById("n"); 258 EXPECT_EQ("Display_", delegate->log()); 259 EXPECT_EQ("Close_programmatically_", delegate2->log()); 260 261 delegate->Release(); 262 delegate2->Release(); 263} 264 265// MessaceCenter-specific test. 266#if defined(RUN_MESSAGE_CENTER_TESTS) 267#define MAYBE_QueueWhenCenterVisible QueueWhenCenterVisible 268#else 269#define MAYBE_QueueWhenCenterVisible DISABLED_QueueWhenCenterVisible 270#endif 271 272IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTest, 273 MAYBE_QueueWhenCenterVisible) { 274#if defined(OS_WIN) && defined(USE_ASH) 275 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 276 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 277 return; 278#endif 279 280 EXPECT_TRUE(NotificationUIManager::DelegatesToMessageCenter()); 281 TestAddObserver observer(message_center()); 282 283 TestDelegate* delegate; 284 TestDelegate* delegate2; 285 286 manager()->Add(CreateTestNotification("n", &delegate), profile()); 287 message_center()->SetVisibility(message_center::VISIBILITY_MESSAGE_CENTER); 288 manager()->Add(CreateTestNotification("n2", &delegate2), profile()); 289 290 // 'update-n' should happen since SetVisibility updates is_read status of n. 291 // TODO(mukai): fix event handling to happen update-n just once. 292 EXPECT_EQ("add-n_update-n_update-n", observer.log()); 293 294 message_center()->SetVisibility(message_center::VISIBILITY_TRANSIENT); 295 296 EXPECT_EQ("add-n_update-n_update-n_add-n2", observer.log()); 297 298 delegate->Release(); 299 delegate2->Release(); 300} 301 302// MessaceCenter-specific test. 303#if defined(RUN_MESSAGE_CENTER_TESTS) 304#define MAYBE_UpdateNonProgressNotificationWhenCenterVisible \ 305 UpdateNonProgressNotificationWhenCenterVisible 306#else 307#define MAYBE_UpdateNonProgressNotificationWhenCenterVisible \ 308 DISABLED_UpdateNonProgressNotificationWhenCenterVisible 309#endif 310 311IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTest, 312 MAYBE_UpdateNonProgressNotificationWhenCenterVisible) { 313#if defined(OS_WIN) && defined(USE_ASH) 314 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 315 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 316 return; 317#endif 318 319 EXPECT_TRUE(NotificationUIManager::DelegatesToMessageCenter()); 320 TestAddObserver observer(message_center()); 321 322 TestDelegate* delegate; 323 324 // Add a non-progress notification and update it while the message center 325 // is visible. 326 Notification notification = CreateTestNotification("n", &delegate); 327 manager()->Add(notification, profile()); 328 message_center()->ClickOnNotification("n"); 329 message_center()->SetVisibility(message_center::VISIBILITY_MESSAGE_CENTER); 330 observer.reset_log(); 331 notification.set_title(ASCIIToUTF16("title2")); 332 manager()->Update(notification, profile()); 333 334 // Expect that the notification update is not done. 335 EXPECT_EQ("", observer.log()); 336 337 message_center()->SetVisibility(message_center::VISIBILITY_TRANSIENT); 338 EXPECT_EQ("update-n", observer.log()); 339 340 delegate->Release(); 341} 342 343// MessaceCenter-specific test. 344#if defined(RUN_MESSAGE_CENTER_TESTS) 345#define MAYBE_UpdateNonProgressToProgressNotificationWhenCenterVisible \ 346 UpdateNonProgressToProgressNotificationWhenCenterVisible 347#else 348#define MAYBE_UpdateNonProgressToProgressNotificationWhenCenterVisible \ 349 DISABLED_UpdateNonProgressToProgressNotificationWhenCenterVisible 350#endif 351 352IN_PROC_BROWSER_TEST_F( 353 MessageCenterNotificationsTest, 354 MAYBE_UpdateNonProgressToProgressNotificationWhenCenterVisible) { 355#if defined(OS_WIN) && defined(USE_ASH) 356 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 357 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 358 return; 359#endif 360 361 EXPECT_TRUE(NotificationUIManager::DelegatesToMessageCenter()); 362 TestAddObserver observer(message_center()); 363 364 TestDelegate* delegate; 365 366 // Add a non-progress notification and change the type to progress while the 367 // message center is visible. 368 Notification notification = CreateTestNotification("n", &delegate); 369 manager()->Add(notification, profile()); 370 message_center()->ClickOnNotification("n"); 371 message_center()->SetVisibility(message_center::VISIBILITY_MESSAGE_CENTER); 372 observer.reset_log(); 373 notification.set_type(message_center::NOTIFICATION_TYPE_PROGRESS); 374 manager()->Update(notification, profile()); 375 376 // Expect that the notification update is not done. 377 EXPECT_EQ("", observer.log()); 378 379 message_center()->SetVisibility(message_center::VISIBILITY_TRANSIENT); 380 EXPECT_EQ("update-n", observer.log()); 381 382 delegate->Release(); 383} 384 385// MessaceCenter-specific test. 386#if defined(RUN_MESSAGE_CENTER_TESTS) 387#define MAYBE_UpdateProgressNotificationWhenCenterVisible \ 388 UpdateProgressNotificationWhenCenterVisible 389#else 390#define MAYBE_UpdateProgressNotificationWhenCenterVisible \ 391 DISABLED_UpdateProgressNotificationWhenCenterVisible 392#endif 393 394IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTest, 395 MAYBE_UpdateProgressNotificationWhenCenterVisible) { 396#if defined(OS_WIN) && defined(USE_ASH) 397 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 398 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 399 return; 400#endif 401 402 EXPECT_TRUE(NotificationUIManager::DelegatesToMessageCenter()); 403 TestAddObserver observer(message_center()); 404 405 TestDelegate* delegate; 406 407 // Add a progress notification and update it while the message center 408 // is visible. 409 Notification notification = CreateTestNotification("n", &delegate); 410 notification.set_type(message_center::NOTIFICATION_TYPE_PROGRESS); 411 manager()->Add(notification, profile()); 412 message_center()->ClickOnNotification("n"); 413 message_center()->SetVisibility(message_center::VISIBILITY_MESSAGE_CENTER); 414 observer.reset_log(); 415 notification.set_progress(50); 416 manager()->Update(notification, profile()); 417 418 // Expect that the progress notification update is performed. 419 EXPECT_EQ("update-n", observer.log()); 420 421 delegate->Release(); 422} 423 424#if !defined(OS_CHROMEOS) && defined(RUN_MESSAGE_CENTER_TESTS) 425#define MAYBE_HideWhenFullscreenEnabled HideWhenFullscreenEnabled 426#else 427#define MAYBE_HideWhenFullscreenEnabled DISABLED_HideWhenFullscreenEnabled 428#endif 429 430IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTest, 431 MAYBE_HideWhenFullscreenEnabled) { 432 EXPECT_TRUE(NotificationUIManager::DelegatesToMessageCenter()); 433 434 TestDelegate* delegate; 435 manager()->Add(CreateTestNotification("n", &delegate), profile()); 436 437 EXPECT_EQ("Display_", delegate->log()); 438 EXPECT_TRUE(message_center()->HasPopupNotifications()); 439 bool is_fullscreen = true; 440 // Cast so that Observe() is public. 441 content::NotificationObserver* observer = 442 static_cast<content::NotificationObserver*>(manager()); 443 observer->Observe(chrome::NOTIFICATION_FULLSCREEN_CHANGED, 444 content::Source<Profile>(profile()), 445 content::Details<bool>(&is_fullscreen)); 446 EXPECT_FALSE(message_center()->HasPopupNotifications()); 447} 448 449#endif // !defined(OS_MACOSX) 450