Initial implementation
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
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: "<rss></rss>",
|
||||
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",
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user