diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ef48651e..43f7470b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -74,6 +74,15 @@ To set up the project locally: For a full guide, see the [Local Setup section in README.md](./README.md#local-setup). +## Dev Container + +This project includes a `.devcontainer` configuration for VS Code. It provides a pre-configured environment with Node.js 22 and necessary extensions. + +To use it: +1. Open the project in VS Code. +2. When prompted, re-open in Container (or use the command palette: "Dev Containers: Reopen in Container"). +3. The container will automatically install dependencies and run the build. + ## Security If you find a vulnerability, please email **[security@bitvid.network](mailto:security@bitvid.network)**. We’ll coordinate a responsible disclosure window before public release. diff --git a/scripts/check-design-tokens.mjs b/scripts/check-design-tokens.mjs index 64133f99..2abe95f6 100755 --- a/scripts/check-design-tokens.mjs +++ b/scripts/check-design-tokens.mjs @@ -35,6 +35,8 @@ const VALUE_ALLOWLIST = new Map([ // Ignore matches inside var() declarations that happen to contain units in the name (value, snippet) => snippet.includes(`var(--`) && snippet.includes(value), + // Mobile breakpoint used in media query + (value) => value === "767.98px", ], ], ]); diff --git a/test_unit.log b/test_unit.log new file mode 100644 index 00000000..71be1601 --- /dev/null +++ b/test_unit.log @@ -0,0 +1,241 @@ + +> 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.595152 + type: 'test' + ... +1..1 +# tests 1 +# suites 0 +# pass 1 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 13.23252 + +→ Running tests/app/channel-profile-moderation.test.mjs +[bitvid] Initialized nostr nip04 helpers. +[bitvid] Initialized nostr nip44 helpers. +[ChannelProfile] Failed to prepare channel videos for moderation TypeError: Cannot read properties of undefined (reading 'normalizeModerationSettings') + at Application.getActiveModerationThresholds (file:///app/js/app.js:6593:56) + at applyChannelModerationToVideos (file:///app/js/channelProfile.js:282:21) + at renderChannelVideosFromList (file:///app/js/channelProfile.js:4490:28) + at TestContext. (file:///app/tests/app/channel-profile-moderation.test.mjs:135:26) + at async Test.run (node:internal/test_runner/test:1054:7) + at async startSubtestAfterBootstrap (node:internal/test_runner/harness:296:3) +[feedEngine/moderation] metadata.moderation updated { + stage: 'moderation', + videoId: 'vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv', + blockAutoplay: true, + blurThumbnail: true, + trustedCount: 2, + reportType: 'nudity', + hidden: false, + hideReason: null, + hideBypass: null +} +[ChannelProfile] Failed to decorate channel video moderation TypeError: Cannot read properties of undefined (reading 'decorateVideo') + at Application.decorateVideoModeration (file:///app/js/app.js:6598:37) + at decorateChannelVideo (file:///app/js/channelProfile.js:210:29) + at applyChannelModerationToVideos (file:///app/js/channelProfile.js:363:26) + at async renderChannelVideosFromList (file:///app/js/channelProfile.js:4490:22) + at async TestContext. (file:///app/tests/app/channel-profile-moderation.test.mjs:216:20) + at async Test.run (node:internal/test_runner/test:1054:7) + at async Test.processPendingSubtests (node:internal/test_runner/test:744:7) +[ChannelProfile] Failed to decorate channel video moderation TypeError: Cannot read properties of undefined (reading 'decorateVideo') + at Application.decorateVideoModeration (file:///app/js/app.js:6598:37) + at decorateChannelVideo (file:///app/js/channelProfile.js:210:29) + at resolveChannelModeration (file:///app/js/channelProfile.js:917:23) + at applyChannelVisualBlur (file:///app/js/channelProfile.js:962:22) + at updateChannelModerationVisuals (file:///app/js/channelProfile.js:1027:18) + at renderChannelVideosFromList (file:///app/js/channelProfile.js:4893:3) + at async TestContext. (file:///app/tests/app/channel-profile-moderation.test.mjs:216:20) + at async Test.run (node:internal/test_runner/test:1054:7) + at async Test.processPendingSubtests (node:internal/test_runner/test:744:7) +[ChannelProfile] Failed to decorate channel video moderation TypeError: Cannot read properties of undefined (reading 'decorateVideo') + at Application.decorateVideoModeration (file:///app/js/app.js:6598:37) + at decorateChannelVideo (file:///app/js/channelProfile.js:210:29) + at applyChannelModerationToVideos (file:///app/js/channelProfile.js:363:26) + at async renderChannelVideosFromList (file:///app/js/channelProfile.js:4490:22) + at async TestContext. (file:///app/tests/app/channel-profile-moderation.test.mjs:309:3) + at async Test.run (node:internal/test_runner/test:1054:7) + at async Test.processPendingSubtests (node:internal/test_runner/test:744:7) +[ChannelProfile] Failed to decorate channel video moderation TypeError: Cannot read properties of undefined (reading 'decorateVideo') + at Application.decorateVideoModeration (file:///app/js/app.js:6598:37) + at decorateChannelVideo (file:///app/js/channelProfile.js:210:29) + at resolveChannelModeration (file:///app/js/channelProfile.js:917:23) + at applyChannelVisualBlur (file:///app/js/channelProfile.js:962:22) + at updateChannelModerationVisuals (file:///app/js/channelProfile.js:1027:18) + at renderChannelVideosFromList (file:///app/js/channelProfile.js:4893:3) + at async TestContext. (file:///app/tests/app/channel-profile-moderation.test.mjs:309:3) + at async Test.run (node:internal/test_runner/test:1054:7) + at async Test.processPendingSubtests (node:internal/test_runner/test:744:7) +[ChannelProfile] Failed to decorate channel video moderation TypeError: Cannot read properties of undefined (reading 'decorateVideo') + at Application.decorateVideoModeration (file:///app/js/app.js:6598:37) + at decorateChannelVideo (file:///app/js/channelProfile.js:210:29) + at applyChannelModerationToVideos (file:///app/js/channelProfile.js:363:26) + at async renderChannelVideosFromList (file:///app/js/channelProfile.js:4490:22) + at async TestContext. (file:///app/tests/app/channel-profile-moderation.test.mjs:383:3) + at async Test.run (node:internal/test_runner/test:1054:7) + at async Test.processPendingSubtests (node:internal/test_runner/test:744:7) +[ChannelProfile] Failed to decorate channel video moderation TypeError: Cannot read properties of undefined (reading 'decorateVideo') + at Application.decorateVideoModeration (file:///app/js/app.js:6598:37) + at decorateChannelVideo (file:///app/js/channelProfile.js:210:29) + at resolveChannelModeration (file:///app/js/channelProfile.js:917:23) + at applyChannelVisualBlur (file:///app/js/channelProfile.js:962:22) + at updateChannelModerationVisuals (file:///app/js/channelProfile.js:1027:18) + at renderChannelVideosFromList (file:///app/js/channelProfile.js:4893:3) + at async TestContext. (file:///app/tests/app/channel-profile-moderation.test.mjs:383:3) + at async Test.run (node:internal/test_runner/test:1054:7) + at async Test.processPendingSubtests (node:internal/test_runner/test:744:7) +[ChannelProfile] Failed to decorate channel video moderation TypeError: Cannot read properties of undefined (reading 'decorateVideo') + at Application.decorateVideoModeration (file:///app/js/app.js:6598:37) + at decorateChannelVideo (file:///app/js/channelProfile.js:210:29) + at resolveChannelModeration (file:///app/js/channelProfile.js:917:23) + at applyChannelVisualBlur (file:///app/js/channelProfile.js:962:22) + at TestContext. (file:///app/tests/app/channel-profile-moderation.test.mjs:390:3) + at async Test.run (node:internal/test_runner/test:1054:7) + at async Test.processPendingSubtests (node:internal/test_runner/test:744:7) +[ChannelProfile] Failed to decorate channel video moderation TypeError: Cannot read properties of undefined (reading 'decorateVideo') + at Application.decorateVideoModeration (file:///app/js/app.js:6598:37) + at decorateChannelVideo (file:///app/js/channelProfile.js:210:29) + at resolveChannelModeration (file:///app/js/channelProfile.js:917:23) + at applyChannelVisualBlur (file:///app/js/channelProfile.js:962:22) + at updateChannelModerationVisuals (file:///app/js/channelProfile.js:1027:18) + at handleChannelModerationOverride (file:///app/js/channelProfile.js:804:5) + at channelModerationBadgeState.boundOverride (file:///app/js/channelProfile.js:570:7) + at HTMLButtonElement.callTheUserObjectsOperation (/app/node_modules/jsdom/lib/jsdom/living/generated/EventListener.js:26:30) + at innerInvokeEventListeners (/app/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:350:25) + at invokeEventListeners (/app/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:286:3) +TAP version 13 +# Subtest: renderChannelVideosFromList decorates videos before storing +ok 1 - renderChannelVideosFromList decorates videos before storing + --- + duration_ms: 227.825736 + type: 'test' + ... +# Subtest: renderChannelVideosFromList applies moderation blur without existing metadata +ok 2 - renderChannelVideosFromList applies moderation blur without existing metadata + --- + duration_ms: 29.073289 + 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: 10.234244 + type: 'test' + ... +# Subtest: moderation override clears channel blur via event wiring +not ok 4 - moderation override clears channel blur via event wiring + --- + duration_ms: 27.303235 + type: 'test' + location: '/app/tests/app/channel-profile-moderation.test.mjs:261:1' + failureType: 'testCodeFailure' + error: |- + Expected values to be strictly equal: + + actual - expected + + + undefined + - 'blurred' + + code: 'ERR_ASSERTION' + name: 'AssertionError' + expected: 'blurred' + operator: 'strictEqual' + stack: |- + TestContext. (file:///app/tests/app/channel-profile-moderation.test.mjs:318:10) + async Test.run (node:internal/test_runner/test:1054:7) + async Test.processPendingSubtests (node:internal/test_runner/test:744:7) + ... +[ChannelProfile] Failed to decorate channel video moderation TypeError: Cannot read properties of undefined (reading 'decorateVideo') + at Application.decorateVideoModeration (file:///app/js/app.js:6598:37) + at decorateChannelVideo (file:///app/js/channelProfile.js:210:29) + at applyChannelModerationToVideos (file:///app/js/channelProfile.js:363:26) + at async renderChannelVideosFromList (file:///app/js/channelProfile.js:4490:22) + at async TestContext. (file:///app/tests/app/channel-profile-moderation.test.mjs:477:3) + at async Test.run (node:internal/test_runner/test:1054:7) + at async Test.processPendingSubtests (node:internal/test_runner/test:744:7) +[ChannelProfile] Failed to decorate channel video moderation TypeError: Cannot read properties of undefined (reading 'decorateVideo') + at Application.decorateVideoModeration (file:///app/js/app.js:6598:37) + at decorateChannelVideo (file:///app/js/channelProfile.js:210:29) + at resolveChannelModeration (file:///app/js/channelProfile.js:917:23) + at applyChannelVisualBlur (file:///app/js/channelProfile.js:962:22) + at updateChannelModerationVisuals (file:///app/js/channelProfile.js:1027:18) + at renderChannelVideosFromList (file:///app/js/channelProfile.js:4893:3) + at async TestContext. (file:///app/tests/app/channel-profile-moderation.test.mjs:477:3) + at async Test.run (node:internal/test_runner/test:1054:7) + at async Test.processPendingSubtests (node:internal/test_runner/test:744:7) +[ChannelProfile] Failed to decorate channel video moderation TypeError: Cannot read properties of undefined (reading 'decorateVideo') + at Application.decorateVideoModeration (file:///app/js/app.js:6598:37) + at decorateChannelVideo (file:///app/js/channelProfile.js:210:29) + at handleModerationSummarySignal (file:///app/js/channelProfile.js:1139:26) + at SimpleEventEmitter.emit (file:///app/js/services/moderationService.js:61:9) + at ModerationService.emit (file:///app/js/services/moderationService.js:979:18) + at TestContext. (file:///app/tests/app/channel-profile-moderation.test.mjs:513:21) + at async Test.run (node:internal/test_runner/test:1054:7) + at async Test.processPendingSubtests (node:internal/test_runner/test:744:7) +[ChannelProfile] Failed to decorate channel video moderation TypeError: Cannot read properties of undefined (reading 'decorateVideo') + at Application.decorateVideoModeration (file:///app/js/app.js:6598:37) + at decorateChannelVideo (file:///app/js/channelProfile.js:210:29) + at resolveChannelModeration (file:///app/js/channelProfile.js:917:23) + at applyChannelVisualBlur (file:///app/js/channelProfile.js:962:22) + at updateChannelModerationVisuals (file:///app/js/channelProfile.js:1027:18) + at handleModerationSummarySignal (file:///app/js/channelProfile.js:1145:3) + at SimpleEventEmitter.emit (file:///app/js/services/moderationService.js:61:9) + at ModerationService.emit (file:///app/js/services/moderationService.js:979:18) + at TestContext. (file:///app/tests/app/channel-profile-moderation.test.mjs:513:21) + at async Test.run (node:internal/test_runner/test:1054:7) +# 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: 29.747436 + 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: 21.934654 + type: 'test' + ... +1..6 +# tests 6 +# suites 0 +# pass 5 +# fail 1 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 357.18362 +file:///app/scripts/run-unit-tests.mjs:68 + reject(new Error(`${relativePath} failed with exit code ${code}`)); + ^ + +Error: tests/app/channel-profile-moderation.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/test_unit_debug.log b/test_unit_debug.log new file mode 100644 index 00000000..12735f2f --- /dev/null +++ b/test_unit_debug.log @@ -0,0 +1,261 @@ + +> 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/test_unit_debug_2.log b/test_unit_debug_2.log new file mode 100644 index 00000000..8b769556 --- /dev/null +++ b/test_unit_debug_2.log @@ -0,0 +1,260 @@ + +> 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.910398 + type: 'test' + ... +1..1 +# tests 1 +# suites 0 +# pass 1 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 26.765285 + +→ 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: 255.735327 + type: 'test' + ... +# Subtest: renderChannelVideosFromList applies moderation blur without existing metadata +ok 2 - renderChannelVideosFromList applies moderation blur without existing metadata + --- + duration_ms: 31.654581 + 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: 10.838215 + type: 'test' + ... +# Subtest: moderation override clears channel blur via event wiring +ok 4 - moderation override clears channel blur via event wiring + --- + duration_ms: 34.798513 + 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: 32.153884 + 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: 21.578259 + type: 'test' + ... +1..6 +# tests 6 +# suites 0 +# pass 6 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 398.296397 + +→ 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: 74.173116 + 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: 9.658917 + type: 'test' + ... +# Subtest: handleHashChange respects explicit view regardless of login state +ok 3 - handleHashChange respects explicit view regardless of login state + --- + duration_ms: 9.775207 + type: 'test' + ... +1..3 +# tests 3 +# suites 0 +# pass 3 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 106.244019 + +→ 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: 104.182525 + type: 'test' + ... +# Subtest: hydrateSidebarNavigation hides chrome controls for logged-out viewers +ok 2 - hydrateSidebarNavigation hides chrome controls for logged-out viewers + --- + duration_ms: 28.824807 + type: 'test' + ... +1..2 +# tests 2 +# suites 0 +# pass 2 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 148.628996 + +→ 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.372662 + type: 'test' + ... +# Subtest: isUserLoggedIn treats extension logins as authenticated +ok 2 - isUserLoggedIn treats extension logins as authenticated + --- + duration_ms: 0.381678 + type: 'test' + ... +# Subtest: isUserLoggedIn guards against mismatched nostrClient state +ok 3 - isUserLoggedIn guards against mismatched nostrClient state + --- + duration_ms: 0.211323 + type: 'test' + ... +# Subtest: isUserLoggedIn ignores anonymous session actor mismatches +ok 4 - isUserLoggedIn ignores anonymous session actor mismatches + --- + duration_ms: 0.255464 + type: 'test' + ... +# Subtest: isUserLoggedIn rejects mismatched managed session actors +ok 5 - isUserLoggedIn rejects mismatched managed session actors + --- + duration_ms: 0.321204 + type: 'test' + ... +1..5 +# tests 5 +# suites 0 +# pass 5 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 33.821343 + +→ Running tests/app/moderation-overrides.test.mjs +[bitvid] Initialized nostr nip04 helpers. +[bitvid] Initialized nostr nip44 helpers. +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: 242.055409 + type: 'test' + ... +# Subtest: handleModerationOverride resumes deferred playback +ok 2 - handleModerationOverride resumes deferred playback + --- + duration_ms: 1.66123 + 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: 5.442489 + 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.600465 + type: 'test' + ... +1..4 +# tests 4 +# suites 0 +# pass 3 +# fail 1 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 286.782704 +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/test_unit_debug_3.log b/test_unit_debug_3.log new file mode 100644 index 00000000..c7e43285 --- /dev/null +++ b/test_unit_debug_3.log @@ -0,0 +1,260 @@ + +> 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: 22.244233 + type: 'test' + ... +1..1 +# tests 1 +# suites 0 +# pass 1 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 36.538516 + +→ 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: 316.648044 + type: 'test' + ... +# Subtest: renderChannelVideosFromList applies moderation blur without existing metadata +ok 2 - renderChannelVideosFromList applies moderation blur without existing metadata + --- + duration_ms: 46.776425 + 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: 15.209442 + type: 'test' + ... +# Subtest: moderation override clears channel blur via event wiring +ok 4 - moderation override clears channel blur via event wiring + --- + duration_ms: 36.087729 + 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: 39.830563 + 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: 32.84156 + type: 'test' + ... +1..6 +# tests 6 +# suites 0 +# pass 6 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 501.07657 + +→ 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: 73.46412 + 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: 9.611748 + type: 'test' + ... +# Subtest: handleHashChange respects explicit view regardless of login state +ok 3 - handleHashChange respects explicit view regardless of login state + --- + duration_ms: 9.764783 + type: 'test' + ... +1..3 +# tests 3 +# suites 0 +# pass 3 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 110.646914 + +→ 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: 99.746325 + type: 'test' + ... +# Subtest: hydrateSidebarNavigation hides chrome controls for logged-out viewers +ok 2 - hydrateSidebarNavigation hides chrome controls for logged-out viewers + --- + duration_ms: 26.407756 + type: 'test' + ... +1..2 +# tests 2 +# suites 0 +# pass 2 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 141.088808 + +→ 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.373918 + type: 'test' + ... +# Subtest: isUserLoggedIn treats extension logins as authenticated +ok 2 - isUserLoggedIn treats extension logins as authenticated + --- + duration_ms: 0.408152 + type: 'test' + ... +# Subtest: isUserLoggedIn guards against mismatched nostrClient state +ok 3 - isUserLoggedIn guards against mismatched nostrClient state + --- + duration_ms: 0.244921 + type: 'test' + ... +# Subtest: isUserLoggedIn ignores anonymous session actor mismatches +ok 4 - isUserLoggedIn ignores anonymous session actor mismatches + --- + duration_ms: 0.257353 + type: 'test' + ... +# Subtest: isUserLoggedIn rejects mismatched managed session actors +ok 5 - isUserLoggedIn rejects mismatched managed session actors + --- + duration_ms: 0.311313 + type: 'test' + ... +1..5 +# tests 5 +# suites 0 +# pass 5 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 32.052639 + +→ Running tests/app/moderation-overrides.test.mjs +[bitvid] Initialized nostr nip04 helpers. +[bitvid] Initialized nostr nip44 helpers. +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: 212.505662 + type: 'test' + ... +# Subtest: handleModerationOverride resumes deferred playback +ok 2 - handleModerationOverride resumes deferred playback + --- + duration_ms: 1.28636 + 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.64235 + 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.619904 + type: 'test' + ... +1..4 +# tests 4 +# suites 0 +# pass 3 +# fail 1 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 250.717362 +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/test_unit_debug_4.log b/test_unit_debug_4.log new file mode 100644 index 00000000..163ef706 --- /dev/null +++ b/test_unit_debug_4.log @@ -0,0 +1,261 @@ + +> 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: 7.683186 + type: 'test' + ... +1..1 +# tests 1 +# suites 0 +# pass 1 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 28.640279 + +→ 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: 376.493065 + type: 'test' + ... +# Subtest: renderChannelVideosFromList applies moderation blur without existing metadata +ok 2 - renderChannelVideosFromList applies moderation blur without existing metadata + --- + duration_ms: 39.743453 + 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: 15.335853 + type: 'test' + ... +# Subtest: moderation override clears channel blur via event wiring +ok 4 - moderation override clears channel blur via event wiring + --- + duration_ms: 47.515622 + 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: 52.962084 + 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: 27.377719 + type: 'test' + ... +1..6 +# tests 6 +# suites 0 +# pass 6 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 573.718626 + +→ 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: 73.304539 + 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: 9.802311 + type: 'test' + ... +# Subtest: handleHashChange respects explicit view regardless of login state +ok 3 - handleHashChange respects explicit view regardless of login state + --- + duration_ms: 10.826679 + type: 'test' + ... +1..3 +# tests 3 +# suites 0 +# pass 3 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 111.820727 + +→ 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: 121.895181 + type: 'test' + ... +# Subtest: hydrateSidebarNavigation hides chrome controls for logged-out viewers +ok 2 - hydrateSidebarNavigation hides chrome controls for logged-out viewers + --- + duration_ms: 27.859075 + type: 'test' + ... +1..2 +# tests 2 +# suites 0 +# pass 2 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 166.232762 + +→ 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: 2.070726 + type: 'test' + ... +# Subtest: isUserLoggedIn treats extension logins as authenticated +ok 2 - isUserLoggedIn treats extension logins as authenticated + --- + duration_ms: 0.592571 + type: 'test' + ... +# Subtest: isUserLoggedIn guards against mismatched nostrClient state +ok 3 - isUserLoggedIn guards against mismatched nostrClient state + --- + duration_ms: 0.445862 + type: 'test' + ... +# Subtest: isUserLoggedIn ignores anonymous session actor mismatches +ok 4 - isUserLoggedIn ignores anonymous session actor mismatches + --- + duration_ms: 0.5379 + type: 'test' + ... +# Subtest: isUserLoggedIn rejects mismatched managed session actors +ok 5 - isUserLoggedIn rejects mismatched managed session actors + --- + duration_ms: 0.568571 + type: 'test' + ... +1..5 +# tests 5 +# suites 0 +# pass 5 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 42.558696 + +→ Running tests/app/moderation-overrides.test.mjs +[bitvid] Initialized nostr nip04 helpers. +[bitvid] Initialized nostr nip44 helpers. +DEBUG: Test 3 Result: true +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: 221.521473 + type: 'test' + ... +# Subtest: handleModerationOverride resumes deferred playback +ok 2 - handleModerationOverride resumes deferred playback + --- + duration_ms: 1.277155 + 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: 5.235509 + 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:229: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.748986 + type: 'test' + ... +1..4 +# tests 4 +# suites 0 +# pass 3 +# fail 1 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 263.815159 +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/test_unit_final.log b/test_unit_final.log new file mode 100644 index 00000000..03d31ef2 --- /dev/null +++ b/test_unit_final.log @@ -0,0 +1,260 @@ + +> 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.941211 + type: 'test' + ... +1..1 +# tests 1 +# suites 0 +# pass 1 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 16.455907 + +→ 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: 243.403366 + type: 'test' + ... +# Subtest: renderChannelVideosFromList applies moderation blur without existing metadata +ok 2 - renderChannelVideosFromList applies moderation blur without existing metadata + --- + duration_ms: 31.534109 + 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: 10.992319 + type: 'test' + ... +# Subtest: moderation override clears channel blur via event wiring +ok 4 - moderation override clears channel blur via event wiring + --- + duration_ms: 38.203729 + 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: 32.713928 + 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: 20.992921 + type: 'test' + ... +1..6 +# tests 6 +# suites 0 +# pass 6 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 389.736415 + +→ 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: 73.866587 + 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: 9.66665 + type: 'test' + ... +# Subtest: handleHashChange respects explicit view regardless of login state +ok 3 - handleHashChange respects explicit view regardless of login state + --- + duration_ms: 9.863301 + type: 'test' + ... +1..3 +# tests 3 +# suites 0 +# pass 3 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 106.76867 + +→ 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: 85.299474 + type: 'test' + ... +# Subtest: hydrateSidebarNavigation hides chrome controls for logged-out viewers +ok 2 - hydrateSidebarNavigation hides chrome controls for logged-out viewers + --- + duration_ms: 13.586181 + type: 'test' + ... +1..2 +# tests 2 +# suites 0 +# pass 2 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 110.142612 + +→ 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.567229 + type: 'test' + ... +# Subtest: isUserLoggedIn treats extension logins as authenticated +ok 2 - isUserLoggedIn treats extension logins as authenticated + --- + duration_ms: 0.354268 + type: 'test' + ... +# Subtest: isUserLoggedIn guards against mismatched nostrClient state +ok 3 - isUserLoggedIn guards against mismatched nostrClient state + --- + duration_ms: 0.275984 + type: 'test' + ... +# Subtest: isUserLoggedIn ignores anonymous session actor mismatches +ok 4 - isUserLoggedIn ignores anonymous session actor mismatches + --- + duration_ms: 0.274841 + type: 'test' + ... +# Subtest: isUserLoggedIn rejects mismatched managed session actors +ok 5 - isUserLoggedIn rejects mismatched managed session actors + --- + duration_ms: 0.252751 + type: 'test' + ... +1..5 +# tests 5 +# suites 0 +# pass 5 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 34.328915 + +→ Running tests/app/moderation-overrides.test.mjs +[bitvid] Initialized nostr nip04 helpers. +[bitvid] Initialized nostr nip44 helpers. +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: 225.848661 + type: 'test' + ... +# Subtest: handleModerationOverride resumes deferred playback +ok 2 - handleModerationOverride resumes deferred playback + --- + duration_ms: 1.28016 + 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: 5.041835 + 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:232: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.571133 + type: 'test' + ... +1..4 +# tests 4 +# suites 0 +# pass 3 +# fail 1 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 268.845775 +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/test_unit_pre_commit.log b/test_unit_pre_commit.log new file mode 100644 index 00000000..5323a5bb --- /dev/null +++ b/test_unit_pre_commit.log @@ -0,0 +1,260 @@ + +> 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: 7.891372 + type: 'test' + ... +1..1 +# tests 1 +# suites 0 +# pass 1 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 22.271669 + +→ 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: 361.619024 + type: 'test' + ... +# Subtest: renderChannelVideosFromList applies moderation blur without existing metadata +ok 2 - renderChannelVideosFromList applies moderation blur without existing metadata + --- + duration_ms: 40.463597 + 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: 16.290213 + type: 'test' + ... +# Subtest: moderation override clears channel blur via event wiring +ok 4 - moderation override clears channel blur via event wiring + --- + duration_ms: 42.036247 + 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: 42.837872 + 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: 26.383893 + type: 'test' + ... +1..6 +# tests 6 +# suites 0 +# pass 6 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 542.904828 + +→ 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: 82.739827 + 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: 21.613469 + type: 'test' + ... +# Subtest: handleHashChange respects explicit view regardless of login state +ok 3 - handleHashChange respects explicit view regardless of login state + --- + duration_ms: 11.465331 + type: 'test' + ... +1..3 +# tests 3 +# suites 0 +# pass 3 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 133.942749 + +→ 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: 101.830503 + type: 'test' + ... +# Subtest: hydrateSidebarNavigation hides chrome controls for logged-out viewers +ok 2 - hydrateSidebarNavigation hides chrome controls for logged-out viewers + --- + duration_ms: 26.06532 + type: 'test' + ... +1..2 +# tests 2 +# suites 0 +# pass 2 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 143.762843 + +→ 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.383277 + type: 'test' + ... +# Subtest: isUserLoggedIn treats extension logins as authenticated +ok 2 - isUserLoggedIn treats extension logins as authenticated + --- + duration_ms: 0.414559 + type: 'test' + ... +# Subtest: isUserLoggedIn guards against mismatched nostrClient state +ok 3 - isUserLoggedIn guards against mismatched nostrClient state + --- + duration_ms: 0.223376 + type: 'test' + ... +# Subtest: isUserLoggedIn ignores anonymous session actor mismatches +ok 4 - isUserLoggedIn ignores anonymous session actor mismatches + --- + duration_ms: 0.345963 + type: 'test' + ... +# Subtest: isUserLoggedIn rejects mismatched managed session actors +ok 5 - isUserLoggedIn rejects mismatched managed session actors + --- + duration_ms: 0.265368 + type: 'test' + ... +1..5 +# tests 5 +# suites 0 +# pass 5 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 31.714232 + +→ Running tests/app/moderation-overrides.test.mjs +[bitvid] Initialized nostr nip04 helpers. +[bitvid] Initialized nostr nip44 helpers. +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: 214.226302 + type: 'test' + ... +# Subtest: handleModerationOverride resumes deferred playback +ok 2 - handleModerationOverride resumes deferred playback + --- + duration_ms: 1.308813 + 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.950644 + 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.626768 + type: 'test' + ... +1..4 +# tests 4 +# suites 0 +# pass 3 +# fail 1 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 254.906261 +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/test_unit_retry.log b/test_unit_retry.log new file mode 100644 index 00000000..772ffd04 --- /dev/null +++ b/test_unit_retry.log @@ -0,0 +1,260 @@ + +> 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: 4.89647 + type: 'test' + ... +1..1 +# tests 1 +# suites 0 +# pass 1 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 21.69378 + +→ 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: 401.108042 + type: 'test' + ... +# Subtest: renderChannelVideosFromList applies moderation blur without existing metadata +ok 2 - renderChannelVideosFromList applies moderation blur without existing metadata + --- + duration_ms: 46.542954 + 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: 15.658716 + type: 'test' + ... +# Subtest: moderation override clears channel blur via event wiring +ok 4 - moderation override clears channel blur via event wiring + --- + duration_ms: 52.358724 + 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: 41.743826 + 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: 26.080671 + type: 'test' + ... +1..6 +# tests 6 +# suites 0 +# pass 6 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 611.793776 + +→ 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: 78.541617 + 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: 10.259655 + type: 'test' + ... +# Subtest: handleHashChange respects explicit view regardless of login state +ok 3 - handleHashChange respects explicit view regardless of login state + --- + duration_ms: 10.116444 + type: 'test' + ... +1..3 +# tests 3 +# suites 0 +# pass 3 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 112.397132 + +→ 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: 98.541032 + type: 'test' + ... +# Subtest: hydrateSidebarNavigation hides chrome controls for logged-out viewers +ok 2 - hydrateSidebarNavigation hides chrome controls for logged-out viewers + --- + duration_ms: 15.672259 + type: 'test' + ... +1..2 +# tests 2 +# suites 0 +# pass 2 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 131.789275 + +→ 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.459953 + type: 'test' + ... +# Subtest: isUserLoggedIn treats extension logins as authenticated +ok 2 - isUserLoggedIn treats extension logins as authenticated + --- + duration_ms: 0.427722 + type: 'test' + ... +# Subtest: isUserLoggedIn guards against mismatched nostrClient state +ok 3 - isUserLoggedIn guards against mismatched nostrClient state + --- + duration_ms: 0.232365 + type: 'test' + ... +# Subtest: isUserLoggedIn ignores anonymous session actor mismatches +ok 4 - isUserLoggedIn ignores anonymous session actor mismatches + --- + duration_ms: 0.295374 + type: 'test' + ... +# Subtest: isUserLoggedIn rejects mismatched managed session actors +ok 5 - isUserLoggedIn rejects mismatched managed session actors + --- + duration_ms: 0.263757 + type: 'test' + ... +1..5 +# tests 5 +# suites 0 +# pass 5 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 32.877837 + +→ Running tests/app/moderation-overrides.test.mjs +[bitvid] Initialized nostr nip04 helpers. +[bitvid] Initialized nostr nip44 helpers. +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: 230.312105 + type: 'test' + ... +# Subtest: handleModerationOverride resumes deferred playback +ok 2 - handleModerationOverride resumes deferred playback + --- + duration_ms: 1.320201 + 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.990623 + 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.778329 + type: 'test' + ... +1..4 +# tests 4 +# suites 0 +# pass 3 +# fail 1 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 271.042194 +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/test_unit_retry_2.log b/test_unit_retry_2.log new file mode 100644 index 00000000..86a9d660 --- /dev/null +++ b/test_unit_retry_2.log @@ -0,0 +1,305 @@ + +> 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: 7.977402 + type: 'test' + ... +1..1 +# tests 1 +# suites 0 +# pass 1 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 22.241514 + +→ 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: 379.80434 + type: 'test' + ... +# Subtest: renderChannelVideosFromList applies moderation blur without existing metadata +ok 2 - renderChannelVideosFromList applies moderation blur without existing metadata + --- + duration_ms: 45.289258 + 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: 15.951023 + type: 'test' + ... +# Subtest: moderation override clears channel blur via event wiring +ok 4 - moderation override clears channel blur via event wiring + --- + duration_ms: 45.789308 + 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: 42.447356 + 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: 25.597118 + type: 'test' + ... +1..6 +# tests 6 +# suites 0 +# pass 6 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 568.177635 + +→ 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: 75.772174 + 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: 9.627833 + type: 'test' + ... +# Subtest: handleHashChange respects explicit view regardless of login state +ok 3 - handleHashChange respects explicit view regardless of login state + --- + duration_ms: 10.030577 + type: 'test' + ... +1..3 +# tests 3 +# suites 0 +# pass 3 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 108.647336 + +→ 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: 118.594258 + type: 'test' + ... +# Subtest: hydrateSidebarNavigation hides chrome controls for logged-out viewers +ok 2 - hydrateSidebarNavigation hides chrome controls for logged-out viewers + --- + duration_ms: 27.333658 + type: 'test' + ... +1..2 +# tests 2 +# suites 0 +# pass 2 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 161.988571 + +→ 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.780936 + type: 'test' + ... +# Subtest: isUserLoggedIn treats extension logins as authenticated +ok 2 - isUserLoggedIn treats extension logins as authenticated + --- + duration_ms: 0.469339 + type: 'test' + ... +# Subtest: isUserLoggedIn guards against mismatched nostrClient state +ok 3 - isUserLoggedIn guards against mismatched nostrClient state + --- + duration_ms: 0.229676 + type: 'test' + ... +# Subtest: isUserLoggedIn ignores anonymous session actor mismatches +ok 4 - isUserLoggedIn ignores anonymous session actor mismatches + --- + duration_ms: 0.274654 + type: 'test' + ... +# Subtest: isUserLoggedIn rejects mismatched managed session actors +ok 5 - isUserLoggedIn rejects mismatched managed session actors + --- + duration_ms: 0.278603 + type: 'test' + ... +1..5 +# tests 5 +# suites 0 +# pass 5 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 35.209771 + +→ Running tests/app/moderation-overrides.test.mjs +[bitvid] Initialized nostr nip04 helpers. +[bitvid] Initialized nostr nip44 helpers. +TAP version 13 +# Subtest: handleModerationOverride decorates stored and current videos then refreshes UI +not ok 1 - handleModerationOverride decorates stored and current videos then refreshes UI + --- + duration_ms: 228.266794 + type: 'test' + location: '/app/tests/app/moderation-overrides.test.mjs:27:1' + failureType: 'testCodeFailure' + error: |- + Expected values to be strictly equal: + + actual - expected + + + undefined + - true + + code: 'ERR_ASSERTION' + name: 'AssertionError' + expected: true + operator: 'strictEqual' + stack: |- + TestContext. (file:///app/tests/app/moderation-overrides.test.mjs:67:10) + async Test.run (node:internal/test_runner/test:1054:7) + async startSubtestAfterBootstrap (node:internal/test_runner/harness:296:3) + ... +# Subtest: handleModerationOverride resumes deferred playback +not ok 2 - handleModerationOverride resumes deferred playback + --- + duration_ms: 2.019286 + type: 'test' + location: '/app/tests/app/moderation-overrides.test.mjs:75:1' + failureType: 'testCodeFailure' + error: |- + Expected values to be strictly equal: + + actual - expected + + + { + + magnet: '', + + triggerProvided: false, + + url: 'https://example.com/video.mp4', + + videoId: 'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' + + } + - null + + code: 'ERR_ASSERTION' + name: 'AssertionError' + expected: ~ + actual: + url: 'https://example.com/video.mp4' + magnet: '' + triggerProvided: false + videoId: 'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' + operator: 'strictEqual' + stack: |- + TestContext. (file:///app/tests/app/moderation-overrides.test.mjs:104:10) + async Test.run (node:internal/test_runner/test:1054:7) + async Test.processPendingSubtests (node:internal/test_runner/test:744:7) + ... +# 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: 2.784959 + type: 'test' + location: '/app/tests/app/moderation-overrides.test.mjs:112:1' + failureType: 'testCodeFailure' + error: |- + Expected values to be strictly equal: + + actual - expected + + + undefined + - true + + code: 'ERR_ASSERTION' + name: 'AssertionError' + expected: true + operator: 'strictEqual' + stack: |- + TestContext. (file:///app/tests/app/moderation-overrides.test.mjs:202: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: 2.057327 + type: 'test' + ... +1..4 +# tests 4 +# suites 0 +# pass 1 +# fail 3 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 267.221529 +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/test_unit_retry_3.log b/test_unit_retry_3.log new file mode 100644 index 00000000..774142bb --- /dev/null +++ b/test_unit_retry_3.log @@ -0,0 +1,287 @@ + +> 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: 4.68097 + type: 'test' + ... +1..1 +# tests 1 +# suites 0 +# pass 1 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 18.751403 + +→ 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: 249.242079 + type: 'test' + ... +# Subtest: renderChannelVideosFromList applies moderation blur without existing metadata +ok 2 - renderChannelVideosFromList applies moderation blur without existing metadata + --- + duration_ms: 34.522355 + 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: 11.527787 + type: 'test' + ... +# Subtest: moderation override clears channel blur via event wiring +ok 4 - moderation override clears channel blur via event wiring + --- + duration_ms: 39.046527 + 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: 34.441459 + 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: 23.360676 + type: 'test' + ... +1..6 +# tests 6 +# suites 0 +# pass 6 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 404.34229 + +→ 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: 1009.599136 + 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: 73.745699 + type: 'test' + ... +# Subtest: handleHashChange respects explicit view regardless of login state +ok 3 - handleHashChange respects explicit view regardless of login state + --- + duration_ms: 33.538414 + type: 'test' + ... +1..3 +# tests 3 +# suites 0 +# pass 3 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 1164.107182 + +→ 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: 123.254594 + type: 'test' + ... +# Subtest: hydrateSidebarNavigation hides chrome controls for logged-out viewers +ok 2 - hydrateSidebarNavigation hides chrome controls for logged-out viewers + --- + duration_ms: 17.578009 + type: 'test' + ... +1..2 +# tests 2 +# suites 0 +# pass 2 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 173.980931 + +→ 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.547337 + type: 'test' + ... +# Subtest: isUserLoggedIn treats extension logins as authenticated +ok 2 - isUserLoggedIn treats extension logins as authenticated + --- + duration_ms: 0.411532 + type: 'test' + ... +# Subtest: isUserLoggedIn guards against mismatched nostrClient state +ok 3 - isUserLoggedIn guards against mismatched nostrClient state + --- + duration_ms: 0.230064 + type: 'test' + ... +# Subtest: isUserLoggedIn ignores anonymous session actor mismatches +ok 4 - isUserLoggedIn ignores anonymous session actor mismatches + --- + duration_ms: 0.402138 + type: 'test' + ... +# Subtest: isUserLoggedIn rejects mismatched managed session actors +ok 5 - isUserLoggedIn rejects mismatched managed session actors + --- + duration_ms: 0.24381 + type: 'test' + ... +1..5 +# tests 5 +# suites 0 +# pass 5 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 48.612244 + +→ Running tests/app/moderation-overrides.test.mjs +[bitvid] Initialized nostr nip04 helpers. +[bitvid] Initialized nostr nip44 helpers. +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: 244.260716 + type: 'test' + ... +# Subtest: handleModerationOverride resumes deferred playback +not ok 2 - handleModerationOverride resumes deferred playback + --- + duration_ms: 3.378509 + type: 'test' + location: '/app/tests/app/moderation-overrides.test.mjs:75:1' + failureType: 'testCodeFailure' + error: |- + Expected values to be strictly equal: + + actual - expected + + + { + + magnet: '', + + triggerProvided: false, + + url: 'https://example.com/video.mp4', + + videoId: 'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' + + } + - null + + code: 'ERR_ASSERTION' + name: 'AssertionError' + expected: ~ + actual: + url: 'https://example.com/video.mp4' + magnet: '' + triggerProvided: false + videoId: 'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' + operator: 'strictEqual' + stack: |- + TestContext. (file:///app/tests/app/moderation-overrides.test.mjs:104:10) + async Test.run (node:internal/test_runner/test:1054:7) + async Test.processPendingSubtests (node:internal/test_runner/test:744:7) + ... +# 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.927295 + 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.922279 + type: 'test' + ... +1..4 +# tests 4 +# suites 0 +# pass 2 +# fail 2 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 287.75859 +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/test_unit_retry_4.log b/test_unit_retry_4.log new file mode 100644 index 00000000..d7e36c57 --- /dev/null +++ b/test_unit_retry_4.log @@ -0,0 +1,260 @@ + +> 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: 6.00491 + type: 'test' + ... +1..1 +# tests 1 +# suites 0 +# pass 1 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 32.022592 + +→ 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: 375.346278 + type: 'test' + ... +# Subtest: renderChannelVideosFromList applies moderation blur without existing metadata +ok 2 - renderChannelVideosFromList applies moderation blur without existing metadata + --- + duration_ms: 37.760277 + 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: 14.528741 + type: 'test' + ... +# Subtest: moderation override clears channel blur via event wiring +ok 4 - moderation override clears channel blur via event wiring + --- + duration_ms: 47.192924 + 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: 39.987443 + 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.837088 + type: 'test' + ... +1..6 +# tests 6 +# suites 0 +# pass 6 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 553.202787 + +→ 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: 73.049804 + 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: 9.496508 + type: 'test' + ... +# Subtest: handleHashChange respects explicit view regardless of login state +ok 3 - handleHashChange respects explicit view regardless of login state + --- + duration_ms: 9.841895 + type: 'test' + ... +1..3 +# tests 3 +# suites 0 +# pass 3 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 105.172847 + +→ 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: 91.833717 + type: 'test' + ... +# Subtest: hydrateSidebarNavigation hides chrome controls for logged-out viewers +ok 2 - hydrateSidebarNavigation hides chrome controls for logged-out viewers + --- + duration_ms: 13.635597 + type: 'test' + ... +1..2 +# tests 2 +# suites 0 +# pass 2 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 122.580199 + +→ 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.302074 + type: 'test' + ... +# Subtest: isUserLoggedIn treats extension logins as authenticated +ok 2 - isUserLoggedIn treats extension logins as authenticated + --- + duration_ms: 0.407277 + type: 'test' + ... +# Subtest: isUserLoggedIn guards against mismatched nostrClient state +ok 3 - isUserLoggedIn guards against mismatched nostrClient state + --- + duration_ms: 0.283539 + type: 'test' + ... +# Subtest: isUserLoggedIn ignores anonymous session actor mismatches +ok 4 - isUserLoggedIn ignores anonymous session actor mismatches + --- + duration_ms: 0.252445 + type: 'test' + ... +# Subtest: isUserLoggedIn rejects mismatched managed session actors +ok 5 - isUserLoggedIn rejects mismatched managed session actors + --- + duration_ms: 0.383152 + type: 'test' + ... +1..5 +# tests 5 +# suites 0 +# pass 5 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 34.198852 + +→ Running tests/app/moderation-overrides.test.mjs +[bitvid] Initialized nostr nip04 helpers. +[bitvid] Initialized nostr nip44 helpers. +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: 210.938803 + type: 'test' + ... +# Subtest: handleModerationOverride resumes deferred playback +ok 2 - handleModerationOverride resumes deferred playback + --- + duration_ms: 1.300514 + 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.873851 + 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.847791 + type: 'test' + ... +1..4 +# tests 4 +# suites 0 +# pass 3 +# fail 1 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 253.404435 +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/helpers/moderation-test-helpers.mjs b/tests/helpers/moderation-test-helpers.mjs index 3d1a8f87..b22338db 100644 --- a/tests/helpers/moderation-test-helpers.mjs +++ b/tests/helpers/moderation-test-helpers.mjs @@ -1,6 +1,13 @@ import "../test-helpers/setup-localstorage.mjs"; import { ModerationService } from "../../js/services/moderationService.js"; -import { getDefaultModerationSettings } from "../../js/state/cache.js"; +import ModerationDecorator from "../../js/services/moderationDecorator.js"; +import ModerationActionController from "../../js/services/moderationActionController.js"; +import { + getDefaultModerationSettings, + setModerationOverride, + clearModerationOverride, +} from "../../js/state/cache.js"; +import { userBlocks } from "../../js/userBlocks.js"; const DEFAULT_CONTACT_OWNER = "f".repeat(64); const DEFAULT_REPORT_TARGET = "e".repeat(64); @@ -209,7 +216,49 @@ export async function createModerationAppHarness() { return app.__profiles.get(pubkey) || null; }; + app.moderationDecorator = new ModerationDecorator({ + getProfileCacheEntry: (pubkey) => app.getProfileCacheEntry(pubkey), + }); + + app.moderationActionController = new ModerationActionController({ + services: { + userBlocks, + setModerationOverride, + clearModerationOverride, + }, + auth: { + isLoggedIn: () => app.isUserLoggedIn(), + getViewerPubkey: () => app.pubkey, + normalizePubkey: (value) => + app.normalizeHexPubkey + ? app.normalizeHexPubkey(value) + : Application.prototype.normalizeHexPubkey.call(app, value), + }, + actions: { + refreshVideos: (payload) => app.onVideosShouldRefresh(payload), + showStatus: (message, options) => app.showStatus(message, options), + showError: (message) => app.showError(message), + decorateVideoModeration: (video) => app.decorateVideoModeration(video), + resumePlayback: (video) => app.resumePendingModeratedPlayback(video), + describeBlockError: (error) => app.describeUserBlockActionError(error), + }, + selectors: { + getVideoById: (id) => (app.videosMap ? app.videosMap.get(id) : null), + getCurrentVideo: () => app.currentVideo, + }, + ui: { + refreshCardModerationUi: (card, options) => + app.refreshCardModerationUi(card, options), + dispatchModerationEvent: (eventName, detail) => + app.dispatchModerationEvent(eventName, detail), + }, + }); + app.decorateVideoModeration = Application.prototype.decorateVideoModeration; + app.resumePendingModeratedPlayback = + Application.prototype.resumePendingModeratedPlayback; + app.describeUserBlockActionError = + Application.prototype.describeUserBlockActionError; app.deriveModerationReportType = Application.prototype.deriveModerationReportType; app.deriveModerationTrustedCount = Application.prototype.deriveModerationTrustedCount; app.getReporterDisplayName = Application.prototype.getReporterDisplayName;