Files
next-tjwater-frontend/src/features/workbench/utils/investigation-chart-groups.test.ts
T

142 lines
8.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, it } from "vitest";
import { groupInvestigationCharts } from "./investigation-chart-groups";
import type { InvestigationChart } from "../hooks/use-investigation-presentation";
const comparison = (id: string, metric = "压力", unit = "m", date = "2026-07-16"): InvestigationChart => ({
action: "open_chart", chart_id: `chart_tc_${id}`, evidence_refs: [`evidence:${id}`],
chart: { title: `${id} ${metric}七日同时刻对照(${unit})`, chart_type: "time_comparison",
x_axis_name: "时间", y_axis_name: `${metric}(${unit})`, x_data: ["07:45", "08:00"],
series: [
{ name: `${id} 当前 ${date}`, type: "line", data: [30, 25], sample_times: [`${date}T07:45:00+08:00`, `${date}T08:00:00+08:00`] },
{ name: `${id} 2026-07-09`, type: "scatter", data: [null, 32], sample_times: [null, "2026-07-09T08:00:00+08:00"] }
] }
});
const legacyComparison = (id: string, metric = "压力", unit = "m", date = "2026-07-16") => {
const command = comparison(id, metric, unit, date);
command.chart.title = `${id} ${metric}三小时趋势与七天同期对照(${unit})`;
command.chart.series[0].name = `${id} ${date.slice(5)}(${unit})`;
command.chart.series[1].name = "07-09";
return command;
};
describe("investigation comparison groups", () => {
it("groups all four bound devices even when titles differ and one device has no observations", () => {
const ids = ["486033", "542017", "541061", "524529"];
const charts = ids.map((id, index) => {
const command = comparison(id, "流量", "m3/h");
command.chart.title = `不同的标题 ${index}`;
command.chart.scada = { role: "comparison", metric: "flow", unit: "m3/h",
window_start: "2026-07-16T05:00:00+08:00", window_end: "2026-07-16T08:00:00+08:00" };
command.chart.series.forEach((series, offset) => {
series.device_id = id;
series.day_offset = offset;
series.name = offset ? "历史" : "当前";
if (id === "524529") { series.data = [null, null]; series.sample_times = [null, null]; }
});
return command;
});
const groups = groupInvestigationCharts(charts);
expect(groups).toHaveLength(1);
expect(groups[0].items.map((item) => item.label)).toEqual(ids);
expect(groups[0].id).toBe(groupInvestigationCharts([charts[3]])[0].id);
expect(groups[0].items[3].command).toBe(charts[3]);
charts[3].chart.scada!.unit = "m³/h";
charts[3].chart.scada!.window_start = "2026-07-15T21:00:00Z";
charts[3].chart.scada!.window_end = "2026-07-16T00:00:00Z";
expect(groupInvestigationCharts(charts)).toHaveLength(1);
});
it("groups pressure objects and pipe flow objects separately without changing data or evidence", () => {
const charts = [comparison("170486"), comparison("175618"), comparison("542017", "管流", "m³/h"), comparison("486033", "管流", "m³/h")];
const groups = groupInvestigationCharts(charts);
expect(groups).toHaveLength(2);
expect(groups[0].items.map((item) => item.label)).toEqual(["170486", "175618"]);
expect(groups[1].items.map((item) => item.label)).toEqual(["542017", "486033"]);
expect(groups[0].title).toBe("压力七日同时刻对照(m)");
expect(groups[0].items[1].command).toBe(charts[1]);
expect(charts[1].chart.series[1].data).toEqual([null, 32]);
});
it("groups saved pressure and flow charts whose titles put the metric before the object ID", () => {
const charts = [["170486", "压力", "m"], ["175618", "压力", "m"], ["541061", "流量", "m³/h"], ["542017", "流量", "m³/h"]].map(([id, metric, unit]) => {
const command = comparison(id, metric, unit);
command.chart.title = `${metric}测点 ${id} 当前曲线与前七天同期对比(${unit})`;
return command;
});
const groups = groupInvestigationCharts(charts);
expect(groups.map((group) => ({ title: group.title, objects: group.items.map((item) => item.label) }))).toEqual([
{ title: "压力当前曲线与前七天同期对比(m)", objects: ["170486", "175618"] },
{ title: "流量当前曲线与前七天同期对比(m³/h)", objects: ["541061", "542017"] }
]);
});
it("recognizes the same explicit object comparison in all three saved title formats", () => {
const charts = [comparison("170486"), comparison("175618"), comparison("159673")];
charts[0].chart.title = "170486 压力三小时与历史对照(m)";
charts[1].chart.title = "测点 175618 压力三小时与历史对照(m)";
charts[2].chart.title = "压力测点 159673 三小时与历史对照(m)";
const groups = groupInvestigationCharts(charts);
expect(groups).toHaveLength(1);
expect(groups[0].title).toBe("压力三小时与历史对照(m)");
expect(groups[0].items.map((item) => item.label)).toEqual(["170486", "175618", "159673"]);
});
it("groups saved date-only historical labels without rewriting commands, readings or evidence", () => {
const charts = [legacyComparison("170486"), legacyComparison("175618")];
charts[1].chart.series[1].data[1] = 0;
const original = structuredClone(charts);
const groups = groupInvestigationCharts(charts);
expect(groups).toHaveLength(1);
expect(groups[0].items.map((item) => item.label)).toEqual(["170486", "175618"]);
groups[0].items.forEach((item, index) => {
expect(item.command).toBe(charts[index]);
expect(item.command.chart.series).toBe(charts[index].chart.series);
expect(item.command.chart.series[1].sample_times).toBe(charts[index].chart.series[1].sample_times);
expect(item.command.evidence_refs).toBe(charts[index].evidence_refs);
});
expect(charts).toEqual(original);
});
it("keeps legacy comparisons with different units, windows or current dates separate", () => {
const shifted = legacyComparison("175618");
shifted.chart.x_data = ["08:00", "08:15"];
shifted.chart.series[0].sample_times = ["2026-07-16T08:00:00+08:00", "2026-07-16T08:15:00+08:00"];
shifted.chart.series[1].sample_times = [null, "2026-07-09T08:15:00+08:00"];
const charts = [legacyComparison("170486"), legacyComparison("P2", "压力", "MPa"), shifted, legacyComparison("P3", "压力", "m", "2026-07-17")];
expect(groupInvestigationCharts(charts)).toHaveLength(charts.length);
});
it("leaves ambiguous or mixed-object legacy charts and unproven historical dates separate", () => {
const ambiguous = legacyComparison("P2"); ambiguous.chart.title = "压力测点历史对照";
const foreign = legacyComparison("P3"); foreign.chart.series[1].name = "P4 07-09";
const mixed = legacyComparison("P4"); mixed.chart.series.push({ ...mixed.chart.series[0], name: "P5 当前 2026-07-16" });
const missing = legacyComparison("P5"); delete missing.chart.series[1].sample_times;
const mismatched = legacyComparison("P6"); mismatched.chart.series[1].sample_times = [null, "2026-07-10T08:00:00+08:00"];
const empty = legacyComparison("P7"); empty.chart.series[1].data = [null, null]; empty.chart.series[1].sample_times = [null, null];
const sameDateInUtc8 = legacyComparison("P8"); sameDateInUtc8.chart.series[1].sample_times = [null, "2026-07-09T00:00:00Z"];
const charts = [legacyComparison("170486"), ambiguous, foreign, mixed, missing, mismatched, empty, sameDateInUtc8];
const groups = groupInvestigationCharts(charts);
expect(groups).toHaveLength(charts.length - 1);
expect(groups[0].items.map((item) => item.label)).toEqual(["170486", "P8"]);
});
it("keeps incompatible units, sampling windows, comparison dates and ordinary trends separate", () => {
const base = comparison("170486");
const window = comparison("175618"); window.chart.x_data = ["08:00", "08:15"];
const trend = comparison("159673"); trend.chart.series = [trend.chart.series[0]];
expect(groupInvestigationCharts([base, comparison("P2", "压力", "MPa"), comparison("P3", "压力", "m", "2026-07-17"), window, trend])).toHaveLength(5);
const noTimes = [comparison("P4"), comparison("P5", "压力", "m", "2026-07-17")];
for (const command of noTimes) for (const series of command.chart.series) delete series.sample_times;
expect(groupInvestigationCharts(noTimes)).toHaveLength(2);
});
it("keeps group identity stable as objects arrive or are closed and leaves ambiguous titles alone", () => {
const first = comparison("170486"), second = comparison("175618");
expect(groupInvestigationCharts([first])[0].id).toBe(groupInvestigationCharts([second, first])[0].id);
const ambiguous = comparison("159673"); ambiguous.chart.title = "压力同期对照";
expect(groupInvestigationCharts([first, ambiguous])).toHaveLength(2);
expect(groupInvestigationCharts([])).toEqual([]);
});
});