Add RegistrationButton component

This commit is contained in:
2026-04-17 01:28:13 +03:00
parent 369b413a32
commit d0c50e81c5
2 changed files with 84 additions and 0 deletions
@@ -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(<RegistrationButton flight={makeFlight()} />);
expect(screen.getByText("SHARED.ONLINE-REGISTRATION")).toBeTruthy();
});
it("has data-testid registration-button", () => {
render(<RegistrationButton flight={makeFlight()} />);
expect(screen.getByTestId("registration-button")).toBeTruthy();
});
it("click opens aeroflot.ru registration URL for SU", () => {
render(<RegistrationButton flight={makeFlight("SU")} />);
fireEvent.click(screen.getByTestId("registration-button"));
const openMock = window.open as ReturnType<typeof vi.fn>;
expect(openMock).toHaveBeenCalledTimes(1);
expect(openMock.mock.calls[0]![0]).toContain("aeroflot.ru");
});
it("click does not open anything for AF (no registrationUrl)", () => {
render(<RegistrationButton flight={makeFlight("AF")} />);
fireEvent.click(screen.getByTestId("registration-button"));
const openMock = window.open as ReturnType<typeof vi.fn>;
expect(openMock).not.toHaveBeenCalled();
});
});
@@ -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<RegistrationButtonProps> = ({ 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 (
<button
type="button"
className="flight-action-btn flight-action-btn--blue-light"
data-testid="registration-button"
onClick={handleClick}
>
{t("SHARED.ONLINE-REGISTRATION")}
</button>
);
};