|
|
|
@@ -1,6 +1,14 @@
|
|
|
|
|
/**
|
|
|
|
|
* Tests for PopularRequestsPanel component.
|
|
|
|
|
*
|
|
|
|
|
* Covers all 5 request modes, loading/error states, keyboard
|
|
|
|
|
* accessibility, and the 4-item display limit.
|
|
|
|
|
*
|
|
|
|
|
* @vitest-environment jsdom
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
|
|
|
import { render, screen, waitFor } from "@testing-library/react";
|
|
|
|
|
import userEvent from "@testing-library/user-event";
|
|
|
|
|
import { render, screen, fireEvent } from "@testing-library/react";
|
|
|
|
|
import { PopularRequestsPanel } from "./PopularRequestsPanel";
|
|
|
|
|
import type { PopularRequest } from "../types";
|
|
|
|
|
|
|
|
|
@@ -8,7 +16,6 @@ import type { PopularRequest } from "../types";
|
|
|
|
|
// Mocks
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
// Mock the usePopularRequests hook
|
|
|
|
|
const mockUsePopularRequests = vi.fn<
|
|
|
|
|
() => { requests: PopularRequest[]; loading: boolean; error: Error | null }
|
|
|
|
|
>();
|
|
|
|
@@ -17,7 +24,6 @@ vi.mock("../hooks/usePopularRequests.js", () => ({
|
|
|
|
|
usePopularRequests: () => mockUsePopularRequests(),
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
// Mock i18n
|
|
|
|
|
vi.mock("@/i18n/provider.js", () => ({
|
|
|
|
|
useTranslation: () => ({
|
|
|
|
|
t: (key: string) => key,
|
|
|
|
@@ -25,7 +31,6 @@ vi.mock("@/i18n/provider.js", () => ({
|
|
|
|
|
}),
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
// Mock useCityName
|
|
|
|
|
vi.mock("@/shared/hooks/useDictionaries.js", () => ({
|
|
|
|
|
useCityName: (code: string) => code,
|
|
|
|
|
}));
|
|
|
|
@@ -121,15 +126,14 @@ describe("PopularRequestsPanel", () => {
|
|
|
|
|
|
|
|
|
|
render(<PopularRequestsPanel onRequestClick={vi.fn()} />);
|
|
|
|
|
|
|
|
|
|
expect(screen.getByText("BOARD.POPULAR-CHAPTERS")).toBeInTheDocument();
|
|
|
|
|
// Should render 4 items
|
|
|
|
|
expect(screen.getByText("BOARD.POPULAR-CHAPTERS")).toBeTruthy();
|
|
|
|
|
const items = screen.getAllByRole("button");
|
|
|
|
|
expect(items).toHaveLength(4);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("calls onRequestClick when a flight number item is clicked", async () => {
|
|
|
|
|
it("calls onRequestClick when a flight number item is clicked", () => {
|
|
|
|
|
mockUsePopularRequests.mockReturnValue({
|
|
|
|
|
requests: [mockRequests[0]!],
|
|
|
|
|
requests: [mockRequests[0] as PopularRequest],
|
|
|
|
|
loading: false,
|
|
|
|
|
error: null,
|
|
|
|
|
});
|
|
|
|
@@ -138,34 +142,42 @@ describe("PopularRequestsPanel", () => {
|
|
|
|
|
render(<PopularRequestsPanel onRequestClick={onRequestClick} />);
|
|
|
|
|
|
|
|
|
|
const button = screen.getByRole("button");
|
|
|
|
|
await userEvent.click(button);
|
|
|
|
|
fireEvent.click(button);
|
|
|
|
|
|
|
|
|
|
expect(onRequestClick).toHaveBeenCalledWith(mockRequests[0]);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("renders flight number with carrier and number", () => {
|
|
|
|
|
mockUsePopularRequests.mockReturnValue({
|
|
|
|
|
requests: [mockRequests[0]!],
|
|
|
|
|
requests: [mockRequests[0] as PopularRequest],
|
|
|
|
|
loading: false,
|
|
|
|
|
error: null,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
render(<PopularRequestsPanel onRequestClick={vi.fn()} />);
|
|
|
|
|
const { container } = render(
|
|
|
|
|
<PopularRequestsPanel onRequestClick={vi.fn()} />,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// SU\u00a09027 (non-breaking space)
|
|
|
|
|
expect(screen.getByText("SU\u00a09027")).toBeInTheDocument();
|
|
|
|
|
// The span contains "SU\u00a09027" — check the button text
|
|
|
|
|
const button = screen.getByRole("button");
|
|
|
|
|
expect(button.textContent).toContain("SU");
|
|
|
|
|
expect(button.textContent).toContain("9027");
|
|
|
|
|
// Also check the container has the FLIGHT_NUMBER label
|
|
|
|
|
expect(container.textContent).toContain("BOARD.FLIGHT_NUMBER");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("renders route request with departure and arrival", () => {
|
|
|
|
|
mockUsePopularRequests.mockReturnValue({
|
|
|
|
|
requests: [mockRequests[2]!],
|
|
|
|
|
requests: [mockRequests[2] as PopularRequest],
|
|
|
|
|
loading: false,
|
|
|
|
|
error: null,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
render(<PopularRequestsPanel onRequestClick={vi.fn()} />);
|
|
|
|
|
const { container } = render(
|
|
|
|
|
<PopularRequestsPanel onRequestClick={vi.fn()} />,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
expect(screen.getByText("KUF - ABA")).toBeInTheDocument();
|
|
|
|
|
expect(container.textContent).toContain("KUF - ABA");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("limits display to 4 items even with more data", () => {
|
|
|
|
@@ -203,10 +215,12 @@ describe("PopularRequestsPanel", () => {
|
|
|
|
|
error: null,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
render(<PopularRequestsPanel onRequestClick={vi.fn()} />);
|
|
|
|
|
const { container } = render(
|
|
|
|
|
<PopularRequestsPanel onRequestClick={vi.fn()} />,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
expect(screen.getByText("BOARD.ARRIVAL")).toBeInTheDocument();
|
|
|
|
|
expect(screen.getByText("SVO")).toBeInTheDocument();
|
|
|
|
|
expect(container.textContent).toContain("BOARD.ARRIVAL");
|
|
|
|
|
expect(screen.getByRole("button").textContent).toBe("SVO");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("renders departure request mode", () => {
|
|
|
|
@@ -222,10 +236,12 @@ describe("PopularRequestsPanel", () => {
|
|
|
|
|
error: null,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
render(<PopularRequestsPanel onRequestClick={vi.fn()} />);
|
|
|
|
|
const { container } = render(
|
|
|
|
|
<PopularRequestsPanel onRequestClick={vi.fn()} />,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
expect(screen.getByText("BOARD.DEPARTURE")).toBeInTheDocument();
|
|
|
|
|
expect(screen.getByText("DME")).toBeInTheDocument();
|
|
|
|
|
expect(container.textContent).toContain("BOARD.DEPARTURE");
|
|
|
|
|
expect(screen.getByRole("button").textContent).toBe("DME");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("renders schedule route with correct label", () => {
|
|
|
|
@@ -242,9 +258,11 @@ describe("PopularRequestsPanel", () => {
|
|
|
|
|
error: null,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
render(<PopularRequestsPanel onRequestClick={vi.fn()} />);
|
|
|
|
|
const { container } = render(
|
|
|
|
|
<PopularRequestsPanel onRequestClick={vi.fn()} />,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
expect(screen.getByText("SCHEDULE.SCHEDULE-OUTBOUND")).toBeInTheDocument();
|
|
|
|
|
expect(container.textContent).toContain("SCHEDULE.SCHEDULE-OUTBOUND");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("renders RouteWithBack with full-route label", () => {
|
|
|
|
@@ -261,16 +279,16 @@ describe("PopularRequestsPanel", () => {
|
|
|
|
|
error: null,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
render(<PopularRequestsPanel onRequestClick={vi.fn()} />);
|
|
|
|
|
const { container } = render(
|
|
|
|
|
<PopularRequestsPanel onRequestClick={vi.fn()} />,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
expect(
|
|
|
|
|
screen.getByText("SCHEDULE.SCHEDULE-FULL-ROUTE"),
|
|
|
|
|
).toBeInTheDocument();
|
|
|
|
|
expect(container.textContent).toContain("SCHEDULE.SCHEDULE-FULL-ROUTE");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("supports keyboard activation (Enter key)", async () => {
|
|
|
|
|
it("supports keyboard activation (Enter key)", () => {
|
|
|
|
|
mockUsePopularRequests.mockReturnValue({
|
|
|
|
|
requests: [mockRequests[0]!],
|
|
|
|
|
requests: [mockRequests[0] as PopularRequest],
|
|
|
|
|
loading: false,
|
|
|
|
|
error: null,
|
|
|
|
|
});
|
|
|
|
@@ -279,8 +297,23 @@ describe("PopularRequestsPanel", () => {
|
|
|
|
|
render(<PopularRequestsPanel onRequestClick={onRequestClick} />);
|
|
|
|
|
|
|
|
|
|
const button = screen.getByRole("button");
|
|
|
|
|
button.focus();
|
|
|
|
|
await userEvent.keyboard("{Enter}");
|
|
|
|
|
fireEvent.keyDown(button, { key: "Enter" });
|
|
|
|
|
|
|
|
|
|
expect(onRequestClick).toHaveBeenCalledWith(mockRequests[0]);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("supports keyboard activation (Space key)", () => {
|
|
|
|
|
mockUsePopularRequests.mockReturnValue({
|
|
|
|
|
requests: [mockRequests[0] as PopularRequest],
|
|
|
|
|
loading: false,
|
|
|
|
|
error: null,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const onRequestClick = vi.fn();
|
|
|
|
|
render(<PopularRequestsPanel onRequestClick={onRequestClick} />);
|
|
|
|
|
|
|
|
|
|
const button = screen.getByRole("button");
|
|
|
|
|
fireEvent.keyDown(button, { key: " " });
|
|
|
|
|
|
|
|
|
|
expect(onRequestClick).toHaveBeenCalledWith(mockRequests[0]);
|
|
|
|
|
});
|
|
|
|
|