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: "#DC2626", medium: "#F59E0B", low: "#16A34A", unrated: "#7C3AED" }); expect(casing).toMatchObject({ type: "circle", paint: { "circle-radius": 16, "circle-stroke-color": "#FFFFFF", "circle-stroke-width": 7 } }); 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-stroke-width": 4 } }); expect(indicator).toMatchObject({ type: "circle", paint: { "circle-radius": 5, "circle-translate": [11, -11], "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": 15, "text-font": ["Noto Sans Regular"], "text-allow-overlap": false }, paint: { "text-halo-color": "#FFFFFF", "text-halo-width": 3, "text-halo-blur": 0.5 } }); expect(JSON.stringify(label)).toContain("#991B1B"); expect(JSON.stringify(label)).toContain("#92400E"); expect(JSON.stringify(label)).toContain("#166534"); }); 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" } } ] };