162 lines
5.1 KiB
TypeScript
162 lines
5.1 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
||
import {
|
||
formatFeaturePropertyValue,
|
||
getFeatureInsightMetrics,
|
||
getFeaturePanelModel,
|
||
getFeaturePanelProperties,
|
||
getLocalizedFeatureProperties,
|
||
getScadaMetricProperties
|
||
} from "./feature-properties";
|
||
|
||
describe("feature panel properties", () => {
|
||
it.each([
|
||
["pumps", ["id", "status", "startup_depth", "shutoff_depth"]],
|
||
["conduits", ["id", "length", "diameter"]],
|
||
["junctions", ["id", "invert_elevation", "max_depth"]],
|
||
["orifices", ["id", "discharge_coeff", "gated", "shape", "geom1", "geom2"]],
|
||
["outfalls", ["id", "invert_elevation", "outfall_type"]]
|
||
] as const)("shows the configured %s fields", (layer, expectedKeys) => {
|
||
const entries = getFeaturePanelProperties(layer, {}, "feature-id");
|
||
|
||
expect(entries.map((entry) => entry.key)).toEqual(expectedKeys);
|
||
expect(entries[0].value).toBe("feature-id");
|
||
});
|
||
|
||
it("formats conduit diameter from meters to millimeters", () => {
|
||
const entries = getFeaturePanelProperties("conduits", {
|
||
id: "C-1",
|
||
length: 42.5,
|
||
diameter: 0.6
|
||
});
|
||
|
||
expect(entries.map(({ label, value }) => [label, value])).toEqual([
|
||
["编号", "C-1"],
|
||
["长度", "42.50 m"],
|
||
["管径", "600 mm"]
|
||
]);
|
||
});
|
||
|
||
it("builds insight metrics from the layer configuration", () => {
|
||
const metrics = getFeatureInsightMetrics("conduits", {
|
||
diameter: 0.6,
|
||
length: 42.5,
|
||
roughness: 0.013,
|
||
status: "OPEN"
|
||
});
|
||
|
||
expect(metrics).toEqual([
|
||
{ label: "管径", value: "600 mm" },
|
||
{ label: "长度", value: "42.50 m" },
|
||
{ label: "粗糙系数", value: "0.01" },
|
||
{ label: "状态", value: "开启" }
|
||
]);
|
||
});
|
||
|
||
it("localizes free outfall type", () => {
|
||
const entries = getFeaturePanelProperties("outfalls", {
|
||
id: "OF-1",
|
||
invert_elevation: -5.67,
|
||
outfall_type: "FREE"
|
||
});
|
||
|
||
expect(entries.map((entry) => entry.value)).toEqual(["OF-1", "-5.67 m", "自由出流"]);
|
||
});
|
||
|
||
it.each([
|
||
{
|
||
layer: "pumps",
|
||
properties: { id: "P-1", status: "ON", startup_depth: 1.2, shutoff_depth: 0.4 },
|
||
badge: { label: "运行", tone: "active" },
|
||
attributeKeys: ["startup_depth", "shutoff_depth"]
|
||
},
|
||
{
|
||
layer: "orifices",
|
||
properties: { id: "O-1", gated: "YES", discharge_coeff: 0.65, shape: "RECT_CLOSED" },
|
||
badge: { label: "有闸门", tone: "info" },
|
||
attributeKeys: ["discharge_coeff", "shape", "geom1", "geom2"]
|
||
}
|
||
] as const)("promotes the $layer badge without repeating it", ({ layer, properties, badge, attributeKeys }) => {
|
||
const model = getFeaturePanelModel(layer, properties);
|
||
|
||
expect(model.id).toBe(properties.id);
|
||
expect(model.badge).toEqual(badge);
|
||
expect(model.attributes.map((entry) => entry.key)).toEqual(attributeKeys);
|
||
expect(model.attributes.every((entry) => entry.value !== properties.id)).toBe(true);
|
||
});
|
||
|
||
it("uses the map feature id when the properties omit it", () => {
|
||
const model = getFeaturePanelModel("junctions", { max_depth: 3.4 }, "map-feature-id");
|
||
|
||
expect(model.id).toBe("map-feature-id");
|
||
expect(model.badge).toBeUndefined();
|
||
expect(model.attributes.map((entry) => entry.key)).toEqual(["invert_elevation", "max_depth"]);
|
||
});
|
||
|
||
it("shows SCADA facility properties without monitoring readings", () => {
|
||
const model = getFeaturePanelModel("scada", {
|
||
sensor_id: "SCADA-001",
|
||
sensor_name: "DY22东市南街环城南路西段交叉口",
|
||
kind: "integrated_monitoring",
|
||
swmm_node: "J-1024",
|
||
topology_order: 17,
|
||
upstream_node_count: 8,
|
||
distance_to_wwtp_m: 1260,
|
||
COD_mg_L: 23.45,
|
||
氨氮_mg_L: 1.26,
|
||
电导率_uS_cm: 746,
|
||
液位_m: 2.18,
|
||
流量_m3_s: 0.37
|
||
});
|
||
|
||
expect(model.id).toBe("SCADA-001");
|
||
expect(model.badge).toBeUndefined();
|
||
expect(model.attributes.map((entry) => entry.key)).toEqual([
|
||
"kind",
|
||
"swmm_node",
|
||
"topology_order",
|
||
"upstream_node_count",
|
||
"distance_to_wwtp_m"
|
||
]);
|
||
expect(model.attributes.map((entry) => entry.value)).toEqual([
|
||
"综合监测点",
|
||
"J-1024",
|
||
"17",
|
||
"8",
|
||
"1260 m"
|
||
]);
|
||
});
|
||
|
||
it("formats the five integrated SCADA metrics with localized labels and units", () => {
|
||
const metrics = getScadaMetricProperties({
|
||
cod_mg_l: 23.45,
|
||
氨氮_mg_L: 1.26,
|
||
电导率_uS_cm: 746,
|
||
液位_m: 2.18,
|
||
流量_m3_s: 0.37
|
||
});
|
||
|
||
expect(metrics.map(({ label, value }) => [label, value])).toEqual([
|
||
["COD", "23.45 mg/L"],
|
||
["氨氮", "1.26 mg/L"],
|
||
["电导率", "746 μS/cm"],
|
||
["液位", "2.18 m"],
|
||
["流量", "0.37 m³/s"]
|
||
]);
|
||
});
|
||
|
||
it("omits the internal SCADA clustering size from user-facing properties", () => {
|
||
const entries = getLocalizedFeatureProperties({
|
||
name: "THC雷达液位计(MQTT)",
|
||
cluster_size: 29,
|
||
external_id: "DEVICE-002"
|
||
});
|
||
|
||
expect(entries.map((entry) => entry.key)).toEqual(["name", "external_id"]);
|
||
});
|
||
|
||
it("labels uniformly sampled SCADA locations", () => {
|
||
expect(formatFeaturePropertyValue("location_source", "uniform_farthest_point_demo"))
|
||
.toBe("空间均匀采样模拟位置");
|
||
});
|
||
});
|