113 lines
3.1 KiB
TypeScript
113 lines
3.1 KiB
TypeScript
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
|
|
import { useReducedMotion } from "@/app/hooks/useReducedMotion";
|
|
import {
|
|
PORTRAIT_CYBER_FEATURES,
|
|
PortraitCyberScene,
|
|
} from "./PortraitCyberScene";
|
|
|
|
jest.mock("@/app/hooks/useReducedMotion", () => ({
|
|
useReducedMotion: jest.fn(),
|
|
}));
|
|
|
|
jest.mock("../animations/LazyRevealImage", () => ({
|
|
LazyRevealImage: ({
|
|
alt,
|
|
className,
|
|
}: {
|
|
alt: string;
|
|
className?: string;
|
|
}) => (
|
|
<div
|
|
aria-label={alt}
|
|
className={className}
|
|
data-testid="portrait-image"
|
|
role="img"
|
|
/>
|
|
),
|
|
}));
|
|
|
|
jest.mock("@react-three/fiber", () => ({
|
|
Canvas: ({ children: _children, ...props }: Record<string, unknown>) => (
|
|
<div data-testid="portrait-cyber-canvas" {...props} />
|
|
),
|
|
useFrame: jest.fn(),
|
|
}));
|
|
|
|
const mockedUseReducedMotion = jest.mocked(useReducedMotion);
|
|
|
|
describe("PortraitCyberScene", () => {
|
|
beforeEach(() => {
|
|
mockedUseReducedMotion.mockReturnValue(false);
|
|
});
|
|
|
|
it("keeps the accessible photo and mounts the cyber layers when visible", async () => {
|
|
render(
|
|
<PortraitCyberScene
|
|
src="/edev.jpg"
|
|
alt="Retrato profissional de Evandro Fonseca Junior"
|
|
/>,
|
|
);
|
|
|
|
const scene = screen.getByTestId("portrait-cyber");
|
|
|
|
await waitFor(() =>
|
|
expect(screen.getByTestId("portrait-cyber-canvas")).toBeInTheDocument(),
|
|
);
|
|
expect(
|
|
screen.getByRole("img", {
|
|
name: "Retrato profissional de Evandro Fonseca Junior",
|
|
}),
|
|
).toBeInTheDocument();
|
|
expect(scene).toHaveAttribute(
|
|
"data-cyber-effects",
|
|
PORTRAIT_CYBER_FEATURES.join(" "),
|
|
);
|
|
expect(screen.getByTestId("portrait-cyber-scanlines")).toBeInTheDocument();
|
|
});
|
|
|
|
it("exposes the RGB split state only while the pointer is over the portrait", async () => {
|
|
render(<PortraitCyberScene src="/edev.jpg" alt="Retrato profissional" />);
|
|
|
|
const scene = screen.getByTestId("portrait-cyber");
|
|
Object.defineProperty(scene, "getBoundingClientRect", {
|
|
configurable: true,
|
|
value: () => ({
|
|
bottom: 100,
|
|
height: 100,
|
|
left: 0,
|
|
right: 100,
|
|
top: 0,
|
|
width: 100,
|
|
x: 0,
|
|
y: 0,
|
|
}),
|
|
});
|
|
|
|
await waitFor(() =>
|
|
expect(screen.getByTestId("portrait-cyber-canvas")).toBeInTheDocument(),
|
|
);
|
|
fireEvent.pointerMove(scene, { clientX: 80, clientY: 20 });
|
|
expect(scene).toHaveAttribute("data-cyber-state", "hovered");
|
|
|
|
fireEvent.pointerLeave(scene);
|
|
expect(scene).toHaveAttribute("data-cyber-state", "idle");
|
|
});
|
|
|
|
it("keeps the photo static while showing the cyber layers when reduced motion is preferred", async () => {
|
|
mockedUseReducedMotion.mockReturnValue(true);
|
|
|
|
render(<PortraitCyberScene src="/edev.jpg" alt="Retrato profissional" />);
|
|
|
|
expect(screen.getByTestId("portrait-cyber")).toHaveAttribute(
|
|
"data-motion",
|
|
"reduced",
|
|
);
|
|
await waitFor(() =>
|
|
expect(screen.getByTestId("portrait-cyber-canvas")).toBeInTheDocument(),
|
|
);
|
|
expect(
|
|
screen.queryByRole("img", { name: "Retrato profissional" }),
|
|
).toBeInTheDocument();
|
|
});
|
|
});
|