Files
frontend/src/app/routes/DocumentTitle/DocumentTitle.test.tsx
T
ksv741 4e5f564fa1 feat: show persisted investment data and sync state
Consume the provided resource-envelope API snapshot. Preserve financial snapshots during
refresh, observe synchronization without importing, and fence late responses across
account and connection changes.
2026-09-26 21:22:49 +03:00

113 lines
3.4 KiB
TypeScript

import { QueryClientProvider } from "@tanstack/react-query";
import {
act,
fireEvent,
render,
screen,
waitFor,
} from "@testing-library/react";
import { HttpResponse, http } from "msw";
import type { FC } from "react";
import { MemoryRouter, useNavigate } from "react-router";
import { beforeEach, describe, expect, it } from "vitest";
import { AuthProvider } from "@/features/auth";
import { createTestQueryClient } from "@/test/query";
import { resource } from "@/test/resource";
import { server } from "@/test/server";
import { ProtectedDocumentTitle } from "./DocumentTitle";
const Navigation: FC = () => {
const navigate = useNavigate();
return (
<>
<button type="button" onClick={() => navigate("/accounts/all/income")}>
Все счета
</button>
<button type="button" onClick={() => navigate(-1)}>
Назад
</button>
</>
);
};
const renderTitle = (path: string) =>
render(
<QueryClientProvider client={createTestQueryClient()}>
<MemoryRouter initialEntries={[path]}>
<AuthProvider>
<ProtectedDocumentTitle />
<Navigation />
</AuthProvider>
</MemoryRouter>
</QueryClientProvider>,
);
beforeEach(() => {
document.title = "Previous page";
server.use(
http.post("*/api/v1/auth/refresh", () =>
HttpResponse.json({
accessToken: "test-token",
user: { id: "user-1", email: "user@example.com" },
}),
),
);
});
describe("document titles", () => {
it("updates a loading account name and follows account scope and history", async () => {
let resolveAccounts!: () => void;
const accountsReady = new Promise<void>((resolve) => {
resolveAccounts = resolve;
});
server.use(
http.get("*/api/v1/brokerage-accounts", async () => {
await accountsReady;
return HttpResponse.json(resource([{ id: "a", name: "ИИС" }]));
}),
);
renderTitle("/accounts/a/income?from=2026-01-01&to=2026-08-31");
expect(document.title).toBe("Пассивный доход — Счет — WealthLedger");
await act(async () => resolveAccounts());
await waitFor(() =>
expect(document.title).toBe("Пассивный доход — ИИС — WealthLedger"),
);
fireEvent.click(screen.getByRole("button", { name: "Все счета" }));
expect(document.title).toBe("Пассивный доход — Все счета — WealthLedger");
fireEvent.click(screen.getByRole("button", { name: "Назад" }));
expect(document.title).toBe("Пассивный доход — ИИС — WealthLedger");
});
it.each([
["bonds", "SU26238RMFS4", "Облигация", "ОФЗ 26238"],
["stocks", "SBER", "Акция", "Сбербанк"],
])(
"updates the %s title when instrument data arrives",
async (kind, id, fallback, name) => {
server.use(
http.get(`*/api/v1/${kind}/by-ticker/:ticker`, () =>
HttpResponse.json(resource({ name })),
),
);
renderTitle(`/${kind}/${id}`);
expect(document.title).toBe(`${fallback} — WealthLedger`);
await waitFor(() =>
expect(document.title).toBe(`${name} — WealthLedger`),
);
},
);
it("keeps a useful title when the instrument is unavailable", async () => {
let requested = false;
server.use(
http.get("*/api/v1/stocks/by-ticker/:ticker", () => {
requested = true;
return HttpResponse.json({ code: "NOT_FOUND" }, { status: 404 });
}),
);
renderTitle("/stocks/missing");
await waitFor(() => expect(requested).toBe(true));
expect(document.title).toBe("Акция — WealthLedger");
});
});