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