import assert from "node:assert/strict"; import test from "node:test"; import { createApp } from "../src/app.js"; import { baseConfig, listen } from "./helpers.js"; const feed = { body: "", etag: '"feed-tag"', lastModified: new Date("2025-01-01T00:00:00Z"), }; test("serves health and RSS endpoints with conditional GET", async (t) => { const app = createApp(baseConfig, { feedService: { async get() { return feed; } }, silent: true, }); const server = await listen(app); t.after(server.close); const health = await fetch(`${server.url}/healthz`); assert.equal(health.status, 200); assert.deepEqual(await health.json(), { status: "ok" }); const response = await fetch(`${server.url}/rss.xml`); assert.equal(response.status, 200); assert.match(response.headers.get("content-type"), /application\/rss\+xml/); assert.equal(response.headers.get("etag"), feed.etag); assert.equal(await response.text(), feed.body); const fresh = await fetch(`${server.url}/rss.xml`, { headers: { "if-none-match": feed.etag }, }); assert.equal(fresh.status, 304); }); test("optionally protects the feed with HTTP Basic auth", async (t) => { const config = structuredClone(baseConfig); config.feed.username = "reader"; config.feed.password = "secret:with-colon"; const app = createApp(config, { feedService: { async get() { return feed; } }, silent: true, }); const server = await listen(app); t.after(server.close); const denied = await fetch(`${server.url}/rss.xml`); assert.equal(denied.status, 401); assert.match(denied.headers.get("www-authenticate"), /Basic/); const accepted = await fetch(`${server.url}/rss.xml`, { headers: { authorization: `Basic ${Buffer.from("reader:secret:with-colon").toString("base64")}`, }, }); assert.equal(accepted.status, 200); }); test("returns 502 without leaking upstream error details", async (t) => { const app = createApp(baseConfig, { feedService: { async get() { throw new Error("secret upstream detail"); } }, silent: true, }); const server = await listen(app); t.after(server.close); const response = await fetch(`${server.url}/rss.xml`); assert.equal(response.status, 502); assert.deepEqual(await response.json(), { error: "Could not generate feed from Suwayomi", }); });