import { afterEach, describe, expect, it, vi } from "vite-plus/test"; import { $createParagraphNode, $createTextNode, $getRoot, $getSelection, $isRangeSelection, COMMAND_PRIORITY_EDITOR, createEditor, PASTE_COMMAND, } from "lexical"; import { registerComposerInlineTokenPaste } from "./composerInlineTokenPaste"; class TestClipboardEvent extends Event { readonly clipboardData: DataTransfer; constructor(text: string) { super("paste", { cancelable: true }); this.clipboardData = { files: [], getData: (type: string) => (type === "text/plain" ? text : ""), } as unknown as DataTransfer; } } describe("registerComposerInlineTokenPaste", () => { afterEach(() => { vi.unstubAllGlobals(); }); it("handles a copied mention without also running the plain-text paste fallback", () => { vi.stubGlobal("ClipboardEvent", TestClipboardEvent); const editor = createEditor(); const mention = "[improve-deploy-error-logging.md](.changeset/improve-deploy-error-logging.md)"; const plainTextFallback = vi.fn(() => { const selection = $getSelection(); if (!$isRangeSelection(selection)) return false; selection.insertText(mention); return true; }); editor.update( () => { const paragraph = $createParagraphNode(); $getRoot().append(paragraph); paragraph.selectEnd(); }, { discrete: true }, ); registerComposerInlineTokenPaste(editor, { createMentionNode: (path) => $createTextNode(``), getExpandedAbsoluteOffsetForPoint: () => 0, }); editor.registerCommand(PASTE_COMMAND, plainTextFallback, COMMAND_PRIORITY_EDITOR); const event = new TestClipboardEvent(mention); let handled = false; editor.update( () => { handled = editor.dispatchCommand(PASTE_COMMAND, event as ClipboardEvent); }, { discrete: true }, ); expect(handled).toBe(true); expect(plainTextFallback).not.toHaveBeenCalled(); expect(event.defaultPrevented).toBe(true); expect(editor.getEditorState().read(() => $getRoot().getTextContent())).toBe( " ", ); }); });