Files
carmanagement/apps/dashboard/src/app/public-auth-pages.test.ts
T
root 0c9f3f8635 fix: resolve TS18046 errors for React 19 element props type
React 19 types React.ReactElement props as unknown instead of any. Test
helper functions that access element.props.children, .className, or .href
need explicit props type parameters on React.ReactElement and isValidElement.

Changes:
- admin/PublicShell.test.ts: add WithChildren type, use React.ReactElement<WithChildren>
- dashboard/PublicShell.test.ts: same pattern for childTypes and contentWrapper
- dashboard/StatCard.test.ts: add ElementWithClass type for className access
- dashboard/public-auth-pages.test.ts: add ElementWithHref type for href access

No any, @ts-ignore, or type assertion bypass used.
2026-06-28 01:21:36 -04:00

97 lines
3.4 KiB
TypeScript

import React, { isValidElement } from "react";
import { describe, expect, it } from "vitest";
import ForgotPasswordPageClient from "./forgot-password/ForgotPasswordPageClient";
import ResetPasswordPageClient from "./reset-password/ResetPasswordPageClient";
import ForgotPasswordPage from "./forgot-password/page";
import ResetPasswordPage from "./reset-password/page";
import AcceptInvitePage from "./onboarding/accept-invite/page";
import SignUpForm from "./sign-up/[[...sign-up]]/SignUpForm";
import SignUpPage from "./sign-up/[[...sign-up]]/page";
function collectText(node: unknown): string[] {
if (node === null || node === undefined || typeof node === "boolean")
return [];
if (typeof node === "string" || typeof node === "number")
return [String(node)];
if (Array.isArray(node)) return node.flatMap(collectText);
if (isValidElement<{ children?: React.ReactNode }>(node))
return collectText(node.props.children);
return [];
}
type ElementWithHref = { children?: React.ReactNode; href?: string; embedded?: boolean }
function findElement(
node: unknown,
predicate: (element: React.ReactElement<ElementWithHref>) => boolean,
): React.ReactElement<ElementWithHref> | null {
if (node === null || node === undefined || typeof node === "boolean")
return null;
if (Array.isArray(node)) {
for (const child of node) {
const found = findElement(child, predicate);
if (found) return found;
}
return null;
}
if (!isValidElement<ElementWithHref>(node)) return null;
if (predicate(node)) return node;
return findElement(node.props.children, predicate);
}
describe("dashboard public auth pages", () => {
it("renders forgot-password with public chrome by default", async () => {
const page = await ForgotPasswordPage({
searchParams: Promise.resolve({}),
});
expect(isValidElement(page)).toBe(true);
expect(page.type).toBe(ForgotPasswordPageClient);
expect(page.props.embedded).toBe(false);
});
it("renders forgot-password in embedded mode when requested", async () => {
const page = await ForgotPasswordPage({
searchParams: Promise.resolve({ embedded: "1" }),
});
expect(isValidElement(page)).toBe(true);
expect(page.type).toBe(ForgotPasswordPageClient);
expect(page.props.embedded).toBe(true);
});
it("renders sign-up in embedded mode when requested", async () => {
const page = await SignUpPage({
searchParams: Promise.resolve({ embedded: "1" }),
});
expect(isValidElement(page)).toBe(true);
expect(page.type).toBe(React.Suspense);
const child = page.props.children;
expect(isValidElement(child)).toBe(true);
expect(child.type).toBe(SignUpForm);
expect(child.props.embedded).toBe(true);
});
it("renders reset-password in embedded mode for the public shell route", () => {
const page = ResetPasswordPage();
expect(isValidElement(page)).toBe(true);
expect(page.type).toBe(ResetPasswordPageClient);
expect(page.props.embedded).toBe(true);
});
it("keeps accept-invite copy and sign-in handoff visible", () => {
const page = AcceptInvitePage();
const text = collectText(page).join(" ");
const signInLink = findElement(
page,
(element) => element.props.href === "/sign-in",
);
expect(text).toContain("Invitation accepted");
expect(text).toContain("Sign in to dashboard");
expect(signInLink).not.toBeNull();
});
});