101 lines
2.9 KiB
TypeScript
101 lines
2.9 KiB
TypeScript
/**
|
|
* Shared test utilities for the form-component tests. Each form needs an
|
|
* `<AuthProvider>` + `<BrandingProvider>` wrap with controllable seams,
|
|
* inside a `<TranslationProvider>` so `useTranslation()` resolves.
|
|
*/
|
|
|
|
import { createI18n } from "@suaveplan/i18n/plugin";
|
|
import { TranslationProvider } from "@suaveplan/react-i18n";
|
|
import { lightTheme, ThemeProvider } from "@suaveplan/react-ui/theme";
|
|
import type { ReactNode } from "react";
|
|
import { AuthProvider } from "../../src/context/auth-context.js";
|
|
import { BrandingProvider } from "../../src/context/branding-context.js";
|
|
import type {
|
|
AuthConfig,
|
|
TenantBranding,
|
|
} from "../../src/types/branding.types.js";
|
|
|
|
export interface FormFetchCall {
|
|
url: string;
|
|
init?: RequestInit;
|
|
}
|
|
|
|
export function makeFetch(
|
|
handler: (call: FormFetchCall) => Response | Promise<Response>
|
|
): {
|
|
fetch: (
|
|
input: string | URL | Request,
|
|
init?: RequestInit
|
|
) => Promise<Response>;
|
|
calls: FormFetchCall[];
|
|
} {
|
|
const calls: FormFetchCall[] = [];
|
|
return {
|
|
calls,
|
|
fetch: async (input, init) => {
|
|
const url = typeof input === "string" ? input : input.toString();
|
|
calls.push({ url, init });
|
|
return handler({ url, init });
|
|
},
|
|
};
|
|
}
|
|
|
|
export function jsonResponse(body: unknown, status = 200): Response {
|
|
return new Response(JSON.stringify(body), {
|
|
status,
|
|
headers: { "Content-Type": "application/json" },
|
|
});
|
|
}
|
|
|
|
export const FORM_TEST_BRANDING: TenantBranding = {
|
|
tenantId: "test",
|
|
name: "Test Co",
|
|
primaryColor: "#3B82F6",
|
|
secondaryColor: "#10B981",
|
|
logo: "https://cdn/logo.svg",
|
|
logoLight: "https://cdn/logo-light.svg",
|
|
};
|
|
|
|
export interface FormWrapperOptions {
|
|
authConfig?: Partial<AuthConfig> | undefined;
|
|
navigated?: string[] | undefined;
|
|
}
|
|
|
|
const sharedI18n = createI18n({
|
|
defaultLocale: "en-GB",
|
|
messages: { "en-GB": {} },
|
|
});
|
|
|
|
export function FormWrapper({
|
|
children,
|
|
options = {},
|
|
}: {
|
|
children: ReactNode;
|
|
options?: FormWrapperOptions;
|
|
}): ReactNode {
|
|
const fetchImpl =
|
|
options.authConfig?.fetch ?? makeFetch(() => jsonResponse({})).fetch;
|
|
const navigate =
|
|
options.authConfig?.navigate ??
|
|
((url: string): void => {
|
|
options.navigated?.push(url);
|
|
});
|
|
const config: AuthConfig = {
|
|
authUrl: "https://auth.example.com",
|
|
...options.authConfig,
|
|
fetch: fetchImpl,
|
|
navigate,
|
|
};
|
|
return (
|
|
<TranslationProvider i18n={sharedI18n}>
|
|
<ThemeProvider themes={[lightTheme]} defaultTheme="light">
|
|
<BrandingProvider staticBranding={FORM_TEST_BRANDING}>
|
|
<AuthProvider config={config} initialUser={null}>
|
|
{children}
|
|
</AuthProvider>
|
|
</BrandingProvider>
|
|
</ThemeProvider>
|
|
</TranslationProvider>
|
|
);
|
|
}
|