refactor: tighten types and reuse instrument UI
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import type { Portfolio } from "@/entities/portfolio";
|
||||
|
||||
const portfolio: Portfolio
|
||||
const portfolio
|
||||
= {
|
||||
cashBalances: [{ currency: "USD", value: "1" }],
|
||||
isStale: true,
|
||||
@@ -42,10 +42,10 @@ const portfolio: Portfolio
|
||||
ticker: null,
|
||||
type: "FUND",
|
||||
},
|
||||
],
|
||||
] satisfies [Portfolio["positions"][number], ...Portfolio["positions"]],
|
||||
structure: { currencies: [], unvaluedCategories: [] },
|
||||
totalsByCurrency: [{ currency: "RUB", value: "150" }],
|
||||
};
|
||||
} satisfies Portfolio;
|
||||
|
||||
const position: Portfolio["positions"][number] = {
|
||||
...portfolio.positions[0],
|
||||
|
||||
@@ -59,13 +59,13 @@ describe("account position sections", () => {
|
||||
"bonds",
|
||||
"other",
|
||||
]);
|
||||
expect(sections[2].groups.map(group => group.positions[0].figi)).toEqual([
|
||||
expect(sections[2]?.groups.map(group => group.positions[0].figi)).toEqual([
|
||||
"FIGI-FUND",
|
||||
...otherTypes.map(type => `FIGI-${type}-NEXT`),
|
||||
]);
|
||||
expect(sections[0].groups[0].positions[0].shareText).toBe("40 %");
|
||||
expect(sections[1].groups[0].positions[0].shareText).toBe("20 %");
|
||||
expect(sections[2].groups[1].positions[0].shareText).toBe("20 %");
|
||||
expect(sections[0]?.groups[0]?.positions[0].shareText).toBe("40 %");
|
||||
expect(sections[1]?.groups[0]?.positions[0].shareText).toBe("20 %");
|
||||
expect(sections[2]?.groups[1]?.positions[0].shareText).toBe("20 %");
|
||||
expect(snapshot).toEqual(original);
|
||||
});
|
||||
|
||||
@@ -125,10 +125,10 @@ describe("account position sections", () => {
|
||||
figi: null,
|
||||
},
|
||||
{ ...second, figi: null },
|
||||
])[0].groups,
|
||||
])[0]?.groups,
|
||||
).toHaveLength(1);
|
||||
expect(
|
||||
sections([position, { ...second, figi: "OTHER-FIGI" }])[0].groups,
|
||||
sections([position, { ...second, figi: "OTHER-FIGI" }])[0]?.groups,
|
||||
).toHaveLength(2);
|
||||
expect(
|
||||
|
||||
@@ -143,19 +143,19 @@ describe("account position sections", () => {
|
||||
figi: null,
|
||||
isin: null,
|
||||
},
|
||||
])[0].groups,
|
||||
])[0]?.groups,
|
||||
).toHaveLength(2);
|
||||
});
|
||||
|
||||
it("preserves one-account cards and does not merge repeated rows on the same account", () => {
|
||||
expect(
|
||||
sections([position, { ...second, account: position.account }])[0].groups,
|
||||
sections([position, { ...second, account: position.account }])[0]?.groups,
|
||||
).toHaveLength(2);
|
||||
expect(
|
||||
sections([
|
||||
{ ...position, account: undefined },
|
||||
{ ...second, account: undefined },
|
||||
])[0].groups,
|
||||
])[0]?.groups,
|
||||
).toHaveLength(2);
|
||||
});
|
||||
|
||||
@@ -170,9 +170,9 @@ describe("account position sections", () => {
|
||||
];
|
||||
|
||||
const before = structuredClone(source);
|
||||
const [group] = sections(source)[0].groups;
|
||||
const group = sections(source)[0]?.groups[0];
|
||||
expect(
|
||||
group.positions.map(item => [
|
||||
group?.positions.map(item => [
|
||||
item.quantity,
|
||||
item.currentValue,
|
||||
item.averagePurchasePrice,
|
||||
|
||||
@@ -11,7 +11,7 @@ type AccountPagePosition = Portfolio["positions"][number] & {
|
||||
|
||||
type AccountPagePositionGroup = {
|
||||
key: string;
|
||||
positions: AccountPagePosition[];
|
||||
positions: [AccountPagePosition, ...AccountPagePosition[]];
|
||||
};
|
||||
|
||||
type AccountPagePositionSection = {
|
||||
|
||||
@@ -67,7 +67,7 @@ function renderPage(ui: React.ReactNode) {
|
||||
);
|
||||
}
|
||||
|
||||
const portfolio: Portfolio
|
||||
const portfolio
|
||||
= {
|
||||
cashBalances: [{ currency: "USD", value: "0.5" }],
|
||||
isStale: true,
|
||||
@@ -97,10 +97,10 @@ const portfolio: Portfolio
|
||||
ticker: null,
|
||||
type: "BOND",
|
||||
},
|
||||
],
|
||||
] satisfies [Portfolio["positions"][number], ...Portfolio["positions"]],
|
||||
structure: { currencies: [], unvaluedCategories: [] },
|
||||
totalsByCurrency: [{ currency: "RUB", value: "1234.5" }],
|
||||
};
|
||||
} satisfies Portfolio;
|
||||
|
||||
function position(
|
||||
overrides: Partial<Portfolio["positions"][number]>,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
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 { assert, describe, expect, it } from "vitest";
|
||||
|
||||
import { toAccountPagePositionSections } from "../../model/positions";
|
||||
import { portfolio, position, second } from "../../model/positions.fixtures";
|
||||
@@ -13,6 +13,8 @@ describe("Positions grouped by security", () => {
|
||||
...portfolio, positions: [position, second],
|
||||
})[0];
|
||||
|
||||
assert.isDefined(section);
|
||||
|
||||
render(
|
||||
<MantineProvider>
|
||||
<MemoryRouter>
|
||||
@@ -27,6 +29,8 @@ describe("Positions grouped by security", () => {
|
||||
).getAllByRole("listitem");
|
||||
|
||||
expect(rows).toHaveLength(2);
|
||||
assert.isDefined(rows[0]);
|
||||
assert.isDefined(rows[1]);
|
||||
expect(
|
||||
within(rows[0]).getByRole("link", { name: "Основной" }),
|
||||
).toHaveAttribute("href", "/accounts/a");
|
||||
|
||||
@@ -6,7 +6,7 @@ import { MantineProvider } from "@mantine/core";
|
||||
// eslint-disable-next-line testing-library/no-manual-cleanup -- Vitest globals are disabled, so RTL cannot register its automatic afterEach cleanup.
|
||||
import { cleanup, render, screen } from "@testing-library/react";
|
||||
import { cssVariablesResolver, theme } from "@wealthledger/ui/theme";
|
||||
import { afterEach, expect, it } from "vitest";
|
||||
import { afterEach, assert, expect, it } from "vitest";
|
||||
|
||||
import type { AccountPagePosition, AccountPagePositionSection } from "../../model/positions";
|
||||
|
||||
@@ -76,6 +76,7 @@ it("keeps expanded positions vertical while other positions adapt to the viewpor
|
||||
expect(current.height, context).toBeGreaterThan(0);
|
||||
if (index === 0) continue;
|
||||
const previous = bounds[index - 1];
|
||||
assert.isDefined(previous);
|
||||
|
||||
if (kind === "other" && width === 1280) {
|
||||
// eslint-disable-next-line vitest/no-conditional-expect -- The fixed table case selects the expected outcome; every case asserts its own branch.
|
||||
|
||||
Reference in New Issue
Block a user