xtablo-source/apps/main/src/components/TabloOverviewSection.test.tsx
2026-03-07 15:45:49 +01:00

111 lines
3.6 KiB
TypeScript

import { fireEvent, screen, waitFor } from "@testing-library/react";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { renderWithProviders } from "../utils/testHelpers";
import { TabloOverviewSection } from "./TabloOverviewSection";
const mockUseTabloEtapes = vi.fn();
const mockUseTasksByTablo = vi.fn();
const createEtapeMock = { mutateAsync: vi.fn(), isPending: false };
const updateEtapeMock = { mutateAsync: vi.fn(), isPending: false };
const deleteEtapeMock = { mutateAsync: vi.fn(), isPending: false };
const reorderEtapesMock = { mutateAsync: vi.fn(), isPending: false };
vi.mock("../hooks/tasks", () => ({
useTabloEtapes: (tabloId: string) => mockUseTabloEtapes(tabloId),
useTasksByTablo: (tabloId: string) => mockUseTasksByTablo(tabloId),
useCreateEtape: () => createEtapeMock,
useUpdateEtape: () => updateEtapeMock,
useDeleteEtape: () => deleteEtapeMock,
useReorderEtapes: () => reorderEtapesMock,
}));
vi.mock("./TabloFilesSection", () => ({
TabloFilesSection: () => <div data-testid="tablo-files-section" />,
}));
vi.mock("./TabloHeaderActions", () => ({
TabloHeaderActions: () => <div data-testid="tablo-header-actions" />,
}));
const mockTablo = {
id: "tablo-1",
name: "Projet Alpha",
color: "bg-blue-500",
user_id: "123",
access_level: "admin",
is_admin: true,
created_at: "2024-01-01T00:00:00Z",
deleted_at: "",
position: 0,
status: "active",
image: "",
};
const etapeFactory = (overrides = {}) => ({
id: "etape-1",
tablo_id: mockTablo.id,
title: "Phase 1",
description: null,
status: "todo",
assignee_id: null,
position: 0,
created_at: "2024-01-01T00:00:00Z",
updated_at: "2024-01-01T00:00:00Z",
is_parent: true,
parent_task_id: null,
...overrides,
});
beforeEach(() => {
vi.clearAllMocks();
mockUseTabloEtapes.mockReturnValue({
data: [etapeFactory()],
isLoading: false,
});
mockUseTasksByTablo.mockReturnValue({
data: [],
isLoading: false,
});
createEtapeMock.mutateAsync = vi.fn().mockResolvedValue(undefined);
updateEtapeMock.mutateAsync = vi.fn().mockResolvedValue(undefined);
deleteEtapeMock.mutateAsync = vi.fn().mockResolvedValue(undefined);
reorderEtapesMock.mutateAsync = vi.fn().mockResolvedValue(undefined);
});
describe("TabloOverviewSection", () => {
it("shows the Étape creation input for the tablo owner", () => {
renderWithProviders(<TabloOverviewSection tablo={mockTablo} isAdmin />, { language: "fr" });
expect(screen.getByPlaceholderText("Nom de l'Étape")).toBeInTheDocument();
expect(screen.getByText("Ajouter l'Étape")).toBeInTheDocument();
});
it("hides management actions for non owners", () => {
renderWithProviders(<TabloOverviewSection tablo={mockTablo} isAdmin={false} />, {
language: "fr",
});
expect(screen.queryByPlaceholderText("Nom de l'Étape")).not.toBeInTheDocument();
expect(
screen.getByText(
"Seul le propriétaire du projet peut modifier les Étapes. Contactez l'administrateur si vous avez besoin d'une nouvelle Étape."
)
).toBeInTheDocument();
});
it("calls the create mutation when adding a new Étape", async () => {
renderWithProviders(<TabloOverviewSection tablo={mockTablo} isAdmin />, { language: "fr" });
const input = screen.getByPlaceholderText("Nom de l'Étape");
fireEvent.change(input, { target: { value: "Kick-off" } });
fireEvent.click(screen.getByText("Ajouter l'Étape"));
await waitFor(() => {
expect(createEtapeMock.mutateAsync).toHaveBeenCalledWith({
tabloId: mockTablo.id,
title: "Kick-off",
position: 1,
});
});
});
});