import { afterAll, beforeAll, describe, expect, it } from 'vitest' import { createTestContext, daysFromToday, hoursAgo } from '../test/helpers.ts' let ctx: Awaited> beforeAll(async () => { ctx = await createTestContext() }) afterAll(() => ctx.close()) describe('stats', () => { it('summarises the dashboard from real data', async () => { const north = await ctx.createSite('North') await ctx.createSite('South') const supervisor = await ctx.createUser('supervisor') const report = (title: string, severity = 'medium', type = 'hazard') => supervisor.post('/api/incidents', { title, type, severity, occurredAt: hoursAgo(3), siteId: north.id }).then((r) => r.body.incident.number as number) const a = await report('A', 'low') await report('B', 'high', 'injury') await supervisor.post(`/api/incidents/${a}/transitions`, { to: 'triage' }) await supervisor.post(`/api/incidents/${a}/transitions`, { to: 'closed' }) const c = await report('C') await supervisor.post(`/api/incidents/${c}/actions`, { title: 'Overdue', assigneeId: supervisor.user.id, dueDate: daysFromToday(-1) }) await supervisor.post(`/api/incidents/${c}/actions`, { title: 'This week', assigneeId: supervisor.user.id, dueDate: daysFromToday(3) }) await supervisor.post(`/api/incidents/${c}/root-causes`, { category: 'equipment', description: 'Worn' }) const overview = (await supervisor.get('/api/stats/overview')).body expect(overview).toMatchObject({ openIncidents: 2, reportedLast7Days: 3, actionsDueThisWeek: 1, overdueActions: 1, actionProgress: { total: 2, completed: 0 } }) expect(overview.byStatus).toMatchObject({ reported: 2, closed: 1 }) expect(overview.averageCloseDays).toBeGreaterThanOrEqual(0) expect(overview.weeklyTrend).toHaveLength(12) expect(overview.weeklyTrend.at(-1).count).toBeGreaterThanOrEqual(1) expect(overview.bySite).toEqual([ { siteId: north.id, name: 'North', count: 3 }, { siteId: expect.any(String), name: 'South', count: 0 }, ]) const to = new Date().toISOString().slice(0, 10) const from = new Date(Date.now() - 29 * 86_400_000).toISOString().slice(0, 10) const analytics = (await supervisor.get(`/api/stats/analytics?from=${from}&to=${to}`)).body expect(analytics.kpis.reports.value).toBe(3) expect(analytics.byRootCause).toEqual([{ category: 'equipment', count: 1 }]) }) it("scopes a reporter's numbers to what they can see", async () => { const reporter = await ctx.createUser('reporter') expect((await reporter.get('/api/stats/overview')).body.openIncidents).toBe(0) }) })