tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 792a8ccf58ec9d8cc1adbc1e4a4a417c7018e485
parent a0e7334489e49a076bf97b9226a3865ce595b5d3
Author: Mike Conley <mconley@mozilla.com>
Date:   Wed, 17 Dec 2025 16:19:02 +0000

Bug 2001387 - Part 1: Have BrowserUtils.callModulesFromCategory return a Promise that resolves when all module tasks are settled. r=Gijs

Differential Revision: https://phabricator.services.mozilla.com/D276294

Diffstat:
Mtoolkit/modules/BrowserUtils.sys.mjs | 16++++++++++++++--
Mtoolkit/modules/tests/xpcshell/test_BrowserUtils.js | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/toolkit/modules/BrowserUtils.sys.mjs b/toolkit/modules/BrowserUtils.sys.mjs @@ -570,6 +570,8 @@ export var BrowserUtils = { * order to do custom failure handling. * @param {...any} args * Arguments to pass to the consumers. + * @returns {Promise} + * A Promise that resolves when all consumers have settled. */ callModulesFromCategory( { @@ -613,15 +615,25 @@ export var BrowserUtils = { } }; + let allTasks = []; + for (let listener of lazy.CatManListenerManager.getListeners( categoryName )) { if (idleDispatch) { - ChromeUtils.idleDispatch(() => callSingleListener(listener)); + allTasks.push( + new Promise(resolve => { + ChromeUtils.idleDispatch(() => { + resolve(callSingleListener(listener)); + }); + }) + ); } else { - callSingleListener(listener); + allTasks.push(callSingleListener(listener)); } } + + return Promise.allSettled(allTasks); }, /** diff --git a/toolkit/modules/tests/xpcshell/test_BrowserUtils.js b/toolkit/modules/tests/xpcshell/test_BrowserUtils.js @@ -386,6 +386,9 @@ add_task(async function test_callModulesFromCategory() { Assert.equal("Hello", await idlePromise, "Idle calls should run eventually."); Services.obs.removeObserver(ob, OBSTOPIC1); + + // Now clean up our category for later tests. + Services.catMan.deleteCategory(CATEGORY); }); // Test that errors are reported but do not throw at the callsite, @@ -449,4 +452,52 @@ add_task(async function test_callModulesFromCategory_errors() { "Uh oh", "Exceptions should be handled." ); + + // Now clean up our category for later tests. + Services.catMan.deleteCategory(OTHER_CAT); +}); + +/** + * Test that callModulesFromCategory returns a Promise that resolves when all + * category tasks have settled. + */ +add_task(async function test_callModulesFromCategory_returns_promise() { + const CATEGORY = "test-modules-from-catman"; + const MODULE1 = "resource://test/my_catman_1.sys.mjs"; + const OBSTOPIC1 = CATEGORY + "-notification"; + + let catManUpdated = TestUtils.topicObserved("xpcom-category-entry-added"); + Services.catMan.addCategoryEntry( + CATEGORY, + MODULE1, + `Module1.test`, + false, + false + ); + await catManUpdated; + + let moduleResult = TestUtils.topicObserved(OBSTOPIC1).then( + ([_subj, data]) => data + ); + + let result = BrowserUtils.callModulesFromCategory( + { categoryName: CATEGORY }, + "Hello" + ); + + Assert.ok(result.then, "Should return a Promise"); + + let settledResults = await result; + Assert.ok(Array.isArray(settledResults), "Should return an array of results"); + Assert.equal(settledResults.length, 1, "Should have one result"); + Assert.equal( + settledResults[0].status, + "fulfilled", + "Task should have been fulfilled" + ); + + Assert.equal(await moduleResult, "Hello", "Module should have been called"); + + // Now clean up our category for later tests. + Services.catMan.deleteCategory(CATEGORY); });