Home | History | Annotate | Download | only in notifications
      1 // Copyright (c) 2012 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 <deque>
      6 #include <string>
      7 
      8 #include "base/bind.h"
      9 #include "base/callback.h"
     10 #include "base/command_line.h"
     11 #include "base/compiler_specific.h"
     12 #include "base/memory/ref_counted.h"
     13 #include "base/run_loop.h"
     14 #include "base/strings/stringprintf.h"
     15 #include "base/strings/utf_string_conversions.h"
     16 #include "chrome/browser/browser_process.h"
     17 #include "chrome/browser/chrome_notification_types.h"
     18 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
     19 #include "chrome/browser/infobars/infobar.h"
     20 #include "chrome/browser/infobars/infobar_service.h"
     21 #include "chrome/browser/notifications/balloon.h"
     22 #include "chrome/browser/notifications/balloon_collection.h"
     23 #include "chrome/browser/notifications/balloon_host.h"
     24 #include "chrome/browser/notifications/balloon_notification_ui_manager.h"
     25 #include "chrome/browser/notifications/desktop_notification_service.h"
     26 #include "chrome/browser/notifications/desktop_notification_service_factory.h"
     27 #include "chrome/browser/notifications/notification.h"
     28 #include "chrome/browser/profiles/profile.h"
     29 #include "chrome/browser/ui/browser.h"
     30 #include "chrome/browser/ui/browser_tabstrip.h"
     31 #include "chrome/browser/ui/browser_window.h"
     32 #include "chrome/browser/ui/tabs/tab_strip_model.h"
     33 #include "chrome/common/content_settings.h"
     34 #include "chrome/common/content_settings_pattern.h"
     35 #include "chrome/test/base/in_process_browser_test.h"
     36 #include "chrome/test/base/ui_test_utils.h"
     37 #include "content/public/browser/notification_service.h"
     38 #include "content/public/browser/notification_source.h"
     39 #include "content/public/browser/notification_types.h"
     40 #include "content/public/browser/render_view_host.h"
     41 #include "content/public/browser/web_contents.h"
     42 #include "content/public/test/browser_test_utils.h"
     43 #include "content/public/test/test_utils.h"
     44 #include "net/base/net_util.h"
     45 #include "net/test/embedded_test_server/embedded_test_server.h"
     46 #include "testing/gtest/include/gtest/gtest.h"
     47 #include "ui/base/window_open_disposition.h"
     48 #include "ui/message_center/message_center.h"
     49 #include "ui/message_center/message_center_observer.h"
     50 #include "ui/message_center/message_center_switches.h"
     51 #include "ui/message_center/message_center_util.h"
     52 #include "url/gurl.h"
     53 
     54 namespace {
     55 
     56 const char kExpectedIconUrl[] = "/notifications/no_such_file.png";
     57 
     58 enum InfobarAction {
     59   DISMISS = 0,
     60   ALLOW,
     61   DENY,
     62 };
     63 
     64 class NotificationChangeObserver {
     65 public:
     66   virtual ~NotificationChangeObserver() {}
     67   virtual bool Wait() = 0;
     68 };
     69 
     70 class MessageCenterChangeObserver
     71     : public message_center::MessageCenterObserver,
     72       public NotificationChangeObserver {
     73  public:
     74   MessageCenterChangeObserver()
     75       : notification_received_(false) {
     76     message_center::MessageCenter::Get()->AddObserver(this);
     77   }
     78 
     79   virtual ~MessageCenterChangeObserver() {
     80     message_center::MessageCenter::Get()->RemoveObserver(this);
     81   }
     82 
     83   // NotificationChangeObserver:
     84   virtual bool Wait() OVERRIDE {
     85     if (notification_received_)
     86       return true;
     87 
     88     message_loop_runner_ = new content::MessageLoopRunner;
     89     message_loop_runner_->Run();
     90     return notification_received_;
     91   }
     92 
     93   // message_center::MessageCenterObserver:
     94   virtual void OnNotificationAdded(
     95       const std::string& notification_id) OVERRIDE {
     96     OnMessageCenterChanged();
     97   }
     98 
     99   virtual void OnNotificationRemoved(const std::string& notification_id,
    100                                      bool by_user) OVERRIDE {
    101     OnMessageCenterChanged();
    102   }
    103 
    104   virtual void OnNotificationUpdated(
    105       const std::string& notification_id) OVERRIDE {
    106     OnMessageCenterChanged();
    107   }
    108 
    109   void OnMessageCenterChanged() {
    110     notification_received_ = true;
    111     if (message_loop_runner_.get())
    112       message_loop_runner_->Quit();
    113   }
    114 
    115   bool notification_received_;
    116   scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
    117 
    118   DISALLOW_COPY_AND_ASSIGN(MessageCenterChangeObserver);
    119 };
    120 
    121 class NotificationBalloonChangeObserver
    122     : public content::NotificationObserver,
    123       public NotificationChangeObserver {
    124  public:
    125   NotificationBalloonChangeObserver()
    126       : collection_(BalloonNotificationUIManager::GetInstanceForTesting()->
    127             balloon_collection()),
    128         collection_changed_(false),
    129         notification_received_(false),
    130         running_(false),
    131         done_(false) {
    132     registrar_.Add(this, chrome::NOTIFICATION_NOTIFY_BALLOON_CONNECTED,
    133                    content::NotificationService::AllSources());
    134     registrar_.Add(this, chrome::NOTIFICATION_NOTIFY_BALLOON_DISCONNECTED,
    135                    content::NotificationService::AllSources());
    136     collection_->set_on_collection_changed_callback(
    137         base::Bind(&NotificationBalloonChangeObserver::OnCollectionChanged,
    138                    base::Unretained(this)));
    139   }
    140 
    141   virtual ~NotificationBalloonChangeObserver() {
    142     collection_->set_on_collection_changed_callback(base::Closure());
    143   }
    144 
    145   // NotificationChangeObserver:
    146   virtual bool Wait() OVERRIDE {
    147     if (!Check()) {
    148       running_ = true;
    149       message_loop_runner_ = new content::MessageLoopRunner;
    150       message_loop_runner_->Run();
    151       EXPECT_TRUE(done_);
    152     }
    153     return done_;
    154   }
    155 
    156   bool Check() {
    157     if (done_)
    158       return true;
    159 
    160     if (collection_changed_ && notification_received_) {
    161       done_ = true;
    162       if (running_) {
    163         message_loop_runner_->Quit();
    164         running_ = false;
    165       }
    166     }
    167     return done_;
    168   }
    169 
    170   void OnCollectionChanged() {
    171     collection_changed_ = true;
    172     Check();
    173   }
    174 
    175   // content::NotificationObserver:
    176   virtual void Observe(int type,
    177                        const content::NotificationSource& source,
    178                        const content::NotificationDetails& details) OVERRIDE {
    179     DCHECK(type == chrome::NOTIFICATION_NOTIFY_BALLOON_DISCONNECTED ||
    180            type == chrome::NOTIFICATION_NOTIFY_BALLOON_CONNECTED);
    181     notification_received_ = true;
    182     Check();
    183   }
    184 
    185  private:
    186   content::NotificationRegistrar registrar_;
    187   BalloonCollection* collection_;
    188 
    189   bool collection_changed_;
    190   bool notification_received_;
    191   bool running_;
    192   bool done_;
    193   scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
    194 
    195   DISALLOW_COPY_AND_ASSIGN(NotificationBalloonChangeObserver);
    196 };
    197 
    198 }  // namespace
    199 
    200 class NotificationsTest : public InProcessBrowserTest {
    201  public:
    202   NotificationsTest() {}
    203 
    204  protected:
    205   int GetNotificationCount();
    206 
    207   NotificationChangeObserver* CreateObserver();
    208 
    209   void CloseBrowserWindow(Browser* browser);
    210   void CrashTab(Browser* browser, int index);
    211   const std::deque<Balloon*>& GetActiveBalloons();
    212   void CrashNotification(Balloon* balloon);
    213   bool CloseNotificationAndWait(const Notification& notification);
    214 
    215   void SetDefaultPermissionSetting(ContentSetting setting);
    216   void DenyOrigin(const GURL& origin);
    217   void AllowOrigin(const GURL& origin);
    218   void AllowAllOrigins();
    219 
    220   void VerifyInfoBar(const Browser* browser, int index);
    221   std::string CreateNotification(Browser* browser,
    222                                  bool wait_for_new_balloon,
    223                                  const char* icon,
    224                                  const char* title,
    225                                  const char* body,
    226                                  const char* replace_id);
    227   std::string CreateSimpleNotification(Browser* browser,
    228                                        bool wait_for_new_balloon);
    229   bool RequestPermissionAndWait(Browser* browser);
    230   bool CancelNotification(const char* notification_id, Browser* browser);
    231   bool PerformActionOnInfoBar(Browser* browser,
    232                               InfobarAction action,
    233                               size_t infobar_index,
    234                               int tab_index);
    235   void GetPrefsByContentSetting(ContentSetting setting,
    236                                 ContentSettingsForOneType* settings);
    237   bool CheckOriginInSetting(const ContentSettingsForOneType& settings,
    238                             const GURL& origin);
    239 
    240   GURL GetTestPageURL() const {
    241     return embedded_test_server()->GetURL(
    242       "/notifications/notification_tester.html");
    243   }
    244 
    245  private:
    246   void DropOriginPreference(const GURL& origin);
    247   DesktopNotificationService* GetDesktopNotificationService();
    248 };
    249 
    250 int NotificationsTest::GetNotificationCount() {
    251   if (message_center::IsRichNotificationEnabled()) {
    252     return message_center::MessageCenter::Get()->NotificationCount();
    253   } else {
    254     return BalloonNotificationUIManager::GetInstanceForTesting()->
    255            balloon_collection()->GetActiveBalloons().size();
    256   }
    257 }
    258 
    259 NotificationChangeObserver* NotificationsTest::CreateObserver() {
    260   if (message_center::IsRichNotificationEnabled())
    261     return new MessageCenterChangeObserver();
    262   else
    263     return new NotificationBalloonChangeObserver();
    264 }
    265 
    266 void NotificationsTest::CloseBrowserWindow(Browser* browser) {
    267   content::WindowedNotificationObserver observer(
    268       chrome::NOTIFICATION_BROWSER_CLOSED,
    269       content::Source<Browser>(browser));
    270   browser->window()->Close();
    271   observer.Wait();
    272 }
    273 
    274 void NotificationsTest::CrashTab(Browser* browser, int index) {
    275   content::CrashTab(browser->tab_strip_model()->GetWebContentsAt(index));
    276 }
    277 
    278 const std::deque<Balloon*>& NotificationsTest::GetActiveBalloons() {
    279   return BalloonNotificationUIManager::GetInstanceForTesting()->
    280       balloon_collection()->GetActiveBalloons();
    281 }
    282 
    283 void NotificationsTest::CrashNotification(Balloon* balloon) {
    284   content::CrashTab(balloon->balloon_view()->GetHost()->web_contents());
    285 }
    286 
    287 bool NotificationsTest::CloseNotificationAndWait(
    288     const Notification& notification) {
    289   scoped_ptr<NotificationChangeObserver> observer(CreateObserver());
    290   bool success = g_browser_process->notification_ui_manager()->
    291       CancelById(notification.notification_id());
    292   if (success)
    293     return observer->Wait();
    294   return false;
    295 }
    296 
    297 void NotificationsTest::SetDefaultPermissionSetting(ContentSetting setting) {
    298   DesktopNotificationService* service = GetDesktopNotificationService();
    299   service->SetDefaultContentSetting(setting);
    300 }
    301 
    302 void NotificationsTest::DenyOrigin(const GURL& origin) {
    303   DropOriginPreference(origin);
    304   GetDesktopNotificationService()->DenyPermission(origin);
    305 }
    306 
    307 void NotificationsTest::AllowOrigin(const GURL& origin) {
    308   DropOriginPreference(origin);
    309   GetDesktopNotificationService()->GrantPermission(origin);
    310 }
    311 
    312 void NotificationsTest::AllowAllOrigins() {
    313   GetDesktopNotificationService()->ResetAllOrigins();
    314   GetDesktopNotificationService()->SetDefaultContentSetting(
    315       CONTENT_SETTING_ALLOW);
    316 }
    317 
    318 void NotificationsTest::VerifyInfoBar(const Browser* browser, int index) {
    319   InfoBarService* infobar_service = InfoBarService::FromWebContents(
    320       browser->tab_strip_model()->GetWebContentsAt(index));
    321 
    322   ASSERT_EQ(1U, infobar_service->infobar_count());
    323   ConfirmInfoBarDelegate* confirm_infobar =
    324       infobar_service->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate();
    325   ASSERT_TRUE(confirm_infobar);
    326   int buttons = confirm_infobar->GetButtons();
    327   EXPECT_TRUE(buttons & ConfirmInfoBarDelegate::BUTTON_OK);
    328   EXPECT_TRUE(buttons & ConfirmInfoBarDelegate::BUTTON_CANCEL);
    329 }
    330 
    331 std::string NotificationsTest::CreateNotification(
    332     Browser* browser,
    333     bool wait_for_new_balloon,
    334     const char* icon,
    335     const char* title,
    336     const char* body,
    337     const char* replace_id) {
    338   std::string script = base::StringPrintf(
    339       "createNotification('%s', '%s', '%s', '%s');",
    340       icon, title, body, replace_id);
    341 
    342   scoped_ptr<NotificationChangeObserver> observer(CreateObserver());
    343   std::string result;
    344   bool success = content::ExecuteScriptAndExtractString(
    345       browser->tab_strip_model()->GetActiveWebContents(),
    346       script,
    347       &result);
    348   if (success && result != "-1" && wait_for_new_balloon)
    349     success = observer->Wait();
    350   EXPECT_TRUE(success);
    351 
    352   return result;
    353 }
    354 
    355 std::string NotificationsTest::CreateSimpleNotification(
    356     Browser* browser,
    357     bool wait_for_new_balloon) {
    358   return CreateNotification(
    359       browser, wait_for_new_balloon,
    360       "no_such_file.png", "My Title", "My Body", "");
    361 }
    362 
    363 bool NotificationsTest::RequestPermissionAndWait(Browser* browser) {
    364   InfoBarService* infobar_service = InfoBarService::FromWebContents(
    365       browser->tab_strip_model()->GetActiveWebContents());
    366   content::WindowedNotificationObserver observer(
    367       chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED,
    368       content::Source<InfoBarService>(infobar_service));
    369   std::string result;
    370   bool success = content::ExecuteScriptAndExtractString(
    371       browser->tab_strip_model()->GetActiveWebContents(),
    372       "requestPermission();",
    373       &result);
    374   if (!success || result != "1")
    375     return false;
    376   observer.Wait();
    377   return true;
    378 }
    379 
    380 bool NotificationsTest::CancelNotification(
    381     const char* notification_id,
    382     Browser* browser) {
    383   std::string script = base::StringPrintf(
    384       "cancelNotification('%s');",
    385       notification_id);
    386 
    387   scoped_ptr<NotificationChangeObserver> observer(CreateObserver());
    388   std::string result;
    389   bool success = content::ExecuteScriptAndExtractString(
    390       browser->tab_strip_model()->GetActiveWebContents(),
    391       script,
    392       &result);
    393   if (!success || result != "1")
    394     return false;
    395   return observer->Wait();
    396 }
    397 
    398 bool NotificationsTest::PerformActionOnInfoBar(
    399     Browser* browser,
    400     InfobarAction action,
    401     size_t infobar_index,
    402     int tab_index) {
    403   InfoBarService* infobar_service = InfoBarService::FromWebContents(
    404       browser->tab_strip_model()->GetWebContentsAt(tab_index));
    405   if (infobar_index >= infobar_service->infobar_count()) {
    406     ADD_FAILURE();
    407     return false;
    408   }
    409 
    410   InfoBar* infobar = infobar_service->infobar_at(infobar_index);
    411   InfoBarDelegate* infobar_delegate = infobar->delegate();
    412   switch (action) {
    413     case DISMISS:
    414       infobar_delegate->InfoBarDismissed();
    415       infobar_service->RemoveInfoBar(infobar);
    416       return true;
    417 
    418     case ALLOW: {
    419       ConfirmInfoBarDelegate* confirm_infobar_delegate =
    420           infobar_delegate->AsConfirmInfoBarDelegate();
    421       if (!confirm_infobar_delegate) {
    422         ADD_FAILURE();
    423       } else if (confirm_infobar_delegate->Accept()) {
    424         infobar_service->RemoveInfoBar(infobar);
    425         return true;
    426       }
    427     }
    428 
    429     case DENY: {
    430       ConfirmInfoBarDelegate* confirm_infobar_delegate =
    431           infobar_delegate->AsConfirmInfoBarDelegate();
    432       if (!confirm_infobar_delegate) {
    433         ADD_FAILURE();
    434       } else if (confirm_infobar_delegate->Cancel()) {
    435         infobar_service->RemoveInfoBar(infobar);
    436         return true;
    437       }
    438     }
    439   }
    440 
    441   return false;
    442 }
    443 
    444 void NotificationsTest::GetPrefsByContentSetting(
    445     ContentSetting setting,
    446     ContentSettingsForOneType* settings) {
    447   DesktopNotificationService* service = GetDesktopNotificationService();
    448   service->GetNotificationsSettings(settings);
    449   for (ContentSettingsForOneType::iterator it = settings->begin();
    450        it != settings->end(); ) {
    451     if (it->setting != setting || it->source.compare("preference") != 0)
    452       it = settings->erase(it);
    453     else
    454       ++it;
    455   }
    456 }
    457 
    458 bool NotificationsTest::CheckOriginInSetting(
    459     const ContentSettingsForOneType& settings,
    460     const GURL& origin) {
    461   ContentSettingsPattern pattern =
    462       ContentSettingsPattern::FromURLNoWildcard(origin);
    463   for (ContentSettingsForOneType::const_iterator it = settings.begin();
    464        it != settings.end(); ++it) {
    465     if (it->primary_pattern == pattern)
    466       return true;
    467   }
    468   return false;
    469 }
    470 
    471 void NotificationsTest::DropOriginPreference(const GURL& origin) {
    472   GetDesktopNotificationService()->ClearSetting(
    473       ContentSettingsPattern::FromURLNoWildcard(origin));
    474 }
    475 
    476 DesktopNotificationService* NotificationsTest::GetDesktopNotificationService() {
    477   Profile* profile = browser()->profile();
    478   return DesktopNotificationServiceFactory::GetForProfile(profile);
    479 }
    480 
    481 // If this flakes, use http://crbug.com/62311 and http://crbug.com/74428.
    482 IN_PROC_BROWSER_TEST_F(NotificationsTest, TestUserGestureInfobar) {
    483   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    484 
    485   ui_test_utils::NavigateToURL(
    486       browser(),
    487       embedded_test_server()->GetURL(
    488           "/notifications/notifications_request_function.html"));
    489 
    490   // Request permission by calling request() while eval'ing an inline script;
    491   // That's considered a user gesture to webkit, and should produce an infobar.
    492   bool result;
    493   ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
    494       browser()->tab_strip_model()->GetActiveWebContents(),
    495       "window.domAutomationController.send(request());",
    496       &result));
    497   EXPECT_TRUE(result);
    498 
    499   EXPECT_EQ(1U, InfoBarService::FromWebContents(
    500       browser()->tab_strip_model()->GetWebContentsAt(0))->infobar_count());
    501 }
    502 
    503 // If this flakes, use http://crbug.com/62311.
    504 IN_PROC_BROWSER_TEST_F(NotificationsTest, TestNoUserGestureInfobar) {
    505   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    506 
    507   // Load a page which just does a request; no user gesture should result
    508   // in no infobar.
    509   ui_test_utils::NavigateToURL(
    510       browser(),
    511       embedded_test_server()->GetURL(
    512           "/notifications/notifications_request_inline.html"));
    513 
    514   EXPECT_EQ(0U, InfoBarService::FromWebContents(
    515       browser()->tab_strip_model()->GetWebContentsAt(0))->infobar_count());
    516 }
    517 
    518 IN_PROC_BROWSER_TEST_F(NotificationsTest, TestCreateSimpleNotification) {
    519   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    520 
    521   // Creates a simple notification.
    522   AllowAllOrigins();
    523   ui_test_utils::NavigateToURL(browser(), GetTestPageURL());
    524 
    525   std::string result = CreateSimpleNotification(browser(), true);
    526   EXPECT_NE("-1", result);
    527 
    528   GURL EXPECTED_ICON_URL = embedded_test_server()->GetURL(kExpectedIconUrl);
    529   ASSERT_EQ(1, GetNotificationCount());
    530   if (message_center::IsRichNotificationEnabled()) {
    531     message_center::NotificationList::Notifications notifications =
    532         message_center::MessageCenter::Get()->GetVisibleNotifications();
    533     EXPECT_EQ(ASCIIToUTF16("My Title"), (*notifications.rbegin())->title());
    534     EXPECT_EQ(ASCIIToUTF16("My Body"), (*notifications.rbegin())->message());
    535   } else {
    536     const std::deque<Balloon*>& balloons = GetActiveBalloons();
    537     ASSERT_EQ(1U, balloons.size());
    538     Balloon* balloon = balloons[0];
    539     const Notification& notification = balloon->notification();
    540     EXPECT_EQ(EXPECTED_ICON_URL, notification.icon_url());
    541     EXPECT_EQ(ASCIIToUTF16("My Title"), notification.title());
    542     EXPECT_EQ(ASCIIToUTF16("My Body"), notification.message());
    543   }
    544 }
    545 
    546 IN_PROC_BROWSER_TEST_F(NotificationsTest, TestCloseNotification) {
    547   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    548 
    549   // Creates a notification and closes it.
    550   AllowAllOrigins();
    551   ui_test_utils::NavigateToURL(browser(), GetTestPageURL());
    552 
    553   std::string result = CreateSimpleNotification(browser(), true);
    554   EXPECT_NE("-1", result);
    555   ASSERT_EQ(1, GetNotificationCount());
    556 
    557   if (message_center::IsRichNotificationEnabled()) {
    558     message_center::NotificationList::Notifications notifications =
    559         message_center::MessageCenter::Get()->GetVisibleNotifications();
    560     message_center::MessageCenter::Get()->RemoveNotification(
    561         (*notifications.rbegin())->id(),
    562         true);  // by_user
    563   } else {
    564     const std::deque<Balloon*>& balloons = GetActiveBalloons();
    565     EXPECT_TRUE(CloseNotificationAndWait(balloons[0]->notification()));
    566   }
    567 
    568   ASSERT_EQ(0, GetNotificationCount());
    569 }
    570 
    571 IN_PROC_BROWSER_TEST_F(NotificationsTest, TestCancelNotification) {
    572   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    573 
    574   // Creates a notification and cancels it in the origin page.
    575   AllowAllOrigins();
    576   ui_test_utils::NavigateToURL(browser(), GetTestPageURL());
    577 
    578   std::string note_id = CreateSimpleNotification(browser(), true);
    579   EXPECT_NE(note_id, "-1");
    580 
    581   ASSERT_EQ(1, GetNotificationCount());
    582   ASSERT_TRUE(CancelNotification(note_id.c_str(), browser()));
    583   ASSERT_EQ(0, GetNotificationCount());
    584 }
    585 
    586 IN_PROC_BROWSER_TEST_F(NotificationsTest, TestPermissionInfobarAppears) {
    587   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    588 
    589   // Requests notification privileges and verifies the infobar appears.
    590   ui_test_utils::NavigateToURL(browser(), GetTestPageURL());
    591   ASSERT_TRUE(RequestPermissionAndWait(browser()));
    592 
    593   ASSERT_EQ(0, GetNotificationCount());
    594   ASSERT_NO_FATAL_FAILURE(VerifyInfoBar(browser(), 0));
    595 }
    596 
    597 IN_PROC_BROWSER_TEST_F(NotificationsTest, TestAllowOnPermissionInfobar) {
    598   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    599 
    600   // Tries to create a notification and clicks allow on the infobar.
    601   ui_test_utils::NavigateToURL(browser(), GetTestPageURL());
    602   // This notification should not be shown because we do not have permission.
    603   CreateSimpleNotification(browser(), false);
    604   ASSERT_EQ(0, GetNotificationCount());
    605 
    606   ASSERT_TRUE(RequestPermissionAndWait(browser()));
    607   ASSERT_TRUE(PerformActionOnInfoBar(browser(), ALLOW, 0, 0));
    608 
    609   CreateSimpleNotification(browser(), true);
    610   EXPECT_EQ(1, GetNotificationCount());
    611 }
    612 
    613 IN_PROC_BROWSER_TEST_F(NotificationsTest, TestDenyOnPermissionInfobar) {
    614   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    615 
    616   // Test that no notification is created
    617   // when Deny is chosen from permission infobar.
    618   ui_test_utils::NavigateToURL(browser(), GetTestPageURL());
    619   ASSERT_TRUE(RequestPermissionAndWait(browser()));
    620   PerformActionOnInfoBar(browser(), DENY, 0, 0);
    621   CreateSimpleNotification(browser(), false);
    622   ASSERT_EQ(0, GetNotificationCount());
    623   ContentSettingsForOneType settings;
    624   GetPrefsByContentSetting(CONTENT_SETTING_BLOCK, &settings);
    625   EXPECT_TRUE(CheckOriginInSetting(settings, GetTestPageURL()));
    626 }
    627 
    628 IN_PROC_BROWSER_TEST_F(NotificationsTest, TestClosePermissionInfobar) {
    629   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    630 
    631   // Test that no notification is created when permission infobar is dismissed.
    632   ui_test_utils::NavigateToURL(browser(), GetTestPageURL());
    633   ASSERT_TRUE(RequestPermissionAndWait(browser()));
    634   PerformActionOnInfoBar(browser(), DISMISS, 0, 0);
    635   CreateSimpleNotification(browser(), false);
    636   ASSERT_EQ(0, GetNotificationCount());
    637   ContentSettingsForOneType settings;
    638   GetPrefsByContentSetting(CONTENT_SETTING_BLOCK, &settings);
    639   EXPECT_EQ(0U, settings.size());
    640 }
    641 
    642 IN_PROC_BROWSER_TEST_F(NotificationsTest, TestAllowNotificationsFromAllSites) {
    643   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    644 
    645   // Verify that all domains can be allowed to show notifications.
    646   SetDefaultPermissionSetting(CONTENT_SETTING_ALLOW);
    647   ui_test_utils::NavigateToURL(browser(), GetTestPageURL());
    648 
    649   std::string result = CreateSimpleNotification(browser(), true);
    650   EXPECT_NE("-1", result);
    651 
    652   ASSERT_EQ(1, GetNotificationCount());
    653   EXPECT_EQ(0U, InfoBarService::FromWebContents(
    654       browser()->tab_strip_model()->GetWebContentsAt(0))->infobar_count());
    655 }
    656 
    657 IN_PROC_BROWSER_TEST_F(NotificationsTest, TestDenyNotificationsFromAllSites) {
    658   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    659 
    660   // Verify that no domain can show notifications.
    661   SetDefaultPermissionSetting(CONTENT_SETTING_BLOCK);
    662   ui_test_utils::NavigateToURL(browser(), GetTestPageURL());
    663 
    664   std::string result = CreateSimpleNotification(browser(), false);
    665   EXPECT_EQ("-1", result);
    666 
    667   ASSERT_EQ(0, GetNotificationCount());
    668 }
    669 
    670 IN_PROC_BROWSER_TEST_F(NotificationsTest, TestDenyDomainAndAllowAll) {
    671   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    672 
    673   // Verify that denying a domain and allowing all shouldn't show
    674   // notifications from the denied domain.
    675   DenyOrigin(GetTestPageURL().GetOrigin());
    676   SetDefaultPermissionSetting(CONTENT_SETTING_ALLOW);
    677 
    678   ui_test_utils::NavigateToURL(browser(), GetTestPageURL());
    679 
    680   std::string result = CreateSimpleNotification(browser(), false);
    681   EXPECT_EQ("-1", result);
    682 
    683   ASSERT_EQ(0, GetNotificationCount());
    684 }
    685 
    686 IN_PROC_BROWSER_TEST_F(NotificationsTest, TestAllowDomainAndDenyAll) {
    687   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    688 
    689   // Verify that allowing a domain and denying all others should show
    690   // notifications from the allowed domain.
    691   AllowOrigin(GetTestPageURL().GetOrigin());
    692   SetDefaultPermissionSetting(CONTENT_SETTING_BLOCK);
    693 
    694   ui_test_utils::NavigateToURL(browser(), GetTestPageURL());
    695 
    696   std::string result = CreateSimpleNotification(browser(), true);
    697   EXPECT_NE("-1", result);
    698 
    699   ASSERT_EQ(1, GetNotificationCount());
    700 }
    701 
    702 IN_PROC_BROWSER_TEST_F(NotificationsTest, TestDenyAndThenAllowDomain) {
    703   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    704 
    705   // Verify that denying and again allowing should show notifications.
    706   DenyOrigin(GetTestPageURL().GetOrigin());
    707 
    708   ui_test_utils::NavigateToURL(browser(), GetTestPageURL());
    709 
    710   std::string result = CreateSimpleNotification(browser(), false);
    711   EXPECT_EQ("-1", result);
    712 
    713   ASSERT_EQ(0, GetNotificationCount());
    714 
    715   AllowOrigin(GetTestPageURL().GetOrigin());
    716   result = CreateSimpleNotification(browser(), true);
    717   EXPECT_NE("-1", result);
    718 
    719   ASSERT_EQ(1, GetNotificationCount());
    720   EXPECT_EQ(0U, InfoBarService::FromWebContents(
    721       browser()->tab_strip_model()->GetWebContentsAt(0))->infobar_count());
    722 }
    723 
    724 IN_PROC_BROWSER_TEST_F(NotificationsTest, TestCreateDenyCloseNotifications) {
    725   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    726 
    727   // Verify able to create, deny, and close the notification.
    728   AllowAllOrigins();
    729   ui_test_utils::NavigateToURL(browser(), GetTestPageURL());
    730   CreateSimpleNotification(browser(), true);
    731   ASSERT_EQ(1, GetNotificationCount());
    732 
    733   DenyOrigin(GetTestPageURL().GetOrigin());
    734   ContentSettingsForOneType settings;
    735   GetPrefsByContentSetting(CONTENT_SETTING_BLOCK, &settings);
    736   ASSERT_TRUE(CheckOriginInSetting(settings, GetTestPageURL().GetOrigin()));
    737 
    738   EXPECT_EQ(1, GetNotificationCount());
    739   if (message_center::IsRichNotificationEnabled()) {
    740     message_center::NotificationList::Notifications notifications =
    741         message_center::MessageCenter::Get()->GetVisibleNotifications();
    742     message_center::MessageCenter::Get()->RemoveNotification(
    743         (*notifications.rbegin())->id(),
    744         true);  // by_user
    745   } else {
    746     const std::deque<Balloon*>& balloons = GetActiveBalloons();
    747     ASSERT_TRUE(CloseNotificationAndWait(balloons[0]->notification()));
    748   }
    749   ASSERT_EQ(0, GetNotificationCount());
    750 }
    751 
    752 // Crashes on Linux/Win. See http://crbug.com/160657.
    753 IN_PROC_BROWSER_TEST_F(
    754     NotificationsTest,
    755     DISABLED_TestOriginPrefsNotSavedInIncognito) {
    756   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    757 
    758   // Verify that allow/deny origin preferences are not saved in incognito.
    759   Browser* incognito = CreateIncognitoBrowser();
    760   ui_test_utils::NavigateToURL(incognito, GetTestPageURL());
    761   ASSERT_TRUE(RequestPermissionAndWait(incognito));
    762   PerformActionOnInfoBar(incognito, DENY, 0, 0);
    763   CloseBrowserWindow(incognito);
    764 
    765   incognito = CreateIncognitoBrowser();
    766   ui_test_utils::NavigateToURL(incognito, GetTestPageURL());
    767   ASSERT_TRUE(RequestPermissionAndWait(incognito));
    768   PerformActionOnInfoBar(incognito, ALLOW, 0, 0);
    769   CreateSimpleNotification(incognito, true);
    770   ASSERT_EQ(1, GetNotificationCount());
    771   CloseBrowserWindow(incognito);
    772 
    773   incognito = CreateIncognitoBrowser();
    774   ui_test_utils::NavigateToURL(incognito, GetTestPageURL());
    775   ASSERT_TRUE(RequestPermissionAndWait(incognito));
    776 
    777   ContentSettingsForOneType settings;
    778   GetPrefsByContentSetting(CONTENT_SETTING_BLOCK, &settings);
    779   EXPECT_EQ(0U, settings.size());
    780   GetPrefsByContentSetting(CONTENT_SETTING_ALLOW, &settings);
    781   EXPECT_EQ(0U, settings.size());
    782 }
    783 
    784 IN_PROC_BROWSER_TEST_F(NotificationsTest, TestExitBrowserWithInfobar) {
    785   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    786 
    787   // Exit the browser window, when the infobar appears.
    788   ui_test_utils::NavigateToURL(browser(), GetTestPageURL());
    789   ASSERT_TRUE(RequestPermissionAndWait(browser()));
    790 }
    791 
    792 // Times out on Windows and Linux. http://crbug.com/168976
    793 #if defined(OS_WIN) || defined(OS_LINUX)
    794 #define MAYBE_TestCrashTabWithPermissionInfobar \
    795     DISABLED_TestCrashTabWithPermissionInfobar
    796 #else
    797 #define MAYBE_TestCrashTabWithPermissionInfobar \
    798     TestCrashTabWithPermissionInfobar
    799 #endif
    800 IN_PROC_BROWSER_TEST_F(NotificationsTest,
    801                        MAYBE_TestCrashTabWithPermissionInfobar) {
    802   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    803 
    804   // Test crashing the tab with permission infobar doesn't crash Chrome.
    805   ui_test_utils::NavigateToURLWithDisposition(
    806       browser(),
    807       embedded_test_server()->GetURL("/empty.html"),
    808       NEW_BACKGROUND_TAB,
    809       ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
    810   browser()->tab_strip_model()->ActivateTabAt(0, true);
    811   ui_test_utils::NavigateToURL(browser(), GetTestPageURL());
    812   ASSERT_TRUE(RequestPermissionAndWait(browser()));
    813   CrashTab(browser(), 0);
    814 }
    815 
    816 IN_PROC_BROWSER_TEST_F(NotificationsTest, TestKillNotificationProcess) {
    817   // Notifications don't have their own process with the message center.
    818   if (message_center::IsRichNotificationEnabled())
    819     return;
    820 
    821   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    822 
    823   // Test killing a notification doesn't crash Chrome.
    824   AllowAllOrigins();
    825   ui_test_utils::NavigateToURL(browser(), GetTestPageURL());
    826   CreateSimpleNotification(browser(), true);
    827   ASSERT_EQ(1, GetNotificationCount());
    828 
    829   const std::deque<Balloon*>& balloons = GetActiveBalloons();
    830   ASSERT_EQ(1U, balloons.size());
    831   CrashNotification(balloons[0]);
    832   ASSERT_EQ(0, GetNotificationCount());
    833 }
    834 
    835 IN_PROC_BROWSER_TEST_F(NotificationsTest, TestIncognitoNotification) {
    836   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    837 
    838   // Test notifications in incognito window.
    839   Browser* browser = CreateIncognitoBrowser();
    840   ui_test_utils::NavigateToURL(browser, GetTestPageURL());
    841   browser->tab_strip_model()->ActivateTabAt(0, true);
    842   ASSERT_TRUE(RequestPermissionAndWait(browser));
    843   PerformActionOnInfoBar(browser, ALLOW, 0, 0);
    844   CreateSimpleNotification(browser, true);
    845   ASSERT_EQ(1, GetNotificationCount());
    846 }
    847 
    848 IN_PROC_BROWSER_TEST_F(NotificationsTest, TestCloseTabWithPermissionInfobar) {
    849   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    850 
    851   // Test that user can close tab when infobar present.
    852   ui_test_utils::NavigateToURLWithDisposition(
    853       browser(),
    854       GURL("about:blank"),
    855       NEW_BACKGROUND_TAB,
    856       ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
    857   browser()->tab_strip_model()->ActivateTabAt(0, true);
    858   ui_test_utils::NavigateToURL(browser(), GetTestPageURL());
    859   ASSERT_TRUE(RequestPermissionAndWait(browser()));
    860   content::WebContentsDestroyedWatcher destroyed_watcher(
    861       browser()->tab_strip_model()->GetWebContentsAt(0));
    862   browser()->tab_strip_model()->CloseWebContentsAt(0,
    863                                                    TabStripModel::CLOSE_NONE);
    864   destroyed_watcher.Wait();
    865 }
    866 
    867 IN_PROC_BROWSER_TEST_F(
    868     NotificationsTest,
    869     TestNavigateAwayWithPermissionInfobar) {
    870   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    871 
    872   // Test navigating away when an infobar is present,
    873   // then trying to create a notification from the same page.
    874   ui_test_utils::NavigateToURLWithDisposition(
    875       browser(),
    876       GURL("about:blank"),
    877       NEW_BACKGROUND_TAB,
    878       ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
    879   browser()->tab_strip_model()->ActivateTabAt(0, true);
    880   ui_test_utils::NavigateToURL(browser(), GetTestPageURL());
    881   ASSERT_TRUE(RequestPermissionAndWait(browser()));
    882   ui_test_utils::NavigateToURL(browser(), GetTestPageURL());
    883   ASSERT_TRUE(RequestPermissionAndWait(browser()));
    884   PerformActionOnInfoBar(browser(), ALLOW, 0, 0);
    885   CreateSimpleNotification(browser(), true);
    886   ASSERT_EQ(1, GetNotificationCount());
    887 }
    888 
    889 // See crbug.com/248470
    890 #if defined(OS_LINUX)
    891 #define MAYBE_TestCrashRendererNotificationRemain \
    892     DISABLED_TestCrashRendererNotificationRemain
    893 #else
    894 #define MAYBE_TestCrashRendererNotificationRemain \
    895     TestCrashRendererNotificationRemain
    896 #endif
    897 
    898 IN_PROC_BROWSER_TEST_F(NotificationsTest,
    899                        MAYBE_TestCrashRendererNotificationRemain) {
    900   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    901 
    902   // Test crashing renderer does not close or crash notification.
    903   AllowAllOrigins();
    904   ui_test_utils::NavigateToURLWithDisposition(
    905       browser(),
    906       GURL("about:blank"),
    907       NEW_BACKGROUND_TAB,
    908       ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
    909   browser()->tab_strip_model()->ActivateTabAt(0, true);
    910   ui_test_utils::NavigateToURL(browser(), GetTestPageURL());
    911   CreateSimpleNotification(browser(), true);
    912   ASSERT_EQ(1, GetNotificationCount());
    913   CrashTab(browser(), 0);
    914   ASSERT_EQ(1, GetNotificationCount());
    915 }
    916 
    917 IN_PROC_BROWSER_TEST_F(NotificationsTest, TestNotificationReplacement) {
    918   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    919 
    920   // Test that we can replace a notification using the replaceId.
    921   AllowAllOrigins();
    922 
    923   ui_test_utils::NavigateToURL(browser(), GetTestPageURL());
    924 
    925   std::string result = CreateNotification(
    926       browser(), true, "abc.png", "Title1", "Body1", "chat");
    927   EXPECT_NE("-1", result);
    928 
    929   ASSERT_EQ(1, GetNotificationCount());
    930 
    931   result = CreateNotification(
    932       browser(), false, "no_such_file.png", "Title2", "Body2", "chat");
    933   EXPECT_NE("-1", result);
    934 
    935   if (message_center::IsRichNotificationEnabled()) {
    936     ASSERT_EQ(1, GetNotificationCount());
    937     message_center::NotificationList::Notifications notifications =
    938         message_center::MessageCenter::Get()->GetVisibleNotifications();
    939     EXPECT_EQ(ASCIIToUTF16("Title2"), (*notifications.rbegin())->title());
    940     EXPECT_EQ(ASCIIToUTF16("Body2"), (*notifications.rbegin())->message());
    941   } else {
    942     const std::deque<Balloon*>& balloons = GetActiveBalloons();
    943     ASSERT_EQ(1U, balloons.size());
    944     Balloon* balloon = balloons[0];
    945     const Notification& notification = balloon->notification();
    946     GURL EXPECTED_ICON_URL = embedded_test_server()->GetURL(kExpectedIconUrl);
    947     EXPECT_EQ(EXPECTED_ICON_URL, notification.icon_url());
    948     EXPECT_EQ(ASCIIToUTF16("Title2"), notification.title());
    949     EXPECT_EQ(ASCIIToUTF16("Body2"), notification.message());
    950   }
    951 }
    952