Add 'transport' to INCIDENT_TYPES; add truck_id field to IncidentInput; reject transport submissions missing truck_id. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CPf5Rc8QPx6V8KLEEgfKEQ
109 lines
3.8 KiB
TypeScript
109 lines
3.8 KiB
TypeScript
import { describe, it, expect } from 'vitest'
|
|
import { validateIncidentInput, validateTypeDetails, type IncidentInput } from '@/lib/incidents/validate'
|
|
|
|
const valid: IncidentInput = {
|
|
zone_token: 'scw1-dock-a-qr-2026',
|
|
incident_type: 'near_miss',
|
|
description: 'Forklift nearly hit a pedestrian in Dock A aisle.',
|
|
injury_involved: false,
|
|
asset_involved: false,
|
|
}
|
|
|
|
describe('validateIncidentInput', () => {
|
|
it('accepts valid input', () => {
|
|
expect(validateIncidentInput(valid)).toEqual({ ok: true, errors: [] })
|
|
})
|
|
|
|
it('rejects missing zone_token', () => {
|
|
const result = validateIncidentInput({ ...valid, zone_token: '' })
|
|
expect(result.ok).toBe(false)
|
|
expect(result.errors).toContain('zone_token is required')
|
|
})
|
|
|
|
it('rejects description under 10 chars', () => {
|
|
const result = validateIncidentInput({ ...valid, description: 'Short' })
|
|
expect(result.ok).toBe(false)
|
|
expect(result.errors).toContain('description must be at least 10 characters')
|
|
})
|
|
|
|
it('requires medical_status when injury_involved is true', () => {
|
|
const result = validateIncidentInput({ ...valid, injury_involved: true })
|
|
expect(result.ok).toBe(false)
|
|
expect(result.errors).toContain('medical_status is required when injury is involved')
|
|
})
|
|
|
|
it('accepts injury with medical_status', () => {
|
|
const result = validateIncidentInput({ ...valid, injury_involved: true, medical_status: 'first_aid' })
|
|
expect(result.ok).toBe(true)
|
|
})
|
|
|
|
it('rejects invalid incident_type', () => {
|
|
const result = validateIncidentInput({ ...valid, incident_type: 'explosion' as any })
|
|
expect(result.ok).toBe(false)
|
|
expect(result.errors).toContain('incident_type is invalid')
|
|
})
|
|
|
|
it('accepts transport type when truck_id is present', () => {
|
|
const r = validateIncidentInput({
|
|
zone_token: 'z',
|
|
incident_type: 'transport',
|
|
description: 'Truck clipped the dock frame reversing into bay 3.',
|
|
injury_involved: false,
|
|
asset_involved: false,
|
|
truck_id: 'truck-uuid',
|
|
} as any)
|
|
expect(r.ok).toBe(true)
|
|
})
|
|
|
|
it('rejects transport type without a truck_id', () => {
|
|
const r = validateIncidentInput({
|
|
zone_token: 'z',
|
|
incident_type: 'transport',
|
|
description: 'Truck clipped the dock frame reversing into bay 3.',
|
|
injury_involved: false,
|
|
asset_involved: false,
|
|
} as any)
|
|
expect(r.ok).toBe(false)
|
|
expect(r.errors).toContain('truck_id is required for transport incidents')
|
|
})
|
|
})
|
|
|
|
describe('validateTypeDetails', () => {
|
|
it('accepts valid environmental fields and trims strings', () => {
|
|
const r = validateTypeDetails('environmental', {
|
|
substance: ' diesel ',
|
|
containment_deployed: true,
|
|
})
|
|
expect(r.ok).toBe(true)
|
|
expect(r.sanitized).toEqual({ substance: 'diesel', containment_deployed: true })
|
|
})
|
|
|
|
it('returns null sanitized when details empty or undefined', () => {
|
|
expect(validateTypeDetails('fire', undefined).sanitized).toBeNull()
|
|
expect(validateTypeDetails('fire', {}).sanitized).toBeNull()
|
|
})
|
|
|
|
it('rejects unknown fields', () => {
|
|
const r = validateTypeDetails('asset_damage', { equipment_id: 'FLT-3', bogus: 'x' })
|
|
expect(r.ok).toBe(false)
|
|
expect(r.errors[0]).toContain('bogus')
|
|
})
|
|
|
|
it('rejects wrong value types', () => {
|
|
const r = validateTypeDetails('security', { police_reported: 'yes' })
|
|
expect(r.ok).toBe(false)
|
|
expect(r.errors[0]).toContain('boolean')
|
|
})
|
|
|
|
it('rejects details for types without extra fields', () => {
|
|
const r = validateTypeDetails('near_miss', { substance: 'oil' })
|
|
expect(r.ok).toBe(false)
|
|
})
|
|
|
|
it('drops empty strings from sanitized output', () => {
|
|
const r = validateTypeDetails('asset_damage', { equipment_id: ' ', loto_applied: false })
|
|
expect(r.ok).toBe(true)
|
|
expect(r.sanitized).toEqual({ loto_applied: false })
|
|
})
|
|
})
|