From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../rs-blocklist/test_blocklist_mlbf_update.js | 75 ++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_blocklist_mlbf_update.js (limited to 'toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_blocklist_mlbf_update.js') diff --git a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_blocklist_mlbf_update.js b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_blocklist_mlbf_update.js new file mode 100644 index 0000000000..b98d6e345d --- /dev/null +++ b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_blocklist_mlbf_update.js @@ -0,0 +1,75 @@ +/* Any copyright is dedicated to the Public Domain. + * https://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * @fileOverview Checks that the MLBF updating logic works reasonably. + */ + +Services.prefs.setBoolPref("extensions.blocklist.useMLBF", true); +const ExtensionBlocklistMLBF = getExtensionBlocklistMLBF(); + +// This test needs to interact with the RemoteSettings client. +ExtensionBlocklistMLBF.ensureInitialized(); + +// Multiple internal calls to update should be coalesced and end up with the +// MLBF attachment from the last update call. +add_task(async function collapse_multiple_pending_update_requests() { + const observed = []; + + // The first step of starting an update is to read from the RemoteSettings + // collection. When a non-forced update is requested while another update is + // pending, the non-forced update should return/await the previous call + // instead of starting a new read/fetch from the RemoteSettings collection. + // Add a spy to the RemoteSettings client, so we can verify that the number + // of RemoteSettings accesses matches with what we expect. + const originalClientGet = ExtensionBlocklistMLBF._client.get; + const spyClientGet = (tag, returnValue) => { + ExtensionBlocklistMLBF._client.get = async function () { + // Record the method call. + observed.push(tag); + // Clone a valid record and tag it so we can identify it below. + let dummyRecord = JSON.parse(JSON.stringify(MLBF_RECORD)); + dummyRecord.tagged = tag; + return [dummyRecord]; + }; + }; + + // Another significant part of updating is fetching the MLBF attachment. + // Add a spy too, so we can check which attachment is being requested. + const originalFetchMLBF = ExtensionBlocklistMLBF._fetchMLBF; + ExtensionBlocklistMLBF._fetchMLBF = async function (record) { + observed.push(`fetchMLBF:${record.tagged}`); + throw new Error(`Deliberately ignoring call to MLBF:${record.tagged}`); + }; + + spyClientGet("initial"); // Very first call = read RS. + let update1 = ExtensionBlocklistMLBF._updateMLBF(false); + spyClientGet("unexpected update2"); // Non-forced update = reuse update1. + let update2 = ExtensionBlocklistMLBF._updateMLBF(false); + spyClientGet("forced1"); // forceUpdate=true = supersede previous update. + let forcedUpdate1 = ExtensionBlocklistMLBF._updateMLBF(true); + spyClientGet("forced2"); // forceUpdate=true = supersede previous update. + let forcedUpdate2 = ExtensionBlocklistMLBF._updateMLBF(true); + + let res = await Promise.all([update1, update2, forcedUpdate1, forcedUpdate2]); + + Assert.equal(observed.length, 4, "expected number of observed events"); + Assert.equal(observed[0], "initial", "First update should request records"); + Assert.equal(observed[1], "forced1", "Forced update supersedes initial"); + Assert.equal(observed[2], "forced2", "Forced update supersedes forced1"); + // We call the _updateMLBF methods immediately after each other. Every update + // request starts with an asynchronous operation (looking up the RS records), + // so the implementation should return early for all update requests except + // for the last one. So we should only observe a fetch for the last request. + Assert.equal(observed[3], "fetchMLBF:forced2", "expected fetch result"); + + // All update requests should end up with the same result. + Assert.equal(res[0], res[1], "update1 == update2"); + Assert.equal(res[1], res[2], "update2 == forcedUpdate1"); + Assert.equal(res[2], res[3], "forcedUpdate1 == forcedUpdate2"); + + ExtensionBlocklistMLBF._client.get = originalClientGet; + ExtensionBlocklistMLBF._fetchMLBF = originalFetchMLBF; +}); -- cgit v1.2.3