import { test, expect, vi } from 'vitest'; import { Packer } from 'docx'; import { buildImportTemplateDocument, TEMPLATE_ROWS } from './importTemplate.js'; import { parseEpisodeListDocx, parseEpisodePassage } from './importParsers.js'; // Real uploads run in the browser, where mammoth takes an ArrayBuffer; its Node build takes a // Buffer. Adapt so the same importer code can run here. vi.mock('mammoth', async () => { const real = await vi.importActual('mammoth'); const convertToHtml = ({ arrayBuffer }) => real.convertToHtml({ buffer: Buffer.from(arrayBuffer) }); return { default: { convertToHtml } }; }); // Runs the generated file through the same importer real uploads go through. async function importTemplate() { const buf = await Packer.toBuffer(buildImportTemplateDocument()); const arrayBuffer = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); return parseEpisodeListDocx({ arrayBuffer: async () => arrayBuffer }); } test('the template imports back as exactly its example rows (header and instructions are ignored)', async () => { const sessions = await importTemplate(); expect(sessions.map((s) => [s.episodeNumber, s.title, s.passage])).toEqual(TEMPLATE_ROWS); }); test('every example passage is one the importer understands', async () => { const sessions = await importTemplate(); const parsed = sessions.map((s) => parseEpisodePassage(s.passage)); expect(parsed).not.toContain('invalid'); expect(parsed[0]).toEqual({ startChapter: 1, startVerse: 1, endChapter: 1, endVerse: 4 }); expect(parsed[3]).toBeNull(); // the "—" row has no passage expect(parsed[5]).toEqual({ startChapter: 2, startVerse: 11, endChapter: 3, endVerse: 2 }); // crosses a chapter }); test('the sessions are numbered in order with no gaps', () => { expect(TEMPLATE_ROWS.map((r) => r[0])).toEqual(['1', '2', '3', '4', '5', '6']); });