fix: separate portfolio cash presentation
This commit is contained in:
@@ -1,6 +1,12 @@
|
||||
import { MantineProvider } from "@mantine/core";
|
||||
import { type QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
|
||||
import {
|
||||
fireEvent,
|
||||
render,
|
||||
screen,
|
||||
waitFor,
|
||||
within,
|
||||
} from "@testing-library/react";
|
||||
import { HttpResponse, http } from "msw";
|
||||
import { MemoryRouter, Route, Routes } from "react-router";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
@@ -145,11 +151,39 @@ describe("AccountPage states", () => {
|
||||
},
|
||||
);
|
||||
|
||||
it("shows only supplied totals despite cash and positions with unknown value", () => {
|
||||
renderPage(<AccountPageLoaded {...loadedProps()} />);
|
||||
it("shows supplied cash separately without adding currency instruments or recalculating totals", () => {
|
||||
renderPage(
|
||||
<AccountPageLoaded
|
||||
{...loadedProps({
|
||||
...portfolio,
|
||||
positions: [
|
||||
...portfolio.positions,
|
||||
{
|
||||
...portfolio.positions[0],
|
||||
figi: "FIGI-CURRENCY",
|
||||
displayName: "Торгуемая валюта",
|
||||
type: "CURRENCY",
|
||||
currentValue: { currency: "RUB", value: "1000" },
|
||||
},
|
||||
],
|
||||
cashBalances: [
|
||||
{ currency: "RUB", value: "234.500000000000000001" },
|
||||
{ currency: "USD", value: "-0.5" },
|
||||
{ currency: "XYZ", value: "3.00" },
|
||||
],
|
||||
})}
|
||||
/>,
|
||||
);
|
||||
const balances = within(
|
||||
screen.getByRole("region", { name: "Денежные остатки" }),
|
||||
);
|
||||
expect(
|
||||
balances.getAllByRole("definition").map((node) => node.textContent),
|
||||
).toEqual(["234,500000000000000001 ₽", "-0,5 $", "3,00 XYZ"]);
|
||||
expect(
|
||||
screen.getAllByRole("definition").map((node) => node.textContent),
|
||||
).toEqual(["1 234,5 ₽"]);
|
||||
).toEqual(["1 234,5 ₽", "234,500000000000000001 ₽", "-0,5 $", "3,00 XYZ"]);
|
||||
expect(screen.queryByText("Торгуемая валюта")).not.toBeInTheDocument();
|
||||
expect(
|
||||
screen.queryByText(/полная оценка|общая стоимость/i),
|
||||
).not.toBeInTheDocument();
|
||||
@@ -169,11 +203,58 @@ describe("AccountPage states", () => {
|
||||
);
|
||||
renderAccountRoute(createTestQueryClient());
|
||||
await screen.findByRole("heading", { name: "Портфель", level: 1 });
|
||||
expect(screen.queryByRole("definition")).not.toBeInTheDocument();
|
||||
expect(screen.getByRole("definition")).toHaveTextContent("0,5 $");
|
||||
expect(screen.queryByText("Портфель пока пуст")).not.toBeInTheDocument();
|
||||
},
|
||||
);
|
||||
|
||||
it.each([
|
||||
{ totalsByCurrency: [] },
|
||||
{ totalsByCurrency: [{ currency: "RUB", value: "100" }] },
|
||||
])(
|
||||
"hides the empty other section without emptying a currency-only portfolio (totals: $totalsByCurrency)",
|
||||
async ({ totalsByCurrency }) => {
|
||||
const snapshot: Portfolio = {
|
||||
...portfolio,
|
||||
totalsByCurrency,
|
||||
positions: [
|
||||
{
|
||||
...portfolio.positions[0],
|
||||
displayName: "Торгуемая валюта",
|
||||
type: "CURRENCY",
|
||||
currentValue: { currency: "RUB", value: "100" },
|
||||
},
|
||||
],
|
||||
cashBalances: [],
|
||||
};
|
||||
server.use(
|
||||
http.get("*/api/v1/brokerage-accounts/:accountId/portfolio", () =>
|
||||
HttpResponse.json(snapshot),
|
||||
),
|
||||
);
|
||||
const queryClient = createTestQueryClient();
|
||||
renderAccountRoute(queryClient);
|
||||
|
||||
await screen.findByRole("heading", { name: "Портфель", level: 1 });
|
||||
expect(
|
||||
screen.queryByRole("button", { name: "Другие позиции" }),
|
||||
).not.toBeInTheDocument();
|
||||
expect(screen.queryByText("Торгуемая валюта")).not.toBeInTheDocument();
|
||||
expect(screen.queryByText("Портфель пока пуст")).not.toBeInTheDocument();
|
||||
expect(
|
||||
within(
|
||||
screen.getByRole("region", { name: "Денежные остатки" }),
|
||||
).queryByRole("definition"),
|
||||
).not.toBeInTheDocument();
|
||||
expect(
|
||||
screen.queryAllByRole("definition").map((node) => node.textContent),
|
||||
).toEqual(totalsByCurrency.length ? ["100 ₽"] : []);
|
||||
expect(
|
||||
queryClient.getQueryData(portfolioQueryOptions("account-1").queryKey),
|
||||
).toEqual(snapshot);
|
||||
},
|
||||
);
|
||||
|
||||
it("renders loading and empty states", () => {
|
||||
renderPage(<AccountPageLoading />);
|
||||
expect(screen.getByRole("status")).toBeInTheDocument();
|
||||
@@ -613,13 +694,17 @@ describe("AccountPage states", () => {
|
||||
),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText("Вторая")).toBeInTheDocument();
|
||||
expect(screen.getByRole("definition")).toHaveTextContent("1 234,5 ₽");
|
||||
expect(
|
||||
screen.getAllByRole("definition").map((node) => node.textContent),
|
||||
).toEqual(["1 234,5 ₽", "0,5 $"]);
|
||||
expect(screen.getByText(/Данные получены/).textContent).toBe(
|
||||
snapshotText,
|
||||
);
|
||||
fireEvent.click(screen.getByRole("button", { name: "Повторить" }));
|
||||
await waitFor(() => expect(requestCount).toBe(3));
|
||||
expect(screen.getByRole("definition")).toHaveTextContent("1 234,5 ₽");
|
||||
expect(
|
||||
screen.getAllByRole("definition").map((node) => node.textContent),
|
||||
).toEqual(["1 234,5 ₽", "0,5 $"]);
|
||||
expect(screen.getByText(/Данные получены/).textContent).toBe(
|
||||
snapshotText,
|
||||
);
|
||||
@@ -629,10 +714,13 @@ describe("AccountPage states", () => {
|
||||
isStale: false,
|
||||
lastSuccessfulAt: "2026-08-14T11:30:00Z",
|
||||
totalsByCurrency: [{ currency: "USD", value: "-0.5" }],
|
||||
cashBalances: [{ currency: "EUR", value: "2.50" }],
|
||||
}),
|
||||
);
|
||||
await waitFor(() =>
|
||||
expect(screen.getByRole("definition")).toHaveTextContent("-0,5 $"),
|
||||
expect(
|
||||
screen.getAllByRole("definition").map((node) => node.textContent),
|
||||
).toEqual(["-0,5 $", "2,50 €"]),
|
||||
);
|
||||
expect(screen.getByText(/Данные получены/)).toHaveTextContent("11:30");
|
||||
expect(
|
||||
@@ -666,7 +754,9 @@ describe("AccountPage states", () => {
|
||||
|
||||
await waitFor(() => expect(requestCount).toBe(2));
|
||||
expect(screen.getByText("Вторая")).toBeInTheDocument();
|
||||
expect(screen.getByRole("definition")).toHaveTextContent("1 234,5 ₽");
|
||||
expect(
|
||||
screen.getAllByRole("definition").map((node) => node.textContent),
|
||||
).toEqual(["1 234,5 ₽", "0,5 $"]);
|
||||
expect(screen.getByText(/Данные получены/)).toHaveTextContent("10:00");
|
||||
expect(
|
||||
screen.queryByRole("status", { name: "Загрузка" }),
|
||||
|
||||
Reference in New Issue
Block a user