Home | History | Annotate | Download | only in notifications
      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 <map>
      6 #include <string>
      7 
      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/utf_string_conversions.h"
     13 #include "chrome/browser/browser_process.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 "ui/message_center/message_center.h"
     22 #include "ui/message_center/message_center_types.h"
     23 
     24 class TestAddObserver : public message_center::MessageCenterObserver {
     25  public:
     26   explicit TestAddObserver(message_center::MessageCenter* message_center)
     27       : message_center_(message_center) {
     28     message_center_->AddObserver(this);
     29   }
     30 
     31   virtual ~TestAddObserver() { message_center_->RemoveObserver(this); }
     32 
     33   virtual void OnNotificationAdded(const std::string& id) OVERRIDE {
     34     std::string log = logs_[id];
     35     if (log != "")
     36       log += "_";
     37     logs_[id] = log + "add-" + id;
     38   }
     39 
     40   virtual void OnNotificationUpdated(const std::string& id) OVERRIDE {
     41     std::string log = logs_[id];
     42     if (log != "")
     43       log += "_";
     44     logs_[id] = log + "update-" + id;
     45   }
     46 
     47   const std::string log(const std::string& id) { return logs_[id]; }
     48   void reset_logs() { logs_.clear(); }
     49 
     50  private:
     51   std::map<std::string, std::string> logs_;
     52   message_center::MessageCenter* message_center_;
     53 };
     54 
     55 class MessageCenterNotificationsTest : public InProcessBrowserTest {
     56  public:
     57   MessageCenterNotificationsTest() {}
     58 
     59   MessageCenterNotificationManager* manager() {
     60     return static_cast<MessageCenterNotificationManager*>(
     61         g_browser_process->notification_ui_manager());
     62   }
     63 
     64   message_center::MessageCenter* message_center() {
     65     return g_browser_process->message_center();
     66   }
     67 
     68   Profile* profile() { return browser()->profile(); }
     69 
     70   class TestDelegate : public NotificationDelegate {
     71    public:
     72     explicit TestDelegate(const std::string& id) : id_(id) {}
     73 
     74     virtual void Display() OVERRIDE { log_ += "Display_"; }
     75     virtual void Error() OVERRIDE { log_ += "Error_"; }
     76     virtual void Close(bool by_user) OVERRIDE {
     77       log_ += "Close_";
     78       log_ += ( by_user ? "by_user_" : "programmatically_");
     79     }
     80     virtual void Click() OVERRIDE { log_ += "Click_"; }
     81     virtual void ButtonClick(int button_index) OVERRIDE {
     82       log_ += "ButtonClick_";
     83       log_ += base::IntToString(button_index) + "_";
     84     }
     85     virtual std::string id() const OVERRIDE { return id_; }
     86     virtual content::WebContents* GetWebContents() const OVERRIDE {
     87       return NULL;
     88     }
     89 
     90     const std::string& log() { return log_; }
     91 
     92    private:
     93     virtual ~TestDelegate() {}
     94     std::string id_;
     95     std::string log_;
     96 
     97     DISALLOW_COPY_AND_ASSIGN(TestDelegate);
     98   };
     99 
    100   Notification CreateTestNotification(const std::string& id,
    101                                       TestDelegate** delegate = NULL) {
    102     TestDelegate* new_delegate = new TestDelegate(id);
    103     if (delegate) {
    104       *delegate = new_delegate;
    105       new_delegate->AddRef();
    106     }
    107 
    108     return Notification(GURL("chrome-test://testing/"),
    109                         GURL(),
    110                         base::ASCIIToUTF16("title"),
    111                         base::ASCIIToUTF16("message"),
    112                         blink::WebTextDirectionDefault,
    113                         base::UTF8ToUTF16("chrome-test://testing/"),
    114                         base::UTF8ToUTF16("REPLACE-ME"),
    115                         new_delegate);
    116   }
    117 
    118   Notification CreateRichTestNotification(const std::string& id,
    119                                           TestDelegate** delegate = NULL) {
    120     TestDelegate* new_delegate = new TestDelegate(id);
    121     if (delegate) {
    122       *delegate = new_delegate;
    123       new_delegate->AddRef();
    124     }
    125 
    126     message_center::RichNotificationData data;
    127 
    128     return Notification(message_center::NOTIFICATION_TYPE_BASE_FORMAT,
    129                         GURL("chrome-test://testing/"),
    130                         base::ASCIIToUTF16("title"),
    131                         base::ASCIIToUTF16("message"),
    132                         gfx::Image(),
    133                         blink::WebTextDirectionDefault,
    134                         message_center::NotifierId(
    135                             message_center::NotifierId::APPLICATION,
    136                             "extension_id"),
    137                         base::UTF8ToUTF16("chrome-test://testing/"),
    138                         base::UTF8ToUTF16("REPLACE-ME"),
    139                         data,
    140                         new_delegate);
    141   }
    142 };
    143 
    144 // TODO(rsesek): Implement Message Center on Mac and get these tests passing
    145 // for real. http://crbug.com/179904
    146 #if !defined(OS_MACOSX)
    147 
    148 IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTest, RetrieveBaseParts) {
    149   EXPECT_TRUE(manager());
    150   EXPECT_TRUE(message_center());
    151 }
    152 
    153 IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTest, BasicAddCancel) {
    154 #if defined(OS_WIN) && defined(USE_ASH)
    155   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
    156   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
    157     return;
    158 #endif
    159 
    160   // Someone may create system notifications like "you're in multi-profile
    161   // mode..." or something which may change the expectation.
    162   // TODO(mukai): move this to SetUpOnMainThread() after fixing the side-effect
    163   // of canceling animation which prevents some Displayed() event.
    164   manager()->CancelAll();
    165   manager()->Add(CreateTestNotification("hey"), profile());
    166   EXPECT_EQ(1u, message_center()->NotificationCount());
    167   manager()->CancelById("hey");
    168   EXPECT_EQ(0u, message_center()->NotificationCount());
    169 }
    170 
    171 IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTest, BasicDelegate) {
    172 #if defined(OS_WIN) && defined(USE_ASH)
    173   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
    174   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
    175     return;
    176 #endif
    177 
    178   TestDelegate* delegate;
    179   manager()->Add(CreateTestNotification("hey", &delegate), profile());
    180   // Verify that delegate accumulated correct log of events.
    181   EXPECT_EQ("Display_", delegate->log());
    182   manager()->CancelById("hey");
    183   // Verify that delegate accumulated correct log of events.
    184   EXPECT_EQ("Display_Close_programmatically_", delegate->log());
    185   delegate->Release();
    186 }
    187 
    188 IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTest, ButtonClickedDelegate) {
    189 #if defined(OS_WIN) && defined(USE_ASH)
    190   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
    191   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
    192     return;
    193 #endif
    194 
    195   TestDelegate* delegate;
    196   manager()->Add(CreateTestNotification("n", &delegate), profile());
    197   message_center()->ClickOnNotificationButton("n", 1);
    198   // Verify that delegate accumulated correct log of events.
    199   EXPECT_EQ("Display_ButtonClick_1_", delegate->log());
    200   delegate->Release();
    201 }
    202 
    203 IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTest,
    204                        UpdateExistingNotification) {
    205 #if defined(OS_WIN) && defined(USE_ASH)
    206   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
    207   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
    208     return;
    209 #endif
    210 
    211   TestDelegate* delegate;
    212   manager()->Add(CreateTestNotification("n", &delegate), profile());
    213   TestDelegate* delegate2;
    214   manager()->Add(CreateRichTestNotification("n", &delegate2), profile());
    215 
    216   manager()->CancelById("n");
    217   EXPECT_EQ("Display_", delegate->log());
    218   EXPECT_EQ("Close_programmatically_", delegate2->log());
    219 
    220   delegate->Release();
    221   delegate2->Release();
    222 }
    223 
    224 IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTest, QueueWhenCenterVisible) {
    225 #if defined(OS_WIN) && defined(USE_ASH)
    226   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
    227   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
    228     return;
    229 #endif
    230 
    231   TestAddObserver observer(message_center());
    232 
    233   TestDelegate* delegate;
    234   TestDelegate* delegate2;
    235 
    236   manager()->Add(CreateTestNotification("n", &delegate), profile());
    237   message_center()->SetVisibility(message_center::VISIBILITY_MESSAGE_CENTER);
    238   manager()->Add(CreateTestNotification("n2", &delegate2), profile());
    239 
    240   // 'update-n' should happen since SetVisibility updates is_read status of n.
    241   // TODO(mukai): fix event handling to happen update-n just once.
    242   EXPECT_EQ("add-n_update-n_update-n", observer.log("n"));
    243 
    244   message_center()->SetVisibility(message_center::VISIBILITY_TRANSIENT);
    245 
    246   EXPECT_EQ("add-n2", observer.log("n2"));
    247 
    248   delegate->Release();
    249   delegate2->Release();
    250 }
    251 
    252 IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTest,
    253                        UpdateNonProgressNotificationWhenCenterVisible) {
    254 #if defined(OS_WIN) && defined(USE_ASH)
    255   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
    256   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
    257     return;
    258 #endif
    259 
    260   TestAddObserver observer(message_center());
    261 
    262   TestDelegate* delegate;
    263 
    264   // Add a non-progress notification and update it while the message center
    265   // is visible.
    266   Notification notification = CreateTestNotification("n", &delegate);
    267   manager()->Add(notification, profile());
    268   message_center()->ClickOnNotification("n");
    269   message_center()->SetVisibility(message_center::VISIBILITY_MESSAGE_CENTER);
    270   observer.reset_logs();
    271   notification.set_title(base::ASCIIToUTF16("title2"));
    272   manager()->Update(notification, profile());
    273 
    274   // Expect that the notification update is not done.
    275   EXPECT_EQ("", observer.log("n"));
    276 
    277   message_center()->SetVisibility(message_center::VISIBILITY_TRANSIENT);
    278   EXPECT_EQ("update-n", observer.log("n"));
    279 
    280   delegate->Release();
    281 }
    282 
    283 IN_PROC_BROWSER_TEST_F(
    284     MessageCenterNotificationsTest,
    285     UpdateNonProgressToProgressNotificationWhenCenterVisible) {
    286 #if defined(OS_WIN) && defined(USE_ASH)
    287   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
    288   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
    289     return;
    290 #endif
    291 
    292   TestAddObserver observer(message_center());
    293 
    294   TestDelegate* delegate;
    295 
    296   // Add a non-progress notification and change the type to progress while the
    297   // message center is visible.
    298   Notification notification = CreateTestNotification("n", &delegate);
    299   manager()->Add(notification, profile());
    300   message_center()->ClickOnNotification("n");
    301   message_center()->SetVisibility(message_center::VISIBILITY_MESSAGE_CENTER);
    302   observer.reset_logs();
    303   notification.set_type(message_center::NOTIFICATION_TYPE_PROGRESS);
    304   manager()->Update(notification, profile());
    305 
    306   // Expect that the notification update is not done.
    307   EXPECT_EQ("", observer.log("n"));
    308 
    309   message_center()->SetVisibility(message_center::VISIBILITY_TRANSIENT);
    310   EXPECT_EQ("update-n", observer.log("n"));
    311 
    312   delegate->Release();
    313 }
    314 
    315 IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTest,
    316                        UpdateProgressNotificationWhenCenterVisible) {
    317 #if defined(OS_WIN) && defined(USE_ASH)
    318   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
    319   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
    320     return;
    321 #endif
    322 
    323   TestAddObserver observer(message_center());
    324 
    325   TestDelegate* delegate;
    326 
    327   // Add a progress notification and update it while the message center
    328   // is visible.
    329   Notification notification = CreateTestNotification("n", &delegate);
    330   notification.set_type(message_center::NOTIFICATION_TYPE_PROGRESS);
    331   manager()->Add(notification, profile());
    332   message_center()->ClickOnNotification("n");
    333   message_center()->SetVisibility(message_center::VISIBILITY_MESSAGE_CENTER);
    334   observer.reset_logs();
    335   notification.set_progress(50);
    336   manager()->Update(notification, profile());
    337 
    338   // Expect that the progress notification update is performed.
    339   EXPECT_EQ("update-n", observer.log("n"));
    340 
    341   delegate->Release();
    342 }
    343 
    344 #endif  // !defined(OS_MACOSX)
    345