forked from mirrors/gecko-dev
Depends on D175553 Differential Revision: https://phabricator.services.mozilla.com/D176005
249 lines
8.3 KiB
JavaScript
249 lines
8.3 KiB
JavaScript
"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();
|
|
});
|