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