Files

69 lines
2.2 KiB
TypeScript

import { describe, it, expect } from 'vitest'
// Pure helpers extracted (conceptually) from dashboard logic — tested here as standalone functions
function computeCapaOnTimeRate(
capas: Array<{ due_date: string; completed_at: string | null; verified_at: string | null }>
): number | null {
if (capas.length === 0) return null
const onTime = capas.filter(c => {
const due = new Date(c.due_date)
const done = c.verified_at
? new Date(c.verified_at)
: c.completed_at
? new Date(c.completed_at)
: null
return done !== null && done <= due
})
return Math.round((onTime.length / capas.length) * 100)
}
function classifyIndicators(incidents: Array<{ incident_type: string }>) {
const leading = incidents.filter(i => ['hazard', 'near_miss'].includes(i.incident_type)).length
const lagging = incidents.filter(i => i.incident_type === 'injury').length
return { leading, lagging }
}
describe('CAPA on-time rate', () => {
it('returns null for empty list', () => {
expect(computeCapaOnTimeRate([])).toBeNull()
})
it('returns 100% when all CAPAs completed on time', () => {
const capas = [
{ due_date: '2026-07-10', completed_at: '2026-07-09', verified_at: null },
{ due_date: '2026-07-10', completed_at: null, verified_at: '2026-07-08' },
]
expect(computeCapaOnTimeRate(capas)).toBe(100)
})
it('returns 50% when half are late', () => {
const capas = [
{ due_date: '2026-07-10', completed_at: '2026-07-09', verified_at: null },
{ due_date: '2026-07-10', completed_at: '2026-07-12', verified_at: null },
]
expect(computeCapaOnTimeRate(capas)).toBe(50)
})
it('returns 0% when all CAPAs are overdue', () => {
const capas = [
{ due_date: '2026-07-10', completed_at: '2026-07-15', verified_at: null },
]
expect(computeCapaOnTimeRate(capas)).toBe(0)
})
})
describe('leading vs lagging indicators', () => {
it('counts hazard and near_miss as leading', () => {
const incidents = [
{ incident_type: 'hazard' },
{ incident_type: 'near_miss' },
{ incident_type: 'injury' },
{ incident_type: 'fire' },
]
const { leading, lagging } = classifyIndicators(incidents)
expect(leading).toBe(2)
expect(lagging).toBe(1)
})
})