feat(config): P3 config batch — group 6 (RSS fidelity + rss_name/rss_max_items)
write_rss now emits upstream's full RSS 2.0 structure: - xmlns:atom on <rss>; channel <link> points at the diary index page (base_url + diary_rel + diary_index + .html), not bare base_url. - <atom:link rel="self"> to base_url + rss_name. - channel + per-item <pubDate> (RFC-822, derived from the diary date; 1970-01-01=Thu weekday math via to_days_epoch). - per-item <guid isPermaLink="false"> holding the bare date. - per-item <![CDATA[ rendered page body ]]> (render_entry_body reads+parses the entry and renders body-only with the wiki's colour/valid-tag/emoji opts; cdata_safe splits any literal ]]>). - rss_name drives the output filename; rss_max_items caps the feed (0 = unlimited). Tests: updated write_rss_uses_base_url_for_public_links for the new channel link/guid/atom/pubDate; new write_rss_honours_rss_name_and_max_items. Full rust suite + clippy clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -613,13 +613,48 @@ fn write_rss_uses_base_url_for_public_links() {
|
||||
}];
|
||||
let path = nuwiki_lsp::commands::export_ops::write_rss(&c, &entries).unwrap();
|
||||
let xml = std::fs::read_to_string(&path).unwrap();
|
||||
// Channel + item links use the public base URL, not file://.
|
||||
assert!(xml.contains("<link>https://example.com/wiki/</link>"));
|
||||
// Channel link points at the diary index page (upstream fidelity); item
|
||||
// link is the public per-entry URL.
|
||||
assert!(
|
||||
xml.contains("<link>https://example.com/wiki/diary/diary.html</link>"),
|
||||
"channel link: {xml}"
|
||||
);
|
||||
assert!(xml.contains("<link>https://example.com/wiki/diary/2026-05-11.html</link>"));
|
||||
assert!(xml.contains("<guid>https://example.com/wiki/diary/2026-05-11.html</guid>"));
|
||||
// guid is the bare date, isPermaLink=false.
|
||||
assert!(
|
||||
xml.contains("<guid isPermaLink=\"false\">2026-05-11</guid>"),
|
||||
"guid: {xml}"
|
||||
);
|
||||
// atom:link self + a pubDate are present.
|
||||
assert!(xml.contains("rel=\"self\""), "atom:link: {xml}");
|
||||
assert!(xml.contains("<pubDate>"), "pubDate: {xml}");
|
||||
assert!(!xml.contains("file:///tmp/diary"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_rss_honours_rss_name_and_max_items() {
|
||||
use nuwiki_lsp::diary::DiaryEntry;
|
||||
use tower_lsp::lsp_types::Url;
|
||||
let root = temp_root("rss_cap");
|
||||
let mut c = WikiConfig::from_root(root.clone());
|
||||
c.html = HtmlConfig::from_root(&root);
|
||||
c.html.rss_name = "feed.xml".into();
|
||||
c.html.rss_max_items = 2;
|
||||
let entries: Vec<DiaryEntry> = (1..=5)
|
||||
.map(|d| DiaryEntry {
|
||||
date: DiaryDate::from_ymd(2026, 5, d).unwrap(),
|
||||
uri: Url::parse(&format!("file:///tmp/diary/2026-05-0{d}.wiki")).unwrap(),
|
||||
})
|
||||
.collect();
|
||||
let path = nuwiki_lsp::commands::export_ops::write_rss(&c, &entries).unwrap();
|
||||
assert!(path.ends_with("feed.xml"), "rss_name: {path:?}");
|
||||
let xml = std::fs::read_to_string(&path).unwrap();
|
||||
// Capped at 2 items (newest first: 05-05, 05-04).
|
||||
assert_eq!(xml.matches("<item>").count(), 2, "cap: {xml}");
|
||||
assert!(xml.contains("2026-05-05") && xml.contains("2026-05-04"));
|
||||
assert!(!xml.contains("2026-05-03"), "older items dropped: {xml}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_page_invokes_custom_wiki2html_converter() {
|
||||
let root = temp_root("custom_w2h");
|
||||
|
||||
Reference in New Issue
Block a user