10 KiB
Design: Test Coverage & Documentation Improvements
Date: 2026-03-22 Source: docs/tech_lead_assessment_Coverage_Documentation.md Scope: 5 improvements — frontend page tests, frontend JSDoc, backend test gaps, E2E tests
Context
The tech lead assessment graded the backend A (332 unit + 145 integration tests, good documentation) and the frontend C (103 utility/API tests only, weak documentation). Every page and component has zero test coverage. This design addresses all 5 recommendations from the assessment.
1. Frontend Component/Page Tests
Goal
Add interaction-level tests for the 5 most critical pages using @solidjs/testing-library + Vitest + MSW.
Test Infrastructure
- MSW (Mock Service Worker) to intercept fetch calls in tests
- Shared
test-utils.tswith arenderWithProviders()helper that wraps components in AuthContext, I18nProvider, ToastProvider, and Router - Mocked Turnstile — stub
window.turnstilein test setup - Mocked EventSource — stub for SSE tests in GenerateSynthesis
Pages and Tests (~39 tests)
Settings.tsx (~10 tests)
- Renders form with all fields populated from API response
- Save button calls PUT /settings with form data
- Provider dropdown populated from config API
- Selecting provider updates model dropdown options
- Dual model dropdowns render (research + writing)
- Rate limit section renders with null values (empty inputs)
- Rate limit section shows effective rate when values set
- Reset link clears rate limit fields to null
- Export downloads JSON file
- Import populates form from uploaded JSON
Home.tsx (~7 tests)
- Renders synthesis list from API response
- Empty state shows when no syntheses
- "Nouvelle Synthese" button links to /generate
- Delete first click shows "Confirmer" state
- Delete second click removes synthesis from list
- Delete auto-cancels after 3 seconds
- In-progress banner shows when a synthesis has status "in_progress"
Sources.tsx (~8 tests)
- Renders source list from API response
- Empty state shows when no sources
- Add form validates empty title/URL
- Add form submits and new source appears in list
- Delete with confirmation removes source
- Bulk import textarea parses and imports
- CSV export triggers download
- CSV import triggers file picker
Login.tsx + Register.tsx (~8 tests)
- Login renders email input and submit button
- Login submit calls POST /auth/login
- Login shows "check inbox" message on success
- Login shows error on API failure
- Resend button disabled during cooldown
- Register renders email + display name + submit
- Register submit calls POST /auth/register
- Register shows confirmation on success
GenerateSynthesis.tsx (~6 tests)
- Renders launch button with settings info
- Launch button calls POST /syntheses/generate
- Progress bar updates from SSE events
- Step checklist shows done/in-progress/pending states
- Completion redirects to synthesis detail
- Error state shows retry button
Dependencies to Add
msw(dev dependency) for API mocking- No other new dependencies needed (
@solidjs/testing-libraryalready installed)
2. Frontend JSDoc Documentation
Goal
Add English JSDoc comments to all exported components, functions, and complex logic blocks. No code changes.
Scope
API Layer
api/client.ts— class purpose, CSRF strategy (X-Requested-With), credential handling (same-origin), 401 redirect behaviorapi/auth.ts,api/settings.ts,api/sources.ts,api/syntheses.ts,api/admin.ts,api/config.ts,api/apiKeys.ts— brief JSDoc on each exported function
Pages (complex logic)
pages/Settings.tsx— export/import logic, provider auto-detection, rate limit null handling, dual model state managementpages/GenerateSynthesis.tsx— SSE state machine (idle -> connecting -> progress -> complete/error), step progression, reconnection, completion redirect timerpages/Home.tsx— delete confirmation timer pattern (first click -> confirm state -> 3s auto-cancel)pages/Sources.tsx— bulk import parsing, CSV import/export flow, URL normalizationpages/SynthesisDetail.tsx— email send flow, file download mechanism (Blob + anchor)pages/Login.tsx,pages/Register.tsx— Turnstile lifecycle, resend cooldown timerpages/AuthVerify.tsx— token extraction from URL, verification flow
Components
components/ApiKeyManager.tsx— key CRUD flow, show/hide toggle, test buttoncomponents/Turnstile.tsx— widget lifecycle, polling initialization, cleanupcomponents/Navbar.tsx— active route detection, admin link visibilitycomponents/MobileMenu.tsx— escape key handler, backdrop clickcomponents/Layout.tsx,components/AdminLayout.tsx— layout structure, sidebar navcomponents/ErrorBoundary.tsx— error catching, retry mechanismcomponents/ui/Button.tsx— props interface, variant behavior (primary/secondary/danger)components/ui/Toast.tsx— toast provider pattern, auto-dismiss timercomponents/ui/LoadingSpinner.tsx— size/fullPage props
Utilities
utils/sse.ts— reconnection backoff logic (exponential, max 3 retries), event type parsing, cleanuputils/dates.ts— date-fns locale configurationutils/providers.ts— provider capability detection
Context
contexts/AuthContext.tsx— session check on mount, 401 handling, isAdmin derived signal
Style
- Brief
/** ... */on exports - Inline
//comments only for non-obvious logic (state machines, timers, edge cases) - No boilerplate comments on trivial code (simple getters, obvious props)
3. Backend Test Gaps
3a. Schema Builder Tests (services/llm/schema.rs) — 6 tests
test_schema_single_category— 1 category producescategory_0with correct item schematest_schema_five_categories— 5 categories producecategory_0throughcategory_4test_schema_twenty_categories— max 20 categories all presenttest_schema_special_characters— category names with accents, quotes, ampersands don't break JSONtest_schema_long_category_name— 200-char category name acceptedtest_schema_item_structure— each category value is array of{title: string, url: string, summary: string}
3b. Auth Middleware Unit Tests (middleware/auth.rs) — 5 tests
test_valid_session_cookie_extracted— properly formatted cookie returns tokentest_malformed_cookie_no_equals— cookie without=returns Nonetest_missing_cookie_header— no Cookie header returns Unauthorizedtest_multiple_cookies_correct_one_picked— session cookie found among other cookiestest_cookie_with_whitespace— leading/trailing whitespace trimmed
3c. Token Utility Tests (util/token.rs) — 4 tests
test_generated_token_length— base64url-encoded token has expected lengthtest_tokens_are_unique— two consecutive generated tokens differtest_hash_is_deterministic— same input produces same hashtest_hash_differs_from_raw— hash output is not the raw token
Total: 15 new backend unit tests, bringing count from 332 to ~347.
4. E2E Tests with Playwright
Infrastructure
e2e/docker-compose.test.yml:
- Extends main
docker-compose.yml - Uses a test-specific Postgres database (fresh per run)
- App service with
TEST_DATABASE_URLand test Turnstile/Resend keys - Exposes app on port 8080
e2e/seed.ts:
- Node.js script connecting directly to test Postgres
- Creates admin user (email_verified, role=admin) with a known session token
- Creates regular test user with a known session token
- Both sessions have 30-day expiry
e2e/helpers/auth.ts:
loginAsAdmin()— sets session cookie for adminloginAsUser()— sets session cookie for regular userregisterAndVerify(email)— inserts magic link token in DB, navigates to verify URL- Direct DB access via
pgnpm package for token extraction
e2e/playwright.config.ts:
- Base URL:
http://localhost:8080 - Timeout: 30s per test
- Retries: 1
- Screenshots on failure
Test Flows (5 specs)
registration.spec.ts
- Navigate to /register
- Fill email, submit (Turnstile bypassed via test key)
- Extract magic link token from DB
- Navigate to /auth/verify?token=...
- Assert: redirected to Home, user email shown in navbar
admin-providers.spec.ts
- Login as admin (cookie injection)
- Navigate to /admin/providers
- Enable Gemini provider, add a model
- Save
- Assert: provider appears in GET /config/providers response
settings.spec.ts
- Login as user
- Navigate to /settings
- Change theme, select provider + models, save
- Reload page
- Assert: all saved values repopulated
sources.spec.ts
- Login as user
- Navigate to /sources
- Add a source (title + URL)
- Bulk import 3 sources
- Assert: 4 sources in list
- Delete one
- Assert: 3 sources remain
- Export CSV
- Assert: downloaded file contains 3 rows
settings-export.spec.ts
- Login as user
- Configure settings (theme, categories, models)
- Export JSON
- Change settings to different values, save
- Import the exported JSON
- Save
- Reload
- Assert: original values restored
File Structure
e2e/
├── playwright.config.ts
├── docker-compose.test.yml
├── package.json — playwright, pg dependencies
├── seed.ts
├── helpers/
│ └── auth.ts
└── tests/
├── registration.spec.ts
├── admin-providers.spec.ts
├── settings.spec.ts
├── sources.spec.ts
└── settings-export.spec.ts
Summary
| Section | New Tests | New Docs | Effort |
|---|---|---|---|
| Frontend page tests | ~39 | — | Large |
| Frontend JSDoc | — | ~30 files | Medium |
| Backend test gaps | ~15 | — | Small |
| E2E tests | ~5 flows | — | Large |
| Total | ~59 tests + 5 E2E flows | ~30 files documented |
Implementation Order
- Backend test gaps (small, independent, quick win)
- Frontend JSDoc (no code changes, can't break anything)
- Frontend page tests (requires MSW setup first, then tests)
- E2E tests (requires Docker test infrastructure, depends on everything else working)