Files
websitedev/scripts/test-content-editor-guide.js
T
Do Siki 1d3abc8cba
CI Pipeline with Test Management / 🧪 Run Tests & Generate Reports (push) Waiting to run
CI Pipeline with Test Management / 🐳 Docker Integration Tests (push) Blocked by required conditions
CI Pipeline with Test Management / 🏗️ Build Docker Image (push) Blocked by required conditions
CI Pipeline with Test Management / 📊 Generate Test Summary (push) Blocked by required conditions
Test Reporting & Gherkin Analysis / 🧪 Run Tests & Generate Reports (push) Waiting to run
Test Reporting & Gherkin Analysis / 📊 Analyze Test Coverage (push) Blocked by required conditions
Test Reporting & Gherkin Analysis / 🔄 Sync with Linear (push) Blocked by required conditions
Test Reporting & Gherkin Analysis / ⚡ Performance Monitoring (push) Blocked by required conditions
feat(cms): add maintained user guide with Súgó menu entry
- docs/felhasznaloi-utmutato.md: user guide for the website and the CMS
  (login, editing, arrays, save/validation, publish, security)
- /guide endpoint renders the markdown auth-protected via a dependency-free
  renderer (scripts/markdown-render.js) in the CMS dark theme
- new  Súgó entry in the CMS bottom bar
- steering rule: the guide must be updated in the same commit as any CMS or
  website feature change

Closes MITHOME-57
2026-08-18 13:20:44 +02:00

114 lines
3.8 KiB
JavaScript

#!/usr/bin/env node
/**
* Tests for the CMS user guide:
* 1. markdown renderer unit checks (headings, bold, code, lists, links, escaping)
* 2. /guide endpoint integration — auth-protected, serves the rendered guide
* 3. the main editor page contains the Súgó menu link
*/
const assert = require('assert/strict');
const fs = require('fs');
const os = require('os');
const path = require('path');
const { spawn } = require('child_process');
const { renderMarkdown } = require('../scripts/markdown-render');
// ── 1. Markdown renderer ─────────────────────────────────────────────────────
const rendered = renderMarkdown([
'# Cím',
'',
'Ez **félkövér** és `kód`, valamint [link](https://example.com).',
'',
'- első',
'- második',
'',
'1. lépés',
'2. lépés',
'',
'---',
'',
'<script>alert(1)</script>',
].join('\n'));
assert.match(rendered, /<h1>Cím<\/h1>/);
assert.match(rendered, /<strong>félkövér<\/strong>/);
assert.match(rendered, /<code>kód<\/code>/);
assert.match(rendered, /<a href="https:\/\/example\.com"[^>]*>link<\/a>/);
assert.match(rendered, /<ul>\s*<li>első<\/li>\s*<li>második<\/li>\s*<\/ul>/);
assert.match(rendered, /<ol>\s*<li>lépés<\/li>\s*<li>lépés<\/li>\s*<\/ol>/);
assert.match(rendered, /<hr>/);
// Raw HTML must be escaped, never executable
assert.doesNotMatch(rendered, /<script>alert/);
assert.match(rendered, /&lt;script&gt;/);
console.log('Markdown renderer unit tests: OK');
// ── 2. /guide endpoint + Súgó menu link (real server) ───────────────────────
const PORT = 4124;
const BASE = `http://127.0.0.1:${PORT}`;
const ROOT = path.join(__dirname, '..');
const AUDIT_FILE = path.join(os.tmpdir(), `content-editor-audit-guide-${process.pid}.jsonl`);
const child = spawn('node', ['content-editor.js'], {
cwd: ROOT,
env: {
...process.env,
CONTENT_EDITOR_PORT: String(PORT),
CONTENT_EDITOR_AUDIT_FILE: AUDIT_FILE,
CMS_USER: 'guide-test-user',
CMS_PASS: 'guide-test-pass',
CMS_DEPLOY_ENV: 'staging',
},
stdio: 'ignore',
});
async function waitForServer(timeoutMs = 10000) {
const deadline = Date.now() + timeoutMs;
while (Date.now() < deadline) {
try {
await fetch(`${BASE}/logout`); // rate-limit-free readiness probe
return;
} catch {
await new Promise(r => setTimeout(r, 200));
}
}
throw new Error('server did not start');
}
async function main() {
await waitForServer();
const auth = 'Basic ' + Buffer.from('guide-test-user:guide-test-pass').toString('base64');
// /guide requires authentication
const unauth = await fetch(`${BASE}/guide`);
assert.equal(unauth.status, 401);
// /guide serves the rendered markdown as HTML
const guide = await fetch(`${BASE}/guide`, { headers: { Authorization: auth } });
assert.equal(guide.status, 200);
assert.match(guide.headers.get('content-type') || '', /text\/html/);
const guideHtml = await guide.text();
assert.match(guideHtml, /Felhasználói útmutató/);
assert.match(guideHtml, /<h2[^>]*>.*Content Editor/); // rendered from the markdown source
// The guide file must exist in the repo (maintenance contract)
assert.ok(fs.existsSync(path.join(ROOT, 'docs', 'felhasznaloi-utmutato.md')));
// The editor page exposes the Súgó menu entry
const editor = await fetch(`${BASE}/`, { headers: { Authorization: auth } });
const editorHtml = await editor.text();
assert.match(editorHtml, /href="\/guide"[^>]*>❓ Súgó/);
console.log('Content Editor guide endpoint test: OK');
}
main()
.catch(err => { console.error('❌', err.message); process.exitCode = 1; })
.finally(() => {
child.kill('SIGTERM');
try { fs.unlinkSync(AUDIT_FILE); } catch { /* already gone */ }
});