Adds aclRepo to @stc/db for canView. Co-Authored-By: Claude Opus 5.5 <[email protected]>
60 lines
2.4 KiB
TypeScript
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);
|
|
});
|