import { render } from "@testing-library/react"; import fc from "fast-check"; import type { HTMLAttributes, ReactNode } from "react"; import type { PortfolioExperience } from "@/lib/portfolio-data"; import Experience from "./Experience"; type MotionProps = HTMLAttributes & { initial?: unknown; whileInView?: unknown; viewport?: unknown; variants?: unknown; whileHover?: unknown; whileTap?: unknown; transition?: unknown; }; type SectionMockProps = { children?: ReactNode; title?: string; eyebrow?: string; description?: string; disableChildrenAnimation?: boolean; id?: string; className?: string; }; jest.mock("motion/react", () => { const createMotionElement = (Tag: "div" | "article") => ({ children, initial: _initial, whileInView: _whileInView, viewport: _viewport, variants: _variants, whileHover: _whileHover, whileTap: _whileTap, transition: _transition, ...props }: MotionProps & { children?: ReactNode }) => ( {children} ); return { motion: { div: createMotionElement("div"), article: createMotionElement("article"), }, useReducedMotion: () => false, }; }); jest.mock("./Section", () => ({ Section: ({ children, title, eyebrow: _eyebrow, description: _description, disableChildrenAnimation: _disableChildrenAnimation, ...props }: SectionMockProps) => (

{title}

{children}
), })); jest.mock("./animations/DrawLine", () => ({ DrawLine: () => , })); function makeExperience(index: number): PortfolioExperience { return { id: `experience-${index}`, title: `Experience ${index}`, company: "Company", period: `${2020 + index} - Present`, location: "Remote", type: index % 2 === 0 ? "Software" : "Hardware", description: "Description", achievements: [], technologies: [], featured: true, }; } describe("Experience heading hierarchy", () => { it("renders one h2 section heading and h3 headings for featured cards", () => { fc.assert( fc.property(fc.integer({ min: 1, max: 8 }), (count) => { const experiences = Array.from({ length: count }, (_, index) => makeExperience(index), ); const { container, unmount } = render( , ); const headings = Array.from( container.querySelectorAll("h1, h2, h3, h4, h5, h6"), ); expect(headings[0]?.tagName).toBe("H2"); expect(container.querySelector("section > h2")).toHaveTextContent( "Experiência em engenharia de software e sistemas críticos", ); expect(container.querySelectorAll("section > h2")).toHaveLength(1); expect(container.querySelectorAll("article h3")).toHaveLength(count); expect( new Set( Array.from(container.querySelectorAll("article h3")).map( (heading) => heading.textContent, ), ), ).toEqual(new Set(experiences.map((experience) => experience.title))); expect(headings.some((heading) => heading.tagName === "H4")).toBe( false, ); unmount(); }), { numRuns: 25 }, ); }); it("renders no card headings when no experiences are supplied", () => { const { container } = render(); expect(container.querySelector("section > h2")).toBeInTheDocument(); expect(container.querySelectorAll("article h3")).toHaveLength(0); }); });