Diagnóstico sem case que não cabe; desktop com o GCC Installer como projeto próprio; IoT com o Twins Lab e a nota da Apolo. Mosaico de pôsteres em /servicos e /cases, faixa baixa em uma coluna no currículo, privacidade e laboratório; Laboratório como lista compacta; SEV começando por catálogo, pedido no WhatsApp e painel; Joinville e SC nos títulos; imagens do LCP com fetchPriority e sizes reais; pré-carregamento só no hover; 404 com Open Graph próprio.
109 lines
3.7 KiB
TypeScript
109 lines
3.7 KiB
TypeScript
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(<PosterMosaic posters={[]} />);
|
|
|
|
expect(container).toBeEmptyDOMElement();
|
|
});
|
|
|
|
it("path: three posters -> decorative, the first one eager with high priority and the real column width", () => {
|
|
const { container } = render(<PosterMosaic posters={three} />);
|
|
|
|
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(<PosterMosaic posters={three} />);
|
|
|
|
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(<PosterMosaic posters={three.slice(0, 1)} />);
|
|
|
|
expect(container.querySelectorAll("img")).toHaveLength(1);
|
|
});
|
|
});
|