test(api): Reports + admin export — fill gaps + lifecycle test
Drives the report/export parts of src/routes/admin.ts to 100% stmts/branch/funcs/lines. Adds one lifecycle test plus gap tests for the previously-uncovered branches; no production behavior changed. Tests added (apps/api/test): - report.test.ts: invalid insole_type / non-numeric activity_id → 400; activity filter narrows; null insole_type bucketed "Onbekend"; null duration counts as 0 worked; export 400 on missing/inverted range. Migrated the report + export describes to resetDb(beforeEach) so exact totals are order-independent (removed the activity_id isolation workaround in the all-users export test). - integration/report-aggregation.test.ts: lifecycle — 2 workers × 2 activities × 2 types → exact totals + every by_worker/by_activity/ by_type row (values and worked-desc order) → user_id filter narrows. Defensive annotations in admin.ts report loop (behavior unchanged): - pausedSeconds/pairCount ?? 0 — NOT NULL columns, DB-impossible nulls. - user_name/activity_name ?? 'Onbekend' — unreachable; userId FK cascades on delete and activityId FK is enforced (libsql enforces FKs), so every session always joins to a real user and activity. No bugs found; the code was already correct.
This commit is contained in:
@@ -152,6 +152,7 @@ adminRoutes.get('/api/admin/report', async (c) => {
|
||||
|
||||
for (const r of rows) {
|
||||
const worked = r.session.durationSeconds ?? 0;
|
||||
/* c8 ignore next 2 -- pausedSeconds & pairCount are NOT NULL (schema defaults); the ?? guards DB-impossible nulls */
|
||||
const paused = r.session.pausedSeconds ?? 0;
|
||||
const pairs = r.session.pairCount ?? 0;
|
||||
|
||||
@@ -163,6 +164,7 @@ adminRoutes.get('/api/admin/report', async (c) => {
|
||||
const uid = r.session.userId;
|
||||
const w = workers.get(uid) ?? {
|
||||
user_id: uid,
|
||||
/* c8 ignore next -- userId FK cascades on user delete, so a session's user always joins */
|
||||
user_name: r.userName ?? 'Onbekend',
|
||||
worked_seconds: 0,
|
||||
paused_seconds: 0,
|
||||
@@ -178,6 +180,7 @@ adminRoutes.get('/api/admin/report', async (c) => {
|
||||
const aid = r.session.activityId;
|
||||
const a = acts.get(aid) ?? {
|
||||
activity_id: aid,
|
||||
/* c8 ignore next -- activityId FK is enforced, so a session's activity always joins */
|
||||
activity_name: r.activityName ?? 'Onbekend',
|
||||
worked_seconds: 0,
|
||||
paused_seconds: 0,
|
||||
|
||||
Reference in New Issue
Block a user