Fix guide editor issues 4-10
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
'use strict';
|
||||
|
||||
const test = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
|
||||
const { normalizeStep } = require('../../core/schema');
|
||||
const { orderedBlocks, blockText } = require('../../core/blocks');
|
||||
|
||||
test('block normalization recovers legacy code fields and preserves order', () => {
|
||||
const step = normalizeStep({
|
||||
stepId: 'step-1',
|
||||
kind: 'content',
|
||||
title: 'Block test',
|
||||
textBlocks: [{ id: 'tb1', order: 2, position: 'after-description', level: 'info', title: 'Note', descriptionHtml: '<p>Text</p>' }],
|
||||
codeBlocks: [{ id: 'cb1', order: 1, language: 'bash', text: 'echo hi' }],
|
||||
tableBlocks: [{ id: 'tbl1', order: 3, rows: [['A', 'B'], ['1', '2']] }],
|
||||
});
|
||||
|
||||
assert.equal(step.codeBlocks[0].code, 'echo hi');
|
||||
assert.equal(blockText(step.codeBlocks[0]), 'echo hi');
|
||||
assert.deepEqual(orderedBlocks(step).map((block) => block.kind), ['code', 'text', 'table']);
|
||||
});
|
||||
@@ -237,6 +237,6 @@ test('a saved template changes exporter behavior through runExport', (t) => {
|
||||
const withTemplate = runExport('pdf', ast, path.join(root, 'out2'), tm.load('pdf', 'no-cover'));
|
||||
assert.ok(withTemplate.pageCount < withDefaults.pageCount, 'dropping cover+toc reduces pages');
|
||||
|
||||
assert.equal(Object.keys(EXPORTERS).length, 9, 'all nine formats wired');
|
||||
assert.equal(Object.keys(EXPORTERS).length, 10, 'all ten formats wired');
|
||||
assert.throws(() => runExport('exe', ast, path.join(root, 'out3')));
|
||||
});
|
||||
|
||||
@@ -9,6 +9,7 @@ const { buildRenderAst, renderStepImage } = require('../../core/renderast');
|
||||
const { exportJson } = require('../../exporters/json');
|
||||
const { exportMarkdown } = require('../../exporters/markdown');
|
||||
const { exportHtmlSimple, exportHtmlRich } = require('../../exporters/html');
|
||||
const { exportConfluence } = require('../../exporters/confluence');
|
||||
const { htmlToMarkdown } = require('../../exporters/htmlmd');
|
||||
const { decodePng } = require('../../core/png');
|
||||
const { buildFixtureGuide } = require('./fixture-guide');
|
||||
@@ -114,6 +115,31 @@ test('Markdown export: TOC anchors resolve, images exist, blocks rendered', (t)
|
||||
assert.equal(lines[warnIdx + 1], '> Admins only.');
|
||||
});
|
||||
|
||||
test('Confluence export writes storage-format XML and image attachments', (t) => {
|
||||
const root = makeTmpDir('expconf');
|
||||
t.after(() => rmrf(root));
|
||||
const { store, guide } = buildFixtureGuide(path.join(root, 'data'));
|
||||
const out = path.join(root, 'out');
|
||||
|
||||
const ast = buildRenderAst(store, guide.guideId);
|
||||
const { file, attachmentCount } = exportConfluence(ast, out);
|
||||
const xml = fs.readFileSync(file, 'utf8');
|
||||
|
||||
assert.equal(attachmentCount, 2);
|
||||
assert.ok(xml.includes('<ac:structured-macro ac:name="code">'));
|
||||
assert.ok(xml.includes('ri:attachment ri:filename='));
|
||||
assert.ok(xml.includes('0 2 * * * /usr/local/bin/acmesync --backup'));
|
||||
|
||||
const attachmentsDir = path.join(out, 'configure-acmesync-backups-attachments');
|
||||
const files = fs.readdirSync(attachmentsDir);
|
||||
assert.equal(files.length, 2);
|
||||
for (const name of files) {
|
||||
const img = decodePng(fs.readFileSync(path.join(attachmentsDir, name)));
|
||||
assert.equal(img.width, 320);
|
||||
assert.equal(img.height, 200);
|
||||
}
|
||||
});
|
||||
|
||||
test('Simple HTML export is self-contained with valid embedded images', (t) => {
|
||||
const root = makeTmpDir('exphtml');
|
||||
t.after(() => rmrf(root));
|
||||
|
||||
Reference in New Issue
Block a user