import test from "node:test"; import assert from "node:assert/strict"; import { postDate, isoDate, limit, filterTagList, readingTime, extractHeadings } from "../src/_filters/index.js"; test("Filters - postDate: formats valid dates", () => { assert.equal(postDate("2026-07-20"), "JUL 20, 2026"); assert.equal(postDate(new Date("2026-12-31T00:00:00Z")), "DEC 31, 2026"); }); test("Filters - postDate: handles adversarial / invalid inputs gracefully", () => { assert.equal(postDate(null), ""); assert.equal(postDate(undefined), ""); assert.equal(postDate("invalid-date-string"), ""); assert.equal(postDate(""), ""); }); test("Filters - isoDate: formats ISO strings", () => { assert.equal(isoDate("2026-07-20"), "2026-07-20"); assert.equal(isoDate(new Date("2026-05-15T00:00:00Z")), "2026-05-15"); }); test("Filters - isoDate: handles adversarial / invalid inputs gracefully", () => { assert.equal(isoDate(null), ""); assert.equal(isoDate(undefined), ""); assert.equal(isoDate("not-a-date"), ""); }); test("Filters - limit: slices arrays correctly", () => { assert.deepEqual(limit([1, 2, 3, 4, 5], 3), [1, 2, 3]); assert.deepEqual(limit([1, 2], 5), [1, 2]); }); test("Filters - limit: handles adversarial inputs (negative, 0, non-array)", () => { assert.deepEqual(limit([1, 2, 3], 0), []); assert.deepEqual(limit([1, 2, 3], -5), []); assert.deepEqual(limit(null, 3), []); assert.deepEqual(limit("not-an-array", 3), []); }); test("Filters - filterTagList: removes internal system tags", () => { const input = ["firmware", "posts", "security", "all", "nav", "post"]; assert.deepEqual(filterTagList(input), ["firmware", "security"]); }); test("Filters - filterTagList: handles adversarial inputs (# prefix, casing, non-string)", () => { const input = ["#firmware", "#POSTS", "ALL", "#homelab", 42, null, undefined]; assert.deepEqual(filterTagList(input), ["#firmware", "#homelab"]); assert.deepEqual(filterTagList(null), []); assert.deepEqual(filterTagList(undefined), []); }); test("Filters - readingTime: calculates reading time from word count", () => { // 199 words -> 1 min const shortText = "word ".repeat(199); assert.equal(readingTime(shortText), "1 MIN READ"); // 201 words -> 2 min const mediumText = "word ".repeat(201); assert.equal(readingTime(mediumText), "2 MIN READ"); // 1000 words -> 5 min const longText = "word ".repeat(1000); assert.equal(readingTime(longText), "5 MIN READ"); }); test("Filters - readingTime: respects explicit frontmatter override", () => { assert.equal(readingTime("any text", "15 MIN READ"), "15 MIN READ"); }); test("Filters - readingTime: handles adversarial HTML tags without inflating word count", () => { // HTML tags should be stripped before counting words const htmlText = "
word

another

"; assert.equal(readingTime(htmlText), "1 MIN READ"); assert.equal(readingTime(""), "1 MIN READ"); assert.equal(readingTime(null), "1 MIN READ"); }); test("Filters - extractHeadings: extracts H2 and H3 with IDs and titles", () => { const html = `

Title To Ignore

1.0 First Section

Some text

1.1 Sub Section

Ignore H4

2.0 Second Section with code and span

`; const headings = extractHeadings(html); assert.equal(headings.length, 3); assert.deepEqual(headings[0], { level: 2, id: "section-1", title: "1.0 First Section" }); assert.deepEqual(headings[1], { level: 3, id: "sub-1", title: "1.1 Sub Section" }); assert.deepEqual(headings[2], { level: 2, id: "section-2", title: "2.0 Second Section with code and span" }); }); test("Filters - extractHeadings: handles adversarial HTML inputs gracefully", () => { assert.deepEqual(extractHeadings(""), []); assert.deepEqual(extractHeadings(null), []); assert.deepEqual(extractHeadings(undefined), []); assert.deepEqual(extractHeadings("

No headings here

"), []); });