import test from 'node:test' import assert from 'node:assert/strict' import { readFileSync, readdirSync } from 'node:fs' // Die React-Teile der Hustler-Seite sind unter Node nicht ladbar (JSX, Canvas, Router): geprüft wird der Quelltext // (Muster adminRoute.test.mjs). Pfade relativ zu src/components/workers/. const read = (p) => readFileSync(new URL('../../src/components/workers/' + p, import.meta.url), 'utf8') test('WorkerCard: Links nur über safeLink, extern mit rel noopener; deutsche Beschriftungen (Review Focus 5)', () => { const src = read('WorkerCard.jsx') assert.match(src, /safeLink\(/); assert.match(src, /rel="noopener noreferrer"/); assert.match(src, /target="_blank"/) for (const t of ['Macht gerade', 'Tokens heute', 'Kosten heute', 'Letzte Aktionen']) assert.ok(src.includes(t), t) assert.match(src, /MODEL_IDS/); assert.match(src, /wk-chip-/) // jeder href und jedes to kommt aus dem safeLink-Ergebnis, nie aus dem Ereignis selbst assert.match(src, /href=\{safe\.href\}/); assert.match(src, /to=\{safe\.href\}/) assert.doesNotMatch(src, /\b(?:href|to)=\{(?!safe\.href\})/) }) test('kein innerHTML in Komponenten und Engine', () => { for (const dir of ['', 'engine/']) for (const f of readdirSync(new URL('../../src/components/workers/' + dir, import.meta.url))) { if (!/\.(jsx|js)$/.test(f)) continue; const s = read(dir + f); assert.doesNotMatch(s, /dangerouslySetInnerHTML|innerHTML/, dir + f) } }) test('WorkersKpis nutzt Stat und kpiTiles; WorkerList: Knopf je Worker mit data-wk-worker, aria-pressed und Statustext', () => { assert.match(read('WorkersKpis.jsx'), /kpiTiles\(/); assert.match(read('WorkersKpis.jsx'), /]|]|href=/) })