feature: Degraded Operations Visibility

This commit is contained in:
voltsrage
2026-06-23 23:18:31 +08:00
parent 940e27c0ac
commit 4399996448
81 changed files with 3949 additions and 323 deletions
@@ -0,0 +1,43 @@
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
import { mount } from '@vue/test-utils'
import DischargeSummaryPanel from '@/components/patient/DischargeSummaryPanel.vue'
vi.mock('@/api/encounters', () => ({
fetchDischargeSummaryStatus: vi.fn(() => Promise.resolve({
status: 'Ready',
dischargedAt: '2026-06-23T10:00:00Z',
})),
fetchDischargeSummaryContent: vi.fn(() => Promise.resolve('DISCHARGE SUMMARY\nPatient: Jane Doe')),
}))
describe('DischargeSummaryPanel', () => {
beforeEach(() => {
vi.useFakeTimers()
})
afterEach(() => {
vi.useRealTimers()
})
it('rendersSummaryWhenDischarged', async () => {
const wrapper = mount(DischargeSummaryPanel, {
props: {
encounterId: 'enc-1',
discharged: true,
},
})
await vi.waitFor(() => expect(wrapper.text()).toContain('DISCHARGE SUMMARY'))
expect(wrapper.text()).toContain('Download')
})
it('hidesWhenNotDischarged', () => {
const wrapper = mount(DischargeSummaryPanel, {
props: {
encounterId: 'enc-1',
discharged: false,
},
})
expect(wrapper.text()).toBe('')
})
})
@@ -0,0 +1,41 @@
import { describe, it, expect, vi, beforeEach } from 'vitest'
import { mount, flushPromises } from '@vue/test-utils'
import { createPinia, setActivePinia } from 'pinia'
import GatewayOperations from '@/views/GatewayOperations.vue'
vi.mock('@/api/operations', () => ({
fetchGatewayFleet: vi.fn(),
fetchGatewayDetail: vi.fn(),
}))
vi.mock('@/composables/usePolling', () => ({
usePolling: (fn) => { fn(); return {} },
}))
import { fetchGatewayFleet } from '@/api/operations'
describe('GatewayOperations', () => {
beforeEach(() => {
setActivePinia(createPinia())
fetchGatewayFleet.mockResolvedValue([
{
id: 'gw-1',
gatewayCode: 'GW-ICU-3B',
department: 'ICU',
siteName: 'Demo Hospital',
status: 'DEGRADED',
reportedBufferDepth: 847,
minutesSinceHeartbeat: 12,
lastSyncAt: null,
},
])
})
it('rendersFleetTableWithDegradedBadge', async () => {
const wrapper = mount(GatewayOperations)
await flushPromises()
expect(wrapper.text()).toContain('GW-ICU-3B')
expect(wrapper.text()).toContain('DEGRADED')
expect(wrapper.text()).toContain('847')
})
})
@@ -0,0 +1,32 @@
import { describe, it, expect, vi } from 'vitest'
import { mount } from '@vue/test-utils'
import { createPinia, setActivePinia } from 'pinia'
import ThresholdManagementView from '@/views/ThresholdManagementView.vue'
vi.mock('@/api/thresholds', () => ({
fetchThresholds: vi.fn(() => Promise.resolve([
{
id: 'thr-1',
observationCode: 'HEART_RATE',
displayName: 'Heart Rate',
unit: 'bpm',
criticalLow: 30,
warningLow: 50,
warningHigh: 100,
criticalHigh: 150,
},
])),
createThreshold: vi.fn(),
updateThreshold: vi.fn(),
deleteThreshold: vi.fn(),
}))
describe('ThresholdManagementView', () => {
it('rendersThresholdTable', async () => {
setActivePinia(createPinia())
const wrapper = mount(ThresholdManagementView)
await vi.waitFor(() => expect(wrapper.text()).toContain('HEART_RATE'))
expect(wrapper.text()).toContain('Alert Thresholds')
expect(wrapper.text()).toContain('Create Threshold')
})
})
@@ -0,0 +1,31 @@
import { describe, it, expect } from 'vitest'
import { canAccessOps, filterNavLinks, isDashboardRole, roleCanAccessRoute, MAIN_NAV_LINKS } from '@/composables/roleAccess'
describe('roleAccess', () => {
it('filtersNavLinksByRole', () => {
const nurseLinks = filterNavLinks(MAIN_NAV_LINKS, 'NURSE')
expect(nurseLinks.some((l) => l.to === '/feedback')).toBe(false)
expect(nurseLinks.some((l) => l.to === '/alerts')).toBe(true)
const physicianLinks = filterNavLinks(MAIN_NAV_LINKS, 'PHYSICIAN')
expect(physicianLinks.some((l) => l.to === '/feedback')).toBe(true)
})
it('rejectsIntegrationDashboardRole', () => {
expect(isDashboardRole('INTEGRATION')).toBe(false)
expect(isDashboardRole('NURSE')).toBe(true)
})
it('guardsRoutesByAllowedRoles', () => {
expect(roleCanAccessRoute('NURSE', { allowedRoles: ['PHYSICIAN', 'ADMIN'] })).toBe(false)
expect(roleCanAccessRoute('ADMIN', { allowedRoles: ['ADMIN'] })).toBe(true)
expect(roleCanAccessRoute('INTEGRATION', { allowedRoles: ['NURSE'] })).toBe(false)
})
it('restrictsOpsAccessToAdminByDefault', () => {
expect(canAccessOps('ADMIN')).toBe(true)
expect(canAccessOps('NURSE')).toBe(false)
expect(canAccessOps('PHYSICIAN')).toBe(false)
expect(canAccessOps('INTEGRATION')).toBe(false)
})
})
@@ -0,0 +1,49 @@
import { describe, it, expect } from 'vitest'
import {
emptyThresholdForm,
thresholdFormToPayload,
validateThresholdForm,
} from '@/composables/thresholdForm'
describe('thresholdForm', () => {
it('validatesRequiredFields', () => {
const result = validateThresholdForm(emptyThresholdForm())
expect(result.valid).toBe(false)
expect(result.errors.observationCode).toBeTruthy()
})
it('validatesThresholdOrdering', () => {
const result = validateThresholdForm({
observationCode: 'HEART_RATE',
displayName: 'Heart Rate',
unit: 'bpm',
criticalLow: '60',
warningLow: '50',
warningHigh: '100',
criticalHigh: '130',
})
expect(result.valid).toBe(false)
expect(result.errors.warningLow).toBeTruthy()
})
it('buildsPayloadWithNullBounds', () => {
const payload = thresholdFormToPayload({
observationCode: 'SPO2',
displayName: 'SpO₂',
unit: '%',
criticalLow: '',
warningLow: '92',
warningHigh: '',
criticalHigh: '88',
})
expect(payload).toEqual({
observationCode: 'SPO2',
displayName: 'SpO₂',
unit: '%',
criticalLow: null,
warningLow: 92,
warningHigh: null,
criticalHigh: 88,
})
})
})