Files
STCourses/packages/core/test/media.test.ts
T
2026-10-30 03:04:46 +01:00

60 lines
2.4 KiB
TypeScript

import { expect, test } from "bun:test";
import { mkdtempSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { serveMedia } from "../src";
const dir = mkdtempSync(join(tmpdir(), "stc-media-"));
const file = join(dir, "clip.mp4");
const bytes = new Uint8Array(1000).map((_, i) => i % 251);
writeFileSync(file, bytes);
const req = (range?: string) => new Request("http://x/m", { headers: range ? { Range: range } : {} });
test("full file gives 200", async () => {
const r = await serveMedia(req(), file);
expect(r.status).toBe(200);
expect(r.headers.get("content-type")).toBe("video/mp4");
expect(r.headers.get("accept-ranges")).toBe("bytes");
expect(r.headers.get("content-length")).toBe("1000");
expect((await r.arrayBuffer()).byteLength).toBe(1000);
});
test("bytes=0-99 gives 206 with Content-Range", async () => {
const r = await serveMedia(req("bytes=0-99"), file);
expect(r.status).toBe(206);
expect(r.headers.get("content-range")).toBe("bytes 0-99/1000");
expect(r.headers.get("content-length")).toBe("100");
expect(new Uint8Array(await r.arrayBuffer())).toEqual(bytes.slice(0, 100));
});
test("open-ended, suffix and clamped ranges", async () => {
let r = await serveMedia(req("bytes=900-"), file);
expect(r.status).toBe(206);
expect(r.headers.get("content-range")).toBe("bytes 900-999/1000");
r = await serveMedia(req("bytes=-10"), file);
expect(r.headers.get("content-range")).toBe("bytes 990-999/1000");
expect(new Uint8Array(await r.arrayBuffer())).toEqual(bytes.slice(990));
r = await serveMedia(req("bytes=990-5000"), file);
expect(r.headers.get("content-range")).toBe("bytes 990-999/1000");
});
test("unsatisfiable range gives 416", async () => {
const r = await serveMedia(req("bytes=999999999-"), file);
expect(r.status).toBe(416);
expect(r.headers.get("content-range")).toBe("bytes */1000");
});
test("non-ASCII filename gets a valid filename*", async () => {
const f = join(dir, "Æble notes.pdf");
writeFileSync(f, "pdf");
const r = await serveMedia(req(), f, { download: true });
expect(r.headers.get("content-type")).toBe("application/pdf");
const cd = r.headers.get("content-disposition")!;
expect(cd).toContain("filename*=UTF-8''%C3%86ble%20notes.pdf");
expect(cd).toContain('filename="_ble notes.pdf"');
});
test("missing file is 404", async () => {
expect((await serveMedia(req(), join(dir, "nope.mp4"))).status).toBe(404);
});