/**
* 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};
}