[Testing 09] test: unit-cover the highest-risk backend libs + raise the coverage ratchet

✅ merged · #237 · open-legal-products/mike ← amal66/mike · opened 3mo ago by amal66 · merged 3mo ago by willchen96 · +5,420-214 across 19 files · ↗ on GitHub

From the PR description

Summary

Follow-up to #229: adds six unit suites (102 new tests, 165 total) for the highest-risk untested backend libs, raises the coverage ratchet floors to match, and adds docs/testing-coverage.md - a prioritized, checkbox-style backlog so any contributor can pick up the next lib.

Changes

New suites in backend/src/lib/__tests__/, following the existing in-memory Supabase mock conventions:

  • userDataCleanup.test.ts (11 tests) - destructive account/project deletes: cascade order, ownership scoping (requesting another user's project deletes nothing of theirs), shared_with email scrubbing, storage-file cleanup, best-effort prefix cleanup, error propagation.
  • documentVersions.test.ts (15) - document integrity: active-version resolution, cross-document versionId spoof guard, soft-delete filtering, Untitled document fallbacks, max assistant_edit version numbers.
  • citations.test.ts (28) - legal-citation parsing: CITATIONS block diagnostics, document + case citation normalization (marker refs, page ranges, quote limits, sheet/cell locators, opinion metadata), the streaming partial-object parser (escapes, braces-in-strings, close-tag handling), and citation payload assembly.
  • safeError.test.ts (21) - secret redaction: provider key patterns (sk-, sk-ant-, AIza), labeled secrets, the OpenAI "Incorrect API key provided" message, and safeErrorMessage/safeErrorLog fallbacks.
  • llmModels.test.ts (11) - provider inference and model-id resolution across the full catalog; asserts every default model is resolvable.
  • userLookup.test.ts (16) - email normalization, profile indexing, missing-email detection, and syncProfileEmail insert/no-op/update paths.

Plus:

  • backend/vitest.config.mts - ratchet floors raised, comment updated, links the roadmap doc.
  • docs/testing-coverage.md - how to run coverage, per-area status table, prioritized TODO checklist (each with a what-to-test hint and S/M size), and the ratchet policy.

Why

These libs were chosen by risk, not by ease: userDataCleanup performs irreversible bulk deletes, documentVersions gates every read-from-storage path, citations is the core legal-citation product surface, safeError prevents API-key leakage into responses/logs, and models/userLookup sit on every request path. All were at 0% coverage.

Coverage (global over backend/src/lib/**):

Metric Before After New floor
Statements 2.58% 11.18% 11
Branches 2.00% 10.98% 10
Functions 4.61% 14.43% 14
Lines 2.58% 10.91% 10

The remaining untested libs are enumerated in docs/testing-coverage.md as a checkbox backlog, so contributors can take one checkbox per PR and keep ratcheting the floors up.

Testing

  • npm test - 11 files, 165 tests, all green.
  • npm run test:coverage - passes the new 11/10/14/10 floors.
  • npm run build - clean (test files stay excluded from tsc).

Note: this branch stacks on #229 (it includes the #228 + #229 commits - please review the top commit only; I'll Graphite-restack once write access allows).

🤖 Generated with Claude Code

Our analysis

Add coverage for critical backend libraries — read the full analysis →

Think the analysis missed something the PR description covers?

Commits in this PR (3)

SHA Subject Author Date
4039b949 test: minimal vitest harness for backend and frontend QA Runner 2026-07-20 ↗ GitHub
commit body
Ported from amal66/mike#24 onto current main; lockfiles regenerated against
this tree. Adds vitest as a dev dependency with a `test` script in both
packages, excludes test files from the backend tsc build, and seeds one
suite per package (backend: downloadTokens, 12 tests; frontend: cn() utils,
8 tests). Verified locally: backend 12/12, frontend 8/8 passing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
c139acc3 test: unit tests for access, storage, userApiKeys, chat doc resolution QA Runner 2026-07-20 ↗ GitHub
commit body
Ported from the amal66 fork (see index Open-Legal-Products/mike#205)
onto current main, adapted to this repo's backend/ layout
(apps/api/src/lib -> backend/src/lib), plus a v8 coverage ratchet.

Suites ported (51 new tests, verified locally):
- access.test.ts (7): owner/shared/private project access, doc access,
  review sharing, document-ID filtering. Dropped the fork's "org RBAC"
  describe block (7 cases) - org_id/org_members multi-tenancy and the
  role/canManage fields do not exist in this repo's access.ts.
- storage.test.ts (25): filename normalization/sanitization, RFC 5987
  encoding, Content-Disposition, storage key helpers. Dropped the fork's
  vi.mock of lib/env - this repo has no env module; storage reads
  process.env directly and the tested helpers are pure.
- userApiKeys.test.ts (10): normalizeApiKeyProvider + hasEnvApiKey.
  Added a beforeEach env clear so shell-exported API keys can't leak
  into assertions.
- chatTypes.test.ts (9): resolveDoc/resolveDocLabel, which live in
  lib/chat/types.ts here (the fork's lib/chatTools.ts equivalent).
  Dropped generateSpotlightNonce cases (2) - no such export here.

Suites dropped entirely (subject not present in this repo):
- upload.test.ts - tested hasMagicBytes; this repo's lib/upload.ts is
  only the multer middleware and exports no magic-byte checker.
- userSettings.test.ts - tested resolveTabularModel (fork-only keyed-
  provider fallback); this repo resolves tabular_model via
  resolveModel with a static default.

Coverage ratchet: vitest.config.mts adds v8 coverage over src/lib/**
with floors measured against this tree (2.58% stmts, 2.00% branches,
4.61% funcs, 2.58% lines -> floors 2/2/4/2). Full suite: 5 files,
63 tests passing (incl. the pre-existing 12 in downloadTokens.test.ts);
npm run test:coverage and npm run build both pass.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2053ca15 test: cover critical backend libs, raise coverage ratchet, add roadmap QA Runner 2026-07-20 ↗ GitHub
commit body
Six new unit suites (102 tests) for the highest-risk untested libs:
userDataCleanup (destructive account/project deletes), documentVersions
(document integrity), chat/citations (legal-citation parsing), safeError
(secret redaction), llm/models (model resolution), and userLookup
(profile email sync). Coverage floors ratchet up 2/2/4/2 ->
11/10/14/10 (measured 11.18/10.98/14.43/10.91), and
docs/testing-coverage.md gives contributors a prioritized backlog for
the remaining untested libs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Capture this PR into my fork

Download a Markdown prompt that tells Claude how to port every commit in this PR into your working tree. Run it via claude -p < capture-pull-237.md from inside the repo you want the changes in.

⬇ Download capture-pull-237.md