feat: incident report form, API route, middleware shared-route + redirect
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import { validateIncidentInput } from '@/lib/incidents/validate'
|
||||
|
||||
describe('incident report validation', () => {
|
||||
it('rejects empty zone_token', () => {
|
||||
const result = validateIncidentInput({
|
||||
zone_token: '',
|
||||
incident_type: 'near_miss',
|
||||
description: 'Forklift nearly hit a worker',
|
||||
injury_involved: false,
|
||||
asset_involved: false,
|
||||
})
|
||||
expect(result.ok).toBe(false)
|
||||
expect(result.errors).toContain('zone_token is required')
|
||||
})
|
||||
|
||||
it('requires medical_status for injury', () => {
|
||||
const result = validateIncidentInput({
|
||||
zone_token: 'scw1-dock-a-qr-2026',
|
||||
incident_type: 'injury',
|
||||
description: 'Worker slipped on wet floor near cold storage entrance',
|
||||
injury_involved: true,
|
||||
asset_involved: false,
|
||||
})
|
||||
expect(result.ok).toBe(false)
|
||||
expect(result.errors).toContain('medical_status is required when injury is involved')
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,45 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import { validateIncidentInput, 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')
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user