import test from "node:test";
import assert from "node:assert/strict";
import { getAdapter, normalizeUrl } from "../src/ingest/adapters/index.js";
const RSS = `
Test Feed
https://example.com/blog
-
First Post
https://example.com/posts/first?utm_source=feed
Some html description
]]>
-
Relative Link
/posts/relative
Relative one
-
Atom style
Atom styled link
`;
test("rss adapter resolves each item's own link, not the feed url", async () => {
// 保留原始 fetch:把 RSS 内容喂进去
const realFetch = globalThis.fetch;
globalThis.fetch = async () => new Response(RSS, { status: 200 });
try {
const items = await getAdapter("rss").fetch("https://example.com/feed.xml");
assert.equal(items.length, 3);
assert.equal(items[0].title, "First Post");
// 关键:url 必须是条目的链接,而不是 https://example.com/feed.xml
assert.equal(items[0].url, "https://example.com/posts/first");
// utm_ 参数被去掉
assert.ok(!items[0].url.includes("utm_source"));
assert.match(items[0].description, /Some html description/);
// 相对链接按 feed 地址解析成绝对地址
assert.equal(items[1].url, "https://example.com/posts/relative");
// 形式也能取到
assert.equal(items[2].url, "https://example.com/posts/atom");
assert.ok(items.every((i) => i.url !== "https://example.com/feed.xml"));
} finally {
globalThis.fetch = realFetch;
}
});
test("normalizeUrl drops tracking params and trailing slash", () => {
assert.equal(normalizeUrl("https://a.com/x/?utm_src=b#frag"), "https://a.com/x");
assert.equal(normalizeUrl("https://a.com/x"), "https://a.com/x");
});