test: expand mime detection coverage
This commit is contained in:
57
src/media/mime.test.ts
Normal file
57
src/media/mime.test.ts
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import JSZip from "jszip";
|
||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
|
||||||
|
import { detectMime } from "./mime.js";
|
||||||
|
|
||||||
|
async function makeOoxmlZip(opts: {
|
||||||
|
mainMime: string;
|
||||||
|
partPath: string;
|
||||||
|
}): Promise<Buffer> {
|
||||||
|
const zip = new JSZip();
|
||||||
|
zip.file(
|
||||||
|
"[Content_Types].xml",
|
||||||
|
`<Types><Override PartName="${opts.partPath}" ContentType="${opts.mainMime}.main+xml"/></Types>`,
|
||||||
|
);
|
||||||
|
zip.file(opts.partPath.slice(1), "<xml/>");
|
||||||
|
return await zip.generateAsync({ type: "nodebuffer" });
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("mime detection", () => {
|
||||||
|
it("detects docx from buffer", async () => {
|
||||||
|
const buf = await makeOoxmlZip({
|
||||||
|
mainMime:
|
||||||
|
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||||
|
partPath: "/word/document.xml",
|
||||||
|
});
|
||||||
|
const mime = await detectMime({ buffer: buf, filePath: "/tmp/file.bin" });
|
||||||
|
expect(mime).toBe(
|
||||||
|
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("detects pptx from buffer", async () => {
|
||||||
|
const buf = await makeOoxmlZip({
|
||||||
|
mainMime:
|
||||||
|
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
||||||
|
partPath: "/ppt/presentation.xml",
|
||||||
|
});
|
||||||
|
const mime = await detectMime({ buffer: buf, filePath: "/tmp/file.bin" });
|
||||||
|
expect(mime).toBe(
|
||||||
|
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("prefers extension mapping over generic zip", async () => {
|
||||||
|
const zip = new JSZip();
|
||||||
|
zip.file("hello.txt", "hi");
|
||||||
|
const buf = await zip.generateAsync({ type: "nodebuffer" });
|
||||||
|
|
||||||
|
const mime = await detectMime({
|
||||||
|
buffer: buf,
|
||||||
|
filePath: "/tmp/file.xlsx",
|
||||||
|
});
|
||||||
|
expect(mime).toBe(
|
||||||
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -3,7 +3,7 @@ import os from "node:os";
|
|||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
|
|
||||||
import sharp from "sharp";
|
import sharp from "sharp";
|
||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||||
|
|
||||||
import { loadWebMedia } from "./media.js";
|
import { loadWebMedia } from "./media.js";
|
||||||
|
|
||||||
@@ -54,4 +54,25 @@ describe("web media loading", () => {
|
|||||||
expect(result.kind).toBe("image");
|
expect(result.kind).toBe("image");
|
||||||
expect(result.contentType).toBe("image/jpeg");
|
expect(result.contentType).toBe("image/jpeg");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("adds extension to URL fileName when missing", async () => {
|
||||||
|
const fetchMock = vi.spyOn(globalThis, "fetch").mockResolvedValueOnce({
|
||||||
|
ok: true,
|
||||||
|
body: true,
|
||||||
|
arrayBuffer: async () => Buffer.from("%PDF-1.4").buffer,
|
||||||
|
headers: { get: () => "application/pdf" },
|
||||||
|
status: 200,
|
||||||
|
} as Response);
|
||||||
|
|
||||||
|
const result = await loadWebMedia(
|
||||||
|
"https://example.com/download",
|
||||||
|
1024 * 1024,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result.kind).toBe("document");
|
||||||
|
expect(result.contentType).toBe("application/pdf");
|
||||||
|
expect(result.fileName).toBe("download.pdf");
|
||||||
|
|
||||||
|
fetchMock.mockRestore();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user