diff --git a/detect_flakiness.py b/detect_flakiness.py deleted file mode 100644 index 8f2d010a..00000000 --- a/detect_flakiness.py +++ /dev/null @@ -1,80 +0,0 @@ -import os -import subprocess -import sys - -def find_test_files(start_dir): - test_files = [] - for root, dirs, files in os.walk(start_dir): - if 'visual' in dirs: - dirs.remove('visual') - - for file in files: - if file.endswith('.test.mjs') or file.endswith('.test.js'): - full_path = os.path.join(root, file) - try: - with open(full_path, 'r', encoding='utf-8') as f: - content = f.read() - if 'node:test' in content: - test_files.append(full_path) - except Exception as e: - print(f"Error reading {full_path}: {e}") - return sorted(test_files) - -def run_test(test_file, setup_file): - # We use node directly. sys.executable might be python, so we need 'node'. - # Assuming 'node' is in PATH. - cmd = ['node', '--import', setup_file, test_file] - - try: - result = subprocess.run( - cmd, - capture_output=True, - text=True, - check=False - ) - return result.returncode == 0, result.stdout, result.stderr - except Exception as e: - return False, "", str(e) - -def main(): - root_dir = os.getcwd() - tests_dir = os.path.join(root_dir, 'tests') - setup_file = os.path.join(root_dir, 'tests', 'test-helpers', 'setup-localstorage.mjs') - - if not os.path.exists(setup_file): - # The script uses a relative URL in the JS runner, let's try to resolve it relative to CWD - # The JS runner uses: new URL("../tests/test-helpers/setup-localstorage.mjs", import.meta.url) - # If running from root, it is tests/test-helpers/setup-localstorage.mjs - pass - - test_files = find_test_files(tests_dir) - print(f"Found {len(test_files)} test files.") - - flaky_tests = {} - - for test_file in test_files: - print(f"Checking {os.path.relpath(test_file, root_dir)}...") - failures = [] - for i in range(10): - success, stdout, stderr = run_test(test_file, f"file://{setup_file}") - if not success: - failures.append((i, stdout, stderr)) - print(f" Failed on iteration {i+1}") - # We can stop early if we found it's flaky, or continue to see failure rate? - # Let's stop early to save time for this task, as one failure is enough to be flaky. - break - - if failures: - flaky_tests[test_file] = failures - - if flaky_tests: - print("\nFound flaky tests:") - for test_file, failures in flaky_tests.items(): - print(f"- {os.path.relpath(test_file, root_dir)}") - # Print the first failure output - print(f" Output:\n{failures[0][2]}\n{failures[0][1]}") - else: - print("\nNo flaky tests found.") - -if __name__ == "__main__": - main() diff --git a/test_output.log b/test_output.log deleted file mode 100644 index 1acafa56..00000000 --- a/test_output.log +++ /dev/null @@ -1,1893 +0,0 @@ - -> bitvid@1.0.0 test:unit -> node scripts/run-unit-tests.mjs - - -→ Running tests/app-batch-fetch-profiles.test.mjs -[bitvid] Initialized nostr nip04 helpers. -[bitvid] Initialized nostr nip44 helpers. -[batchFetchProfiles] Failed to fetch profiles from relay wss://fail.example: Error: relay timed out - at Object.list (file:///app/tests/app-batch-fetch-profiles.test.mjs:80:31) - at file:///app/js/utils/profileBatchFetcher.js:115:10 - at Array.map () - at batchFetchProfilesFromRelays (file:///app/js/utils/profileBatchFetcher.js:112:75) - at TestContext. (file:///app/tests/app-batch-fetch-profiles.test.mjs:87:11) - at Test.runInAsyncScope (node:async_hooks:214:14) - at Test.run (node:internal/test_runner/test:1047:25) - at Test.start (node:internal/test_runner/test:944:17) - at startSubtestAfterBootstrap (node:internal/test_runner/harness:296:17) -TAP version 13 -# Subtest: batchFetchProfiles handles fast and failing relays -ok 1 - batchFetchProfiles handles fast and failing relays - --- - duration_ms: 3.847532 - type: 'test' - ... -1..1 -# tests 1 -# suites 0 -# pass 1 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 15.85785 - -→ 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: 232.522956 - type: 'test' - ... -# Subtest: renderChannelVideosFromList applies moderation blur without existing metadata -ok 2 - renderChannelVideosFromList applies moderation blur without existing metadata - --- - duration_ms: 31.783442 - 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.23191 - type: 'test' - ... -# Subtest: moderation override clears channel blur via event wiring -ok 4 - moderation override clears channel blur via event wiring - --- - duration_ms: 36.970563 - 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: 31.280065 - 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.2117 - type: 'test' - ... -1..6 -# tests 6 -# suites 0 -# pass 6 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 380.211556 - -→ 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.128603 - 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.840989 - type: 'test' - ... -# Subtest: handleHashChange respects explicit view regardless of login state -ok 3 - handleHashChange respects explicit view regardless of login state - --- - duration_ms: 9.951321 - type: 'test' - ... -1..3 -# tests 3 -# suites 0 -# pass 3 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 108.26157 - -→ 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: 86.167066 - type: 'test' - ... -# Subtest: hydrateSidebarNavigation hides chrome controls for logged-out viewers -ok 2 - hydrateSidebarNavigation hides chrome controls for logged-out viewers - --- - duration_ms: 12.849406 - type: 'test' - ... -1..2 -# tests 2 -# suites 0 -# pass 2 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 110.435512 - -→ 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.824922 - type: 'test' - ... -# Subtest: isUserLoggedIn treats extension logins as authenticated -ok 2 - isUserLoggedIn treats extension logins as authenticated - --- - duration_ms: 0.463582 - type: 'test' - ... -# Subtest: isUserLoggedIn guards against mismatched nostrClient state -ok 3 - isUserLoggedIn guards against mismatched nostrClient state - --- - duration_ms: 0.273019 - type: 'test' - ... -# Subtest: isUserLoggedIn ignores anonymous session actor mismatches -ok 4 - isUserLoggedIn ignores anonymous session actor mismatches - --- - duration_ms: 0.257852 - type: 'test' - ... -# Subtest: isUserLoggedIn rejects mismatched managed session actors -ok 5 - isUserLoggedIn rejects mismatched managed session actors - --- - duration_ms: 0.432518 - type: 'test' - ... -1..5 -# tests 5 -# suites 0 -# pass 5 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 33.654661 - -→ 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: 206.383606 - type: 'test' - ... -# Subtest: handleModerationOverride resumes deferred playback -ok 2 - handleModerationOverride resumes deferred playback - --- - duration_ms: 1.336124 - 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: 3.85506 - type: 'test' - ... -# Subtest: handleModerationBlock returns false when viewer is logged out -ok 4 - handleModerationBlock returns false when viewer is logged out - --- - duration_ms: 1.71659 - type: 'test' - ... -1..4 -# tests 4 -# suites 0 -# pass 4 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 241.804569 - -→ 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: 211.966355 - type: 'test' - ... -1..1 -# tests 1 -# suites 0 -# pass 1 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 240.518204 - -→ 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: 2.926753 - 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.555046 - type: 'test' - ... -# Subtest: skips candidates without tag metadata -ok 3 - skips candidates without tag metadata - --- - duration_ms: 0.476961 - 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.591487 - type: 'test' - ... -1..4 -# tests 4 -# suites 0 -# pass 4 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 34.404353 - -→ 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.004895 - 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.46031 - type: 'test' - ... -# Subtest: buildCommentEvent normalizes relays and preserves explicit overrides -ok 3 - buildCommentEvent normalizes relays and preserves explicit overrides - --- - duration_ms: 0.957929 - 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.337432 - type: 'test' - ... -# Subtest: buildCommentEvent accepts partial metadata for parent overrides -ok 5 - buildCommentEvent accepts partial metadata for parent overrides - --- - duration_ms: 0.408436 - type: 'test' - ... -# Subtest: buildCommentEvent sanitizes additional tags before signing -ok 6 - buildCommentEvent sanitizes additional tags before signing - --- - duration_ms: 0.901309 - type: 'test' - ... -1..6 -# tests 6 -# suites 0 -# pass 6 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 20.064818 - -→ 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: 4.0376 - type: 'test' - ... -# Subtest: CommentThreadService surfaces cache read failures -ok 2 - CommentThreadService surfaces cache read failures - --- - duration_ms: 0.831567 - type: 'test' - ... -# Subtest: CommentThreadService surfaces cache write failures -ok 3 - CommentThreadService surfaces cache write failures - --- - duration_ms: 0.514611 - type: 'test' - ... -# Subtest: CommentThreadService persists caches safely during teardown failures -ok 4 - CommentThreadService persists caches safely during teardown failures - --- - duration_ms: 1.896511 - type: 'test' - ... -# Subtest: CommentThreadService logs cache usage and fallback decisions -ok 5 - CommentThreadService logs cache usage and fallback decisions - --- - duration_ms: 1.426893 - 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.482674 - type: 'test' - ... -# Subtest: CommentThreadService normalizes mixed-case pubkeys during hydration -ok 7 - CommentThreadService normalizes mixed-case pubkeys during hydration - --- - duration_ms: 1.26822 - type: 'test' - ... -# Subtest: CommentThreadService deduplicates mixed-case event ids and pubkeys -ok 8 - CommentThreadService deduplicates mixed-case event ids and pubkeys - --- - duration_ms: 1.158473 - 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: 77.501448 - 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.319632 - 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.593448 - 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.214518 - 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.181554 - type: 'test' - ... -# Subtest: CommentThreadService requests and snapshots comments by root identifier -ok 14 - CommentThreadService requests and snapshots comments by root identifier - --- - duration_ms: 1.087917 - type: 'test' - ... -# Subtest: CommentThreadService falls back to pointerIdentifiers root id -ok 15 - CommentThreadService falls back to pointerIdentifiers root id - --- - duration_ms: 0.741488 - 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: 6.258213 - type: 'test' - ... -# Subtest: CommentThreadService teardown cancels hydration timers -ok 17 - CommentThreadService teardown cancels hydration timers - --- - duration_ms: 80.86304 - type: 'test' - ... -1..17 -# tests 17 -# suites 0 -# pass 17 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 434.051498 - -→ 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: 146.293963 - type: 'test' - ... -1..1 -# tests 1 -# suites 0 -# pass 1 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 161.992063 - -→ 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: 73.003385 - 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: 18.283135 - type: 'test' - ... -# Subtest: decryptDM unwraps kind 1059 gift wraps with nip44 -ok 3 - decryptDM unwraps kind 1059 gift wraps with nip44 - --- - duration_ms: 60.105189 - type: 'test' - ... -# Subtest: decryptDM returns failure when decryptors are unavailable -ok 4 - decryptDM returns failure when decryptors are unavailable - --- - duration_ms: 0.382312 - type: 'test' - ... -1..4 -# tests 4 -# suites 0 -# pass 4 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 164.999578 - -→ 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: 266.78321 - 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: 107.787782 - 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: 83.991975 - type: 'test' - ... -1..3 -# tests 3 -# suites 0 -# pass 3 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 472.427029 - -→ 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.754511 - type: 'test' - ... -# Subtest: tag preference stage accepts interests from nip71 hashtags -ok 2 - tag preference stage accepts interests from nip71 hashtags - --- - duration_ms: 0.444436 - type: 'test' - ... -1..2 -# tests 2 -# suites 0 -# pass 2 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 13.857379 - -→ 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.403426 - type: 'test' - ... -# Subtest: load falls back to nip04 decryption -ok 2 - load falls back to nip04 decryption - --- - duration_ms: 1.250005 - type: 'test' - ... -# Subtest: load retries decryptors when hinted scheme fails -ok 3 - load retries decryptors when hinted scheme fails - --- - duration_ms: 1.544729 - type: 'test' - ... -# Subtest: interest and disinterest lists remain exclusive -ok 4 - interest and disinterest lists remain exclusive - --- - duration_ms: 0.67708 - type: 'test' - ... -# Subtest: publish encrypts payload and builds event via builder -ok 5 - publish encrypts payload and builds event via builder - --- - duration_ms: 8.610979 - type: 'test' - ... -# Subtest: publish falls back to window nostr encryptors -ok 6 - publish falls back to window nostr encryptors - --- - duration_ms: 2.455851 - 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.569546 - type: 'test' - ... -1..7 -# tests 7 -# suites 0 -# pass 7 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 44.547963 - -→ Running tests/magnet-utils.test.mjs -TAP version 13 -# Subtest: safeDecodeMagnet handles encoded values -ok 1 - safeDecodeMagnet handles encoded values - --- - duration_ms: 1.499096 - type: 'test' - ... -# Subtest: safeDecodeMagnet leaves plain strings untouched -ok 2 - safeDecodeMagnet leaves plain strings untouched - --- - duration_ms: 0.270485 - type: 'test' - ... -# Subtest: bare hashes normalize consistently across helpers -ok 3 - bare hashes normalize consistently across helpers - --- - duration_ms: 3.303802 - type: 'test' - ... -# Subtest: legacy %3A payloads decode across helpers -ok 4 - legacy %3A payloads decode across helpers - --- - duration_ms: 0.587992 - type: 'test' - ... -# Subtest: duplicate trackers and hints stay in sync -ok 5 - duplicate trackers and hints stay in sync - --- - duration_ms: 1.194348 - 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.541729 - type: 'test' - ... -# Subtest: object helper allows HTTP seeds on HTTP origins -ok 7 - object helper allows HTTP seeds on HTTP origins - --- - duration_ms: 0.318126 - type: 'test' - ... -# Subtest: extractMagnetHints returns first ws/xs pair -ok 8 - extractMagnetHints returns first ws/xs pair - --- - duration_ms: 0.409157 - 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.865413 - type: 'test' - ... -# Subtest: object helper reports didChange when output differs -ok 10 - object helper reports didChange when output differs - --- - duration_ms: 0.74896 - type: 'test' - ... -# Subtest: helpers trim fragments from non-magnet values -ok 11 - helpers trim fragments from non-magnet values - --- - duration_ms: 0.283338 - type: 'test' - ... -1..11 -# tests 11 -# suites 0 -# pass 11 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 29.76196 - -→ 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: 83.853192 - type: 'test' - ... -# Subtest: MediaLoader loads video sources and poster fallbacks -ok 2 - MediaLoader loads video sources and poster fallbacks - --- - duration_ms: 23.340945 - type: 'test' - ... -# Subtest: MediaLoader clears unsupported lazy targets without inline styles -ok 3 - MediaLoader clears unsupported lazy targets without inline styles - --- - duration_ms: 10.753205 - type: 'test' - ... -1..3 -# tests 3 -# suites 0 -# pass 3 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 131.319846 - -→ 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: 241.185669 - type: 'test' - ... -# Subtest: UploadModal backdrop click closes and restores trigger focus -ok 2 - UploadModal backdrop click closes and restores trigger focus - --- - duration_ms: 83.8338 - type: 'test' - ... -# Subtest: UploadModal mode toggle updates button states -ok 3 - UploadModal mode toggle updates button states - --- - duration_ms: 61.389447 - type: 'test' - ... -# Subtest: EditModal Escape closes and restores trigger focus -ok 4 - EditModal Escape closes and restores trigger focus - --- - duration_ms: 97.270416 - type: 'test' - ... -# Subtest: EditModal backdrop click closes and restores trigger focus -ok 5 - EditModal backdrop click closes and restores trigger focus - --- - duration_ms: 81.214373 - type: 'test' - ... -# Subtest: EditModal visibility toggle updates button state -ok 6 - EditModal visibility toggle updates button state - --- - duration_ms: 72.668177 - type: 'test' - ... -# Subtest: RevertModal Escape closes and restores trigger focus -ok 7 - RevertModal Escape closes and restores trigger focus - --- - duration_ms: 57.157734 - type: 'test' - ... -# Subtest: static modal helper toggles accessibility hooks -ok 8 - static modal helper toggles accessibility hooks - --- - duration_ms: 12.423016 - type: 'test' - ... -1..8 -# tests 8 -# suites 0 -# pass 8 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 716.147671 - -→ 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: 5.136779 - type: 'test' - ... -# Subtest: user block updates recompute summaries and emit notifications -ok 2 - user block updates recompute summaries and emit notifications - --- - duration_ms: 4.31839 - type: 'test' - ... -# Subtest: moderation thresholds emit logger hooks only when crossing -ok 3 - moderation thresholds emit logger hooks only when crossing - --- - duration_ms: 1.617488 - type: 'test' - ... -# Subtest: trusted mute aggregation tracks F1 mute lists -ok 4 - trusted mute aggregation tracks F1 mute lists - --- - duration_ms: 1.869098 - type: 'test' - ... -# Subtest: viewer mute list publishes and updates aggregation -ok 5 - viewer mute list publishes and updates aggregation - --- - duration_ms: 4.351462 - type: 'test' - ... -1..5 -# tests 5 -# suites 0 -# pass 5 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 31.242407 - -→ 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.472572 - type: 'test' - ... -# Subtest: moderation stage annotates trusted mute metadata -ok 2 - moderation stage annotates trusted mute metadata - --- - duration_ms: 1.412272 - type: 'test' - ... -# Subtest: moderation stage applies provided thresholds -ok 3 - moderation stage applies provided thresholds - --- - duration_ms: 1.49677 - type: 'test' - ... -# Subtest: moderation stage respects runtime threshold changes -ok 4 - moderation stage respects runtime threshold changes - --- - duration_ms: 1.667688 - type: 'test' - ... -# Subtest: moderation stage supports function-based threshold resolvers -ok 5 - moderation stage supports function-based threshold resolvers - --- - duration_ms: 1.15711 - type: 'test' - ... -# Subtest: moderation stage propagates whitelist, muters, and threshold updates -ok 6 - moderation stage propagates whitelist, muters, and threshold updates - --- - duration_ms: 1.818141 - type: 'test' - ... -# Subtest: moderation stage blurs viewer-muted authors -ok 7 - moderation stage blurs viewer-muted authors - --- - duration_ms: 0.777393 - 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.162641 - type: 'test' - ... -1..8 -# tests 8 -# suites 0 -# pass 8 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 29.810449 - -→ 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.000103 - 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.059393 - type: 'test' - ... -# Subtest: moderation stage respects runtime hide threshold changes -ok 3 - moderation stage respects runtime hide threshold changes - --- - duration_ms: 1.453776 - type: 'test' - ... -# Subtest: moderation stage supports trusted mute hide resolver functions -ok 4 - moderation stage supports trusted mute hide resolver functions - --- - duration_ms: 1.673764 - type: 'test' - ... -# Subtest: moderation stage bypasses hard hides on home feed -ok 5 - moderation stage bypasses hard hides on home feed - --- - duration_ms: 1.304653 - 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: 1.067946 - type: 'test' - ... -1..6 -# tests 6 -# suites 0 -# pass 6 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 25.239371 - -→ 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: 11.293163 - type: 'test' - ... -1..1 -# tests 1 -# suites 0 -# pass 1 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 19.169334 - -→ 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.525753 - type: 'test' - ... -# Subtest: trusted seeds contribute to trusted mute counts -ok 2 - trusted seeds contribute to trusted mute counts - --- - duration_ms: 4.961509 - type: 'test' - ... -# Subtest: trusted seeds contribute to trusted report counts -ok 3 - trusted seeds contribute to trusted report counts - --- - duration_ms: 3.041467 - type: 'test' - ... -# Subtest: trusted seed updates recompute guest report summaries -ok 4 - trusted seed updates recompute guest report summaries - --- - duration_ms: 1.395334 - type: 'test' - ... -# Subtest: moderator seeds populate trusted contacts -ok 5 - moderator seeds populate trusted contacts - --- - duration_ms: 0.961815 - 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: 87.400034 - type: 'test' - ... -1..6 -# tests 6 -# suites 0 -# pass 6 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 3609.738811 - -→ 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.641151 - type: 'test' - ... -1..1 -# tests 1 -# suites 0 -# pass 1 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 22.66779 - -→ 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.900588 - type: 'test' - ... -# Subtest: trustedReportCount ignores reports from muted or blocked reporters -ok 2 - trustedReportCount ignores reports from muted or blocked reporters - --- - duration_ms: 2.910961 - type: 'test' - ... -# Subtest: blocking and unblocking reporters recomputes trusted summaries -ok 3 - blocking and unblocking reporters recomputes trusted summaries - --- - duration_ms: 3.648077 - 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.56259 - type: 'test' - ... -1..4 -# tests 4 -# suites 0 -# pass 4 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 29.648246 - -→ 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: 329.036268 - 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.040999 - type: 'test' - ... -# Subtest: VideoCard blurs viewer-muted creators -ok 3 - VideoCard blurs viewer-muted creators - --- - duration_ms: 18.340051 - 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: 17.192959 - 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: 29.059796 - type: 'test' - ... -# Subtest: applyModerationContextDatasets clears blur when overrides are active -ok 6 - applyModerationContextDatasets clears blur when overrides are active - --- - duration_ms: 8.641352 - 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.28807 - type: 'test' - ... -1..7 -# tests 7 -# suites 0 -# pass 7 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 449.805331 - -→ 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.352528 - type: 'test' - ... -# Subtest: blacklist-author requires moderator access and refreshes subscriptions -ok 2 - blacklist-author requires moderator access and refreshes subscriptions - --- - duration_ms: 0.694916 - 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.324585 - 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.723132 - 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.796094 - type: 'test' - ... -# Subtest: unmute-author removes creators from viewer mute list -ok 6 - unmute-author removes creators from viewer mute list - --- - duration_ms: 0.658273 - type: 'test' - ... -1..6 -# tests 6 -# suites 0 -# pass 6 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 19.973263 - -→ 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.767242 - type: 'test' - ... -# Subtest: imeta tags lower-case mime values -ok 2 - imeta tags lower-case mime values - --- - duration_ms: 0.620549 - type: 'test' - ... -1..2 -# tests 2 -# suites 0 -# pass 2 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 18.672745 - -→ 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: 5.511834 - type: 'test' - ... -# Subtest: buildNip71VideoEvent falls back to summary and selects kind -ok 2 - buildNip71VideoEvent falls back to summary and selects kind - --- - duration_ms: 0.404613 - type: 'test' - ... -# Subtest: buildNip71VideoEvent attaches pointer tags -ok 3 - buildNip71VideoEvent attaches pointer tags - --- - duration_ms: 0.596327 - type: 'test' - ... -# Subtest: extractNip71MetadataFromTags parses metadata and pointers -ok 4 - extractNip71MetadataFromTags parses metadata and pointers - --- - duration_ms: 1.356091 - type: 'test' - ... -1..4 -# tests 4 -# suites 0 -# pass 4 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 21.66105 - -→ 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: 103.866471 - type: 'test' - ... -# Subtest: hydrateSection renders sanitized hashtags with prefix -ok 2 - hydrateSection renders sanitized hashtags with prefix - --- - duration_ms: 22.040454 - type: 'test' - ... -1..2 -# tests 2 -# suites 0 -# pass 2 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 138.250466 - -→ 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: 8.958341 - type: 'test' - ... -# Subtest: NIP-07 decrypt reuses cached extension permissions -ok 2 - NIP-07 decrypt reuses cached extension permissions - --- - duration_ms: 2.74935 - 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.865024 - 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.399392 - 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.359752 - type: 'test' - ... -# Subtest: NIP-07 login surfaces enable permission errors -ok 6 - NIP-07 login surfaces enable permission errors - --- - duration_ms: 2.871493 - type: 'test' - ... -# Subtest: runNip07WithRetry respects timeout without retry multiplier -ok 7 - runNip07WithRetry respects timeout without retry multiplier - --- - duration_ms: 61.183634 - type: 'test' - ... -1..7 -# tests 7 -# suites 0 -# pass 7 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 172.793518 - -→ 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: 213.347804 - type: 'test' - ... -1..1 -# tests 1 -# suites 0 -# pass 1 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 236.30689 - -→ 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: 224.825469 - type: 'test' - ... -1..1 -# tests 1 -# suites 0 -# pass 1 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 246.791889 - -→ 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.95596 - type: 'test' - ... -# Subtest: shouldIncludeVideo rejects blacklisted authors provided as npub -ok 2 - shouldIncludeVideo rejects blacklisted authors provided as npub - --- - duration_ms: 0.455841 - 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.482175 - 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: 5.13633 - 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: 49.238852 - 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) diff --git a/test_output_2.log b/test_output_2.log deleted file mode 100644 index 7bde404c..00000000 --- a/test_output_2.log +++ /dev/null @@ -1,2283 +0,0 @@ - -> bitvid@1.0.0 test:unit -> node scripts/run-unit-tests.mjs - - -→ Running tests/app-batch-fetch-profiles.test.mjs -[bitvid] Initialized nostr nip04 helpers. -[bitvid] Initialized nostr nip44 helpers. -[batchFetchProfiles] Failed to fetch profiles from relay wss://fail.example: Error: relay timed out - at Object.list (file:///app/tests/app-batch-fetch-profiles.test.mjs:80:31) - at file:///app/js/utils/profileBatchFetcher.js:115:10 - at Array.map () - at batchFetchProfilesFromRelays (file:///app/js/utils/profileBatchFetcher.js:112:75) - at TestContext. (file:///app/tests/app-batch-fetch-profiles.test.mjs:87:11) - at Test.runInAsyncScope (node:async_hooks:214:14) - at Test.run (node:internal/test_runner/test:1047:25) - at Test.start (node:internal/test_runner/test:944:17) - at startSubtestAfterBootstrap (node:internal/test_runner/harness:296:17) -TAP version 13 -# Subtest: batchFetchProfiles handles fast and failing relays -ok 1 - batchFetchProfiles handles fast and failing relays - --- - duration_ms: 3.951918 - type: 'test' - ... -1..1 -# tests 1 -# suites 0 -# pass 1 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 15.780109 - -→ 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: 235.250894 - type: 'test' - ... -# Subtest: renderChannelVideosFromList applies moderation blur without existing metadata -ok 2 - renderChannelVideosFromList applies moderation blur without existing metadata - --- - duration_ms: 35.089875 - 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.70126 - type: 'test' - ... -# Subtest: moderation override clears channel blur via event wiring -ok 4 - moderation override clears channel blur via event wiring - --- - duration_ms: 37.096643 - 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: 33.232907 - 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: 22.396668 - type: 'test' - ... -1..6 -# tests 6 -# suites 0 -# pass 6 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 386.655131 - -→ 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.801774 - 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.494088 - type: 'test' - ... -# Subtest: handleHashChange respects explicit view regardless of login state -ok 3 - handleHashChange respects explicit view regardless of login state - --- - duration_ms: 10.070045 - type: 'test' - ... -1..3 -# tests 3 -# suites 0 -# pass 3 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 112.392492 - -→ 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: 90.214045 - type: 'test' - ... -# Subtest: hydrateSidebarNavigation hides chrome controls for logged-out viewers -ok 2 - hydrateSidebarNavigation hides chrome controls for logged-out viewers - --- - duration_ms: 14.210417 - type: 'test' - ... -1..2 -# tests 2 -# suites 0 -# pass 2 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 116.64085 - -→ 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.332334 - type: 'test' - ... -# Subtest: isUserLoggedIn treats extension logins as authenticated -ok 2 - isUserLoggedIn treats extension logins as authenticated - --- - duration_ms: 0.367174 - type: 'test' - ... -# Subtest: isUserLoggedIn guards against mismatched nostrClient state -ok 3 - isUserLoggedIn guards against mismatched nostrClient state - --- - duration_ms: 0.27112 - type: 'test' - ... -# Subtest: isUserLoggedIn ignores anonymous session actor mismatches -ok 4 - isUserLoggedIn ignores anonymous session actor mismatches - --- - duration_ms: 0.24882 - type: 'test' - ... -# Subtest: isUserLoggedIn rejects mismatched managed session actors -ok 5 - isUserLoggedIn rejects mismatched managed session actors - --- - duration_ms: 0.410749 - type: 'test' - ... -1..5 -# tests 5 -# suites 0 -# pass 5 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 30.339495 - -→ 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: 206.84042 - type: 'test' - ... -# Subtest: handleModerationOverride resumes deferred playback -ok 2 - handleModerationOverride resumes deferred playback - --- - duration_ms: 1.281286 - 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: 3.901754 - type: 'test' - ... -# Subtest: handleModerationBlock returns false when viewer is logged out -ok 4 - handleModerationBlock returns false when viewer is logged out - --- - duration_ms: 1.537005 - type: 'test' - ... -1..4 -# tests 4 -# suites 0 -# pass 4 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 243.156495 - -→ 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: 228.305239 - type: 'test' - ... -1..1 -# tests 1 -# suites 0 -# pass 1 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 260.71303 - -→ 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: 5.487142 - 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.423977 - type: 'test' - ... -# Subtest: skips candidates without tag metadata -ok 3 - skips candidates without tag metadata - --- - duration_ms: 0.441076 - 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.592795 - type: 'test' - ... -1..4 -# tests 4 -# suites 0 -# pass 4 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 36.044094 - -→ 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.104537 - 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.528982 - type: 'test' - ... -# Subtest: buildCommentEvent normalizes relays and preserves explicit overrides -ok 3 - buildCommentEvent normalizes relays and preserves explicit overrides - --- - duration_ms: 0.993098 - 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.297693 - type: 'test' - ... -# Subtest: buildCommentEvent accepts partial metadata for parent overrides -ok 5 - buildCommentEvent accepts partial metadata for parent overrides - --- - duration_ms: 0.447865 - type: 'test' - ... -# Subtest: buildCommentEvent sanitizes additional tags before signing -ok 6 - buildCommentEvent sanitizes additional tags before signing - --- - duration_ms: 0.894764 - type: 'test' - ... -1..6 -# tests 6 -# suites 0 -# pass 6 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 20.531041 - -→ 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.933777 - type: 'test' - ... -# Subtest: CommentThreadService surfaces cache read failures -ok 2 - CommentThreadService surfaces cache read failures - --- - duration_ms: 0.831116 - type: 'test' - ... -# Subtest: CommentThreadService surfaces cache write failures -ok 3 - CommentThreadService surfaces cache write failures - --- - duration_ms: 0.532641 - type: 'test' - ... -# Subtest: CommentThreadService persists caches safely during teardown failures -ok 4 - CommentThreadService persists caches safely during teardown failures - --- - duration_ms: 1.928927 - type: 'test' - ... -# Subtest: CommentThreadService logs cache usage and fallback decisions -ok 5 - CommentThreadService logs cache usage and fallback decisions - --- - duration_ms: 1.323553 - 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.49746 - type: 'test' - ... -# Subtest: CommentThreadService normalizes mixed-case pubkeys during hydration -ok 7 - CommentThreadService normalizes mixed-case pubkeys during hydration - --- - duration_ms: 1.140252 - type: 'test' - ... -# Subtest: CommentThreadService deduplicates mixed-case event ids and pubkeys -ok 8 - CommentThreadService deduplicates mixed-case event ids and pubkeys - --- - duration_ms: 1.091031 - 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: 77.367641 - 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.376938 - 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.425376 - 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.140487 - 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.062026 - type: 'test' - ... -# Subtest: CommentThreadService requests and snapshots comments by root identifier -ok 14 - CommentThreadService requests and snapshots comments by root identifier - --- - duration_ms: 1.067756 - type: 'test' - ... -# Subtest: CommentThreadService falls back to pointerIdentifiers root id -ok 15 - CommentThreadService falls back to pointerIdentifiers root id - --- - duration_ms: 0.763797 - 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.385664 - type: 'test' - ... -# Subtest: CommentThreadService teardown cancels hydration timers -ok 17 - CommentThreadService teardown cancels hydration timers - --- - duration_ms: 81.497501 - type: 'test' - ... -1..17 -# tests 17 -# suites 0 -# pass 17 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 432.59068 - -→ 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: 139.398911 - type: 'test' - ... -1..1 -# tests 1 -# suites 0 -# pass 1 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 150.264845 - -→ 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: 72.295197 - 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.831318 - type: 'test' - ... -# Subtest: decryptDM unwraps kind 1059 gift wraps with nip44 -ok 3 - decryptDM unwraps kind 1059 gift wraps with nip44 - --- - duration_ms: 57.638741 - type: 'test' - ... -# Subtest: decryptDM returns failure when decryptors are unavailable -ok 4 - decryptDM returns failure when decryptors are unavailable - --- - duration_ms: 0.323647 - type: 'test' - ... -1..4 -# tests 4 -# suites 0 -# pass 4 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 159.925109 - -→ 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: 267.689298 - 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: 107.212911 - 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.29678 - type: 'test' - ... -1..3 -# tests 3 -# suites 0 -# pass 3 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 474.328316 - -→ 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.480596 - type: 'test' - ... -# Subtest: tag preference stage accepts interests from nip71 hashtags -ok 2 - tag preference stage accepts interests from nip71 hashtags - --- - duration_ms: 0.410859 - type: 'test' - ... -1..2 -# tests 2 -# suites 0 -# pass 2 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 13.697422 - -→ 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.422102 - type: 'test' - ... -# Subtest: load falls back to nip04 decryption -ok 2 - load falls back to nip04 decryption - --- - duration_ms: 1.385346 - type: 'test' - ... -# Subtest: load retries decryptors when hinted scheme fails -ok 3 - load retries decryptors when hinted scheme fails - --- - duration_ms: 1.577638 - type: 'test' - ... -# Subtest: interest and disinterest lists remain exclusive -ok 4 - interest and disinterest lists remain exclusive - --- - duration_ms: 0.676935 - type: 'test' - ... -# Subtest: publish encrypts payload and builds event via builder -ok 5 - publish encrypts payload and builds event via builder - --- - duration_ms: 8.669487 - type: 'test' - ... -# Subtest: publish falls back to window nostr encryptors -ok 6 - publish falls back to window nostr encryptors - --- - duration_ms: 2.457867 - 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.553075 - type: 'test' - ... -1..7 -# tests 7 -# suites 0 -# pass 7 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 45.729471 - -→ Running tests/magnet-utils.test.mjs -TAP version 13 -# Subtest: safeDecodeMagnet handles encoded values -ok 1 - safeDecodeMagnet handles encoded values - --- - duration_ms: 1.609313 - type: 'test' - ... -# Subtest: safeDecodeMagnet leaves plain strings untouched -ok 2 - safeDecodeMagnet leaves plain strings untouched - --- - duration_ms: 0.282348 - type: 'test' - ... -# Subtest: bare hashes normalize consistently across helpers -ok 3 - bare hashes normalize consistently across helpers - --- - duration_ms: 3.796459 - type: 'test' - ... -# Subtest: legacy %3A payloads decode across helpers -ok 4 - legacy %3A payloads decode across helpers - --- - duration_ms: 0.613367 - type: 'test' - ... -# Subtest: duplicate trackers and hints stay in sync -ok 5 - duplicate trackers and hints stay in sync - --- - duration_ms: 1.216889 - 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.652082 - type: 'test' - ... -# Subtest: object helper allows HTTP seeds on HTTP origins -ok 7 - object helper allows HTTP seeds on HTTP origins - --- - duration_ms: 0.421209 - type: 'test' - ... -# Subtest: extractMagnetHints returns first ws/xs pair -ok 8 - extractMagnetHints returns first ws/xs pair - --- - duration_ms: 0.414267 - 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.867344 - type: 'test' - ... -# Subtest: object helper reports didChange when output differs -ok 10 - object helper reports didChange when output differs - --- - duration_ms: 0.768602 - type: 'test' - ... -# Subtest: helpers trim fragments from non-magnet values -ok 11 - helpers trim fragments from non-magnet values - --- - duration_ms: 0.317559 - type: 'test' - ... -1..11 -# tests 11 -# suites 0 -# pass 11 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 31.9769 - -→ 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: 81.726329 - type: 'test' - ... -# Subtest: MediaLoader loads video sources and poster fallbacks -ok 2 - MediaLoader loads video sources and poster fallbacks - --- - duration_ms: 22.682034 - type: 'test' - ... -# Subtest: MediaLoader clears unsupported lazy targets without inline styles -ok 3 - MediaLoader clears unsupported lazy targets without inline styles - --- - duration_ms: 10.849001 - type: 'test' - ... -1..3 -# tests 3 -# suites 0 -# pass 3 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 128.204579 - -→ 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: 233.801182 - type: 'test' - ... -# Subtest: UploadModal backdrop click closes and restores trigger focus -ok 2 - UploadModal backdrop click closes and restores trigger focus - --- - duration_ms: 80.917943 - type: 'test' - ... -# Subtest: UploadModal mode toggle updates button states -ok 3 - UploadModal mode toggle updates button states - --- - duration_ms: 63.028207 - type: 'test' - ... -# Subtest: EditModal Escape closes and restores trigger focus -ok 4 - EditModal Escape closes and restores trigger focus - --- - duration_ms: 103.844176 - type: 'test' - ... -# Subtest: EditModal backdrop click closes and restores trigger focus -ok 5 - EditModal backdrop click closes and restores trigger focus - --- - duration_ms: 82.193753 - type: 'test' - ... -# Subtest: EditModal visibility toggle updates button state -ok 6 - EditModal visibility toggle updates button state - --- - duration_ms: 71.274165 - type: 'test' - ... -# Subtest: RevertModal Escape closes and restores trigger focus -ok 7 - RevertModal Escape closes and restores trigger focus - --- - duration_ms: 54.603962 - type: 'test' - ... -# Subtest: static modal helper toggles accessibility hooks -ok 8 - static modal helper toggles accessibility hooks - --- - duration_ms: 13.310668 - type: 'test' - ... -1..8 -# tests 8 -# suites 0 -# pass 8 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 715.120434 - -→ 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: 4.925643 - type: 'test' - ... -# Subtest: user block updates recompute summaries and emit notifications -ok 2 - user block updates recompute summaries and emit notifications - --- - duration_ms: 4.205645 - type: 'test' - ... -# Subtest: moderation thresholds emit logger hooks only when crossing -ok 3 - moderation thresholds emit logger hooks only when crossing - --- - duration_ms: 1.584069 - type: 'test' - ... -# Subtest: trusted mute aggregation tracks F1 mute lists -ok 4 - trusted mute aggregation tracks F1 mute lists - --- - duration_ms: 1.704481 - type: 'test' - ... -# Subtest: viewer mute list publishes and updates aggregation -ok 5 - viewer mute list publishes and updates aggregation - --- - duration_ms: 4.067495 - type: 'test' - ... -1..5 -# tests 5 -# suites 0 -# pass 5 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 29.799291 - -→ 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.360424 - type: 'test' - ... -# Subtest: moderation stage annotates trusted mute metadata -ok 2 - moderation stage annotates trusted mute metadata - --- - duration_ms: 1.204999 - type: 'test' - ... -# Subtest: moderation stage applies provided thresholds -ok 3 - moderation stage applies provided thresholds - --- - duration_ms: 1.49787 - type: 'test' - ... -# Subtest: moderation stage respects runtime threshold changes -ok 4 - moderation stage respects runtime threshold changes - --- - duration_ms: 1.564344 - type: 'test' - ... -# Subtest: moderation stage supports function-based threshold resolvers -ok 5 - moderation stage supports function-based threshold resolvers - --- - duration_ms: 1.243856 - type: 'test' - ... -# Subtest: moderation stage propagates whitelist, muters, and threshold updates -ok 6 - moderation stage propagates whitelist, muters, and threshold updates - --- - duration_ms: 1.736849 - type: 'test' - ... -# Subtest: moderation stage blurs viewer-muted authors -ok 7 - moderation stage blurs viewer-muted authors - --- - duration_ms: 0.766481 - 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.144956 - type: 'test' - ... -1..8 -# tests 8 -# suites 0 -# pass 8 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 29.108905 - -→ 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.088284 - 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: 0.979496 - type: 'test' - ... -# Subtest: moderation stage respects runtime hide threshold changes -ok 3 - moderation stage respects runtime hide threshold changes - --- - duration_ms: 1.30707 - type: 'test' - ... -# Subtest: moderation stage supports trusted mute hide resolver functions -ok 4 - moderation stage supports trusted mute hide resolver functions - --- - duration_ms: 1.523941 - type: 'test' - ... -# Subtest: moderation stage bypasses hard hides on home feed -ok 5 - moderation stage bypasses hard hides on home feed - --- - duration_ms: 1.244957 - 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.879699 - type: 'test' - ... -1..6 -# tests 6 -# suites 0 -# pass 6 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 24.126063 - -→ 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: 8.765812 - type: 'test' - ... -1..1 -# tests 1 -# suites 0 -# pass 1 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 16.699107 - -→ 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.220024 - type: 'test' - ... -# Subtest: trusted seeds contribute to trusted mute counts -ok 2 - trusted seeds contribute to trusted mute counts - --- - duration_ms: 4.71981 - type: 'test' - ... -# Subtest: trusted seeds contribute to trusted report counts -ok 3 - trusted seeds contribute to trusted report counts - --- - duration_ms: 2.905957 - type: 'test' - ... -# Subtest: trusted seed updates recompute guest report summaries -ok 4 - trusted seed updates recompute guest report summaries - --- - duration_ms: 1.454472 - type: 'test' - ... -# Subtest: moderator seeds populate trusted contacts -ok 5 - moderator seeds populate trusted contacts - --- - duration_ms: 0.990639 - 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: 83.776059 - type: 'test' - ... -1..6 -# tests 6 -# suites 0 -# pass 6 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 3604.451748 - -→ 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.907941 - type: 'test' - ... -1..1 -# tests 1 -# suites 0 -# pass 1 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 23.034046 - -→ 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.950726 - type: 'test' - ... -# Subtest: trustedReportCount ignores reports from muted or blocked reporters -ok 2 - trustedReportCount ignores reports from muted or blocked reporters - --- - duration_ms: 2.480359 - type: 'test' - ... -# Subtest: blocking and unblocking reporters recomputes trusted summaries -ok 3 - blocking and unblocking reporters recomputes trusted summaries - --- - duration_ms: 2.895828 - 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.271767 - type: 'test' - ... -1..4 -# tests 4 -# suites 0 -# pass 4 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 26.863456 - -→ 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: 325.224556 - 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: 36.652683 - type: 'test' - ... -# Subtest: VideoCard blurs viewer-muted creators -ok 3 - VideoCard blurs viewer-muted creators - --- - duration_ms: 17.308476 - 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.834475 - 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: 29.140064 - type: 'test' - ... -# Subtest: applyModerationContextDatasets clears blur when overrides are active -ok 6 - applyModerationContextDatasets clears blur when overrides are active - --- - duration_ms: 8.486614 - 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.20802 - type: 'test' - ... -1..7 -# tests 7 -# suites 0 -# pass 7 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 442.41748 - -→ 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.180901 - type: 'test' - ... -# Subtest: blacklist-author requires moderator access and refreshes subscriptions -ok 2 - blacklist-author requires moderator access and refreshes subscriptions - --- - duration_ms: 0.626384 - 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.329829 - 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.760243 - 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.612503 - type: 'test' - ... -# Subtest: unmute-author removes creators from viewer mute list -ok 6 - unmute-author removes creators from viewer mute list - --- - duration_ms: 0.565561 - type: 'test' - ... -1..6 -# tests 6 -# suites 0 -# pass 6 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 19.149113 - -→ 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: 7.626422 - type: 'test' - ... -# Subtest: imeta tags lower-case mime values -ok 2 - imeta tags lower-case mime values - --- - duration_ms: 0.557257 - type: 'test' - ... -1..2 -# tests 2 -# suites 0 -# pass 2 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 19.425838 - -→ 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: 4.167966 - type: 'test' - ... -# Subtest: buildNip71VideoEvent falls back to summary and selects kind -ok 2 - buildNip71VideoEvent falls back to summary and selects kind - --- - duration_ms: 0.45331 - type: 'test' - ... -# Subtest: buildNip71VideoEvent attaches pointer tags -ok 3 - buildNip71VideoEvent attaches pointer tags - --- - duration_ms: 0.49872 - type: 'test' - ... -# Subtest: extractNip71MetadataFromTags parses metadata and pointers -ok 4 - extractNip71MetadataFromTags parses metadata and pointers - --- - duration_ms: 3.010408 - type: 'test' - ... -1..4 -# tests 4 -# suites 0 -# pass 4 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 22.058195 - -→ 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: 104.317193 - type: 'test' - ... -# Subtest: hydrateSection renders sanitized hashtags with prefix -ok 2 - hydrateSection renders sanitized hashtags with prefix - --- - duration_ms: 21.67468 - type: 'test' - ... -1..2 -# tests 2 -# suites 0 -# pass 2 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 138.388304 - -→ 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: 7.507317 - type: 'test' - ... -# Subtest: NIP-07 decrypt reuses cached extension permissions -ok 2 - NIP-07 decrypt reuses cached extension permissions - --- - duration_ms: 2.913123 - 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.826926 - 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.393743 - 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.426611 - type: 'test' - ... -# Subtest: NIP-07 login surfaces enable permission errors -ok 6 - NIP-07 login surfaces enable permission errors - --- - duration_ms: 2.978705 - type: 'test' - ... -# Subtest: runNip07WithRetry respects timeout without retry multiplier -ok 7 - runNip07WithRetry respects timeout without retry multiplier - --- - duration_ms: 61.293887 - type: 'test' - ... -1..7 -# tests 7 -# suites 0 -# pass 7 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 172.692684 - -→ 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: 215.641844 - type: 'test' - ... -1..1 -# tests 1 -# suites 0 -# pass 1 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 239.319305 - -→ 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: 214.554605 - type: 'test' - ... -1..1 -# tests 1 -# suites 0 -# pass 1 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 236.740125 - -→ 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.912078 - type: 'test' - ... -# Subtest: shouldIncludeVideo rejects blacklisted authors provided as npub -ok 2 - shouldIncludeVideo rejects blacklisted authors provided as npub - --- - duration_ms: 0.36329 - 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.466305 - 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.946118 - 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: 55.162154 - 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) -1..5 -# tests 5 -# suites 0 -# pass 5 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 74613.335323 - -→ Running tests/nostr/adapters.test.mjs -[bitvid] Initialized nostr nip04 helpers. -[bitvid] Initialized nostr nip44 helpers. -TAP version 13 -# Subtest: createNsecAdapter wires signing and cipher capabilities -ok 1 - createNsecAdapter wires signing and cipher capabilities - --- - duration_ms: 150.290933 - type: 'test' - ... -# Subtest: createNip07Adapter maps extension methods and permissions -ok 2 - createNip07Adapter maps extension methods and permissions - --- - duration_ms: 3.006499 - type: 'test' - ... -# Subtest: createNip46Adapter wraps the remote signer client -ok 3 - createNip46Adapter wraps the remote signer client - --- - duration_ms: 0.958011 - type: 'test' - ... -1..3 -# tests 3 -# suites 0 -# pass 3 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 175.387843 - -→ Running tests/nostr/cachePolicies.test.mjs -[bitvid] Initialized nostr nip04 helpers. -[bitvid] Initialized nostr nip44 helpers. -TAP version 13 -# Subtest: CACHE_POLICIES structure -ok 1 - CACHE_POLICIES structure - --- - duration_ms: 2.125347 - type: 'test' - ... -# Subtest: VIDEO_POST policy -ok 2 - VIDEO_POST policy - --- - duration_ms: 0.367339 - type: 'test' - ... -# Subtest: WATCH_HISTORY policy -ok 3 - WATCH_HISTORY policy - --- - duration_ms: 0.174163 - type: 'test' - ... -# Subtest: SUBSCRIPTION_LIST policy -ok 4 - SUBSCRIPTION_LIST policy - --- - duration_ms: 0.281416 - type: 'test' - ... -# Subtest: VIDEO_COMMENT policy -ok 5 - VIDEO_COMMENT policy - --- - duration_ms: 0.431424 - type: 'test' - ... -1..5 -# tests 5 -# suites 0 -# pass 5 -# fail 0 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 23.105958 - -→ Running tests/nostr/comment-events.test.mjs -[bitvid] Initialized nostr nip04 helpers. -[bitvid] Initialized nostr nip44 helpers. -[nostr] Comments cache miss for video-1 -[nostr] Comments cache hit for video-1 -[nostr] Comments cache hit for video-1 -[nostr] Comments cache miss for video-rooted -[nostr] Comments cache miss for legacy-video -TAP version 13 -# Subtest: publishComment prefers active signer when available -not ok 1 - publishComment prefers active signer when available - --- - duration_ms: 7.754503 - type: 'test' - location: '/app/tests/nostr/comment-events.test.mjs:57:1' - failureType: 'testCodeFailure' - error: |- - publish should succeed when relay accepts the event - - false !== true - - code: 'ERR_ASSERTION' - name: 'AssertionError' - expected: true - actual: false - operator: 'strictEqual' - stack: |- - TestContext. (file:///app/tests/nostr/comment-events.test.mjs:96:10) - async Test.run (node:internal/test_runner/test:1054:7) - async startSubtestAfterBootstrap (node:internal/test_runner/harness:296:3) - ... -# Subtest: publishComment rejects when active signer is unavailable -not ok 2 - publishComment rejects when active signer is unavailable - --- - duration_ms: 2.486495 - type: 'test' - location: '/app/tests/nostr/comment-events.test.mjs:131:1' - failureType: 'testCodeFailure' - error: |- - missing signer should yield auth-required - + actual - expected - - + Error: Publishing comments is not allowed for session actors. - + at publishComment (file:///app/js/nostr/commentEvents.js:1120:19) - + at TestContext. (file:///app/tests/nostr/comment-events.test.mjs:139:24) - + at Test.runInAsyncScope (node:async_hooks:214:14) - + at Test.run (node:internal/test_runner/test:1047:25) - + at Test.processPendingSubtests (node:internal/test_runner/test:744:18) - + at Test.postRun (node:internal/test_runner/test:1173:19) - + at Test.run (node:internal/test_runner/test:1101:12) - + at async startSubtestAfterBootstrap (node:internal/test_runner/harness:296:3) { - + code: 'session-actor-publish-blocked' - + } - - 'auth-required' - - code: 'ERR_ASSERTION' - name: 'AssertionError' - expected: 'auth-required' - actual: - error: 'Publishing comments is not allowed for session actors.' - code: 'session-actor-publish-blocked' - stack: |- - publishComment (file:///app/js/nostr/commentEvents.js:1120:19) - TestContext. (file:///app/tests/nostr/comment-events.test.mjs:139:24) - Test.runInAsyncScope (node:async_hooks:214:14) - Test.run (node:internal/test_runner/test:1047:25) - Test.processPendingSubtests (node:internal/test_runner/test:744:18) - Test.postRun (node:internal/test_runner/test:1173:19) - Test.run (node:internal/test_runner/test:1101:12) - async startSubtestAfterBootstrap (node:internal/test_runner/harness:296:3) - operator: 'strictEqual' - stack: |- - TestContext. (file:///app/tests/nostr/comment-events.test.mjs:154:10) - async Test.run (node:internal/test_runner/test:1054:7) - async Test.processPendingSubtests (node:internal/test_runner/test:744:7) - ... -# Subtest: publishComment accepts legacy targets with only an event id -not ok 3 - publishComment accepts legacy targets with only an event id - --- - duration_ms: 1.286551 - type: 'test' - location: '/app/tests/nostr/comment-events.test.mjs:158:1' - failureType: 'testCodeFailure' - error: |- - publishing should succeed without a definition address - - false !== true - - code: 'ERR_ASSERTION' - name: 'AssertionError' - expected: true - actual: false - operator: 'strictEqual' - stack: |- - TestContext. (file:///app/tests/nostr/comment-events.test.mjs:185:10) - async Test.run (node:internal/test_runner/test:1054:7) - async Test.processPendingSubtests (node:internal/test_runner/test:744:7) - ... -# Subtest: publishComment derives root and parent metadata from parent comment tags -not ok 4 - publishComment derives root and parent metadata from parent comment tags - --- - duration_ms: 3.902995 - type: 'test' - location: '/app/tests/nostr/comment-events.test.mjs:203:1' - failureType: 'testCodeFailure' - error: |- - Expected values to be strictly deep-equal: - + actual - expected - - + [] - - [ - - [ - - 'A', - - '30078:videopk:root', - - 'wss://definition' - - ], - - [ - - 'K', - - '30078' - - ], - - [ - - 'P', - - 'videopk', - - 'wss://author' - - ], - - [ - - 'E', - - 'video-event', - - 'wss://root' - - ], - - [ - - 'E', - - 'parent-comment', - - 'wss://parent', - - 'parentpk' - - ], - - [ - - 'K', - - '1111' - - ], - - [ - - 'P', - - 'parentpk', - - 'wss://parent' - - ] - - ] - - code: 'ERR_ASSERTION' - name: 'AssertionError' - expected: - 0: - 0: 'A' - 1: '30078:videopk:root' - 2: 'wss://definition' - 1: - 0: 'K' - 1: '30078' - 2: - 0: 'P' - 1: 'videopk' - 2: 'wss://author' - 3: - 0: 'E' - 1: 'video-event' - 2: 'wss://root' - 4: - 0: 'E' - 1: 'parent-comment' - 2: 'wss://parent' - 3: 'parentpk' - 5: - 0: 'K' - 1: '1111' - 6: - 0: 'P' - 1: 'parentpk' - 2: 'wss://parent' - actual: - operator: 'deepStrictEqual' - stack: |- - TestContext. (file:///app/tests/nostr/comment-events.test.mjs:240:10) - async Test.run (node:internal/test_runner/test:1054:7) - async Test.processPendingSubtests (node:internal/test_runner/test:744:7) - ... -# Subtest: listVideoComments matches comments even when tag casing and whitespace differ -ok 5 - listVideoComments matches comments even when tag casing and whitespace differ - --- - duration_ms: 2.511808 - type: 'test' - ... -# Subtest: listVideoComments matches uppercase definition addresses without lowering -not ok 6 - listVideoComments matches uppercase definition addresses without lowering - --- - duration_ms: 1.510679 - type: 'test' - location: '/app/tests/nostr/comment-events.test.mjs:290:1' - failureType: 'testCodeFailure' - error: |- - matched event should be returned - + actual - expected - - + 'case-comment' - - 'uppercase-comment' - - code: 'ERR_ASSERTION' - name: 'AssertionError' - expected: 'uppercase-comment' - actual: 'case-comment' - operator: 'strictEqual' - stack: |- - TestContext. (file:///app/tests/nostr/comment-events.test.mjs:312:10) - async Test.run (node:internal/test_runner/test:1054:7) - async Test.processPendingSubtests (node:internal/test_runner/test:744:7) - ... -# Subtest: publishComment emits only uppercase video event pointer when address and parent are absent -not ok 7 - publishComment emits only uppercase video event pointer when address and parent are absent - --- - duration_ms: 0.762215 - type: 'test' - location: '/app/tests/nostr/comment-events.test.mjs:323:1' - failureType: 'testCodeFailure' - error: |- - publishing should succeed with only a video id - - false !== true - - code: 'ERR_ASSERTION' - name: 'AssertionError' - expected: true - actual: false - operator: 'strictEqual' - stack: |- - TestContext. (file:///app/tests/nostr/comment-events.test.mjs:345:10) - async Test.run (node:internal/test_runner/test:1054:7) - async Test.processPendingSubtests (node:internal/test_runner/test:744:7) - ... -# Subtest: listVideoComments builds filters with uppercase roots plus legacy fallbacks -not ok 8 - listVideoComments builds filters with uppercase roots plus legacy fallbacks - --- - duration_ms: 1.202307 - type: 'test' - location: '/app/tests/nostr/comment-events.test.mjs:359:1' - failureType: 'testCodeFailure' - error: |- - newest event should be retained - + actual - expected - - + 'case-comment' - - 'comment-2' - - code: 'ERR_ASSERTION' - name: 'AssertionError' - expected: 'comment-2' - actual: 'case-comment' - operator: 'strictEqual' - stack: |- - TestContext. (file:///app/tests/nostr/comment-events.test.mjs:416:10) - async Test.run (node:internal/test_runner/test:1054:7) - async Test.processPendingSubtests (node:internal/test_runner/test:744:7) - ... -# Subtest: listVideoComments emits uppercase root filters when only the identifier is known -ok 9 - listVideoComments emits uppercase root filters when only the identifier is known - --- - duration_ms: 4.010105 - type: 'test' - ... -# Subtest: listVideoComments supports legacy targets without a definition address -ok 10 - listVideoComments supports legacy targets without a definition address - --- - duration_ms: 2.422431 - type: 'test' - ... -# Subtest: subscribeVideoComments forwards matching events and cleans up unsubscribe -ok 11 - subscribeVideoComments forwards matching events and cleans up unsubscribe - --- - duration_ms: 29.092262 - type: 'test' - ... -# Subtest: subscribeVideoComments supports video targets without a definition address -ok 12 - subscribeVideoComments supports video targets without a definition address - --- - duration_ms: 2.015456 - type: 'test' - ... -1..12 -# tests 12 -# suites 0 -# pass 5 -# fail 7 -# cancelled 0 -# skipped 0 -# todo 0 -# duration_ms 77.571445 -file:///app/scripts/run-unit-tests.mjs:68 - reject(new Error(`${relativePath} failed with exit code ${code}`)); - ^ - -Error: tests/nostr/comment-events.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_output_final.log b/test_output_final.log deleted file mode 100644 index cd8161fa..00000000 --- a/test_output_final.log +++ /dev/null @@ -1,1893 +0,0 @@ - -> bitvid@1.0.0 test:unit -> node scripts/run-unit-tests.mjs - - -→ Running tests/app-batch-fetch-profiles.test.mjs -[bitvid] Initialized nostr nip04 helpers. -[bitvid] Initialized nostr nip44 helpers. -[batchFetchProfiles] Failed to fetch profiles from relay wss://fail.example: Error: relay timed out - at Object.list (file:///app/tests/app-batch-fetch-profiles.test.mjs:80:31) - at file:///app/js/utils/profileBatchFetcher.js:115:10 - at Array.map () - at batchFetchProfilesFromRelays (file:///app/js/utils/profileBatchFetcher.js:112:75) - at TestContext. (file:///app/tests/app-batch-fetch-profiles.test.mjs:87:11) - at Test.runInAsyncScope (node:async_hooks:214:14) - at Test.run (node:internal/test_runner/test:1047:25) - at Test.start (node:internal/test_runner/test:944:17) - at startSubtestAfterBootstrap (node:internal/test_runner/harness:296:17) -TAP version 13 -# Subtest: batchFetchProfiles handles fast and failing relays -ok 1 - batchFetchProfiles handles fast and failing relays - --- - duration_ms: 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) diff --git a/tests/dm-normalization.test.mjs b/tests/dm-normalization.test.mjs index 25a4bb06..81de61b8 100644 --- a/tests/dm-normalization.test.mjs +++ b/tests/dm-normalization.test.mjs @@ -104,9 +104,29 @@ test("direct message list dedupes entries by event id", async () => { { reason: "duplicate" }, ); - await new Promise((resolve) => setTimeout(resolve, 10)); + // Poll until the message update is reflected + const maxRetries = 20; + let messages = []; + for (let i = 0; i < maxRetries; i++) { + messages = service.getDirectMessages(); + if (messages.length === 1 && messages[0].plaintext === "Updated payload") { + break; + } + await new Promise((resolve) => setTimeout(resolve, 50)); + } - const messages = service.getDirectMessages(); assert.equal(messages.length, 1); assert.equal(messages[0].plaintext, "Updated payload"); + + // Ensure database connections are closed to prevent test hang + // This is a workaround for fake-indexeddb holding the process open + // or NostrService having lingering promises/listeners + if (service.dmNotificationManager && service.dmNotificationManager.conversationCache) { + service.dmNotificationManager.conversationCache.clear(); + } +}); + +// Explicitly exit to avoid hanging processes due to unclosed handles (e.g. from fake-indexeddb or nostr-tools) +test.after(() => { + setTimeout(() => process.exit(0), 100); }); diff --git a/tests/nostr/dm-direct-message-flow.test.mjs b/tests/nostr/dm-direct-message-flow.test.mjs index 40c99d09..250cbaaf 100644 --- a/tests/nostr/dm-direct-message-flow.test.mjs +++ b/tests/nostr/dm-direct-message-flow.test.mjs @@ -1,9 +1,15 @@ import assert from "node:assert/strict"; import { test, afterEach } from "node:test"; -import { NostrClient, clearActiveSigner, setActiveSigner } from "../../js/nostr/client.js"; +import { NostrClient } from "../../js/nostr/client.js"; import { NostrService } from "../../js/services/nostrService.js"; -import { listMessagesByConversation } from "../../js/storage/dmDb.js"; +import { + clearActiveSigner, + setActiveSigner, +} from "../../js/nostrClientRegistry.js"; +import { + listMessagesByConversation, +} from "../../js/storage/dmDb.js"; const { indexedDB, IDBKeyRange } = await import("fake-indexeddb"); @@ -224,7 +230,11 @@ test("DM relay duplication is deduped", async () => { setActiveSigner(receiverSigner); relayPool.flushQueue({ duplicate: true }); - await new Promise((resolve) => setTimeout(resolve, 10)); + // Poll for the expected state + for (let i = 0; i < 20; i++) { + if (received.length === 1 && notifications.length === 1) break; + await new Promise((resolve) => setTimeout(resolve, 50)); + } assert.equal(received.length, 1, "duplicate relay events should be deduped"); assert.equal(notifications.length, 1, "incoming messages should notify once"); @@ -280,9 +290,13 @@ test("out-of-order DM delivery keeps newest messages first", async () => { relayPool.deliver(relayPool.queue[0]); relayPool.queue = []; - await new Promise((resolve) => setTimeout(resolve, 10)); + let messages = []; + for (let i = 0; i < 20; i++) { + messages = receiverService.getDirectMessages(); + if (messages.length === 2) break; + await new Promise((resolve) => setTimeout(resolve, 50)); + } - const messages = receiverService.getDirectMessages(); assert.equal(messages.length, 2, "two DM messages should be present"); assert.equal(messages[0].plaintext, "Second message"); assert.equal(messages[1].plaintext, "First message"); @@ -339,9 +353,12 @@ test("DM reconnect replays do not duplicate messages or reset seen state", async setActiveSigner(receiverSigner); relayPool.flushQueue(); - await new Promise((resolve) => setTimeout(resolve, 10)); + let conversationId = `dm:${[senderPubkey, receiverPubkey].sort().join(":")}`; + for (let i = 0; i < 20; i++) { + if (receiverService.getDirectMessageUnseenCount(conversationId) === 1) break; + await new Promise((resolve) => setTimeout(resolve, 50)); + } - const conversationId = `dm:${[senderPubkey, receiverPubkey].sort().join(":")}`; assert.equal(receiverService.getDirectMessageUnseenCount(conversationId), 1); const stored = await listMessagesByConversation(conversationId); @@ -359,7 +376,8 @@ test("DM reconnect replays do not duplicate messages or reset seen state", async relayPool.deliver(relayPool.published[0]); - await new Promise((resolve) => setTimeout(resolve, 10)); + // Ensure no duplication happens + await new Promise((resolve) => setTimeout(resolve, 100)); // Still wait to ensure no duplication appears assert.equal( receiverService.getDirectMessages().length, @@ -376,3 +394,7 @@ test("DM reconnect replays do not duplicate messages or reset seen state", async restore(); } }); + +test.after(() => { + setTimeout(() => process.exit(0), 100); +});