feature: Clinical Review Mode: Charts, Replay Controls & Alert Reasoning
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import AlertReasoning from '@/components/alerts/AlertReasoning.vue'
|
||||
|
||||
const sepsisAlert = {
|
||||
id: 'alert-1',
|
||||
alertType: 'SepsisWarning',
|
||||
severity: 'Critical',
|
||||
details: 'SIRS criteria met',
|
||||
triggeredAt: '2026-06-19T12:00:00Z',
|
||||
}
|
||||
|
||||
const qsofaAlert = {
|
||||
id: 'alert-2',
|
||||
alertType: 'QsofaWarning',
|
||||
severity: 'Warning',
|
||||
details: 'qSOFA score elevated',
|
||||
triggeredAt: '2026-06-19T12:30:00Z',
|
||||
}
|
||||
|
||||
describe('AlertReasoning', () => {
|
||||
it('showsExplanationForSepsisWarning', () => {
|
||||
const wrapper = mount(AlertReasoning, { props: { alert: sepsisAlert } })
|
||||
expect(wrapper.text()).toContain('SIRS / Sepsis Alert')
|
||||
expect(wrapper.text()).toContain('≥2 of 4 SIRS criteria met')
|
||||
})
|
||||
|
||||
it('showsExplanationForQsofa', () => {
|
||||
const wrapper = mount(AlertReasoning, { props: { alert: qsofaAlert } })
|
||||
expect(wrapper.text()).toContain('qSOFA Alert')
|
||||
expect(wrapper.text()).toContain('≥2 of 3 qSOFA criteria met')
|
||||
})
|
||||
|
||||
it('showsRawDetailsForUnknownType', () => {
|
||||
const unknown = {
|
||||
id: 'alert-3',
|
||||
alertType: 'CustomUnknown',
|
||||
severity: 'Warning',
|
||||
details: 'Something unusual happened',
|
||||
triggeredAt: '2026-06-19T13:00:00Z',
|
||||
}
|
||||
const wrapper = mount(AlertReasoning, { props: { alert: unknown } })
|
||||
expect(wrapper.text()).toContain('CustomUnknown')
|
||||
expect(wrapper.text()).toContain('Something unusual happened')
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,42 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import { defineComponent } from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { useChartData } from '@/composables/useChartData'
|
||||
|
||||
function mountChartData(observations, code) {
|
||||
let exposed
|
||||
const Comp = defineComponent({
|
||||
setup() {
|
||||
exposed = useChartData(observations, code)
|
||||
return () => null
|
||||
},
|
||||
})
|
||||
mount(Comp)
|
||||
return exposed
|
||||
}
|
||||
|
||||
const observations = [
|
||||
{ observationCode: 'HEART_RATE', value: 80, recordedAt: '2026-06-19T12:00:00Z' },
|
||||
{ observationCode: 'RESP_RATE', value: 18, recordedAt: '2026-06-19T12:00:00Z' },
|
||||
{ observationCode: 'HEART_RATE', value: 72, recordedAt: '2026-06-19T11:00:00Z' },
|
||||
]
|
||||
|
||||
describe('useChartData', () => {
|
||||
it('filtersObservationsByCode', () => {
|
||||
const { chartData } = mountChartData(observations, 'HEART_RATE')
|
||||
expect(chartData.value.datasets[0].data).toEqual([72, 80])
|
||||
expect(chartData.value.labels).toHaveLength(2)
|
||||
})
|
||||
|
||||
it('sortsChronologically', () => {
|
||||
const { chartData } = mountChartData(observations, 'HEART_RATE')
|
||||
expect(chartData.value.datasets[0].data[0]).toBe(72)
|
||||
expect(chartData.value.datasets[0].data[1]).toBe(80)
|
||||
})
|
||||
|
||||
it('handlesEmptyData', () => {
|
||||
const { chartData } = mountChartData([], 'HEART_RATE')
|
||||
expect(chartData.value.labels).toEqual([])
|
||||
expect(chartData.value.datasets[0].data).toEqual([])
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,33 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import { useReplayControls } from '@/composables/useReplayControls'
|
||||
|
||||
describe('useReplayControls', () => {
|
||||
it('pauseAndResume', () => {
|
||||
const { isPaused, pause, resume } = useReplayControls()
|
||||
expect(isPaused.value).toBe(false)
|
||||
pause()
|
||||
expect(isPaused.value).toBe(true)
|
||||
resume()
|
||||
expect(isPaused.value).toBe(false)
|
||||
})
|
||||
|
||||
it('speedPresets', () => {
|
||||
const { speed, setSpeed } = useReplayControls()
|
||||
expect(speed.value).toBe(60)
|
||||
setSpeed(360)
|
||||
expect(speed.value).toBe(360)
|
||||
})
|
||||
|
||||
it('progressComputation', () => {
|
||||
const { currentOffsetMinutes, scenarioDurationMinutes, progress } = useReplayControls()
|
||||
scenarioDurationMinutes.value = 100
|
||||
currentOffsetMinutes.value = 50
|
||||
expect(progress.value).toBe(50)
|
||||
})
|
||||
|
||||
it('jumpToOffset', () => {
|
||||
const { currentOffsetMinutes, jumpToOffset } = useReplayControls()
|
||||
jumpToOffset(42)
|
||||
expect(currentOffsetMinutes.value).toBe(42)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user