diff --git a/tests/ai-toolbar.test.ts b/tests/ai-toolbar.test.ts index 1a26c52..ac10ce7 100644 --- a/tests/ai-toolbar.test.ts +++ b/tests/ai-toolbar.test.ts @@ -502,6 +502,20 @@ describe("AI toolbar paste capture", () => { expect(imageTriggerOpen).toHaveBeenCalledTimes(1); }); + test("Shift+Cmd+A also opens the image picker when the composer is idle", async () => { + const { textareaProps, imageTriggerOpen } = await renderToolbarBoundary(); + const metaEvent = createTextareaKeydownEvent({ + key: "A", + metaKey: true, + shiftKey: true, + }); + + textareaProps.onKeyDown?.(metaEvent); + + expect(metaEvent.preventDefault).toHaveBeenCalledTimes(1); + expect(imageTriggerOpen).toHaveBeenCalledTimes(1); + }); + test("Shift+Mod+A stays disabled while generation is in progress", async () => { const { textareaProps, imageTriggerOpen } = await renderToolbarBoundary({ aiLoading: true, @@ -592,7 +606,7 @@ describe("AI toolbar paste capture", () => { expect(onImagesSelect.mock.calls[0]?.[0][0]?.type).toBe("image/png"); }); - test("async clipboard fallback does not double-handle a paste already captured by the synchronous paste event", async () => { + test("async clipboard fallback does not double-handle a paste already handled by the synchronous document paste flow", async () => { const onImagesSelect = mock(); const clipboardRead = mock(async () => [ { @@ -611,24 +625,35 @@ describe("AI toolbar paste capture", () => { "paste", (entry) => entry.options?.capture === true, ); + const handleDocumentPaste = getDocumentListener( + "paste", + (entry) => !entry.options?.capture, + ); const handleDocumentKeydown = getDocumentListener("keydown"); const image = new File(["image-bytes"], "clipboard.png", { type: "image/png", }); + const preventDefault = mock(); const keydownPromise = handleDocumentKeydown( createDocumentKeydownEvent({ ctrlKey: true }), ); - handleCapturePaste({ + const pasteEvent = { target: { tagName: "DIV", isContentEditable: false }, clipboardData: createClipboardData([image]), - } as unknown as Event); + preventDefault, + } as unknown as Event; + + handleCapturePaste(pasteEvent); + handleDocumentPaste(pasteEvent); await keydownPromise; + expect(preventDefault).toHaveBeenCalledTimes(1); expect(clipboardRead).not.toHaveBeenCalled(); - expect(onImagesSelect).not.toHaveBeenCalled(); + expect(onImagesSelect).toHaveBeenCalledTimes(1); + expect(onImagesSelect).toHaveBeenCalledWith([image]); }); test("global paste listeners only arm when AI paste capture is usable, and disarm on cleanup", async () => {