/** Component-level SSR integration; not a browser/layout or GPU validation. */ import assert from 'node:assert/strict' import { readFileSync } from 'node:fs' import { registerHooks } from 'node:module' import { parse, compileScript, compileTemplate } from '@vue/compiler-sfc' import { compile } from '@vue/compiler-ssr' import { createRequire } from 'node:module' import { createSSRApp, computed } from 'vue' import { renderToString } from '@vue/server-renderer' import { createPinia, setActivePinia } from 'pinia' const root = new URL('../../../src/modules/cockpit/', import.meta.url) const observation = Symbol.for('t41.location-observation') globalThis[observation] = [] const hooks = registerHooks({ resolve(specifier, context, nextResolve) { const resolved = nextResolve(specifier, context) if (resolved.url.endsWith('/cockpit/services/mapService.js')) return { ...resolved, url: `${resolved.url}?t41-observed` } return resolved }, load(url, context, nextLoad) { const mutation = process.env.T41_MUTATION if (mutation === 'marker-gate' && url.endsWith('/domain/modeLayerPlan.js')) { const source = readFileSync(new URL(url), 'utf8') const previous = /return Boolean\(point && mode !== MODE_LAYER\.INFRASTRUCTURE &&\s*\(mode !== MODE_LAYER\.WARNING_RESPONSE \|\| isAbnormalPoint\(point, abnormalCodes\)\)\)/ assert.ok(previous.test(source), 'mutation matches current gate') return { format: 'module', shortCircuit: true, source: source.replace(previous, `return markers.some((item) => item.code === current.pointCode)`) } } if (mutation === 'drop-empty' && url.endsWith('/services/detailApi.js')) { const source = readFileSync(new URL(url), 'utf8') assert.ok(source.includes('toData: toMonitoringPointDetail,'), 'mutation matches point adapter') return { format: 'module', shortCircuit: true, source: source.replace('toData: toMonitoringPointDetail,', `toData: toMonitoringPointDetail, isEmpty: isEmptyBy((payload) => payload?.pointStatus === 'EMPTY'),`) } } if (url.endsWith('?t41-observed')) { const actual = url.replace('?t41-observed', '?t41-actual') return { format: 'module', shortCircuit: true, source: ` import * as actual from ${JSON.stringify(actual)}; export * from ${JSON.stringify(actual)}; export function locateMonitoringPoint(...args) { globalThis[Symbol.for('t41.location-observation')].push(args); return actual.locateMonitoringPoint(...args); } ` } } if (url.endsWith('.json')) return { format: 'module', shortCircuit: true, source: `export default ${readFileSync(new URL(url), 'utf8')}` } if (url.endsWith('.vue')) { const { descriptor } = parse(readFileSync(new URL(url), 'utf8'), { filename: new URL(url).pathname }) const script = compileScript(descriptor, { id: 't41-render', genDefaultAs: '__sfc__' }) const template = compileTemplate({ source: descriptor.template.content, filename: new URL(url).pathname, id: 't41-render', ssr: true, ssrCssVars: [], compilerOptions: { bindingMetadata: script.bindings } }) assert.deepEqual(template.errors, []) return { format: 'module', shortCircuit: true, source: `${script.content}\n${template.code}\n__sfc__.ssrRender = ssrRender; export default __sfc__;` } } return nextLoad(url, context) }, }) const { useDetailStore } = await import(new URL('stores/detailStore.js', root)) const { useMapStore } = await import(new URL('stores/mapStore.js', root)) const { useMonitoringStore } = await import(new URL('stores/monitoringStore.js', root)) const { registerMockTransport, resetMockTransportsForTest } = await import(new URL('services/cockpitApi.js', root)) const { planModeLayers } = await import(new URL('domain/modeLayerPlan.js', root)) const { resolveDetailAnchor, detailAnchorLocation } = await import(new URL('domain/detailAnchor.js', root)) const { default: PointDetailCard } = await import(new URL('components/PointDetailCard.vue', root)) const pinia = createPinia(); setActivePinia(pinia) const config = { dataSource: 'mock', api: { baseUrl: '', token: '' } } const detail = useDetailStore(); detail.configure({ config }) const map = useMapStore(); map.setup({ config }) const ledger = useMonitoringStore() resetMockTransportsForTest() const code = 'P-FIXED' const validation = { state: 'INVALID', reason: 'OUTSIDE_PRIMARY_AREA', renderable: false, crs: 'WGS84' } registerMockTransport('/map-snapshot', () => ({ page: 1, pageSize: 2, total: 1, complete: true, snapshotAt: '2026-10-12T10:00:00+08:00', monitoringPoints: [{ pointCode: code, pointName: '区外监测点', pointStatus: 'NORMAL', deviceCodes: ['EQ-FIXED'], longitude: 110.1, latitude: 28.4, coordinateValidation: validation }], unassociatedEquipment: [] })) registerMockTransport(`/monitoring-points/${code}`, () => ({ monitoringPointCode: code, monitoringPointName: '区外监测点', pointStatus: 'NORMAL', statusLabel: '正常', devices: [{ deviceCode: 'EQ-FIXED', deviceName: '区外设备', deviceStatus: 'NORMAL', coordinateValidation: validation }], deviceStatistics: { totalDeviceCount: 1, normalDeviceCount: 1 }, coordinateValidation: validation })) await map.advance() await ledger.openLedgerPoint(code) // Use the production floating detail template without invoking shell lifecycle/server actions. const shell = readFileSync(new URL('CockpitShell.vue', root), 'utf8') const begin = shell.indexOf('
assert.equal(globalThis[observation].length, 0)) await check('monitoring mode retains the fixed detail without fake map marker', async () => { mode = 'monitoring' const html = await render() assert.match(html, /data-anchor-state="fixed"/) assert.equal(planModeLayers({ mode, objects: map.summary.objects }).markers.length, 0) }) await check('infrastructure suspends fixed detail but keeps selected identity', async () => { mode = 'infrastructure' assert.ok(!(await render()).includes('data-point-detail')) assert.equal(detail.selection.pointCode, code) }) await check('switching back to overview restores fixed detail', async () => { mode = 'overview'; assert.match(await render(), /data-anchor-state="fixed"/) }) await check('unloaded object is not falsely labelled no-location', () => { assert.equal(detailAnchorLocation(resolveDetailAnchor({ selection: { level: 'point', pointCode: 'P-LATER' }, objects: map.summary.objects })).present, false) }) await check('no-device blocked point retains its name and EMPTY business status', async () => { detail.closeDetail() registerMockTransport(`/monitoring-points/${code}`, () => ({ monitoringPointCode: code, monitoringPointName: '区外监测点', pointStatus: 'EMPTY', statusLabel: '无设备', devices: [], deviceStatistics: { totalDeviceCount: 0 }, coordinateValidation: validation })) await ledger.openLedgerPoint(code) assert.equal(detail.sections.pointDetail.data?.name, '区外监测点') assert.equal(detail.sections.pointDetail.data?.status, 'EMPTY') assert.equal(detail.sections.pointDetail.data.statistics.total, 0) assert.equal(detail.sections.pointDetail.data.coordinate.renderable, false) assert.equal(detail.sections.pointDetail.data.coordinate.reason, 'OUTSIDE_PRIMARY_AREA') const html = await render() assert.ok(html.includes('区外监测点')) assert.ok(html.includes('无设备')) assert.match(html, /data-point-code-value[^>]*>P-FIXED<\/dd>/) assert.match(html, /data-point-device-count[^>]*>0<\/b>/) assert.equal(globalThis[observation].length, 0) }) await check('closing removes detail without issuing a point-location request', async () => { detail.closeDetail(); assert.ok(!(await render()).includes('data-point-detail')) assert.equal(globalThis[observation].length, 0) }) resetMockTransportsForTest(); delete globalThis[observation]; hooks.deregister() console.log(`T41 fixed-detail SSR: ${checks-failures}/${checks}, not browser verification`) process.exitCode = failures ? 1 : 0