This repository has been archived on 2026-08-23. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
pi-web/src/client/src/promptAttachmentCapture.test.ts
T

82 lines
3.5 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { capturePromptAttachments, DEFAULT_FILE_MIME_TYPE, effectivePromptAttachmentDelivery, READ_FAILURE_MESSAGE, type CapturableFile } from "./promptAttachmentCapture";
function file(name: string, type: string, size = 10): CapturableFile {
return { name, type, size };
}
describe("capturePromptAttachments", () => {
it("reads supported images as native inline image attachments", async () => {
const result = await capturePromptAttachments(
[file("shot.png", "image/png"), file("pic.webp", "image/webp")],
(f) => Promise.resolve(`data-for-${f.name}`),
);
expect(result.error).toBeUndefined();
expect(result.attachments).toEqual([
{ kind: "image", name: "shot.png", mimeType: "image/png", data: "data-for-shot.png", size: 10 },
{ kind: "image", name: "pic.webp", mimeType: "image/webp", data: "data-for-pic.webp", size: 10 },
]);
});
it("captures generic files with their browser MIME type", async () => {
const result = await capturePromptAttachments(
[file("report.pdf", "application/pdf", 1234), file("vector.svg", "image/svg+xml")],
(f) => Promise.resolve(`data-for-${f.name}`),
);
expect(result.error).toBeUndefined();
expect(result.attachments).toEqual([
{ kind: "file", name: "report.pdf", mimeType: "application/pdf", data: "data-for-report.pdf", size: 1234 },
{ kind: "file", name: "vector.svg", mimeType: "image/svg+xml", data: "data-for-vector.svg", size: 10 },
]);
});
it("uses application/octet-stream when the browser does not provide a MIME type", async () => {
const result = await capturePromptAttachments([file("archive", "")], () => Promise.resolve("x"));
expect(result.attachments[0]).toMatchObject({ kind: "file", name: "archive", mimeType: DEFAULT_FILE_MIME_TYPE });
});
it("derives fallback names for unnamed pasted attachments", async () => {
const result = await capturePromptAttachments(
[file("", "image/jpeg"), file("", "application/pdf")],
() => Promise.resolve("x"),
);
expect(result.attachments.map((attachment) => attachment.name)).toEqual(["pasted-image.jpg", "pasted-file.bin"]);
});
it("reports a read failure without dropping other attachments", async () => {
const result = await capturePromptAttachments(
[file("bad.png", "image/png"), file("good.txt", "text/plain")],
(f) => f.name === "bad.png" ? Promise.reject(new Error("boom")) : Promise.resolve("ok"),
);
expect(result.error).toBe(READ_FAILURE_MESSAGE);
expect(result.attachments.map((attachment) => attachment.name)).toEqual(["good.txt"]);
});
it("returns no attachments and no error for an empty batch", async () => {
const result = await capturePromptAttachments([], () => Promise.resolve("x"));
expect(result).toEqual({ attachments: [] });
});
});
describe("effectivePromptAttachmentDelivery", () => {
it("preserves inline delivery when all pending attachments are supported images", () => {
expect(effectivePromptAttachmentDelivery("inline", [{ kind: "image", mimeType: "image/png" }])).toBe("inline");
});
it("preserves an explicit folder preference for supported images", () => {
expect(effectivePromptAttachmentDelivery("folder", [{ kind: "image", mimeType: "image/png" }])).toBe("folder");
});
it("forces folder delivery when any attachment is a generic file", () => {
expect(effectivePromptAttachmentDelivery("inline", [
{ kind: "image", mimeType: "image/png" },
{ kind: "file", mimeType: "application/pdf" },
])).toBe("folder");
});
});