diff --git a/src/features/online-board/components/FullRouteTimeline/detectStationChange.test.ts b/src/features/online-board/components/FullRouteTimeline/detectStationChange.test.ts new file mode 100644 index 00000000..d3504ec1 --- /dev/null +++ b/src/features/online-board/components/FullRouteTimeline/detectStationChange.test.ts @@ -0,0 +1,61 @@ +import { describe, it, expect } from "vitest"; +import { detectStationChange } from "./detectStationChange.js"; +import type { IFlightLegStation } from "../../types.js"; + +function makeStation(overrides: { + cityCode?: string; + airportCode?: string; + terminal?: string; +}): IFlightLegStation { + return { + scheduled: { + airport: "", + airportCode: overrides.airportCode ?? "SVO", + city: "", + cityCode: overrides.cityCode ?? "MOW", + countryCode: "RU", + }, + latest: { + airport: "", + airportCode: overrides.airportCode ?? "SVO", + city: "", + cityCode: overrides.cityCode ?? "MOW", + countryCode: "RU", + }, + dispatch: "", + gate: "", + terminal: overrides.terminal ?? "", + } as IFlightLegStation; +} + +describe("detectStationChange", () => { + it("returns 'noChange' when city/airport/terminal all match", () => { + const a = makeStation({ cityCode: "MOW", airportCode: "SVO", terminal: "D" }); + const b = makeStation({ cityCode: "MOW", airportCode: "SVO", terminal: "D" }); + expect(detectStationChange(a, b)).toBe("noChange"); + }); + + it("returns 'city' when cityCode differs", () => { + const a = makeStation({ cityCode: "MOW", airportCode: "SVO" }); + const b = makeStation({ cityCode: "LED", airportCode: "LED" }); + expect(detectStationChange(a, b)).toBe("city"); + }); + + it("returns 'airport' when cities match but airport differs", () => { + const a = makeStation({ cityCode: "MOW", airportCode: "SVO" }); + const b = makeStation({ cityCode: "MOW", airportCode: "DME" }); + expect(detectStationChange(a, b)).toBe("airport"); + }); + + it("returns 'terminal' when airport matches but terminal differs", () => { + const a = makeStation({ cityCode: "MOW", airportCode: "SVO", terminal: "D" }); + const b = makeStation({ cityCode: "MOW", airportCode: "SVO", terminal: "F" }); + expect(detectStationChange(a, b)).toBe("terminal"); + }); + + it("returns 'noChange' when terminals are both empty strings", () => { + const a = makeStation({ cityCode: "MOW", airportCode: "SVO", terminal: "" }); + const b = makeStation({ cityCode: "MOW", airportCode: "SVO", terminal: "" }); + expect(detectStationChange(a, b)).toBe("noChange"); + }); +}); diff --git a/src/features/online-board/components/FullRouteTimeline/detectStationChange.ts b/src/features/online-board/components/FullRouteTimeline/detectStationChange.ts new file mode 100644 index 00000000..ccf0a2c4 --- /dev/null +++ b/src/features/online-board/components/FullRouteTimeline/detectStationChange.ts @@ -0,0 +1,19 @@ +import type { IFlightLegStation } from "../../types.js"; + +export type StationChange = "city" | "airport" | "terminal" | "noChange"; + +/** + * Detect the kind of transition between two stations by priority: + * city change > airport change > terminal change > no change. + * + * Uses the `scheduled` snapshot for comparisons (stable across updates). + */ +export function detectStationChange( + from: IFlightLegStation, + to: IFlightLegStation, +): StationChange { + if (from.scheduled.cityCode !== to.scheduled.cityCode) return "city"; + if (from.scheduled.airportCode !== to.scheduled.airportCode) return "airport"; + if (from.terminal && to.terminal && from.terminal !== to.terminal) return "terminal"; + return "noChange"; +}