From 3986c091549c2975b5191e3762f5bd8b5457a2b1 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Mon, 18 May 2026 02:47:51 -0700 Subject: [PATCH] =?UTF-8?q?test(FN-4951):=20complete=20Step=202=20?= =?UTF-8?q?=E2=80=94=20add=20clipboard=20utility=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fusion-Task-Id: FN-4951 Fusion-Task-Lineage: 25de66db-c8cf-463b-86f2-efff1bc22683 --- .../utils/__tests__/copyToClipboard.test.ts | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 packages/dashboard/app/utils/__tests__/copyToClipboard.test.ts diff --git a/packages/dashboard/app/utils/__tests__/copyToClipboard.test.ts b/packages/dashboard/app/utils/__tests__/copyToClipboard.test.ts new file mode 100644 index 000000000..724fa93b5 --- /dev/null +++ b/packages/dashboard/app/utils/__tests__/copyToClipboard.test.ts @@ -0,0 +1,77 @@ +import { afterEach, describe, expect, it, vi } from "vitest"; + +import { copyTextToClipboard } from "../copyToClipboard"; + +describe("copyTextToClipboard", () => { + const originalClipboard = navigator.clipboard; + + afterEach(() => { + Object.defineProperty(navigator, "clipboard", { + configurable: true, + value: originalClipboard, + }); + vi.restoreAllMocks(); + document.body.innerHTML = ""; + }); + + it("uses Clipboard API when available", async () => { + const writeText = vi.fn().mockResolvedValue(undefined); + Object.defineProperty(navigator, "clipboard", { + configurable: true, + value: { writeText }, + }); + + await expect(copyTextToClipboard("abc123")).resolves.toBe(true); + expect(writeText).toHaveBeenCalledWith("abc123"); + }); + + it("falls back to execCommand when Clipboard API is unavailable", async () => { + Object.defineProperty(navigator, "clipboard", { + configurable: true, + value: undefined, + }); + const execSpy = vi.spyOn(document, "execCommand").mockReturnValue(true); + + await expect(copyTextToClipboard("fallback")).resolves.toBe(true); + expect(execSpy).toHaveBeenCalledWith("copy"); + }); + + it("falls back to execCommand when Clipboard API rejects", async () => { + const writeText = vi.fn().mockRejectedValue(new Error("NotAllowedError")); + Object.defineProperty(navigator, "clipboard", { + configurable: true, + value: { writeText }, + }); + const execSpy = vi.spyOn(document, "execCommand").mockReturnValue(false); + + await expect(copyTextToClipboard("reject-path")).resolves.toBe(false); + expect(writeText).toHaveBeenCalledWith("reject-path"); + expect(execSpy).toHaveBeenCalledWith("copy"); + }); + + it("returns false when both clipboard and fallback fail", async () => { + Object.defineProperty(navigator, "clipboard", { + configurable: true, + value: undefined, + }); + vi.spyOn(document, "execCommand").mockReturnValue(false); + + await expect(copyTextToClipboard("nope")).resolves.toBe(false); + }); + + it("removes temporary textarea after fallback attempts", async () => { + Object.defineProperty(navigator, "clipboard", { + configurable: true, + value: undefined, + }); + + const execSpy = vi.spyOn(document, "execCommand").mockReturnValue(true); + await copyTextToClipboard("cleanup-success"); + expect(execSpy).toHaveBeenCalledWith("copy"); + expect(document.querySelector("textarea")).toBeNull(); + + execSpy.mockReturnValueOnce(false); + await copyTextToClipboard("cleanup-failure"); + expect(document.querySelector("textarea")).toBeNull(); + }); +});