From bb31c6f5157fd9e359a688b4784ec32efde55e4e Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 9 May 2026 01:33:06 +0200 Subject: [PATCH] test docs toc links --- test/admin-docs-toc.test.js | 67 +++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 test/admin-docs-toc.test.js diff --git a/test/admin-docs-toc.test.js b/test/admin-docs-toc.test.js new file mode 100644 index 0000000..601b3a8 --- /dev/null +++ b/test/admin-docs-toc.test.js @@ -0,0 +1,67 @@ +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'); +});