1import { afterEach, describe, expect, it, vi } from "vite-plus/test";
2
3import { COMPOSER_CONTEXT_CLIPBOARD_MIME } from "@t3tools/shared/composerContextClipboard";
4
5import { writeTextToClipboard } from "./useCopyToClipboard";
6
7describe("writeTextToClipboard", () => {
8 it("reserves plain text even when an extra flavor attempts to replace it", async () => {
9 const write = vi.fn().mockResolvedValue(undefined);
10 vi.stubGlobal("window", {});
11 vi.stubGlobal("navigator", { clipboard: { write, writeText: vi.fn() } });
12 vi.stubGlobal(
13 "ClipboardItem",
14 class {
15 constructor(readonly data: Record<string, Blob>) {}
16 },
17 );
18 await expect(
19 writeTextToClipboard("original", "message", {
20 "text/plain": "replacement",
21 "text/html": "<b>original</b>",
22 }),
23 ).resolves.toBe(true);
24 const items = write.mock.calls[0]![0] as Array<{ data: Record<string, Blob> }>;
25 expect(await items[0]!.data["text/plain"]!.text()).toBe("original");
26 });
27 afterEach(() => {
28 vi.unstubAllGlobals();
29 });
30
31 it("keeps caller-built rich HTML when attaching a context fragment", async () => {
32 const write = vi.fn().mockResolvedValue(undefined);
33 vi.stubGlobal("window", {});
34 vi.stubGlobal("navigator", { clipboard: { write, writeText: vi.fn() } });
35 vi.stubGlobal(
36 "ClipboardItem",
37 class {
38 constructor(readonly data: Record<string, Blob>) {}
39 },
40 );
41 const fragment = JSON.stringify({ version: 1, source: {}, records: [] });
42 const rich = "<p><strong>Message</strong></p>";
43
44 await expect(
45 writeTextToClipboard("Message", "message", {
46 [COMPOSER_CONTEXT_CLIPBOARD_MIME]: fragment,
47 "text/html": rich,
48 }),
49 ).resolves.toBe(true);
50
51 const items = write.mock.calls[0]![0] as Array<{ data: Record<string, Blob> }>;
52 const html = await items[0]!.data["text/html"]!.text();
53 expect(html).toContain(rich);
54 expect(html).toContain("data-t3-context-fragment=");
55 });
56});