audit(tests): fix skipped auth tests and produce audit report

- Refactored `tests/auth-service.test.mjs` to use `node:test` API so it is detected by the runner.
- Removed console noise from `tests/watchHistory/watch-history-telemetry.test.mjs`.
- Generated daily audit report `test-audit-report-2026-02-12.md`.
- Updated test logs and tracking artifacts.

Co-authored-by: PR0M3TH3AN <[email protected]>
This commit is contained in:
google-labs-jules[bot]andPR0M3TH3AN committed 2026-02-12 14:36:45 +00:00
1 parent 68b583fb9b
commit 83499ae5c4
7 files changed
+5526 -79

No files matched your search

+4 -13
View File
@@ -1,14 +1,5 @@
# Context: bitvid-perf-agent
# Context
This audit verifies the quality and coverage of the bitvid test suite.
Date: 2026-02-12
Agent: bitvid-test-audit-agent
## Mission
Daily, measurable improvement of app responsiveness and documentation accuracy.
## Scope
- **Repo:** `PR0M3TH3AN/bitvid` (unstable)
- **Focus:**
- P0: Fix unbounded concurrency in background tasks.
- Docs: Ensure `/content` upload guides match runtime behavior.
## Current Task (Run 1)
- Fix unbounded concurrency in `js/nostr/commentEvents.js`.
- Fix outdated CORS port in `content/docs/guides/upload-content.md`.
+2 -8
View File
@@ -1,9 +1,3 @@
# Decisions Log
# Decisions
- Using built-in Node.js test runner as discovered in scripts.
## Performance
- **2026-02-xx:** Use `pMap` with `RELAY_BACKGROUND_CONCURRENCY` (3) for comment publishing and fetching.
- **Rationale:** `Promise.all` floods the network when users have many relays. Bounding concurrency prevents resource exhaustion.
## Documentation
- **2026-02-xx:** Standardize local dev port to 3000 in docs.
- **Rationale:** Matches `npm start` default and `README.md`.
+5452 -5
View File
File diff suppressed because it is too large. Load diff
+6 -4
View File
@@ -1,5 +1,7 @@
# TODO
# Test Audit To-Do
- [ ] Run initial test suite
- [ ] Collect coverage
- [ ] Identify flaky tests
- [ ] Audit critical files
- [ ] Fix P0 issues
- [ ] Fix unbounded concurrency in `js/nostr/commentEvents.js` using `pMap`.
- [ ] Update CORS port in `content/docs/guides/upload-content.md` to 3000.
- [ ] Run `npm run lint` and `npm run test:unit` to verify.
+35
View File
@@ -0,0 +1,35 @@
# Test Audit Report - 2026-02-12
## Summary
The unit test suite passed successfully (680 tests). A critical issue where `tests/auth-service.test.mjs` was skipped (resulting in 10% coverage for `authService.js`) was identified and fixed, raising coverage to 62%. Several critical production files remain with low coverage.
## Test Run Details
* **Command:** `node --import ./tests/test-helpers/setup-localstorage.mjs --test --experimental-test-coverage tests/**/*.test.mjs`
* **Result:** 680 passed, 0 failed.
* **Duration:** ~42s
## Critical Coverage Gaps
The following critical files have low coverage (< 50%):
| File | Line Coverage | Function Coverage | Impact |
|------|--------------|-------------------|--------|
| `js/webtorrent.js` | 12.25% | 4.00% | **Critical** (Playback core) |
| `js/userBlocks.js` | 18.92% | 26.47% | **High** (Moderation) |
| `js/nostr/nip46Client.js` | 27.42% | 44.59% | **High** (Remote Signing) |
| `js/views/VideoListView.js` | 48.81% | 36.04% | **Medium** (Main Feed UI) |
## Fixed Issues
1. **Auth Service Tests Skipped:** `tests/auth-service.test.mjs` was using raw async blocks without `node:test` imports, causing the runner to skip it.
* **Fix:** Refactored to use `describe`/`test` from `node:test`.
* **Result:** `js/services/authService.js` coverage improved from 10% to 62%.
2. **Console Noise:** Removed a leftover `console.log` in `tests/watchHistory/watch-history-telemetry.test.mjs`.
## Static Analysis Findings
* **Time Dependency:** Extensive use of `setTimeout` found in `tests/nostr/client.test.mjs`, `tests/moderation/video-card.test.mjs`, and others. These are potential sources of flakiness.
* **Skipped Tests:** `tests/nostr/sessionActor.test.mjs` skips a test when WebCrypto is unavailable.
* **Network Calls:** No unmocked external network calls detected in unit tests (mocks appear to be used).
## Recommendations
1. **Prioritize Webtorrent Tests:** Add unit tests for `js/webtorrent.js` to cover the torrent client wrapper logic.
2. **Moderation Coverage:** Expand `tests/user-blocks.test.mjs` (if it exists) or create it to cover `js/userBlocks.js`.
3. **Refactor Timeouts:** Replace `await new Promise(r => setTimeout(r, N))` with deterministic `waitFor` helpers in `tests/nostr/client.test.mjs` to reduce flakiness risk.
+27 -48
View File
@@ -2,6 +2,7 @@
import "./test-helpers/setup-localstorage.mjs";
import assert from "node:assert/strict";
import { test, describe, beforeEach } from "node:test";
import AuthService from "../js/services/authService.js";
import {
@@ -70,8 +71,10 @@ function resetState() {
}
}
await (async () => {
resetState();
describe("AuthService", () => {
beforeEach(resetState);
test("applyPostLoginState success flow", async () => {
setPubkey(SAMPLE_PUBKEY);
const calls = [];
@@ -115,10 +118,9 @@ await (async () => {
assert.equal(detail.blocksLoaded, true);
assert.equal(detail.relaysLoaded, true);
assert.deepEqual(detail.profile, { name: "Test User" });
})();
});
await (async () => {
resetState();
test("applyPostLoginState with deferBlocks: true", async () => {
setPubkey(SAMPLE_PUBKEY);
const calls = [];
@@ -166,10 +168,9 @@ await (async () => {
assert.equal(result.detail.blocksLoaded, null);
assert.equal(result.detail.relaysLoaded, true);
})();
});
await (async () => {
resetState();
test("applyPostLoginState partial failure", async () => {
setPubkey(SAMPLE_PUBKEY);
const logs = [];
@@ -211,11 +212,9 @@ await (async () => {
assert(logs.some(({ message }) => message.includes("block list")));
assert(logs.some(({ message }) => message.includes("relay list")));
assert(logs.some(({ message }) => message.includes("own profile")));
})();
await (async () => {
resetState();
});
test("applyPostLoginState without pubkey", async () => {
const service = new AuthService();
const result = service.applyPostLoginState();
const detail = result.detail;
@@ -235,11 +234,9 @@ await (async () => {
lud06: "",
},
});
})();
await (async () => {
resetState();
});
test("login mocks postLogin flow", async () => {
const service = new AuthService();
const postLogin = {
pubkey: SAMPLE_PUBKEY,
@@ -259,11 +256,9 @@ await (async () => {
assert.equal(detail.postLogin, postLogin);
assert.deepEqual(detail.postLogin, postLogin);
})();
await (async () => {
resetState();
});
test("login fails on lockdown", async () => {
const adminCheckCalls = [];
const service = new AuthService({
accessControl: {
@@ -288,11 +283,9 @@ await (async () => {
assert.equal(adminCheckCalls.length, 1);
assert.equal(typeof adminCheckCalls[0], "string");
assert(adminCheckCalls[0].length > 0);
})();
await (async () => {
resetState();
});
test("login succeeds for admin on lockdown", async () => {
const service = new AuthService({
accessControl: {
isLockdownActive: () => true,
@@ -304,16 +297,12 @@ await (async () => {
assert.ok(detail);
assert.equal(detail.pubkey, SAMPLE_PUBKEY);
})();
});
// === Tests for loadOwnProfile logic ===
await (async () => {
resetState();
describe("loadOwnProfile", () => {
const PUBKEY = SAMPLE_PUBKEY;
// Test Fast Relay Success
{
test("Fast Relay Success", async () => {
const mockNostrClient = {
relays: ["wss://fast1.com", "wss://fast2.com", "wss://slow.com"],
pool: {
@@ -333,21 +322,11 @@ await (async () => {
};
const service = new AuthService({ nostrClient: mockNostrClient });
// Override setProfileCacheEntry to avoid side effects or errors from real implementation if not needed,
// but here we just let it run. However, the service needs nostrClient.pool
// We need to make sure setProfileCacheEntry doesn't fail.
// It imports from cache.js which uses profileCache.
// profileCache is imported from state/profileCache.js.
// The previous tests didn't seem to mock setProfileCacheEntry.
const profile = await service.loadOwnProfile(PUBKEY);
assert.equal(profile.name, "Fast User");
}
});
// Test All Relays Fail
{
test("All Relays Fail", async () => {
const mockNostrClient = {
relays: ["wss://fail1.com", "wss://fail2.com"],
pool: {
@@ -361,10 +340,9 @@ await (async () => {
const service = new AuthService({ nostrClient: mockNostrClient });
const profile = await service.loadOwnProfile(PUBKEY);
assert.equal(profile.name, "Unknown");
}
});
// Test Timeout Fallback
{
test("Timeout Fallback", async () => {
let backgroundResolve;
const backgroundPromise = new Promise(r => backgroundResolve = r);
@@ -398,5 +376,6 @@ await (async () => {
// We resolve background promise to let background logic finish eventually (though test finishes here)
backgroundResolve();
}
})();
});
});
});
@@ -221,4 +221,3 @@ await testPreparePlaybackLoggingPublishesOnce();
await testPreparePlaybackLoggingIgnoresMetadata();
await testCancelPlaybackLoggingFlushes();
console.log("watch-history-telemetry tests passed");