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); }); });