import assert from 'node:assert/strict' import { readFile } from 'node:fs/promises' import test from 'node:test' import { ensureUniqueSubsystemRouteNames } from '../src/router/routeNameUtils.js' const page = () => readFile('src/views/subSystem/alarm/audit.vue', 'utf8') test('shared audit page requires a decision but leaves the opinion optional with a length limit', async () => { const source = await page() assert.ok(source.includes("item.key !== 'UNREVIEWED'")) assert.ok(source.includes('v-for="item in reviewChoices"')) assert.ok(source.includes("auditStatus: [{ required: true, message: '请选择审核结果'")) assert.ok(source.includes("opinion: [{ max: 500, message: '审核意见最多500字', trigger: 'blur' }]")) assert.ok(source.includes('placeholder="选填,可填写核实情况、判定依据或误报原因"')) assert.ok(!source.includes('请填写审核意见')) assert.ok(source.includes('auditStatus: undefined')) assert.ok(source.includes('await formRef.value.validate()')) assert.ok(!source.includes('auditAction')) }) test('closing the review skips discard confirmation and still protects active requests', async () => { const source = await page() assert.ok(source.includes(':before-close="closeReview"')) assert.ok(source.includes('@click="closeReview()"')) assert.ok(source.includes('reviewVisible.value = false')) assert.ok(source.includes("if (submitting.value || uploading.value) { ElMessage.warning('请等待上传或提交完成'); return false }")) assert.ok(!source.includes('ElMessageBox')) assert.ok(!source.includes('放弃本次审核')) assert.ok(!source.includes('const dirty')) }) test('queue and statistics use shared REST endpoints with subsystem scope and server paging', async () => { const source = await page() const api = await readFile('src/api/alarmReview.js', 'utf8') for (const path of ['/api/alarm/reviews', '/api/alarm/reviews/statistics']) assert.ok(api.includes(path)) assert.ok(source.includes('route.query.rootTypeId')) assert.ok(source.includes('route.query.warning_code')) assert.ok(source.includes('pageNum: pageNum.value, pageSize: pageSize.value')) assert.ok(source.includes('row.auditStatus === unreviewed.value')) assert.ok(!source.includes('仅展示未处理报警')) assert.ok(!source.includes('list-note')) }) test('list and detail omit the entire numeric snapshot for alarms without an actual value', async () => { const source = await page() const summary = await readFile('src/views/subSystem/alarm/AlarmSummary.vue', 'utf8') assert.ok(source.includes('
实际值:'))
})
test('search card uses symmetric vertical padding without trailing form margins', async () => {
const source = await page()
assert.ok(source.includes('.search-card :deep(.el-card__body){padding:16px 20px}'))
assert.ok(source.includes('.search-form :deep(.el-form-item){margin:0}'))
assert.ok(source.includes('gap:12px 24px;margin:0'))
})
test('timeline renders thumbnails with teleported full-size image preview', async () => {
const source = await page()
const attachments = await readFile('src/views/subSystem/alarm/AlarmAttachments.vue', 'utf8')
const history = await readFile('src/views/subSystem/alarm/AlarmHistory.vue', 'utf8')
assert.ok(source.includes('