test(ai-toolbar): isolate split suites and action coverage

This commit is contained in:
2026-04-23 05:52:48 -04:00
parent bd08e9fc63
commit 2590e1dbaf
5 changed files with 143 additions and 10 deletions

View File

@@ -54,7 +54,7 @@ export const createToolbarProps = (
...overrides,
});
export const registerAIToolbarTestHooks = () => {
export const registerAIToolbarEffectHooks = () => {
beforeEach(() => {
documentAddEventListener.mockClear();
documentRemoveEventListener.mockClear();
@@ -97,6 +97,26 @@ export const registerAIToolbarTestHooks = () => {
});
};
export const registerAIToolbarMarkupHooks = () => {
beforeEach(() => {
globalThis.document = {
addEventListener: () => {},
removeEventListener: () => {},
} as Document;
mock.module("@/hooks/use-mobile", () => ({
useIsMobile: () => false,
}));
});
afterEach(() => {
delete (globalThis as { document?: Document }).document;
delete (globalThis as { navigator?: Navigator }).navigator;
mock.restore();
});
};
export const registerAIToolbarTestHooks = registerAIToolbarEffectHooks;
export const renderToolbar = async (
overrides: Partial<AIToolbarProps> = {},
) => {
@@ -158,6 +178,52 @@ export const renderToolbarBoundary = async (
return { textareaProps: capturedTextareaProps!, imageTriggerOpen };
};
export const renderToolbarActionBoundary = async (
overrides: Partial<AIToolbarProps> = {},
) => {
type CapturedButton = React.ComponentProps<"button"> & {
label: string;
ariaLabel?: string;
};
const buttons: CapturedButton[] = [];
mock.module("@/components/ui/button", () => ({
Button: ({ children, ...props }: React.ComponentProps<"button">) => {
const label = renderToStaticMarkup(
actualReact.createElement(actualReact.Fragment, null, children),
)
.replace(/<[^>]+>/g, "")
.trim();
buttons.push({
...props,
label,
ariaLabel: props["aria-label"] as string | undefined,
});
return actualReact.createElement("button", props, children);
},
}));
const { AIToolbar } = await import("@/components/ai-toolbar");
renderToStaticMarkup(
actualReact.createElement(AIToolbar, createToolbarProps(overrides)),
);
return {
buttons,
getButtonByLabel: (label: string) => {
const button = buttons.find((entry) => entry.label.includes(label));
expect(button).toBeDefined();
return button!;
},
getButtonByAriaLabel: (ariaLabel: string) => {
const button = buttons.find((entry) => entry.ariaLabel === ariaLabel);
expect(button).toBeDefined();
return button!;
},
};
};
export const getDocumentListener = (
type: string,
predicate: (entry: {