summaryrefslogtreecommitdiffstats
path: root/browser/extensions/search-detection/tests/browser/browser_client_side_redirection.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/extensions/search-detection/tests/browser/browser_client_side_redirection.js')
-rw-r--r--browser/extensions/search-detection/tests/browser/browser_client_side_redirection.js204
1 files changed, 204 insertions, 0 deletions
diff --git a/browser/extensions/search-detection/tests/browser/browser_client_side_redirection.js b/browser/extensions/search-detection/tests/browser/browser_client_side_redirection.js
new file mode 100644
index 0000000000..5dad39dba4
--- /dev/null
+++ b/browser/extensions/search-detection/tests/browser/browser_client_side_redirection.js
@@ -0,0 +1,204 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const { AddonTestUtils } = ChromeUtils.importESModule(
+ "resource://testing-common/AddonTestUtils.sys.mjs"
+);
+
+const { TelemetryTestUtils } = ChromeUtils.importESModule(
+ "resource://testing-common/TelemetryTestUtils.sys.mjs"
+);
+
+AddonTestUtils.initMochitest(this);
+
+const TELEMETRY_EVENTS_FILTERS = {
+ category: "addonsSearchDetection",
+ method: "etld_change",
+};
+
+// The search-detection built-in add-on registers dynamic events.
+const TELEMETRY_TEST_UTILS_OPTIONS = { clear: true, process: "dynamic" };
+
+async function testClientSideRedirect({
+ background,
+ permissions,
+ telemetryExpected = false,
+}) {
+ Services.telemetry.clearEvents();
+
+ // Load an extension that does a client-side redirect. We expect this
+ // extension to be reported in a Telemetry event when `telemetryExpected` is
+ // set to `true`.
+ const addonId = "some@addon-id";
+ const addonVersion = "1.2.3";
+
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ version: addonVersion,
+ browser_specific_settings: { gecko: { id: addonId } },
+ permissions,
+ },
+ useAddonManager: "temporary",
+ background,
+ });
+
+ await extension.startup();
+ await extension.awaitMessage("ready");
+
+ // Simulate a search (with the test search engine) by navigating to it.
+ await BrowserTestUtils.withNewTab(
+ {
+ gBrowser,
+ url: "https://example.com/search?q=babar",
+ },
+ () => {}
+ );
+
+ await extension.unload();
+
+ TelemetryTestUtils.assertEvents(
+ telemetryExpected
+ ? [
+ {
+ object: "webrequest",
+ value: "extension",
+ extra: {
+ addonId,
+ addonVersion,
+ from: "example.com",
+ to: "mochi.test",
+ },
+ },
+ ]
+ : [],
+ TELEMETRY_EVENTS_FILTERS,
+ TELEMETRY_TEST_UTILS_OPTIONS
+ );
+}
+
+add_setup(async function () {
+ const searchEngineName = "test search engine";
+
+ let searchEngine;
+
+ // This cleanup function has to be registered before the one registered
+ // internally by loadExtension, otherwise it is going to trigger a test
+ // failure (because it will be called too late).
+ registerCleanupFunction(async () => {
+ await searchEngine.unload();
+ ok(
+ !Services.search.getEngineByName(searchEngineName),
+ "test search engine unregistered"
+ );
+ });
+
+ searchEngine = ExtensionTestUtils.loadExtension({
+ manifest: {
+ chrome_settings_overrides: {
+ search_provider: {
+ name: searchEngineName,
+ keyword: "test",
+ search_url: "https://example.com/?q={searchTerms}",
+ },
+ },
+ },
+ // NOTE: the search extension needs to be installed through the
+ // AddonManager to be correctly unregistered when it is uninstalled.
+ useAddonManager: "temporary",
+ });
+
+ await searchEngine.startup();
+ await AddonTestUtils.waitForSearchProviderStartup(searchEngine);
+ ok(
+ Services.search.getEngineByName(searchEngineName),
+ "test search engine registered"
+ );
+});
+
+add_task(function test_onBeforeRequest() {
+ return testClientSideRedirect({
+ background() {
+ browser.webRequest.onBeforeRequest.addListener(
+ () => {
+ return {
+ redirectUrl: "http://mochi.test:8888/",
+ };
+ },
+ { urls: ["*://example.com/*"] },
+ ["blocking"]
+ );
+
+ browser.test.sendMessage("ready");
+ },
+ permissions: ["webRequest", "webRequestBlocking", "*://example.com/*"],
+ telemetryExpected: true,
+ });
+});
+
+add_task(function test_onBeforeRequest_url_not_monitored() {
+ // Here, we load an extension that does a client-side redirect. Because this
+ // extension does not listen to the URL of the search engine registered
+ // above, we don't expect this extension to be reported in a Telemetry event.
+ return testClientSideRedirect({
+ background() {
+ browser.webRequest.onBeforeRequest.addListener(
+ () => {
+ return {
+ redirectUrl: "http://mochi.test:8888/",
+ };
+ },
+ { urls: ["*://google.com/*"] },
+ ["blocking"]
+ );
+
+ browser.test.sendMessage("ready");
+ },
+ permissions: ["webRequest", "webRequestBlocking", "*://google.com/*"],
+ telemetryExpected: false,
+ });
+});
+
+add_task(function test_onHeadersReceived() {
+ return testClientSideRedirect({
+ background() {
+ browser.webRequest.onHeadersReceived.addListener(
+ () => {
+ return {
+ redirectUrl: "http://mochi.test:8888/",
+ };
+ },
+ { urls: ["*://example.com/*"], types: ["main_frame"] },
+ ["blocking"]
+ );
+
+ browser.test.sendMessage("ready");
+ },
+ permissions: ["webRequest", "webRequestBlocking", "*://example.com/*"],
+ telemetryExpected: true,
+ });
+});
+
+add_task(function test_onHeadersReceived_url_not_monitored() {
+ // Here, we load an extension that does a client-side redirect. Because this
+ // extension does not listen to the URL of the search engine registered
+ // above, we don't expect this extension to be reported in a Telemetry event.
+ return testClientSideRedirect({
+ background() {
+ browser.webRequest.onHeadersReceived.addListener(
+ () => {
+ return {
+ redirectUrl: "http://mochi.test:8888/",
+ };
+ },
+ { urls: ["*://google.com/*"], types: ["main_frame"] },
+ ["blocking"]
+ );
+
+ browser.test.sendMessage("ready");
+ },
+ permissions: ["webRequest", "webRequestBlocking", "*://google.com/*"],
+ telemetryExpected: false,
+ });
+});