import { describe, it, expect } from 'vitest'; import { buildPublicationAsciiDoc, renderPublication, renderPublicationFromEvents, renderEvent, toPublicationIndexLike, } from './publication-helper.js'; const index = { kind: 30040 as const, title: 'My Book', d: 'my-book-v1', a: ['30041:abc:ch1', '30041:abc:ch2'], type: 'book', }; const sections = [ { address: '30041:abc:ch1', title: 'Chapter One', content: 'First chapter body.' }, { address: '30041:abc:ch2', title: 'Chapter Two', content: 'Second chapter body.' }, ]; describe('buildPublicationAsciiDoc', () => { it('builds combined AsciiDoc from index and sections', () => { const adoc = buildPublicationAsciiDoc({ index, sections }); expect(adoc).toContain('= My Book'); expect(adoc).toContain('== Chapter One'); expect(adoc).toContain('First chapter body.'); expect(adoc).toContain('== Chapter Two'); expect(adoc).toContain('Second chapter body.'); }); it('throws if kind is not 30040', () => { expect(() => buildPublicationAsciiDoc({ index: { ...index, kind: 1 as 30040 }, sections, }) ).toThrow('Expected kind 30040'); }); }); describe('renderPublication', () => { it('returns asciidoc, html, and tableOfContents', () => { const out = renderPublication({ index, sections }); expect(out.asciidoc).toContain('= My Book'); expect(out.html).toContain('My Book'); expect(out.html).toContain('Chapter One'); expect(out.html).toContain('First chapter body.'); expect(typeof out.tableOfContents).toBe('string'); }); it('can disable toc', () => { const out = renderPublication({ index, sections }, { toc: false }); expect(out.tableOfContents).toBe(''); }); }); describe('toPublicationIndexLike', () => { it('parses event-like payload with kind 30040 and title', () => { const payload = { kind: 30040, tags: [ ['title', 'Test Pub'], ['d', 'test-d'], ['a', '30041:pk1:d1'], ['a', '30041:pk1:d2'], ['type', 'blog'], ['image', 'https://example.com/cover.png'], ], }; const parsed = toPublicationIndexLike(payload); expect(parsed).not.toBeNull(); expect(parsed!.kind).toBe(30040); expect(parsed!.title).toBe('Test Pub'); expect(parsed!.d).toBe('test-d'); expect(parsed!.a).toEqual(['30041:pk1:d1', '30041:pk1:d2']); expect(parsed!.type).toBe('blog'); expect(parsed!.image).toBe('https://example.com/cover.png'); }); it('returns null for wrong kind', () => { expect(toPublicationIndexLike({ kind: 1, tags: [['title', 'X']] })).toBeNull(); }); it('returns null when title is missing', () => { expect(toPublicationIndexLike({ kind: 30040, tags: [['d', 'x']] })).toBeNull(); }); }); describe('renderEvent', () => { it('accepts event JSON and returns HTML', () => { const event = { kind: 30041, content: '= One section\n\nSome *bold* text.', tags: [['title', 'One section']], pubkey: 'abc', }; const html = renderEvent(event); expect(html).toContain('