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