refactor: colocate frontend component files
Frontend security / security (push) Successful in 9s
Frontend verify / verify (push) Successful in 5m10s
Conventional commits / commits (pull_request) Successful in 25s
Frontend security / security (pull_request) Successful in 9s
Frontend verify / verify (pull_request) Successful in 5m10s

This commit is contained in:
2026-09-23 08:34:58 +03:00
parent 85fcfe3d07
commit b987fd8e78
190 changed files with 131 additions and 108 deletions
@@ -0,0 +1,165 @@
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.08.2026 · RU000A0JX0J2")).toBeVisible();
expect(screen.getAllByText(/RU000A0JX0J2$/)).toHaveLength(1);
expect(screen.getByText("25.08.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("За выбранный период событий не найдено"),
).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();
});
});