Files
Moh e2e06be86e test: add comprehensive automated test coverage
- Vitest multi-project setup (unit / integration / component)
- Real-Postgres integration harness via in-process PGlite (TEST_DATABASE_URL
  override), migrations applied per worker; production code untouched
- Unit: routing, locale, validation/Zod schemas, metadata, mail, site-theme,
  marquee, media, portfolio helpers, plus architecture-rule tests
- Integration: Prisma data layer, API routes, and all server actions
- Component: UI primitives and form components (jsdom + Testing Library)
- 371 tests passing
2026-08-06 02:27:20 +02:00

68 lines
1.9 KiB
TypeScript

import { vi } from "vitest";
/**
* Shared mocks for the Next.js runtime pieces that server actions depend on.
* Action tests wire these in with `vi.mock(...)` at the top of each file, e.g.:
*
* vi.mock("next/navigation", async () => ({
* redirect: (await import("@/tests/helpers/next-mocks")).redirect,
* }));
*/
export class RedirectError extends Error {
readonly digest = "NEXT_REDIRECT";
readonly __isRedirect = true;
constructor(public url: string) {
super(`NEXT_REDIRECT:${url}`);
}
}
export function redirect(url: string): never {
throw new RedirectError(url);
}
export function isRedirectError(error: unknown): error is RedirectError {
return (
error instanceof RedirectError ||
(typeof error === "object" && error !== null && (error as { __isRedirect?: boolean }).__isRedirect === true)
);
}
export const revalidatePath = vi.fn();
export const adminAuth = { authenticated: true };
export const clearAdminSessionCookie = vi.fn(async () => {});
export async function isAdminAuthenticated(): Promise<boolean> {
return adminAuth.authenticated;
}
/** Run an action and return the URL it redirected to (or throw if it didn't). */
export async function captureRedirect(run: () => Promise<unknown>): Promise<string> {
try {
await run();
} catch (error) {
if (isRedirectError(error)) {
return error.url;
}
throw error;
}
throw new Error("Expected the action to redirect, but it returned normally.");
}
export function resetNextMocks() {
revalidatePath.mockClear();
clearAdminSessionCookie.mockClear();
adminAuth.authenticated = true;
}
/** Build a FormData from a flat record (strings and Files). */
export function formDataFrom(fields: Record<string, string | File | undefined>): FormData {
const formData = new FormData();
for (const [key, value] of Object.entries(fields)) {
if (value !== undefined) {
formData.set(key, value);
}
}
return formData;
}