import { afterEach, describe, expect, test } from "bun:test"; import { convertHtmlToMarkdown, extractTitleFromMarkdownDocument, } from "../extract/html-to-markdown"; const originalFetch = globalThis.fetch; afterEach(() => { globalThis.fetch = originalFetch; }); describe("extractTitleFromMarkdownDocument", () => { test("prefers frontmatter title when present", () => { const title = extractTitleFromMarkdownDocument(`--- title: "Frontmatter Title" --- # Heading Title `); expect(title).toBe("Frontmatter Title"); }); test("falls back to the first markdown heading", () => { const title = extractTitleFromMarkdownDocument(` Intro text # Heading Title Body text. `); expect(title).toBe("Heading Title"); }); }); describe("convertHtmlToMarkdown remote fallback", () => { test("does not call defuddle.md when the remote fallback option is disabled", async () => { let fetchCalls = 0; globalThis.fetch = Object.assign( async () => { fetchCalls += 1; return new Response("# Remote Title\n\nRemote body.", { headers: { "content-type": "text/markdown", }, }); }, { preconnect: originalFetch.preconnect, }, ) as typeof fetch; const result = await convertHtmlToMarkdown( "Local Title", "https://example.com/post", ); expect(fetchCalls).toBe(0); expect(result.conversionMethod).not.toBe("defuddle-api"); }); test("uses defuddle.md markdown when local extraction is empty", async () => { const fetchCalls: Array<{ input: RequestInfo | URL; init?: RequestInit }> = []; globalThis.fetch = Object.assign( async (input: RequestInfo | URL, init?: RequestInit) => { fetchCalls.push({ input, init }); return new Response(`--- title: "Remote Title" --- # Remote Title Remote body. `, { headers: { "content-type": "text/markdown", }, }); }, { preconnect: originalFetch.preconnect, }, ) as typeof fetch; const result = await convertHtmlToMarkdown( "Local Title", "https://example.com/post", { enableRemoteMarkdownFallback: true }, ); expect(fetchCalls).toHaveLength(1); expect(String(fetchCalls[0]?.input)).toBe( "https://defuddle.md/https%3A%2F%2Fexample.com%2Fpost", ); expect(fetchCalls[0]?.init?.headers).toEqual({ accept: "text/markdown,text/plain;q=0.9,*/*;q=0.1", }); expect(result.conversionMethod).toBe("defuddle-api"); expect(result.metadata.title).toBe("Remote Title"); expect(result.markdown).toBe("# Remote Title\n\nRemote body."); expect(result.fallbackReason).toContain("defuddle.md"); }); });