diff --git a/src/features/online-board/components/FullRouteTimeline/StationChange.test.tsx b/src/features/online-board/components/FullRouteTimeline/StationChange.test.tsx new file mode 100644 index 00000000..a51ed8d5 --- /dev/null +++ b/src/features/online-board/components/FullRouteTimeline/StationChange.test.tsx @@ -0,0 +1,72 @@ +// @vitest-environment jsdom +import { describe, it, expect } from "vitest"; +import { render, screen } from "@testing-library/react"; +import { StationChange } from "./StationChange.js"; +import type { IFlightLegStation } from "../../types.js"; + +function makeStation(overrides: { + city?: string; + cityCode?: string; + airportCode?: string; + terminal?: string; +}): IFlightLegStation { + return { + scheduled: { + airport: "", + airportCode: overrides.airportCode ?? "SVO", + city: overrides.city ?? "Moscow", + cityCode: overrides.cityCode ?? "MOW", + countryCode: "RU", + }, + latest: { + airport: "", + airportCode: overrides.airportCode ?? "SVO", + city: overrides.city ?? "Moscow", + cityCode: overrides.cityCode ?? "MOW", + countryCode: "RU", + }, + dispatch: "", + gate: "", + terminal: overrides.terminal ?? "", + } as IFlightLegStation; +} + +describe("StationChange", () => { + it("renders a single Station when there is no change (noChange)", () => { + const a = makeStation({ city: "Moscow", cityCode: "MOW", airportCode: "SVO", terminal: "D" }); + const b = makeStation({ city: "Moscow", cityCode: "MOW", airportCode: "SVO", terminal: "D" }); + const { container } = render(); + // Single Station rendered (no station-change wrapper) + expect(container.querySelector(".station-change")).toBeNull(); + expect(container.querySelector(".station")).not.toBeNull(); + }); + + it("renders two Stations separated by arrow when city differs", () => { + const a = makeStation({ city: "Moscow", cityCode: "MOW", airportCode: "SVO" }); + const b = makeStation({ city: "Saint Petersburg", cityCode: "LED", airportCode: "LED" }); + const { container } = render(); + expect(container.querySelector(".station-change--city")).not.toBeNull(); + expect(screen.getByText("Moscow")).toBeTruthy(); + expect(screen.getByText("Saint Petersburg")).toBeTruthy(); + expect(container.querySelector(".station-change__arrow")).not.toBeNull(); + }); + + it("renders airport change format when airports differ but city matches", () => { + const a = makeStation({ city: "Moscow", cityCode: "MOW", airportCode: "SVO", terminal: "D" }); + const b = makeStation({ city: "Moscow", cityCode: "MOW", airportCode: "DME" }); + const { container } = render(); + expect(container.querySelector(".station-change--airport")).not.toBeNull(); + expect(screen.getByText("Moscow")).toBeTruthy(); + expect(screen.getByText("SVO/D")).toBeTruthy(); + expect(screen.getByText("DME")).toBeTruthy(); + }); + + it("renders terminal change format when only terminal differs", () => { + const a = makeStation({ city: "Moscow", cityCode: "MOW", airportCode: "SVO", terminal: "D" }); + const b = makeStation({ city: "Moscow", cityCode: "MOW", airportCode: "SVO", terminal: "F" }); + const { container } = render(); + expect(container.querySelector(".station-change--terminal")).not.toBeNull(); + expect(screen.getByText("SVO/D")).toBeTruthy(); + expect(screen.getByText("SVO/F")).toBeTruthy(); + }); +}); diff --git a/src/features/online-board/components/FullRouteTimeline/StationChange.tsx b/src/features/online-board/components/FullRouteTimeline/StationChange.tsx new file mode 100644 index 00000000..7cbf15a3 --- /dev/null +++ b/src/features/online-board/components/FullRouteTimeline/StationChange.tsx @@ -0,0 +1,42 @@ +import type { FC } from "react"; +import type { IFlightLegStation } from "../../types.js"; +import { Station } from "./Station.js"; +import { detectStationChange } from "./detectStationChange.js"; + +export interface StationChangeProps { + from: IFlightLegStation; + to: IFlightLegStation; +} + +function formatAirportWithTerminal(station: IFlightLegStation): string { + const code = station.scheduled.airportCode; + return station.terminal ? `${code}/${station.terminal}` : code; +} + +export const StationChange: FC = ({ from, to }) => { + const changeType = detectStationChange(from, to); + + if (changeType === "noChange") { + return ; + } + + if (changeType === "city") { + return ( +
+ + + +
+ ); + } + + // airport or terminal — same city + return ( +
+ {from.scheduled.city} + {formatAirportWithTerminal(from)} + + {formatAirportWithTerminal(to)} +
+ ); +};