Commit 7d80539e authored by Anita Woodruff's avatar Anita Woodruff Committed by Commit Bot

[Testing++] Add BlinkNotificationServiceImpl unit tests

Change-Id: Id007aa212c96d2d171a9f658da16d47e17ba21e3
Reviewed-on: https://chromium-review.googlesource.com/911573
Commit-Queue: Anita Woodruff <awdf@chromium.org>
Reviewed-by: default avatarPeter Beverloo <peter@chromium.org>
Cr-Commit-Position: refs/heads/master@{#537669}
parent 8e3c5d36
include_rules = [ include_rules = [
"+third_party/leveldatabase", "+third_party/leveldatabase",
] "+third_party/WebKit/public/platform/modules/notifications/notification_service.mojom.h",
\ No newline at end of file ]
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_context.h"
#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/interface_request.h" #include "mojo/public/cpp/bindings/interface_request.h"
...@@ -22,7 +23,8 @@ class ResourceContext; ...@@ -22,7 +23,8 @@ class ResourceContext;
// Implementation of the NotificationService used for Web Notifications. Is // Implementation of the NotificationService used for Web Notifications. Is
// responsible for displaying, updating and reading of both non-persistent // responsible for displaying, updating and reading of both non-persistent
// and persistent notifications. Lives on the IO thread. // and persistent notifications. Lives on the IO thread.
class BlinkNotificationServiceImpl : public blink::mojom::NotificationService { class CONTENT_EXPORT BlinkNotificationServiceImpl
: public blink::mojom::NotificationService {
public: public:
BlinkNotificationServiceImpl( BlinkNotificationServiceImpl(
PlatformNotificationContextImpl* notification_context, PlatformNotificationContextImpl* notification_context,
......
// Copyright 2018 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 <stdint.h>
#include <memory>
#include <vector>
#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "base/run_loop.h"
#include "base/test/test_simple_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/browser/notifications/blink_notification_service_impl.h"
#include "content/browser/notifications/platform_notification_context_impl.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/public/test/mock_resource_context.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h"
#include "content/test/mock_platform_notification_service.h"
#include "content/test/test_content_browser_client.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/modules/notifications/notification_service.mojom.h"
#include "third_party/WebKit/public/platform/modules/permissions/permission_status.mojom.h"
namespace content {
namespace {
const int kFakeRenderProcessId = 1;
const char kTestOrigin[] = "https://example.com";
class MockNonPersistentNotificationListener
: public blink::mojom::NonPersistentNotificationListener {
public:
MockNonPersistentNotificationListener() : binding_(this) {}
~MockNonPersistentNotificationListener() override = default;
blink::mojom::NonPersistentNotificationListenerPtr GetPtr() {
blink::mojom::NonPersistentNotificationListenerPtr ptr;
binding_.Bind(mojo::MakeRequest(&ptr));
return ptr;
}
// NonPersistentNotificationListener interface.
void OnShow() override {}
void OnClick() override {}
void OnClose() override {}
private:
mojo::Binding<blink::mojom::NonPersistentNotificationListener> binding_;
};
} // anonymous namespace
// This is for overriding the Platform Notification Service with a mock one.
class NotificationBrowserClient : public TestContentBrowserClient {
public:
NotificationBrowserClient(
MockPlatformNotificationService* mock_platform_service)
: platform_notification_service_(mock_platform_service) {}
PlatformNotificationService* GetPlatformNotificationService() override {
return platform_notification_service_;
}
private:
MockPlatformNotificationService* platform_notification_service_;
};
class BlinkNotificationServiceImplTest : public ::testing::Test {
public:
// Using REAL_IO_THREAD would give better coverage for thread safety, but
// at time of writing EmbeddedWorkerTestHelper didn't seem to support that.
BlinkNotificationServiceImplTest()
: thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
notification_browser_client_(&mock_platform_service_) {
SetBrowserClientForTesting(&notification_browser_client_);
}
~BlinkNotificationServiceImplTest() override = default;
// ::testing::Test overrides.
void SetUp() override {
notification_context_ = new PlatformNotificationContextImpl(
base::FilePath(), &browser_context_,
nullptr /* service_worker_context */);
notification_context_->Initialize();
blink::mojom::NotificationServicePtr notification_service_ptr;
notification_service_ = std::make_unique<BlinkNotificationServiceImpl>(
notification_context_.get(), &browser_context_, &resource_context_,
kFakeRenderProcessId, url::Origin::Create(GURL(kTestOrigin)),
mojo::MakeRequest(&notification_service_ptr));
}
void DidGetPermissionStatus(
blink::mojom::PermissionStatus permission_status) {
permission_callback_result_ = permission_status;
}
blink::mojom::PermissionStatus GetPermissionCallbackResult() {
return permission_callback_result_;
}
void DidGetDisplayedNotifications(
base::OnceClosure quit_closure,
std::unique_ptr<std::set<std::string>> notification_ids,
bool supports_synchronization) {
get_displayed_callback_result_ = *notification_ids;
std::move(quit_closure).Run();
}
// Synchronous wrapper of
// PlatformNotificationService::GetDisplayedNotifications
std::set<std::string> GetDisplayedNotifications() {
base::RunLoop run_loop;
mock_platform_service_.GetDisplayedNotifications(
&browser_context_,
base::Bind(
&BlinkNotificationServiceImplTest::DidGetDisplayedNotifications,
base::Unretained(this), run_loop.QuitClosure()));
run_loop.Run();
return get_displayed_callback_result_;
}
protected:
TestBrowserThreadBundle thread_bundle_; // Must be first member.
std::unique_ptr<BlinkNotificationServiceImpl> notification_service_;
TestBrowserContext browser_context_;
MockPlatformNotificationService mock_platform_service_;
MockNonPersistentNotificationListener non_persistent_notification_listener_;
private:
NotificationBrowserClient notification_browser_client_;
scoped_refptr<PlatformNotificationContextImpl> notification_context_;
blink::mojom::PermissionStatus permission_callback_result_ =
blink::mojom::PermissionStatus::ASK;
std::set<std::string> get_displayed_callback_result_;
MockResourceContext resource_context_;
DISALLOW_COPY_AND_ASSIGN(BlinkNotificationServiceImplTest);
};
TEST_F(BlinkNotificationServiceImplTest, GetPermissionStatus) {
mock_platform_service_.SetPermission(blink::mojom::PermissionStatus::GRANTED);
notification_service_->GetPermissionStatus(
base::BindOnce(&BlinkNotificationServiceImplTest::DidGetPermissionStatus,
base::Unretained(this)));
EXPECT_EQ(blink::mojom::PermissionStatus::GRANTED,
GetPermissionCallbackResult());
mock_platform_service_.SetPermission(blink::mojom::PermissionStatus::DENIED);
notification_service_->GetPermissionStatus(
base::BindOnce(&BlinkNotificationServiceImplTest::DidGetPermissionStatus,
base::Unretained(this)));
EXPECT_EQ(blink::mojom::PermissionStatus::DENIED,
GetPermissionCallbackResult());
mock_platform_service_.SetPermission(blink::mojom::PermissionStatus::ASK);
notification_service_->GetPermissionStatus(
base::BindOnce(&BlinkNotificationServiceImplTest::DidGetPermissionStatus,
base::Unretained(this)));
EXPECT_EQ(blink::mojom::PermissionStatus::ASK, GetPermissionCallbackResult());
}
TEST_F(BlinkNotificationServiceImplTest,
DisplayNonPersistentNotificationWithPermission) {
mock_platform_service_.SetPermission(blink::mojom::PermissionStatus::GRANTED);
notification_service_->DisplayNonPersistentNotification(
"token", PlatformNotificationData(), NotificationResources(),
non_persistent_notification_listener_.GetPtr());
// TODO(https://crbug.com/787459): Pass a callback to
// DisplayNonPersistentNotification instead of waiting for all tasks to run
// here; a callback parameter will be needed anyway to enable
// non-persistent notification event acknowledgements - see bug.
RunAllTasksUntilIdle();
EXPECT_EQ(1u, GetDisplayedNotifications().size());
}
TEST_F(BlinkNotificationServiceImplTest,
DisplayNonPersistentNotificationWithoutPermission) {
mock_platform_service_.SetPermission(blink::mojom::PermissionStatus::DENIED);
notification_service_->DisplayNonPersistentNotification(
"token", PlatformNotificationData(), NotificationResources(),
non_persistent_notification_listener_.GetPtr());
// TODO(https://crbug.com/787459): Pass a callback to
// DisplayNonPersistentNotification instead of waiting for all tasks to run
// here; a callback parameter will be needed anyway to enable
// non-persistent notification event acknowledgements - see bug.
RunAllTasksUntilIdle();
EXPECT_EQ(0u, GetDisplayedNotifications().size());
}
} // namespace content
...@@ -1364,6 +1364,7 @@ test("content_unittests") { ...@@ -1364,6 +1364,7 @@ test("content_unittests") {
"../browser/net/network_quality_observer_impl_unittest.cc", "../browser/net/network_quality_observer_impl_unittest.cc",
"../browser/net/quota_policy_cookie_store_unittest.cc", "../browser/net/quota_policy_cookie_store_unittest.cc",
"../browser/notification_service_impl_unittest.cc", "../browser/notification_service_impl_unittest.cc",
"../browser/notifications/blink_notification_service_impl_unittest.cc",
"../browser/notifications/notification_database_data_unittest.cc", "../browser/notifications/notification_database_data_unittest.cc",
"../browser/notifications/notification_database_unittest.cc", "../browser/notifications/notification_database_unittest.cc",
"../browser/notifications/notification_event_dispatcher_impl_unittest.cc", "../browser/notifications/notification_event_dispatcher_impl_unittest.cc",
......
...@@ -93,6 +93,8 @@ void MockPlatformNotificationService::GetDisplayedNotifications( ...@@ -93,6 +93,8 @@ void MockPlatformNotificationService::GetDisplayedNotifications(
for (const auto& kv : persistent_notifications_) for (const auto& kv : persistent_notifications_)
displayed_notifications->insert(kv.first); displayed_notifications->insert(kv.first);
for (const auto& notification_id : non_persistent_notifications_)
displayed_notifications->insert(notification_id);
BrowserThread::PostTask( BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE, BrowserThread::UI, FROM_HERE,
...@@ -151,6 +153,11 @@ void MockPlatformNotificationService::SimulateClose(const std::string& title, ...@@ -151,6 +153,11 @@ void MockPlatformNotificationService::SimulateClose(const std::string& title,
by_user, base::BindOnce(&OnEventDispatchComplete)); by_user, base::BindOnce(&OnEventDispatchComplete));
} }
void MockPlatformNotificationService::SetPermission(
blink::mojom::PermissionStatus permission_status) {
permission_status_ = permission_status;
}
blink::mojom::PermissionStatus blink::mojom::PermissionStatus
MockPlatformNotificationService::CheckPermissionOnUIThread( MockPlatformNotificationService::CheckPermissionOnUIThread(
BrowserContext* browser_context, BrowserContext* browser_context,
...@@ -177,7 +184,7 @@ void MockPlatformNotificationService::ReplaceNotificationIfNeeded( ...@@ -177,7 +184,7 @@ void MockPlatformNotificationService::ReplaceNotificationIfNeeded(
blink::mojom::PermissionStatus MockPlatformNotificationService::CheckPermission( blink::mojom::PermissionStatus MockPlatformNotificationService::CheckPermission(
const GURL& origin) { const GURL& origin) {
return blink::mojom::PermissionStatus::GRANTED; return permission_status_;
} }
} // namespace content } // namespace content
...@@ -41,6 +41,9 @@ class MockPlatformNotificationService : public PlatformNotificationService { ...@@ -41,6 +41,9 @@ class MockPlatformNotificationService : public PlatformNotificationService {
// the UI thread. // the UI thread.
void SimulateClose(const std::string& title, bool by_user); void SimulateClose(const std::string& title, bool by_user);
// Sets the notification permission returned by CheckPermission.
void SetPermission(blink::mojom::PermissionStatus permission_status);
// PlatformNotificationService implementation. // PlatformNotificationService implementation.
blink::mojom::PermissionStatus CheckPermissionOnUIThread( blink::mojom::PermissionStatus CheckPermissionOnUIThread(
BrowserContext* browser_context, BrowserContext* browser_context,
...@@ -94,6 +97,10 @@ class MockPlatformNotificationService : public PlatformNotificationService { ...@@ -94,6 +97,10 @@ class MockPlatformNotificationService : public PlatformNotificationService {
// Mapping of titles to notification ids giving test a usable identifier. // Mapping of titles to notification ids giving test a usable identifier.
std::unordered_map<std::string, std::string> notification_id_map_; std::unordered_map<std::string, std::string> notification_id_map_;
// Permission is initialized to GRANTED for the convenience of most tests.
blink::mojom::PermissionStatus permission_status_ =
blink::mojom::PermissionStatus::GRANTED;
DISALLOW_COPY_AND_ASSIGN(MockPlatformNotificationService); DISALLOW_COPY_AND_ASSIGN(MockPlatformNotificationService);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment