Files
jayjennings 61c876edec
CI / Lint, typecheck, test, build (push) Canceled after 0s
CI / End-to-end tests (push) Canceled after 0s
Add OSHA Form 301 and Osha page components
- Implemented Form301 component for displaying OSHA Form 301 equivalent, including employee and case information.
- Created Osha component to manage OSHA recordkeeping, including tabs for 300 Log, 300A Summary, Hours & rates, and Submit to OSHA.
- Added functionality for printing and downloading CSV files for OSHA submissions.
- Integrated loading and error handling states for data fetching.
2026-10-06 13:09:57 -07:00

50 lines
2.6 KiB
TypeScript

import { afterAll, beforeAll, describe, expect, it } from 'vitest'
import { createTestContext, daysFromToday, hoursAgo } from '../test/helpers.ts'
let ctx: Awaited<ReturnType<typeof createTestContext>>
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)
})
})