/* @vitest-environment node */ import { describe, it, expect, vi, afterEach } from "vitest"; import { writeTextToClipboard } from "./clipboard.js"; function createDocumentStub({ copyResult = true } = {}) { const textarea = { value: "", style: {}, setAttribute: vi.fn(), focus: vi.fn(), select: vi.fn(), setSelectionRange: vi.fn(), remove: vi.fn(), }; const documentStub = { createElement: vi.fn().mockReturnValue(textarea), body: { appendChild: vi.fn(), }, execCommand: vi.fn().mockReturnValue(copyResult), }; return { documentStub, textarea }; } describe("lib/frontend/ui/clipboard", () => { afterEach(() => { vi.unstubAllGlobals(); vi.restoreAllMocks(); }); it("uses navigator.clipboard when available", async () => { const writeText = vi.fn().mockResolvedValue(undefined); vi.stubGlobal("navigator", { clipboard: { writeText }, }); const { documentStub } = createDocumentStub({ copyResult: true }); vi.stubGlobal("document", documentStub); const result = await writeTextToClipboard("secret"); expect(writeText).toHaveBeenCalledWith("secret"); expect(documentStub.execCommand).not.toHaveBeenCalled(); expect(result).toEqual({ ok: true, method: "clipboard" }); }); it("falls back to execCommand when Clipboard API is unavailable", async () => { vi.stubGlobal("navigator", {}); const { documentStub, textarea } = createDocumentStub({ copyResult: true }); vi.stubGlobal("document", documentStub); const result = await writeTextToClipboard("secret"); expect(documentStub.createElement).toHaveBeenCalledWith("textarea"); expect(documentStub.body.appendChild).toHaveBeenCalledWith(textarea); expect(documentStub.execCommand).toHaveBeenCalledWith("copy"); expect(textarea.remove).toHaveBeenCalledTimes(1); expect(result).toEqual({ ok: true, method: "execCommand" }); }); it("falls back to execCommand when Clipboard API throws", async () => { const writeText = vi.fn().mockRejectedValue(new Error("not allowed")); vi.stubGlobal("navigator", { clipboard: { writeText }, }); const { documentStub } = createDocumentStub({ copyResult: true }); vi.stubGlobal("document", documentStub); const result = await writeTextToClipboard("secret"); expect(writeText).toHaveBeenCalledWith("secret"); expect(documentStub.execCommand).toHaveBeenCalledWith("copy"); expect(result).toEqual({ ok: true, method: "execCommand" }); }); it("returns ok=false when no copy mechanism is available", async () => { vi.stubGlobal("navigator", {}); vi.stubGlobal("document", undefined); const result = await writeTextToClipboard("secret"); expect(result).toEqual({ ok: false, method: null }); }); });