# Testing **Mobile flows:** before merging any PR that touches file input, navigation, or wallet connection, check [`docs/mobile-restrictions.md`](mobile-restrictions.md). ## Running tests ```sh # Server (from repo root) npm test # PWA cd pwa && npx vitest run # With coverage npm test -- --coverage cd pwa && npx vitest run --coverage ``` ## Coverage thresholds Both suites enforce 85% globally across statements, branches, functions, and lines. CI exits non-zero if any threshold is missed. ### Server (`vitest.config.ts`) | File | Threshold | |---|---| | indexer/vote-queue.ts | 90% lines + functions | | indexer/address-registry.ts | 90% lines + functions | | indexer/attestation.ts | 90% lines + functions | | indexer/payment-request.ts | 90% lines + functions | | types/lexicons.ts | excluded — pure interface declarations, no executable JS | | indexer/index.ts | excluded — orchestrates live infra, integration-tested only | | src/main.ts | excluded — entrypoint | ### PWA (`pwa/vitest.config.ts`) | File | Threshold | |---|---| | src/lib/atprotoOauthUtils.ts | 95% lines + branches + functions | | src/hooks/useWalletAddress.ts | 95% lines + branches + functions | | src/lib/attestation.ts | 90% lines + functions, 85% branches | | src/hooks/useWalletSession.ts | 90% lines + functions, 85% branches | | src/hooks/useMallbucksWalletClient.ts | 85% lines + functions, 80% branches | | src/lib/wallet.ts | 80% lines + functions, 75% branches | | src/lib/walletSession.ts | 80% lines + functions, 75% branches | | src/lib/idb.ts | 80% lines, 70% functions, 50% branches | | src/hooks/useMallbucksSmartAccountClient.ts | excluded — ZeroDev + WASM, crashes worker threads | ## Current coverage (as of commit 2a77ddd) ### Server | File | Stmts | Branch | Funcs | Lines | |---|---|---|---|---| | indexer/address-registry.ts | 100% | 100% | 100% | 100% | | indexer/atproto-writer.ts | 100% | 100% | 100% | 100% | | indexer/attestation.ts | 100% | 87.5% | 100% | 100% | | indexer/monad-watcher.ts | 100% | 100% | 100% | 100% | | indexer/payment-request.ts | 100% | 100% | 100% | 100% | | indexer/vote-queue.ts | 100% | 100% | 100% | 100% | | server/index.ts | 78.73% | 90.18% | 92.15% | 78.73% | | **All files** | **85.87%** | **92.87%** | **95.78%** | **85.87%** | ### PWA | Metric | Coverage | |---|---| | Statements | 93.52% (1011/1081) | | Branches | 85.00% (663/780) | | Functions | 92.3% (264/286) | | Lines | 97.38% (931/956) | ## Known uncoverable branches These branches exist in the source but cannot be reached in the test environment: - `DashboardPage.tsx` lines 324, 331-332: `dir: "in"` rows (ReceiveIcon, "+" prefix) — `fetchActivity` never produces `dir: "in"` entries; dead code. - `SearchPage.tsx` line 163: `setVisibleCount` inside an IntersectionObserver callback — jsdom never triggers intersection events. - `idb.ts` lines 9-10: `if (!req.result.objectStoreNames.contains(STORE))` — requires the IDB store to already exist on a second open; not controllable in jsdom.