86 lines
3.3 KiB
TypeScript
86 lines
3.3 KiB
TypeScript
import { expect, test } from "@playwright/test";
|
|
|
|
import {
|
|
proxyCanvasAudioSource,
|
|
proxyCanvasVideoSource,
|
|
} from "../../lib/video-canvas/audio-source-proxy";
|
|
|
|
function requestFor(source?: string) {
|
|
const url = new URL("http://127.0.0.1/api/canvas/audio-source");
|
|
if (source) url.searchParams.set("url", source);
|
|
return new Request(url);
|
|
}
|
|
|
|
test.describe.serial("video canvas audio source proxy", () => {
|
|
test("requires a public HTTPS audio URL", async () => {
|
|
expect((await proxyCanvasAudioSource(requestFor())).status).toBe(400);
|
|
expect((await proxyCanvasAudioSource(requestFor("http://example.com/audio.mp3"))).status).toBe(400);
|
|
expect((await proxyCanvasAudioSource(requestFor("https://127.0.0.1/audio.mp3"))).status).toBe(400);
|
|
expect((await proxyCanvasAudioSource(requestFor("https://[fc00::1]/audio.mp3"))).status).toBe(400);
|
|
});
|
|
|
|
test("streams an accepted audio response", async () => {
|
|
const fetcher = (async () =>
|
|
new Response(new Uint8Array([1, 2, 3]), {
|
|
headers: { "content-length": "3", "content-type": "audio/mpeg" },
|
|
})) as typeof fetch;
|
|
|
|
const response = await proxyCanvasAudioSource(requestFor("https://1.1.1.1/audio.mp3"), fetcher);
|
|
expect(response.status).toBe(200);
|
|
expect(response.headers.get("content-type")).toBe("audio/mpeg");
|
|
expect(Array.from(new Uint8Array(await response.arrayBuffer()))).toEqual([1, 2, 3]);
|
|
});
|
|
|
|
test("rejects non-audio and oversized upstream responses", async () => {
|
|
const textFetcher = (async () =>
|
|
new Response("not audio", { headers: { "content-type": "text/plain" } })) as typeof fetch;
|
|
expect(
|
|
(await proxyCanvasAudioSource(requestFor("https://1.1.1.1/file.txt"), textFetcher)).status,
|
|
).toBe(415);
|
|
|
|
const oversizedFetcher = (async () =>
|
|
new Response(new Uint8Array([1]), {
|
|
headers: {
|
|
"content-length": String(101 * 1024 * 1024),
|
|
"content-type": "audio/wav",
|
|
},
|
|
})) as typeof fetch;
|
|
expect(
|
|
(await proxyCanvasAudioSource(requestFor("https://1.1.1.1/audio.wav"), oversizedFetcher)).status,
|
|
).toBe(413);
|
|
});
|
|
|
|
test("accepts video only through the video proxy", async () => {
|
|
const fetcher = (async () =>
|
|
new Response(new Uint8Array([4, 5, 6]), {
|
|
headers: { "content-length": "3", "content-type": "video/mp4" },
|
|
})) as typeof fetch;
|
|
expect(
|
|
(await proxyCanvasAudioSource(requestFor("https://1.1.1.1/video.mp4"), fetcher)).status,
|
|
).toBe(415);
|
|
const response = await proxyCanvasVideoSource(
|
|
requestFor("https://1.1.1.1/video.mp4"),
|
|
fetcher,
|
|
);
|
|
expect(response.status).toBe(200);
|
|
expect(response.headers.get("content-type")).toBe("video/mp4");
|
|
});
|
|
|
|
test("normalizes a CDN response that mislabels an MP4 as text", async () => {
|
|
const fetcher = (async () =>
|
|
new Response(new Uint8Array([0, 0, 0, 24]), {
|
|
headers: { "content-length": "4", "content-type": "text/plain" },
|
|
})) as typeof fetch;
|
|
|
|
const response = await proxyCanvasVideoSource(
|
|
requestFor("https://1.1.1.1/generated-video.mp4"),
|
|
fetcher,
|
|
);
|
|
expect(response.status).toBe(200);
|
|
expect(response.headers.get("content-type")).toBe("video/mp4");
|
|
expect(
|
|
(await proxyCanvasVideoSource(requestFor("https://1.1.1.1/readme.txt"), fetcher)).status,
|
|
).toBe(415);
|
|
});
|
|
});
|