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( , ); } 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(); }); });