Files
frontend/src/pages/account-events/ui/AccountEventsPage.test.tsx
T

166 lines
4.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { MantineProvider } from "@mantine/core";
import { fireEvent, render, screen } from "@testing-library/react";
import { MemoryRouter, Route, Routes } from "react-router";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { useBrokerageEvents } from "@/entities/brokerage-event";
import { AccountEventsPage } from "./AccountEventsPage";
vi.mock("@/entities/brokerage-event", async (importOriginal) => ({
...(await importOriginal<typeof import("@/entities/brokerage-event")>()),
useBrokerageEvents: vi.fn(),
}));
const query = vi.mocked(useBrokerageEvents);
function renderPage() {
return render(
<MantineProvider>
<MemoryRouter>
<AccountEventsPage />
</MemoryRouter>
</MantineProvider>,
);
}
describe("AccountEventsPage", () => {
beforeEach(() => {
query.mockReturnValue({
data: {
accountId: "account",
calculatedAt: "2026-08-14T00:00:00Z",
events: [],
},
isError: false,
isLoading: false,
refetch: vi.fn(),
} as never);
});
it("passes the selected route account to the query", () => {
render(
<MantineProvider>
<MemoryRouter initialEntries={["/accounts/selected-account/events"]}>
<Routes>
<Route
path="/accounts/:accountId/events"
element={<AccountEventsPage />}
/>
</Routes>
</MemoryRouter>
</MantineProvider>,
);
expect(query).toHaveBeenCalledWith("selected-account");
});
it("keeps the loading fallback when no result or account is available", () => {
query.mockReturnValue({
data: undefined,
isError: false,
isLoading: false,
refetch: vi.fn(),
} as never);
renderPage();
expect(query).toHaveBeenCalledWith(undefined);
expect(screen.getByRole("status", { name: "Загрузка" })).toHaveAttribute(
"aria-busy",
"true",
);
});
it("renders events and marks an offer without an amount", () => {
query.mockReturnValue({
data: {
accountId: "account",
calculatedAt: "2026-08-14T00:00:00Z",
events: [
{
date: "2026-08-20",
dateKind: "event",
displayName: "ОФЗ 26238",
figi: "FIGI",
instrumentUid: "UID",
projectedAmount: { currency: "RUB", value: "1250" },
ticker: "OFZ",
type: "coupon",
logoName: "ofz.png",
isin: "RU000A0JX0J2",
},
{
date: "2026-08-25",
dateKind: "event",
displayName: "ОФЗ 26238",
figi: "FIGI",
instrumentUid: "UID",
projectedAmount: null,
ticker: "OFZ",
type: "offer",
logoName: null,
isin: null,
},
],
},
isError: false,
isLoading: false,
refetch: vi.fn(),
} as never);
const { container } = renderPage();
expect(screen.getByText("1 250 ₽")).toBeInTheDocument();
expect(screen.getByText("Сумма неизвестна")).toBeInTheDocument();
expect(screen.getByText("Купон · ОФЗ 26238")).toBeVisible();
expect(screen.getByText("Оферта · ОФЗ 26238")).toBeVisible();
expect(screen.getByText("20 авг. 2026 г. · RU000A0JX0J2")).toBeVisible();
expect(screen.getAllByText(/RU000A0JX0J2$/)).toHaveLength(1);
expect(screen.getByText("25 авг. 2026 г.")).toBeVisible();
expect(screen.queryByText(/Дата события/)).not.toBeInTheDocument();
expect(screen.getAllByText("Ожидаемая сумма")).toHaveLength(2);
const logo = container.querySelector("img");
expect(logo).toHaveAttribute(
"src",
"https://invest-brands.cdn-tinkoff.ru/ofzx160.png",
);
expect(screen.getAllByText("O")).toHaveLength(1);
if (!logo) throw new Error("Expected the event logo");
fireEvent.error(logo);
expect(container.querySelector("img")).toBeNull();
expect(screen.getAllByText("O")).toHaveLength(2);
});
it("renders empty and retryable error states", () => {
const refetch = vi.fn();
const { rerender } = renderPage();
expect(
screen.getByText("На ближайшие 30 дней событий не найдено"),
).toBeInTheDocument();
query.mockReturnValue({
data: undefined,
isError: true,
isLoading: false,
refetch,
} as never);
rerender(
<MantineProvider>
<MemoryRouter>
<AccountEventsPage />
</MemoryRouter>
</MantineProvider>,
);
screen.getByRole("button", { name: "Повторить" }).click();
expect(refetch).toHaveBeenCalledOnce();
});
it("shows a structural busy state before events are available", () => {
query.mockReturnValue({
data: undefined,
isError: false,
isLoading: true,
refetch: vi.fn(),
} as never);
renderPage();
const status = screen.getByRole("status", { name: "Загрузка" });
expect(status).toHaveAttribute("aria-busy", "true");
expect(status.querySelector("button")).toBeNull();
});
});