Fix lint warnings and test environment for Phase 5 tests

Remove unused type alias, unused variable, add jsdom environment
directive, and use container.textContent for cross-element text
assertions.
This commit is contained in:
2026-04-15 10:09:56 +03:00
parent 78205c378e
commit 031ad7c15d
3 changed files with 70 additions and 41 deletions
@@ -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]);
});
+4 -6
View File
@@ -1,3 +1,7 @@
/**
* @vitest-environment jsdom
*/
import { describe, it, expect, beforeEach, vi } from "vitest";
import { renderHook, act } from "@testing-library/react";
import { useSearchHistory } from "./useSearchHistory";
@@ -42,12 +46,6 @@ const routeItem: SearchHistoryItem = {
label: "SVO - JFK",
};
const scheduleItem: SearchHistoryItem = {
type: "schedule-route",
url: "/ru/schedule/route/SVO-LED/20250601-20250607",
label: "SVO - LED",
};
// ---------------------------------------------------------------------------
// Tests
// ---------------------------------------------------------------------------
-2
View File
@@ -48,8 +48,6 @@ const searchHistoryItemSchema = z.object({
const searchHistorySchema = z.array(searchHistoryItemSchema);
type SearchHistoryData = z.infer<typeof searchHistorySchema>;
// ---------------------------------------------------------------------------
// Storage key
// ---------------------------------------------------------------------------