test: cover chat attachments
This commit is contained in:
58
src/gateway/chat-attachments.test.ts
Normal file
58
src/gateway/chat-attachments.test.ts
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
|
||||||
|
import {
|
||||||
|
buildMessageWithAttachments,
|
||||||
|
type ChatAttachment,
|
||||||
|
} from "./chat-attachments.js";
|
||||||
|
|
||||||
|
const PNG_1x1 =
|
||||||
|
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/woAAn8B9FD5fHAAAAAASUVORK5CYII=";
|
||||||
|
|
||||||
|
describe("buildMessageWithAttachments", () => {
|
||||||
|
it("embeds a single image as data URL", () => {
|
||||||
|
const msg = buildMessageWithAttachments("see this", [
|
||||||
|
{
|
||||||
|
type: "image",
|
||||||
|
mimeType: "image/png",
|
||||||
|
fileName: "dot.png",
|
||||||
|
content: PNG_1x1,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
expect(msg).toContain("see this");
|
||||||
|
expect(msg).toContain(`data:image/png;base64,${PNG_1x1}`);
|
||||||
|
expect(msg).toContain("![dot.png]");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("rejects non-image mime types", () => {
|
||||||
|
const bad: ChatAttachment = {
|
||||||
|
type: "file",
|
||||||
|
mimeType: "application/pdf",
|
||||||
|
fileName: "a.pdf",
|
||||||
|
content: "AAA",
|
||||||
|
};
|
||||||
|
expect(() => buildMessageWithAttachments("x", [bad])).toThrow(/image/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("rejects invalid base64 content", () => {
|
||||||
|
const bad: ChatAttachment = {
|
||||||
|
type: "image",
|
||||||
|
mimeType: "image/png",
|
||||||
|
fileName: "dot.png",
|
||||||
|
content: "%not-base64%",
|
||||||
|
};
|
||||||
|
expect(() => buildMessageWithAttachments("x", [bad])).toThrow(/base64/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("rejects images over limit", () => {
|
||||||
|
const big = Buffer.alloc(6_000_000, 0).toString("base64");
|
||||||
|
const att: ChatAttachment = {
|
||||||
|
type: "image",
|
||||||
|
mimeType: "image/png",
|
||||||
|
fileName: "big.png",
|
||||||
|
content: big,
|
||||||
|
};
|
||||||
|
expect(() =>
|
||||||
|
buildMessageWithAttachments("x", [att], { maxBytes: 5_000_000 }),
|
||||||
|
).toThrow(/exceeds size limit/i);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -29,8 +29,13 @@ export function buildMessageWithAttachments(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let sizeBytes = 0;
|
let sizeBytes = 0;
|
||||||
|
const b64 = content.trim();
|
||||||
|
// Basic base64 sanity: length multiple of 4 and charset check.
|
||||||
|
if (b64.length % 4 !== 0 || /[^A-Za-z0-9+/=]/.test(b64)) {
|
||||||
|
throw new Error(`attachment ${label}: invalid base64 content`);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
sizeBytes = Buffer.from(content, "base64").byteLength;
|
sizeBytes = Buffer.from(b64, "base64").byteLength;
|
||||||
} catch {
|
} catch {
|
||||||
throw new Error(`attachment ${label}: invalid base64 content`);
|
throw new Error(`attachment ${label}: invalid base64 content`);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user