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( , ); } 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 USD.*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); }); });