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. 4 5#include "chrome/browser/ui/views/message_center/web_notification_tray.h" 6 7#include <set> 8 9#include "ash/root_window_controller.h" 10#include "ash/system/status_area_widget.h" 11#include "ash/system/tray/system_tray_item.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/notification.h" 16#include "chrome/browser/notifications/notification_delegate.h" 17#include "chrome/browser/notifications/notification_ui_manager.h" 18#include "chrome/browser/ui/browser.h" 19#include "chrome/test/base/in_process_browser_test.h" 20#include "content/public/test/test_utils.h" 21#include "ui/message_center/message_center_style.h" 22#include "ui/message_center/message_center_tray.h" 23#include "ui/message_center/notification_list.h" 24#include "ui/message_center/notification_types.h" 25#include "ui/message_center/views/message_center_bubble.h" 26#include "ui/message_center/views/message_popup_collection.h" 27#include "ui/views/controls/label.h" 28#include "ui/views/layout/fill_layout.h" 29#include "ui/views/view.h" 30#include "ui/views/widget/widget.h" 31 32namespace message_center { 33 34namespace { 35 36class WebNotificationTrayTest : public InProcessBrowserTest { 37 public: 38 WebNotificationTrayTest() {} 39 virtual ~WebNotificationTrayTest() {} 40 41 virtual void CleanUpOnMainThread() OVERRIDE { 42 message_center::MessageCenter::Get()->RemoveAllNotifications(false); 43 } 44 45 protected: 46 class TestNotificationDelegate : public ::NotificationDelegate { 47 public: 48 explicit TestNotificationDelegate(std::string id) : id_(id) {} 49 virtual void Display() OVERRIDE {} 50 virtual void Error() OVERRIDE {} 51 virtual void Close(bool by_user) OVERRIDE {} 52 virtual void Click() OVERRIDE {} 53 virtual std::string id() const OVERRIDE { return id_; } 54 virtual content::RenderViewHost* GetRenderViewHost() const OVERRIDE { 55 return NULL; 56 } 57 58 private: 59 virtual ~TestNotificationDelegate() {} 60 61 std::string id_; 62 }; 63 64 void AddNotification(const std::string& id, const std::string& replace_id) { 65 ::Notification notification(GURL("chrome-extension://abbccedd"), 66 GURL(), 67 ASCIIToUTF16("Test Web Notification"), 68 ASCIIToUTF16("Notification message body."), 69 blink::WebTextDirectionDefault, 70 base::string16(), 71 ASCIIToUTF16(replace_id), 72 new TestNotificationDelegate(id)); 73 74 g_browser_process->notification_ui_manager()->Add( 75 notification, browser()->profile()); 76 } 77 78 void UpdateNotification(const std::string& replace_id, 79 const std::string& new_id) { 80 ::Notification notification(GURL("chrome-extension://abbccedd"), 81 GURL(""), 82 ASCIIToUTF16("Updated Web Notification"), 83 ASCIIToUTF16("Updated message body."), 84 blink::WebTextDirectionDefault, 85 base::string16(), 86 ASCIIToUTF16(replace_id), 87 new TestNotificationDelegate(new_id)); 88 89 g_browser_process->notification_ui_manager()->Add( 90 notification, browser()->profile()); 91 } 92 93 void RemoveNotification(const std::string& id) { 94 g_browser_process->notification_ui_manager()->CancelById(id); 95 } 96 97 private: 98 DISALLOW_COPY_AND_ASSIGN(WebNotificationTrayTest); 99}; 100 101} // namespace 102 103 104#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA) 105// TODO(erg): linux_aura bringup: http://crbug.com/163931 106#define MAYBE_WebNotifications DISABLED_WebNotifications 107#else 108#define MAYBE_WebNotifications WebNotifications 109#endif 110 111// TODO(dewittj): More exhaustive testing. 112IN_PROC_BROWSER_TEST_F(WebNotificationTrayTest, MAYBE_WebNotifications) { 113 message_center::MessageCenter* message_center = 114 message_center::MessageCenter::Get(); 115 116 // Add a notification. 117 AddNotification("test_id1", "replace_id1"); 118 EXPECT_EQ(1u, message_center->NotificationCount()); 119 EXPECT_TRUE(message_center->HasNotification("test_id1")); 120 EXPECT_FALSE(message_center->HasNotification("test_id2")); 121 AddNotification("test_id2", "replace_id2"); 122 AddNotification("test_id2", "replace_id2"); 123 EXPECT_EQ(2u, message_center->NotificationCount()); 124 EXPECT_TRUE(message_center->HasNotification("test_id2")); 125 126 // Ensure that updating a notification does not affect the count. 127 UpdateNotification("replace_id2", "test_id3"); 128 UpdateNotification("replace_id2", "test_id3"); 129 EXPECT_EQ(2u, message_center->NotificationCount()); 130 EXPECT_FALSE(message_center->HasNotification("test_id2")); 131 132 // Ensure that Removing the first notification removes it from the tray. 133 RemoveNotification("test_id1"); 134 EXPECT_FALSE(message_center->HasNotification("test_id1")); 135 EXPECT_EQ(1u, message_center->NotificationCount()); 136 137 // Remove the remaining notification. 138 RemoveNotification("test_id3"); 139 EXPECT_EQ(0u, message_center->NotificationCount()); 140 EXPECT_FALSE(message_center->HasNotification("test_id3")); 141} 142 143IN_PROC_BROWSER_TEST_F(WebNotificationTrayTest, WebNotificationPopupBubble) { 144 scoped_ptr<WebNotificationTray> tray(new WebNotificationTray()); 145 tray->message_center(); 146 147 // Adding a notification should show the popup bubble. 148 AddNotification("test_id1", "replace_id1"); 149 EXPECT_TRUE(tray->message_center_tray_->popups_visible()); 150 151 // Updating a notification should not hide the popup bubble. 152 AddNotification("test_id2", "replace_id2"); 153 UpdateNotification("replace_id2", "test_id3"); 154 EXPECT_TRUE(tray->message_center_tray_->popups_visible()); 155 156 // Removing the first notification should not hide the popup bubble. 157 RemoveNotification("test_id1"); 158 EXPECT_TRUE(tray->message_center_tray_->popups_visible()); 159 160 // Removing the visible notification should hide the popup bubble. 161 RemoveNotification("test_id3"); 162 EXPECT_FALSE(tray->message_center_tray_->popups_visible()); 163} 164 165using message_center::NotificationList; 166 167// Flaky, see http://crbug.com/222500 . 168IN_PROC_BROWSER_TEST_F(WebNotificationTrayTest, 169 DISABLED_ManyMessageCenterNotifications) { 170 scoped_ptr<WebNotificationTray> tray(new WebNotificationTray()); 171 message_center::MessageCenter* message_center = tray->message_center(); 172 173 // Add the max visible notifications +1, ensure the correct visible number. 174 size_t notifications_to_add = kMaxVisibleMessageCenterNotifications + 1; 175 for (size_t i = 0; i < notifications_to_add; ++i) { 176 std::string id = base::StringPrintf("test_id%d", static_cast<int>(i)); 177 std::string replace_id = 178 base::StringPrintf("replace_id%d", static_cast<int>(i)); 179 AddNotification(id, replace_id); 180 } 181 bool shown = tray->message_center_tray_->ShowMessageCenterBubble(); 182 EXPECT_TRUE(shown); 183 content::RunAllPendingInMessageLoop(); 184 EXPECT_TRUE(tray->message_center_delegate_ != NULL); 185 EXPECT_EQ(notifications_to_add, message_center->NotificationCount()); 186 EXPECT_EQ(kMaxVisibleMessageCenterNotifications, 187 tray->message_center_delegate_->NumMessageViewsForTest()); 188} 189 190#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA) 191// TODO(erg): linux_aura bringup: http://crbug.com/163931 192#define MAYBE_ManyPopupNotifications DISABLED_ManyPopupNotifications 193#else 194#define MAYBE_ManyPopupNotifications ManyPopupNotifications 195#endif 196 197IN_PROC_BROWSER_TEST_F(WebNotificationTrayTest, MAYBE_ManyPopupNotifications) { 198 scoped_ptr<WebNotificationTray> tray(new WebNotificationTray()); 199 message_center::MessageCenter* message_center = tray->message_center(); 200 201 // Add the max visible popup notifications +1, ensure the correct num visible. 202 size_t notifications_to_add = kMaxVisiblePopupNotifications + 1; 203 for (size_t i = 0; i < notifications_to_add; ++i) { 204 std::string id = base::StringPrintf("test_id%d", static_cast<int>(i)); 205 std::string replace_id = 206 base::StringPrintf("replace_id%d", static_cast<int>(i)); 207 AddNotification(id, replace_id); 208 } 209 // Hide and reshow the bubble so that it is updated immediately, not delayed. 210 tray->message_center_tray_->HidePopupBubble(); 211 tray->message_center_tray_->ShowPopupBubble(); 212 EXPECT_TRUE(tray->message_center_tray_->popups_visible()); 213 EXPECT_EQ(notifications_to_add, message_center->NotificationCount()); 214 NotificationList::PopupNotifications popups = 215 message_center->GetPopupNotifications(); 216 EXPECT_EQ(kMaxVisiblePopupNotifications, popups.size()); 217} 218 219} // namespace message_center 220