import { get, html, stubNetwork } from "../helpers.ts"; import { assertEquals } from "@std/assert"; import type { Tralbum } from "../../../shared/player.ts"; function escapeAttr(s: string): string { return s.replaceAll("&", "&").replaceAll('"', """); } function tralbumPage(data: unknown): string { return `
`; } const STREAM = "https://t4.bcbits.com/stream/abc/mp3-128/1?p=0&ts=1&t=x"; const ALBUM = { item_type: "album", artist: "Artist", art_id: 12345, current: { title: 'The "Album" & more' }, trackinfo: [ { track_num: 1, title: "One", duration: 180.5, streaming: 1, file: { "mp3-128": STREAM }, }, { track_num: 2, title: "Preorder", streaming: 1, unreleased_track: true, file: null, }, { track_num: 3, title: "", streaming: 1, file: { "mp3-128": "https://evil.test/x.mp3" }, }, { track_num: 4, title: "Capped", streaming: 1, is_capped: true, file: { "mp3-128": STREAM }, }, ], }; Deno.test("GET /api/bandcamp/tracks: resolves, caches, and forces a refetch", async () => { using net = stubNetwork(() => html(tralbumPage(ALBUM))); const url = "https://cached.bandcamp.com/album/x"; const res = await get( `/api/bandcamp/tracks?url=${encodeURIComponent(url)}`, ); assertEquals(res.status, 200); assertEquals(res.headers.get("cache-control"), "private, max-age=3600"); assertEquals(res.data.tracks.length, 4); // Same page (different query/case/trailing slash) → cache hit. await get( `/api/bandcamp/tracks?url=${ encodeURIComponent("https://CACHED.bandcamp.com/album/x/?from=y") }`, ); assertEquals(net.calls.length, 1); await get(`/api/bandcamp/tracks?url=${encodeURIComponent(url)}&force=1`); assertEquals(net.calls.length, 2); }); Deno.test("GET /api/bandcamp/tracks: refusals and upstream failures", async () => { using _ = stubNetwork((url) => { if (url.hostname.startsWith("down")) { return new Response("", { status: 503 }); } if (url.hostname.startsWith("json")) return Response.json({}); return html("no tralbum"); }); const status = async (url: string) => (await get(`/api/bandcamp/tracks?url=${encodeURIComponent(url)}`)).status; assertEquals(await status("https://example.com/album/x"), 400); assertEquals(await status("https://bandcamp.com.evil.test/album/x"), 400); assertEquals(await status("http://localhost/album/x"), 400); assertEquals(await status("https://down.bandcamp.com/album/x"), 502); assertEquals(await status("https://json.bandcamp.com/album/x"), 502); assertEquals(await status("https://empty.bandcamp.com/album/x"), 404); });