> 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.047673 type: 'test' ... 1..1 # tests 1 # suites 0 # pass 1 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 26.973512 → 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: 424.523566 type: 'test' ... # Subtest: renderChannelVideosFromList applies moderation blur without existing metadata ok 2 - renderChannelVideosFromList applies moderation blur without existing metadata --- duration_ms: 43.519859 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: 22.257236 type: 'test' ... # Subtest: moderation override clears channel blur via event wiring ok 4 - moderation override clears channel blur via event wiring --- duration_ms: 75.089235 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.679109 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: 28.718554 type: 'test' ... 1..6 # tests 6 # suites 0 # pass 6 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 648.713038 → 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.580087 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: 14.083857 type: 'test' ... # Subtest: handleHashChange respects explicit view regardless of login state ok 3 - handleHashChange respects explicit view regardless of login state --- duration_ms: 13.137905 type: 'test' ... 1..3 # tests 3 # suites 0 # pass 3 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 120.032462 → 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: 114.831471 type: 'test' ... # Subtest: hydrateSidebarNavigation hides chrome controls for logged-out viewers ok 2 - hydrateSidebarNavigation hides chrome controls for logged-out viewers --- duration_ms: 26.671506 type: 'test' ... 1..2 # tests 2 # suites 0 # pass 2 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 158.748383 → 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.387683 type: 'test' ... # Subtest: isUserLoggedIn treats extension logins as authenticated ok 2 - isUserLoggedIn treats extension logins as authenticated --- duration_ms: 0.382702 type: 'test' ... # Subtest: isUserLoggedIn guards against mismatched nostrClient state ok 3 - isUserLoggedIn guards against mismatched nostrClient state --- duration_ms: 0.236296 type: 'test' ... # Subtest: isUserLoggedIn ignores anonymous session actor mismatches ok 4 - isUserLoggedIn ignores anonymous session actor mismatches --- duration_ms: 0.235494 type: 'test' ... # Subtest: isUserLoggedIn rejects mismatched managed session actors ok 5 - isUserLoggedIn rejects mismatched managed session actors --- duration_ms: 0.403705 type: 'test' ... 1..5 # tests 5 # suites 0 # pass 5 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 30.525363 → 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.368271 type: 'test' ... # Subtest: handleModerationOverride resumes deferred playback ok 2 - handleModerationOverride resumes deferred playback --- duration_ms: 1.154001 type: 'test' ... # Subtest: handleModerationBlock requests a block, clears overrides, and refreshes hidden state ok 3 - handleModerationBlock requests a block, clears overrides, and refreshes hidden state --- duration_ms: 4.28666 type: 'test' ... # Subtest: handleModerationBlock returns false when viewer is logged out ok 4 - handleModerationBlock returns false when viewer is logged out --- duration_ms: 1.52359 type: 'test' ... 1..4 # tests 4 # suites 0 # pass 4 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 250.034393 → Running tests/app/moderation-settings-refresh.test.mjs [bitvid] Initialized nostr nip04 helpers. [bitvid] Initialized nostr nip44 helpers. TAP version 13 # Subtest: handleModerationSettingsChange refreshes feeds with updated thresholds ok 1 - handleModerationSettingsChange refreshes feeds with updated thresholds --- duration_ms: 313.030547 type: 'test' ... 1..1 # tests 1 # suites 0 # pass 1 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 347.325493 → Running tests/app/similar-content.test.mjs [bitvid] Initialized nostr nip04 helpers. [bitvid] Initialized nostr nip44 helpers. TAP version 13 # Subtest: orders similar videos by shared tags then timestamp ok 1 - orders similar videos by shared tags then timestamp --- duration_ms: 3.453395 type: 'test' ... # Subtest: returns no matches when the active video lacks tags ok 2 - returns no matches when the active video lacks tags --- duration_ms: 0.603237 type: 'test' ... # Subtest: skips candidates without tag metadata ok 3 - skips candidates without tag metadata --- duration_ms: 0.399555 type: 'test' ... # Subtest: filters NSFW and private videos when NSFW content is disabled ok 4 - filters NSFW and private videos when NSFW content is disabled --- duration_ms: 0.8717 type: 'test' ... 1..4 # tests 4 # suites 0 # pass 4 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 37.191787 → Running tests/comment-event-builder.test.mjs [bitvid] Initialized nostr nip04 helpers. [bitvid] Initialized nostr nip44 helpers. [nostrEventSchemas] Dropping unmatched surrogate characters from event content [nostrEventSchemas] Dropping unmatched surrogate characters from event content TAP version 13 # Subtest: buildCommentEvent emits NIP-22 root metadata while keeping legacy fallbacks ok 1 - buildCommentEvent emits NIP-22 root metadata while keeping legacy fallbacks --- duration_ms: 3.261985 type: 'test' ... # Subtest: buildCommentEvent includes parent pointers, kinds, and authors for replies ok 2 - buildCommentEvent includes parent pointers, kinds, and authors for replies --- duration_ms: 0.544666 type: 'test' ... # Subtest: buildCommentEvent normalizes relays and preserves explicit overrides ok 3 - buildCommentEvent normalizes relays and preserves explicit overrides --- duration_ms: 0.938528 type: 'test' ... # Subtest: buildCommentEvent falls back to event pointers when no address is supplied ok 4 - buildCommentEvent falls back to event pointers when no address is supplied --- duration_ms: 0.267393 type: 'test' ... # Subtest: buildCommentEvent accepts partial metadata for parent overrides ok 5 - buildCommentEvent accepts partial metadata for parent overrides --- duration_ms: 0.417176 type: 'test' ... # Subtest: buildCommentEvent sanitizes additional tags before signing ok 6 - buildCommentEvent sanitizes additional tags before signing --- duration_ms: 0.859564 type: 'test' ... 1..6 # tests 6 # suites 0 # pass 6 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 20.310888 → Running tests/comment-thread-service.test.mjs [bitvid] Initialized nostr nip04 helpers. [bitvid] Initialized nostr nip44 helpers. [commentThread] Cached 1 comments for AABBCC11223344556677889900aabbcc11223344556677889900aabbcc112233. [commentThread] Loaded 1 cached comments for aabbcc11223344556677889900aabbcc11223344556677889900aabbcc112233. [commentThread] Improved fetching fallback: feature disabled. [commentThread] Improved fetching fallback: feature disabled. [commentThread] Improved fetching fallback: feature disabled. TAP version 13 # Subtest: CommentThreadService caches mixed-case video ids consistently ok 1 - CommentThreadService caches mixed-case video ids consistently --- duration_ms: 3.887797 type: 'test' ... # Subtest: CommentThreadService surfaces cache read failures ok 2 - CommentThreadService surfaces cache read failures --- duration_ms: 0.832272 type: 'test' ... # Subtest: CommentThreadService surfaces cache write failures ok 3 - CommentThreadService surfaces cache write failures --- duration_ms: 0.536733 type: 'test' ... # Subtest: CommentThreadService persists caches safely during teardown failures ok 4 - CommentThreadService persists caches safely during teardown failures --- duration_ms: 2.01607 type: 'test' ... # Subtest: CommentThreadService logs cache usage and fallback decisions ok 5 - CommentThreadService logs cache usage and fallback decisions --- duration_ms: 1.344342 type: 'test' ... # Subtest: CommentThreadService normalizes mixed-case event ids in thread state ok 6 - CommentThreadService normalizes mixed-case event ids in thread state --- duration_ms: 2.385415 type: 'test' ... # Subtest: CommentThreadService normalizes mixed-case pubkeys during hydration ok 7 - CommentThreadService normalizes mixed-case pubkeys during hydration --- duration_ms: 1.075149 type: 'test' ... # Subtest: CommentThreadService deduplicates mixed-case event ids and pubkeys ok 8 - CommentThreadService deduplicates mixed-case event ids and pubkeys --- duration_ms: 1.072922 type: 'test' ... [commentThread] Profile hydration attempt 1/3 failed for pubkeys: cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc, dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd. Error: temporary hydration failure at CommentThreadService.batchFetchProfiles (file:///app/tests/comment-thread-service.test.mjs:545:15) at file:///app/js/services/commentThreadService.js:908:40 at CommentThreadService.flushProfileQueue (file:///app/js/services/commentThreadService.js:955:7) at Timeout._onTimeout (file:///app/js/services/commentThreadService.js:884:12) at listOnTimeout (node:internal/timers:588:17) at process.processTimers (node:internal/timers:523:7) [commentThread] Retrying profile hydration in 50ms for pubkeys: cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc, dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd. # Subtest: CommentThreadService retries profile hydration before succeeding ok 9 - CommentThreadService retries profile hydration before succeeding --- duration_ms: 78.993241 type: 'test' ... [nostr] Comments cache miss for ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff [nostr] Comments cache hit for ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff [commentThread] Improved fetching fallback: feature disabled. # Subtest: CommentThreadService surfaces profile hydration failures after retries ok 10 - CommentThreadService surfaces profile hydration failures after retries --- duration_ms: 201.81237 type: 'test' ... # Subtest: listVideoComments accepts builder events without parent ids and filters replies ok 11 - listVideoComments accepts builder events without parent ids and filters replies --- duration_ms: 5.537908 type: 'test' ... [commentThread] Improved fetching fallback: feature disabled. [commentThread] Improved fetching fallback: feature disabled. [commentThread] Improved fetching fallback: feature disabled. [commentThread] Improved fetching fallback: feature disabled. # Subtest: CommentThreadService hydrates, subscribes, and dedupes incoming comment events ok 12 - CommentThreadService hydrates, subscribes, and dedupes incoming comment events --- duration_ms: 35.265616 type: 'test' ... # Subtest: CommentThreadService loadThread falls back to event id when address is missing ok 13 - CommentThreadService loadThread falls back to event id when address is missing --- duration_ms: 1.704164 type: 'test' ... # Subtest: CommentThreadService requests and snapshots comments by root identifier ok 14 - CommentThreadService requests and snapshots comments by root identifier --- duration_ms: 1.104305 type: 'test' ... # Subtest: CommentThreadService falls back to pointerIdentifiers root id ok 15 - CommentThreadService falls back to pointerIdentifiers root id --- duration_ms: 0.788635 type: 'test' ... [commentThread] Comment cache miss for aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: no entry present. [commentThread] Cached 0 comments for aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa. [commentThread] Loaded 0 cached comments for aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa. [commentThread] Cached 0 comments for aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa. [commentThread] Cached 1 comments for aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa. [commentThread] Cached 1 comments for aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa. # Subtest: CommentThreadService preserves raw video author pubkeys during hydration fetches ok 16 - CommentThreadService preserves raw video author pubkeys during hydration fetches --- duration_ms: 5.172487 type: 'test' ... # Subtest: CommentThreadService teardown cancels hydration timers ok 17 - CommentThreadService teardown cancels hydration timers --- duration_ms: 81.482912 type: 'test' ... 1..17 # tests 17 # suites 0 # pass 17 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 435.451953 → Running tests/design-system-metrics.test.mjs TAP version 13 # Subtest: metric probe falls back to numeric parsing when measurement fails ok 1 - metric probe falls back to numeric parsing when measurement fails --- duration_ms: 148.360102 type: 'test' ... 1..1 # tests 1 # suites 0 # pass 1 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 158.878974 → Running tests/dm-decryptor.test.mjs [bitvid] Initialized nostr nip04 helpers. [bitvid] Initialized nostr nip44 helpers. TAP version 13 # Subtest: decryptDM handles kind 4 events with nip04 ciphertext ok 1 - decryptDM handles kind 4 events with nip04 ciphertext --- duration_ms: 71.331447 type: 'test' ... # Subtest: decryptDM prefers recipient pubkeys when actor is the sender ok 2 - decryptDM prefers recipient pubkeys when actor is the sender --- duration_ms: 16.99039 type: 'test' ... # Subtest: decryptDM unwraps kind 1059 gift wraps with nip44 ok 3 - decryptDM unwraps kind 1059 gift wraps with nip44 --- duration_ms: 57.507123 type: 'test' ... # Subtest: decryptDM returns failure when decryptors are unavailable ok 4 - decryptDM returns failure when decryptors are unavailable --- duration_ms: 0.369621 type: 'test' ... 1..4 # tests 4 # suites 0 # pass 4 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 159.118752 → Running tests/edit-modal-submit-state.test.mjs TAP version 13 # Subtest: ignores additional submissions while pending without spurious errors ok 1 - ignores additional submissions while pending without spurious errors --- duration_ms: 280.317764 type: 'test' ... # Subtest: editing the magnet refreshes torrent hints when ws/xs remain locked ok 2 - editing the magnet refreshes torrent hints when ws/xs remain locked --- duration_ms: 110.930823 type: 'test' ... # Subtest: does not show missing video error after modal closes ok 3 - does not show missing video error after modal closes --- duration_ms: 85.079892 type: 'test' ... 1..3 # tests 3 # suites 0 # pass 3 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 490.188046 → Running tests/feed-engine/tag-preference-filter.test.mjs [bitvid] Initialized nostr nip04 helpers. [bitvid] Initialized nostr nip44 helpers. TAP version 13 # Subtest: tag preference stage filters by interests and excludes disinterests ok 1 - tag preference stage filters by interests and excludes disinterests --- duration_ms: 2.625713 type: 'test' ... # Subtest: tag preference stage accepts interests from nip71 hashtags ok 2 - tag preference stage accepts interests from nip71 hashtags --- duration_ms: 0.393675 type: 'test' ... 1..2 # tests 2 # suites 0 # pass 2 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 13.809832 → Running tests/hashtag-preferences.test.mjs [bitvid] Initialized nostr nip04 helpers. [bitvid] Initialized nostr nip44 helpers. TAP version 13 # Subtest: load decrypts nip44 payloads and normalizes tags ok 1 - load decrypts nip44 payloads and normalizes tags --- duration_ms: 19.593929 type: 'test' ... # Subtest: load falls back to nip04 decryption ok 2 - load falls back to nip04 decryption --- duration_ms: 1.303362 type: 'test' ... # Subtest: load retries decryptors when hinted scheme fails ok 3 - load retries decryptors when hinted scheme fails --- duration_ms: 1.51936 type: 'test' ... # Subtest: interest and disinterest lists remain exclusive ok 4 - interest and disinterest lists remain exclusive --- duration_ms: 0.611777 type: 'test' ... # Subtest: publish encrypts payload and builds event via builder ok 5 - publish encrypts payload and builds event via builder --- duration_ms: 9.460495 type: 'test' ... # Subtest: publish falls back to window nostr encryptors ok 6 - publish falls back to window nostr encryptors --- duration_ms: 2.323176 type: 'test' ... # Subtest: load prefers canonical kind when timestamps match while accepting legacy payload ok 7 - load prefers canonical kind when timestamps match while accepting legacy payload --- duration_ms: 1.559711 type: 'test' ... 1..7 # tests 7 # suites 0 # pass 7 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 45.345208 → Running tests/magnet-utils.test.mjs TAP version 13 # Subtest: safeDecodeMagnet handles encoded values ok 1 - safeDecodeMagnet handles encoded values --- duration_ms: 1.78923 type: 'test' ... # Subtest: safeDecodeMagnet leaves plain strings untouched ok 2 - safeDecodeMagnet leaves plain strings untouched --- duration_ms: 0.27931 type: 'test' ... # Subtest: bare hashes normalize consistently across helpers ok 3 - bare hashes normalize consistently across helpers --- duration_ms: 3.521858 type: 'test' ... # Subtest: legacy %3A payloads decode across helpers ok 4 - legacy %3A payloads decode across helpers --- duration_ms: 0.644925 type: 'test' ... # Subtest: duplicate trackers and hints stay in sync ok 5 - duplicate trackers and hints stay in sync --- duration_ms: 1.173092 type: 'test' ... # Subtest: object helper enforces HTTPS web seeds when on HTTPS ok 6 - object helper enforces HTTPS web seeds when on HTTPS --- duration_ms: 0.580791 type: 'test' ... # Subtest: object helper allows HTTP seeds on HTTP origins ok 7 - object helper allows HTTP seeds on HTTP origins --- duration_ms: 0.367328 type: 'test' ... # Subtest: extractMagnetHints returns first ws/xs pair ok 8 - extractMagnetHints returns first ws/xs pair --- duration_ms: 0.368801 type: 'test' ... # Subtest: string helper skips insecure ws hints on HTTPS origins ok 9 - string helper skips insecure ws hints on HTTPS origins --- duration_ms: 0.741878 type: 'test' ... # Subtest: object helper reports didChange when output differs ok 10 - object helper reports didChange when output differs --- duration_ms: 0.698761 type: 'test' ... # Subtest: helpers trim fragments from non-magnet values ok 11 - helpers trim fragments from non-magnet values --- duration_ms: 0.507018 type: 'test' ... 1..11 # tests 11 # suites 0 # pass 11 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 30.632859 → Running tests/media-loader.test.mjs TAP version 13 # Subtest: MediaLoader assigns image sources once intersecting ok 1 - MediaLoader assigns image sources once intersecting --- duration_ms: 88.756519 type: 'test' ... # Subtest: MediaLoader loads video sources and poster fallbacks ok 2 - MediaLoader loads video sources and poster fallbacks --- duration_ms: 29.411585 type: 'test' ... # Subtest: MediaLoader clears unsupported lazy targets without inline styles ok 3 - MediaLoader clears unsupported lazy targets without inline styles --- duration_ms: 13.771679 type: 'test' ... 1..3 # tests 3 # suites 0 # pass 3 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 153.122197 → Running tests/modal-accessibility.test.mjs [bitvid] Initialized nostr nip04 helpers. [bitvid] Initialized nostr nip44 helpers. TAP version 13 # Subtest: UploadModal closes on Escape and restores trigger focus ok 1 - UploadModal closes on Escape and restores trigger focus --- duration_ms: 253.34657 type: 'test' ... # Subtest: UploadModal backdrop click closes and restores trigger focus ok 2 - UploadModal backdrop click closes and restores trigger focus --- duration_ms: 100.634629 type: 'test' ... # Subtest: UploadModal mode toggle updates button states ok 3 - UploadModal mode toggle updates button states --- duration_ms: 66.857486 type: 'test' ... # Subtest: EditModal Escape closes and restores trigger focus ok 4 - EditModal Escape closes and restores trigger focus --- duration_ms: 97.583839 type: 'test' ... # Subtest: EditModal backdrop click closes and restores trigger focus ok 5 - EditModal backdrop click closes and restores trigger focus --- duration_ms: 90.667403 type: 'test' ... # Subtest: EditModal visibility toggle updates button state ok 6 - EditModal visibility toggle updates button state --- duration_ms: 83.446267 type: 'test' ... # Subtest: RevertModal Escape closes and restores trigger focus ok 7 - RevertModal Escape closes and restores trigger focus --- duration_ms: 63.535346 type: 'test' ... # Subtest: static modal helper toggles accessibility hooks ok 8 - static modal helper toggles accessibility hooks --- duration_ms: 12.214055 type: 'test' ... 1..8 # tests 8 # suites 0 # pass 8 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 780.198467 → Running tests/moderation-service.test.mjs [bitvid] Initialized nostr nip04 helpers. [bitvid] Initialized nostr nip44 helpers. TAP version 13 # Subtest: trusted report summaries respect personal blocks and admin lists ok 1 - trusted report summaries respect personal blocks and admin lists --- duration_ms: 6.901779 type: 'test' ... # Subtest: user block updates recompute summaries and emit notifications ok 2 - user block updates recompute summaries and emit notifications --- duration_ms: 6.727866 type: 'test' ... # Subtest: moderation thresholds emit logger hooks only when crossing ok 3 - moderation thresholds emit logger hooks only when crossing --- duration_ms: 2.621253 type: 'test' ... # Subtest: trusted mute aggregation tracks F1 mute lists ok 4 - trusted mute aggregation tracks F1 mute lists --- duration_ms: 1.901955 type: 'test' ... # Subtest: viewer mute list publishes and updates aggregation ok 5 - viewer mute list publishes and updates aggregation --- duration_ms: 5.24948 type: 'test' ... 1..5 # tests 5 # suites 0 # pass 5 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 41.81816 → Running tests/moderation-stage.test.mjs [bitvid] Initialized nostr nip04 helpers. [bitvid] Initialized nostr nip44 helpers. [feedEngine/moderation] metadata.moderation updated { stage: 'moderation', videoId: 'c', blockAutoplay: true, blurThumbnail: true, trustedCount: 5, reportType: 'nudity', hidden: false, hideReason: null, hideBypass: null } [feedEngine/moderation] metadata.moderation updated { stage: 'moderation', videoId: 'd', blockAutoplay: true, blurThumbnail: true, trustedCount: 3, reportType: 'nudity', hidden: false, hideReason: null, hideBypass: null } [feedEngine/moderation] metadata.moderation updated { stage: 'moderation', videoId: 'muted', blockAutoplay: true, blurThumbnail: true, trustedCount: 0, reportType: 'nudity', hidden: false, hideReason: null, hideBypass: null } [feedEngine/moderation] metadata.moderation updated { stage: 'moderation', videoId: 'normal', blockAutoplay: false, blurThumbnail: false, trustedCount: 0, reportType: 'nudity', hidden: false, hideReason: null, hideBypass: null } [feedEngine/moderation] metadata.moderation updated { stage: 'moderation', videoId: 'custom-threshold', blockAutoplay: false, blurThumbnail: false, trustedCount: 4, reportType: 'nudity', hidden: false, hideReason: null, hideBypass: null } [feedEngine/moderation] metadata.moderation updated { stage: 'moderation', videoId: 'custom-threshold', blockAutoplay: true, blurThumbnail: true, trustedCount: 4, reportType: 'nudity', hidden: false, hideReason: null, hideBypass: null } [feedEngine/moderation] metadata.moderation updated { stage: 'moderation', videoId: 'runtime-threshold', blockAutoplay: true, blurThumbnail: true, trustedCount: 3, reportType: 'nudity', hidden: true, hideReason: 'trusted-report-hide', hideBypass: null } [feedEngine/moderation] metadata.moderation updated { stage: 'moderation', videoId: 'runtime-threshold', blockAutoplay: false, blurThumbnail: false, trustedCount: 3, reportType: 'nudity', hidden: false, hideReason: null, hideBypass: null } [feedEngine/moderation] metadata.moderation updated { stage: 'moderation', videoId: 'resolver-threshold', blockAutoplay: false, blurThumbnail: false, trustedCount: 2, reportType: 'nudity', hidden: false, hideReason: null, hideBypass: null } [feedEngine/moderation] metadata.moderation updated { stage: 'moderation', videoId: 'resolver-threshold', blockAutoplay: true, blurThumbnail: true, trustedCount: 2, reportType: 'nudity', hidden: true, hideReason: 'trusted-report-hide', hideBypass: null } [feedEngine/moderation] metadata.moderation updated { stage: 'moderation', videoId: 'whitelisted-video', blockAutoplay: true, blurThumbnail: true, trustedCount: 4, reportType: 'nudity', hidden: false, hideReason: null, hideBypass: null } [feedEngine/moderation] metadata.moderation updated { stage: 'moderation', videoId: 'muted-video', blockAutoplay: true, blurThumbnail: true, trustedCount: 3, reportType: 'nudity', hidden: false, hideReason: null, hideBypass: null } [feedEngine/moderation] metadata.moderation updated { stage: 'moderation', videoId: 'whitelisted-video', blockAutoplay: true, blurThumbnail: true, trustedCount: 4, reportType: 'nudity', hidden: false, hideReason: null, hideBypass: null } [feedEngine/moderation] metadata.moderation updated { stage: 'moderation', videoId: 'muted-video', blockAutoplay: false, blurThumbnail: false, trustedCount: 0, reportType: 'nudity', hidden: false, hideReason: null, hideBypass: null } [feedEngine/moderation] metadata.moderation updated { stage: 'moderation', videoId: 'viewer-muted', blockAutoplay: true, blurThumbnail: true, trustedCount: 0, reportType: 'nudity', hidden: false, hideReason: null, hideBypass: null } [feedEngine/moderation] metadata.moderation updated { stage: 'moderation', videoId: '9999999999999999999999999999999999999999999999999999999999999999', blockAutoplay: true, blurThumbnail: true, trustedCount: 1, reportType: 'nudity', hidden: false, hideReason: null, hideBypass: null } [feedEngine/moderation] metadata.moderation updated { stage: 'moderation', videoId: '9999999999999999999999999999999999999999999999999999999999999999', blockAutoplay: false, blurThumbnail: false, trustedCount: 0, reportType: 'nudity', hidden: false, hideReason: null, hideBypass: null } TAP version 13 # Subtest: moderation stage enforces admin lists without whitelist bypass ok 1 - moderation stage enforces admin lists without whitelist bypass --- duration_ms: 5.702472 type: 'test' ... # Subtest: moderation stage annotates trusted mute metadata ok 2 - moderation stage annotates trusted mute metadata --- duration_ms: 1.608884 type: 'test' ... # Subtest: moderation stage applies provided thresholds ok 3 - moderation stage applies provided thresholds --- duration_ms: 1.731432 type: 'test' ... # Subtest: moderation stage respects runtime threshold changes ok 4 - moderation stage respects runtime threshold changes --- duration_ms: 2.123386 type: 'test' ... # Subtest: moderation stage supports function-based threshold resolvers ok 5 - moderation stage supports function-based threshold resolvers --- duration_ms: 1.466937 type: 'test' ... # Subtest: moderation stage propagates whitelist, muters, and threshold updates ok 6 - moderation stage propagates whitelist, muters, and threshold updates --- duration_ms: 1.89511 type: 'test' ... # Subtest: moderation stage blurs viewer-muted authors ok 7 - moderation stage blurs viewer-muted authors --- duration_ms: 0.827521 type: 'test' ... # Subtest: moderation stage clears cached reporters and muters after service signals ok 8 - moderation stage clears cached reporters and muters after service signals --- duration_ms: 1.194666 type: 'test' ... 1..8 # tests 8 # suites 0 # pass 8 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 34.735258 → Running tests/moderation/hide-thresholds.test.mjs [bitvid] Initialized nostr nip04 helpers. [bitvid] Initialized nostr nip44 helpers. [feedEngine/moderation] metadata.moderation updated { stage: 'moderation', videoId: '1111111111111111111111111111111111111111111111111111111111111111', blockAutoplay: true, blurThumbnail: true, trustedCount: 0, reportType: 'nudity', hidden: true, hideReason: 'trusted-mute-hide', hideBypass: null } [feedEngine/moderation] metadata.moderation updated { stage: 'moderation', videoId: '2222222222222222222222222222222222222222222222222222222222222222', blockAutoplay: true, blurThumbnail: true, trustedCount: 5, reportType: 'nudity', hidden: true, hideReason: 'trusted-report-hide', hideBypass: null } [feedEngine/moderation] metadata.moderation updated { stage: 'moderation', videoId: '6666666666666666666666666666666666666666666666666666666666666666', blockAutoplay: true, blurThumbnail: true, trustedCount: 4, reportType: 'nudity', hidden: true, hideReason: 'trusted-mute-hide', hideBypass: null } [feedEngine/moderation] metadata.moderation updated { stage: 'moderation', videoId: '6666666666666666666666666666666666666666666666666666666666666666', blockAutoplay: true, blurThumbnail: true, trustedCount: 4, reportType: 'nudity', hidden: false, hideReason: null, hideBypass: null } [feedEngine/moderation] metadata.moderation updated { stage: 'moderation', videoId: '9999999999999999999999999999999999999999999999999999999999999999', blockAutoplay: true, blurThumbnail: true, trustedCount: 0, reportType: 'nudity', hidden: false, hideReason: null, hideBypass: null } [feedEngine/moderation] metadata.moderation updated { stage: 'moderation', videoId: '9999999999999999999999999999999999999999999999999999999999999999', blockAutoplay: true, blurThumbnail: true, trustedCount: 0, reportType: 'nudity', hidden: true, hideReason: 'trusted-mute-hide', hideBypass: null } [feedEngine/moderation] metadata.moderation updated { stage: 'moderation', videoId: '3333333333333333333333333333333333333333333333333333333333333333', blockAutoplay: true, blurThumbnail: true, trustedCount: 4, reportType: 'nudity', hidden: false, hideReason: 'trusted-report-hide', hideBypass: 'feed-policy' } [feedEngine/moderation] metadata.moderation updated { stage: 'moderation', videoId: '4444444444444444444444444444444444444444444444444444444444444444', blockAutoplay: true, blurThumbnail: true, trustedCount: 6, reportType: 'nudity', hidden: true, hideReason: 'trusted-report-hide', hideBypass: null } TAP version 13 # Subtest: moderation stage hides videos muted by trusted when threshold met ok 1 - moderation stage hides videos muted by trusted when threshold met --- duration_ms: 5.841599 type: 'test' ... # Subtest: moderation stage hides videos when trusted reports exceed threshold ok 2 - moderation stage hides videos when trusted reports exceed threshold --- duration_ms: 1.197931 type: 'test' ... # Subtest: moderation stage respects runtime hide threshold changes ok 3 - moderation stage respects runtime hide threshold changes --- duration_ms: 1.590689 type: 'test' ... # Subtest: moderation stage supports trusted mute hide resolver functions ok 4 - moderation stage supports trusted mute hide resolver functions --- duration_ms: 1.583179 type: 'test' ... # Subtest: moderation stage bypasses hard hides on home feed ok 5 - moderation stage bypasses hard hides on home feed --- duration_ms: 1.389067 type: 'test' ... # Subtest: moderation stage hides admin-whitelisted videos once thresholds fire ok 6 - moderation stage hides admin-whitelisted videos once thresholds fire --- duration_ms: 0.974627 type: 'test' ... 1..6 # tests 6 # suites 0 # pass 6 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 27.86573 → Running tests/moderation/submit-report.test.mjs [bitvid] Initialized nostr nip04 helpers. [bitvid] Initialized nostr nip44 helpers. TAP version 13 # Subtest: submitReport emits NIP-56 compliant report tags ok 1 - submitReport emits NIP-56 compliant report tags --- duration_ms: 10.002344 type: 'test' ... 1..1 # tests 1 # suites 0 # pass 1 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 18.651764 → Running tests/moderation/trust-seeds.test.mjs [bitvid] Initialized nostr nip04 helpers. [bitvid] Initialized nostr nip44 helpers. [bitvid] [moderationService] moderation threshold crossed [bitvid] [moderationService] moderation threshold crossed [bitvid] [moderationService] moderation threshold crossed [bitvid] [moderationService] moderation threshold crossed TAP version 13 # Subtest: default trust seeds derive from config ok 1 - default trust seeds derive from config --- duration_ms: 2.500167 type: 'test' ... # Subtest: trusted seeds contribute to trusted mute counts ok 2 - trusted seeds contribute to trusted mute counts --- duration_ms: 4.813344 type: 'test' ... # Subtest: trusted seeds contribute to trusted report counts ok 3 - trusted seeds contribute to trusted report counts --- duration_ms: 2.791678 type: 'test' ... # Subtest: trusted seed updates recompute guest report summaries ok 4 - trusted seed updates recompute guest report summaries --- duration_ms: 1.188947 type: 'test' ... # Subtest: moderator seeds populate trusted contacts ok 5 - moderator seeds populate trusted contacts --- duration_ms: 0.918822 type: 'test' ... [trustBootstrap] bootstrapTrustedSeeds called [trustBootstrap] waitForAccessControl result { ok: true, timedOut: false } [trustBootstrap] Applying 2 trusted seeds [ 'npub15jnttpymeytm80hatjqcvhhqhzrhx6gxp8pq0wn93rhnu8s9h9dsha32lx', 'npub1moderatorexamplemoderatorexamplemoderatorexample1' ] [trustBootstrap] Applying 2 trusted seeds [ 'npub15jnttpymeytm80hatjqcvhhqhzrhx6gxp8pq0wn93rhnu8s9h9dsha32lx', 'npub1moderatorexamplemoderatorexamplemoderatorexample1' ] [trustBootstrap] Applying 3 trusted seeds [ 'npub15jnttpymeytm80hatjqcvhhqhzrhx6gxp8pq0wn93rhnu8s9h9dsha32lx', 'npub1newmoderatorexamplemoderatorexamplemoderator', 'npub1secondmoderatorexamplemoderatorexamplemod' ] # Subtest: bootstrap seeds track editor roster and ignore whitelist-only changes ok 6 - bootstrap seeds track editor roster and ignore whitelist-only changes --- duration_ms: 134.05908 type: 'test' ... 1..6 # tests 6 # suites 0 # pass 6 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 3654.203339 → Running tests/moderation/trusted-mute-lists.test.mjs [bitvid] Initialized nostr nip04 helpers. [bitvid] Initialized nostr nip44 helpers. TAP version 13 [feedEngine/moderation] metadata.moderation updated { stage: 'moderation', videoId: 'video-muted', blockAutoplay: true, blurThumbnail: true, trustedCount: 0, reportType: 'nudity', hidden: true, hideReason: 'trusted-mute-hide', hideBypass: null } # Subtest: trusted mute lists from seeds hide authors for anonymous viewers ok 1 - trusted mute lists from seeds hide authors for anonymous viewers --- duration_ms: 14.216512 type: 'test' ... 1..1 # tests 1 # suites 0 # pass 1 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 21.917289 → Running tests/moderation/trusted-report-count.test.mjs [bitvid] Initialized nostr nip04 helpers. [bitvid] Initialized nostr nip44 helpers. [bitvid] [moderationService] moderation threshold crossed [bitvid] [moderationService] moderation threshold crossed [bitvid] [moderationService] moderation threshold crossed [bitvid] [moderationService] moderation threshold crossed [bitvid] [moderationService] moderation threshold crossed [bitvid] [moderationService] moderation threshold crossed [bitvid] [moderationService] moderation threshold crossed [bitvid] [moderationService] moderation threshold crossed [bitvid] [moderationService] moderation threshold crossed [bitvid] [moderationService] moderation threshold crossed [bitvid] [moderationService] moderation threshold crossed [bitvid] [moderationService] moderation threshold crossed TAP version 13 # Subtest: trustedReportCount dedupes multiple reports from the same trusted reporter ok 1 - trustedReportCount dedupes multiple reports from the same trusted reporter --- duration_ms: 5.629397 type: 'test' ... # Subtest: trustedReportCount ignores reports from muted or blocked reporters ok 2 - trustedReportCount ignores reports from muted or blocked reporters --- duration_ms: 2.843805 type: 'test' ... # Subtest: blocking and unblocking reporters recomputes trusted summaries ok 3 - blocking and unblocking reporters recomputes trusted summaries --- duration_ms: 2.877519 type: 'test' ... # Subtest: trustedReportCount only counts eligible F1 reporters and admin whitelist ok 4 - trustedReportCount only counts eligible F1 reporters and admin whitelist --- duration_ms: 2.122859 type: 'test' ... 1..4 # tests 4 # suites 0 # pass 4 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 26.031327 → Running tests/moderation/video-card.test.mjs [bitvid] Initialized nostr nip04 helpers. [bitvid] Initialized nostr nip44 helpers. TAP version 13 # Subtest: VideoCard renders moderation badges and respects viewer override ok 1 - VideoCard renders moderation badges and respects viewer override --- duration_ms: 337.716608 type: 'test' ... # Subtest: VideoCard hides content when hide metadata is present and override unmasks it ok 2 - VideoCard hides content when hide metadata is present and override unmasks it --- duration_ms: 39.07444 type: 'test' ... # Subtest: VideoCard blurs viewer-muted creators ok 3 - VideoCard blurs viewer-muted creators --- duration_ms: 17.605454 type: 'test' ... # Subtest: VideoCard blurs thumbnails when trusted mute triggers without reports ok 4 - VideoCard blurs thumbnails when trusted mute triggers without reports --- duration_ms: 16.79893 type: 'test' ... # Subtest: VideoCard block action restores trusted mute hide state after override ok 5 - VideoCard block action restores trusted mute hide state after override --- duration_ms: 35.096038 type: 'test' ... # Subtest: applyModerationContextDatasets clears blur when overrides are active ok 6 - applyModerationContextDatasets clears blur when overrides are active --- duration_ms: 8.693161 type: 'test' ... # Subtest: buildModerationBadgeText returns trusted contact block copy when autoplay block and trusted mute combine ok 7 - buildModerationBadgeText returns trusted contact block copy when autoplay block and trusted mute combine --- duration_ms: 0.211171 type: 'test' ... 1..7 # tests 7 # suites 0 # pass 7 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 463.775147 → Running tests/more-menu-controller.test.mjs [bitvid] Initialized nostr nip04 helpers. [bitvid] Initialized nostr nip44 helpers. TAP version 13 # Subtest: copy-link action writes to clipboard and shows success ok 1 - copy-link action writes to clipboard and shows success --- duration_ms: 3.111129 type: 'test' ... # Subtest: blacklist-author requires moderator access and refreshes subscriptions ok 2 - blacklist-author requires moderator access and refreshes subscriptions --- duration_ms: 0.731558 type: 'test' ... # Subtest: blacklist-author shows error when no moderator session is available ok 3 - blacklist-author shows error when no moderator session is available --- duration_ms: 0.318548 type: 'test' ... # Subtest: block-author updates user blocks, reloads videos, and refreshes feeds ok 4 - block-author updates user blocks, reloads videos, and refreshes feeds --- duration_ms: 0.720938 type: 'test' ... # Subtest: mute-author updates viewer mute list and refreshes feeds ok 5 - mute-author updates viewer mute list and refreshes feeds --- duration_ms: 0.851143 type: 'test' ... # Subtest: unmute-author removes creators from viewer mute list ok 6 - unmute-author removes creators from viewer mute list --- duration_ms: 0.556184 type: 'test' ... 1..6 # tests 6 # suites 0 # pass 6 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 19.862063 → Running tests/nip71-base-event-tags.test.mjs [bitvid] Initialized nostr nip04 helpers. [bitvid] Initialized nostr nip44 helpers. TAP version 13 # Subtest: 30078 events carry nip71 metadata tags and hydrate fallback metadata ok 1 - 30078 events carry nip71 metadata tags and hydrate fallback metadata --- duration_ms: 5.893582 type: 'test' ... # Subtest: imeta tags lower-case mime values ok 2 - imeta tags lower-case mime values --- duration_ms: 0.55853 type: 'test' ... 1..2 # tests 2 # suites 0 # pass 2 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 19.71169 → Running tests/nip71-builder.test.mjs [bitvid] Initialized nostr nip04 helpers. [bitvid] Initialized nostr nip44 helpers. TAP version 13 # Subtest: buildNip71VideoEvent assembles rich metadata ok 1 - buildNip71VideoEvent assembles rich metadata --- duration_ms: 3.961743 type: 'test' ... # Subtest: buildNip71VideoEvent falls back to summary and selects kind ok 2 - buildNip71VideoEvent falls back to summary and selects kind --- duration_ms: 0.471883 type: 'test' ... # Subtest: buildNip71VideoEvent attaches pointer tags ok 3 - buildNip71VideoEvent attaches pointer tags --- duration_ms: 2.247628 type: 'test' ... # Subtest: extractNip71MetadataFromTags parses metadata and pointers ok 4 - extractNip71MetadataFromTags parses metadata and pointers --- duration_ms: 1.468437 type: 'test' ... 1..4 # tests 4 # suites 0 # pass 4 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 21.73109 → Running tests/nip71-form-manager.test.mjs TAP version 13 # Subtest: collectSection sanitizes and deduplicates hashtags ok 1 - collectSection sanitizes and deduplicates hashtags --- duration_ms: 106.146146 type: 'test' ... # Subtest: hydrateSection renders sanitized hashtags with prefix ok 2 - hydrateSection renders sanitized hashtags with prefix --- duration_ms: 21.629194 type: 'test' ... 1..2 # tests 2 # suites 0 # pass 2 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 139.702012 → Running tests/nostr-login-permissions.test.mjs [bitvid] Initialized nostr nip04 helpers. [bitvid] Initialized nostr nip44 helpers. Got pubkey: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff Converted to npub: npub1lllllllllllllllllllllllllllllllllllllllllllllllllllsq7lrjw Whitelist: [] Blacklist: [] Logged in with extension. Pubkey: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff User logged out. Got pubkey: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff Converted to npub: npub1lllllllllllllllllllllllllllllllllllllllllllllllllllsq7lrjw Whitelist: [] Blacklist: [] Logged in with extension. Pubkey: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff User logged out. [bitvid] [nostr] extension.enable request with explicit permissions failed: Error: object permissions unsupported at enableImpl (file:///app/tests/nostr-login-permissions.test.mjs:299:31) at Object.enable (file:///app/tests/nostr-login-permissions.test.mjs:60:32) at runNip07WithRetry.label (file:///app/js/nostr/nip07Permissions.js:282:36) at getOrStartOperation (file:///app/js/nostr/nip07Permissions.js:202:41) at withNip07Timeout (file:///app/js/nostr/nip07Permissions.js:170:23) at runNip07WithRetry (file:///app/js/nostr/nip07Permissions.js:214:18) at requestEnablePermissions (file:///app/js/nostr/nip07Permissions.js:281:13) at NostrClient.ensureExtensionPermissions (file:///app/js/nostr/client.js:2488:32) at NostrClient.login (file:///app/js/nostr/client.js:3799:43) at TestContext. (file:///app/tests/nostr-login-permissions.test.mjs:309:38) Got pubkey: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff Converted to npub: npub1lllllllllllllllllllllllllllllllllllllllllllllllllllsq7lrjw Whitelist: [] Blacklist: [] Logged in with extension. Pubkey: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff User logged out. [bitvid] [nostr] extension.enable request with explicit permissions failed: Error: payloads not supported at enableImpl (file:///app/tests/nostr-login-permissions.test.mjs:342:31) at Object.enable (file:///app/tests/nostr-login-permissions.test.mjs:60:32) at runNip07WithRetry.label (file:///app/js/nostr/nip07Permissions.js:282:36) at getOrStartOperation (file:///app/js/nostr/nip07Permissions.js:202:41) at withNip07Timeout (file:///app/js/nostr/nip07Permissions.js:170:23) at runNip07WithRetry (file:///app/js/nostr/nip07Permissions.js:214:18) at requestEnablePermissions (file:///app/js/nostr/nip07Permissions.js:281:13) at NostrClient.ensureExtensionPermissions (file:///app/js/nostr/client.js:2488:32) at NostrClient.login (file:///app/js/nostr/client.js:3799:43) at TestContext. (file:///app/tests/nostr-login-permissions.test.mjs:349:38) [bitvid] [nostr] extension.enable request with explicit permissions failed: Error: payloads not supported at enableImpl (file:///app/tests/nostr-login-permissions.test.mjs:342:31) at Object.enable (file:///app/tests/nostr-login-permissions.test.mjs:60:32) at runNip07WithRetry.label (file:///app/js/nostr/nip07Permissions.js:282:36) at getOrStartOperation (file:///app/js/nostr/nip07Permissions.js:202:41) at withNip07Timeout (file:///app/js/nostr/nip07Permissions.js:170:23) at runNip07WithRetry (file:///app/js/nostr/nip07Permissions.js:214:18) at requestEnablePermissions (file:///app/js/nostr/nip07Permissions.js:281:13) at async NostrClient.ensureExtensionPermissions (file:///app/js/nostr/client.js:2488:26) at async NostrClient.login (file:///app/js/nostr/client.js:3799:32) at async TestContext. (file:///app/tests/nostr-login-permissions.test.mjs:349:20) Got pubkey: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff Converted to npub: npub1lllllllllllllllllllllllllllllllllllllllllllllllllllsq7lrjw Whitelist: [] Blacklist: [] Logged in with extension. Pubkey: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff User logged out. TAP version 13 # Subtest: NIP-07 login requests decrypt permissions upfront ok 1 - NIP-07 login requests decrypt permissions upfront --- duration_ms: 6.864581 type: 'test' ... # Subtest: NIP-07 decrypt reuses cached extension permissions ok 2 - NIP-07 decrypt reuses cached extension permissions --- duration_ms: 2.756726 type: 'test' ... # Subtest: NIP-07 login falls back when structured permissions fail ok 3 - NIP-07 login falls back when structured permissions fail --- duration_ms: 2.674764 type: 'test' ... # Subtest: NIP-07 login supports extensions that only allow enable() without payload ok 4 - NIP-07 login supports extensions that only allow enable() without payload --- duration_ms: 2.226945 type: 'test' ... [bitvid] [nostr] extension.enable request with explicit permissions failed: Error: Timed out waiting for the NIP-07 extension. Confirm the extension prompt in your browser toolbar and try again. at Timeout. (file:///app/js/nostr/nip07Permissions.js:164:14) at listOnTimeout (node:internal/timers:588:17) at process.processTimers (node:internal/timers:523:7) Got pubkey: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff Converted to npub: npub1lllllllllllllllllllllllllllllllllllllllllllllllllllsq7lrjw Whitelist: [] Blacklist: [] Logged in with extension. Pubkey: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff User logged out. [bitvid] [nostr] extension.enable request with explicit permissions failed: Error: permission denied at enableImpl (file:///app/tests/nostr-login-permissions.test.mjs:430:29) at Object.enable (file:///app/tests/nostr-login-permissions.test.mjs:60:32) at runNip07WithRetry.label (file:///app/js/nostr/nip07Permissions.js:282:36) at getOrStartOperation (file:///app/js/nostr/nip07Permissions.js:202:41) at withNip07Timeout (file:///app/js/nostr/nip07Permissions.js:170:23) at runNip07WithRetry (file:///app/js/nostr/nip07Permissions.js:214:18) at requestEnablePermissions (file:///app/js/nostr/nip07Permissions.js:281:13) at NostrClient.ensureExtensionPermissions (file:///app/js/nostr/client.js:2488:32) at NostrClient.login (file:///app/js/nostr/client.js:3799:43) at file:///app/tests/nostr-login-permissions.test.mjs:435:44 [bitvid] [nostr] extension.enable request with explicit permissions failed: Error: permission denied at enableImpl (file:///app/tests/nostr-login-permissions.test.mjs:430:29) at Object.enable (file:///app/tests/nostr-login-permissions.test.mjs:60:32) at runNip07WithRetry.label (file:///app/js/nostr/nip07Permissions.js:282:36) at getOrStartOperation (file:///app/js/nostr/nip07Permissions.js:202:41) at withNip07Timeout (file:///app/js/nostr/nip07Permissions.js:170:23) at runNip07WithRetry (file:///app/js/nostr/nip07Permissions.js:214:18) at requestEnablePermissions (file:///app/js/nostr/nip07Permissions.js:281:13) at async NostrClient.ensureExtensionPermissions (file:///app/js/nostr/client.js:2488:26) at async NostrClient.login (file:///app/js/nostr/client.js:3799:32) at async waitForActual (node:assert:644:5) [bitvid] Login error: Error: The NIP-07 extension reported "permission denied". Please approve the prompt and try again. at NostrClient.login (file:///app/js/nostr/client.js:3805:29) at async waitForActual (node:assert:644:5) at async Function.rejects (node:assert:767:25) at async TestContext. (file:///app/tests/nostr-login-permissions.test.mjs:435:5) at async Test.run (node:internal/test_runner/test:1054:7) at async Test.processPendingSubtests (node:internal/test_runner/test:744:7) { cause: Error: permission denied at enableImpl (file:///app/tests/nostr-login-permissions.test.mjs:430:29) at Object.enable (file:///app/tests/nostr-login-permissions.test.mjs:60:32) at runNip07WithRetry.label (file:///app/js/nostr/nip07Permissions.js:282:64) at getOrStartOperation (file:///app/js/nostr/nip07Permissions.js:202:41) at withNip07Timeout (file:///app/js/nostr/nip07Permissions.js:170:23) at runNip07WithRetry (file:///app/js/nostr/nip07Permissions.js:214:18) at requestEnablePermissions (file:///app/js/nostr/nip07Permissions.js:281:13) at async NostrClient.ensureExtensionPermissions (file:///app/js/nostr/client.js:2488:26) at async NostrClient.login (file:///app/js/nostr/client.js:3799:32) at async waitForActual (node:assert:644:5) } User logged out. # Subtest: NIP-07 login quickly retries when a permission payload stalls ok 5 - NIP-07 login quickly retries when a permission payload stalls --- duration_ms: 82.658153 type: 'test' ... # Subtest: NIP-07 login surfaces enable permission errors ok 6 - NIP-07 login surfaces enable permission errors --- duration_ms: 3.366801 type: 'test' ... # Subtest: runNip07WithRetry respects timeout without retry multiplier ok 7 - runNip07WithRetry respects timeout without retry multiplier --- duration_ms: 61.445633 type: 'test' ... 1..7 # tests 7 # suites 0 # pass 7 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 173.0472 → Running tests/nostr-private-key-signer.test.mjs [bitvid] Initialized nostr nip04 helpers. [bitvid] Initialized nostr nip44 helpers. TAP version 13 # Subtest: registerPrivateKeySigner exposes nip04 helpers ok 1 - registerPrivateKeySigner exposes nip04 helpers --- duration_ms: 257.484794 type: 'test' ... 1..1 # tests 1 # suites 0 # pass 1 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 282.402631 → Running tests/nostr-send-direct-message.test.mjs [bitvid] Initialized nostr nip04 helpers. [bitvid] Initialized nostr nip44 helpers. TAP version 13 # Subtest: sendDirectMessage succeeds with private key signer and no extension ok 1 - sendDirectMessage succeeds with private key signer and no extension --- duration_ms: 266.203941 type: 'test' ... 1..1 # tests 1 # suites 0 # pass 1 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 289.835841 → Running tests/nostr-service-access-control.test.mjs [bitvid] Initialized nostr nip04 helpers. [bitvid] Initialized nostr nip44 helpers. [moderationService] reconcileTrustedMuteSubscriptions { previous: 0, next: 0 } [moderationService] subscribing to trusted mute list for 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef (moderationService) ensurePool failed while subscribing to trusted mute list for 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef Error: nostr-client-unavailable at ModerationService.ensurePool (file:///app/js/services/moderationService.js:1842:13) at file:///app/js/services/moderationService.js:1128:20 at ModerationService.subscribeToTrustedMuteList (file:///app/js/services/moderationService.js:1195:7) at ModerationService.reconcileTrustedMuteSubscriptions (file:///app/js/services/moderationService.js:1076:12) at ModerationService.rebuildTrustedContacts (file:///app/js/services/moderationService.js:655:10) at ModerationService.clearTrustedMuteTracking (file:///app/js/services/moderationService.js:1039:10) at ModerationService.setViewerPubkey (file:///app/js/services/moderationService.js:1887:10) at ModerationService.refreshViewerFromClient (file:///app/js/services/moderationService.js:1861:17) at NostrService.getModerationService (file:///app/js/services/nostrService.js:870:32) at NostrService.isViewerVideoAuthor (file:///app/js/services/nostrService.js:1706:12) [moderationService] ensurePool failed while fetching contacts Error: nostr-client-unavailable at ModerationService.ensurePool (file:///app/js/services/moderationService.js:1842:13) at ModerationService.fetchTrustedContacts (file:///app/js/services/moderationService.js:1937:18) at ModerationService.setViewerPubkey (file:///app/js/services/moderationService.js:1903:36) at ModerationService.refreshViewerFromClient (file:///app/js/services/moderationService.js:1861:17) at NostrService.getModerationService (file:///app/js/services/nostrService.js:870:32) at NostrService.isViewerVideoAuthor (file:///app/js/services/nostrService.js:1706:12) at NostrService.shouldIncludeVideo (file:///app/js/services/nostrService.js:1002:33) at TestContext. (file:///app/tests/nostr-service-access-control.test.mjs:143:13) at Test.runInAsyncScope (node:async_hooks:214:14) at Test.run (node:internal/test_runner/test:1047:25) [moderationService] ensurePool failed while subscribing to contacts Error: nostr-client-unavailable at ModerationService.ensurePool (file:///app/js/services/moderationService.js:1842:13) at ModerationService.subscribeToContactList (file:///app/js/services/moderationService.js:2011:18) at ModerationService.setViewerPubkey (file:///app/js/services/moderationService.js:1918:10) TAP version 13 # Subtest: shouldIncludeVideo returns true for whitelist author when npubEncode throws ok 1 - shouldIncludeVideo returns true for whitelist author when npubEncode throws --- duration_ms: 1.829777 type: 'test' ... # Subtest: shouldIncludeVideo rejects blacklisted authors provided as npub ok 2 - shouldIncludeVideo rejects blacklisted authors provided as npub --- duration_ms: 0.375703 type: 'test' ... # Subtest: shouldIncludeVideo rejects blacklisted authors provided as hex when npubEncode throws ok 3 - shouldIncludeVideo rejects blacklisted authors provided as hex when npubEncode throws --- duration_ms: 0.421284 type: 'test' ... # Subtest: shouldIncludeVideo always returns true for the viewer's own video ok 4 - shouldIncludeVideo always returns true for the viewer's own video --- duration_ms: 4.98275 type: 'test' ... # Subtest: shouldIncludeVideo allows access when access control would deny the author ok 5 - shouldIncludeVideo allows access when access control would deny the author --- duration_ms: 57.840207 type: 'test' ... [moderationService] subscribing to trusted mute list for 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef (moderationService) ensurePool failed while subscribing to trusted mute list for 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef Error: nostr-client-unavailable at ModerationService.ensurePool (file:///app/js/services/moderationService.js:1842:13) at file:///app/js/services/moderationService.js:1128:20 at ModerationService.subscribeToTrustedMuteList (file:///app/js/services/moderationService.js:1195:7) at ModerationService.ensureViewerMuteListLoaded (file:///app/js/services/moderationService.js:1516:35) at ModerationService.setViewerPubkey (file:///app/js/services/moderationService.js:1923:16)