blob: 6de0bdff3cc2d0a2f9fcf1888c3ed5fadc9bb885 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <memory>
#include <string>
#include <vector>
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "base/time/time.h"
#include "chrome/browser/notifications/desktop_notification_profile_util.h"
#include "chrome/browser/notifications/message_center_display_service.h"
#include "chrome/browser/notifications/notification.h"
#include "chrome/browser/notifications/notification_test_util.h"
#include "chrome/browser/notifications/platform_notification_service_impl.h"
#include "chrome/browser/notifications/web_notification_delegate.h"
#include "chrome/browser/permissions/permission_manager.h"
#include "chrome/browser/permissions/permission_request_manager.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/exclusive_access/exclusive_access_context.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_features.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/interactive_test_utils.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test_utils.h"
#include "net/base/filename_util.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/WebKit/public/platform/modules/permissions/permission_status.mojom.h"
#if BUILDFLAG(ENABLE_BACKGROUND)
#include "chrome/browser/lifetime/keep_alive_registry.h"
#include "chrome/browser/lifetime/keep_alive_types.h"
#endif
#if defined(OS_MACOSX)
#include "base/mac/mac_util.h"
#include "ui/base/test/scoped_fake_nswindow_fullscreen.h"
#endif
// -----------------------------------------------------------------------------
// Dimensions of the icon.png resource in the notification test data directory.
const int kIconWidth = 100;
const int kIconHeight = 100;
const int kNotificationVibrationPattern[] = { 100, 200, 300 };
const double kNotificationTimestamp = 621046800000.;
class PlatformNotificationServiceBrowserTest : public InProcessBrowserTest {
public:
PlatformNotificationServiceBrowserTest();
~PlatformNotificationServiceBrowserTest() override {}
// InProcessBrowserTest overrides.
void SetUpCommandLine(base::CommandLine* command_line) override;
void SetUp() override;
void SetUpOnMainThread() override;
void TearDown() override;
protected:
// Returns the Platform Notification Service these unit tests are for.
PlatformNotificationServiceImpl* service() const {
return PlatformNotificationServiceImpl::GetInstance();
}
// Grants permission to display Web Notifications for origin of the test
// page that's being used in this browser test.
void GrantNotificationPermissionForTest() const;
bool RequestAndAcceptPermission();
bool RequestAndDenyPermission();
void EnableFullscreenNotifications();
void DisableFullscreenNotifications();
// Returns the UI Manager on which notifications will be displayed.
StubNotificationUIManager* ui_manager() const { return ui_manager_.get(); }
const base::FilePath& server_root() const { return server_root_; }
// Navigates the browser to the test page indicated by |path|.
void NavigateToTestPage(const std::string& path) const;
// Executes |script| and stores the result as a string in |result|. A boolean
// will be returned, indicating whether the script was executed successfully.
bool RunScript(const std::string& script, std::string* result) const;
net::HostPortPair ServerHostPort() const;
GURL TestPageUrl() const;
private:
std::string RequestAndRespondToPermission(
PermissionRequestManager::AutoResponseType bubble_response);
content::WebContents* GetActiveWebContents(Browser* browser) {
return browser->tab_strip_model()->GetActiveWebContents();
}
const base::FilePath server_root_;
const std::string test_page_url_;
std::unique_ptr<StubNotificationUIManager> ui_manager_;
std::unique_ptr<MessageCenterDisplayService> display_service_;
std::unique_ptr<net::EmbeddedTestServer> https_server_;
base::test::ScopedFeatureList feature_list_;
};
// -----------------------------------------------------------------------------
namespace {
const char kTestFileName[] = "notifications/platform_notification_service.html";
}
PlatformNotificationServiceBrowserTest::PlatformNotificationServiceBrowserTest()
: server_root_(FILE_PATH_LITERAL("chrome/test/data")),
// The test server has a base directory that doesn't exist in the
// filesystem.
test_page_url_(std::string("/") + kTestFileName) {}
void PlatformNotificationServiceBrowserTest::SetUpCommandLine(
base::CommandLine* command_line) {
command_line->AppendSwitch(switches::kEnableExperimentalWebPlatformFeatures);
InProcessBrowserTest::SetUpCommandLine(command_line);
}
void PlatformNotificationServiceBrowserTest::SetUp() {
ui_manager_.reset(new StubNotificationUIManager);
https_server_.reset(
new net::EmbeddedTestServer(net::EmbeddedTestServer::TYPE_HTTPS));
https_server_->ServeFilesFromSourceDirectory(server_root_);
ASSERT_TRUE(https_server_->Start());
InProcessBrowserTest::SetUp();
}
void PlatformNotificationServiceBrowserTest::SetUpOnMainThread() {
NavigateToTestPage(test_page_url_);
display_service_.reset(
new MessageCenterDisplayService(browser()->profile(), ui_manager_.get()));
service()->SetNotificationDisplayServiceForTesting(display_service_.get());
InProcessBrowserTest::SetUpOnMainThread();
}
void PlatformNotificationServiceBrowserTest::TearDown() {
service()->SetNotificationDisplayServiceForTesting(nullptr);
}
void PlatformNotificationServiceBrowserTest::
GrantNotificationPermissionForTest() const {
GURL origin = TestPageUrl().GetOrigin();
DesktopNotificationProfileUtil::GrantPermission(browser()->profile(), origin);
ASSERT_EQ(blink::mojom::PermissionStatus::GRANTED,
PermissionManager::Get(browser()->profile())
->GetPermissionStatus(CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
origin, origin));
}
void PlatformNotificationServiceBrowserTest::NavigateToTestPage(
const std::string& path) const {
ui_test_utils::NavigateToURL(browser(), https_server_->GetURL(path));
}
bool PlatformNotificationServiceBrowserTest::RunScript(
const std::string& script, std::string* result) const {
return content::ExecuteScriptAndExtractString(
browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
script,
result);
}
net::HostPortPair PlatformNotificationServiceBrowserTest::ServerHostPort()
const {
return https_server_->host_port_pair();
}
GURL PlatformNotificationServiceBrowserTest::TestPageUrl() const {
return https_server_->GetURL(test_page_url_);
}
std::string
PlatformNotificationServiceBrowserTest::RequestAndRespondToPermission(
PermissionRequestManager::AutoResponseType bubble_response) {
std::string result;
content::WebContents* web_contents = GetActiveWebContents(browser());
PermissionRequestManager::FromWebContents(web_contents)
->set_auto_response_for_test(bubble_response);
EXPECT_TRUE(RunScript("RequestPermission();", &result));
return result;
}
bool PlatformNotificationServiceBrowserTest::RequestAndAcceptPermission() {
std::string result =
RequestAndRespondToPermission(PermissionRequestManager::ACCEPT_ALL);
return "granted" == result;
}
bool PlatformNotificationServiceBrowserTest::RequestAndDenyPermission() {
std::string result =
RequestAndRespondToPermission(PermissionRequestManager::DENY_ALL);
return "denied" == result;
}
void PlatformNotificationServiceBrowserTest::EnableFullscreenNotifications() {
feature_list_.InitWithFeatures({
features::kPreferHtmlOverPlugins,
features::kAllowFullscreenWebNotificationsFeature}, {});
}
void PlatformNotificationServiceBrowserTest::DisableFullscreenNotifications() {
feature_list_.InitWithFeatures(
{features::kPreferHtmlOverPlugins},
{features::kAllowFullscreenWebNotificationsFeature});
}
// -----------------------------------------------------------------------------
// TODO(peter): Move PlatformNotificationService-related tests over from
// notification_browsertest.cc to this file.
IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
DisplayPersistentNotificationWithoutPermission) {
RequestAndDenyPermission();
std::string script_result;
ASSERT_TRUE(RunScript("DisplayPersistentNotification()", &script_result));
EXPECT_EQ(
"TypeError: No notification permission has been granted for this origin.",
script_result);
ASSERT_EQ(0u, ui_manager()->GetNotificationCount());
}
IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
DisplayPersistentNotificationWithPermission) {
RequestAndAcceptPermission();
std::string script_result;
ASSERT_TRUE(RunScript("DisplayPersistentNotification('action_none')",
&script_result));
EXPECT_EQ("ok", script_result);
ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
#if BUILDFLAG(ENABLE_BACKGROUND)
ASSERT_FALSE(KeepAliveRegistry::GetInstance()->IsOriginRegistered(
KeepAliveOrigin::PENDING_NOTIFICATION_CLICK_EVENT));
#endif
const Notification& notification = ui_manager()->GetNotificationAt(0);
notification.delegate()->Click();
#if BUILDFLAG(ENABLE_BACKGROUND)
ASSERT_TRUE(KeepAliveRegistry::GetInstance()->IsOriginRegistered(
KeepAliveOrigin::PENDING_NOTIFICATION_CLICK_EVENT));
#endif
ASSERT_TRUE(RunScript("GetMessageFromWorker()", &script_result));
EXPECT_EQ("action_none", script_result);
#if BUILDFLAG(ENABLE_BACKGROUND)
ASSERT_FALSE(KeepAliveRegistry::GetInstance()->IsOriginRegistered(
KeepAliveOrigin::PENDING_NOTIFICATION_CLICK_EVENT));
#endif
ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
}
IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
WebNotificationOptionsReflection) {
ASSERT_NO_FATAL_FAILURE(GrantNotificationPermissionForTest());
// First, test the default values.
std::string script_result;
ASSERT_TRUE(RunScript("DisplayPersistentNotification('Some title', {})",
&script_result));
EXPECT_EQ("ok", script_result);
ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
// We don't use or check the notification's direction and language.
const Notification& default_notification = ui_manager()->GetNotificationAt(0);
EXPECT_EQ("Some title", base::UTF16ToUTF8(default_notification.title()));
EXPECT_EQ("", base::UTF16ToUTF8(default_notification.message()));
EXPECT_EQ("", default_notification.tag());
EXPECT_TRUE(default_notification.image().IsEmpty());
EXPECT_TRUE(default_notification.icon().IsEmpty());
EXPECT_TRUE(default_notification.small_image().IsEmpty());
EXPECT_FALSE(default_notification.renotify());
EXPECT_FALSE(default_notification.silent());
EXPECT_FALSE(default_notification.never_timeout());
EXPECT_EQ(0u, default_notification.buttons().size());
// Verifies that the notification's default timestamp is set in the last 30
// seconds. This number has no significance, but it needs to be significantly
// high to avoid flakiness in the test.
EXPECT_NEAR(default_notification.timestamp().ToJsTime(),
base::Time::Now().ToJsTime(), 30 * 1000);
// Now, test the non-default values.
ASSERT_TRUE(RunScript("DisplayPersistentAllOptionsNotification()",
&script_result));
EXPECT_EQ("ok", script_result);
ASSERT_EQ(2u, ui_manager()->GetNotificationCount());
// We don't use or check the notification's direction and language.
const Notification& all_options_notification =
ui_manager()->GetNotificationAt(1);
EXPECT_EQ("Title", base::UTF16ToUTF8(all_options_notification.title()));
EXPECT_EQ("Contents", base::UTF16ToUTF8(all_options_notification.message()));
EXPECT_EQ("replace-id", all_options_notification.tag());
EXPECT_FALSE(all_options_notification.image().IsEmpty());
EXPECT_EQ(kIconWidth, all_options_notification.image().Width());
EXPECT_EQ(kIconHeight, all_options_notification.image().Height());
EXPECT_FALSE(all_options_notification.icon().IsEmpty());
EXPECT_EQ(kIconWidth, all_options_notification.icon().Width());
EXPECT_EQ(kIconHeight, all_options_notification.icon().Height());
EXPECT_TRUE(all_options_notification.small_image().IsEmpty());
EXPECT_TRUE(all_options_notification.renotify());
EXPECT_TRUE(all_options_notification.silent());
EXPECT_TRUE(all_options_notification.never_timeout());
EXPECT_DOUBLE_EQ(kNotificationTimestamp,
all_options_notification.timestamp().ToJsTime());
EXPECT_EQ(1u, all_options_notification.buttons().size());
EXPECT_EQ("actionTitle",
base::UTF16ToUTF8(all_options_notification.buttons()[0].title));
EXPECT_FALSE(all_options_notification.buttons()[0].icon.IsEmpty());
EXPECT_EQ(kIconWidth, all_options_notification.buttons()[0].icon.Width());
EXPECT_EQ(kIconHeight, all_options_notification.buttons()[0].icon.Height());
}
IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
WebNotificationSiteSettingsButton) {
ASSERT_NO_FATAL_FAILURE(GrantNotificationPermissionForTest());
std::string script_result;
ASSERT_TRUE(RunScript("DisplayPersistentNotification('Some title', {})",
&script_result));
EXPECT_EQ("ok", script_result);
ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
const Notification& notification = ui_manager()->GetNotificationAt(0);
const std::vector<message_center::ButtonInfo>& buttons =
notification.buttons();
EXPECT_EQ(0u, buttons.size());
notification.delegate()->SettingsClick();
ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
content::WebContents* web_contents =
browser()->tab_strip_model()->GetActiveWebContents();
ASSERT_TRUE(content::WaitForLoadStop(web_contents));
ASSERT_EQ("chrome://settings/contentExceptions#notifications",
web_contents->GetLastCommittedURL().spec());
}
IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
WebNotificationOptionsVibrationPattern) {
ASSERT_NO_FATAL_FAILURE(GrantNotificationPermissionForTest());
std::string script_result;
ASSERT_TRUE(RunScript("DisplayPersistentNotificationVibrate()",
&script_result));
EXPECT_EQ("ok", script_result);
ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
const Notification& notification = ui_manager()->GetNotificationAt(0);
EXPECT_EQ("Title", base::UTF16ToUTF8(notification.title()));
EXPECT_EQ("Contents", base::UTF16ToUTF8(notification.message()));
EXPECT_THAT(notification.vibration_pattern(),
testing::ElementsAreArray(kNotificationVibrationPattern));
}
IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
CloseDisplayedPersistentNotification) {
ASSERT_NO_FATAL_FAILURE(GrantNotificationPermissionForTest());
std::string script_result;
ASSERT_TRUE(RunScript("DisplayPersistentNotification('action_close')",
&script_result));
EXPECT_EQ("ok", script_result);
ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
const Notification& notification = ui_manager()->GetNotificationAt(0);
notification.delegate()->Click();
ASSERT_TRUE(RunScript("GetMessageFromWorker()", &script_result));
EXPECT_EQ("action_close", script_result);
ASSERT_EQ(0u, ui_manager()->GetNotificationCount());
}
IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
UserClosesPersistentNotification) {
ASSERT_NO_FATAL_FAILURE(GrantNotificationPermissionForTest());
std::string script_result;
ASSERT_TRUE(
RunScript("DisplayPersistentNotification('close_test')", &script_result));
EXPECT_EQ("ok", script_result);
ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
const Notification& notification = ui_manager()->GetNotificationAt(0);
notification.delegate()->Close(true /* by_user */);
ASSERT_TRUE(RunScript("GetMessageFromWorker()", &script_result));
EXPECT_EQ("closing notification: close_test", script_result);
}
IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
TestDisplayOriginContextMessage) {
RequestAndAcceptPermission();
// Creates a simple notification.
std::string script_result;
ASSERT_TRUE(RunScript("DisplayPersistentNotification()", &script_result));
net::HostPortPair host_port = ServerHostPort();
const Notification& notification = ui_manager()->GetNotificationAt(0);
EXPECT_TRUE(notification.context_message().empty());
EXPECT_EQ("https://" + host_port.ToString() + "/",
notification.origin_url().spec());
}
IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
PersistentNotificationServiceWorkerScope) {
RequestAndAcceptPermission();
// Creates a simple notification.
std::string script_result;
ASSERT_TRUE(RunScript("DisplayPersistentNotification()", &script_result));
const Notification& notification = ui_manager()->GetNotificationAt(0);
EXPECT_EQ(TestPageUrl().spec(), notification.service_worker_scope().spec());
}
// TODO(felt): This DCHECKs when bubbles are enabled, when the file_url is
// persisted. crbug.com/502057
IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
DISABLED_CheckFilePermissionNotGranted) {
// This case should succeed because a normal page URL is used.
std::string script_result;
PermissionManager* permission_manager =
PermissionManager::Get(browser()->profile());
EXPECT_EQ(blink::mojom::PermissionStatus::ASK,
permission_manager->GetPermissionStatus(
CONTENT_SETTINGS_TYPE_NOTIFICATIONS, TestPageUrl(),
TestPageUrl()));
RequestAndAcceptPermission();
EXPECT_EQ(blink::mojom::PermissionStatus::GRANTED,
permission_manager->GetPermissionStatus(
CONTENT_SETTINGS_TYPE_NOTIFICATIONS, TestPageUrl(),
TestPageUrl()));
// This case should fail because a file URL is used.
base::FilePath dir_source_root;
EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &dir_source_root));
base::FilePath full_file_path =
dir_source_root.Append(server_root()).AppendASCII(kTestFileName);
GURL file_url(net::FilePathToFileURL(full_file_path));
ui_test_utils::NavigateToURL(browser(), file_url);
EXPECT_EQ(blink::mojom::PermissionStatus::ASK,
permission_manager->GetPermissionStatus(
CONTENT_SETTINGS_TYPE_NOTIFICATIONS, file_url, file_url));
RequestAndAcceptPermission();
EXPECT_EQ(blink::mojom::PermissionStatus::ASK,
permission_manager->GetPermissionStatus(
CONTENT_SETTINGS_TYPE_NOTIFICATIONS, file_url, file_url))
<< "If this test fails, you may have fixed a bug preventing file origins "
<< "from sending their origin from Blink; if so you need to update the "
<< "display function for notification origins to show the file path.";
}
IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
DataUrlAsNotificationImage) {
ASSERT_NO_FATAL_FAILURE(GrantNotificationPermissionForTest());
std::string script_result;
ASSERT_TRUE(RunScript("DisplayPersistentNotificationDataUrlImage()",
&script_result));
EXPECT_EQ("ok", script_result);
ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
const Notification& notification = ui_manager()->GetNotificationAt(0);
EXPECT_FALSE(notification.icon().IsEmpty());
EXPECT_EQ("Data URL Title", base::UTF16ToUTF8(notification.title()));
EXPECT_EQ(kIconWidth, notification.icon().Width());
EXPECT_EQ(kIconHeight, notification.icon().Height());
}
IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
BlobAsNotificationImage) {
ASSERT_NO_FATAL_FAILURE(GrantNotificationPermissionForTest());
std::string script_result;
ASSERT_TRUE(RunScript("DisplayPersistentNotificationBlobImage()",
&script_result));
EXPECT_EQ("ok", script_result);
ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
const Notification& notification = ui_manager()->GetNotificationAt(0);
EXPECT_FALSE(notification.icon().IsEmpty());
EXPECT_EQ("Blob Title", base::UTF16ToUTF8(notification.title()));
EXPECT_EQ(kIconWidth, notification.icon().Width());
EXPECT_EQ(kIconHeight, notification.icon().Height());
}
IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
DisplayPersistentNotificationWithActionButtons) {
ASSERT_NO_FATAL_FAILURE(GrantNotificationPermissionForTest());
std::string script_result;
ASSERT_TRUE(RunScript("DisplayPersistentNotificationWithActionButtons()",
&script_result));
EXPECT_EQ("ok", script_result);
ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
const Notification& notification = ui_manager()->GetNotificationAt(0);
ASSERT_EQ(2u, notification.buttons().size());
EXPECT_EQ("actionTitle1", base::UTF16ToUTF8(notification.buttons()[0].title));
EXPECT_EQ("actionTitle2", base::UTF16ToUTF8(notification.buttons()[1].title));
notification.delegate()->ButtonClick(0);
ASSERT_TRUE(RunScript("GetMessageFromWorker()", &script_result));
EXPECT_EQ("action_button_click actionId1", script_result);
notification.delegate()->ButtonClick(1);
ASSERT_TRUE(RunScript("GetMessageFromWorker()", &script_result));
EXPECT_EQ("action_button_click actionId2", script_result);
}
IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
DisplayPersistentNotificationWithReplyButton) {
ASSERT_NO_FATAL_FAILURE(GrantNotificationPermissionForTest());
std::string script_result;
ASSERT_TRUE(RunScript("DisplayPersistentNotificationWithReplyButton()",
&script_result));
EXPECT_EQ("ok", script_result);
ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
const Notification& notification = ui_manager()->GetNotificationAt(0);
ASSERT_EQ(1u, notification.buttons().size());
EXPECT_EQ("actionTitle1", base::UTF16ToUTF8(notification.buttons()[0].title));
notification.delegate()->ButtonClickWithReply(0, base::ASCIIToUTF16("hello"));
ASSERT_TRUE(RunScript("GetMessageFromWorker()", &script_result));
EXPECT_EQ("action_button_click actionId1 hello", script_result);
}
IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
GetDisplayedNotifications) {
RequestAndAcceptPermission();
std::string script_result;
std::string script_message;
ASSERT_TRUE(RunScript("DisplayNonPersistentNotification('NonPersistent')",
&script_result));
EXPECT_EQ("ok", script_result);
ASSERT_TRUE(RunScript("DisplayPersistentNotification('PersistentI')",
&script_result));
EXPECT_EQ("ok", script_result);
ASSERT_TRUE(RunScript("DisplayPersistentNotification('PersistentII')",
&script_result));
EXPECT_EQ("ok", script_result);
// Only the persistent ones should show.
ASSERT_TRUE(RunScript("GetDisplayedNotifications()", &script_result));
EXPECT_EQ("ok", script_result);
ASSERT_TRUE(RunScript("GetMessageFromWorker()", &script_message));
std::vector<std::string> notifications = base::SplitString(
script_message, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
ASSERT_EQ(2u, notifications.size());
// Now remove one of the notifications straight from the ui manager
// without going through the database.
const Notification& notification = ui_manager()->GetNotificationAt(1);
// p: is the prefix for persistent notifications. See
// content/browser/notifications/notification_id_generator.{h,cc} for details
ASSERT_TRUE(
base::StartsWith(notification.id(), "p:", base::CompareCase::SENSITIVE));
ASSERT_TRUE(ui_manager()->SilentDismissById(
notification.delegate_id(),
NotificationUIManager::GetProfileID(browser()->profile())));
ASSERT_TRUE(RunScript("GetDisplayedNotifications()", &script_result));
EXPECT_EQ("ok", script_result);
ASSERT_TRUE(RunScript("GetMessageFromWorker()", &script_message));
notifications = base::SplitString(script_message, ",", base::KEEP_WHITESPACE,
base::SPLIT_WANT_ALL);
ASSERT_EQ(1u, notifications.size());
}
IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
TestShouldDisplayNormal) {
ASSERT_NO_FATAL_FAILURE(GrantNotificationPermissionForTest());
EnableFullscreenNotifications();
std::string script_result;
ASSERT_TRUE(RunScript(
"DisplayPersistentNotification('display_normal')", &script_result));
EXPECT_EQ("ok", script_result);
ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
const Notification& notification = ui_manager()->GetNotificationAt(0);
EXPECT_FALSE(notification.delegate()->ShouldDisplayOverFullscreen());
}
IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
TestShouldDisplayFullscreen) {
#if defined(OS_MACOSX)
ui::test::ScopedFakeNSWindowFullscreen fake_fullscreen;
#endif
ASSERT_NO_FATAL_FAILURE(GrantNotificationPermissionForTest());
EnableFullscreenNotifications();
std::string script_result;
ASSERT_TRUE(RunScript(
"DisplayPersistentNotification('display_normal')", &script_result));
EXPECT_EQ("ok", script_result);
// Set the page fullscreen
browser()->exclusive_access_manager()->fullscreen_controller()->
ToggleBrowserFullscreenMode();
{
FullscreenStateWaiter fs_state(browser(), true);
fs_state.Wait();
}
ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
browser()->window()->GetNativeWindow()));
ASSERT_TRUE(browser()->window()->IsActive())
<< "Browser is active after going fullscreen";
ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
const Notification& notification = ui_manager()->GetNotificationAt(0);
EXPECT_TRUE(notification.delegate()->ShouldDisplayOverFullscreen());
}
IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
TestShouldDisplayFullscreenOff) {
#if defined(OS_MACOSX)
ui::test::ScopedFakeNSWindowFullscreen fake_fullscreen;
#endif
ASSERT_NO_FATAL_FAILURE(GrantNotificationPermissionForTest());
DisableFullscreenNotifications();
std::string script_result;
ASSERT_TRUE(RunScript(
"DisplayPersistentNotification('display_normal')", &script_result));
EXPECT_EQ("ok", script_result);
// Set the page fullscreen
browser()->exclusive_access_manager()->fullscreen_controller()->
ToggleBrowserFullscreenMode();
{
FullscreenStateWaiter fs_state(browser(), true);
fs_state.Wait();
}
ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
browser()->window()->GetNativeWindow()));
ASSERT_TRUE(browser()->window()->IsActive())
<< "Browser is active after going fullscreen";
ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
const Notification& notification = ui_manager()->GetNotificationAt(0);
// When the experiment flag is off, then ShouldDisplayOverFullscreen should
// return false.
EXPECT_FALSE(notification.delegate()->ShouldDisplayOverFullscreen());
}
// The Fake OSX fullscreen window doesn't like drawing a second fullscreen
// window when another is visible.
#if !defined(OS_MACOSX)
IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
TestShouldDisplayMultiFullscreen) {
ASSERT_NO_FATAL_FAILURE(GrantNotificationPermissionForTest());
EnableFullscreenNotifications();
Browser* other_browser = CreateBrowser(browser()->profile());
ui_test_utils::NavigateToURL(other_browser, GURL("about:blank"));
std::string script_result;
ASSERT_TRUE(RunScript(
"DisplayPersistentNotification('display_normal')", &script_result));
EXPECT_EQ("ok", script_result);
// Set the notifcation page fullscreen
browser()->exclusive_access_manager()->fullscreen_controller()->
ToggleBrowserFullscreenMode();
{
FullscreenStateWaiter fs_state(browser(), true);
fs_state.Wait();
}
// Set the other browser fullscreen
other_browser->exclusive_access_manager()->fullscreen_controller()->
ToggleBrowserFullscreenMode();
{
FullscreenStateWaiter fs_state(other_browser, true);
fs_state.Wait();
}
ASSERT_TRUE(browser()->exclusive_access_manager()->context()->IsFullscreen());
ASSERT_TRUE(
other_browser->exclusive_access_manager()->context()->IsFullscreen());
ASSERT_FALSE(browser()->window()->IsActive());
ASSERT_TRUE(other_browser->window()->IsActive());
ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
const Notification& notification = ui_manager()->GetNotificationAt(0);
EXPECT_FALSE(notification.delegate()->ShouldDisplayOverFullscreen());
}
#endif
class PlatformNotificationServiceWithoutContentImageBrowserTest
: public PlatformNotificationServiceBrowserTest {
public:
// InProcessBrowserTest overrides.
void SetUpInProcessBrowserTestFixture() override {
scoped_feature_list_.InitAndDisableFeature(
features::kNotificationContentImage);
InProcessBrowserTest::SetUpInProcessBrowserTestFixture();
}
private:
base::test::ScopedFeatureList scoped_feature_list_;
};
IN_PROC_BROWSER_TEST_F(
PlatformNotificationServiceWithoutContentImageBrowserTest,
KillSwitch) {
ASSERT_NO_FATAL_FAILURE(GrantNotificationPermissionForTest());
std::string script_result;
ASSERT_TRUE(
RunScript("DisplayPersistentAllOptionsNotification()", &script_result));
EXPECT_EQ("ok", script_result);
ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
const Notification& notification = ui_manager()->GetNotificationAt(0);
// Since the kNotificationContentImage kill switch has disabled images, the
// notification should be shown without an image.
EXPECT_TRUE(notification.image().IsEmpty());
}