mirror of
https://github.com/juherr/kill-the-news.git
synced 2026-06-20 22:03:48 +00:00
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:
@@ -147,6 +147,37 @@ describe("generateRssFeed", () => {
|
||||
expect(result).not.toContain("<item>");
|
||||
});
|
||||
|
||||
it("leaves the item title unprefixed by default", () => {
|
||||
const result = generateRssFeed(
|
||||
mockFeedConfig,
|
||||
mockEmails,
|
||||
BASE_URL,
|
||||
FEED_ID,
|
||||
);
|
||||
expect(result).toContain("Hello World");
|
||||
expect(result).not.toContain("[Alice]");
|
||||
});
|
||||
|
||||
it("prefixes the item title with the sender when sender_in_title is set", () => {
|
||||
const result = generateRssFeed(
|
||||
{ ...mockFeedConfig, sender_in_title: true },
|
||||
mockEmails,
|
||||
BASE_URL,
|
||||
FEED_ID,
|
||||
);
|
||||
expect(result).toContain("[Alice] Hello World");
|
||||
});
|
||||
|
||||
it("falls back to the email address when the sender has no display name", () => {
|
||||
const result = generateRssFeed(
|
||||
{ ...mockFeedConfig, sender_in_title: true },
|
||||
[{ ...mockEmails[0], from: "bob@example.com" }],
|
||||
BASE_URL,
|
||||
FEED_ID,
|
||||
);
|
||||
expect(result).toContain("[bob@example.com] Hello World");
|
||||
});
|
||||
|
||||
it("feed link points to the public read URL, never an admin path", () => {
|
||||
const result = generateRssFeed(
|
||||
mockFeedConfig,
|
||||
|
||||
@@ -74,8 +74,12 @@ function buildFeed(
|
||||
baseUrl,
|
||||
EmailAddress.parse(email.from)?.siteBaseUrl() ?? "",
|
||||
);
|
||||
const subject = htmlToText(email.subject);
|
||||
const title = feedConfig.sender_in_title
|
||||
? `[${parseFromAddress(email.from).name ?? email.from}] ${subject}`
|
||||
: subject;
|
||||
feed.addItem({
|
||||
title: htmlToText(email.subject),
|
||||
title,
|
||||
id: entryUrl,
|
||||
link: entryUrl,
|
||||
description: bodyContent,
|
||||
|
||||
@@ -18,6 +18,7 @@ export function fromConfigDTO(dto: FeedConfig): FeedState {
|
||||
language: dto.language,
|
||||
mailboxId: dto.mailbox_id,
|
||||
author: dto.author,
|
||||
senderInTitle: dto.sender_in_title,
|
||||
allowedSenders: dto.allowed_senders ?? [],
|
||||
blockedSenders: dto.blocked_senders ?? [],
|
||||
createdAt: dto.created_at,
|
||||
@@ -34,6 +35,7 @@ export function toConfigDTO(state: FeedState): FeedConfig {
|
||||
language: state.language,
|
||||
mailbox_id: state.mailboxId,
|
||||
author: state.author,
|
||||
sender_in_title: state.senderInTitle,
|
||||
allowed_senders: state.allowedSenders,
|
||||
blocked_senders: state.blockedSenders,
|
||||
created_at: state.createdAt,
|
||||
|
||||
Reference in New Issue
Block a user