import assert from 'node:assert/strict'; import fs from 'node:fs/promises'; import os from 'node:os'; import path from 'node:path'; import test from 'node:test'; import { createPageService, pageInternals, normalizeWorkspaceRelativePath } from './mindspace-pages.mjs'; import { PUBLISH_ROOT_DIR } from './user-publish.mjs'; test('parseJsonColumn accepts mysql json objects and strings', () => { const objectValue = { relative_path: 'public/demo.html', auto_synced: true }; assert.deepEqual(pageInternals.parseJsonColumn(objectValue), objectValue); assert.deepEqual( pageInternals.parseJsonColumn(JSON.stringify(objectValue)), objectValue, ); assert.deepEqual(pageInternals.parseJsonColumn(null, { ok: true }), { ok: true }); }); test('normalizePageInput trims values and constrains templates', () => { const result = pageInternals.normalizePageInput({ title: ' 页面标题 ', content: ' 页面正文 ', templateId: 'unknown-template', }); assert.equal(result.title, '页面标题'); assert.equal(result.content, '页面正文'); assert.equal(result.templateId, 'editorial'); assert.equal(result.contentBytes, Buffer.byteLength('页面正文')); }); test('normalizePageInput rejects empty and oversized page content', () => { assert.throws( () => pageInternals.normalizePageInput({ title: '', content: '正文' }), { code: 'invalid_page_input' }, ); assert.throws( () => pageInternals.normalizePageInput({ title: '页面', content: '文'.repeat(400_000), }), { code: 'page_content_too_large' }, ); }); test('normalizePageInput maps html content to static-html template', () => { const result = pageInternals.normalizePageInput({ title: '页面', content: '
Hi', contentFormat: 'html', }); assert.equal(result.contentFormat, 'html'); assert.equal(result.templateId, 'static-html'); assert.equal(result.pageType, 'html'); }); test('renderHtmlPreview injects restrictive CSP', () => { const html = pageInternals.renderHtmlPreview( '