Files
next-tjwater-frontend/src/features/workbench/map/scada-analysis.test.ts
T
jiang f4318a9b9c feat: refine workbench visuals and map controls
Unify the Agent history extension with the header acrylic surface, preserve the full conversation body, and consolidate shared control and status styling.

Restore map flow and SCADA controller behavior, remove obsolete rendering paths, and extend regression coverage. Button press coverage now releases outside the target so state assertions cannot accidentally toggle the control.
2026-07-28 16:39:36 +08:00

92 lines
3.9 KiB
TypeScript

import type { FeatureCollection } from "geojson";
import { describe, expect, it } from "vitest";
import {
SCADA_ANALYSIS_LAYER_IDS,
SCADA_ANALYSIS_LEVEL_COLORS,
createScadaAnalysisCollection,
parseScadaAnalysisItems,
scadaAnalysisLayers
} from "./scada-analysis";
describe("SCADA analysis overlay", () => {
it("uses distinct semantic rings, status indicators, and legible priority labels", () => {
const casing = scadaAnalysisLayers.find((layer) => layer.id === SCADA_ANALYSIS_LAYER_IDS.casing);
const level = scadaAnalysisLayers.find((layer) => layer.id === SCADA_ANALYSIS_LAYER_IDS.level);
const indicator = scadaAnalysisLayers.find((layer) => layer.id === SCADA_ANALYSIS_LAYER_IDS.indicator);
const label = scadaAnalysisLayers.find((layer) => layer.id === SCADA_ANALYSIS_LAYER_IDS.label);
expect(SCADA_ANALYSIS_LEVEL_COLORS).toEqual({
high: "#C34A4A",
medium: "#C66A16",
low: "#2E8B64",
unrated: "#7656C7"
});
expect(casing).toMatchObject({
type: "circle",
paint: { "circle-radius": 20, "circle-stroke-color": "#FFFFFF", "circle-stroke-width": 8 }
});
expect(JSON.stringify(level)).toContain(SCADA_ANALYSIS_LEVEL_COLORS.high);
expect(JSON.stringify(level)).toContain(SCADA_ANALYSIS_LEVEL_COLORS.medium);
expect(JSON.stringify(level)).toContain(SCADA_ANALYSIS_LEVEL_COLORS.low);
expect(JSON.stringify(level)).toContain(SCADA_ANALYSIS_LEVEL_COLORS.unrated);
expect(level).toMatchObject({ paint: { "circle-radius": 20, "circle-stroke-width": 5 } });
expect(indicator).toMatchObject({
type: "circle",
paint: {
"circle-radius": 6,
"circle-translate": [14, -14],
"circle-stroke-color": "#FFFFFF",
"circle-stroke-width": 2
}
});
expect(label).toMatchObject({
type: "symbol",
layout: {
"symbol-sort-key": ["get", "sort_priority"],
"text-field": ["get", "analysis_label"],
"text-size": 18,
"text-font": ["Noto Sans Regular"],
"text-allow-overlap": false
},
paint: { "text-halo-color": "#FFFFFF", "text-halo-width": 4, "text-halo-blur": 0.5 }
});
expect(JSON.stringify(label)).toContain("#9C3036");
expect(JSON.stringify(label)).toContain("#8C470D");
expect(JSON.stringify(label)).toContain("#1F6F4D");
expect(JSON.stringify(label)).toContain("#573E9C");
});
it("validates one to one hundred unique IDs and fixed levels", () => {
expect(parseScadaAnalysisItems([{ sensor_id: " MP01 ", level: "high" }])).toEqual([
{ sensor_id: "MP01", level: "high" }
]);
expect(parseScadaAnalysisItems([])).toBeNull();
expect(parseScadaAnalysisItems([{ sensor_id: "MP01", level: "high" }, { sensor_id: "MP01", level: "low" }])).toBeNull();
expect(parseScadaAnalysisItems([{ sensor_id: "MP01", level: "critical" }])).toBeNull();
});
it("uses trusted WFS sensor IDs for localized labels and reports partial misses", () => {
const result = createScadaAnalysisCollection(scadaCollection, [
{ sensor_id: "MP01", level: "high" },
{ sensor_id: "MP02", level: "medium" },
{ sensor_id: "MP404", level: "low" }
]);
expect(result.result).toEqual({
rendered_ids: ["MP01", "MP02"],
missing_ids: ["MP404"],
level_counts: { high: 1, medium: 1, low: 0, unrated: 0 }
});
expect(result.collection.features.map((feature) => feature.properties)).toEqual([
expect.objectContaining({ sensor_id: "MP01", analysis_label: "MP01 · 高", sort_priority: 0 }),
expect.objectContaining({ sensor_id: "MP02", analysis_label: "MP02 · 中", sort_priority: 1 })
]);
});
});
const scadaCollection: FeatureCollection = {
type: "FeatureCollection",
features: [
{ type: "Feature", geometry: { type: "Point", coordinates: [120.7, 28] }, properties: { sensor_id: "MP01" } },
{ type: "Feature", geometry: { type: "Point", coordinates: [120.72, 28.02] }, properties: { sensor_id: "MP02" } }
]
};