156 lines
4.5 KiB
TypeScript
156 lines
4.5 KiB
TypeScript
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<string, string> = {
|
||
home: "Home",
|
||
about: "About",
|
||
projects: "Projects",
|
||
contact: "Contact",
|
||
};
|
||
return map[key] || key;
|
||
}
|
||
if (namespace === "common") {
|
||
const map: Record<string, string> = {
|
||
backToHome: "Back to Home",
|
||
backToProjects: "Back to Projects",
|
||
};
|
||
return map[key] || key;
|
||
}
|
||
if (namespace === "home.hero") {
|
||
const map: Record<string, string> = {
|
||
"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<string, string> = {
|
||
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<string, string> = {
|
||
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<HTMLImageElement>) {
|
||
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 };
|