From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- .../test/xpcshell/test_ext_dnr_tabIds.js | 249 +++++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 toolkit/components/extensions/test/xpcshell/test_ext_dnr_tabIds.js (limited to 'toolkit/components/extensions/test/xpcshell/test_ext_dnr_tabIds.js') diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_dnr_tabIds.js b/toolkit/components/extensions/test/xpcshell/test_ext_dnr_tabIds.js new file mode 100644 index 0000000000..84b75bb5be --- /dev/null +++ b/toolkit/components/extensions/test/xpcshell/test_ext_dnr_tabIds.js @@ -0,0 +1,249 @@ +"use strict"; + +// This test verifies that the internals for associating requests with tabId +// are only active when a session rule with a tabId rule exists. +// +// There are tests for the logic of tabId matching in the match_tabIds task in +// toolkit/components/extensions/test/xpcshell/test_ext_dnr_testMatchOutcome.js +// +// And there are tests that verify matching with real network requests in +// toolkit/components/extensions/test/mochitest/test_ext_dnr_tabIds.html + +const server = createHttpServer({ hosts: ["from", "any", "in", "ex"] }); +server.registerPathHandler("/", (req, res) => { + res.setHeader("Access-Control-Allow-Origin", "*"); +}); + +let gTabLookupSpy; + +add_setup(async () => { + Services.prefs.setBoolPref("extensions.manifestV3.enabled", true); + Services.prefs.setBoolPref("extensions.dnr.enabled", true); + + // Install a spy on WebRequest.getTabIdForChannelWrapper. + const { WebRequest } = ChromeUtils.importESModule( + "resource://gre/modules/WebRequest.sys.mjs" + ); + const { sinon } = ChromeUtils.importESModule( + "resource://testing-common/Sinon.sys.mjs" + ); + gTabLookupSpy = sinon.spy(WebRequest, "getTabIdForChannelWrapper"); + + await ExtensionTestUtils.startAddonManager(); +}); + +function numberOfTabLookupsSinceLastCheck() { + let result = gTabLookupSpy.callCount; + gTabLookupSpy.resetHistory(); + return result; +} + +// This test checks that WebRequest.getTabIdForChannelWrapper is only called +// when there are any registered tabId/excludedTabIds rules. Moreover, it +// verifies that after unloading (reloading) the extension, that the method is +// still not called unnecessarily. +add_task(async function getTabIdForChannelWrapper_only_called_when_needed() { + async function background() { + const RULE_ANY_TAB_ID = { + id: 1, + condition: { requestDomains: ["from"] }, + action: { type: "redirect", redirect: { url: "http://any/" } }, + }; + const RULE_INCLUDE_TAB_ID = { + id: 2, + condition: { requestDomains: ["from"], tabIds: [-1] }, + action: { type: "redirect", redirect: { url: "http://in/" } }, + priority: 2, + }; + const RULE_EXCLUDE_TAB_ID = { + id: 3, + condition: { requestDomains: ["from"], excludedTabIds: [-1] }, + action: { type: "redirect", redirect: { url: "http://ex/" } }, + priority: 2, + }; + async function promiseOneMessage(messageName) { + return new Promise(resolve => { + browser.test.onMessage.addListener(function listener(msg, result) { + if (messageName === msg) { + browser.test.onMessage.removeListener(listener); + resolve(result); + } + }); + }); + } + async function numberOfTabLookupsSinceLastCheck() { + let promise = promiseOneMessage("tabLookups"); + browser.test.sendMessage("getTabLookups"); + return promise; + } + async function testFetchUrl(url, expectedUrl, expectedCount, description) { + let res = await fetch(url); + browser.test.assertEq(expectedUrl, res.url, `Final URL for ${url}`); + browser.test.assertEq( + expectedCount, + await numberOfTabLookupsSinceLastCheck(), + `Expected number of tab lookups - ${url} - ${description}` + ); + } + + const startupCountPromise = promiseOneMessage("extensionStartupCount"); + browser.test.sendMessage("extensionStarted"); + const startupCount = await startupCountPromise; + if (startupCount !== 0) { + browser.test.assertEq(1, startupCount, "Extension restarted once"); + + // Note: declarativeNetRequest.updateSessionRules is intentionally not + // called here, because we want to verify that upon unloading the + // extension, that the tabId lookup logic was properly cleaned up, + // i.e. that NetworkIntegration.maybeUpdateTabIdChecker() was called. + + await testFetchUrl( + "http://from/?after-restart-supposedly-no-include-tab", + "http://from/?after-restart-supposedly-no-include-tab", + 0, + "No lookup because session rules should have disappeared at reload" + ); + + browser.test.assertDeepEq( + [], + await browser.declarativeNetRequest.getSessionRules(), + "The session rules have indeed been cleared upon reload." + ); + + browser.test.sendMessage("test_completed_after_reload"); + return; + } + + browser.test.assertEq( + 0, + await numberOfTabLookupsSinceLastCheck(), + "Initially, no tab lookups" + ); + + await testFetchUrl( + "http://from/?no_dnr_rules", + "http://from/?no_dnr_rules", + 0, + "No tab lookups without any registered DNR rules" + ); + + await browser.declarativeNetRequest.updateSessionRules({ + addRules: [RULE_ANY_TAB_ID], + }); + // Active rules now: RULE_ANY_TAB_ID + + await testFetchUrl( + "http://from/?only_dnr_rule_matches_any_tab", + "http://any/", + 0, + "No tab lookups when only rule has no tabIds/excludedTabIds conditions" + ); + + await browser.declarativeNetRequest.updateSessionRules({ + addRules: [RULE_EXCLUDE_TAB_ID], + }); + // Active rules now: RULE_ANY_TAB_ID, RULE_EXCLUDE_TAB_ID + + await testFetchUrl( + "http://from/?dnr_rule_matches_any,dnr_rule_excludes_-1", + // should be "any" instead of "ex" because excludedTabIds: [-1] should + // exclude the background. + "http://any/", + 2, // initial request + redirect request. + "Expected tabId lookup when a tabId rule is registered" + ); + + await browser.declarativeNetRequest.updateSessionRules({ + removeRuleIds: [RULE_ANY_TAB_ID.id], + }); + // Active rules now: RULE_EXCLUDE_TAB_ID + + await testFetchUrl( + "http://from/?only_dnr_rule_excludes_-1", + // Not redirected to "ex" because excludedTabIds: [-1] does not match the + // background that has tabId -1. + "http://from/?only_dnr_rule_excludes_-1", + 1, + "Expected lookup after unregistering unrelated rule, keeping tabId rule" + ); + + await browser.declarativeNetRequest.updateSessionRules({ + addRules: [RULE_INCLUDE_TAB_ID], + }); + // Active rules now: RULE_EXCLUDE_TAB_ID, RULE_INCLUDE_TAB_ID + await testFetchUrl( + "http://from/?two_dnr_rule_include_and_exclude_-1", + "http://in/", + 2, // initial request + redirect request. + "Expecting lookup because of 2 DNR rules with tabId and excludedTabIds" + ); + + await browser.declarativeNetRequest.updateSessionRules({ + removeRuleIds: [RULE_EXCLUDE_TAB_ID.id], + }); + // Active rules now: RULE_INCLUDE_TAB_ID + + await testFetchUrl( + "http://from/?only_dnr_rule_includes_-1", + "http://in/", + 2, // initial request + redirect request. + "Expecting lookup because of remaining tabId DNR rule" + ); + + await browser.declarativeNetRequest.updateSessionRules({ + removeRuleIds: [RULE_INCLUDE_TAB_ID.id], + }); + // Active rules now: none + + await testFetchUrl( + "http://from/?no_rules_again", + "http://from/?no_rules_again", + 0, + "Expected no lookups after unregistering the last remaining rule" + ); + + await browser.declarativeNetRequest.updateSessionRules({ + addRules: [RULE_INCLUDE_TAB_ID], + }); + // Active rules now: RULE_INCLUDE_TAB_ID + + await testFetchUrl( + "http://from/?again_with-include-1", + "http://in/", + 2, // initial request + redirect request. + "Expecting lookup again because of include rule" + ); + + // Ending test with remaining rule: RULE_INCLUDE_TAB_ID + // Reload extension. + browser.test.sendMessage("reload_extension"); + } + let extension = ExtensionTestUtils.loadExtension({ + background, + useAddonManager: "temporary", // for reload and granted_host_permissions. + allowInsecureRequests: true, + manifest: { + manifest_version: 3, + host_permissions: ["*://from/*"], + granted_host_permissions: true, + permissions: ["declarativeNetRequest"], + }, + }); + extension.onMessage("getTabLookups", () => { + extension.sendMessage("tabLookups", numberOfTabLookupsSinceLastCheck()); + }); + let startupCount = 0; + extension.onMessage("extensionStarted", () => { + extension.sendMessage("extensionStartupCount", startupCount++); + }); + await extension.startup(); + await extension.awaitMessage("reload_extension"); + await extension.addon.reload(); + await extension.awaitMessage("test_completed_after_reload"); + Assert.equal( + 0, + numberOfTabLookupsSinceLastCheck(), + "No new tab lookups since completion of extension tests" + ); + await extension.unload(); +}); -- cgit v1.2.3