Files
frontend/src/app/routes/AppRoutes.test.tsx
T

159 lines
4.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { MantineProvider } from "@mantine/core";
import { QueryClientProvider } from "@tanstack/react-query";
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import { HttpResponse, http } from "msw";
import { MemoryRouter } from "react-router";
import { describe, expect, it } from "vitest";
import { AuthProvider } from "@/features/auth";
import { cssVariablesResolver, theme } from "@/shared/theme";
import { createTestQueryClient } from "@/test/query";
import { server } from "@/test/server";
import { AppRoutes } from "./AppRoutes";
describe("AppRoutes", () => {
function renderRoutes(path: string) {
return render(
<QueryClientProvider client={createTestQueryClient()}>
<MemoryRouter initialEntries={[path]}>
<MantineProvider
cssVariablesResolver={cssVariablesResolver}
theme={theme}
>
<AuthProvider>
<AppRoutes />
</AuthProvider>
</MantineProvider>
</MemoryRouter>
</QueryClientProvider>,
);
}
it.each([
["/", "Вход"],
["/login", "Вход"],
["/register", "Регистрация"],
["/accounts", "Вход"],
["/accounts/demo", "Вход"],
["/accounts/demo/operations", "Вход"],
["/settings", "Вход"],
["/cards?month=2026-08", "Вход"],
["/unknown", "Страница не найдена"],
])("renders %s with its page title", async (path, title) => {
renderRoutes(path);
await waitFor(() =>
expect(
screen.getByRole("heading", { level: 1, name: title }),
).toBeInTheDocument(),
);
expect(document.title).toBe(`${title} — WealthLedger`);
});
it("redirects anonymous users from accounts", async () => {
renderRoutes("/accounts");
await waitFor(() =>
expect(
screen.getByRole("heading", { level: 1, name: "Вход" }),
).toBeInTheDocument(),
);
});
it("logs in through the public form and reaches the protected landing", async () => {
let credentials: unknown;
server.use(
http.post("*/api/v1/auth/login", async ({ request }) => {
credentials = await request.json();
return HttpResponse.json({
accessToken: "login-token",
user: { id: "user-1", email: "user@example.com" },
});
}),
);
renderRoutes("/accounts");
await screen.findByRole("heading", { level: 1, name: "Вход" });
fireEvent.change(screen.getByLabelText("Email"), {
target: { value: " User@Example.com " },
});
fireEvent.change(screen.getByLabelText("Пароль"), {
target: { value: "a secure password" },
});
fireEvent.click(screen.getByRole("button", { name: "Вход" }));
expect(
await screen.findByRole("heading", {
level: 2,
name: "Нет инвестиционных счетов",
}),
).toBeInTheDocument();
expect(document.title).toBe("Счета — WealthLedger");
expect(credentials).toEqual({
email: "user@example.com",
password: "a secure password",
});
});
it("returns after login to cards with the selected month without T-Bank", async () => {
server.use(
http.get("*/api/v1/bank-cards/categories", () => HttpResponse.json([])),
http.post("*/api/v1/auth/login", () =>
HttpResponse.json({
accessToken: "test",
user: { id: "user-1", email: "user@example.com" },
}),
),
http.get("*/api/v1/bank-cards", () => HttpResponse.json([])),
http.get("*/api/v1/bank-cards/summary", () =>
HttpResponse.json({
month: "2026-08",
cardId: null,
expenses: { currency: "RUB", value: "0" },
refunds: { currency: "RUB", value: "0" },
net: { currency: "RUB", value: "0" },
categories: [],
}),
),
);
renderRoutes("/cards?month=2026-08");
await screen.findByRole("heading", { name: "Вход" });
fireEvent.change(screen.getByLabelText("Email"), {
target: { value: "user@example.com" },
});
fireEvent.change(screen.getByLabelText("Пароль"), {
target: { value: "a secure password" },
});
fireEvent.click(screen.getByRole("button", { name: "Вход" }));
await screen.findByRole("heading", { name: "Добавьте первую карту" });
expect(screen.getByLabelText("Период")).toHaveTextContent(
"01.08.2026 – 31.08.2026",
);
expect(document.title).toBe("Карты — WealthLedger");
});
it("lazy-loads the protected shell for an authenticated accounts route", async () => {
server.use(
http.post("*/api/v1/auth/refresh", () =>
HttpResponse.json({
accessToken: "test-token",
user: { id: "user-1", email: "user@example.com" },
}),
),
);
renderRoutes("/accounts");
await waitFor(() =>
expect(
screen.getByRole("heading", {
level: 2,
name: "Нет инвестиционных счетов",
}),
).toBeInTheDocument(),
);
expect(
screen.getByRole("navigation", { name: "WealthLedger" }),
).toBeInTheDocument();
});
});