Popular sites on the NTP: check that experiment group StartsWith (rather than IS...
[chromium-blink-merge.git] / chrome / browser / notifications / platform_notification_service_browsertest.cc
blobb90dec69f9830a3e9b01a21a9c1e65d13cf4ab10
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.
5 #include <string>
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/notifications/desktop_notification_profile_util.h"
13 #include "chrome/browser/notifications/notification_permission_context.h"
14 #include "chrome/browser/notifications/notification_permission_context_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/browser/ui/website_settings/permission_bubble_manager.h"
20 #include "chrome/test/base/in_process_browser_test.h"
21 #include "chrome/test/base/ui_test_utils.h"
22 #include "content/public/test/browser_test_utils.h"
23 #include "net/base/filename_util.h"
24 #include "net/test/spawned_test_server/spawned_test_server.h"
25 #include "testing/gmock/include/gmock/gmock.h"
27 // -----------------------------------------------------------------------------
29 // Dimensions of the icon.png resource in the notification test data directory.
30 const int kIconWidth = 100;
31 const int kIconHeight = 100;
33 const int kNotificationVibrationPattern[] = { 100, 200, 300 };
35 class PlatformNotificationServiceBrowserTest : public InProcessBrowserTest {
36 public:
37 PlatformNotificationServiceBrowserTest();
38 ~PlatformNotificationServiceBrowserTest() override {}
40 // InProcessBrowserTest overrides.
41 void SetUp() override;
42 void SetUpOnMainThread() override;
43 void TearDown() override;
45 protected:
46 // Returns the Platform Notification Service these unit tests are for.
47 PlatformNotificationServiceImpl* service() const {
48 return PlatformNotificationServiceImpl::GetInstance();
51 // Grants permission to display Web Notifications for origin of the test
52 // page that's being used in this browser test.
53 void GrantNotificationPermissionForTest() const;
55 bool RequestAndAcceptPermission();
56 bool RequestAndDenyPermission();
58 // Returns the UI Manager on which notifications will be displayed.
59 StubNotificationUIManager* ui_manager() const { return ui_manager_.get(); }
61 const base::FilePath& server_root() const { return server_root_; }
63 // Navigates the browser to the test page indicated by |path|.
64 void NavigateToTestPage(const std::string& path) const;
66 // Executes |script| and stores the result as a string in |result|. A boolean
67 // will be returned, indicating whether the script was executed successfully.
68 bool RunScript(const std::string& script, std::string* result) const;
70 net::HostPortPair ServerHostPort() const;
71 GURL TestPageUrl() const;
73 private:
74 std::string RequestAndRespondToPermission(
75 PermissionBubbleManager::AutoResponseType bubble_response);
77 content::WebContents* GetActiveWebContents(Browser* browser) {
78 return browser->tab_strip_model()->GetActiveWebContents();
81 const base::FilePath server_root_;
82 const std::string test_page_url_;
83 scoped_ptr<StubNotificationUIManager> ui_manager_;
84 scoped_ptr<net::SpawnedTestServer> https_server_;
87 // -----------------------------------------------------------------------------
89 namespace {
90 const char kTestFileName[] = "notifications/platform_notification_service.html";
93 PlatformNotificationServiceBrowserTest::PlatformNotificationServiceBrowserTest()
94 : server_root_(FILE_PATH_LITERAL("chrome/test/data")),
95 // The test server has a base directory that doesn't exist in the
96 // filesystem.
97 test_page_url_(std::string("files/") + kTestFileName) {
100 void PlatformNotificationServiceBrowserTest::SetUp() {
101 ui_manager_.reset(new StubNotificationUIManager);
102 https_server_.reset(new net::SpawnedTestServer(
103 net::SpawnedTestServer::TYPE_HTTPS,
104 net::BaseTestServer::SSLOptions(net::BaseTestServer::SSLOptions::CERT_OK),
105 server_root_));
106 ASSERT_TRUE(https_server_->Start());
108 service()->SetNotificationUIManagerForTesting(ui_manager_.get());
110 InProcessBrowserTest::SetUp();
113 void PlatformNotificationServiceBrowserTest::SetUpOnMainThread() {
114 NavigateToTestPage(test_page_url_);
116 InProcessBrowserTest::SetUpOnMainThread();
119 void PlatformNotificationServiceBrowserTest::TearDown() {
120 service()->SetNotificationUIManagerForTesting(nullptr);
123 void PlatformNotificationServiceBrowserTest::
124 GrantNotificationPermissionForTest() const {
125 GURL origin = TestPageUrl().GetOrigin();
127 DesktopNotificationProfileUtil::GrantPermission(browser()->profile(), origin);
128 ASSERT_EQ(CONTENT_SETTING_ALLOW,
129 DesktopNotificationProfileUtil::GetContentSetting(
130 browser()->profile(), origin));
133 void PlatformNotificationServiceBrowserTest::NavigateToTestPage(
134 const std::string& path) const {
135 ui_test_utils::NavigateToURL(browser(), https_server_->GetURL(path));
138 bool PlatformNotificationServiceBrowserTest::RunScript(
139 const std::string& script, std::string* result) const {
140 return content::ExecuteScriptAndExtractString(
141 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
142 script,
143 result);
146 net::HostPortPair PlatformNotificationServiceBrowserTest::ServerHostPort()
147 const {
148 return https_server_->host_port_pair();
151 GURL PlatformNotificationServiceBrowserTest::TestPageUrl() const {
152 return https_server_->GetURL(test_page_url_);
155 std::string
156 PlatformNotificationServiceBrowserTest::RequestAndRespondToPermission(
157 PermissionBubbleManager::AutoResponseType bubble_response) {
158 std::string result;
159 content::WebContents* web_contents = GetActiveWebContents(browser());
160 PermissionBubbleManager::FromWebContents(web_contents)
161 ->set_auto_response_for_test(bubble_response);
162 EXPECT_TRUE(RunScript("RequestPermission();", &result));
163 return result;
166 bool PlatformNotificationServiceBrowserTest::RequestAndAcceptPermission() {
167 std::string result =
168 RequestAndRespondToPermission(PermissionBubbleManager::ACCEPT_ALL);
169 return "granted" == result;
172 bool PlatformNotificationServiceBrowserTest::RequestAndDenyPermission() {
173 std::string result =
174 RequestAndRespondToPermission(PermissionBubbleManager::DENY_ALL);
175 return "denied" == result;
178 // -----------------------------------------------------------------------------
180 // TODO(peter): Move PlatformNotificationService-related tests over from
181 // notification_browsertest.cc to this file.
183 IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
184 DisplayPersistentNotificationWithoutPermission) {
185 RequestAndDenyPermission();
187 std::string script_result;
188 ASSERT_TRUE(RunScript("DisplayPersistentNotification()", &script_result));
189 EXPECT_EQ(
190 "TypeError: No notification permission has been granted for this origin.",
191 script_result);
193 ASSERT_EQ(0u, ui_manager()->GetNotificationCount());
196 IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
197 DisplayPersistentNotificationWithPermission) {
198 RequestAndAcceptPermission();
200 std::string script_result;
201 ASSERT_TRUE(RunScript("DisplayPersistentNotification('action_none')",
202 &script_result));
203 EXPECT_EQ("ok", script_result);
205 ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
207 const Notification& notification = ui_manager()->GetNotificationAt(0);
208 notification.delegate()->Click();
210 ASSERT_TRUE(RunScript("GetMessageFromWorker()", &script_result));
211 EXPECT_EQ("action_none", script_result);
213 ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
216 IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
217 WebNotificationOptionsReflection) {
218 ASSERT_NO_FATAL_FAILURE(GrantNotificationPermissionForTest());
220 std::string script_result;
221 ASSERT_TRUE(RunScript("DisplayPersistentAllOptionsNotification()",
222 &script_result));
223 EXPECT_EQ("ok", script_result);
225 ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
227 // We don't use or check the notification's direction and language.
228 const Notification& notification = ui_manager()->GetNotificationAt(0);
229 EXPECT_EQ("Title", base::UTF16ToUTF8(notification.title()));
230 EXPECT_EQ("Contents", base::UTF16ToUTF8(notification.message()));
231 EXPECT_EQ("replace-id", notification.tag());
232 EXPECT_FALSE(notification.icon().IsEmpty());
233 EXPECT_TRUE(notification.silent());
235 EXPECT_EQ(kIconWidth, notification.icon().Width());
236 EXPECT_EQ(kIconHeight, notification.icon().Height());
239 IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
240 WebNotificationOptionsVibrationPattern) {
241 ASSERT_NO_FATAL_FAILURE(GrantNotificationPermissionForTest());
243 std::string script_result;
244 ASSERT_TRUE(RunScript("DisplayPersistentNotificationVibrate()",
245 &script_result));
246 EXPECT_EQ("ok", script_result);
248 ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
250 const Notification& notification = ui_manager()->GetNotificationAt(0);
251 EXPECT_EQ("Title", base::UTF16ToUTF8(notification.title()));
252 EXPECT_EQ("Contents", base::UTF16ToUTF8(notification.message()));
254 EXPECT_THAT(notification.vibration_pattern(),
255 testing::ElementsAreArray(kNotificationVibrationPattern));
258 IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
259 CloseDisplayedPersistentNotification) {
260 ASSERT_NO_FATAL_FAILURE(GrantNotificationPermissionForTest());
262 std::string script_result;
263 ASSERT_TRUE(RunScript("DisplayPersistentNotification('action_close')",
264 &script_result));
265 EXPECT_EQ("ok", script_result);
267 ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
269 const Notification& notification = ui_manager()->GetNotificationAt(0);
270 notification.delegate()->Click();
272 ASSERT_TRUE(RunScript("GetMessageFromWorker()", &script_result));
273 EXPECT_EQ("action_close", script_result);
275 ASSERT_EQ(0u, ui_manager()->GetNotificationCount());
278 IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
279 TestDisplayOriginContextMessage) {
280 RequestAndAcceptPermission();
282 // Creates a simple notification.
283 std::string script_result;
284 ASSERT_TRUE(RunScript("DisplayPersistentNotification()", &script_result));
286 net::HostPortPair host_port = ServerHostPort();
288 const Notification& notification = ui_manager()->GetNotificationAt(0);
290 EXPECT_TRUE(notification.context_message().empty());
291 EXPECT_EQ("https://" + host_port.ToString() + "/",
292 notification.origin_url().spec());
295 IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
296 CheckFilePermissionNotGranted) {
297 // TODO(felt): This DCHECKs when bubbles are enabled, when the file_url is
298 // persisted. crbug.com/502057
299 if (PermissionBubbleManager::Enabled())
300 return;
302 // TODO(dewittj): It currently isn't possible to get the notification
303 // permission for a file:// URL. If that changes, this test will fail to
304 // remind the author that the
305 // |PlatformNotificationServiceImpl::WebOriginDisplayName| function needs
306 // to be updated to properly display file:// URL origins.
307 // See crbug.com/402191.
309 // This case should succeed because a normal page URL is used.
310 std::string script_result;
312 NotificationPermissionContext* permission_context =
313 NotificationPermissionContextFactory::GetForProfile(browser()->profile());
314 ASSERT_TRUE(permission_context);
316 EXPECT_EQ(CONTENT_SETTING_ASK,
317 permission_context->GetPermissionStatus(TestPageUrl(),
318 TestPageUrl()));
320 RequestAndAcceptPermission();
321 EXPECT_EQ(CONTENT_SETTING_ALLOW,
322 permission_context->GetPermissionStatus(TestPageUrl(),
323 TestPageUrl()));
325 // This case should fail because a file URL is used.
326 base::FilePath dir_source_root;
327 EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &dir_source_root));
328 base::FilePath full_file_path =
329 dir_source_root.Append(server_root()).AppendASCII(kTestFileName);
330 GURL file_url(net::FilePathToFileURL(full_file_path));
332 ui_test_utils::NavigateToURL(browser(), file_url);
334 EXPECT_EQ(CONTENT_SETTING_ASK,
335 permission_context->GetPermissionStatus(file_url, file_url));
337 RequestAndAcceptPermission();
338 EXPECT_EQ(CONTENT_SETTING_ASK,
339 permission_context->GetPermissionStatus(file_url, file_url))
340 << "If this test fails, you may have fixed a bug preventing file origins "
341 << "from sending their origin from Blink; if so you need to update the "
342 << "display function for notification origins to show the file path.";
345 IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
346 DataUrlAsNotificationImage) {
347 ASSERT_NO_FATAL_FAILURE(GrantNotificationPermissionForTest());
349 std::string script_result;
350 ASSERT_TRUE(RunScript("DisplayPersistentNotificationDataUrlImage()",
351 &script_result));
352 EXPECT_EQ("ok", script_result);
354 ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
356 const Notification& notification = ui_manager()->GetNotificationAt(0);
357 EXPECT_FALSE(notification.icon().IsEmpty());
359 EXPECT_EQ("Data URL Title", base::UTF16ToUTF8(notification.title()));
360 EXPECT_EQ(kIconWidth, notification.icon().Width());
361 EXPECT_EQ(kIconHeight, notification.icon().Height());
364 IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
365 BlobAsNotificationImage) {
366 ASSERT_NO_FATAL_FAILURE(GrantNotificationPermissionForTest());
368 std::string script_result;
369 ASSERT_TRUE(RunScript("DisplayPersistentNotificationBlobImage()",
370 &script_result));
371 EXPECT_EQ("ok", script_result);
373 ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
375 const Notification& notification = ui_manager()->GetNotificationAt(0);
376 EXPECT_FALSE(notification.icon().IsEmpty());
378 EXPECT_EQ("Blob Title", base::UTF16ToUTF8(notification.title()));
379 EXPECT_EQ(kIconWidth, notification.icon().Width());
380 EXPECT_EQ(kIconHeight, notification.icon().Height());