#!/usr/bin/env node /** * Integration test for CMS deploy versioning (MITHOME-63): * 1. GET /version is public and reports the git SHA of the checked-out commit * 2. the editor page displays the same version in the bottom bar * 3. a startup audit entry records the version */ const assert = require('assert/strict'); const { execFileSync, spawn } = require('child_process'); const fs = require('fs'); const os = require('os'); const path = require('path'); const ROOT = path.join(__dirname, '..'); const PORT = 4129; const BASE = `http://127.0.0.1:${PORT}`; const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'cms-version-')); const auditFile = path.join(tmp, 'audit.jsonl'); const expectedVersion = execFileSync('git', ['-C', ROOT, 'rev-parse', '--short', 'HEAD'], { encoding: 'utf8' }).trim(); const child = spawn('node', ['content-editor.js'], { cwd: ROOT, env: { ...process.env, CONTENT_EDITOR_PORT: String(PORT), CONTENT_EDITOR_AUDIT_FILE: auditFile, CMS_USER: 'version-test-user', CMS_PASS: 'version-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}/version`); return; } catch { await new Promise(r => setTimeout(r, 200)); } } throw new Error('server did not start'); } async function main() { await waitForServer(); // 1. public /version const res = await fetch(`${BASE}/version`); assert.equal(res.status, 200); const body = await res.json(); assert.equal(body.version, expectedVersion); assert.equal(body.env, 'staging'); // 2. footer shows the same version const login = await fetch(`${BASE}/login`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ user: 'version-test-user', pass: 'version-test-pass' }), }); const cookie = (login.headers.get('set-cookie') || '').split(';')[0]; const page = await (await fetch(`${BASE}/`, { headers: { Cookie: cookie, Accept: 'text/html' } })).text(); assert.ok(page.includes(`v${expectedVersion}`), 'bottom bar must show the deploy version'); // 3. startup audit entry const audit = fs.readFileSync(auditFile, 'utf8').trim().split('\n').map(l => JSON.parse(l)); const startup = audit.find(e => e.event === 'startup'); assert.ok(startup, 'startup audit entry exists'); assert.equal(startup.version, expectedVersion); console.log('Content Editor deploy version test: OK'); } main() .catch(err => { console.error('❌', err.message); process.exitCode = 1; }) .finally(() => { child.kill('SIGTERM'); try { fs.rmSync(tmp, { recursive: true, force: true }); } catch { /* best effort */ } });