ui-feedback-regressions.mjs 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738
  1. import assert from 'node:assert/strict'
  2. import { ringSlicePath } from '../../../src/modules/cockpit/domain/ringGeometry.js'
  3. import { planStatusPie } from '../../../src/modules/cockpit/domain/statusPie.js'
  4. import { donutBlock } from '../../../src/modules/cockpit/domain/panelBlocks.js'
  5. import { planEventLocate } from '../../../src/modules/cockpit/domain/eventDetail.js'
  6. import { eventTimeWindow, historyWindows } from '../../../src/modules/cockpit/domain/eventRange.js'
  7. import { resolveDeviceImageUrl } from '../../../src/modules/cockpit/services/deviceImage.js'
  8. // Full rings need four arcs, not a coincident-endpoint single arc.
  9. assert.equal((ringSlicePath(0, 360).match(/ A /g) || []).length, 4)
  10. const donut = donutBlock('single', [{ code: 'MANHOLE', label: '窨井', count: 7 }])
  11. assert.equal(donut.slices.length, 1)
  12. assert.equal((donut.slices[0].path.match(/ A /g) || []).length, 4)
  13. const pie = planStatusPie({ distribution: { available: true, counts: { UNKNOWN: 7 } }, rows: [{ key: 'UNKNOWN', label: '状态未发布', tone: 'point-unknown' }] })
  14. assert.equal((pie.slices[0].path.match(/ A /g) || []).length, 4)
  15. assert.ok(!pie.slices[0].path.includes('NaN'))
  16. // Precise device identity wins even if a parent point comes first.
  17. const point = { kind: 'monitoring-point', code: 'P', deviceCodes: ['D'], coordinate: { renderable: true }, longitude: 110, latitude: 28 }
  18. const device = { kind: 'unassociated-equipment', code: 'D', deviceCodes: [], coordinate: { renderable: true }, longitude: 110.1, latitude: 28.1 }
  19. assert.equal(planEventLocate({ deviceCode: 'D' }, [point, device]).object, device)
  20. assert.equal(planEventLocate({ deviceCode: 'D', coordinate: { validated: true, renderable: false } }, [device]).result, 'ok')
  21. assert.equal(planEventLocate({ deviceCode: 'D' }, [{ ...device, kind: 'monitoring-device' }]).result, 'ok')
  22. // Inclusive hourly server buckets are disjoint and cover the entire 90-day window.
  23. const range = eventTimeWindow('LAST_90_DAYS', Date.parse('2026-10-13T12:34:00+08:00'))
  24. const windows = historyWindows(range.startTime, range.endTime)
  25. const seen = new Set()
  26. for (const window of windows) {
  27. assert.ok(Date.parse(window.endTime) - Date.parse(window.startTime) < 31 * 86400000)
  28. for (let hour = Math.floor(Date.parse(window.startTime) / 3600000); hour <= Math.floor(Date.parse(window.endTime) / 3600000); hour++) {
  29. assert.ok(!seen.has(hour), 'hour was requested twice')
  30. seen.add(hour)
  31. }
  32. }
  33. assert.equal(seen.size, Math.floor(Date.parse(range.endTime) / 3600000) - Math.floor(Date.parse(range.startTime) / 3600000) + 1)
  34. assert.equal(resolveDeviceImageUrl('/profile/upload/test.jpg', { dataSource: 'real', api: { baseUrl: 'https://backend.example/api/cockpit/v1' } }), 'https://backend.example/profile/upload/test.jpg')
  35. console.log('UI feedback regressions passed')