/** * @file promptAttach.test.ts — `claudePastes`: how files reach a `claude` pane. * @author Nguyễn Ngọc Trí Vĩ */ import { describe, expect, it } from "vitest"; import { claudePastes, copiedFilePaths, localCandidates } from "../promptAttach"; describe("claudePastes", () => { it("pastes each image as its bare path and the other files as one @ mention paste", () => { expect( claudePastes(["/d/drops/a.png", "/d/drops/b-report.pdf", "/d/x.JPG", "/d/c.log"]) ).toEqual(["/d/drops/a.png", "/d/x.JPG", "@/d/drops/b-report.pdf @/d/c.log"]); }); it("keeps a Windows or spaced image path a mention", () => { expect(claudePastes(["C:\\u\\drops\\a.png", "/home/u/my shot.png"])).toEqual([ '@C:/u/drops/a.png @"/home/u/my shot.png"', ]); }); }); /** A clipboard as the browser hands it to a paste handler. */ const clip = (data: Record) => ({ getData: (t: string) => data[t] ?? "" }) as unknown as DataTransfer; const file = (name: string) => new File(["x"], name); describe("localCandidates (a file manager's copy, pasted)", () => { it("takes the plain-text paths when their names match the pasted files", () => { expect(window.location.hostname).toBe("localhost"); const dt = clip({ "text/plain": "/home/u/Videos/big.mp4\n/home/u/b c.pdf\n" }); expect(localCandidates(dt, [file("b c.pdf"), file("big.mp4")])).toEqual([ "/home/u/Videos/big.mp4", "/home/u/b c.pdf", ]); }); it("takes file:// lines too, decoded", () => { const dt = clip({ "text/plain": "file:///home/u/a%20b.zip" }); expect(localCandidates(dt, [file("a b.zip")])).toEqual(["/home/u/a b.zip"]); }); it("refuses text that does not name exactly the pasted files", () => { expect(localCandidates(clip({ "text/plain": "/etc/passwd" }), [file("big.mp4")])).toBeNull(); expect(localCandidates(clip({ "text/plain": "hello" }), [file("hello")])).toBeNull(); expect( localCandidates(clip({ "text/plain": "/a/x.txt" }), [file("x.txt"), file("y.txt")]) ).toBeNull(); }); it("prefers a uri-list (a drag) as before", () => { const dt = clip({ "text/uri-list": "file:///tmp/z.bin", "text/plain": "/other/z.bin" }); expect(localCandidates(dt, [file("z.bin")])).toEqual(["/tmp/z.bin"]); }); }); describe("copiedFilePaths (no file beside the text)", () => { it("takes file:// text, never bare absolute paths, which stay text to paste", () => { expect(copiedFilePaths(clip({ "text/plain": "file:///home/u/a.txt" }))).toEqual([ "/home/u/a.txt", ]); expect(copiedFilePaths(clip({ "text/plain": "/home/u/a.txt" }))).toBeNull(); }); });