Files
frontend/src/pages/account/ui/AccountPage.test.tsx
T
2026-08-13 22:45:00 +03:00

118 lines
3.4 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 { cleanup, render, screen } from "@testing-library/react";
import { MemoryRouter } from "react-router";
import { afterEach, describe, expect, it, vi } from "vitest";
import type { Portfolio } from "../../../entities/portfolio";
import {
AccountPageEmpty,
AccountPageError,
AccountPageLoaded,
AccountPageLoading,
} from "./AccountPage";
function renderPage(ui: React.ReactNode) {
return render(
<MantineProvider>
<MemoryRouter>{ui}</MemoryRouter>
</MantineProvider>,
);
}
const portfolio: Portfolio = {
lastSuccessfulAt: "2026-08-13T10:00:00Z",
isStale: true,
totalsByCurrency: [{ currency: "RUB", value: "1234.5" }],
positions: [
{
figi: "FIGI-2",
displayName: "Вторая",
type: "STOCK",
quantity: "2",
currentValue: null,
averagePurchasePrice: null,
absoluteReturn: null,
},
{
figi: "FIGI-1",
displayName: "Первая",
type: "BOND",
quantity: "1",
currentValue: { currency: "RUB", value: "10" },
averagePurchasePrice: null,
absoluteReturn: { currency: "RUB", value: "-1" },
},
],
cashBalances: [{ currency: "USD", value: "0.5" }],
};
describe("AccountPage states", () => {
afterEach(cleanup);
it("renders loading and empty states", () => {
renderPage(<AccountPageLoading />);
expect(screen.getByRole("status")).toBeInTheDocument();
renderPage(<AccountPageEmpty />);
expect(
screen.getByRole("heading", { name: "Портфель пока пуст" }),
).toBeInTheDocument();
});
it("renders allowed error actions", () => {
const retry = vi.fn();
renderPage(<AccountPageError code="NOT_FOUND" retry={retry} />);
expect(screen.getByRole("link", { name: "К счетам" })).toHaveAttribute(
"href",
"/accounts",
);
renderPage(<AccountPageError code="TBANK_NOT_CONNECTED" retry={retry} />);
expect(
screen.getByRole("link", { name: "Открыть настройки T-Bank" }),
).toHaveAttribute("href", "/settings");
renderPage(<AccountPageError code="TBANK_UNAVAILABLE" retry={retry} />);
screen.getByRole("button", { name: "Повторить" }).click();
expect(retry).toHaveBeenCalledOnce();
});
it("renders a stale portfolio in upstream order with nullable values", () => {
renderPage(<AccountPageLoaded portfolio={portfolio} />);
expect(
screen.getByRole("heading", { level: 1, name: "Портфель" }),
).toBeInTheDocument();
expect(
screen.getByText(
"T-Bank временно недоступен. Показан последний успешный снимок.",
),
).toBeInTheDocument();
expect(screen.getByText("—")).toBeInTheDocument();
expect(screen.getByText("Доход: —")).toBeInTheDocument();
const positions = screen
.getAllByText(/Вторая|Первая/)
.map((element) => element.textContent);
expect(positions).toEqual(["Вторая", "Первая"]);
expect(screen.getByRole("heading", { name: "Акции" })).toBeInTheDocument();
expect(
screen.getByRole("heading", { name: "Облигации" }),
).toBeInTheDocument();
});
it("uses the cached account title when available", () => {
renderPage(
<AccountPageLoaded
portfolio={portfolio}
account={{
id: "account-1",
name: "Основной",
type: "BROKERAGE",
openedOn: null,
}}
/>,
);
expect(
screen.getByRole("heading", { level: 1, name: "Основной" }),
).toBeInTheDocument();
});
});