Home | History | Annotate | Download | only in message_center
      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:
     39   WebNotificationTrayTest() {}
     40   virtual ~WebNotificationTrayTest() {}
     41 
     42   virtual void TearDownOnMainThread() OVERRIDE {
     43     message_center::MessageCenter::Get()->RemoveAllNotifications(false);
     44   }
     45 
     46  protected:
     47   class TestNotificationDelegate : public ::NotificationDelegate {
     48    public:
     49     explicit TestNotificationDelegate(std::string id) : id_(id) {}
     50     virtual void Display() OVERRIDE {}
     51     virtual void Error() OVERRIDE {}
     52     virtual void Close(bool by_user) OVERRIDE {}
     53     virtual void Click() OVERRIDE {}
     54     virtual std::string id() const OVERRIDE { return id_; }
     55     virtual content::WebContents* GetWebContents() const OVERRIDE {
     56       return NULL;
     57     }
     58 
     59    private:
     60     virtual ~TestNotificationDelegate() {}
     61 
     62     std::string id_;
     63   };
     64 
     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 
     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 
     95   void RemoveNotification(const std::string& id) {
     96     g_browser_process->notification_ui_manager()->CancelById(id);
     97   }
     98 
     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.
    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 
    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 .
    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 
    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 
    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
    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