Fix schedule search endpoint (GET not POST, dateTo + 1 day)

Angular's ScheduleApiService.getFlights uses GET with query params
and a half-open date interval (sends dateTo = requested end + 1 day).
React sent POST with a JSON body matching the params verbatim, which
returned HTTP 500 from the backend.

searchSchedule now:
- GETs flights/1/{lang}/schedule with ?departure=...&arrival=...
- extends dateTo by one day
- coerces connections to '0'/'1' and drops empty timeFrom/timeTo

Verified the call returns 200 with real flight data for
SVO→LED 2026-04-18..2026-04-25. Updated the api tests accordingly.
This commit is contained in:
2026-04-18 13:38:15 +03:00
parent 08bddc0db6
commit 6f634092b2
2 changed files with 42 additions and 8 deletions
+9 -5
View File
@@ -69,7 +69,7 @@ const DAYS_RESPONSE: IScheduleDaysResponse = {
// ---------------------------------------------------------------------------
describe("searchSchedule", () => {
it("sends POST to schedule/1", async () => {
it("sends GET to schedule/1 with query params", async () => {
const { client, mockFetch } = createMockClient(SCHEDULE_RESPONSE);
const params: IScheduleSearchRequest = {
@@ -83,10 +83,10 @@ describe("searchSchedule", () => {
const url = extractUrl(mockFetch);
expect(url.pathname).toBe("/flights/1/ru/schedule");
expect(extractMethod(mockFetch)).toBe("POST");
expect(extractMethod(mockFetch)).toBe("GET");
});
it("sends params as JSON body", async () => {
it("advances dateTo by 1 day (half-open interval)", async () => {
const { client, mockFetch } = createMockClient(SCHEDULE_RESPONSE);
const params: IScheduleSearchRequest = {
@@ -99,8 +99,12 @@ describe("searchSchedule", () => {
await searchSchedule(client, params);
const body = extractBody(mockFetch);
expect(body).toEqual(params);
const url = extractUrl(mockFetch);
expect(url.searchParams.get("departure")).toBe("SVO");
expect(url.searchParams.get("arrival")).toBe("LED");
expect(url.searchParams.get("dateFrom")).toBe("2025-01-15");
expect(url.searchParams.get("dateTo")).toBe("2025-01-17");
expect(url.searchParams.get("connections")).toBe("1");
});
it("returns the deserialized response", async () => {
+33 -3
View File
@@ -22,15 +22,45 @@ import type {
/**
* Search schedule flights.
* Maps to: `POST schedule/1` with body parameters.
* Maps to: `GET schedule/1?departure=SVO&arrival=LED&dateFrom=2026-04-18&dateTo=2026-04-26&...`
*
* The API response is an array of flight objects (IFlight[]).
* Mirrors Angular's ScheduleApiService.getFlights which:
* - uses GET with query params (not POST with JSON body)
* - sends dateTo = requested end + 1 day (half-open interval)
* - coerces `connections` to a string ('0' / '1')
* - drops empty timeFrom/timeTo
*/
export async function searchSchedule(
client: ApiClient,
params: IScheduleSearchRequest,
): Promise<IScheduleResponse> {
return client.post<IScheduleResponse>(`flights/1/${client.locale}/schedule`, params);
const query: Record<string, string> = {
departure: params.departure,
arrival: params.arrival,
dateFrom: params.dateFrom,
dateTo: addOneDayIso(params.dateTo),
connections: String(params.connections ?? 1),
};
if (params.timeFrom) query["timeFrom"] = params.timeFrom;
if (params.timeTo) query["timeTo"] = params.timeTo;
if (params.attribute) query["attribute"] = String(params.attribute);
return client.get<IScheduleResponse>(
`flights/1/${client.locale}/schedule`,
query,
);
}
/** Return the date one day after a yyyy-MM-dd string (passthrough on bad input). */
function addOneDayIso(iso: string): string {
const m = /^(\d{4})-(\d{2})-(\d{2})(.*)$/.exec(iso);
if (!m) return iso;
const [, y, mm, dd, tail] = m;
const d = new Date(Number(y), Number(mm) - 1, Number(dd));
d.setDate(d.getDate() + 1);
const ny = d.getFullYear().toString();
const nm = (d.getMonth() + 1).toString().padStart(2, "0");
const nd = d.getDate().toString().padStart(2, "0");
return `${ny}-${nm}-${nd}${tail ?? ""}`;
}
/**