123 lines
3.6 KiB
TypeScript
123 lines
3.6 KiB
TypeScript
import { MantineProvider } from "@mantine/core";
|
|
import { render, screen, within } from "@testing-library/react";
|
|
import { MemoryRouter } from "react-router";
|
|
import { describe, expect, it } from "vitest";
|
|
|
|
import type { BrokerageEvent } from "../api/useBrokerageEvents";
|
|
|
|
import { BrokerageEventGroup } from "./BrokerageEventGroup";
|
|
|
|
function event(
|
|
account: { id: string; name: string },
|
|
value: null | string,
|
|
currency = "RUB",
|
|
): BrokerageEvent {
|
|
return {
|
|
account,
|
|
date: "2026-08-20",
|
|
dateKind: "registry",
|
|
displayName: "ОФЗ 26238",
|
|
figi: "FIGI",
|
|
instrumentUid: "UID",
|
|
isin: "RU000A0JX0J2",
|
|
logoName: null,
|
|
projectedAmount: value === null ? null : { currency, value },
|
|
ticker: "OFZ",
|
|
type: "coupon",
|
|
};
|
|
}
|
|
|
|
function renderGroup(
|
|
events: [BrokerageEvent, BrokerageEvent],
|
|
isTotalVisible = true,
|
|
) {
|
|
return render(
|
|
<MantineProvider>
|
|
<MemoryRouter>
|
|
<ul>
|
|
<BrokerageEventGroup
|
|
events={events}
|
|
totalVisible={isTotalVisible}
|
|
/>
|
|
</ul>
|
|
</MemoryRouter>
|
|
</MantineProvider>,
|
|
);
|
|
}
|
|
|
|
describe("BrokerageEventGroup", () => {
|
|
it("shows an unsigned forecast total and every account forecast", () => {
|
|
renderGroup([
|
|
event({ id: "broker", name: "Брокерский" }, "100.5"),
|
|
event({ id: "iis", name: "ИИС" }, "49.5"),
|
|
]);
|
|
|
|
expect(screen.getByText("Купон · ОФЗ 26238")).toBeInTheDocument();
|
|
expect(screen.getByText("150 ₽")).toBeInTheDocument();
|
|
expect(screen.getAllByText("Прогноз").length).toBeGreaterThanOrEqual(3);
|
|
|
|
const accounts = within(screen.getByRole("list", {
|
|
name: /Купон · ОФЗ 26238, 20\.08\.2026 · Дата реестра, 150 ₽/,
|
|
}));
|
|
|
|
expect(accounts.getByText("Брокерский")).toBeInTheDocument();
|
|
expect(accounts.getByText("ИИС")).toBeInTheDocument();
|
|
expect(accounts.getByText("100,5 ₽")).toBeInTheDocument();
|
|
expect(accounts.getByText("49,5 ₽")).toBeInTheDocument();
|
|
expect(accounts.queryByRole("link")).not.toBeInTheDocument();
|
|
});
|
|
|
|
it("announces an unknown total as unavailable", () => {
|
|
renderGroup([
|
|
event({ id: "broker", name: "Брокерский" }, null),
|
|
event({ id: "iis", name: "ИИС" }, "49.5"),
|
|
]);
|
|
|
|
expect(screen.getByRole("list", {
|
|
name: /Купон · ОФЗ 26238.*Итог недоступен/,
|
|
})).toBeInTheDocument();
|
|
expect(screen.getByText("Сумма неизвестна")).toBeInTheDocument();
|
|
});
|
|
|
|
it("hides the total for incomplete data", () => {
|
|
renderGroup([
|
|
event({ id: "broker", name: "Брокерский" }, "100.5"),
|
|
event({ id: "iis", name: "ИИС" }, "49.5"),
|
|
], false);
|
|
expect(screen.queryByText("150 ₽")).not.toBeInTheDocument();
|
|
});
|
|
|
|
it("allows zero source forecasts to produce a visible zero total", () => {
|
|
renderGroup([
|
|
event({ id: "broker", name: "Брокерский" }, "0"),
|
|
event({ id: "iis", name: "ИИС" }, "0.00"),
|
|
]);
|
|
|
|
expect(screen.getAllByText("0 ₽")).toHaveLength(2);
|
|
expect(screen.getByText("0,00 ₽")).toBeInTheDocument();
|
|
});
|
|
|
|
it("shows separate forecast totals per currency without conversion", () => {
|
|
renderGroup([
|
|
event({ id: "broker", name: "Брокерский" }, "10", "USD"),
|
|
event({ id: "iis", name: "ИИС" }, "200"),
|
|
]);
|
|
|
|
expect(screen.getByRole("list", { name: /10 \$.*200 ₽/ }))
|
|
.toBeInTheDocument();
|
|
});
|
|
|
|
it("shows an offer group without a total", () => {
|
|
renderGroup([
|
|
{ ...event({ id: "broker", name: "Брокерский" }, null), type: "offer" },
|
|
{ ...event({ id: "iis", name: "ИИС" }, null), type: "offer" },
|
|
]);
|
|
|
|
const accounts = within(screen.getByRole("list", {
|
|
name: /Итог недоступен/,
|
|
}));
|
|
|
|
expect(accounts.getAllByRole("listitem")).toHaveLength(2);
|
|
});
|
|
});
|