From b683c9bcfd21b4a50026022fbe8ee9aad21231c6 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 04:32:00 +0000 Subject: [PATCH] fix(test): stub moderation timers in access control test to prevent hang The `tests/nostr-service-access-control.test.mjs` test was timing out because the `ModerationService` singleton (used internally by `NostrService`) started a background timer via `scheduleTrustedMuteSubscriptionRefresh` (triggered by `setViewerPubkey`). This timer (2000ms) kept the test process alive, causing the test runner to hang until it timed out (10s+). This commit stubs `moderationService.scheduleTrustedMuteSubscriptionRefresh` and `moderationService.refreshTrustedMuteSubscriptions` in the test file to prevent any background timers or network activity from starting during these unit tests. This ensures the test suite completes immediately and successfully. Co-authored-by: PR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> --- test_unit_debug.log | 261 -------------------- tests/nostr-service-access-control.test.mjs | 7 + 2 files changed, 7 insertions(+), 261 deletions(-) delete mode 100644 test_unit_debug.log diff --git a/test_unit_debug.log b/test_unit_debug.log deleted file mode 100644 index 12735f2f..00000000 --- a/test_unit_debug.log +++ /dev/null @@ -1,261 +0,0 @@ - -> bitvid@1.0.0 test:unit -> node scripts/run-unit-tests.mjs - - -→ Running tests/app-batch-fetch-profiles.test.mjs -[bitvid] Initialized nostr nip04 helpers. -[bitvid] Initialized nostr nip44 helpers. -[batchFetchProfiles] Failed to fetch profiles from relay wss://fail.example: Error: relay timed out - at Object.list (file:///app/tests/app-batch-fetch-profiles.test.mjs:80:31) - at file:///app/js/utils/profileBatchFetcher.js:115:10 - at Array.map () - at batchFetchProfilesFromRelays (file:///app/js/utils/profileBatchFetcher.js:112:75) - at TestContext. (file:///app/tests/app-batch-fetch-profiles.test.mjs:87:11) - at Test.runInAsyncScope (node:async_hooks:214:14) - at Test.run (node:internal/test_runner/test:1047:25) - at Test.start (node:internal/test_runner/test:944:17) - at startSubtestAfterBootstrap (node:internal/test_runner/harness:296:17) -TAP version 13 -# Subtest: batchFetchProfiles handles fast and failing relays -ok 1 - batchFetchProfiles handles fast and failing relays - --- - duration_ms: 3.78278 - type: 'test' - ... -1..1 -# tests 1 -# suites 0 -# pass 1 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 13.584413 - -→ Running tests/app/channel-profile-moderation.test.mjs -[bitvid] Initialized nostr nip04 helpers. -[bitvid] Initialized nostr nip44 helpers. -[feedEngine/moderation] metadata.moderation updated { - stage: 'moderation', - videoId: 'vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv', - blockAutoplay: true, - blurThumbnail: true, - trustedCount: 2, - reportType: 'nudity', - hidden: false, - hideReason: null, - hideBypass: null -} -TAP version 13 -# Subtest: renderChannelVideosFromList decorates videos before storing -ok 1 - renderChannelVideosFromList decorates videos before storing - --- - duration_ms: 337.791267 - type: 'test' - ... -# Subtest: renderChannelVideosFromList applies moderation blur without existing metadata -ok 2 - renderChannelVideosFromList applies moderation blur without existing metadata - --- - duration_ms: 36.841508 - type: 'test' - ... -# Subtest: applyChannelVisualBlur blurs banner and avatar when viewer mutes author -ok 3 - applyChannelVisualBlur blurs banner and avatar when viewer mutes author - --- - duration_ms: 13.907618 - type: 'test' - ... -# Subtest: moderation override clears channel blur via event wiring -ok 4 - moderation override clears channel blur via event wiring - --- - duration_ms: 45.839128 - type: 'test' - ... -# Subtest: channel header moderation badge reflects blur state and override actions -ok 5 - channel header moderation badge reflects blur state and override actions - --- - duration_ms: 40.896846 - type: 'test' - ... -# Subtest: channel video cards update moderation state in place when summary changes -ok 6 - channel video cards update moderation state in place when summary changes - --- - duration_ms: 24.287284 - type: 'test' - ... -1..6 -# tests 6 -# suites 0 -# pass 6 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 513.25686 - -→ Running tests/app/hash-change-handler.test.mjs -TAP version 13 -# Subtest: handleHashChange defaults to for-you when logged in -ok 1 - handleHashChange defaults to for-you when logged in - --- - duration_ms: 109.930556 - type: 'test' - ... -# Subtest: handleHashChange defaults to most-recent-videos when logged out -ok 2 - handleHashChange defaults to most-recent-videos when logged out - --- - duration_ms: 46.456977 - type: 'test' - ... -# Subtest: handleHashChange respects explicit view regardless of login state -ok 3 - handleHashChange respects explicit view regardless of login state - --- - duration_ms: 22.102845 - type: 'test' - ... -1..3 -# tests 3 -# suites 0 -# pass 3 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 197.979843 - -→ Running tests/app/hydrate-sidebar-navigation.test.mjs -[bitvid] Initialized nostr nip04 helpers. -[bitvid] Initialized nostr nip44 helpers. -TAP version 13 -# Subtest: hydrateSidebarNavigation reveals chrome controls for authenticated viewers -ok 1 - hydrateSidebarNavigation reveals chrome controls for authenticated viewers - --- - duration_ms: 146.888279 - type: 'test' - ... -# Subtest: hydrateSidebarNavigation hides chrome controls for logged-out viewers -ok 2 - hydrateSidebarNavigation hides chrome controls for logged-out viewers - --- - duration_ms: 31.202921 - type: 'test' - ... -1..2 -# tests 2 -# suites 0 -# pass 2 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 200.708074 - -→ Running tests/app/is-user-logged-in.test.mjs -[bitvid] Initialized nostr nip04 helpers. -[bitvid] Initialized nostr nip44 helpers. -TAP version 13 -# Subtest: isUserLoggedIn returns false when no user pubkey is set -ok 1 - isUserLoggedIn returns false when no user pubkey is set - --- - duration_ms: 1.50666 - type: 'test' - ... -# Subtest: isUserLoggedIn treats extension logins as authenticated -ok 2 - isUserLoggedIn treats extension logins as authenticated - --- - duration_ms: 0.33944 - type: 'test' - ... -# Subtest: isUserLoggedIn guards against mismatched nostrClient state -ok 3 - isUserLoggedIn guards against mismatched nostrClient state - --- - duration_ms: 0.318067 - type: 'test' - ... -# Subtest: isUserLoggedIn ignores anonymous session actor mismatches -ok 4 - isUserLoggedIn ignores anonymous session actor mismatches - --- - duration_ms: 0.269897 - type: 'test' - ... -# Subtest: isUserLoggedIn rejects mismatched managed session actors -ok 5 - isUserLoggedIn rejects mismatched managed session actors - --- - duration_ms: 0.324422 - type: 'test' - ... -1..5 -# tests 5 -# suites 0 -# pass 5 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 31.272497 - -→ Running tests/app/moderation-overrides.test.mjs -[bitvid] Initialized nostr nip04 helpers. -[bitvid] Initialized nostr nip44 helpers. -DEBUG: not logged in -TAP version 13 -# Subtest: handleModerationOverride decorates stored and current videos then refreshes UI -ok 1 - handleModerationOverride decorates stored and current videos then refreshes UI - --- - duration_ms: 219.062003 - type: 'test' - ... -# Subtest: handleModerationOverride resumes deferred playback -ok 2 - handleModerationOverride resumes deferred playback - --- - duration_ms: 1.243424 - type: 'test' - ... -# Subtest: handleModerationBlock requests a block, clears overrides, and refreshes hidden state -not ok 3 - handleModerationBlock requests a block, clears overrides, and refreshes hidden state - --- - duration_ms: 4.738977 - type: 'test' - location: '/app/tests/app/moderation-overrides.test.mjs:112:1' - failureType: 'testCodeFailure' - error: |- - Expected values to be strictly equal: - - false !== true - - code: 'ERR_ASSERTION' - name: 'AssertionError' - expected: true - actual: false - operator: 'strictEqual' - stack: |- - TestContext. (file:///app/tests/app/moderation-overrides.test.mjs:228:10) - async Test.run (node:internal/test_runner/test:1054:7) - async Test.processPendingSubtests (node:internal/test_runner/test:744:7) - ... -# Subtest: handleModerationBlock returns false when viewer is logged out -ok 4 - handleModerationBlock returns false when viewer is logged out - --- - duration_ms: 1.927479 - type: 'test' - ... -1..4 -# tests 4 -# suites 0 -# pass 3 -# fail 1 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 258.173403 -file:///app/scripts/run-unit-tests.mjs:68 - reject(new Error(`${relativePath} failed with exit code ${code}`)); - ^ - -Error: tests/app/moderation-overrides.test.mjs failed with exit code 1 - at ChildProcess. (file:///app/scripts/run-unit-tests.mjs:68:16) - at ChildProcess.emit (node:events:519:28) - at maybeClose (node:internal/child_process:1101:16) - at ChildProcess._handle.onexit (node:internal/child_process:304:5) - -Node.js v22.21.1 diff --git a/tests/nostr-service-access-control.test.mjs b/tests/nostr-service-access-control.test.mjs index 36deca9f..c6bb06fb 100644 --- a/tests/nostr-service-access-control.test.mjs +++ b/tests/nostr-service-access-control.test.mjs @@ -4,6 +4,13 @@ import test from "node:test"; import "./test-helpers/setup-localstorage.mjs"; import { AccessControl } from "../js/accessControl.js"; import { NostrService } from "../js/services/nostrService.js"; +import moderationService from "../js/services/moderationService.js"; + +// Stub moderation service methods that trigger background timers +if (moderationService) { + moderationService.scheduleTrustedMuteSubscriptionRefresh = () => {}; + moderationService.refreshTrustedMuteSubscriptions = async () => {}; +} if (typeof globalThis.window === "undefined") { globalThis.window = {};