fix(api): align frontend with REST contracts
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
import { act, fireEvent, render, screen, waitFor } from "@testing-library/react";
|
||||
import SchemeEditor from "./SchemeEditor";
|
||||
import type { SensorPlacementScheme } from "./types";
|
||||
|
||||
const mockOpen = jest.fn();
|
||||
let mockSingleClickHandler: ((event: unknown) => void) | undefined;
|
||||
|
||||
const mockMap = {
|
||||
addLayer: jest.fn(),
|
||||
removeLayer: jest.fn(),
|
||||
on: jest.fn((eventName: string, handler: (event: unknown) => void) => {
|
||||
if (eventName === "singleclick") {
|
||||
mockSingleClickHandler = handler;
|
||||
}
|
||||
}),
|
||||
un: jest.fn(),
|
||||
forEachFeatureAtPixel: jest.fn(() => undefined),
|
||||
getView: jest.fn(() => ({
|
||||
animate: jest.fn(),
|
||||
getZoom: jest.fn(() => 16),
|
||||
getResolution: jest.fn(() => 1),
|
||||
})),
|
||||
};
|
||||
|
||||
jest.mock("@refinedev/core", () => ({
|
||||
useNotification: () => ({ open: mockOpen }),
|
||||
}));
|
||||
|
||||
jest.mock("@components/olmap/core/MapComponent", () => ({
|
||||
useMap: () => mockMap,
|
||||
}));
|
||||
|
||||
jest.mock("@mui/x-data-grid", () => ({
|
||||
DataGrid: () => <div data-testid="scheme-grid" />,
|
||||
GridToolbar: () => null,
|
||||
}));
|
||||
|
||||
jest.mock("@mui/x-data-grid/locales", () => ({
|
||||
zhCN: {
|
||||
components: {
|
||||
MuiDataGrid: {
|
||||
defaultProps: {
|
||||
localeText: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock("ol/Feature", () => ({
|
||||
__esModule: true,
|
||||
default: class {
|
||||
private values: Record<string, unknown>;
|
||||
|
||||
constructor(values: Record<string, unknown>) {
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
get(key: string) {
|
||||
return this.values[key];
|
||||
}
|
||||
|
||||
setId() {}
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock("ol/geom/Point", () => ({
|
||||
__esModule: true,
|
||||
default: class {
|
||||
constructor(_coordinates: number[]) {}
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock("ol/source/Vector", () => ({
|
||||
__esModule: true,
|
||||
default: class {
|
||||
clear() {}
|
||||
addFeature() {}
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock("ol/layer/Vector", () => ({
|
||||
__esModule: true,
|
||||
default: class {
|
||||
private source: { clear: () => void; addFeature: () => void };
|
||||
|
||||
constructor(options: {
|
||||
source: { clear: () => void; addFeature: () => void };
|
||||
}) {
|
||||
this.source = options.source;
|
||||
}
|
||||
|
||||
getSource() {
|
||||
return this.source;
|
||||
}
|
||||
|
||||
setVisible() {}
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock("ol/style", () => ({
|
||||
Circle: class {},
|
||||
Fill: class {},
|
||||
Stroke: class {},
|
||||
Style: class {},
|
||||
Text: class {},
|
||||
}));
|
||||
|
||||
jest.mock("ol/proj", () => ({
|
||||
fromLonLat: (coordinates: number[]) => coordinates,
|
||||
toLonLat: (coordinates: number[]) => coordinates,
|
||||
}));
|
||||
|
||||
jest.mock("@/utils/mapQueryService", () => ({
|
||||
handleMapClickSelectFeatures: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock("./SchemeDrawingDialog", () => ({
|
||||
__esModule: true,
|
||||
default: () => null,
|
||||
}));
|
||||
|
||||
jest.mock("./schemeApi", () => ({
|
||||
exportSensorPlacementExcel: jest.fn(),
|
||||
overwriteSensorPlacementScheme: jest.fn(),
|
||||
}));
|
||||
|
||||
const scheme: SensorPlacementScheme = {
|
||||
id: 1,
|
||||
scheme_name: "测试方案",
|
||||
sensor_number: 1,
|
||||
min_diameter: 300,
|
||||
username: "operator",
|
||||
create_time: "2026-07-30T08:00:00+08:00",
|
||||
sensor_location: ["J1"],
|
||||
sensor_points: [
|
||||
{
|
||||
node_id: "J1",
|
||||
project_x: 10,
|
||||
project_y: 20,
|
||||
map_x: 13500010,
|
||||
map_y: 3600020,
|
||||
longitude: 121,
|
||||
latitude: 31,
|
||||
elevation: 5,
|
||||
},
|
||||
],
|
||||
can_edit: true,
|
||||
};
|
||||
|
||||
describe("SchemeEditor notifications", () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
mockSingleClickHandler = undefined;
|
||||
});
|
||||
|
||||
it("uses the same error notification contract as scheme query when replace starts outside an existing sensor", async () => {
|
||||
render(<SchemeEditor scheme={scheme} network="fengyang" />);
|
||||
|
||||
fireEvent.click(screen.getByRole("button", { name: "替换" }));
|
||||
await waitFor(() => expect(mockSingleClickHandler).toBeDefined());
|
||||
|
||||
act(() => {
|
||||
mockSingleClickHandler?.({
|
||||
pixel: [0, 0],
|
||||
coordinate: [13500000, 3600000],
|
||||
stopPropagation: jest.fn(),
|
||||
});
|
||||
});
|
||||
|
||||
expect(mockOpen).toHaveBeenCalledWith({
|
||||
type: "error",
|
||||
message: "请先点击要替换的监测点",
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user