Adds a /api/staff/file proxy that re-streams Civi attachments with Content-Disposition: inline so a native <dialog> lightbox can preview images and PDFs in place. Office docs keep their plain download link and gain a "View in Google Docs" secondary link (uses the Civi-signed URL so Google can fetch without our staff key). Also threads mime through /api/staff/report (Attachment.get mime_type) so the dispatcher picks the right affordance without relying solely on filename inference.
83 lines
2.8 KiB
JavaScript
83 lines
2.8 KiB
JavaScript
// Run with: npm run test:mime
|
|
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import {
|
|
extOf,
|
|
mimeFromFilename,
|
|
resolveMime,
|
|
categoryFromMime,
|
|
} from "./mime.mjs";
|
|
|
|
test("extOf returns lowercased extension", () => {
|
|
assert.equal(extOf("Photo.JPG"), "jpg");
|
|
assert.equal(extOf("doc.tar.gz"), "gz");
|
|
});
|
|
|
|
test("extOf handles missing or trailing-dot names", () => {
|
|
assert.equal(extOf(""), "");
|
|
assert.equal(extOf(null), "");
|
|
assert.equal(extOf("no-extension"), "");
|
|
assert.equal(extOf("trailing."), "");
|
|
});
|
|
|
|
test("mimeFromFilename recognises known types", () => {
|
|
assert.equal(mimeFromFilename("vision.pdf"), "application/pdf");
|
|
assert.equal(mimeFromFilename("budget.XLSX"),
|
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
|
assert.equal(mimeFromFilename("logo.PNG"), "image/png");
|
|
});
|
|
|
|
test("mimeFromFilename returns null for unknown extensions", () => {
|
|
assert.equal(mimeFromFilename("archive.zip"), null);
|
|
assert.equal(mimeFromFilename("readme"), null);
|
|
});
|
|
|
|
test("resolveMime trusts an explicit non-octet mime", () => {
|
|
assert.equal(resolveMime("application/pdf", "anything.txt"), "application/pdf");
|
|
});
|
|
|
|
test("resolveMime falls back to filename when explicit is missing", () => {
|
|
assert.equal(resolveMime(undefined, "report.pdf"), "application/pdf");
|
|
assert.equal(resolveMime(null, "image.gif"), "image/gif");
|
|
});
|
|
|
|
test("resolveMime falls back to filename when explicit is octet-stream", () => {
|
|
assert.equal(
|
|
resolveMime("application/octet-stream", "spreadsheet.xlsx"),
|
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
);
|
|
});
|
|
|
|
test("resolveMime returns octet-stream when nothing is known", () => {
|
|
assert.equal(resolveMime(null, null), "application/octet-stream");
|
|
assert.equal(resolveMime(undefined, "unknownfile"), "application/octet-stream");
|
|
});
|
|
|
|
test("categoryFromMime: image", () => {
|
|
assert.equal(categoryFromMime("image/png"), "image");
|
|
assert.equal(categoryFromMime("image/webp"), "image");
|
|
});
|
|
|
|
test("categoryFromMime: pdf", () => {
|
|
assert.equal(categoryFromMime("application/pdf"), "pdf");
|
|
});
|
|
|
|
test("categoryFromMime: office variants", () => {
|
|
assert.equal(categoryFromMime("application/msword"), "office");
|
|
assert.equal(
|
|
categoryFromMime("application/vnd.openxmlformats-officedocument.wordprocessingml.document"),
|
|
"office",
|
|
);
|
|
assert.equal(categoryFromMime("application/vnd.ms-excel"), "office");
|
|
assert.equal(
|
|
categoryFromMime("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"),
|
|
"office",
|
|
);
|
|
});
|
|
|
|
test("categoryFromMime: other", () => {
|
|
assert.equal(categoryFromMime("application/zip"), "other");
|
|
assert.equal(categoryFromMime("text/plain"), "other");
|
|
assert.equal(categoryFromMime("application/octet-stream"), "other");
|
|
});
|