Test FlightsMapStartPage marker construction from dictionaries

This commit is contained in:
2026-04-17 08:46:43 +03:00
parent 1f24ee7159
commit a9b47036b5
2 changed files with 90 additions and 15 deletions
@@ -23,8 +23,12 @@ vi.mock("./ClientOnly.js", () => ({
ClientOnly: ({ children }: { children: React.ReactNode }) => <>{children}</>,
}));
let lastMapCanvasProps: Record<string, unknown> | null = null;
vi.mock("./MapCanvas.js", () => ({
MapCanvas: () => <div data-testid="map-canvas" />,
MapCanvas: (props: Record<string, unknown>) => {
lastMapCanvasProps = props;
return <div data-testid="map-canvas" />;
},
}));
vi.mock("./FlightsMapFilter.js", () => ({
@@ -43,10 +47,23 @@ vi.mock("../hooks/useFlightsMapCalendar.js", () => ({
useFlightsMapCalendar: () => ({ availableDays: [] }),
}));
const dictState = {
dictionaries: null as unknown,
const dictState: {
dictionaries:
| null
| {
cities: Array<{
code: string;
name: string;
country_code: string;
location: { lat: number; lon: number };
}>;
};
loading: boolean;
error: Error | null;
} = {
dictionaries: null,
loading: true,
error: null as Error | null,
error: null,
};
vi.mock("@/shared/dictionaries/index.js", () => ({
useDictionaries: () => dictState,
@@ -74,17 +91,73 @@ describe("FlightsMapStartPage — dictionaries integration", () => {
it("does not show the loader once dictionaries resolve", () => {
dictState.loading = false;
dictState.dictionaries = {
regions: [],
countries: [],
cities: [],
airports: [],
cityByCode: new Map(),
airportByCode: new Map(),
ruCityCodes: new Set(),
otherCityCodes: new Set(),
};
dictState.dictionaries = { cities: [] };
render(<FlightsMapStartPage />);
expect(screen.queryByTestId("map-loader")).toBeNull();
});
});
describe("FlightsMapStartPage — markers from dictionaries", () => {
beforeEach(() => {
lastMapCanvasProps = null;
dictState.dictionaries = null;
dictState.loading = false;
dictState.error = null;
});
it("maps cities to IMapMarker[] with zoomLevel and countryType", () => {
dictState.dictionaries = {
cities: [
{
code: "MOW",
name: "Москва",
country_code: "RU",
location: { lat: 55, lon: 37 },
},
{
code: "PAR",
name: "Париж",
country_code: "FR",
location: { lat: 48, lon: 2 },
},
],
};
render(<FlightsMapStartPage />);
const markers = lastMapCanvasProps!["markers"] as Array<Record<string, unknown>>;
expect(markers).toHaveLength(2);
const mow = markers.find((m) => m["id"] === "MOW")!;
expect(mow["countryType"]).toBe("ru");
expect(mow["zoomLevel"]).toBe(2);
expect(mow["label"]).toBe("Москва");
const par = markers.find((m) => m["id"] === "PAR")!;
expect(par["countryType"]).toBe("other");
expect(par["zoomLevel"]).toBe(6);
});
it("drops cities whose location is missing or invalid", () => {
dictState.dictionaries = {
cities: [
{ code: "MOW", name: "Москва", country_code: "RU", location: { lat: 55, lon: 37 } },
{ code: "BAD", name: "Bad", country_code: "RU", location: { lat: Number.NaN, lon: 0 } },
],
};
render(<FlightsMapStartPage />);
const markers = lastMapCanvasProps!["markers"] as Array<Record<string, unknown>>;
expect(markers.map((m) => m["id"])).toEqual(["MOW"]);
});
it("passes domestic/international toggles through to MapCanvas", () => {
dictState.dictionaries = { cities: [] };
render(<FlightsMapStartPage />);
expect(lastMapCanvasProps!["domestic"]).toBe(false);
expect(lastMapCanvasProps!["international"]).toBe(false);
});
});
@@ -137,7 +137,9 @@ export const FlightsMapStartPage: FC = () => {
.filter(
(c) =>
typeof c.location?.lat === "number" &&
typeof c.location?.lon === "number",
typeof c.location?.lon === "number" &&
Number.isFinite(c.location.lat) &&
Number.isFinite(c.location.lon),
)
.map((city) => {
const isHighlighted =