[Eraser strings] Remove unused Supervised User infobar and corresponding strings
[chromium-blink-merge.git] / chrome / browser / notifications / platform_notification_service_unittest.cc
blob7c4542a4a2e12ecc2657c5b0ab04b8e45e4ccd84
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 "base/strings/utf_string_conversions.h"
6 #include "base/threading/platform_thread.h"
7 #include "base/time/time.h"
8 #include "chrome/browser/notifications/notification_test_util.h"
9 #include "chrome/browser/notifications/platform_notification_service_impl.h"
10 #include "chrome/test/base/testing_profile.h"
11 #include "components/content_settings/core/browser/host_content_settings_map.h"
12 #include "content/public/browser/desktop_notification_delegate.h"
13 #include "content/public/common/platform_notification_data.h"
14 #include "content/public/test/test_browser_thread_bundle.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "third_party/skia/include/core/SkBitmap.h"
19 #if defined(ENABLE_EXTENSIONS)
20 #include "base/command_line.h"
21 #include "chrome/browser/extensions/extension_service.h"
22 #include "chrome/browser/extensions/test_extension_system.h"
23 #include "extensions/browser/extension_registry.h"
24 #include "extensions/browser/process_map.h"
25 #include "extensions/common/extension.h"
26 #include "extensions/common/extension_builder.h"
27 #include "extensions/common/permissions/api_permission.h"
28 #include "extensions/common/value_builder.h"
29 #endif
31 #if defined(ENABLE_EXTENSIONS) && defined(OS_CHROMEOS)
32 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
33 #include "chrome/browser/chromeos/settings/cros_settings.h"
34 #include "chrome/browser/chromeos/settings/device_settings_service.h"
35 #endif
37 namespace {
39 const int kNotificationVibrationPattern[] = { 100, 200, 300 };
41 #if !defined(OS_ANDROID)
42 const int64_t kPersistentNotificationId = 42;
43 #endif
45 class MockDesktopNotificationDelegate
46 : public content::DesktopNotificationDelegate {
47 public:
48 MockDesktopNotificationDelegate()
49 : displayed_(false),
50 clicked_(false) {}
52 ~MockDesktopNotificationDelegate() override {}
54 // content::DesktopNotificationDelegate implementation.
55 void NotificationDisplayed() override { displayed_ = true; }
56 void NotificationClosed() override {}
57 void NotificationClick() override { clicked_ = true; }
59 bool displayed() const { return displayed_; }
60 bool clicked() const { return clicked_; }
62 private:
63 bool displayed_;
64 bool clicked_;
67 } // namespace
69 class PlatformNotificationServiceTest : public testing::Test {
70 public:
71 void SetUp() override {
72 ui_manager_.reset(new StubNotificationUIManager);
73 profile_.reset(new TestingProfile());
75 service()->SetNotificationUIManagerForTesting(ui_manager_.get());
78 void TearDown() override {
79 service()->SetNotificationUIManagerForTesting(nullptr);
81 profile_.reset();
82 ui_manager_.reset();
85 protected:
86 // Displays a simple, fake notifications and returns a weak pointer to the
87 // delegate receiving events for it (ownership is transferred to the service).
88 MockDesktopNotificationDelegate* CreateSimplePageNotification() const {
89 return CreateSimplePageNotificationWithCloseClosure(nullptr);
92 // Displays a simple, fake notification and returns a weak pointer to the
93 // delegate receiving events for it (ownership is transferred to the service).
94 // The close closure may be specified if so desired.
95 MockDesktopNotificationDelegate* CreateSimplePageNotificationWithCloseClosure(
96 base::Closure* close_closure) const {
97 content::PlatformNotificationData notification_data;
98 notification_data.title = base::ASCIIToUTF16("My Notification");
99 notification_data.body = base::ASCIIToUTF16("Hello, world!");
101 MockDesktopNotificationDelegate* delegate =
102 new MockDesktopNotificationDelegate();
104 service()->DisplayNotification(profile(),
105 GURL("https://chrome.com/"),
106 SkBitmap(),
107 notification_data,
108 make_scoped_ptr(delegate),
109 close_closure);
111 return delegate;
114 // Returns the Platform Notification Service these unit tests are for.
115 PlatformNotificationServiceImpl* service() const {
116 return PlatformNotificationServiceImpl::GetInstance();
119 // Returns the Profile to be used for these tests.
120 Profile* profile() const { return profile_.get(); }
122 // Returns the UI Manager on which notifications will be displayed.
123 StubNotificationUIManager* ui_manager() const { return ui_manager_.get(); }
125 private:
126 scoped_ptr<StubNotificationUIManager> ui_manager_;
127 scoped_ptr<TestingProfile> profile_;
129 content::TestBrowserThreadBundle thread_bundle_;
132 TEST_F(PlatformNotificationServiceTest, DisplayPageDisplayedEvent) {
133 auto* delegate = CreateSimplePageNotification();
135 EXPECT_EQ(1u, ui_manager()->GetNotificationCount());
136 EXPECT_TRUE(delegate->displayed());
139 TEST_F(PlatformNotificationServiceTest, DisplayPageCloseClosure) {
140 base::Closure close_closure;
141 CreateSimplePageNotificationWithCloseClosure(&close_closure);
143 EXPECT_EQ(1u, ui_manager()->GetNotificationCount());
145 ASSERT_FALSE(close_closure.is_null());
146 close_closure.Run();
148 EXPECT_EQ(0u, ui_manager()->GetNotificationCount());
150 // Note that we cannot verify whether the closed event was called on the
151 // delegate given that it'd result in a use-after-free.
154 // TODO(peter): Re-enable this test when //content is responsible for creating
155 // the notification delegate ids.
156 #if !defined(OS_ANDROID)
157 TEST_F(PlatformNotificationServiceTest, PersistentNotificationDisplay) {
158 content::PlatformNotificationData notification_data;
159 notification_data.title = base::ASCIIToUTF16("My notification's title");
160 notification_data.body = base::ASCIIToUTF16("Hello, world!");
162 service()->DisplayPersistentNotification(
163 profile(), kPersistentNotificationId, GURL("https://chrome.com/"),
164 SkBitmap(), notification_data);
166 ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
168 const Notification& notification = ui_manager()->GetNotificationAt(0);
169 EXPECT_EQ("https://chrome.com/", notification.origin_url().spec());
170 EXPECT_EQ("My notification's title",
171 base::UTF16ToUTF8(notification.title()));
172 EXPECT_EQ("Hello, world!",
173 base::UTF16ToUTF8(notification.message()));
175 service()->ClosePersistentNotification(profile(), kPersistentNotificationId);
176 EXPECT_EQ(0u, ui_manager()->GetNotificationCount());
178 #endif // !defined(OS_ANDROID)
180 TEST_F(PlatformNotificationServiceTest, DisplayPageNotificationMatches) {
181 std::vector<int> vibration_pattern(
182 kNotificationVibrationPattern,
183 kNotificationVibrationPattern + arraysize(kNotificationVibrationPattern));
185 content::PlatformNotificationData notification_data;
186 notification_data.title = base::ASCIIToUTF16("My notification's title");
187 notification_data.body = base::ASCIIToUTF16("Hello, world!");
188 notification_data.vibration_pattern = vibration_pattern;
189 notification_data.silent = true;
190 notification_data.actions.resize(2);
191 notification_data.actions[0].title = base::ASCIIToUTF16("Button 1");
192 notification_data.actions[1].title = base::ASCIIToUTF16("Button 2");
194 MockDesktopNotificationDelegate* delegate
195 = new MockDesktopNotificationDelegate();
196 service()->DisplayNotification(profile(),
197 GURL("https://chrome.com/"),
198 SkBitmap(),
199 notification_data,
200 make_scoped_ptr(delegate),
201 nullptr);
203 ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
205 const Notification& notification = ui_manager()->GetNotificationAt(0);
206 EXPECT_EQ("https://chrome.com/", notification.origin_url().spec());
207 EXPECT_EQ("My notification's title",
208 base::UTF16ToUTF8(notification.title()));
209 EXPECT_EQ("Hello, world!",
210 base::UTF16ToUTF8(notification.message()));
212 EXPECT_THAT(notification.vibration_pattern(),
213 testing::ElementsAreArray(kNotificationVibrationPattern));
215 EXPECT_TRUE(notification.silent());
217 const auto& buttons = notification.buttons();
218 ASSERT_EQ(2u, buttons.size());
219 EXPECT_EQ("Button 1", base::UTF16ToUTF8(buttons[0].title));
220 EXPECT_EQ("Button 2", base::UTF16ToUTF8(buttons[1].title));
223 TEST_F(PlatformNotificationServiceTest, DisplayNameForOrigin) {
224 base::string16 display_name =
225 service()->DisplayNameForOrigin(profile(), GURL("https://chrome.com/"));
227 EXPECT_EQ(base::ASCIIToUTF16("chrome.com"), display_name);
229 // TODO(peter): Include unit tests for the extension-name translation
230 // functionality of DisplayNameForOriginInProcessId.
233 TEST_F(PlatformNotificationServiceTest, TestWebOriginDisplayName) {
234 std::string language("en-us");
236 GURL https_origin("https://mail.google.com/");
237 base::string16 expected_display_name = base::ASCIIToUTF16("mail.google.com");
238 EXPECT_EQ(expected_display_name,
239 PlatformNotificationServiceImpl::WebOriginDisplayName(https_origin,
240 language));
242 GURL https_origin_standard_port("https://mail.google.com:443/");
243 expected_display_name = base::ASCIIToUTF16("mail.google.com");
244 EXPECT_EQ(expected_display_name,
245 PlatformNotificationServiceImpl::WebOriginDisplayName(
246 https_origin_standard_port, language));
248 GURL https_origin_nonstandard_port("https://mail.google.com:444/");
249 expected_display_name = base::ASCIIToUTF16("mail.google.com:444");
250 EXPECT_EQ(expected_display_name,
251 PlatformNotificationServiceImpl::WebOriginDisplayName(
252 https_origin_nonstandard_port, language));
254 GURL http_origin("http://mail.google.com/");
255 expected_display_name = base::ASCIIToUTF16("http://mail.google.com");
256 EXPECT_EQ(expected_display_name,
257 PlatformNotificationServiceImpl::WebOriginDisplayName(http_origin,
258 language));
260 GURL http_origin_standard_port("http://mail.google.com:80/");
261 expected_display_name = base::ASCIIToUTF16("http://mail.google.com");
262 EXPECT_EQ(expected_display_name,
263 PlatformNotificationServiceImpl::WebOriginDisplayName(
264 http_origin_standard_port, language));
266 GURL http_origin_nonstandard_port("http://mail.google.com:81/");
267 expected_display_name = base::ASCIIToUTF16("http://mail.google.com:81");
268 EXPECT_EQ(expected_display_name,
269 PlatformNotificationServiceImpl::WebOriginDisplayName(
270 http_origin_nonstandard_port, language));
271 // TODO(dewittj): Add file origin once it's supported.
274 TEST_F(PlatformNotificationServiceTest, NotificationPermissionLastUsage) {
275 // Both page and persistent notifications should update the last usage
276 // time of the notification permission for the origin.
277 GURL origin("https://chrome.com/");
278 base::Time begin_time;
280 CreateSimplePageNotification();
282 base::Time after_page_notification =
283 profile()->GetHostContentSettingsMap()->GetLastUsage(
284 origin, origin, CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
285 EXPECT_GT(after_page_notification, begin_time);
287 // Ensure that there is at least some time between the two calls.
288 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
290 service()->DisplayPersistentNotification(
291 profile(), 42 /* sw_registration_id */, origin, SkBitmap(),
292 content::PlatformNotificationData());
294 base::Time after_persistent_notification =
295 profile()->GetHostContentSettingsMap()->GetLastUsage(
296 origin, origin, CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
297 EXPECT_GT(after_persistent_notification, after_page_notification);
300 #if defined(ENABLE_EXTENSIONS)
302 TEST_F(PlatformNotificationServiceTest, ExtensionPermissionChecks) {
303 #if defined(OS_CHROMEOS)
304 // The ExtensionService on Chrome OS requires these objects to be initialized.
305 chromeos::ScopedTestDeviceSettingsService test_device_settings_service;
306 chromeos::ScopedTestCrosSettings test_cros_settings;
307 chromeos::ScopedTestUserManager test_user_manager;
308 #endif
310 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
311 extensions::TestExtensionSystem* test_extension_system =
312 static_cast<extensions::TestExtensionSystem*>(
313 extensions::ExtensionSystem::Get(profile()));
315 ExtensionService* extension_service =
316 test_extension_system->CreateExtensionService(
317 &command_line, base::FilePath() /* install_directory */,
318 false /* autoupdate_enabled*/);
320 // Create a mocked extension that has the notifications API permission.
321 scoped_refptr<extensions::Extension> extension =
322 extensions::ExtensionBuilder().SetManifest(
323 extensions::DictionaryBuilder()
324 .Set("name", "NotificationTest")
325 .Set("version", "1.0")
326 .Set("manifest_version", 2)
327 .Set("description", "Test Extension")
328 .Set("permissions",
329 extensions::ListBuilder().Append("notifications"))).Build();
331 // Install the extension on the faked extension service, and verify that it
332 // has been added to the extension registry successfully.
333 extension_service->AddExtension(extension.get());
334 extensions::ExtensionRegistry* registry =
335 extensions::ExtensionRegistry::Get(profile());
337 ASSERT_TRUE(registry->GetExtensionById(
338 extension->id(), extensions::ExtensionRegistry::ENABLED));
340 const int kFakeRenderProcessId = 42;
342 // Mock that the extension is running in a fake render process id.
343 extensions::ProcessMap::Get(profile())->Insert(extension->id(),
344 kFakeRenderProcessId,
345 -1 /* site_instance_id */);
347 // Verify that the service indicates that permission has been granted. We only
348 // check the UI thread-method for now, as that's the one guarding the behavior
349 // in the browser process.
350 EXPECT_EQ(blink::WebNotificationPermissionAllowed,
351 service()->CheckPermissionOnUIThread(profile(),
352 extension->url(),
353 kFakeRenderProcessId));
356 #endif // defined(ENABLE_EXTENSIONS)