summaryrefslogtreecommitdiffstats
path: root/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_blocklist_mlbf_update.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_blocklist_mlbf_update.js')
-rw-r--r--toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_blocklist_mlbf_update.js75
1 files changed, 75 insertions, 0 deletions
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;
+});