diff --git a/src/features/online-board/components/BoardDetailsHeader/RegistrationButton.test.tsx b/src/features/online-board/components/BoardDetailsHeader/RegistrationButton.test.tsx new file mode 100644 index 00000000..050f0a33 --- /dev/null +++ b/src/features/online-board/components/BoardDetailsHeader/RegistrationButton.test.tsx @@ -0,0 +1,52 @@ +// @vitest-environment jsdom +import { describe, it, expect, vi, beforeEach } from "vitest"; +import { render, screen, fireEvent } from "@testing-library/react"; +import { RegistrationButton } from "./RegistrationButton.js"; +import type { ISimpleFlight } from "../../types.js"; + +vi.mock("@/i18n/provider.js", () => ({ + useTranslation: () => ({ t: (k: string) => k }), +})); + +function makeFlight(carrier = "SU"): ISimpleFlight { + return { + id: "X", + routeType: "Direct", + flyingTime: "1h", + status: "Scheduled", + flightId: { carrier, flightNumber: "0022", suffix: "", date: "20260417" }, + operatingBy: { carrier, flightNumber: "0022" }, + leg: {} as never, + } as ISimpleFlight; +} + +describe("RegistrationButton", () => { + beforeEach(() => { + Object.defineProperty(window, "open", { value: vi.fn(), writable: true }); + }); + + it("renders label SHARED.ONLINE-REGISTRATION", () => { + render(); + expect(screen.getByText("SHARED.ONLINE-REGISTRATION")).toBeTruthy(); + }); + + it("has data-testid registration-button", () => { + render(); + expect(screen.getByTestId("registration-button")).toBeTruthy(); + }); + + it("click opens aeroflot.ru registration URL for SU", () => { + render(); + fireEvent.click(screen.getByTestId("registration-button")); + const openMock = window.open as ReturnType; + expect(openMock).toHaveBeenCalledTimes(1); + expect(openMock.mock.calls[0]![0]).toContain("aeroflot.ru"); + }); + + it("click does not open anything for AF (no registrationUrl)", () => { + render(); + fireEvent.click(screen.getByTestId("registration-button")); + const openMock = window.open as ReturnType; + expect(openMock).not.toHaveBeenCalled(); + }); +}); diff --git a/src/features/online-board/components/BoardDetailsHeader/RegistrationButton.tsx b/src/features/online-board/components/BoardDetailsHeader/RegistrationButton.tsx new file mode 100644 index 00000000..5fcdb031 --- /dev/null +++ b/src/features/online-board/components/BoardDetailsHeader/RegistrationButton.tsx @@ -0,0 +1,32 @@ +import type { FC } from "react"; +import { useTranslation } from "@/i18n/provider.js"; +import type { ISimpleFlight } from "../../types.js"; +import { AIRLINES } from "./airlines.js"; +import "./actions.scss"; + +export interface RegistrationButtonProps { + flight: ISimpleFlight; +} + +export const RegistrationButton: FC = ({ flight }) => { + const { t } = useTranslation(); + + const handleClick = () => { + const carrier = flight.operatingBy.carrier; + if (!carrier) return; + const config = AIRLINES[carrier]; + if (!config?.registrationUrl) return; + window.open(config.registrationUrl, "_blank", "noopener,noreferrer"); + }; + + return ( + + ); +};