waterAlarmAuditWorkbench.test.mjs 4.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import assert from 'node:assert/strict'
  2. import { readFile } from 'node:fs/promises'
  3. import test from 'node:test'
  4. import { ensureUniqueSubsystemRouteNames } from '../src/router/routeNameUtils.js'
  5. const page = () => readFile('src/views/subSystem/alarm/common/audit.vue', 'utf8')
  6. test('shared audit page requires a decision but leaves the opinion optional with a length limit', async () => {
  7. const source = await page()
  8. assert.ok(source.includes("item.key !== 'UNREVIEWED'"))
  9. assert.ok(source.includes('v-for="item in reviewChoices"'))
  10. assert.ok(source.includes("auditStatus: [{ required: true, message: '请选择核实结果'"))
  11. assert.ok(source.includes("opinion: [{ max: 500, message: '核实意见最多500字', trigger: 'blur' }]"))
  12. assert.ok(source.includes('placeholder="选填,可填写核实情况、判定依据或误报原因"'))
  13. assert.ok(!source.includes('请填写审核意见'))
  14. assert.ok(source.includes('auditStatus: undefined'))
  15. assert.ok(source.includes('await formRef.value.validate()'))
  16. assert.ok(!source.includes('auditAction'))
  17. })
  18. test('closing the review skips discard confirmation and still protects active requests', async () => {
  19. const source = await page()
  20. assert.ok(source.includes(':before-close="closeReview"'))
  21. assert.ok(source.includes('@click="closeReview()"'))
  22. assert.ok(source.includes('reviewVisible.value = false'))
  23. assert.ok(source.includes("if (submitting.value || uploading.value) { ElMessage.warning('请等待上传或提交完成'); return false }"))
  24. assert.ok(!source.includes('ElMessageBox'))
  25. assert.ok(!source.includes('放弃本次审核'))
  26. assert.ok(!source.includes('const dirty'))
  27. })
  28. test('queue and statistics use shared REST endpoints with subsystem scope and server paging', async () => {
  29. const source = await page()
  30. const api = await readFile('src/api/alarmReview.js', 'utf8')
  31. for (const path of ['/api/alarm/reviews', '/api/alarm/reviews/statistics']) assert.ok(api.includes(path))
  32. assert.ok(source.includes('route.query.rootTypeId'))
  33. assert.ok(source.includes('route.query.warning_code'))
  34. assert.ok(source.includes('pageNum: pageNum.value, pageSize: pageSize.value'))
  35. assert.ok(source.includes('row.auditStatus === unreviewed.value'))
  36. assert.ok(!source.includes('仅展示未处理报警'))
  37. assert.ok(!source.includes('list-note'))
  38. })
  39. test('list omits numeric snapshots and shared detail guards alarms without an actual value', async () => {
  40. const source = await page()
  41. const summary = await readFile('src/views/subSystem/alarm/AlarmSummary.vue', 'utf8')
  42. assert.ok(!source.includes('row.actualValue'))
  43. assert.ok(summary.includes('<p v-if="hasActualValue(alarm)">实际值:'))
  44. })
  45. test('search card uses symmetric vertical padding without trailing form margins', async () => {
  46. const source = await page()
  47. assert.ok(source.includes('.search-card :deep(.el-card__body){padding:16px 20px}'))
  48. assert.ok(source.includes('.search-form :deep(.el-form-item){margin:0}'))
  49. assert.ok(source.includes('gap:12px 24px;margin:0'))
  50. })
  51. test('timeline renders thumbnails with teleported full-size image preview', async () => {
  52. const source = await page()
  53. const attachments = await readFile('src/views/subSystem/alarm/AlarmAttachments.vue', 'utf8')
  54. const history = await readFile('src/views/subSystem/alarm/AlarmHistory.vue', 'utf8')
  55. assert.ok(source.includes('<AlarmHistory :records="logs"'))
  56. assert.ok(history.includes('<AlarmAttachments v-if="item.attachUrl"'))
  57. assert.ok(attachments.includes(':preview-src-list="previewUrls"'))
  58. assert.ok(attachments.includes(':initial-index="index"'))
  59. assert.ok(attachments.includes('preview-teleported'))
  60. assert.ok(attachments.includes('images.value.map(file => file.url)'))
  61. assert.ok(!attachments.includes('<el-link'))
  62. assert.ok(attachments.includes('width: 96px; height: 72px;'))
  63. assert.ok(source.includes('accept=".jpg,.jpeg,.png"'))
  64. assert.ok(!source.includes('PDF'))
  65. assert.ok(!source.includes('|pdf'))
  66. })
  67. test('shared alarm detail navigates to authorized audit and supply map no longer implements auditing', async () => {
  68. const ledger = await readFile('src/views/subSystem/waterSupply/alarm/alarmGIS.vue','utf8')
  69. const detail = await readFile('src/views/subSystem/alarm/AlarmDetail.vue','utf8')
  70. assert.ok(detail.includes("navigate('alarmAudit'"))
  71. assert.ok(!ledger.includes("mode === 'manage'"))
  72. assert.ok(!ledger.includes('submitAudit'))
  73. assert.ok(!ledger.includes('auditOrderStatCards'))
  74. const api = await readFile('src/api/pipeNetwork/waterSupply.js','utf8')
  75. assert.ok(!api.includes('/waterSupply/alarm/audit'))
  76. })
  77. test('four identical relative alarmAudit paths retain unique router names', () => {
  78. const routes = ensureUniqueSubsystemRouteNames(['waterSupply','drainage','gas','manholeCover'].map(name => ({
  79. path: '/subSystem/' + name, children: [{path:'alarmAudit',name:'AlarmAudit'}]
  80. })))
  81. assert.equal(new Set(routes.map(route => route.children[0].name)).size,4)
  82. })