Align flights map date window with Angular

This commit is contained in:
2026-05-06 12:53:21 +03:00
parent 19ae50af80
commit eda44d4218
2 changed files with 68 additions and 16 deletions
@@ -8,7 +8,10 @@ import { FlightsMapStartPage } from "./FlightsMapStartPage.js";
import type * as DictionariesModuleNS from "@/shared/dictionaries/index.js";
import { transformDictionaries } from "@/shared/dictionaries/index.js";
import type { IDictionaries, IRawDictionaries } from "@/shared/dictionaries/index.js";
import type { FlightsMapSearchParams } from "../types.js";
import type {
FlightsMapCalendarParams,
FlightsMapSearchParams,
} from "../types.js";
import {
resetCrossSectionStore,
setMapFilter,
@@ -82,8 +85,12 @@ vi.mock("../hooks/useFlightsMapSearch.js", () => ({
},
}));
const calendarCalls: Array<FlightsMapCalendarParams | null> = [];
vi.mock("../hooks/useFlightsMapCalendar.js", () => ({
useFlightsMapCalendar: () => ({ availableDays: [] }),
useFlightsMapCalendar: (params: FlightsMapCalendarParams | null) => {
calendarCalls.push(params);
return { availableDays: [] };
},
}));
const dictState: {
@@ -984,6 +991,7 @@ describe("§4.1.24.5 R44: routes API uses [-1d, +6mo] date window", () => {
beforeEach(() => {
lastMapFilterProps = null;
searchCalls.length = 0;
calendarCalls.length = 0;
dictState.dictionaries = buildDictionaries();
dictState.loading = false;
dictState.error = null;
@@ -1000,21 +1008,36 @@ describe("§4.1.24.5 R44: routes API uses [-1d, +6mo] date window", () => {
expect(callsWithDeparture).toHaveLength(0);
});
it("4.1.24-R44: dateFrom/dateTo span today to +6 months when departure is set", () => {
it("4.1.24-R44: dateFrom starts yesterday and dateTo spans to +6 months when departure is set", () => {
resetCrossSectionStore();
setMapFilter({
departure: "MOW", arrival: null, date: null,
showInternal: false, showInternational: false, showTransfers: false,
});
render(<FlightsMapStartPage />);
render(<FlightsMapStartPage today="20260506" />);
const callsWithDeparture = searchCalls.filter((p) => p?.departure === "MOW");
if (callsWithDeparture.length > 0) {
const call = callsWithDeparture[0]!;
const today = new Date();
const expectedYear = today.getFullYear().toString();
expect(call.dateFrom.slice(0, 4)).toBe(expectedYear);
expect(call.dateTo.slice(0, 4)).toMatch(/^\d{4}$/);
}
expect(callsWithDeparture).not.toHaveLength(0);
expect(callsWithDeparture[0]).toMatchObject({
departure: "MOW",
dateFrom: "20260505",
dateTo: "20261105",
});
});
it("4.1.24-R44: calendar availability request starts from the same yesterday anchor", () => {
resetCrossSectionStore();
setMapFilter({
departure: "MOW", arrival: null, date: null,
showInternal: false, showInternational: false, showTransfers: false,
});
render(<FlightsMapStartPage today="20260506" />);
const callsWithDeparture = calendarCalls.filter((p) => p?.departure === "MOW");
expect(callsWithDeparture).not.toHaveLength(0);
expect(callsWithDeparture[0]).toMatchObject({
departure: "MOW",
date: "20260505",
});
});
});
@@ -63,6 +63,18 @@ function addMonthsYyyymmdd(base: string, months: number): string {
return `${ry}${rm}${rd}`;
}
function addDaysYyyymmdd(base: string, days: number): string {
const y = Number(base.slice(0, 4));
const m = Number(base.slice(4, 6)) - 1;
const d = Number(base.slice(6, 8));
const date = new Date(y, m, d);
date.setDate(date.getDate() + days);
const ry = date.getFullYear().toString();
const rm = (date.getMonth() + 1).toString().padStart(2, "0");
const rd = date.getDate().toString().padStart(2, "0");
return `${ry}${rm}${rd}`;
}
// ---------------------------------------------------------------------------
// Component
// ---------------------------------------------------------------------------
@@ -94,6 +106,10 @@ export const FlightsMapStartPage: FC<FlightsMapStartPageProps> = ({
// there but always called to keep hook order stable.
const fallbackTodayYmd = useRef(todayYyyymmdd()).current;
const todayYmd = today ?? fallbackTodayYmd;
const searchDateFromYmd = useMemo(
() => addDaysYyyymmdd(todayYmd, -1),
[todayYmd],
);
const { t } = useTranslation();
const { language } = useLocale();
@@ -171,23 +187,36 @@ export const FlightsMapStartPage: FC<FlightsMapStartPageProps> = ({
return {
departure: filterState.departure,
arrival: filterState.arrival,
dateFrom: todayYmd,
dateTo: addMonthsYyyymmdd(todayYmd, 6),
// Angular starts the flights-map destinations window at minDateCalendar
// (today - 1 day). Keeping this aligned preserves Moscow domestic
// airport-internal directions such as DME-SVO and ZIA-SVO.
dateFrom: searchDateFromYmd,
dateTo: addMonthsYyyymmdd(searchDateFromYmd, 6),
connections: filterState.arrival ? effectiveConnections : 0,
};
}, [filterState.departure, filterState.arrival, effectiveConnections, todayYmd]);
}, [
filterState.departure,
filterState.arrival,
effectiveConnections,
searchDateFromYmd,
]);
// Build calendar params
const calendarParams = useMemo<FlightsMapCalendarParams | null>(() => {
if (!filterState.departure) return null;
return {
date: todayYmd,
date: searchDateFromYmd,
departure: filterState.departure,
arrival: filterState.arrival,
connections: filterState.arrival ? filterState.connections : false,
};
}, [filterState.departure, filterState.arrival, filterState.connections, todayYmd]);
}, [
filterState.departure,
filterState.arrival,
filterState.connections,
searchDateFromYmd,
]);
const { routes, loading, error } = useFlightsMapSearch(searchParams);
const { availableDays } = useFlightsMapCalendar(calendarParams);