import "@testing-library/jest-dom"; import "whatwg-fetch"; import React from "react"; import { render } from "@testing-library/react"; import { ToastProvider } from "@/components/Toast"; // Mock Next.js router jest.mock("next/navigation", () => ({ useRouter() { return { push: jest.fn(), replace: jest.fn(), prefetch: jest.fn(), back: jest.fn(), pathname: "/", query: {}, asPath: "/", }; }, usePathname() { return "/"; }, useSearchParams() { return new URLSearchParams(); }, notFound: jest.fn(), })); // Mock next-intl (ESM) for Jest jest.mock("next-intl", () => ({ useLocale: () => "en", useTranslations: (namespace?: string) => (key: string) => { if (namespace === "nav") { const map: Record = { home: "Home", about: "About", projects: "Projects", contact: "Contact", }; return map[key] || key; } if (namespace === "common") { const map: Record = { backToHome: "Back to Home", backToProjects: "Back to Projects", }; return map[key] || key; } if (namespace === "home.hero") { const map: Record = { "features.f1": "Next.js & Flutter", "features.f2": "Docker Swarm & CI/CD", "features.f3": "Self-Hosted Infrastructure", description: "Student and passionate self-hoster building full-stack web apps and mobile solutions. I run my own infrastructure and love exploring DevOps.", ctaWork: "View My Work", ctaContact: "Contact Me", }; return map[key] || key; } if (namespace === "home.about") { const map: Record = { title: "About Me", p1: "Hi, I'm Dennis – a student and passionate self-hoster based in Osnabrück, Germany.", p2: "I love building full-stack web applications with Next.js and mobile apps with Flutter. But what really excites me is DevOps: I run my own infrastructure and automate deployments with CI/CD.", p3: "When I'm not coding or tinkering with servers, you'll find me gaming, jogging, or experimenting with automation workflows.", funFactTitle: "Fun Fact", funFactBody: "Even though I automate a lot, I still use pen and paper for my calendar and notes – it helps me stay focused.", }; return map[key] || key; } if (namespace === "home.contact") { const map: Record = { title: "Contact Me", subtitle: "Interested in working together or have questions about my projects? Feel free to reach out!", getInTouch: "Get In Touch", getInTouchBody: "I'm always available to discuss new opportunities, interesting projects, or simply chat about technology and innovation.", }; return map[key] || key; } return key; }, NextIntlClientProvider: ({ children }: { children: React.ReactNode }) => React.createElement(React.Fragment, null, children), })); // Mock next/link jest.mock("next/link", () => { return function Link({ children, href, }: { children: React.ReactNode; href: string; }) { return React.createElement("a", { href }, children); }; }); // Mock next/image jest.mock("next/image", () => { return function Image({ src, alt, ...props }: React.ImgHTMLAttributes) { return React.createElement("img", { src, alt, ...props }); }; }); // Mock react-responsive-masonry if it's used jest.mock("react-responsive-masonry", () => { const MasonryComponent = function Masonry({ children, }: { children: React.ReactNode; }) { return React.createElement("div", { "data-testid": "masonry" }, children); }; const ResponsiveMasonryComponent = function ResponsiveMasonry({ children, }: { children: React.ReactNode; }) { return React.createElement( "div", { "data-testid": "responsive-masonry" }, children, ); }; return { __esModule: true, default: MasonryComponent, ResponsiveMasonry: ResponsiveMasonryComponent, }; }); // Custom render function with ToastProvider const customRender = (ui: React.ReactElement, options = {}) => render(ui, { wrapper: ({ children }) => React.createElement(ToastProvider, null, children), ...options, }); // Re-export everything export * from "@testing-library/react"; export { customRender as render };