const fs = require('fs');
const path = require('path');
const JSZip = require('jszip');
const DocxFontEmbedder = require('../src/main/DocxFontEmbedder');
describe('DocxFontEmbedder.embed', () => {
const dir = path.join(__dirname, 'fixtures-docx');
const docxPath = path.join(dir, 'in.docx');
const fontPath = path.join(dir, 'fake.ttf');
beforeAll(async () => {
fs.mkdirSync(dir, { recursive: true });
fs.writeFileSync(fontPath, 'fake-ttf-data');
const zip = new JSZip();
zip.file('[Content_Types].xml', '');
zip.file('_rels/.rels', '');
zip.file('word/document.xml', '');
zip.file('word/styles.xml', '');
fs.writeFileSync(docxPath, await zip.generateAsync({ type: 'nodebuffer' }));
});
afterAll(() => fs.rmSync(dir, { recursive: true, force: true }));
test('embeds TTF and patches fontTable.xml + styles.xml', async () => {
const out = await DocxFontEmbedder.embed(docxPath, [
{ path: fontPath, family: 'JetBrains Mono', weight: 400 },
]);
const zip = await JSZip.loadAsync(fs.readFileSync(out));
expect(Object.keys(zip.files).some((f) => f.startsWith('word/fonts/'))).toBe(true);
const fontTable = zip.file('word/fontTable.xml') ? await zip.file('word/fontTable.xml').async('string') : '';
expect(fontTable).toContain('JetBrains Mono');
expect(fontTable).toMatch(/]*w:ascii="JetBrains Mono"/);
});
test('is idempotent: running twice does not double-embed', async () => {
const once = await DocxFontEmbedder.embed(docxPath, [{ path: fontPath, family: 'JetBrains Mono', weight: 400 }]);
const twice = await DocxFontEmbedder.embed(once, [{ path: fontPath, family: 'JetBrains Mono', weight: 400 }]);
const zip = await JSZip.loadAsync(fs.readFileSync(twice));
const fontEntries = Object.keys(zip.files).filter((f) => /^word\/fonts\/[^/]+\.ttf$/.test(f));
expect(fontEntries.length).toBe(1);
});
});