feat: group all-account rows by instrument and day (WealthLedger/main#47) (#126)
This commit was merged in pull request #126.
This commit is contained in:
+92
-3
@@ -2,7 +2,7 @@ import type { FC } from "react";
|
||||
|
||||
import { MantineProvider } from "@mantine/core";
|
||||
import { 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 { http, HttpResponse } from "msw";
|
||||
import {
|
||||
MemoryRouter,
|
||||
@@ -44,6 +44,25 @@ const operation: BrokerageOperation
|
||||
type: "OPERATION_TYPE_BUY",
|
||||
};
|
||||
|
||||
function coupon(
|
||||
id: string,
|
||||
accountId: string,
|
||||
accountName: string,
|
||||
value: string,
|
||||
): BrokerageOperation {
|
||||
return {
|
||||
...operation,
|
||||
account: { id: accountId, name: accountName },
|
||||
category: "income",
|
||||
description: "Купон",
|
||||
id,
|
||||
instrumentUid: "UID",
|
||||
payment: { currency: "RUB", value },
|
||||
ticker: "BOND",
|
||||
type: "OPERATION_TYPE_COUPON",
|
||||
};
|
||||
}
|
||||
|
||||
const Navigation: FC = () => {
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
@@ -71,12 +90,12 @@ function configureTestAuth() {
|
||||
});
|
||||
}
|
||||
|
||||
function renderPage(search = "") {
|
||||
function renderPage(search = "", accountId = "account-1") {
|
||||
return render(
|
||||
<QueryClientProvider client={createTestQueryClient()}>
|
||||
<MantineProvider>
|
||||
<MemoryRouter
|
||||
initialEntries={[`/accounts/account-1/operations${search}`]}
|
||||
initialEntries={[`/accounts/${accountId}/operations${search}`]}
|
||||
>
|
||||
<Routes>
|
||||
<Route
|
||||
@@ -650,3 +669,73 @@ it("recovers an invalid cursor at the first page without clearing applied filter
|
||||
for (const key of ["from", "to", "categories"])
|
||||
expect(searches[2].get(key)).toBe(searches[0].get(key));
|
||||
});
|
||||
|
||||
describe("all-account operation groups", () => {
|
||||
it("groups only the current page and rebuilds the group at its boundary", async () => {
|
||||
configureTestAuth();
|
||||
server.use(
|
||||
http.get(
|
||||
"*/api/v1/brokerage-accounts/:accountId/operations",
|
||||
({ request }) => {
|
||||
const cursor = new URL(request.url).searchParams.get("cursor");
|
||||
|
||||
const items = cursor
|
||||
? [
|
||||
coupon("X2", "iis", "ИИС", "150"),
|
||||
coupon("X3", "broker", "Брокерский", "50"),
|
||||
operation,
|
||||
]
|
||||
: [coupon("X1", "broker", "Брокерский", "100")];
|
||||
|
||||
return HttpResponse.json(resource({
|
||||
accountId: "all",
|
||||
hasNext: !cursor,
|
||||
items,
|
||||
nextCursor: cursor ? null : "page-2",
|
||||
}));
|
||||
},
|
||||
),
|
||||
);
|
||||
renderPage("", "all");
|
||||
|
||||
await screen.findAllByText("Купон");
|
||||
expect(screen.queryByRole("list", { name: "Разбивка по счетам" }))
|
||||
.not.toBeInTheDocument();
|
||||
fireEvent.click(screen.getByRole("button", { name: "Далее" }));
|
||||
|
||||
const accounts = await screen.findByRole("list", {
|
||||
name: /Купон · BOND, Исполнено/,
|
||||
});
|
||||
|
||||
expect(screen.getByText("Купон · BOND")).toBeInTheDocument();
|
||||
expect(screen.getByText("+200 ₽")).toBeInTheDocument();
|
||||
expect(within(accounts).getAllByRole("listitem")).toHaveLength(2);
|
||||
|
||||
fireEvent.click(screen.getByRole("button", { name: "Назад" }));
|
||||
await screen.findAllByText("Купон");
|
||||
expect(screen.queryByRole("list", { name: "Разбивка по счетам" }))
|
||||
.not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("leaves repeated operations ungrouped for one account", async () => {
|
||||
configureTestAuth();
|
||||
server.use(
|
||||
http.get("*/api/v1/brokerage-accounts/:accountId/operations", () =>
|
||||
HttpResponse.json(resource({
|
||||
accountId: "account-1",
|
||||
hasNext: false,
|
||||
items: [
|
||||
coupon("X1", "account-1", "Брокерский", "100"),
|
||||
coupon("X2", "account-1", "Брокерский", "150"),
|
||||
],
|
||||
nextCursor: null,
|
||||
})),
|
||||
),
|
||||
);
|
||||
renderPage();
|
||||
|
||||
await screen.findAllByText("Купон");
|
||||
expect(screen.queryByRole("list", { name: /Разбивка|Исполнено/ }))
|
||||
.not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user