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.
92 lines
3.9 KiB
TypeScript
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" } }
|
|
]
|
|
};
|