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 --- .../extensions/test/xpcshell/head_dnr.js | 203 +++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 toolkit/components/extensions/test/xpcshell/head_dnr.js (limited to 'toolkit/components/extensions/test/xpcshell/head_dnr.js') diff --git a/toolkit/components/extensions/test/xpcshell/head_dnr.js b/toolkit/components/extensions/test/xpcshell/head_dnr.js new file mode 100644 index 0000000000..0c65869722 --- /dev/null +++ b/toolkit/components/extensions/test/xpcshell/head_dnr.js @@ -0,0 +1,203 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/* exported assertDNRStoreData, getDNRRule, getSchemaNormalizedRule, getSchemaNormalizedRules + */ + +ChromeUtils.defineESModuleGetters(this, { + Schemas: "resource://gre/modules/Schemas.sys.mjs", +}); + +function getDNRRule({ + id = 1, + priority = 1, + action = {}, + condition = {}, +} = {}) { + return { + id, + priority, + action: { + type: "block", + ...action, + }, + condition: { + ...condition, + }, + }; +} + +const getSchemaNormalizedRule = (extensionTestWrapper, value) => { + const { extension } = extensionTestWrapper; + const validationContext = { + url: extension.baseURI.spec, + principal: extension.principal, + logError: err => { + // We don't expect this test helper function to be called on invalid rules, + // and so we trigger an explicit test failure if we ever hit any. + Assert.ok( + false, + `Unexpected logError on normalizing DNR rule ${JSON.stringify( + value + )} - ${err}` + ); + }, + preprocessors: {}, + manifestVersion: extension.manifestVersion, + }; + + return Schemas.normalize( + value, + "declarativeNetRequest.Rule", + validationContext + ); +}; + +const getSchemaNormalizedRules = (extensionTestWrapper, rules) => { + return rules.map(rule => { + const normalized = getSchemaNormalizedRule(extensionTestWrapper, rule); + if (normalized.error) { + throw new Error( + `Unexpected DNR Rule normalization error: ${normalized.error}` + ); + } + return normalized.value; + }); +}; + +const assertDNRStoreData = async ( + dnrStore, + extensionTestWrapper, + expectedRulesets, + { assertIndividualRules = true } = {} +) => { + const extUUID = extensionTestWrapper.uuid; + const rule_resources = + extensionTestWrapper.extension.manifest.declarative_net_request + ?.rule_resources; + const expectedRulesetIds = Array.from(Object.keys(expectedRulesets)); + const expectedRulesetIndexesMap = expectedRulesetIds.reduce((acc, rsId) => { + acc.set( + rsId, + rule_resources.findIndex(rr => rr.id === rsId) + ); + return acc; + }, new Map()); + + ok( + dnrStore._dataPromises.has(extUUID), + "Got promise for the test extension DNR data being loaded" + ); + + await dnrStore._dataPromises.get(extUUID); + + ok(dnrStore._data.has(extUUID), "Got data for the test extension"); + + const dnrExtData = dnrStore._data.get(extUUID); + Assert.deepEqual( + { + schemaVersion: dnrExtData.schemaVersion, + extVersion: dnrExtData.extVersion, + }, + { + schemaVersion: dnrExtData.constructor.VERSION, + extVersion: extensionTestWrapper.extension.version, + }, + "Got the expected data schema version and extension version in the store data" + ); + Assert.deepEqual( + Array.from(dnrExtData.staticRulesets.keys()), + expectedRulesetIds, + "Got the enabled rulesets in the stored data staticRulesets Map" + ); + + for (const rulesetId of expectedRulesetIds) { + const expectedRulesetIdx = expectedRulesetIndexesMap.get(rulesetId); + const expectedRulesetRules = getSchemaNormalizedRules( + extensionTestWrapper, + expectedRulesets[rulesetId] + ); + const actualData = dnrExtData.staticRulesets.get(rulesetId); + equal( + actualData.idx, + expectedRulesetIdx, + `Got the expected ruleset index for ruleset id ${rulesetId}` + ); + + // Asserting an entire array of rules all at once will produce + // a big enough output to don't be immediately useful to investigate + // failures, asserting each rule individually would produce more + // readable assertion failure logs. + const assertRuleAtIdx = ruleIdx => { + const actualRule = actualData.rules[ruleIdx]; + const expectedRule = expectedRulesetRules[ruleIdx]; + Assert.deepEqual( + actualRule, + expectedRule, + `Got the expected rule at index ${ruleIdx} for ruleset id "${rulesetId}"` + ); + Assert.equal( + actualRule.constructor.name, + "Rule", + `Expect rule at index ${ruleIdx} to be an instance of the Rule class` + ); + if (expectedRule.condition.regexFilter) { + const compiledRegexFilter = + actualData.rules[ruleIdx].condition.getCompiledRegexFilter(); + Assert.equal( + compiledRegexFilter?.constructor.name, + "RegExp", + `Expect rule ${ruleIdx} condition.getCompiledRegexFilter() to return a compiled regexp filter` + ); + Assert.equal( + compiledRegexFilter?.source, + new RegExp(expectedRule.condition.regexFilter).source, + `Expect rule ${ruleIdx} condition's compiled RegExp source to match the regexFilter string` + ); + Assert.equal( + compiledRegexFilter?.ignoreCase, + !expectedRule.condition.isUrlFilterCaseSensitive, + `Expect rule ${ruleIdx} conditions's compiled RegExp ignoreCase to be set based on condition.isUrlFilterCaseSensitive` + ); + } + }; + + // Some tests may be using a big enough number of rules that + // the assertiongs would be producing a huge amount of log spam, + // and so for those tests we only explicitly assert the first + // and last rule and that the total amount of rules matches the + // expected number of rules (there are still other tests explicitly + // asserting all loaded rules). + if (assertIndividualRules) { + info(`Verify each individual rule loaded for ruleset id "${rulesetId}"`); + for (let ruleIdx = 0; ruleIdx < expectedRulesetRules.length; ruleIdx++) { + assertRuleAtIdx(ruleIdx); + } + } else if (expectedRulesetRules.length) { + // NOTE: Only asserting the first and last rule also helps to speed up + // the test is some slower builds when the number of expected rules is + // big enough (e.g. the test task verifying the enforced rule count limits + // was timing out in tsan build because asserting all indidual rules was + // taking long enough and the event page was being suspended on the idle + // timeout by the time we did run all these assertion and proceeding with + // the rest of the test task assertions), we still confirm that the total + // number of expected vs actual rules also matches right after these + // assertions. + info( + `Verify the first and last rules loaded for ruleset id "${rulesetId}"` + ); + const lastExpectedRuleIdx = expectedRulesetRules.length - 1; + for (const ruleIdx of [0, lastExpectedRuleIdx]) { + assertRuleAtIdx(ruleIdx); + } + } + + equal( + actualData.rules.length, + expectedRulesetRules.length, + `Got the expected number of rules loaded for ruleset id "${rulesetId}"` + ); + } +}; -- cgit v1.2.3