sdlc-hub/web/src/projects/NewProjectDialog.test.tsx
Andrey Epifancev 867875daf6 Веб: поля проекта от модулей (#91)
Окно «Новый проект» собирает поля из MODULES[].projectFields; Project — ядро плюс поля модулей;
useUpdateProject (PATCH /projects/{label}); метка «долг hub-modules» снята; e2e читают токен агента из tokens.agents.jira.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 01:41:23 +04:00

69 lines
3.0 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 { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { render, screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { setToken } from "../auth/token.ts";
import { jiraModule } from "../modules/jira/index.tsx";
import type { HubModule } from "../modules/types.ts";
import { json, mockFetch } from "../test/fetchMock.ts";
import { NewProjectDialog } from "./NewProjectDialog.tsx";
// второй модуль с текстовым полем: окно собирает поля из всех модулей, а не только из jira
vi.mock("../modules/index.ts", async () => {
const { jiraModule: jira } = await import("../modules/jira/index.tsx");
const extra: HubModule = {
name: "extra", pages: [], nav: [],
projectFields: [{ name: "space_key", label: "Пространство", hint: "ключ", kind: "text" }],
};
return { MODULES: [jira, extra] };
});
const CREATED = { project: { label: "P", name: "Пэ", created_at: "" }, batch_id: 3 };
function setup() {
const posts: unknown[] = [];
mockFetch((method, _url, body) => {
if (method === "POST") { posts.push(body); return json(201, CREATED); }
return json(404, { error: "not_found" });
});
const onCreated = vi.fn();
render(
<QueryClientProvider client={new QueryClient()}>
<NewProjectDialog onClose={() => {}} onCreated={onCreated} />
</QueryClientProvider>,
);
return { posts, onCreated };
}
const fill = async () => {
await userEvent.type(screen.getByLabelText("Метка"), "P");
await userEvent.type(screen.getByLabelText("Название"), "Пэ");
};
describe("NewProjectDialog: поля модулей", () => {
beforeEach(() => setToken("tok"));
it("jira описывает поле доски", () => {
expect(jiraModule.projectFields).toEqual([
{ name: "board_id", label: "Номер доски Jira", hint: "scrum или kanban определится сам", kind: "int" },
]);
});
it("пустые поля в тело не попадают", async () => {
const { posts } = setup();
await fill();
await userEvent.click(screen.getByRole("button", { name: "Создать" }));
await waitFor(() => expect(posts).toHaveLength(1));
expect(posts[0]).toEqual({ label: "P", name: "Пэ", author: "viewer" });
});
it("доска «5120» уходит числом, текстовое поле другого модуля — строкой", async () => {
const { posts } = setup();
await fill();
await userEvent.type(screen.getByLabelText("Номер доски Jira"), "5120");
await userEvent.type(screen.getByLabelText("Пространство"), " KEY ");
await userEvent.click(screen.getByRole("button", { name: "Создать" }));
await waitFor(() => expect(posts).toHaveLength(1));
expect(posts[0]).toEqual({ label: "P", name: "Пэ", board_id: 5120, space_key: "KEY", author: "viewer" });
});
});