notification_browsertest.cc revision 8bcbed890bc3ce4d7a057a8f32cab53fa534672e
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
53namespace {
54
55const char kExpectedIconUrl[] = "/notifications/no_such_file.png";
56
57enum InfobarAction {
58  DISMISS = 0,
59  ALLOW,
60  DENY,
61};
62
63class NotificationChangeObserver {
64public:
65  virtual ~NotificationChangeObserver() {}
66  virtual bool Wait() = 0;
67};
68
69class 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
120class 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
199class 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
249int 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
258NotificationChangeObserver* NotificationsTest::CreateObserver() {
259  if (message_center::IsRichNotificationEnabled())
260    return new MessageCenterChangeObserver();
261  else
262    return new NotificationBalloonChangeObserver();
263}
264
265void 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
273void NotificationsTest::CrashTab(Browser* browser, int index) {
274  content::CrashTab(browser->tab_strip_model()->GetWebContentsAt(index));
275}
276
277const std::deque<Balloon*>& NotificationsTest::GetActiveBalloons() {
278  return BalloonNotificationUIManager::GetInstanceForTesting()->
279      balloon_collection()->GetActiveBalloons();
280}
281
282void NotificationsTest::CrashNotification(Balloon* balloon) {
283  content::CrashTab(balloon->balloon_view()->GetHost()->web_contents());
284}
285
286bool 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
296void NotificationsTest::SetDefaultPermissionSetting(ContentSetting setting) {
297  DesktopNotificationService* service = GetDesktopNotificationService();
298  service->SetDefaultContentSetting(setting);
299}
300
301void NotificationsTest::DenyOrigin(const GURL& origin) {
302  DropOriginPreference(origin);
303  GetDesktopNotificationService()->DenyPermission(origin);
304}
305
306void NotificationsTest::AllowOrigin(const GURL& origin) {
307  DropOriginPreference(origin);
308  GetDesktopNotificationService()->GrantPermission(origin);
309}
310
311void NotificationsTest::AllowAllOrigins() {
312  GetDesktopNotificationService()->ResetAllOrigins();
313  GetDesktopNotificationService()->SetDefaultContentSetting(
314      CONTENT_SETTING_ALLOW);
315}
316
317void 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
330std::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
354std::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
362bool 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
379bool 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
397bool 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
443void 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
457bool 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
470void NotificationsTest::DropOriginPreference(const GURL& origin) {
471  GetDesktopNotificationService()->ClearSetting(
472      ContentSettingsPattern::FromURLNoWildcard(origin));
473}
474
475DesktopNotificationService* 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.
481IN_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.
503IN_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
517IN_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()->GetVisibleNotifications();
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
545IN_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()->GetVisibleNotifications();
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
570IN_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
585IN_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
596IN_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
612IN_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
627IN_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
641IN_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
656IN_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
669IN_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
685IN_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
701IN_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
723IN_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()->GetVisibleNotifications();
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.
752IN_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
783IN_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
799IN_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
815IN_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
834IN_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
847IN_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::WebContentsDestroyedWatcher destroyed_watcher(
860      browser()->tab_strip_model()->GetWebContentsAt(0));
861  browser()->tab_strip_model()->CloseWebContentsAt(0,
862                                                   TabStripModel::CLOSE_NONE);
863  destroyed_watcher.Wait();
864}
865
866IN_PROC_BROWSER_TEST_F(
867    NotificationsTest,
868    TestNavigateAwayWithPermissionInfobar) {
869  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
870
871  // Test navigating away when an infobar is present,
872  // then trying to create a notification from the same page.
873  ui_test_utils::NavigateToURLWithDisposition(
874      browser(),
875      GURL("about:blank"),
876      NEW_BACKGROUND_TAB,
877      ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
878  browser()->tab_strip_model()->ActivateTabAt(0, true);
879  ui_test_utils::NavigateToURL(browser(), GetTestPageURL());
880  ASSERT_TRUE(RequestPermissionAndWait(browser()));
881  ui_test_utils::NavigateToURL(browser(), GetTestPageURL());
882  ASSERT_TRUE(RequestPermissionAndWait(browser()));
883  PerformActionOnInfoBar(browser(), ALLOW, 0, 0);
884  CreateSimpleNotification(browser(), true);
885  ASSERT_EQ(1, GetNotificationCount());
886}
887
888// See crbug.com/248470
889#if defined(OS_LINUX)
890#define MAYBE_TestCrashRendererNotificationRemain \
891    DISABLED_TestCrashRendererNotificationRemain
892#else
893#define MAYBE_TestCrashRendererNotificationRemain \
894    TestCrashRendererNotificationRemain
895#endif
896
897IN_PROC_BROWSER_TEST_F(NotificationsTest,
898                       MAYBE_TestCrashRendererNotificationRemain) {
899  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
900
901  // Test crashing renderer does not close or crash notification.
902  AllowAllOrigins();
903  ui_test_utils::NavigateToURLWithDisposition(
904      browser(),
905      GURL("about:blank"),
906      NEW_BACKGROUND_TAB,
907      ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
908  browser()->tab_strip_model()->ActivateTabAt(0, true);
909  ui_test_utils::NavigateToURL(browser(), GetTestPageURL());
910  CreateSimpleNotification(browser(), true);
911  ASSERT_EQ(1, GetNotificationCount());
912  CrashTab(browser(), 0);
913  ASSERT_EQ(1, GetNotificationCount());
914}
915
916IN_PROC_BROWSER_TEST_F(NotificationsTest, TestNotificationReplacement) {
917  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
918
919  // Test that we can replace a notification using the replaceId.
920  AllowAllOrigins();
921
922  ui_test_utils::NavigateToURL(browser(), GetTestPageURL());
923
924  std::string result = CreateNotification(
925      browser(), true, "abc.png", "Title1", "Body1", "chat");
926  EXPECT_NE("-1", result);
927
928  ASSERT_EQ(1, GetNotificationCount());
929
930  result = CreateNotification(
931      browser(), false, "no_such_file.png", "Title2", "Body2", "chat");
932  EXPECT_NE("-1", result);
933
934  if (message_center::IsRichNotificationEnabled()) {
935    ASSERT_EQ(1, GetNotificationCount());
936    message_center::NotificationList::Notifications notifications =
937        message_center::MessageCenter::Get()->GetVisibleNotifications();
938    EXPECT_EQ(ASCIIToUTF16("Title2"), (*notifications.rbegin())->title());
939    EXPECT_EQ(ASCIIToUTF16("Body2"), (*notifications.rbegin())->message());
940  } else {
941    const std::deque<Balloon*>& balloons = GetActiveBalloons();
942    ASSERT_EQ(1U, balloons.size());
943    Balloon* balloon = balloons[0];
944    const Notification& notification = balloon->notification();
945    GURL EXPECTED_ICON_URL = embedded_test_server()->GetURL(kExpectedIconUrl);
946    EXPECT_EQ(EXPECTED_ICON_URL, notification.icon_url());
947    EXPECT_EQ(ASCIIToUTF16("Title2"), notification.title());
948    EXPECT_EQ(ASCIIToUTF16("Body2"), notification.message());
949  }
950}
951