1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
|
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/push_messaging/push_messaging_notification_manager.h"
#include "base/functional/bind.h"
#include "base/strings/stringprintf.h"
#include "build/chromeos_buildflags.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/test_renderer_host.h"
#include "extensions/buildflags/buildflags.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "chrome/browser/extensions/chrome_test_extension_loader.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/extensions/extension_service_test_with_install.h"
#include "extensions/common/extension.h"
#include "extensions/test/test_extension_dir.h"
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
class PushMessagingNotificationManagerTest
: public ChromeRenderViewHostTestHarness {};
TEST_F(PushMessagingNotificationManagerTest, IsTabVisible) {
PushMessagingNotificationManager manager(profile());
GURL origin("https://google.com/");
GURL origin_with_path = origin.Resolve("/path/");
NavigateAndCommit(origin_with_path);
EXPECT_FALSE(manager.IsTabVisible(profile(), nullptr, origin));
EXPECT_FALSE(manager.IsTabVisible(profile(), web_contents(),
GURL("https://chrome.com/")));
EXPECT_TRUE(manager.IsTabVisible(profile(), web_contents(), origin));
content::RenderViewHostTester::For(rvh())->SimulateWasHidden();
EXPECT_FALSE(manager.IsTabVisible(profile(), web_contents(), origin));
content::RenderViewHostTester::For(rvh())->SimulateWasShown();
EXPECT_TRUE(manager.IsTabVisible(profile(), web_contents(), origin));
}
TEST_F(PushMessagingNotificationManagerTest, IsTabVisibleViewSource) {
PushMessagingNotificationManager manager(profile());
GURL origin("https://google.com/");
GURL view_source_page("view-source:https://google.com/path/");
NavigateAndCommit(view_source_page);
ASSERT_EQ(view_source_page, web_contents()->GetVisibleURL());
EXPECT_TRUE(manager.IsTabVisible(profile(), web_contents(), origin));
content::RenderViewHostTester::For(rvh())->SimulateWasHidden();
EXPECT_FALSE(manager.IsTabVisible(profile(), web_contents(), origin));
}
#if BUILDFLAG(ENABLE_EXTENSIONS)
namespace extensions {
using ContextType = extensions::browser_test_util::ContextType;
class ExtensionsPushMessagingNotificationManagerTest
: public ExtensionServiceTestWithInstall,
public testing::WithParamInterface<ContextType> {
public:
ExtensionsPushMessagingNotificationManagerTest() = default;
ExtensionsPushMessagingNotificationManagerTest(
const ExtensionsPushMessagingNotificationManagerTest&) = delete;
ExtensionsPushMessagingNotificationManagerTest& operator=(
const ExtensionsPushMessagingNotificationManagerTest&) = delete;
void SetUp() override {
ExtensionServiceTestWithInstall::SetUp();
InitializeExtensionService(ExtensionServiceInitParams());
}
};
// Tests that when receiving a push message only service worker-based extensions
// are allowed to bypass/skip the user visible notification requirement only if
// they set userVisible == false when they subscribed to the push server.
TEST_P(ExtensionsPushMessagingNotificationManagerTest,
SkipEnforceUserVisibleOnlyRequirements_ForExtensions) {
static constexpr char kManifestPersistentBackgroundScript[] =
R"({"scripts": ["background.js"], "persistent": true})";
static constexpr char kManifestEventPageBackgroundScript[] =
R"({"persistent": false,
"scripts": ["background.js"]
}
)";
static constexpr char kManifestServiceWorkerBackgroundScript[] =
R"({"service_worker": "background.js"})";
// Load an extension of ContextType.
TestExtensionDir test_dir;
constexpr char kManifest[] =
R"({
"name": "Test Extension",
"manifest_version": %s,
"version": "0.1",
"background": %s,
"permissions": ["notifications"]
})";
ContextType extension_context_type = GetParam();
bool worker_extension = extension_context_type == ContextType::kServiceWorker;
const char* background_script;
if (worker_extension) {
background_script = kManifestServiceWorkerBackgroundScript;
} else if (extension_context_type == ContextType::kEventPage) {
background_script = kManifestEventPageBackgroundScript;
} else {
background_script = kManifestPersistentBackgroundScript;
}
const char* manifest_version = worker_extension ? "3" : "2";
std::string manifest =
base::StringPrintf(kManifest, manifest_version, background_script);
test_dir.WriteManifest(manifest);
test_dir.WriteFile(FILE_PATH_LITERAL("background.js"), "");
ChromeTestExtensionLoader loader(profile());
scoped_refptr<const Extension> extension =
loader.LoadExtension(test_dir.UnpackedPath());
ASSERT_TRUE(extension);
// Attempt to skip while userVisible == false.
bool skip_allowed = false;
PushMessagingNotificationManager manager(profile());
manager.EnforceUserVisibleOnlyRequirements(
Extension::GetBaseURLFromExtensionId(extension->id()), 0l,
// Callback that is called when user visible requirements are skipped.
base::BindOnce(
[](bool* skip_allowed, bool did_show_generic_notification) {
*skip_allowed = true;
// Generic notifications are shown if the push subscriber didn't
// show a user visible notification when receiving a push
// notification.
EXPECT_FALSE(did_show_generic_notification);
},
&skip_allowed),
/*requested_user_visible_only=*/true); // userVisible == false
// Only workers are allowed to skip the userVisible notification.
if (worker_extension) {
EXPECT_TRUE(skip_allowed);
} else {
EXPECT_FALSE(skip_allowed);
}
// Attempt to skip while userVisible == true.
skip_allowed = false;
manager.EnforceUserVisibleOnlyRequirements(
Extension::GetBaseURLFromExtensionId(extension->id()), 0l,
// Callback that is called when user visible requirements are skipped.
base::BindOnce(
[](bool* skip_allowed, bool did_show_generic_notification) {
*skip_allowed = true;
// Generic notifications are shown if the push subscriber didn't
// show a user visible notification when receiving a push
// notification.
EXPECT_FALSE(did_show_generic_notification);
},
&skip_allowed),
/*requested_user_visible_only=*/false); // userVisible == true
// If userVisible == true then no matter the extension context type we should
// not skip.
EXPECT_FALSE(skip_allowed);
}
INSTANTIATE_TEST_SUITE_P(
NonWorkerExtension,
ExtensionsPushMessagingNotificationManagerTest,
::testing::ValuesIn({ContextType::kEventPage,
ContextType::kPersistentBackground}));
INSTANTIATE_TEST_SUITE_P(WorkerBasedExtension,
ExtensionsPushMessagingNotificationManagerTest,
::testing::Values(ContextType::kServiceWorker));
} // namespace extensions
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
|