Merge pull request #2623 from PR0M3TH3AN/test-audit-workflow-7235434178597122811

Add Test Audit Workflow & Initial Report
This commit is contained in:
thePR0M3TH3AN authored and GitHub committed 2026-02-18 15:22:44 -05:00
commit b536ee9a8e
14 files changed
+2576 -125

No files matched your search

+20
View File
@@ -0,0 +1,20 @@
# Test Audit Context - 2025-02-18
## Mission
To audit the test suite for behavior fidelity, determinism, and cheat vectors. The goal is to build a daily test-audit workflow that identifies flaky tests, suspicious patterns, and coverage gaps in critical modules.
## Scope
- Unit tests (`tests/` excluding `visual/` and `e2e/`).
- Critical modules:
- `js/services/authService.js`
- `js/relayManager.js`
- `js/nostr/dmDecryptWorker.js`
- `js/nostr/watchHistory.js`
- `js/userBlocks.js`
## Definition of Done
- `test-audit-report-YYYY-MM-DD.md` generated.
- `test-audit/flakiness-matrix.json` generated.
- `test-audit/suspicious-tests.json` generated.
- `test-audit/coverage-gaps.json` generated.
- Prioritized remediation tasks identified.
+11
View File
@@ -0,0 +1,11 @@
# Decisions - 2025-02-18
## Test Audit Implementation
- **Tooling**: Used `c8` for coverage and custom Node.js scripts for flakiness/static analysis.
- **Timeout**: Experienced timeouts with full suite coverage run; mitigation was to use the partial results which were sufficient for initial audit.
- **Coverage**: Mapped coverage to critical files using `coverage-summary.json`.
- **Artifacts**: Stored all artifacts in `test-audit/` for historical tracking.
## Findings
- Confirmed that critical modules (`userBlocks`, `relayManager`) have low test coverage.
- Identified widespread use of `sleep` and `fetch` in unit tests, indicating a need for better test isolation and determinism helpers.
+22
View File
@@ -0,0 +1,22 @@
# Test Audit Findings - 2025-02-18
## Overview
The daily test audit has identified significant coverage gaps and suspicious patterns in the test suite.
## Critical Coverage Gaps (< 70%)
1. **js/userBlocks.js** (25.77% statements) - Critical for moderation.
2. **js/relayManager.js** (56.75% statements) - Core networking logic.
3. **js/nostr/watchHistory.js** (58.14% statements) - User data integrity.
4. **js/services/authService.js** (Branches: 62.71%) - Auth flow reliability.
5. **js/nostr/dmDecryptWorker.js** (Branches: 31.66%) - Privacy/Security.
## Suspicious Patterns
- **91 files** contain suspicious patterns.
- **Network Dependence**: High usage of `fetch` / `WebSocket` without apparent mocking in unit tests (e.g., `tests/nostr/client.test.mjs`, `tests/services/attachmentService.test.mjs`).
- **Time Dependence**: Frequent use of `sleep`/`setTimeout` (e.g., `tests/login-modal-controller.test.mjs`).
- **Console Usage**: Tests logging to console (e.g., `tests/nostr/watchHistory.test.js` has 19 occurrences).
## Recommended Actions
1. **Immediate**: Create a "fixit" sprint to address coverage in `js/userBlocks.js` and `js/relayManager.js`.
2. **Refactor**: Replace `sleep()` calls with `waitFor()` or mock timers in `tests/login-modal-controller.test.mjs`.
3. **Infrastructure**: Introduce `msw` or `nock` for network mocking to remove `fetch` dependencies in unit tests.
+84
View File
@@ -0,0 +1,84 @@
import fs from 'node:fs';
import path from 'node:path';
const logDir = 'test-audit';
const matrixFile = path.join(logDir, 'flakiness-matrix.json');
function parseLog(content) {
const results = {};
const lines = content.split('\n');
let currentFile = null;
for (const line of lines) {
// "→ Running tests/..."
const runningMatch = line.match(/→ Running (.+)/);
if (runningMatch) {
currentFile = runningMatch[1];
if (!results[currentFile]) {
results[currentFile] = 'PASS'; // Assume pass until failure found
}
continue;
}
// "✖ tests/... failed with exit code ..."
const failMatch = line.match(/✖ (.+) failed with exit code/);
if (failMatch) {
results[failMatch[1]] = 'FAIL';
continue;
}
// TAP failures
if (line.trim().startsWith('not ok')) {
// Ideally we'd map this to the specific test case, but for now map to the file
if (currentFile) {
results[currentFile] = 'FAIL';
}
}
}
return results;
}
function main() {
const matrix = {};
const runFiles = fs.readdirSync(logDir).filter(f => f.startsWith('run-') && f.endsWith('.log'));
if (runFiles.length === 0) {
console.log('No run logs found.');
return;
}
console.log(`Analyzing ${runFiles.length} runs...`);
for (const file of runFiles) {
const content = fs.readFileSync(path.join(logDir, file), 'utf8');
const runResults = parseLog(content);
for (const [testFile, status] of Object.entries(runResults)) {
if (!matrix[testFile]) {
matrix[testFile] = [];
}
matrix[testFile].push(status);
}
}
// Identify flaky tests
const flakyTests = {};
for (const [testFile, statuses] of Object.entries(matrix)) {
const hasPass = statuses.includes('PASS');
const hasFail = statuses.includes('FAIL');
if (hasPass && hasFail) {
flakyTests[testFile] = { statuses, verdict: 'FLAKY' };
} else if (hasFail) {
flakyTests[testFile] = { statuses, verdict: 'FAIL' };
} else {
// Consistent PASS, ignore for report to save space, or include?
// Let's include everything for completeness
flakyTests[testFile] = { statuses, verdict: 'PASS' };
}
}
fs.writeFileSync(matrixFile, JSON.stringify(flakyTests, null, 2));
console.log(`Wrote flakiness matrix to ${matrixFile}`);
}
main();
+84
View File
@@ -0,0 +1,84 @@
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const rootDir = path.dirname(path.dirname(fileURLToPath(import.meta.url)));
let coverageFile = path.join(rootDir, 'test-audit', 'coverage', 'coverage', 'coverage-summary.json');
const outputFile = path.join(rootDir, 'test-audit', 'coverage-gaps.json');
const criticalFiles = [
'js/services/authService.js',
'js/relayManager.js',
'js/nostr/dmDecryptWorker.js',
'js/nostr/watchHistory.js',
'js/userBlocks.js'
];
async function main() {
if (!fs.existsSync(coverageFile)) {
const altPath = path.join(rootDir, 'test-audit', 'coverage', 'coverage-summary.json');
if (fs.existsSync(altPath)) {
coverageFile = altPath;
} else {
// One more fallback for potential flatter structure
const flatPath = path.join(rootDir, 'test-audit', 'coverage-summary.json');
if (fs.existsSync(flatPath)) {
coverageFile = flatPath;
} else {
console.error(`Coverage file not found at ${coverageFile} or ${altPath}`);
process.exit(1);
}
}
}
console.log(`Reading coverage from: ${coverageFile}`);
const coverage = JSON.parse(fs.readFileSync(coverageFile, 'utf8'));
const gaps = {};
// Create a normalized map of coverage keys (absolute paths) to relative paths
const normalizedCoverage = {};
for (const key of Object.keys(coverage)) {
let relativeKey = path.relative(rootDir, key);
normalizedCoverage[relativeKey] = coverage[key];
}
for (const file of criticalFiles) {
const fileCoverage = normalizedCoverage[file];
if (!fileCoverage) {
gaps[file] = {
lines: 0,
statements: 0,
functions: 0,
branches: 0,
status: 'MISSING'
};
continue;
}
const { lines, statements, functions, branches } = fileCoverage;
// Check if any metric is < 70%
if (lines.pct < 70 || statements.pct < 70 || functions.pct < 70 || branches.pct < 70) {
gaps[file] = {
lines: lines.pct,
statements: statements.pct,
functions: functions.pct,
branches: branches.pct,
status: 'LOW_COVERAGE'
};
} else {
gaps[file] = {
lines: lines.pct,
statements: statements.pct,
functions: functions.pct,
branches: branches.pct,
status: 'OK'
};
}
}
fs.writeFileSync(outputFile, JSON.stringify(gaps, null, 2));
console.log(`Wrote coverage gaps to ${outputFile}`);
}
main();
+126
View File
@@ -0,0 +1,126 @@
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { execSync } from 'node:child_process';
const rootDir = path.dirname(path.dirname(fileURLToPath(import.meta.url)));
const flakinessFile = path.join(rootDir, 'test-audit', 'flakiness-matrix.json');
const suspiciousFile = path.join(rootDir, 'test-audit', 'suspicious-tests.json');
const coverageFile = path.join(rootDir, 'test-audit', 'coverage-gaps.json');
const outputFile = path.join(rootDir, 'test-audit-report-' + new Date().toISOString().split('T')[0] + '.md');
function readJson(file) {
if (fs.existsSync(file)) {
return JSON.parse(fs.readFileSync(file, 'utf8'));
}
return null;
}
function main() {
const flakiness = readJson(flakinessFile);
const suspicious = readJson(suspiciousFile);
const coverage = readJson(coverageFile);
const nodeVersion = process.version;
let npmVersion = 'unknown';
try {
npmVersion = execSync('npm --version').toString().trim();
} catch (e) {}
let report = `# Test Audit Report - ${new Date().toISOString().split('T')[0]}\n\n`;
report += `## Run Metadata\n`;
report += `- **Date**: ${new Date().toISOString()}\n`;
report += `- **Node Version**: ${nodeVersion}\n`;
report += `- **NPM Version**: ${npmVersion}\n`;
report += `- **Test Command**: \`npm run test:unit\` (with c8 coverage)\n\n`;
// Summary
report += `## Summary\n`;
report += `- **Flaky Tests**: ${flakiness ? Object.keys(flakiness).filter(k => flakiness[k].verdict === 'FLAKY').length : 'N/A'}\n`;
report += `- **Suspicious Files**: ${suspicious ? Object.keys(suspicious).length : 'N/A'}\n`;
report += `- **Critical Coverage Gaps**: ${coverage ? Object.keys(coverage).filter(k => coverage[k].status === 'LOW_COVERAGE').length : 'N/A'}\n\n`;
// Flakiness
report += `## Flakiness Detection\n`;
if (flakiness) {
const flakyTests = Object.keys(flakiness).filter(k => flakiness[k].verdict === 'FLAKY');
if (flakyTests.length > 0) {
report += `Found ${flakyTests.length} flaky tests:\n`;
for (const test of flakyTests) {
report += `- **${test}**: ${flakiness[test].statuses.join(', ')}\n`;
}
} else {
report += `No flaky tests detected (based on run matrix).\n`;
}
} else {
report += `Flakiness matrix not found.\n`;
}
report += `\n`;
// Suspicious Tests
report += `## Suspicious Patterns\n`;
if (suspicious) {
const files = Object.keys(suspicious);
if (files.length > 0) {
report += `Found suspicious patterns in ${files.length} files:\n`;
for (const file of files) {
report += `### ${file}\n`;
for (const issue of suspicious[file]) {
report += `- ${issue}\n`;
}
}
} else {
report += `No suspicious patterns found.\n`;
}
} else {
report += `Suspicious tests file not found.\n`;
}
report += `\n`;
// Coverage Gaps
report += `## Critical Coverage Gaps\n`;
if (coverage) {
const gaps = Object.keys(coverage).filter(k => coverage[k].status !== 'OK');
if (gaps.length > 0) {
report += `Critical modules with low coverage (< 70%):\n`;
for (const file of gaps) {
const stats = coverage[file];
if (stats.status === 'MISSING') {
report += `- **${file}**: No coverage data found.\n`;
} else {
report += `- **${file}**: Lines: ${stats.lines}%, Statements: ${stats.statements}%, Functions: ${stats.functions}%, Branches: ${stats.branches}%\n`;
}
}
} else {
report += `All critical modules have acceptable coverage.\n`;
}
} else {
report += `Coverage gaps file not found.\n`;
}
report += `\n`;
// Remediation
report += `## Prioritized Remediation\n`;
report += `### High Priority (P0)\n`;
if (coverage) {
const gaps = Object.keys(coverage).filter(k => coverage[k].status !== 'OK');
for (const file of gaps) {
report += `- [ ] Increase coverage for \`${file}\` (currently < 70%).\n`;
}
}
if (flakiness) {
const flakyTests = Object.keys(flakiness).filter(k => flakiness[k].verdict === 'FLAKY');
for (const test of flakyTests) {
report += `- [ ] Fix flakiness in \`${test}\`.\n`;
}
}
report += `\n### Medium Priority (P1)\n`;
report += `- [ ] Review suspicious tests (time dependence, network usage) and replace with deterministic patterns.\n`;
fs.writeFileSync(outputFile, report);
console.log(`Generated report: ${outputFile}`);
}
main();
+44
View File
@@ -0,0 +1,44 @@
#!/bin/bash
set -e
# Setup
mkdir -p test-audit/coverage
echo "Step 1: Running unit tests with coverage..."
# We use || true because tests might fail, but we still want coverage
# Using npx c8 to ensure coverage is captured
npx c8 --reporter=lcov --reporter=text --reporter=json-summary npm run test:unit > test-audit/coverage-run.log 2>&1 || true
# Copy artifacts
# Check if coverage directory exists before copying
if [ -d "coverage" ]; then
cp -r coverage/* test-audit/coverage/
else
echo "Warning: coverage directory not found. Coverage step might have failed completely."
fi
echo "Step 2: Detecting flakiness..."
# Save the first run log
cp test-audit/coverage-run.log test-audit/run-1.log
# Run 2
echo "Pass 2..."
npm run test:unit > test-audit/run-2.log 2>&1 || true
# Run 3
echo "Pass 3..."
npm run test:unit > test-audit/run-3.log 2>&1 || true
echo "Step 3: Analyzing flakiness..."
node scripts/analyze-flakiness.mjs
echo "Step 4: Static Analysis..."
node scripts/static-test-analysis.mjs
echo "Step 5: Coverage Gap Analysis..."
node scripts/coverage-gap-analysis.mjs
echo "Step 6: Generating Report..."
node scripts/generate-audit-report.mjs
echo "Done. Report generated."
+78
View File
@@ -0,0 +1,78 @@
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const rootDir = path.dirname(path.dirname(fileURLToPath(import.meta.url)));
const testsDir = path.join(rootDir, 'tests');
const outputFile = path.join(rootDir, 'test-audit', 'suspicious-tests.json');
const checks = {
zeroAssertions: {
pattern: /(expect\(|assert\.|t\.is|chai\.expect|should\.)/g,
inverse: true,
message: 'No assertions found'
},
focusedOrSkipped: {
pattern: /\.(only|skip)\(/g,
message: 'Focused or skipped test'
},
timeDependence: {
pattern: /(setTimeout|setInterval|sleep|delay)\(/g,
message: 'Time dependence (sleep/timeout)'
},
networkDependence: {
pattern: /(fetch|axios\.|new WebSocket|WebSocket\()/g,
message: 'Network dependence (fetch/WebSocket)'
},
consoleUsage: {
pattern: /console\.(log|warn|error)/g,
message: 'Console usage'
}
};
async function scanFile(filePath) {
const content = fs.readFileSync(filePath, 'utf8');
const fileIssues = [];
for (const [key, check] of Object.entries(checks)) {
const matches = content.match(check.pattern);
if (check.inverse) {
if (!matches) {
fileIssues.push(check.message);
}
} else {
if (matches) {
fileIssues.push(`${check.message} (${matches.length} occurrences)`);
}
}
}
return fileIssues;
}
async function walk(dir) {
let results = {};
const list = fs.readdirSync(dir);
for (const file of list) {
if (file === 'node_modules' || file === 'visual' || file === 'e2e') continue;
const filePath = path.join(dir, file);
const stat = fs.statSync(filePath);
if (stat && stat.isDirectory()) {
Object.assign(results, await walk(filePath));
} else if (file.endsWith('.test.mjs') || file.endsWith('.test.js')) {
const issues = await scanFile(filePath);
if (issues.length > 0) {
results[path.relative(rootDir, filePath)] = issues;
}
}
}
return results;
}
async function main() {
console.log('Scanning tests for suspicious patterns...');
const suspiciousTests = await walk(testsDir);
fs.writeFileSync(outputFile, JSON.stringify(suspiciousTests, null, 2));
console.log(`Wrote suspicious tests to ${outputFile}`);
}
main();
+239 -27
View File
@@ -1,34 +1,246 @@
# Test Audit Report (2025-02-18)
# Test Audit Report - 2025-02-18
## Summary
The test suite is functional but slow (~6m+ if run fully with retry). Overall line coverage is ~42%, with critical gaps in `authService.js` (10%) and `playbackCoordinator.js` (9%). Static analysis reveals widespread usage of `setTimeout` in tests, which contributes to potential flakiness and slowness.
- **Flaky Tests**: 0
- **Suspicious Files**: 91
- **Critical Coverage Gaps**: 5
## Test Run
- **Environment**: Node.js v22 (experimental-test-coverage enabled)
- **Result**: 361 tests passed, 0 failed.
- **Flakiness**: Unable to fully assess due to timeout (suite > 400s), but timeouts in test code indicate risk.
## Flakiness Detection
No flaky tests detected (based on 2 runs).
## Coverage Gaps (Critical Files)
| File | Coverage (Line) | Criticality |
| :--- | :--- | :--- |
| `js/services/authService.js` | 10.16% | **P0** (Login/Security) |
| `js/app/playbackCoordinator.js` | 9.70% | **P0** (Core Feature) |
| `js/userBlocks.js` | 18.92% | **P1** (Moderation) |
| `js/relayManager.js` | 49.94% | **P1** (Network) |
| `js/nostr/watchHistory.js` | 46.24% | **P1** (User Data) |
| `js/nostr/dmDecryptWorkerClient.js`| 44.09% | **P1** (Privacy) |
## Suspicious Patterns
Found suspicious patterns in 91 files:
### tests/admin-list-store.test.mjs
- Time dependence (sleep/timeout) (2 occurrences)
- Console usage (4 occurrences)
### tests/app/feedCoordinator.test.mjs
- Network dependence (fetch/WebSocket) (1 occurrences)
### tests/app-batch-fetch-profiles.test.mjs
- Network dependence (fetch/WebSocket) (2 occurrences)
- Console usage (3 occurrences)
### tests/auth-service.test.mjs
- Time dependence (sleep/timeout) (2 occurrences)
### tests/comment-thread-service.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
- Network dependence (fetch/WebSocket) (78 occurrences)
- Console usage (1 occurrences)
### tests/compliance/nip07_compliance.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/discussion-count-service.test.mjs
- Network dependence (fetch/WebSocket) (2 occurrences)
- Console usage (1 occurrences)
### tests/dm-normalization.test.mjs
- Time dependence (sleep/timeout) (2 occurrences)
### tests/edit-modal-submit-state.test.mjs
- Network dependence (fetch/WebSocket) (3 occurrences)
### tests/event-schemas.test.mjs
- Console usage (3 occurrences)
### tests/feed-engine.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
- Console usage (1 occurrences)
### tests/hashtag-preferences.test.mjs
- Time dependence (sleep/timeout) (2 occurrences)
- Network dependence (fetch/WebSocket) (8 occurrences)
### tests/login-modal-controller.test.mjs
- Time dependence (sleep/timeout) (6 occurrences)
### tests/minimal-webtorrent.test.mjs
- No assertions found
### tests/modal-accessibility.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
- Network dependence (fetch/WebSocket) (4 occurrences)
### tests/moderation/submit-report.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/moderation/video-card.test.mjs
- Time dependence (sleep/timeout) (6 occurrences)
### tests/nip07-concurrency.test.mjs
- Time dependence (sleep/timeout) (2 occurrences)
### tests/nostr/client.test.mjs
- Time dependence (sleep/timeout) (3 occurrences)
- Network dependence (fetch/WebSocket) (13 occurrences)
### tests/nostr/comment-events.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/nostr/countDiagnostics.test.mjs
- Console usage (4 occurrences)
### tests/nostr/dm-direct-message-flow.test.mjs
- Time dependence (sleep/timeout) (2 occurrences)
### tests/nostr/dmDecryptWorkerClient.test.mjs
- Console usage (4 occurrences)
### tests/nostr/dmSignalEvents.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/nostr/integration-remote-flow.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/nostr/nip04WorkerClient.test.mjs
- Console usage (2 occurrences)
### tests/nostr/nip07Permissions.test.js
- Time dependence (sleep/timeout) (1 occurrences)
### tests/nostr/nip71.test.js
- Network dependence (fetch/WebSocket) (10 occurrences)
### tests/nostr/sessionActor.test.mjs
- Focused or skipped test (1 occurrences)
### tests/nostr/sign-request-queue.test.mjs
- Time dependence (sleep/timeout) (3 occurrences)
### tests/nostr/toolkit.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/nostr/watchHistory.test.js
- Time dependence (sleep/timeout) (1 occurrences)
- Network dependence (fetch/WebSocket) (5 occurrences)
### tests/nostr-boost-actions.test.mjs
- Network dependence (fetch/WebSocket) (2 occurrences)
- Console usage (1 occurrences)
### tests/nostr-count-fallback.test.mjs
- Console usage (4 occurrences)
### tests/nostr-delete-flow.test.mjs
- Console usage (1 occurrences)
### tests/nostr-login-permissions.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/nostr-nip46-queue.test.mjs
- Time dependence (sleep/timeout) (3 occurrences)
### tests/nostr-private-key-signer.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/nostr-publish-rejection.test.mjs
- Console usage (1 occurrences)
### tests/nostr-rebroadcast-guard.test.mjs
- Network dependence (fetch/WebSocket) (1 occurrences)
- Console usage (1 occurrences)
### tests/nostr-send-direct-message.test.mjs
- Time dependence (sleep/timeout) (2 occurrences)
### tests/nostr-service-access-control.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/nostr-signer-race.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/nostr-view-event-bindings.test.mjs
- Console usage (1 occurrences)
### tests/nostr-view-events.test.mjs
- Console usage (1 occurrences)
### tests/nwc-client.test.mjs
- Time dependence (sleep/timeout) (2 occurrences)
### tests/performance/resolvePostedAt.test.mjs
- Network dependence (fetch/WebSocket) (2 occurrences)
- Console usage (2 occurrences)
### tests/profile-cache.test.mjs
- Time dependence (sleep/timeout) (2 occurrences)
### tests/profile-modal-controller.test.mjs
- Time dependence (sleep/timeout) (3 occurrences)
- Network dependence (fetch/WebSocket) (3 occurrences)
### tests/race/nostr-client-init-race.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/revert-modal-controller.test.mjs
- Network dependence (fetch/WebSocket) (2 occurrences)
### tests/services/attachmentService.test.mjs
- Network dependence (fetch/WebSocket) (12 occurrences)
### tests/services/discussionCountService.test.mjs
- Network dependence (fetch/WebSocket) (1 occurrences)
### tests/services/exploreDataService.test.mjs
- Console usage (4 occurrences)
### tests/services/link-preview-service.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
- Network dependence (fetch/WebSocket) (7 occurrences)
- Console usage (1 occurrences)
### tests/services/nostr-service.test.mjs
- Network dependence (fetch/WebSocket) (3 occurrences)
### tests/services/playbackService_forcedSource.test.mjs
- Time dependence (sleep/timeout) (3 occurrences)
### tests/services/profileMetadataService.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
- Network dependence (fetch/WebSocket) (13 occurrences)
### tests/services/relay-health-service.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
- Network dependence (fetch/WebSocket) (1 occurrences)
### tests/services/trustBootstrap.test.mjs
- Time dependence (sleep/timeout) (2 occurrences)
### tests/sign-request-queue.test.mjs
- Time dependence (sleep/timeout) (3 occurrences)
### tests/state/cache.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/subscriptions-feed.test.mjs
- Network dependence (fetch/WebSocket) (1 occurrences)
- Console usage (1 occurrences)
### tests/subscriptions-manager.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
- Network dependence (fetch/WebSocket) (3 occurrences)
### tests/torrent/service-worker-fallback-message.test.mjs
- Network dependence (fetch/WebSocket) (1 occurrences)
### tests/torrent/toast-service.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/ui/components/debug_hashtag_strip_helper.test.mjs
- No assertions found
- Console usage (3 occurrences)
### tests/ui/creatorProfileController.test.mjs
- Network dependence (fetch/WebSocket) (12 occurrences)
### tests/ui/profile-modal-moderation-settings.test.mjs
- Network dependence (fetch/WebSocket) (2 occurrences)
### tests/ui/profileModalController-addProfile.test.mjs
- Network dependence (fetch/WebSocket) (2 occurrences)
- Console usage (2 occurrences)
### tests/ui/uploadModal-integration.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
- Network dependence (fetch/WebSocket) (7 occurrences)
### tests/ui/uploadModal-reset.test.mjs
- Network dependence (fetch/WebSocket) (1 occurrences)
- Console usage (1 occurrences)
### tests/ui/url-health-controller.test.mjs
- Time dependence (sleep/timeout) (5 occurrences)
- Network dependence (fetch/WebSocket) (3 occurrences)
### tests/unit/client-count-resilience.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/unit/editModalController.test.mjs
- Network dependence (fetch/WebSocket) (2 occurrences)
### tests/unit/notificationController.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/unit/services/r2Service.storage-config.test.mjs
- Network dependence (fetch/WebSocket) (3 occurrences)
### tests/unit/ui/videoModalController.test.mjs
- Time dependence (sleep/timeout) (2 occurrences)
### tests/user-blocks.test.mjs
- Time dependence (sleep/timeout) (2 occurrences)
### tests/utils/domUtils.test.mjs
- Console usage (2 occurrences)
### tests/video-card-source-visibility.test.mjs
- Time dependence (sleep/timeout) (2 occurrences)
### tests/video-modal-accessibility.test.mjs
- Network dependence (fetch/WebSocket) (5 occurrences)
- Console usage (4 occurrences)
### tests/video-modal-zap.test.mjs
- Network dependence (fetch/WebSocket) (4 occurrences)
### tests/view-counter.test.mjs
- Time dependence (sleep/timeout) (2 occurrences)
- Network dependence (fetch/WebSocket) (6 occurrences)
- Console usage (4 occurrences)
### tests/watch-history-feed.test.mjs
- Console usage (1 occurrences)
### tests/watch-history.test.mjs
- Time dependence (sleep/timeout) (4 occurrences)
- Network dependence (fetch/WebSocket) (14 occurrences)
- Console usage (19 occurrences)
### tests/watchHistory/watch-history-telemetry.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/webtorrent-handlers.test.mjs
- Time dependence (sleep/timeout) (3 occurrences)
### tests/webtorrent-regression.test.mjs
- Time dependence (sleep/timeout) (2 occurrences)
- Console usage (1 occurrences)
### tests/zap-shared-state.test.mjs
- Console usage (1 occurrences)
### tests/zap-split.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
- Network dependence (fetch/WebSocket) (7 occurrences)
- Console usage (1 occurrences)
## Findings & Smells
1. **Low Coverage in Auth**: `authService.js` is barely tested. It handles login, key management, and profile hydration.
2. **Timeouts in Tests**: Found 19 instances of `setTimeout` in tests. `tests/nostr/dm-direct-message-flow.test.mjs` uses `setTimeout(r, intervalMs)` and `setTimeout(resolve, 100)` to wait for events, which is fragile.
3. **Console Logs**: 20+ instances of `console.log` in test files.
4. **Slow Tests**: The suite takes too long to run repeatedly for flakiness checks.
## Critical Coverage Gaps
Critical modules with low coverage (< 70%):
- **js/services/authService.js**: Lines: 77.34%, Statements: 77.34%, Functions: 61.9%, Branches: 62.71%
- **js/relayManager.js**: Lines: 56.75%, Statements: 56.75%, Functions: 73.33%, Branches: 51.93%
- **js/nostr/dmDecryptWorker.js**: Lines: 71.8%, Statements: 71.8%, Functions: 100%, Branches: 31.66%
- **js/nostr/watchHistory.js**: Lines: 58.14%, Statements: 58.14%, Functions: 69.64%, Branches: 40.68%
- **js/userBlocks.js**: Lines: 25.77%, Statements: 25.77%, Functions: 33.33%, Branches: 29.2%
## Recommendations
1. **Fix P0 Coverage**: Add unit tests for `authService.js` (login flows, error handling).
2. **Refactor Timeouts**: Replace `setTimeout` with `waitFor` helpers or event listeners in `dm-direct-message-flow.test.mjs`.
3. **Cleanup**: Remove `console.log` from tests.
## Prioritized Remediation
### High Priority (P0)
- [ ] Increase coverage for `js/services/authService.js` (currently < 70%).
- [ ] Increase coverage for `js/relayManager.js` (currently < 70%).
- [ ] Increase coverage for `js/nostr/dmDecryptWorker.js` (currently < 70%).
- [ ] Increase coverage for `js/nostr/watchHistory.js` (currently < 70%).
- [ ] Increase coverage for `js/userBlocks.js` (currently < 70%).
## Remediation Plan
- **Action**: Create a PR to add tests for `js/services/authService.js`.
- **Target**: Increase coverage for `authService` to > 30% by testing the public `login` and `logout` methods.
### Medium Priority (P1)
- [ ] Review suspicious tests (time dependence, network usage) and replace with deterministic patterns.
+252
View File
@@ -0,0 +1,252 @@
# Test Audit Report - 2026-02-18
## Run Metadata
- **Date**: 2026-02-18T20:13:50.582Z
- **Node Version**: v22.22.0
- **NPM Version**: 11.7.0
- **Test Command**: `npm run test:unit` (with c8 coverage)
## Summary
- **Flaky Tests**: 0
- **Suspicious Files**: 91
- **Critical Coverage Gaps**: 5
## Flakiness Detection
No flaky tests detected (based on run matrix).
## Suspicious Patterns
Found suspicious patterns in 91 files:
### tests/admin-list-store.test.mjs
- Time dependence (sleep/timeout) (2 occurrences)
- Console usage (4 occurrences)
### tests/app/feedCoordinator.test.mjs
- Network dependence (fetch/WebSocket) (1 occurrences)
### tests/app-batch-fetch-profiles.test.mjs
- Network dependence (fetch/WebSocket) (2 occurrences)
- Console usage (3 occurrences)
### tests/auth-service.test.mjs
- Time dependence (sleep/timeout) (2 occurrences)
### tests/comment-thread-service.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
- Network dependence (fetch/WebSocket) (78 occurrences)
- Console usage (1 occurrences)
### tests/compliance/nip07_compliance.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/discussion-count-service.test.mjs
- Network dependence (fetch/WebSocket) (2 occurrences)
- Console usage (1 occurrences)
### tests/dm-normalization.test.mjs
- Time dependence (sleep/timeout) (2 occurrences)
### tests/edit-modal-submit-state.test.mjs
- Network dependence (fetch/WebSocket) (3 occurrences)
### tests/event-schemas.test.mjs
- Console usage (3 occurrences)
### tests/feed-engine.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
- Console usage (1 occurrences)
### tests/hashtag-preferences.test.mjs
- Time dependence (sleep/timeout) (2 occurrences)
- Network dependence (fetch/WebSocket) (8 occurrences)
### tests/login-modal-controller.test.mjs
- Time dependence (sleep/timeout) (6 occurrences)
### tests/minimal-webtorrent.test.mjs
- No assertions found
### tests/modal-accessibility.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
- Network dependence (fetch/WebSocket) (4 occurrences)
### tests/moderation/submit-report.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/moderation/video-card.test.mjs
- Time dependence (sleep/timeout) (6 occurrences)
### tests/nip07-concurrency.test.mjs
- Time dependence (sleep/timeout) (2 occurrences)
### tests/nostr/client.test.mjs
- Time dependence (sleep/timeout) (3 occurrences)
- Network dependence (fetch/WebSocket) (13 occurrences)
### tests/nostr/comment-events.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/nostr/countDiagnostics.test.mjs
- Console usage (4 occurrences)
### tests/nostr/dm-direct-message-flow.test.mjs
- Time dependence (sleep/timeout) (2 occurrences)
### tests/nostr/dmDecryptWorkerClient.test.mjs
- Console usage (4 occurrences)
### tests/nostr/dmSignalEvents.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/nostr/integration-remote-flow.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/nostr/nip04WorkerClient.test.mjs
- Console usage (2 occurrences)
### tests/nostr/nip07Permissions.test.js
- Time dependence (sleep/timeout) (1 occurrences)
### tests/nostr/nip71.test.js
- Network dependence (fetch/WebSocket) (10 occurrences)
### tests/nostr/sessionActor.test.mjs
- Focused or skipped test (1 occurrences)
### tests/nostr/sign-request-queue.test.mjs
- Time dependence (sleep/timeout) (3 occurrences)
### tests/nostr/toolkit.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/nostr/watchHistory.test.js
- Time dependence (sleep/timeout) (1 occurrences)
- Network dependence (fetch/WebSocket) (5 occurrences)
### tests/nostr-boost-actions.test.mjs
- Network dependence (fetch/WebSocket) (2 occurrences)
- Console usage (1 occurrences)
### tests/nostr-count-fallback.test.mjs
- Console usage (4 occurrences)
### tests/nostr-delete-flow.test.mjs
- Console usage (1 occurrences)
### tests/nostr-login-permissions.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/nostr-nip46-queue.test.mjs
- Time dependence (sleep/timeout) (3 occurrences)
### tests/nostr-private-key-signer.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/nostr-publish-rejection.test.mjs
- Console usage (1 occurrences)
### tests/nostr-rebroadcast-guard.test.mjs
- Network dependence (fetch/WebSocket) (1 occurrences)
- Console usage (1 occurrences)
### tests/nostr-send-direct-message.test.mjs
- Time dependence (sleep/timeout) (2 occurrences)
### tests/nostr-service-access-control.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/nostr-signer-race.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/nostr-view-event-bindings.test.mjs
- Console usage (1 occurrences)
### tests/nostr-view-events.test.mjs
- Console usage (1 occurrences)
### tests/nwc-client.test.mjs
- Time dependence (sleep/timeout) (2 occurrences)
### tests/performance/resolvePostedAt.test.mjs
- Network dependence (fetch/WebSocket) (2 occurrences)
- Console usage (2 occurrences)
### tests/profile-cache.test.mjs
- Time dependence (sleep/timeout) (2 occurrences)
### tests/profile-modal-controller.test.mjs
- Time dependence (sleep/timeout) (3 occurrences)
- Network dependence (fetch/WebSocket) (3 occurrences)
### tests/race/nostr-client-init-race.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/revert-modal-controller.test.mjs
- Network dependence (fetch/WebSocket) (2 occurrences)
### tests/services/attachmentService.test.mjs
- Network dependence (fetch/WebSocket) (12 occurrences)
### tests/services/discussionCountService.test.mjs
- Network dependence (fetch/WebSocket) (1 occurrences)
### tests/services/exploreDataService.test.mjs
- Console usage (4 occurrences)
### tests/services/link-preview-service.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
- Network dependence (fetch/WebSocket) (7 occurrences)
- Console usage (1 occurrences)
### tests/services/nostr-service.test.mjs
- Network dependence (fetch/WebSocket) (3 occurrences)
### tests/services/playbackService_forcedSource.test.mjs
- Time dependence (sleep/timeout) (3 occurrences)
### tests/services/profileMetadataService.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
- Network dependence (fetch/WebSocket) (13 occurrences)
### tests/services/relay-health-service.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
- Network dependence (fetch/WebSocket) (1 occurrences)
### tests/services/trustBootstrap.test.mjs
- Time dependence (sleep/timeout) (2 occurrences)
### tests/sign-request-queue.test.mjs
- Time dependence (sleep/timeout) (3 occurrences)
### tests/state/cache.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/subscriptions-feed.test.mjs
- Network dependence (fetch/WebSocket) (1 occurrences)
- Console usage (1 occurrences)
### tests/subscriptions-manager.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
- Network dependence (fetch/WebSocket) (3 occurrences)
### tests/torrent/service-worker-fallback-message.test.mjs
- Network dependence (fetch/WebSocket) (1 occurrences)
### tests/torrent/toast-service.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/ui/components/debug_hashtag_strip_helper.test.mjs
- No assertions found
- Console usage (3 occurrences)
### tests/ui/creatorProfileController.test.mjs
- Network dependence (fetch/WebSocket) (12 occurrences)
### tests/ui/profile-modal-moderation-settings.test.mjs
- Network dependence (fetch/WebSocket) (2 occurrences)
### tests/ui/profileModalController-addProfile.test.mjs
- Network dependence (fetch/WebSocket) (2 occurrences)
- Console usage (2 occurrences)
### tests/ui/uploadModal-integration.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
- Network dependence (fetch/WebSocket) (7 occurrences)
### tests/ui/uploadModal-reset.test.mjs
- Network dependence (fetch/WebSocket) (1 occurrences)
- Console usage (1 occurrences)
### tests/ui/url-health-controller.test.mjs
- Time dependence (sleep/timeout) (5 occurrences)
- Network dependence (fetch/WebSocket) (3 occurrences)
### tests/unit/client-count-resilience.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/unit/editModalController.test.mjs
- Network dependence (fetch/WebSocket) (2 occurrences)
### tests/unit/notificationController.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/unit/services/r2Service.storage-config.test.mjs
- Network dependence (fetch/WebSocket) (3 occurrences)
### tests/unit/ui/videoModalController.test.mjs
- Time dependence (sleep/timeout) (2 occurrences)
### tests/user-blocks.test.mjs
- Time dependence (sleep/timeout) (2 occurrences)
### tests/utils/domUtils.test.mjs
- Console usage (2 occurrences)
### tests/video-card-source-visibility.test.mjs
- Time dependence (sleep/timeout) (2 occurrences)
### tests/video-modal-accessibility.test.mjs
- Network dependence (fetch/WebSocket) (5 occurrences)
- Console usage (4 occurrences)
### tests/video-modal-zap.test.mjs
- Network dependence (fetch/WebSocket) (4 occurrences)
### tests/view-counter.test.mjs
- Time dependence (sleep/timeout) (2 occurrences)
- Network dependence (fetch/WebSocket) (6 occurrences)
- Console usage (4 occurrences)
### tests/watch-history-feed.test.mjs
- Console usage (1 occurrences)
### tests/watch-history.test.mjs
- Time dependence (sleep/timeout) (4 occurrences)
- Network dependence (fetch/WebSocket) (14 occurrences)
- Console usage (19 occurrences)
### tests/watchHistory/watch-history-telemetry.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
### tests/webtorrent-handlers.test.mjs
- Time dependence (sleep/timeout) (3 occurrences)
### tests/webtorrent-regression.test.mjs
- Time dependence (sleep/timeout) (2 occurrences)
- Console usage (1 occurrences)
### tests/zap-shared-state.test.mjs
- Console usage (1 occurrences)
### tests/zap-split.test.mjs
- Time dependence (sleep/timeout) (1 occurrences)
- Network dependence (fetch/WebSocket) (7 occurrences)
- Console usage (1 occurrences)
## Critical Coverage Gaps
Critical modules with low coverage (< 70%):
- **js/services/authService.js**: Lines: 77.34%, Statements: 77.34%, Functions: 61.9%, Branches: 62.71%
- **js/relayManager.js**: Lines: 56.75%, Statements: 56.75%, Functions: 73.33%, Branches: 51.93%
- **js/nostr/dmDecryptWorker.js**: Lines: 71.8%, Statements: 71.8%, Functions: 100%, Branches: 31.66%
- **js/nostr/watchHistory.js**: Lines: 58.14%, Statements: 58.14%, Functions: 69.64%, Branches: 40.68%
- **js/userBlocks.js**: Lines: 25.77%, Statements: 25.77%, Functions: 33.33%, Branches: 29.2%
## Prioritized Remediation
### High Priority (P0)
- [ ] Increase coverage for `js/services/authService.js` (currently < 70%).
- [ ] Increase coverage for `js/relayManager.js` (currently < 70%).
- [ ] Increase coverage for `js/nostr/dmDecryptWorker.js` (currently < 70%).
- [ ] Increase coverage for `js/nostr/watchHistory.js` (currently < 70%).
- [ ] Increase coverage for `js/userBlocks.js` (currently < 70%).
### Medium Priority (P1)
- [ ] Review suspicious tests (time dependence, network usage) and replace with deterministic patterns.
+35 -8
View File
@@ -1,10 +1,37 @@
{
"js/services/authService.js": 77.34,
"js/relayManager.js": 49.93,
"js/nostr/dmDecryptWorker.js": 71.8,
"js/nostr/dmDecryptWorkerClient.js": 96.85,
"js/nostr/watchHistory.js": 58.14,
"js/userBlocks.js": 25.86,
"js/ui/ambientBackground.js": 33.02,
"torrent/app.js": 0
"js/services/authService.js": {
"lines": 77.34,
"statements": 77.34,
"functions": 61.9,
"branches": 62.71,
"status": "LOW_COVERAGE"
},
"js/relayManager.js": {
"lines": 56.75,
"statements": 56.75,
"functions": 73.33,
"branches": 51.93,
"status": "LOW_COVERAGE"
},
"js/nostr/dmDecryptWorker.js": {
"lines": 71.8,
"statements": 71.8,
"functions": 100,
"branches": 31.66,
"status": "LOW_COVERAGE"
},
"js/nostr/watchHistory.js": {
"lines": 58.14,
"statements": 58.14,
"functions": 69.64,
"branches": 40.68,
"status": "LOW_COVERAGE"
},
"js/userBlocks.js": {
"lines": 25.77,
"statements": 25.77,
"functions": 33.33,
"branches": 29.2,
"status": "LOW_COVERAGE"
}
}
File diff suppressed because it is too large. Load diff
+151 -88
View File
@@ -1,245 +1,308 @@
{
"tests/admin-list-store.test.mjs": [
"Uses setTimeout/sleep (brittle)",
"Console usage inside test"
"Time dependence (sleep/timeout) (2 occurrences)",
"Console usage (4 occurrences)"
],
"tests/app/feedCoordinator.test.mjs": [
"Network dependence (fetch/WebSocket) (1 occurrences)"
],
"tests/app-batch-fetch-profiles.test.mjs": [
"Console usage inside test"
"Network dependence (fetch/WebSocket) (2 occurrences)",
"Console usage (3 occurrences)"
],
"tests/auth-service.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (2 occurrences)"
],
"tests/comment-thread-service.test.mjs": [
"Uses setTimeout/sleep (brittle)",
"Console usage inside test"
"Time dependence (sleep/timeout) (1 occurrences)",
"Network dependence (fetch/WebSocket) (78 occurrences)",
"Console usage (1 occurrences)"
],
"tests/compliance/nip07_compliance.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (1 occurrences)"
],
"tests/discussion-count-service.test.mjs": [
"Console usage inside test"
"Network dependence (fetch/WebSocket) (2 occurrences)",
"Console usage (1 occurrences)"
],
"tests/dm-normalization.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (2 occurrences)"
],
"tests/edit-modal-submit-state.test.mjs": [
"Network dependence (fetch/WebSocket) (3 occurrences)"
],
"tests/event-schemas.test.mjs": [
"Console usage inside test"
"Console usage (3 occurrences)"
],
"tests/feed-engine.test.mjs": [
"Uses setTimeout/sleep (brittle)",
"Console usage inside test"
"Time dependence (sleep/timeout) (1 occurrences)",
"Console usage (1 occurrences)"
],
"tests/hashtag-preferences.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (2 occurrences)",
"Network dependence (fetch/WebSocket) (8 occurrences)"
],
"tests/minimal-channel-profile.test.mjs": [
"No obvious assertions found"
"tests/login-modal-controller.test.mjs": [
"Time dependence (sleep/timeout) (6 occurrences)"
],
"tests/minimal-webtorrent.test.mjs": [
"No obvious assertions found"
"No assertions found"
],
"tests/modal-accessibility.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (1 occurrences)",
"Network dependence (fetch/WebSocket) (4 occurrences)"
],
"tests/moderation/submit-report.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (1 occurrences)"
],
"tests/moderation/video-card.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (6 occurrences)"
],
"tests/nip07-concurrency.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (2 occurrences)"
],
"tests/nostr/client.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (3 occurrences)",
"Network dependence (fetch/WebSocket) (13 occurrences)"
],
"tests/nostr/comment-events.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (1 occurrences)"
],
"tests/nostr/countDiagnostics.test.mjs": [
"Console usage inside test"
"Console usage (4 occurrences)"
],
"tests/nostr/dm-direct-message-flow.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (2 occurrences)"
],
"tests/nostr/dmDecryptWorkerClient.test.mjs": [
"Console usage inside test"
"Console usage (4 occurrences)"
],
"tests/nostr/dmSignalEvents.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (1 occurrences)"
],
"tests/nostr/integration-remote-flow.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (1 occurrences)"
],
"tests/nostr/nip04WorkerClient.test.mjs": [
"Console usage inside test"
"Console usage (2 occurrences)"
],
"tests/nostr/nip07Permissions.test.js": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (1 occurrences)"
],
"tests/nostr/nip71.test.js": [
"Network dependence (fetch/WebSocket) (10 occurrences)"
],
"tests/nostr/sessionActor.test.mjs": [
"Test is focused (.only) or skipped (.skip)"
"Focused or skipped test (1 occurrences)"
],
"tests/nostr/sign-request-queue.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (3 occurrences)"
],
"tests/nostr/toolkit.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (1 occurrences)"
],
"tests/nostr/watchHistory.test.js": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (1 occurrences)",
"Network dependence (fetch/WebSocket) (5 occurrences)"
],
"tests/nostr-boost-actions.test.mjs": [
"Console usage inside test"
"Network dependence (fetch/WebSocket) (2 occurrences)",
"Console usage (1 occurrences)"
],
"tests/nostr-count-fallback.test.mjs": [
"Console usage inside test"
"Console usage (4 occurrences)"
],
"tests/nostr-delete-flow.test.mjs": [
"Console usage inside test"
"Console usage (1 occurrences)"
],
"tests/nostr-login-permissions.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (1 occurrences)"
],
"tests/nostr-nip46-queue.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (3 occurrences)"
],
"tests/nostr-private-key-signer.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (1 occurrences)"
],
"tests/nostr-publish-rejection.test.mjs": [
"Console usage inside test"
"Console usage (1 occurrences)"
],
"tests/nostr-rebroadcast-guard.test.mjs": [
"Console usage inside test"
"Network dependence (fetch/WebSocket) (1 occurrences)",
"Console usage (1 occurrences)"
],
"tests/nostr-send-direct-message.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (2 occurrences)"
],
"tests/nostr-service-access-control.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (1 occurrences)"
],
"tests/nostr-signer-race.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (1 occurrences)"
],
"tests/nostr-view-event-bindings.test.mjs": [
"Console usage inside test"
"Console usage (1 occurrences)"
],
"tests/nostr-view-events.test.mjs": [
"Console usage inside test"
"Console usage (1 occurrences)"
],
"tests/nwc-client.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (2 occurrences)"
],
"tests/performance/resolvePostedAt.test.mjs": [
"Console usage inside test"
"Network dependence (fetch/WebSocket) (2 occurrences)",
"Console usage (2 occurrences)"
],
"tests/profile-cache.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (2 occurrences)"
],
"tests/profile-modal-controller.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (3 occurrences)",
"Network dependence (fetch/WebSocket) (3 occurrences)"
],
"tests/race/nostr-client-init-race.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (1 occurrences)"
],
"tests/revert-modal-controller.test.mjs": [
"Network dependence (fetch/WebSocket) (2 occurrences)"
],
"tests/services/attachmentService.test.mjs": [
"Network dependence (fetch/WebSocket) (12 occurrences)"
],
"tests/services/discussionCountService.test.mjs": [
"Network dependence (fetch/WebSocket) (1 occurrences)"
],
"tests/services/exploreDataService.test.mjs": [
"Console usage inside test"
"Console usage (4 occurrences)"
],
"tests/services/link-preview-service.test.mjs": [
"Uses setTimeout/sleep (brittle)",
"Console usage inside test"
"Time dependence (sleep/timeout) (1 occurrences)",
"Network dependence (fetch/WebSocket) (7 occurrences)",
"Console usage (1 occurrences)"
],
"tests/services/nostr-service.test.mjs": [
"Network dependence (fetch/WebSocket) (3 occurrences)"
],
"tests/services/playbackService_forcedSource.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (3 occurrences)"
],
"tests/services/profileMetadataService.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (1 occurrences)",
"Network dependence (fetch/WebSocket) (13 occurrences)"
],
"tests/services/relay-health-service.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (1 occurrences)",
"Network dependence (fetch/WebSocket) (1 occurrences)"
],
"tests/services/trustBootstrap.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (2 occurrences)"
],
"tests/sign-request-queue.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (3 occurrences)"
],
"tests/state/cache.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (1 occurrences)"
],
"tests/subscriptions-feed.test.mjs": [
"Console usage inside test"
"Network dependence (fetch/WebSocket) (1 occurrences)",
"Console usage (1 occurrences)"
],
"tests/subscriptions-manager.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (1 occurrences)",
"Network dependence (fetch/WebSocket) (3 occurrences)"
],
"tests/torrent/service-worker-fallback-message.test.mjs": [
"Network dependence (fetch/WebSocket) (1 occurrences)"
],
"tests/torrent/toast-service.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (1 occurrences)"
],
"tests/ui/components/debug_hashtag_strip_helper.test.mjs": [
"No obvious assertions found",
"Console usage inside test"
"No assertions found",
"Console usage (3 occurrences)"
],
"tests/ui/creatorProfileController.test.mjs": [
"Network dependence (fetch/WebSocket) (12 occurrences)"
],
"tests/ui/profile-modal-moderation-settings.test.mjs": [
"Network dependence (fetch/WebSocket) (2 occurrences)"
],
"tests/ui/profileModalController-addProfile.test.mjs": [
"Console usage inside test"
"Network dependence (fetch/WebSocket) (2 occurrences)",
"Console usage (2 occurrences)"
],
"tests/ui/uploadModal-integration.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (1 occurrences)",
"Network dependence (fetch/WebSocket) (7 occurrences)"
],
"tests/ui/uploadModal-reset.test.mjs": [
"Console usage inside test"
"Network dependence (fetch/WebSocket) (1 occurrences)",
"Console usage (1 occurrences)"
],
"tests/ui/url-health-controller.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (5 occurrences)",
"Network dependence (fetch/WebSocket) (3 occurrences)"
],
"tests/unit/client-count-resilience.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (1 occurrences)"
],
"tests/unit/editModalController.test.mjs": [
"Network dependence (fetch/WebSocket) (2 occurrences)"
],
"tests/unit/notificationController.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (1 occurrences)"
],
"tests/unit/services/r2Service.storage-config.test.mjs": [
"Network dependence (fetch/WebSocket) (3 occurrences)"
],
"tests/unit/ui/videoModalController.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (2 occurrences)"
],
"tests/user-blocks.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (2 occurrences)"
],
"tests/utils/domUtils.test.mjs": [
"Console usage inside test"
"Console usage (2 occurrences)"
],
"tests/video-card-source-visibility.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (2 occurrences)"
],
"tests/video-modal-accessibility.test.mjs": [
"Console usage inside test"
"Network dependence (fetch/WebSocket) (5 occurrences)",
"Console usage (4 occurrences)"
],
"tests/video-modal-zap.test.mjs": [
"Network dependence (fetch/WebSocket) (4 occurrences)"
],
"tests/view-counter.test.mjs": [
"Uses setTimeout/sleep (brittle)",
"Console usage inside test"
"Time dependence (sleep/timeout) (2 occurrences)",
"Network dependence (fetch/WebSocket) (6 occurrences)",
"Console usage (4 occurrences)"
],
"tests/watch-history-feed.test.mjs": [
"Console usage inside test"
"Console usage (1 occurrences)"
],
"tests/watch-history.test.mjs": [
"Uses setTimeout/sleep (brittle)",
"Console usage inside test"
"Time dependence (sleep/timeout) (4 occurrences)",
"Network dependence (fetch/WebSocket) (14 occurrences)",
"Console usage (19 occurrences)"
],
"tests/watchHistory/watch-history-telemetry.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (1 occurrences)"
],
"tests/webtorrent-handlers.test.mjs": [
"Uses setTimeout/sleep (brittle)"
"Time dependence (sleep/timeout) (3 occurrences)"
],
"tests/webtorrent-regression.test.mjs": [
"Uses setTimeout/sleep (brittle)",
"Console usage inside test"
"Time dependence (sleep/timeout) (2 occurrences)",
"Console usage (1 occurrences)"
],
"tests/zap-shared-state.test.mjs": [
"Console usage inside test"
"Console usage (1 occurrences)"
],
"tests/zap-split.test.mjs": [
"Uses setTimeout/sleep (brittle)",
"Console usage inside test"
"Time dependence (sleep/timeout) (1 occurrences)",
"Network dependence (fetch/WebSocket) (7 occurrences)",
"Console usage (1 occurrences)"
]
}
+9
View File
@@ -0,0 +1,9 @@
# Test Audit Todo - 2025-02-18
- [ ] Execute unit tests with coverage.
- [ ] Run flakiness detection loop (5x).
- [ ] Create `scripts/analyze-flakiness.mjs`.
- [ ] Create `scripts/static-test-analysis.mjs`.
- [ ] Create `scripts/coverage-gap-analysis.mjs`.
- [ ] Create `scripts/generate-audit-report.mjs`.
- [ ] Generate final audit report.