blob: 2bd06aae249565bb910708c4b3bfe572f88d79a6 [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 "base/strings/utf_string_conversions.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "chrome/browser/notifications/notification_test_util.h"
#include "chrome/browser/notifications/platform_notification_service_impl.h"
#include "chrome/test/base/testing_profile.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "content/public/browser/desktop_notification_delegate.h"
#include "content/public/common/platform_notification_data.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
namespace {
class MockDesktopNotificationDelegate
: public content::DesktopNotificationDelegate {
public:
MockDesktopNotificationDelegate()
: displayed_(false),
clicked_(false) {}
~MockDesktopNotificationDelegate() override {}
// content::DesktopNotificationDelegate implementation.
void NotificationDisplayed() override { displayed_ = true; }
void NotificationClosed() override {}
void NotificationClick() override { clicked_ = true; }
bool displayed() const { return displayed_; }
bool clicked() const { return clicked_; }
private:
bool displayed_;
bool clicked_;
};
} // namespace
class PlatformNotificationServiceTest : public testing::Test {
public:
void SetUp() override {
ui_manager_.reset(new StubNotificationUIManager);
profile_.reset(new TestingProfile());
service()->SetNotificationUIManagerForTesting(ui_manager_.get());
}
void TearDown() override {
service()->SetNotificationUIManagerForTesting(nullptr);
profile_.reset();
ui_manager_.reset();
}
protected:
// Displays a simple, fake notifications and returns a weak pointer to the
// delegate receiving events for it (ownership is transferred to the service).
MockDesktopNotificationDelegate* CreateSimplePageNotification() const {
return CreateSimplePageNotificationWithCloseClosure(nullptr);
}
// Displays a simple, fake notification and returns a weak pointer to the
// delegate receiving events for it (ownership is transferred to the service).
// The close closure may be specified if so desired.
MockDesktopNotificationDelegate* CreateSimplePageNotificationWithCloseClosure(
base::Closure* close_closure) const {
content::PlatformNotificationData notification_data;
notification_data.title = base::ASCIIToUTF16("My Notification");
notification_data.body = base::ASCIIToUTF16("Hello, world!");
MockDesktopNotificationDelegate* delegate =
new MockDesktopNotificationDelegate();
service()->DisplayNotification(profile(),
GURL("https://chrome.com/"),
SkBitmap(),
notification_data,
make_scoped_ptr(delegate),
close_closure);
return delegate;
}
// Returns the Platform Notification Service these unit tests are for.
PlatformNotificationServiceImpl* service() const {
return PlatformNotificationServiceImpl::GetInstance();
}
// Returns the Profile to be used for these tests.
Profile* profile() const { return profile_.get(); }
// Returns the UI Manager on which notifications will be displayed.
StubNotificationUIManager* ui_manager() const { return ui_manager_.get(); }
private:
scoped_ptr<StubNotificationUIManager> ui_manager_;
scoped_ptr<TestingProfile> profile_;
content::TestBrowserThreadBundle thread_bundle_;
};
TEST_F(PlatformNotificationServiceTest, DisplayPageDisplayedEvent) {
auto* delegate = CreateSimplePageNotification();
EXPECT_EQ(1u, ui_manager()->GetNotificationCount());
EXPECT_TRUE(delegate->displayed());
}
TEST_F(PlatformNotificationServiceTest, DisplayPageCloseClosure) {
base::Closure close_closure;
CreateSimplePageNotificationWithCloseClosure(&close_closure);
EXPECT_EQ(1u, ui_manager()->GetNotificationCount());
ASSERT_FALSE(close_closure.is_null());
close_closure.Run();
EXPECT_EQ(0u, ui_manager()->GetNotificationCount());
// Note that we cannot verify whether the closed event was called on the
// delegate given that it'd result in a use-after-free.
}
TEST_F(PlatformNotificationServiceTest, PersistentNotificationDisplay) {
content::PlatformNotificationData notification_data;
notification_data.title = base::ASCIIToUTF16("My notification's title");
notification_data.body = base::ASCIIToUTF16("Hello, world!");
service()->DisplayPersistentNotification(
profile(), 42 /* sw_registration_id */, GURL("https://chrome.com/"),
SkBitmap(), notification_data);
ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
const Notification& notification = ui_manager()->GetNotificationAt(0);
EXPECT_EQ("https://chrome.com/", notification.origin_url().spec());
EXPECT_EQ("My notification's title",
base::UTF16ToUTF8(notification.title()));
EXPECT_EQ("Hello, world!",
base::UTF16ToUTF8(notification.message()));
service()->ClosePersistentNotification(profile(),
notification.delegate_id());
EXPECT_EQ(0u, ui_manager()->GetNotificationCount());
}
TEST_F(PlatformNotificationServiceTest, DisplayPageNotificationMatches) {
content::PlatformNotificationData notification_data;
notification_data.title = base::ASCIIToUTF16("My notification's title");
notification_data.body = base::ASCIIToUTF16("Hello, world!");
notification_data.silent = true;
MockDesktopNotificationDelegate* delegate
= new MockDesktopNotificationDelegate();
service()->DisplayNotification(profile(),
GURL("https://chrome.com/"),
SkBitmap(),
notification_data,
make_scoped_ptr(delegate),
nullptr);
ASSERT_EQ(1u, ui_manager()->GetNotificationCount());
const Notification& notification = ui_manager()->GetNotificationAt(0);
EXPECT_EQ("https://chrome.com/", notification.origin_url().spec());
EXPECT_EQ("My notification's title",
base::UTF16ToUTF8(notification.title()));
EXPECT_EQ("Hello, world!",
base::UTF16ToUTF8(notification.message()));
EXPECT_TRUE(notification.silent());
}
TEST_F(PlatformNotificationServiceTest, DisplayNameForOrigin) {
base::string16 display_name =
service()->DisplayNameForOrigin(profile(), GURL("https://chrome.com/"));
EXPECT_EQ(base::ASCIIToUTF16("chrome.com"), display_name);
// TODO(peter): Include unit tests for the extension-name translation
// functionality of DisplayNameForOriginInProcessId.
}
TEST_F(PlatformNotificationServiceTest, TestWebOriginDisplayName) {
std::string language("en-us");
GURL https_origin("https://mail.google.com/");
base::string16 expected_display_name = base::ASCIIToUTF16("mail.google.com");
EXPECT_EQ(expected_display_name,
PlatformNotificationServiceImpl::WebOriginDisplayName(https_origin,
language));
GURL https_origin_standard_port("https://mail.google.com:443/");
expected_display_name = base::ASCIIToUTF16("mail.google.com");
EXPECT_EQ(expected_display_name,
PlatformNotificationServiceImpl::WebOriginDisplayName(
https_origin_standard_port, language));
GURL https_origin_nonstandard_port("https://mail.google.com:444/");
expected_display_name = base::ASCIIToUTF16("mail.google.com:444");
EXPECT_EQ(expected_display_name,
PlatformNotificationServiceImpl::WebOriginDisplayName(
https_origin_nonstandard_port, language));
GURL http_origin("http://mail.google.com/");
expected_display_name = base::ASCIIToUTF16("http://mail.google.com");
EXPECT_EQ(expected_display_name,
PlatformNotificationServiceImpl::WebOriginDisplayName(http_origin,
language));
GURL http_origin_standard_port("http://mail.google.com:80/");
expected_display_name = base::ASCIIToUTF16("http://mail.google.com");
EXPECT_EQ(expected_display_name,
PlatformNotificationServiceImpl::WebOriginDisplayName(
http_origin_standard_port, language));
GURL http_origin_nonstandard_port("http://mail.google.com:81/");
expected_display_name = base::ASCIIToUTF16("http://mail.google.com:81");
EXPECT_EQ(expected_display_name,
PlatformNotificationServiceImpl::WebOriginDisplayName(
http_origin_nonstandard_port, language));
// TODO(dewittj): Add file origin once it's supported.
}
TEST_F(PlatformNotificationServiceTest, NotificationPermissionLastUsage) {
// Both page and persistent notifications should update the last usage
// time of the notification permission for the origin.
GURL origin("https://chrome.com/");
base::Time begin_time;
CreateSimplePageNotification();
base::Time after_page_notification =
profile()->GetHostContentSettingsMap()->GetLastUsage(
origin, origin, CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
EXPECT_GT(after_page_notification, begin_time);
// Ensure that there is at least some time between the two calls.
base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
service()->DisplayPersistentNotification(
profile(), 42 /* sw_registration_id */, origin, SkBitmap(),
content::PlatformNotificationData());
base::Time after_persistent_notification =
profile()->GetHostContentSettingsMap()->GetLastUsage(
origin, origin, CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
EXPECT_GT(after_persistent_notification, after_page_notification);
}