From 9234dcd2e12dfc91ac7296bf7f990bfc5069ed0c Mon Sep 17 00:00:00 2001 From: gnezim Date: Fri, 17 Apr 2026 01:22:15 +0300 Subject: [PATCH] Add canRegister visibility logic --- .../visibility/registrationVisibility.test.ts | 75 +++++++++++++++++++ .../visibility/registrationVisibility.ts | 22 ++++++ 2 files changed, 97 insertions(+) create mode 100644 src/features/online-board/components/BoardDetailsHeader/visibility/registrationVisibility.test.ts create mode 100644 src/features/online-board/components/BoardDetailsHeader/visibility/registrationVisibility.ts diff --git a/src/features/online-board/components/BoardDetailsHeader/visibility/registrationVisibility.test.ts b/src/features/online-board/components/BoardDetailsHeader/visibility/registrationVisibility.test.ts new file mode 100644 index 00000000..2cc723bb --- /dev/null +++ b/src/features/online-board/components/BoardDetailsHeader/visibility/registrationVisibility.test.ts @@ -0,0 +1,75 @@ +import { describe, it, expect } from "vitest"; +import { canRegister } from "./registrationVisibility.js"; +import { AIRLINES } from "../airlines.js"; +import type { ISimpleFlight, FlightTransitionStatus } from "../../../types.js"; + +function makeFlight(carrier: string, regStatus?: FlightTransitionStatus): ISimpleFlight { + const legBase = { + arrival: { + scheduled: { airport: "", airportCode: "", city: "", cityCode: "", countryCode: "" }, + latest: { airport: "", airportCode: "", city: "", cityCode: "", countryCode: "" }, + dispatch: "", gate: "", terminal: "", + times: { scheduledArrival: { dayChange: { value: 0, title: "" }, local: "", localTime: "", tzOffset: 0, utc: "" } }, + }, + dayChange: 0, + departure: { + scheduled: { airport: "", airportCode: "", city: "", cityCode: "", countryCode: "" }, + latest: { airport: "", airportCode: "", city: "", cityCode: "", countryCode: "" }, + dispatch: "", gate: "", terminal: "", checkingStatus: "Scheduled", parkingStand: "", + times: { scheduledDeparture: { dayChange: { value: 0, title: "" }, local: "", localTime: "", tzOffset: 0, utc: "" } }, + }, + equipment: {}, + flags: { checkinAvailable: false, returnToAirport: false, routeChanged: false }, + flyingTime: "1h", + index: 0, + operatingBy: {}, + status: "Scheduled" as const, + updated: "", + }; + + const leg = regStatus + ? { + ...legBase, + transition: { + registration: { + start: {} as never, + end: {} as never, + status: regStatus, + isActual: true, + }, + }, + } + : legBase; + + return { + id: "X-1", + routeType: "Direct", + flyingTime: "1h", + status: "Scheduled", + flightId: { carrier, flightNumber: "0022", suffix: "", date: "20260417" }, + operatingBy: { carrier, flightNumber: "0022" }, + leg, + } as ISimpleFlight; +} + +describe("canRegister", () => { + it("returns true for SU with InProgress registration", () => { + expect(canRegister(makeFlight("SU", "InProgress"), AIRLINES)).toBe(true); + }); + + it("returns false for SU without InProgress registration", () => { + expect(canRegister(makeFlight("SU", "Scheduled"), AIRLINES)).toBe(false); + }); + + it("returns false for SU with no registration transition", () => { + expect(canRegister(makeFlight("SU"), AIRLINES)).toBe(false); + }); + + it("returns false for AF (no registration URL)", () => { + expect(canRegister(makeFlight("AF", "InProgress"), AIRLINES)).toBe(false); + }); + + it("returns false for unknown carrier", () => { + expect(canRegister(makeFlight("XX", "InProgress"), AIRLINES)).toBe(false); + }); +}); diff --git a/src/features/online-board/components/BoardDetailsHeader/visibility/registrationVisibility.ts b/src/features/online-board/components/BoardDetailsHeader/visibility/registrationVisibility.ts new file mode 100644 index 00000000..19ce7ec5 --- /dev/null +++ b/src/features/online-board/components/BoardDetailsHeader/visibility/registrationVisibility.ts @@ -0,0 +1,22 @@ +import type { ISimpleFlight } from "../../../types.js"; +import type { AirlineConfig } from "../airlines.js"; + +/** + * Registration button is visible when: + * - the operating carrier has a registrationUrl + * - the first leg's registration transition status is "InProgress" + */ +export function canRegister( + flight: ISimpleFlight, + airlineConfig: Record, +): boolean { + const carrier = flight.operatingBy.carrier; + if (!carrier) return false; + const config = airlineConfig[carrier]; + if (!config?.registrationUrl) return false; + + const leg = flight.routeType === "Direct" ? flight.leg : flight.legs[0]; + if (!leg) return false; + + return leg.transition?.registration?.status === "InProgress"; +}