import { describe, it, expect, beforeEach } from 'vitest'; import { eq } from 'drizzle-orm'; import { createApp } from '../../src/app'; import { db } from '../../src/db/client'; import { workSessions } from '../../src/db/schema'; import { authToken, bearer, seedActivity, resetDb } from '../helpers'; describe('worker session lifecycle (start→pause→resume→stop→history→export)', () => { beforeEach(resetDb); it('excludes paused time, shows in history, and exports a CSV row', async () => { const app = createApp(); const token = await authToken(app, 'lifecycle@example.com'); const activityId = await seedActivity('Frezen', ['Kurk']); // start const startRes = await app.request('/api/sessions/start', { method: 'POST', headers: bearer(token), body: JSON.stringify({ activity_id: activityId, insole_type: 'Kurk', pair_count: 3 }), }); expect(startRes.status).toBe(200); const started = await startRes.json(); // pause, then backdate the pause start by 4s so resume accumulates a real span await app.request(`/api/sessions/${started.id}/pause`, { method: 'POST', headers: bearer(token), }); await db .update(workSessions) .set({ pausedAt: new Date(Date.now() - 4000) }) .where(eq(workSessions.id, started.id)); const resumeRes = await app.request(`/api/sessions/${started.id}/resume`, { method: 'POST', headers: bearer(token), }); expect((await resumeRes.json()).paused_seconds).toBeGreaterThan(0); // backdate the start by 10s so worked-time is deterministic-ish, then stop await db .update(workSessions) .set({ startTime: new Date(Date.now() - 10000) }) .where(eq(workSessions.id, started.id)); const stopRes = await app.request(`/api/sessions/${started.id}/stop`, { method: 'POST', headers: bearer(token), }); const stopped = await stopRes.json(); expect(stopped.status).toBe('completed'); expect(stopped.paused_seconds).toBeGreaterThan(0); expect(stopped.duration_seconds).toBeLessThan(10); // paused time excluded const wall = Math.round((Date.parse(stopped.end_time) - Date.parse(stopped.start_time)) / 1000); expect(stopped.duration_seconds + stopped.paused_seconds).toBe(wall); // history shows it const hist = await (await app.request('/api/sessions', { headers: bearer(token) })).json(); expect(hist).toHaveLength(1); expect(hist[0].id).toBe(started.id); expect(hist[0].activity_name).toBe('Frezen'); // export contains the completed row const csvRes = await app.request('/api/export', { headers: bearer(token) }); expect(csvRes.status).toBe(200); const csv = await csvRes.text(); expect(csv).toContain('Frezen'); expect(csv.trim().split('\n').length).toBe(2); // header + 1 row }); });