feat(sensor): 完善监测点结果编辑与图层切换

This commit is contained in:
2026-08-03 19:00:16 +08:00
parent 5592c27386
commit 5d9c40e454
12 changed files with 463 additions and 127 deletions
@@ -1,9 +1,16 @@
import { act, fireEvent, render, screen, waitFor } from "@testing-library/react";
import SchemeEditor from "./SchemeEditor";
import { getSensorPlacementCandidate } from "./schemeApi";
import type { SensorPlacementScheme } from "./types";
import { handleMapClickSelectFeatures } from "@/utils/mapQueryService";
const mockOpen = jest.fn();
let mockSingleClickHandler: ((event: unknown) => void) | undefined;
let mockGridColumns: Array<{
field: string;
headerName?: string;
valueFormatter?: (value: unknown) => string;
}> = [];
const mockMap = {
addLayer: jest.fn(),
@@ -32,19 +39,23 @@ jest.mock("@components/olmap/core/MapComponent", () => ({
jest.mock("@mui/x-data-grid", () => ({
DataGrid: (props: {
columns: typeof mockGridColumns;
density?: string;
initialState?: { density?: string };
rowHeight?: number;
columnHeaderHeight?: number;
}) => (
<div
data-testid="scheme-grid"
data-density={props.density ?? "uncontrolled"}
data-initial-density={props.initialState?.density ?? ""}
data-row-height={props.rowHeight ?? "automatic"}
data-column-header-height={props.columnHeaderHeight ?? "automatic"}
/>
),
}) => {
mockGridColumns = props.columns;
return (
<div
data-testid="scheme-grid"
data-density={props.density ?? "uncontrolled"}
data-initial-density={props.initialState?.density ?? ""}
data-row-height={props.rowHeight ?? "automatic"}
data-column-header-height={props.columnHeaderHeight ?? "automatic"}
/>
);
},
GridToolbar: () => null,
}));
@@ -119,11 +130,6 @@ jest.mock("ol/style", () => ({
Text: class {},
}));
jest.mock("ol/proj", () => ({
fromLonLat: (coordinates: number[]) => coordinates,
toLonLat: (coordinates: number[]) => coordinates,
}));
jest.mock("@/utils/mapQueryService", () => ({
handleMapClickSelectFeatures: jest.fn(),
}));
@@ -135,6 +141,7 @@ jest.mock("./SchemeDrawingDialog", () => ({
jest.mock("./schemeApi", () => ({
exportSensorPlacementExcel: jest.fn(),
getSensorPlacementCandidate: jest.fn(),
overwriteSensorPlacementScheme: jest.fn(),
}));
@@ -149,6 +156,7 @@ const scheme: SensorPlacementScheme = {
sensor_points: [
{
node_id: "J1",
max_pipe_diameter: 400,
project_x: 10,
project_y: 20,
map_x: 13500010,
@@ -161,10 +169,18 @@ const scheme: SensorPlacementScheme = {
can_edit: true,
};
const mockGetSensorPlacementCandidate = jest.mocked(
getSensorPlacementCandidate,
);
const mockHandleMapClickSelectFeatures = jest.mocked(
handleMapClickSelectFeatures,
);
describe("SchemeEditor notifications", () => {
beforeEach(() => {
jest.clearAllMocks();
mockSingleClickHandler = undefined;
mockGridColumns = [];
});
it("uses the same error notification contract as scheme query when replace starts outside an existing sensor", async () => {
@@ -187,6 +203,38 @@ describe("SchemeEditor notifications", () => {
});
});
it("loads authoritative point details when adding a map-selected node", async () => {
mockHandleMapClickSelectFeatures.mockResolvedValue({
get: (key: string) => (key === "id" ? "J2" : undefined),
getId: () => "J2",
} as never);
mockGetSensorPlacementCandidate.mockResolvedValue({
node_id: "J2",
max_pipe_diameter: 500,
project_x: 30,
project_y: 40,
map_x: 13500030,
map_y: 3600040,
longitude: 121.1,
latitude: 31.1,
elevation: 6,
});
render(<SchemeEditor scheme={scheme} network="fengyang" />);
fireEvent.click(screen.getByRole("button", { name: "添加" }));
await waitFor(() => expect(mockSingleClickHandler).toBeDefined());
await act(async () => {
mockSingleClickHandler?.({
pixel: [0, 0],
coordinate: [13500030, 3600040],
stopPropagation: jest.fn(),
});
await Promise.resolve();
});
expect(mockGetSensorPlacementCandidate).toHaveBeenCalledWith("J2");
});
it("lets the Data Grid density selector control row sizing", () => {
render(<SchemeEditor scheme={scheme} network="fengyang" />);
@@ -207,4 +255,22 @@ describe("SchemeEditor notifications", () => {
"automatic",
);
});
it("places actions and status first and displays the selected pipe diameter", () => {
render(<SchemeEditor scheme={scheme} network="fengyang" />);
expect(mockGridColumns.slice(0, 5).map((column) => column.field)).toEqual([
"actions",
"adjustment_status",
"sequence",
"node_id",
"max_pipe_diameter",
]);
const diameterColumn = mockGridColumns.find(
(column) => column.field === "max_pipe_diameter",
);
expect(diameterColumn?.headerName).toBe("最大管径 (mm)");
expect(diameterColumn?.valueFormatter?.(400)).toBe("400");
expect(diameterColumn?.valueFormatter?.(null)).toBe("无");
});
});