A music player that connects to your cloud/distributed storage. diffuse.sh
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176import { describe, it, beforeAll, afterAll } from "@std/testing/bdd";import { expect } from "@std/expect";
import { mockServer } from "@tests/common/server.ts";import type { Track } from "~/definitions/types.d.ts";import * as Worker from "~/components/input/icecast/worker.js";
const METAINT = 16;const META_STRING = "StreamTitle='Pink Floyd - Time';StreamUrl='';";const META_PADDED = (() => { const encoded = new TextEncoder().encode(META_STRING); const len = Math.ceil(encoded.length / 16) * 16; const out = new Uint8Array(len); out.set(encoded); return out;})();const META_LENGTH_BYTE = new Uint8Array([META_PADDED.length / 16]);
function streamBody() { const audio = new Uint8Array(METAINT).fill(0xAA); return new Blob([audio, META_LENGTH_BYTE, META_PADDED]).stream();}
// Two servers on distinct ports so the per-host consult cache doesn't bleed// between scenarios.let goodServer: Deno.HttpServer;let goodPort: number;let plainServer: Deno.HttpServer;let plainPort: number;let deadPort: number;
beforeAll(async () => { const good = await mockServer((_req, url) => { if (url.pathname === "/stream.mp3") { return new Response(streamBody(), { status: 200, headers: { "Content-Type": "audio/mpeg", "icy-name": "TestRadio", "icy-genre": "Prog Rock", "icy-br": "128", "icy-metaint": String(METAINT), }, }); } return new Response("", { status: 404 }); }); goodServer = good.server; goodPort = good.port;
const plain = await mockServer((_req, url) => { if (url.pathname === "/noicy") { return new Response(new Uint8Array(32), { status: 200, headers: { "Content-Type": "audio/mpeg" }, }); } return new Response("", { status: 404 }); }); plainServer = plain.server; plainPort = plain.port;
// A port that nothing listens on. deadPort = plainPort + 1;});
afterAll(async () => { await goodServer.shutdown(); await plainServer.shutdown();});
describe("components/input/icecast (integration)", () => { it('consult returns "yes" for a live stream with ICY metadata', async () => { const result = await Worker.consult(`icecast://127.0.0.1:${goodPort}/stream.mp3?tls=0`); expect(result.supported).toBe(true); if (result.supported) { expect(result.consult).toBe("yes"); } });
it('consult returns "no" for a stream without icy-metaint', async () => { const result = await Worker.consult(`icecast://127.0.0.1:${plainPort}/noicy?tls=0`); expect(result.supported).toBe(true); if (result.supported) { expect(result.consult).toBe("no"); } });
it('consult returns "no" for an unreachable host', async () => { const result = await Worker.consult(`icecast://127.0.0.1:${deadPort}/stream.mp3?tls=0`); expect(result.supported).toBe(true); if (result.supported) { expect(result.consult).toBe("no"); } });
it("resolve returns the HTTPS stream URL by default", async () => { const resolved = await Worker.resolve({ uri: "icecast://radio.example.com/stream.mp3" }); expect(resolved).not.toBe(undefined); if (resolved && "url" in resolved) { expect(resolved.url).toContain("https://"); expect(resolved.url).toContain("radio.example.com"); expect(resolved.expiresAt).toBeGreaterThan(Date.now() / 1000); } });
it("resolve returns an HTTP stream URL when tls=0", async () => { const resolved = await Worker.resolve({ uri: `icecast://127.0.0.1:${goodPort}/stream.mp3?tls=0`, }); expect(resolved).not.toBe(undefined); if (resolved && "url" in resolved) { expect(resolved.url).toContain("http://127.0.0.1"); expect(resolved.url).toContain("/stream.mp3"); } });
it("list enriches tracks with ICY metadata from the stream", async () => { const tracks: Track[] = [{ $type: "sh.diffuse.output.track", id: "t1", uri: `icecast://127.0.0.1:${goodPort}/stream.mp3?tls=0`, }]; const refreshed = await Worker.list(tracks); expect(refreshed.length).toBe(1); expect(refreshed[0].kind).toBe("stream"); expect(refreshed[0].tags?.title).toBe("TestRadio"); expect(refreshed[0].tags?.genres).toEqual(["Prog Rock"]); expect(refreshed[0].stats?.bitrate).toBe(128_000); });
it("groupConsult reports available for a reachable host", async () => { const result = await Worker.groupConsult([ `icecast://127.0.0.1:${goodPort}/stream.mp3?tls=0`, ]); const key = `icecast://127.0.0.1:${goodPort}`; expect(result[key]?.available).toBe("yes"); expect(result[key]?.uris).toEqual([ `icecast://127.0.0.1:${goodPort}/stream.mp3?tls=0`, ]); });
it("groupConsult reports unavailable for an unreachable host", async () => { const result = await Worker.groupConsult([ `icecast://127.0.0.1:${deadPort}/stream.mp3?tls=0`, ]); const key = `icecast://127.0.0.1:${deadPort}`; expect(result[key]?.available).toBe("no"); if (result[key]?.available === "no") { expect(result[key]?.reason).toBeDefined(); } });
it("detach with scheme removes all icecast tracks", async () => { const tracks: Track[] = [ { $type: "sh.diffuse.output.track", id: "1", uri: `icecast://127.0.0.1:${goodPort}/a?tls=0` }, { $type: "sh.diffuse.output.track", id: "2", uri: `icecast://127.0.0.1:${goodPort}/b?tls=0` }, ]; const remaining = await Worker.detach({ fileUriOrScheme: "icecast", tracks }); expect(remaining.length).toBe(0); });
it("detach with a specific host URI removes only that host's tracks", async () => { const tracks: Track[] = [ { $type: "sh.diffuse.output.track", id: "1", uri: `icecast://127.0.0.1:${goodPort}/a?tls=0` }, { $type: "sh.diffuse.output.track", id: "2", uri: "icecast://other.example.com/c" }, ]; const remaining = await Worker.detach({ fileUriOrScheme: `icecast://127.0.0.1:${goodPort}/a?tls=0`, tracks, }); expect(remaining.length).toBe(1); expect(remaining[0].id).toBe("2"); });});