waterAlarmAuditWorkbench.test.mjs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. import assert from 'node:assert/strict'
  2. import { readFile } from 'node:fs/promises'
  3. import test from 'node:test'
  4. const pagePath = 'src/views/subSystem/waterSupply/components/WaterAlarmPage.vue'
  5. const apiPath = 'src/api/pipeNetwork/waterSupply.js'
  6. test('audit workbench exposes exactly two actions, not an action x result matrix', async () => {
  7. const source = await readFile(pagePath, 'utf8')
  8. assert.match(source, /<el-radio value="transfer">转工单<\/el-radio>/u)
  9. assert.match(source, /<el-radio value="release">误报解除<\/el-radio>/u)
  10. assert.doesNotMatch(source, /v-model="auditForm\.auditAction"/u, '不应再暴露 auditAction 原始码')
  11. assert.doesNotMatch(source, /v-model="auditForm\.auditResult"/u, '不应再暴露 auditResult 原始码')
  12. assert.doesNotMatch(source, /label="审核结果"/u, '四个组合已收敛为两个动作')
  13. })
  14. test('audit submission maps to backend action codes and requires an opinion on release', async () => {
  15. const source = await readFile(pagePath, 'utf8')
  16. const submit = source.slice(source.indexOf('async function submitAudit'),
  17. source.indexOf('async function submitAudit') + 1000)
  18. assert.match(submit, /auditAction: decision === 'release' \? 2 : 1/u)
  19. assert.match(submit, /auditResult: decision === 'release' \? 2 : 1/u)
  20. assert.match(submit, /decision === 'release' && !String\(auditOpinion \|\| ''\)\.trim\(\)/u,
  21. '误报解除必须留下审核意见')
  22. })
  23. test('audit workbench shows work order status counts fed by the backend aggregate', async () => {
  24. const source = await readFile(pagePath, 'utf8')
  25. const api = await readFile(apiPath, 'utf8')
  26. assert.match(api, /getAuditOrderStats[^\n]*\/waterSupply\/alarm\/audit\/order-stats/u)
  27. const cards = source.slice(source.indexOf('const auditOrderStatCards'),
  28. source.indexOf('const pageIcon'))
  29. for (const label of ['全部工单', '待处理', '处理中', '待验收', '已完成']) {
  30. assert.match(cards, new RegExp(`label: '${label}'`, 'u'), `计数条缺少:${label}`)
  31. }
  32. assert.match(source, /v-for="card in auditOrderStatCards"/u)
  33. assert.match(source, /getAuditOrderStats\(\)/u, '审核模式应加载工单状态计数')
  34. })
  35. test('audit queue reads derived display status instead of raw alarm record status', async () => {
  36. const source = await readFile(pagePath, 'utf8')
  37. // 队列来源:只读台账接口 + 展示状态=待审核
  38. assert.match(source, /const AUDIT_DISPLAY_PENDING = 1/u)
  39. assert.match(source, /listAlarmLedger\(\{\.\.\.query\.value, displayStatus: AUDIT_DISPLAY_PENDING\}\)/u)
  40. assert.doesNotMatch(source, /listAlarmHistory\(\{\.\.\.query\.value, alarmStatus: 0\}\)/u,
  41. '不应再按底层报警记录状态硬过滤队列')
  42. // 「未处理/已处理」噪声口径不应再出现在审核模式
  43. assert.doesNotMatch(source, /<el-option label="未处理" :value="0"\/>/u)
  44. assert.doesNotMatch(source, /Number\(row\.alarmStatus\) === 1 \? '已处理' : '未处理'/u)
  45. assert.match(source, /<el-tag :type="displayStatusType\(row\.displayStatus\)">/u,
  46. '两种模式都应展示后端推导的展示状态')
  47. })