Problem
- No integration tests — No test exercises a full HTTP round-trip (client → Flask route → parser → JSON response). Critical endpoints are unverified at the boundary.
- Frontend JS untested — Nine ES modules under
static/js/ (router, route handlers, shared utils) have no programmatic tests; Week 20 module extraction is only manually verified.
- Search crash regression risk — The
limit=abc misuse case (Monday fix) needs an integration-level guard, not only tests/test_search.py.
- No coverage gate on API layer — Parser utilities have ~2,500 lines of tests;
api/ blueprints and CLI wiring have almost none.
Eval cluster: verification-gap (test 30 — Test Presence).
Scope (one PR)
Phase 1 — Fixtures
tests/fixtures/session_minimal.jsonl — minimal messages, no tool calls
tests/fixtures/session_with_tools.jsonl — at least one tool-call path
- Optional:
session_with_thinking.jsonl
- Shared
client fixture: create_app(base_dir=tmp_path) with copied fixtures under projects/test-project/
Phase 2 — Python API integration tests
New tests/test_api_integration.py — ≥5 scenarios, target ~10:
| Endpoint |
Scenarios |
GET /api/projects |
Happy path (non-empty list); empty base dir → [] |
GET /api/sessions/<project_id> |
List sessions for project; unknown project (200 empty or 404 — assert actual behavior) |
GET /api/sessions/<project_id>/<session_id> |
Happy path (messages or session_id in body); 404 + {"error": "..."} |
GET /api/search |
Results for q=Hello; empty q= → []; limit=abc → 400 (Monday regression); valid limit=5 caps results |
Reuse error-shape helper; leave commented stub for Wednesday "code" field.
Phase 3–4 — Frontend JS tests
package.json + vitest.config.js (environment: 'jsdom')
- Dev deps:
vitest, jsdom, @vitest/coverage-v8
- Tests:
static/js/utils.test.js, markdown.test.js, state.test.js
- Add
export to testable functions only — no signature/behavior changes
- XSS stub on markdown: assert
<script> is not emitted when DOMPurify path exists
Slip if overloaded: Phases 3–4 may land as a follow-up commit on the same PR; Phase 2 + fixtures are non-negotiable for merge.
Phase 5 — Coverage + CI
requirements-dev.txt: pytest-cov>=5.0
pyproject.toml: [tool.pytest.ini_options] with --cov=api --cov=utils --cov=models
.github/workflows/ci.yml:
integration-tests job — pytest tests/test_api_integration.py + coverage artifact
js-tests job — npm ci + npm test (omit if JS deferred; document in PR)
Acceptance criteria
Out of scope
- Structured
ErrorCode enum on error responses (Wednesday, 3 pt)
- Full HTTP route matrix for every blueprint + CLI export script (Wednesday, 5 pt — issue
fab633e4-4f9d-56b4-97d4-cfc84b5bbdd7)
- Playwright / Selenium / browser E2E
- API reference or
CONTRIBUTING.md (Thursday)
- Changes to production JSON response shapes
Problem
static/js/(router, route handlers, shared utils) have no programmatic tests; Week 20 module extraction is only manually verified.limit=abcmisuse case (Monday fix) needs an integration-level guard, not onlytests/test_search.py.api/blueprints and CLI wiring have almost none.Eval cluster: verification-gap (test 30 — Test Presence).
Scope (one PR)
Phase 1 — Fixtures
tests/fixtures/session_minimal.jsonl— minimal messages, no tool callstests/fixtures/session_with_tools.jsonl— at least one tool-call pathsession_with_thinking.jsonlclientfixture:create_app(base_dir=tmp_path)with copied fixtures underprojects/test-project/Phase 2 — Python API integration tests
New
tests/test_api_integration.py— ≥5 scenarios, target ~10:GET /api/projects[]GET /api/sessions/<project_id>GET /api/sessions/<project_id>/<session_id>messagesorsession_idin body); 404 +{"error": "..."}GET /api/searchq=Hello; emptyq=→[];limit=abc→ 400 (Monday regression); validlimit=5caps resultsReuse error-shape helper; leave commented stub for Wednesday
"code"field.Phase 3–4 — Frontend JS tests
package.json+vitest.config.js(environment: 'jsdom')vitest,jsdom,@vitest/coverage-v8static/js/utils.test.js,markdown.test.js,state.test.jsexportto testable functions only — no signature/behavior changes<script>is not emitted when DOMPurify path existsSlip if overloaded: Phases 3–4 may land as a follow-up commit on the same PR; Phase 2 + fixtures are non-negotiable for merge.
Phase 5 — Coverage + CI
requirements-dev.txt:pytest-cov>=5.0pyproject.toml:[tool.pytest.ini_options]with--cov=api --cov=utils --cov=models.github/workflows/ci.yml:integration-testsjob —pytest tests/test_api_integration.py+ coverage artifactjs-testsjob —npm ci+npm test(omit if JS deferred; document in PR)Acceptance criteria
/api/projects,/api/sessions/<id>,/api/searchGET /api/search?q=test&limit=abcreturns 400 with JSONerrorkey (not 500)utils.js,markdown.js,state.jsapi/+models/(or documented gap + follow-up)Out of scope
ErrorCodeenum on error responses (Wednesday, 3 pt)fab633e4-4f9d-56b4-97d4-cfc84b5bbdd7)CONTRIBUTING.md(Thursday)