From 6f634092b28a4a670cf8ff0d338c73e8093b0f28 Mon Sep 17 00:00:00 2001 From: gnezim Date: Sat, 18 Apr 2026 13:38:15 +0300 Subject: [PATCH] Fix schedule search endpoint (GET not POST, dateTo + 1 day) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- src/features/schedule/api.test.ts | 14 +++++++----- src/features/schedule/api.ts | 36 ++++++++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/features/schedule/api.test.ts b/src/features/schedule/api.test.ts index c6344eed..8ab33590 100644 --- a/src/features/schedule/api.test.ts +++ b/src/features/schedule/api.test.ts @@ -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 () => { diff --git a/src/features/schedule/api.ts b/src/features/schedule/api.ts index bb52ac5c..bc33e890 100644 --- a/src/features/schedule/api.ts +++ b/src/features/schedule/api.ts @@ -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 { - return client.post(`flights/1/${client.locale}/schedule`, params); + const query: Record = { + 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( + `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 ?? ""}`; } /**