import { act, render, screen } from "@testing-library/react";
import { setNavigation } from "@/__mocks__/next/navigation";
import CinematicOverlays from "./CinematicOverlays";
// o grão vem por import dinâmico (pacote próprio): aqui ele vira um marcador, e o contador diz se o pacote foi pedido
const mockLoaded = jest.fn();
jest.mock("./FilmGrain", () => {
mockLoaded();
return {
__esModule: true,
default: function MockGrain() {
return
;
},
};
});
/** O import dinâmico do grão resolve em microtarefas. */
const loaded = () =>
act(async () => {
for (let i = 0; i < 5; i++) await Promise.resolve();
});
const original = window.matchMedia;
function mockMedia(active: string[] = []) {
window.matchMedia = jest.fn().mockImplementation((query: string) => ({
matches: active.includes(query),
media: query,
addEventListener() {},
removeEventListener() {},
}));
}
beforeEach(() => {
setNavigation({ pathname: "/" });
mockMedia();
});
afterEach(() => {
window.matchMedia = original;
});
/*
* Os três primeiros testes vêm antes de qualquer um que carregue o grão: o módulo, depois de pedido uma vez, fica
* no registro do Jest, então "o pacote nunca foi pedido" só vale enquanto ninguém o pediu.
*/
describe("CinematicOverlays: where the grain package is never requested", () => {
it("does not request the grain on a touch screen (nothing invisible left measuring the page); the progress bar stays", async () => {
mockMedia(["(pointer: coarse)"]);
const { container } = render();
await loaded();
expect(mockLoaded).not.toHaveBeenCalled();
expect(screen.queryByTestId("grain")).toBeNull();
// a barra de progresso é CSS puro: continua
expect(container.querySelector(".ds-scroll-bar")).toBeInTheDocument();
});
it("does not request the grain for users who prefer reduced motion", async () => {
mockMedia(["(prefers-reduced-motion: reduce)"]);
render();
await loaded();
expect(mockLoaded).not.toHaveBeenCalled();
expect(screen.queryByTestId("grain")).toBeNull();
});
it("shows nothing, and requests nothing, on the other pages", async () => {
setNavigation({ pathname: "/cases" });
const { container } = render();
await loaded();
expect(mockLoaded).not.toHaveBeenCalled();
expect(screen.queryByTestId("grain")).toBeNull();
expect(container).toBeEmptyDOMElement();
});
});
describe("CinematicOverlays: with a mouse", () => {
it("shows the scroll progress at once and the film grain as soon as its package arrives", async () => {
const { container } = render();
// a barra vem no HTML; o grão só depois do import
expect(container.querySelector(".ds-scroll-bar")).toBeInTheDocument();
expect(screen.queryByTestId("grain")).toBeNull();
await loaded();
expect(screen.getByTestId("grain")).toBeInTheDocument();
expect(mockLoaded).toHaveBeenCalled();
});
it("does not mount the grain if the page unmounts while its package loads", async () => {
const { unmount } = render();
unmount();
await loaded();
expect(screen.queryByTestId("grain")).toBeNull();
});
});