From c725b480807654356d42c9905545a797a023ed49 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 27 Jan 2026 14:45:40 +0000 Subject: [PATCH] fix(tests): resolve race condition in moderation overrides test Refactor `ModerationActionController` initialization in test harness to support dependency injection for `userBlocks`. This allows tests to use isolated mock instances instead of monkey-patching the global singleton, preventing race conditions when tests run in parallel or overlap. Fixes intermittent failures in `tests/app/moderation-overrides.test.mjs` where `userBlocks` state leaked between tests. Co-authored-by: PR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> --- tests/app/moderation-overrides.test.mjs | 66 +++++++++-------------- tests/helpers/moderation-test-helpers.mjs | 4 +- 2 files changed, 27 insertions(+), 43 deletions(-) diff --git a/tests/app/moderation-overrides.test.mjs b/tests/app/moderation-overrides.test.mjs index e700197a..f41d15b6 100644 --- a/tests/app/moderation-overrides.test.mjs +++ b/tests/app/moderation-overrides.test.mjs @@ -112,7 +112,21 @@ test("handleModerationOverride resumes deferred playback", async (t) => { test("handleModerationBlock requests a block, clears overrides, and refreshes hidden state", async (t) => { withMockedNostrTools(t); - const app = await createModerationAppHarness(); + const ensureLoadedMock = mock.fn(async () => {}); + let blockedState = false; + const addBlockMock = mock.fn(async () => { + blockedState = true; + return { ok: true }; + }); + const isBlockedMock = mock.fn(() => blockedState); + + const mockUserBlocks = { + ensureLoaded: ensureLoadedMock, + addBlock: addBlockMock, + isBlocked: isBlockedMock, + }; + + const app = await createModerationAppHarness({ userBlocks: mockUserBlocks }); app.getActiveModerationThresholds = () => ({ autoplayBlockThreshold: Number.POSITIVE_INFINITY, blurThreshold: Number.POSITIVE_INFINITY, @@ -179,28 +193,6 @@ test("handleModerationBlock requests a block, clears overrides, and refreshes hi }, }; - const originalEnsureLoaded = userBlocks.ensureLoaded; - const originalAddBlock = userBlocks.addBlock; - const originalIsBlocked = userBlocks.isBlocked; - - const ensureLoadedMock = mock.fn(async () => {}); - let blockedState = false; - const addBlockMock = mock.fn(async () => { - blockedState = true; - return { ok: true }; - }); - const isBlockedMock = mock.fn(() => blockedState); - - userBlocks.ensureLoaded = ensureLoadedMock; - userBlocks.addBlock = addBlockMock; - userBlocks.isBlocked = isBlockedMock; - - t.after(() => { - userBlocks.ensureLoaded = originalEnsureLoaded; - userBlocks.addBlock = originalAddBlock; - userBlocks.isBlocked = originalIsBlocked; - }); - await app.handleModerationOverride({ video: incomingVideo, card }); assert.equal(storedVideo.moderation.viewerOverride?.showAnyway, true); @@ -237,29 +229,21 @@ test("handleModerationBlock requests a block, clears overrides, and refreshes hi test("handleModerationBlock returns false when viewer is logged out", async (t) => { withMockedNostrTools(t); - const app = await createModerationAppHarness(); - app.pubkey = "f".repeat(64); - app.isUserLoggedIn = () => false; - app.showStatus = mock.fn(() => {}); - app.showError = mock.fn(() => {}); - - const originalEnsureLoaded = userBlocks.ensureLoaded; - const originalAddBlock = userBlocks.addBlock; - const originalIsBlocked = userBlocks.isBlocked; - const ensureLoadedMock = mock.fn(async () => {}); const addBlockMock = mock.fn(async () => ({ ok: true })); const isBlockedMock = mock.fn(() => false); - userBlocks.ensureLoaded = ensureLoadedMock; - userBlocks.addBlock = addBlockMock; - userBlocks.isBlocked = isBlockedMock; + const mockUserBlocks = { + ensureLoaded: ensureLoadedMock, + addBlock: addBlockMock, + isBlocked: isBlockedMock, + }; - t.after(() => { - userBlocks.ensureLoaded = originalEnsureLoaded; - userBlocks.addBlock = originalAddBlock; - userBlocks.isBlocked = originalIsBlocked; - }); + const app = await createModerationAppHarness({ userBlocks: mockUserBlocks }); + app.pubkey = "f".repeat(64); + app.isUserLoggedIn = () => false; + app.showStatus = mock.fn(() => {}); + app.showError = mock.fn(() => {}); const video = { id: "c".repeat(64), diff --git a/tests/helpers/moderation-test-helpers.mjs b/tests/helpers/moderation-test-helpers.mjs index b22338db..1b8b4431 100644 --- a/tests/helpers/moderation-test-helpers.mjs +++ b/tests/helpers/moderation-test-helpers.mjs @@ -199,7 +199,7 @@ async function getApplicationClass() { return cachedApplicationClass; } -export async function createModerationAppHarness() { +export async function createModerationAppHarness(options = {}) { const Application = await getApplicationClass(); const app = Object.create(Application.prototype); @@ -222,7 +222,7 @@ export async function createModerationAppHarness() { app.moderationActionController = new ModerationActionController({ services: { - userBlocks, + userBlocks: options.userBlocks || userBlocks, setModerationOverride, clearModerationOverride, },