import { render } from "@testing-library/react"; import { getShowcaseAssets } from "@/lib/project-showcase"; import { coverSizes } from "./CaseCover"; import { getCaseMedia } from "./case-media"; import { getMosaicPosters, MOSAIC_SIZE, PosterMosaic } from "./PosterMosaic"; /** * Mosaico de pôsteres do topo de /servicos e /cases: quais pôsteres entram (só os com captura, no máximo três), * e como cada imagem carrega (a primeira, a maior, na hora e com prioridade alta; as outras só quando aparecem). */ jest.mock("./case-media", () => ({ getCaseMedia: jest.fn() })); const mockedGetCaseMedia = jest.mocked(getCaseMedia); afterEach(() => { mockedGetCaseMedia.mockReset(); }); describe("getMosaicPosters", () => { it("path: every id has a capture -> keeps the order and stops at three", () => { mockedGetCaseMedia.mockImplementation(getShowcaseAssets); const posters = getMosaicPosters(["a", "b", "c", "d"]); expect(MOSAIC_SIZE).toBe(3); expect(posters).toEqual([ { id: "a", poster: "/videos/a/desktop.webp" }, { id: "b", poster: "/videos/b/desktop.webp" }, { id: "c", poster: "/videos/c/desktop.webp" }, ]); }); it("path: some ids have no capture -> skips them and fills with the next ones", () => { mockedGetCaseMedia.mockImplementation((id, device) => id === "b" ? undefined : getShowcaseAssets(id, device), ); expect(getMosaicPosters(["a", "b", "c", "d"]).map(({ id }) => id)).toEqual([ "a", "c", "d", ]); expect(mockedGetCaseMedia).toHaveBeenCalledWith("b", "desktop"); }); it("path: no id has a capture -> an empty list", () => { mockedGetCaseMedia.mockReturnValue(undefined); expect(getMosaicPosters(["a", "b"])).toEqual([]); }); }); describe("PosterMosaic", () => { const three = ["a", "b", "c"].map((id) => ({ id, poster: `/videos/${id}/desktop.webp`, })); it("path: no posters -> renders nothing", () => { const { container } = render(); expect(container).toBeEmptyDOMElement(); }); it("path: three posters -> decorative, the first one eager with high priority and the real column width", () => { const { container } = render(); expect(container.firstElementChild).toHaveAttribute("aria-hidden", "true"); const images = Array.from(container.querySelectorAll("img")); expect(images).toHaveLength(3); for (const image of images) { expect(image).toHaveAttribute("alt", ""); } const [main, ...side] = images; expect(main).toHaveAttribute("loading", "eager"); expect(main).toHaveAttribute("fetchpriority", "high"); expect(main).toHaveAttribute("sizes", coverSizes.hero); expect(main.closest("div")).toHaveClass("col-span-2"); for (const image of side) { expect(image).toHaveAttribute("loading", "lazy"); expect(image).not.toHaveAttribute("fetchpriority"); // metade da coluna, e nunca a largura toda da tela expect(image.getAttribute("sizes")).toBe( "(min-width: 1440px) 274px, 20vw", ); } }); it("path: the smaller posters are hidden below 1024 px, so they are not downloaded on a phone", () => { const { container } = render(); const [main, ...side] = Array.from(container.querySelectorAll("img")).map( (image) => image.closest("div"), ); expect(main).not.toHaveClass("hidden"); for (const frame of side) { expect(frame).toHaveClass("hidden", "lg:block"); } }); it("path: a single poster -> only the main one, with no side posters", () => { const { container } = render(); expect(container.querySelectorAll("img")).toHaveLength(1); }); });