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/gtest/include/gtest/gtest.h"
16 #include "third_party/skia/include/core/SkBitmap.h"
20 class MockDesktopNotificationDelegate
21 : public content::DesktopNotificationDelegate
{
23 MockDesktopNotificationDelegate()
27 ~MockDesktopNotificationDelegate() override
{}
29 // content::DesktopNotificationDelegate implementation.
30 void NotificationDisplayed() override
{ displayed_
= true; }
31 void NotificationClosed() override
{}
32 void NotificationClick() override
{ clicked_
= true; }
34 bool displayed() const { return displayed_
; }
35 bool clicked() const { return clicked_
; }
44 class PlatformNotificationServiceTest
: public testing::Test
{
46 void SetUp() override
{
47 ui_manager_
.reset(new StubNotificationUIManager
);
48 profile_
.reset(new TestingProfile());
50 service()->SetNotificationUIManagerForTesting(ui_manager_
.get());
53 void TearDown() override
{
54 service()->SetNotificationUIManagerForTesting(nullptr);
61 // Displays a simple, fake notifications and returns a weak pointer to the
62 // delegate receiving events for it (ownership is transferred to the service).
63 MockDesktopNotificationDelegate
* CreateSimplePageNotification() const {
64 return CreateSimplePageNotificationWithCloseClosure(nullptr);
67 // Displays a simple, fake notification and returns a weak pointer to the
68 // delegate receiving events for it (ownership is transferred to the service).
69 // The close closure may be specified if so desired.
70 MockDesktopNotificationDelegate
* CreateSimplePageNotificationWithCloseClosure(
71 base::Closure
* close_closure
) const {
72 content::PlatformNotificationData notification_data
;
73 notification_data
.title
= base::ASCIIToUTF16("My Notification");
74 notification_data
.body
= base::ASCIIToUTF16("Hello, world!");
76 MockDesktopNotificationDelegate
* delegate
=
77 new MockDesktopNotificationDelegate();
79 service()->DisplayNotification(profile(),
80 GURL("https://chrome.com/"),
83 make_scoped_ptr(delegate
),
89 // Returns the Platform Notification Service these unit tests are for.
90 PlatformNotificationServiceImpl
* service() const {
91 return PlatformNotificationServiceImpl::GetInstance();
94 // Returns the Profile to be used for these tests.
95 Profile
* profile() const { return profile_
.get(); }
97 // Returns the UI Manager on which notifications will be displayed.
98 StubNotificationUIManager
* ui_manager() const { return ui_manager_
.get(); }
101 scoped_ptr
<StubNotificationUIManager
> ui_manager_
;
102 scoped_ptr
<TestingProfile
> profile_
;
104 content::TestBrowserThreadBundle thread_bundle_
;
107 TEST_F(PlatformNotificationServiceTest
, DisplayPageDisplayedEvent
) {
108 auto* delegate
= CreateSimplePageNotification();
110 EXPECT_EQ(1u, ui_manager()->GetNotificationCount());
111 EXPECT_TRUE(delegate
->displayed());
114 TEST_F(PlatformNotificationServiceTest
, DisplayPageCloseClosure
) {
115 base::Closure close_closure
;
116 CreateSimplePageNotificationWithCloseClosure(&close_closure
);
118 EXPECT_EQ(1u, ui_manager()->GetNotificationCount());
120 ASSERT_FALSE(close_closure
.is_null());
123 EXPECT_EQ(0u, ui_manager()->GetNotificationCount());
125 // Note that we cannot verify whether the closed event was called on the
126 // delegate given that it'd result in a use-after-free.
129 TEST_F(PlatformNotificationServiceTest
, PersistentNotificationDisplay
) {
130 content::PlatformNotificationData notification_data
;
131 notification_data
.title
= base::ASCIIToUTF16("My notification's title");
132 notification_data
.body
= base::ASCIIToUTF16("Hello, world!");
134 service()->DisplayPersistentNotification(
135 profile(), 42 /* sw_registration_id */, GURL("https://chrome.com/"),
136 SkBitmap(), notification_data
);
138 ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
140 const Notification
& notification
= ui_manager()->GetNotificationAt(0);
141 EXPECT_EQ("https://chrome.com/", notification
.origin_url().spec());
142 EXPECT_EQ("My notification's title",
143 base::UTF16ToUTF8(notification
.title()));
144 EXPECT_EQ("Hello, world!",
145 base::UTF16ToUTF8(notification
.message()));
147 service()->ClosePersistentNotification(profile(),
148 notification
.delegate_id());
149 EXPECT_EQ(0u, ui_manager()->GetNotificationCount());
152 TEST_F(PlatformNotificationServiceTest
, DisplayPageNotificationMatches
) {
153 content::PlatformNotificationData notification_data
;
154 notification_data
.title
= base::ASCIIToUTF16("My notification's title");
155 notification_data
.body
= base::ASCIIToUTF16("Hello, world!");
156 notification_data
.silent
= true;
158 MockDesktopNotificationDelegate
* delegate
159 = new MockDesktopNotificationDelegate();
160 service()->DisplayNotification(profile(),
161 GURL("https://chrome.com/"),
164 make_scoped_ptr(delegate
),
167 ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
169 const Notification
& notification
= ui_manager()->GetNotificationAt(0);
170 EXPECT_EQ("https://chrome.com/", notification
.origin_url().spec());
171 EXPECT_EQ("My notification's title",
172 base::UTF16ToUTF8(notification
.title()));
173 EXPECT_EQ("Hello, world!",
174 base::UTF16ToUTF8(notification
.message()));
175 EXPECT_TRUE(notification
.silent());
178 TEST_F(PlatformNotificationServiceTest
, DisplayNameForOrigin
) {
179 base::string16 display_name
=
180 service()->DisplayNameForOrigin(profile(), GURL("https://chrome.com/"));
182 EXPECT_EQ(base::ASCIIToUTF16("chrome.com"), display_name
);
184 // TODO(peter): Include unit tests for the extension-name translation
185 // functionality of DisplayNameForOriginInProcessId.
188 TEST_F(PlatformNotificationServiceTest
, TestWebOriginDisplayName
) {
189 std::string
language("en-us");
191 GURL
https_origin("https://mail.google.com/");
192 base::string16 expected_display_name
= base::ASCIIToUTF16("mail.google.com");
193 EXPECT_EQ(expected_display_name
,
194 PlatformNotificationServiceImpl::WebOriginDisplayName(https_origin
,
197 GURL
https_origin_standard_port("https://mail.google.com:443/");
198 expected_display_name
= base::ASCIIToUTF16("mail.google.com");
199 EXPECT_EQ(expected_display_name
,
200 PlatformNotificationServiceImpl::WebOriginDisplayName(
201 https_origin_standard_port
, language
));
203 GURL
https_origin_nonstandard_port("https://mail.google.com:444/");
204 expected_display_name
= base::ASCIIToUTF16("mail.google.com:444");
205 EXPECT_EQ(expected_display_name
,
206 PlatformNotificationServiceImpl::WebOriginDisplayName(
207 https_origin_nonstandard_port
, language
));
209 GURL
http_origin("http://mail.google.com/");
210 expected_display_name
= base::ASCIIToUTF16("http://mail.google.com");
211 EXPECT_EQ(expected_display_name
,
212 PlatformNotificationServiceImpl::WebOriginDisplayName(http_origin
,
215 GURL
http_origin_standard_port("http://mail.google.com:80/");
216 expected_display_name
= base::ASCIIToUTF16("http://mail.google.com");
217 EXPECT_EQ(expected_display_name
,
218 PlatformNotificationServiceImpl::WebOriginDisplayName(
219 http_origin_standard_port
, language
));
221 GURL
http_origin_nonstandard_port("http://mail.google.com:81/");
222 expected_display_name
= base::ASCIIToUTF16("http://mail.google.com:81");
223 EXPECT_EQ(expected_display_name
,
224 PlatformNotificationServiceImpl::WebOriginDisplayName(
225 http_origin_nonstandard_port
, language
));
226 // TODO(dewittj): Add file origin once it's supported.
229 TEST_F(PlatformNotificationServiceTest
, NotificationPermissionLastUsage
) {
230 // Both page and persistent notifications should update the last usage
231 // time of the notification permission for the origin.
232 GURL
origin("https://chrome.com/");
233 base::Time begin_time
;
235 CreateSimplePageNotification();
237 base::Time after_page_notification
=
238 profile()->GetHostContentSettingsMap()->GetLastUsage(
239 origin
, origin
, CONTENT_SETTINGS_TYPE_NOTIFICATIONS
);
240 EXPECT_GT(after_page_notification
, begin_time
);
242 // Ensure that there is at least some time between the two calls.
243 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
245 service()->DisplayPersistentNotification(
246 profile(), 42 /* sw_registration_id */, origin
, SkBitmap(),
247 content::PlatformNotificationData());
249 base::Time after_persistent_notification
=
250 profile()->GetHostContentSettingsMap()->GetLastUsage(
251 origin
, origin
, CONTENT_SETTINGS_TYPE_NOTIFICATIONS
);
252 EXPECT_GT(after_persistent_notification
, after_page_notification
);