test(ai-toolbar): close remaining modifier and identity gaps
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
|
||||
import * as React from "react";
|
||||
import { renderToStaticMarkup } from "react-dom/server";
|
||||
import { imageFileKey } from "@/lib/multi-image";
|
||||
|
||||
type AIToolbarProps = {
|
||||
adminAiEnabled: boolean;
|
||||
@@ -586,6 +587,19 @@ describe("AI toolbar paste capture", () => {
|
||||
expect(imageTriggerOpen).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test("Mod+A without Shift does not open the image picker", async () => {
|
||||
const { textareaProps, imageTriggerOpen } = await renderToolbarBoundary();
|
||||
const event = createTextareaKeydownEvent({
|
||||
key: "A",
|
||||
ctrlKey: true,
|
||||
});
|
||||
|
||||
textareaProps.onKeyDown?.(event);
|
||||
|
||||
expect(event.preventDefault).not.toHaveBeenCalled();
|
||||
expect(imageTriggerOpen).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test("Shift+Cmd+A also opens the image picker when the composer is idle", async () => {
|
||||
const { textareaProps, imageTriggerOpen } = await renderToolbarBoundary();
|
||||
const metaEvent = createTextareaKeydownEvent({
|
||||
@@ -748,6 +762,69 @@ describe("AI toolbar paste capture", () => {
|
||||
expect(onImagesSelect).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test("Shift+Mod+V does not trigger the async clipboard fallback", async () => {
|
||||
const onImagesSelect = mock();
|
||||
const clipboardRead = mock(async () => []);
|
||||
|
||||
(globalThis as { navigator?: Navigator }).navigator = {
|
||||
clipboard: { read: clipboardRead },
|
||||
} as Navigator;
|
||||
|
||||
await renderToolbar({ onImagesSelect });
|
||||
|
||||
const handleDocumentKeydown = getDocumentListener("keydown");
|
||||
|
||||
await handleDocumentKeydown(
|
||||
createDocumentKeydownEvent({ ctrlKey: true, shiftKey: true }),
|
||||
);
|
||||
|
||||
expect(clipboardRead).not.toHaveBeenCalled();
|
||||
expect(onImagesSelect).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test("Alt+Mod+V does not trigger the async clipboard fallback", async () => {
|
||||
const onImagesSelect = mock();
|
||||
const clipboardRead = mock(async () => []);
|
||||
|
||||
(globalThis as { navigator?: Navigator }).navigator = {
|
||||
clipboard: { read: clipboardRead },
|
||||
} as Navigator;
|
||||
|
||||
await renderToolbar({ onImagesSelect });
|
||||
|
||||
const handleDocumentKeydown = getDocumentListener("keydown");
|
||||
|
||||
await handleDocumentKeydown(
|
||||
createDocumentKeydownEvent({ ctrlKey: true, altKey: true }),
|
||||
);
|
||||
|
||||
expect(clipboardRead).not.toHaveBeenCalled();
|
||||
expect(onImagesSelect).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test("async clipboard fallback ignores editable targets", async () => {
|
||||
const onImagesSelect = mock();
|
||||
const clipboardRead = mock(async () => []);
|
||||
|
||||
(globalThis as { navigator?: Navigator }).navigator = {
|
||||
clipboard: { read: clipboardRead },
|
||||
} as Navigator;
|
||||
|
||||
await renderToolbar({ onImagesSelect });
|
||||
|
||||
const handleDocumentKeydown = getDocumentListener("keydown");
|
||||
|
||||
await handleDocumentKeydown(
|
||||
createDocumentKeydownEvent({
|
||||
ctrlKey: true,
|
||||
target: { tagName: "DIV", isContentEditable: true },
|
||||
}),
|
||||
);
|
||||
|
||||
expect(clipboardRead).not.toHaveBeenCalled();
|
||||
expect(onImagesSelect).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test("Ctrl+Meta+V does not trigger the async clipboard fallback", async () => {
|
||||
const onImagesSelect = mock();
|
||||
const clipboardRead = mock(async () => []);
|
||||
@@ -918,6 +995,9 @@ describe("AI toolbar paste capture", () => {
|
||||
expect(syncOnImagesSelect.mock.calls[0]?.[0][0]?.lastModified).toBe(
|
||||
asyncOnImagesSelect.mock.calls[0]?.[0][0]?.lastModified,
|
||||
);
|
||||
expect(
|
||||
imageFileKey(syncOnImagesSelect.mock.calls[0]?.[0][0]),
|
||||
).toBe(imageFileKey(asyncOnImagesSelect.mock.calls[0]?.[0][0]));
|
||||
});
|
||||
|
||||
test("async clipboard fallback does not double-handle a paste already handled by the synchronous document paste flow", async () => {
|
||||
|
||||
Reference in New Issue
Block a user