feat(feed): optional per-feed sender-in-title toggle

Add a per-feed senderInTitle flag (domain FeedState.senderInTitle ↔
FeedConfig.sender_in_title). When set, the feed generator prefixes each
entry title with [Sender] (display name, falling back to the address).
Exposed as an admin edit-form checkbox and across the REST API
create/update/response schemas.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Julien Herr
2026-05-25 15:48:31 +02:00
parent 7086526670
commit e86beeeb8a
14 changed files with 234 additions and 2 deletions
+34
View File
@@ -143,6 +143,40 @@ describe("REST API (/api/v1)", () => {
expect(afterList.feeds.map((f) => f.id)).not.toContain(created.id);
});
it("defaults senderInTitle to false and lets it be set on create and update", async () => {
const createRes = await request("/api/v1/feeds", {
method: "POST",
headers: { ...authHeaders, "Content-Type": "application/json" },
body: JSON.stringify({ title: "Title Feed" }),
});
const created = (await createRes.json()) as {
id: string;
senderInTitle: boolean;
};
expect(created.senderInTitle).toBe(false);
const setRes = await request("/api/v1/feeds", {
method: "POST",
headers: { ...authHeaders, "Content-Type": "application/json" },
body: JSON.stringify({ title: "Prefixed Feed", senderInTitle: true }),
});
const set = (await setRes.json()) as {
id: string;
senderInTitle: boolean;
};
expect(set.senderInTitle).toBe(true);
const patchRes = await request(`/api/v1/feeds/${set.id}`, {
method: "PATCH",
headers: { ...authHeaders, "Content-Type": "application/json" },
body: JSON.stringify({ senderInTitle: false }),
});
expect(patchRes.status).toBe(200);
expect(
(await patchRes.json()) as { senderInTitle: boolean },
).toMatchObject({ senderInTitle: false });
});
it("returns 400 for an invalid create body", async () => {
const res = await request("/api/v1/feeds", {
method: "POST",