1 // Copyright 2014 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.
7 #include "base/command_line.h"
8 #include "base/files/file_path.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/path_service.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/infobars/infobar_service.h"
13 #include "chrome/browser/notifications/desktop_notification_service.h"
14 #include "chrome/browser/notifications/desktop_notification_service_factory.h"
15 #include "chrome/browser/notifications/notification_test_util.h"
16 #include "chrome/browser/notifications/platform_notification_service_impl.h"
17 #include "chrome/browser/ui/browser.h"
18 #include "chrome/browser/ui/tabs/tab_strip_model.h"
19 #include "chrome/test/base/in_process_browser_test.h"
20 #include "chrome/test/base/ui_test_utils.h"
21 #include "components/infobars/core/confirm_infobar_delegate.h"
22 #include "components/infobars/core/infobar.h"
23 #include "components/infobars/core/infobar_manager.h"
24 #include "content/public/test/browser_test_utils.h"
25 #include "net/base/filename_util.h"
26 #include "net/test/spawned_test_server/spawned_test_server.h"
28 // -----------------------------------------------------------------------------
30 // Accept or rejects the first shown confirm infobar. The infobar will be
31 // responsed to asynchronously, to imitate the behavior of a user.
32 // TODO(peter): Generalize this class, as it's commonly useful.
33 class InfoBarResponder
: public infobars::InfoBarManager::Observer
{
35 InfoBarResponder(Browser
* browser
, bool accept
);
36 ~InfoBarResponder() override
;
38 // infobars::InfoBarManager::Observer overrides.
39 void OnInfoBarAdded(infobars::InfoBar
* infobar
) override
;
42 void Respond(ConfirmInfoBarDelegate
* delegate
);
44 InfoBarService
* infobar_service_
;
49 InfoBarResponder::InfoBarResponder(Browser
* browser
, bool accept
)
50 : infobar_service_(InfoBarService::FromWebContents(
51 browser
->tab_strip_model()->GetActiveWebContents())),
53 has_observed_(false) {
54 infobar_service_
->AddObserver(this);
57 InfoBarResponder::~InfoBarResponder() {
58 infobar_service_
->RemoveObserver(this);
61 void InfoBarResponder::OnInfoBarAdded(infobars::InfoBar
* infobar
) {
66 ConfirmInfoBarDelegate
* delegate
=
67 infobar
->delegate()->AsConfirmInfoBarDelegate();
70 // Respond to the infobar asynchronously, like a person.
71 base::MessageLoop::current()->PostTask(
74 &InfoBarResponder::Respond
, base::Unretained(this), delegate
));
77 void InfoBarResponder::Respond(ConfirmInfoBarDelegate
* delegate
) {
84 // -----------------------------------------------------------------------------
86 class PlatformNotificationServiceBrowserTest
: public InProcessBrowserTest
{
88 PlatformNotificationServiceBrowserTest();
89 ~PlatformNotificationServiceBrowserTest() override
{}
91 // InProcessBrowserTest overrides.
92 void SetUp() override
;
93 void SetUpOnMainThread() override
;
94 void TearDown() override
;
97 // Returns the Platform Notification Service these unit tests are for.
98 PlatformNotificationServiceImpl
* service() const {
99 return PlatformNotificationServiceImpl::GetInstance();
102 // Returns the UI Manager on which notifications will be displayed.
103 StubNotificationUIManager
* ui_manager() const { return ui_manager_
.get(); }
105 const base::FilePath
& server_root() const { return server_root_
; }
107 // Navigates the browser to the test page indicated by |path|.
108 void NavigateToTestPage(const std::string
& path
) const;
110 // Executes |script| and stores the result as a string in |result|. A boolean
111 // will be returned, indicating whether the script was executed successfully.
112 bool RunScript(const std::string
& script
, std::string
* result
) const;
114 net::HostPortPair
ServerHostPort() const;
115 GURL
TestPageUrl() const;
118 const base::FilePath server_root_
;
119 const std::string test_page_url_
;
120 scoped_ptr
<StubNotificationUIManager
> ui_manager_
;
121 scoped_ptr
<net::SpawnedTestServer
> https_server_
;
124 // -----------------------------------------------------------------------------
127 const char kTestFileName
[] = "notifications/platform_notification_service.html";
130 PlatformNotificationServiceBrowserTest::PlatformNotificationServiceBrowserTest()
131 : server_root_(FILE_PATH_LITERAL("chrome/test/data")),
132 // The test server has a base directory that doesn't exist in the
134 test_page_url_(std::string("files/") + kTestFileName
) {
137 void PlatformNotificationServiceBrowserTest::SetUp() {
138 ui_manager_
.reset(new StubNotificationUIManager
);
139 https_server_
.reset(new net::SpawnedTestServer(
140 net::SpawnedTestServer::TYPE_HTTPS
,
141 net::BaseTestServer::SSLOptions(net::BaseTestServer::SSLOptions::CERT_OK
),
143 ASSERT_TRUE(https_server_
->Start());
145 service()->SetNotificationUIManagerForTesting(ui_manager_
.get());
147 InProcessBrowserTest::SetUp();
150 void PlatformNotificationServiceBrowserTest::SetUpOnMainThread() {
151 NavigateToTestPage(test_page_url_
);
153 InProcessBrowserTest::SetUpOnMainThread();
156 void PlatformNotificationServiceBrowserTest::TearDown() {
157 service()->SetNotificationUIManagerForTesting(nullptr);
160 void PlatformNotificationServiceBrowserTest::NavigateToTestPage(
161 const std::string
& path
) const {
162 ui_test_utils::NavigateToURL(browser(), https_server_
->GetURL(path
));
165 bool PlatformNotificationServiceBrowserTest::RunScript(
166 const std::string
& script
, std::string
* result
) const {
167 return content::ExecuteScriptAndExtractString(
168 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
173 net::HostPortPair
PlatformNotificationServiceBrowserTest::ServerHostPort()
175 return https_server_
->host_port_pair();
178 GURL
PlatformNotificationServiceBrowserTest::TestPageUrl() const {
179 return https_server_
->GetURL(test_page_url_
);
182 // -----------------------------------------------------------------------------
184 // TODO(peter): Move PlatformNotificationService-related tests over from
185 // notification_browsertest.cc to this file.
187 IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest
,
188 DisplayPersistentNotificationWithoutPermission
) {
189 std::string script_result
;
191 InfoBarResponder
accepting_responder(browser(), false);
192 ASSERT_TRUE(RunScript("RequestPermission()", &script_result
));
193 EXPECT_EQ("denied", script_result
);
195 ASSERT_TRUE(RunScript("DisplayPersistentNotification()", &script_result
));
197 "TypeError: No notification permission has been granted for this origin.",
200 ASSERT_EQ(0u, ui_manager()->GetNotificationCount());
203 IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest
,
204 DisplayPersistentNotificationWithPermission
) {
205 std::string script_result
;
207 InfoBarResponder
accepting_responder(browser(), true);
208 ASSERT_TRUE(RunScript("RequestPermission()", &script_result
));
209 EXPECT_EQ("granted", script_result
);
211 ASSERT_TRUE(RunScript("DisplayPersistentNotification('action_none')",
213 EXPECT_EQ("ok", script_result
);
215 ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
217 const Notification
& notification
= ui_manager()->GetNotificationAt(0);
218 notification
.delegate()->Click();
220 ASSERT_TRUE(RunScript("GetMessageFromWorker()", &script_result
));
221 EXPECT_EQ("action_none", script_result
);
223 ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
226 IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest
,
227 CloseDisplayedPersistentNotification
) {
228 std::string script_result
;
230 InfoBarResponder
accepting_responder(browser(), true);
231 ASSERT_TRUE(RunScript("RequestPermission()", &script_result
));
232 EXPECT_EQ("granted", script_result
);
234 ASSERT_TRUE(RunScript("DisplayPersistentNotification('action_close')",
236 EXPECT_EQ("ok", script_result
);
238 ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
240 const Notification
& notification
= ui_manager()->GetNotificationAt(0);
241 notification
.delegate()->Click();
243 ASSERT_TRUE(RunScript("GetMessageFromWorker()", &script_result
));
244 EXPECT_EQ("action_close", script_result
);
246 ASSERT_EQ(0u, ui_manager()->GetNotificationCount());
249 IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest
,
250 TestDisplayOriginContextMessage
) {
251 std::string script_result
;
253 // Creates a simple notification.
254 InfoBarResponder
accepting_responder(browser(), true);
255 ASSERT_TRUE(RunScript("RequestPermission()", &script_result
));
256 ASSERT_EQ("granted", script_result
);
257 ASSERT_TRUE(RunScript("DisplayPersistentNotification()", &script_result
));
259 net::HostPortPair host_port
= ServerHostPort();
261 const Notification
& notification
= ui_manager()->GetNotificationAt(0);
263 EXPECT_EQ(base::UTF8ToUTF16(host_port
.ToString()),
264 notification
.context_message());
267 IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest
,
268 CheckFilePermissionNotGranted
) {
269 // TODO(dewittj): This test verifies that a bug exists in Chrome; the test
270 // will fail if the bug is fixed. The
271 // |PlatformNotificationServiceImpl::WebOriginDisplayName| function needs
272 // to be updated to properly display file:// URL origins.
273 // See crbug.com/402191.
274 std::string script_result
;
276 InfoBarResponder
accepting_responder_web(browser(), true);
278 DesktopNotificationService
* notification_service
=
279 DesktopNotificationServiceFactory::GetForProfile(browser()->profile());
280 ASSERT_TRUE(notification_service
);
281 message_center::NotifierId
web_notifier(TestPageUrl());
282 EXPECT_FALSE(notification_service
->IsNotifierEnabled(web_notifier
));
283 ASSERT_TRUE(RunScript("RequestPermission()", &script_result
));
284 EXPECT_EQ("granted", script_result
);
286 EXPECT_TRUE(notification_service
->IsNotifierEnabled(web_notifier
));
288 base::FilePath dir_source_root
;
289 EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT
, &dir_source_root
));
290 base::FilePath full_file_path
=
291 dir_source_root
.Append(server_root()).AppendASCII(kTestFileName
);
292 GURL
file_url(net::FilePathToFileURL(full_file_path
));
293 ui_test_utils::NavigateToURL(browser(), file_url
);
295 message_center::NotifierId
file_notifier(file_url
);
296 EXPECT_FALSE(notification_service
->IsNotifierEnabled(file_notifier
));
298 InfoBarResponder
accepting_responder_file(browser(), true);
299 ASSERT_TRUE(RunScript("RequestPermission()", &script_result
));
300 EXPECT_EQ("granted", script_result
);
302 EXPECT_FALSE(notification_service
->IsNotifierEnabled(file_notifier
))
303 << "If this test fails, you may have fixed a bug preventing file origins "
304 << "from sending their origin from Blink; if so you need to update the "
305 << "display function for notification origins to show the file path.";