• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/message_center_notification_manager.h"
16 #include "chrome/browser/notifications/notification.h"
17 #include "chrome/browser/notifications/notification_delegate.h"
18 #include "chrome/browser/notifications/notification_ui_manager.h"
19 #include "chrome/browser/ui/browser.h"
20 #include "chrome/test/base/in_process_browser_test.h"
21 #include "content/public/test/test_utils.h"
22 #include "ui/message_center/message_center_style.h"
23 #include "ui/message_center/message_center_tray.h"
24 #include "ui/message_center/notification_list.h"
25 #include "ui/message_center/notification_types.h"
26 #include "ui/message_center/views/message_center_bubble.h"
27 #include "ui/message_center/views/message_popup_collection.h"
28 #include "ui/views/controls/label.h"
29 #include "ui/views/layout/fill_layout.h"
30 #include "ui/views/view.h"
31 #include "ui/views/widget/widget.h"
32 
33 namespace message_center {
34 
35 namespace {
36 
37 class WebNotificationTrayTest : public InProcessBrowserTest {
38  public:
WebNotificationTrayTest()39   WebNotificationTrayTest() {}
~WebNotificationTrayTest()40   virtual ~WebNotificationTrayTest() {}
41 
CleanUpOnMainThread()42   virtual void CleanUpOnMainThread() OVERRIDE {
43     message_center::MessageCenter::Get()->RemoveAllNotifications(false);
44   }
45 
46  protected:
47   class TestNotificationDelegate : public ::NotificationDelegate {
48    public:
TestNotificationDelegate(std::string id)49     explicit TestNotificationDelegate(std::string id) : id_(id) {}
Display()50     virtual void Display() OVERRIDE {}
Error()51     virtual void Error() OVERRIDE {}
Close(bool by_user)52     virtual void Close(bool by_user) OVERRIDE {}
Click()53     virtual void Click() OVERRIDE {}
id() const54     virtual std::string id() const OVERRIDE { return id_; }
GetWebContents() const55     virtual content::WebContents* GetWebContents() const OVERRIDE {
56       return NULL;
57     }
58 
59    private:
~TestNotificationDelegate()60     virtual ~TestNotificationDelegate() {}
61 
62     std::string id_;
63   };
64 
AddNotification(const std::string & id,const std::string & replace_id)65   void AddNotification(const std::string& id, const std::string& replace_id) {
66     ::Notification notification(GURL("chrome-extension://abbccedd"),
67                                 GURL(),
68                                 base::ASCIIToUTF16("Test Web Notification"),
69                                 base::ASCIIToUTF16(
70                                     "Notification message body."),
71                                 blink::WebTextDirectionDefault,
72                                 base::string16(),
73                                 base::ASCIIToUTF16(replace_id),
74                                 new TestNotificationDelegate(id));
75 
76     g_browser_process->notification_ui_manager()->Add(
77      notification, browser()->profile());
78   }
79 
UpdateNotification(const std::string & replace_id,const std::string & new_id)80   void UpdateNotification(const std::string& replace_id,
81                           const std::string& new_id) {
82     ::Notification notification(GURL("chrome-extension://abbccedd"),
83                                 GURL(""),
84                                 base::ASCIIToUTF16("Updated Web Notification"),
85                                 base::ASCIIToUTF16("Updated message body."),
86                                 blink::WebTextDirectionDefault,
87                                 base::string16(),
88                                 base::ASCIIToUTF16(replace_id),
89                                 new TestNotificationDelegate(new_id));
90 
91     g_browser_process->notification_ui_manager()->Add(
92      notification, browser()->profile());
93   }
94 
RemoveNotification(const std::string & id)95   void RemoveNotification(const std::string& id) {
96     g_browser_process->notification_ui_manager()->CancelById(id);
97   }
98 
HasNotification(message_center::MessageCenter * message_center,const std::string & id)99   bool HasNotification(message_center::MessageCenter* message_center,
100                        const std::string& id) {
101     return message_center->FindVisibleNotificationById(id) != NULL;
102   }
103 
104  private:
105   DISALLOW_COPY_AND_ASSIGN(WebNotificationTrayTest);
106 };
107 
108 }  // namespace
109 
110 
111 // TODO(dewittj): More exhaustive testing.
IN_PROC_BROWSER_TEST_F(WebNotificationTrayTest,WebNotifications)112 IN_PROC_BROWSER_TEST_F(WebNotificationTrayTest, 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(HasNotification(message_center, "test_id1"));
120   EXPECT_FALSE(HasNotification(message_center, "test_id2"));
121   AddNotification("test_id2", "replace_id2");
122   AddNotification("test_id2", "replace_id2");
123   EXPECT_EQ(2u, message_center->NotificationCount());
124   EXPECT_TRUE(HasNotification(message_center, "test_id1"));
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(HasNotification(message_center, "test_id2"));
131 
132   // Ensure that Removing the first notification removes it from the tray.
133   RemoveNotification("test_id1");
134   EXPECT_FALSE(HasNotification(message_center, "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(HasNotification(message_center, "test_id1"));
141 }
142 
IN_PROC_BROWSER_TEST_F(WebNotificationTrayTest,WebNotificationPopupBubble)143 IN_PROC_BROWSER_TEST_F(WebNotificationTrayTest, WebNotificationPopupBubble) {
144   scoped_ptr<WebNotificationTray> tray(new WebNotificationTray(NULL));
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 
165 using message_center::NotificationList;
166 
167 // Flaky, see http://crbug.com/222500 .
IN_PROC_BROWSER_TEST_F(WebNotificationTrayTest,DISABLED_ManyMessageCenterNotifications)168 IN_PROC_BROWSER_TEST_F(WebNotificationTrayTest,
169                        DISABLED_ManyMessageCenterNotifications) {
170   scoped_ptr<WebNotificationTray> tray(new WebNotificationTray(NULL));
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 
IN_PROC_BROWSER_TEST_F(WebNotificationTrayTest,ManyPopupNotifications)190 IN_PROC_BROWSER_TEST_F(WebNotificationTrayTest, ManyPopupNotifications) {
191   scoped_ptr<WebNotificationTray> tray(new WebNotificationTray(NULL));
192   message_center::MessageCenter* message_center = tray->message_center();
193 
194   // Add the max visible popup notifications +1, ensure the correct num visible.
195   size_t notifications_to_add = kMaxVisiblePopupNotifications + 1;
196   for (size_t i = 0; i < notifications_to_add; ++i) {
197     std::string id = base::StringPrintf("test_id%d", static_cast<int>(i));
198     std::string replace_id =
199         base::StringPrintf("replace_id%d", static_cast<int>(i));
200     AddNotification(id, replace_id);
201   }
202   // Hide and reshow the bubble so that it is updated immediately, not delayed.
203   tray->message_center_tray_->HidePopupBubble();
204   tray->message_center_tray_->ShowPopupBubble();
205   EXPECT_TRUE(tray->message_center_tray_->popups_visible());
206   EXPECT_EQ(notifications_to_add, message_center->NotificationCount());
207   NotificationList::PopupNotifications popups =
208       message_center->GetPopupNotifications();
209   EXPECT_EQ(kMaxVisiblePopupNotifications, popups.size());
210 }
211 
IN_PROC_BROWSER_TEST_F(WebNotificationTrayTest,ManuallyCloseMessageCenter)212 IN_PROC_BROWSER_TEST_F(WebNotificationTrayTest,
213                        ManuallyCloseMessageCenter) {
214   NotificationUIManager* manager = g_browser_process->notification_ui_manager();
215   MessageCenterNotificationManager* mc_manager =
216       static_cast<MessageCenterNotificationManager*>(manager);
217 
218   WebNotificationTray* tray =
219       static_cast<WebNotificationTray*>(mc_manager->tray_.get());
220   ASSERT_TRUE(NULL != tray);
221 
222   message_center::MessageCenter* message_center = tray->message_center();
223 
224   bool shown = tray->message_center_tray_->ShowMessageCenterBubble();
225   EXPECT_TRUE(shown);
226   EXPECT_TRUE(message_center->IsMessageCenterVisible());
227 
228   mc_manager->EnsureMessageCenterClosed();
229 
230   EXPECT_FALSE(message_center->IsMessageCenterVisible());
231   if (NULL != tray->message_center_delegate_)
232     EXPECT_TRUE(tray->message_center_delegate_->GetWidget()->IsClosed());
233 }
234 
235 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
236 #define MAYBE_StatusIconBehavior DISABLED_StatusIconBehavior
237 #else
238 #define MAYBE_StatusIconBehavior StatusIconBehavior
239 #endif
IN_PROC_BROWSER_TEST_F(WebNotificationTrayTest,MAYBE_StatusIconBehavior)240 IN_PROC_BROWSER_TEST_F(WebNotificationTrayTest, MAYBE_StatusIconBehavior) {
241   scoped_ptr<WebNotificationTray> tray(new WebNotificationTray(NULL));
242 
243   EXPECT_TRUE(tray->status_icon_ == NULL);
244   tray->OnMessageCenterTrayChanged();
245   base::RunLoop().RunUntilIdle();
246   EXPECT_TRUE(tray->status_icon_ == NULL);
247   AddNotification("test_id", "replace_id");
248   base::RunLoop().RunUntilIdle();
249   EXPECT_TRUE(tray->status_icon_ != NULL);
250   RemoveNotification("test_id");
251   base::RunLoop().RunUntilIdle();
252   EXPECT_TRUE(tray->status_icon_ != NULL);
253 }
254 }  // namespace message_center
255