test(api): Work-sessions — fill gaps + lifecycle test

Drives src/routes/sessions.ts and src/lib/work-session.ts to 100%
stmts/branch/funcs/lines (branch was 84.12% / 83.33%).

- sessions.test.ts: added error/edge branch tests — malformed-JSON start
  (400), non-numeric id on pause/resume/stop/discard (404), pause/resume of a
  no-longer-active session (409), discard missing (404) + already-closed (409),
  stop missing (404), and discard ownership scoping (user B → 404).
- work-session.test.ts: mapper unit tests — null insoleType, nullish
  pausedSeconds → 0, null durationSeconds/notes, full-field shape with
  activity/user opts, and opts defaulting to undefined.
- test/integration/worker-session-lifecycle.test.ts: the anchor lifecycle test
  (start→pause→resume→stop→history→export).

No bugs found — the code was correct. The two remaining uncovered branches were
the defensive `row.pausedSeconds ?? 0` guards in resume/stop; pausedSeconds is
NOT NULL DEFAULT 0 in the schema, so the null branch is unreachable via any
route. Annotated both with `/* c8 ignore next -- reason */` (comment only, no
behavior change).
This commit is contained in:
Bas van Rossem
2026-07-22 12:14:32 +02:00
parent af7251398c
commit 9ecbf952d3
5 changed files with 319 additions and 0 deletions

View File

@@ -136,6 +136,7 @@ sessionsRoutes.post('/api/sessions/:id/resume', async (c) => {
if (!row.pausedAt) return c.json({ error: 'Not paused' }, 409);
const pausedSeconds =
/* c8 ignore next -- pausedSeconds is NOT NULL (default 0) in schema; ?? 0 is a defensive guard */
(row.pausedSeconds ?? 0) + Math.round((Date.now() - new Date(row.pausedAt).getTime()) / 1000);
const [updated] = await db
@@ -164,6 +165,7 @@ sessionsRoutes.post('/api/sessions/:id/stop', async (c) => {
const extraPaused = row.pausedAt
? Math.round((now - new Date(row.pausedAt).getTime()) / 1000)
: 0;
/* c8 ignore next -- pausedSeconds is NOT NULL (default 0) in schema; ?? 0 is a defensive guard */
const pausedSeconds = (row.pausedSeconds ?? 0) + extraPaused;
const endTime = new Date(now);
const wall = Math.round((now - new Date(row.startTime).getTime()) / 1000);