72 lines
4.1 KiB
TypeScript
72 lines
4.1 KiB
TypeScript
import { render, screen, waitFor, within } from "@testing-library/react";
|
||
import userEvent from "@testing-library/user-event";
|
||
import { createMemoryRouter } from "react-router";
|
||
import { beforeEach, describe, expect, it } from "vitest";
|
||
import { App } from "./App.tsx";
|
||
import { clearToken, getAuth, setToken } from "./auth/token.ts";
|
||
import { routes } from "./routes.tsx";
|
||
import { PAGE_ROUTES } from "./shell/pages.tsx";
|
||
import { json, mockFetch } from "./test/fetchMock.ts";
|
||
|
||
const at = (path: string) => createMemoryRouter(routes, { initialEntries: [path], basename: "/app" });
|
||
|
||
const A = { label: "AWPCA", name: "АРМ КА", board_id: null, board_type: null, created_at: "", issues_count: 0 };
|
||
describe("оболочка", () => {
|
||
beforeEach(() => { setToken("tok"); mockFetch((_m, url) => json(200, url.pathname === "/projects" ? { projects: [A] } : {})); });
|
||
|
||
it("/app открывает «Обзор»", async () => {
|
||
render(<App router={at("/app")} />);
|
||
await waitFor(() => expect(screen.getByTestId("page-overview")).toBeInTheDocument());
|
||
});
|
||
|
||
it("переход «Задачи» и обратно", async () => {
|
||
const router = at("/app/jira/board");
|
||
render(<App router={router} />);
|
||
await userEvent.click(screen.getByRole("link", { name: "Задачи" }));
|
||
expect(router.state.location.pathname).toBe("/app/jira/issues");
|
||
expect(router.state.location.search).toBe("?project=AWPCA");
|
||
expect(await screen.findByTestId("page-issues")).toBeInTheDocument();
|
||
await userEvent.click(screen.getByRole("link", { name: "Доска связей" }));
|
||
expect(router.state.location.pathname).toBe("/app/jira/board");
|
||
expect(router.state.location.search).toBe("?project=AWPCA");
|
||
expect(await screen.findByTestId("page-board")).toBeInTheDocument();
|
||
});
|
||
|
||
it("неизвестный путь — «не найдено» со ссылками", async () => {
|
||
render(<App router={at("/app/nope")} />);
|
||
expect(await screen.findByRole("heading", { name: "Страница не найдена" })).toBeInTheDocument();
|
||
const main = within(screen.getByRole("main"));
|
||
expect(main.getByRole("link", { name: "Обзор" })).toHaveAttribute("href", expect.stringMatching(/^\/app\/?$/));
|
||
expect(main.getByRole("link", { name: "Доска связей" })).toHaveAttribute("href", "/app/jira/board");
|
||
expect(main.getByRole("link", { name: "Задачи" })).toHaveAttribute("href", "/app/jira/issues");
|
||
});
|
||
|
||
it("«Сменить токен» показывает экран входа", async () => {
|
||
render(<App router={at("/app/jira/board")} />);
|
||
await userEvent.click(within(await screen.findByRole("complementary", { name: "Панель приложения" })).getByRole("button", { name: "Ещё" })); // #68 M-2: на доске есть ещё и «Ещё — доска»
|
||
await userEvent.click(screen.getByRole("button", { name: "Сменить токен" }));
|
||
expect(getAuth().token).toBe("");
|
||
expect(screen.getByRole("heading", { name: "Вход в хаб" })).toBeInTheDocument();
|
||
});
|
||
|
||
it("исключение в странице — сообщение и «Перезагрузить», панель на месте", async () => {
|
||
const Boom = () => { throw new Error("сломалось"); };
|
||
const boom = { path: "/x", element: <Boom /> };
|
||
PAGE_ROUTES.unshift(boom);
|
||
try {
|
||
const router = createMemoryRouter(routes, { initialEntries: ["/app/x"], basename: "/app" });
|
||
render(<App router={router} />);
|
||
expect(await screen.findByText(/сломалось/)).toBeInTheDocument();
|
||
expect(screen.getByRole("button", { name: "Перезагрузить" })).toBeInTheDocument();
|
||
expect(screen.getAllByRole("alert")).toHaveLength(1);
|
||
expect(screen.getByRole("link", { name: "Доска связей" })).toBeInTheDocument();
|
||
} finally { PAGE_ROUTES.splice(PAGE_ROUTES.indexOf(boom), 1); }
|
||
});
|
||
|
||
it("без токена — только экран входа", () => {
|
||
clearToken();
|
||
render(<App router={at("/app/jira/board")} />);
|
||
expect(screen.queryByRole("link", { name: "Доска связей" })).not.toBeInTheDocument();
|
||
});
|
||
});
|