import { fireEvent, render, screen } from "@testing-library/react"; import { getFeaturedProjects } from "@/lib/portfolio-data"; import { type ShowcaseItem, ShowcaseProvider, useShowcaseItems, useShowcaseOpen, } from "./ShowcaseProvider"; /** * Testes de caminhos-base de ShowcaseProvider (complemento de ShowcaseProvider.test.tsx). O provedor só guarda a * lista da vitrine e qual projeto está ampliado: aqui, a janela aberta quando a lista muda, a troca de projeto * com a janela já aberta e a estabilidade do que ele entrega (lista e função de abrir) entre renderizações. * A janela ampliada é um dublê que só mostra o índice. */ jest.mock("./ProjectLightbox", () => ({ ProjectLightbox: ({ index, items, onClose, }: { index: number; items: unknown[]; onClose: () => void; }) => (
aberto:{index} de {items.length}
), })); const projects = getFeaturedProjects(null); const clientIds = ["sev-modaintima", "lavacao-047", "sc-plus", "as-servicos"]; const clients = projects.filter((project) => clientIds.includes(project.id)); function Opener({ id }: { id: string }) { const open = useShowcaseOpen(); return ( ); } describe("ShowcaseProvider: janela ampliada e mudança da lista", () => { it("path: window open and its project leaves the list -> the window goes away", () => { const { rerender } = render( , ); fireEvent.click(screen.getByRole("button", { name: "abrir sc-plus" })); expect(screen.getByRole("dialog")).toHaveTextContent("aberto:2 de 4"); rerender( project.id !== "sc-plus")} > , ); expect(screen.queryByRole("dialog")).toBeNull(); }); it("path: window open and another project is opened -> it moves to the new project, one window only", () => { render( , ); fireEvent.click( screen.getByRole("button", { name: "abrir sev-modaintima" }), ); expect(screen.getByRole("dialog")).toHaveTextContent("aberto:0 de 4"); fireEvent.click(screen.getByRole("button", { name: "abrir as-servicos" })); expect(screen.getAllByRole("dialog")).toHaveLength(1); expect(screen.getByRole("dialog")).toHaveTextContent("aberto:3 de 4"); }); it("path: a project outside the showcase is asked while another window is open -> no window is left", () => { render( , ); fireEvent.click( screen.getByRole("button", { name: "abrir sev-modaintima" }), ); fireEvent.click( screen.getByRole("button", { name: "abrir reddit-explorer" }), ); // o id desconhecido não acha posição na lista: a janela não mostra projeto nenhum expect(screen.queryByRole("dialog")).toBeNull(); }); it("path: closed window -> reopening the same project works again", () => { render( , ); fireEvent.click(screen.getByRole("button", { name: "abrir lavacao-047" })); fireEvent.click(screen.getByRole("button", { name: "fechar" })); expect(screen.queryByRole("dialog")).toBeNull(); fireEvent.click(screen.getByRole("button", { name: "abrir lavacao-047" })); expect(screen.getByRole("dialog")).toHaveTextContent("aberto:1 de 4"); }); }); type Captured = { items: ShowcaseItem[]; open: (id: string) => void; }; function Probe({ onRender }: { onRender: (captured: Captured) => void }) { onRender({ items: useShowcaseItems(), open: useShowcaseOpen() }); return null; } describe("ShowcaseProvider: o que entrega a quem está dentro", () => { it("path: re-render with the same projects -> the same list and the same open function", () => { const seen: Captured[] = []; const tree = () => ( seen.push(captured)} /> ); const { rerender } = render(tree()); rerender(tree()); expect(seen.length).toBeGreaterThan(1); expect(seen[seen.length - 1].items).toBe(seen[0].items); expect(seen[seen.length - 1].open).toBe(seen[0].open); }); it("path: a different list of projects -> a new list of items", () => { const seen: Captured[] = []; const probe = seen.push(captured)} />; const { rerender } = render( {probe}, ); rerender( {probe} , ); expect(seen[0].items).toHaveLength(4); expect(seen[seen.length - 1].items).toHaveLength(2); }); });