/** * Test helper: wrap a render in a UiPrimitiveProvider with mock impls. * * Plugin tests that render components calling `useUiPrimitive(key)` need a * provider in scope. This helper builds an ad-hoc registry, registers any * impls the caller supplies, and wraps the children. Keys NOT supplied in * `partialImpls` are unregistered — strict-hook lookups will throw, soft-hook * lookups return null (matches production behavior on missing registrations). * * Usage in a test: * render( * withUiPrimitiveProvider( * { "ui:markdown-content": MockMarkdown }, * , * ), * ); * * See change: add-plugin-ui-primitive-registry. */ import React, { type ReactNode } from "react"; import { UI_PRIMITIVE_KEYS, type UiPrimitiveKey, type UiPrimitiveMap, } from "@blackbelt-technology/pi-dashboard-shared/dashboard-plugin/ui-primitives.js"; import { createUiPrimitiveRegistry, registerUiPrimitive, } from "../ui-primitive-registry.js"; import { UiPrimitiveProvider } from "../ui-primitive-context.js"; /** * Wrap `children` in a `` populated with the provided * impls. Keys absent from `partialImpls` remain unregistered so the test * matches production semantics for missing registrations (strict-hook throw, * soft-hook null). */ export function withUiPrimitiveProvider( partialImpls: Partial, children: ReactNode, ): React.ReactElement { const registry = createUiPrimitiveRegistry(); // Iterate the canonical key set so impls are registered exactly once each // (avoids unintended duplication if the caller's object has stray keys). for (const key of Object.values(UI_PRIMITIVE_KEYS) as UiPrimitiveKey[]) { const impl = partialImpls[key]; if (impl !== undefined) { // Type-narrowed: the value at partialImpls[key] is UiPrimitiveMap[key]. registerUiPrimitive(registry, key, impl as UiPrimitiveMap[typeof key]); } } return {children}; }