const { test } = require('node:test'); const assert = require('node:assert/strict'); const fs = require('node:fs'); const path = require('node:path'); const vm = require('node:vm'); const { JSDOM } = require('jsdom'); function loadAdminDocsHarness() { const dom = new JSDOM(`
`, { url: 'https://app.example.test/' }); const source = fs.readFileSync(path.join(__dirname, '..', 'public/js/admin-docs.js'), 'utf8'); const context = vm.createContext({ window: dom.window, document: dom.window.document, console: { log() {}, warn() {}, error() {} }, URL: dom.window.URL, history: dom.window.history, requestAnimationFrame: function(fn) { fn(); }, setTimeout: function(fn) { fn(); return 0; }, fetch: function() { throw new Error('fetch not expected'); }, getAuthHeaders: function() { return {}; } }); vm.runInContext(source + '\nwindow.__adminDocsTest = { prepareDocAnchors, prepareDocLinks, scrollReaderToHash, handleDocAnchorClick };', context); return { dom, api: dom.window.__adminDocsTest }; } test('admin docs TOC links keep href and scroll the internal reader', () => { const { dom, api } = loadAdminDocsHarness(); const document = dom.window.document; const body = document.getElementById('docs-reader-body'); const reader = document.getElementById('docs-reader'); body.innerHTML = '

Admin - Configuration

'; api.prepareDocAnchors(body); api.prepareDocLinks(body); const link = body.querySelector('a'); const target = document.getElementById('admin---configuration'); assert.equal(link.getAttribute('href'), '#admin---configuration'); assert.equal(link.dataset.docHash, '#admin---configuration'); assert.ok(target, 'heading should get a stable GitHub-style id'); reader.getBoundingClientRect = function() { return { top: 10 }; }; target.getBoundingClientRect = function() { return { top: 110 }; }; const handled = api.handleDocAnchorClick({ target: link, preventDefault() {} }); assert.equal(handled, true); assert.equal(reader.scrollTop, 92); assert.equal(dom.window.location.hash, '#admin---configuration'); }); test('admin docs rewrites relative markdown hash links as in-app doc links', () => { const { dom, api } = loadAdminDocsHarness(); const body = dom.window.document.getElementById('docs-reader-body'); body.innerHTML = 'Architecture'; api.prepareDocLinks(body); const link = body.querySelector('a'); assert.equal(link.getAttribute('href'), 'logic/architecture.md#runtime-architecture'); assert.equal(link.dataset.docFile, 'logic/architecture.md'); assert.equal(link.dataset.docHash, '#runtime-architecture'); });