import test from 'node:test' import assert from 'node:assert/strict' import { readFileSync } from 'node:fs' // Die Seite und die Routen sind unter Node nicht ladbar (JSX, Router): geprüft wird der Quelltext (Muster workersComponents.test.mjs) test('App: /hustler lazy hinter ProtectedRoute, /leads und /workers leiten mit erhaltener Query auf /hustler um, kein statischer Import', () => { const s = readFileSync(new URL('../../src/App.jsx', import.meta.url), 'utf8') assert.match(s, /const WorkersPage = lazy\(\(\) => import\('\.\/pages\/WorkersPage'\)\)/); assert.doesNotMatch(s, /import WorkersPage from/) assert.match(s, /<\/Suspense><\/ProtectedRoute>\} \/>/) assert.match(s, /\} \/>/); assert.match(s, /\} \/>/) assert.match(s, /function HustlerRedirect\(\)[\s\S]*?useLocation\(\)[\s\S]*?/) // /workers?tab=botleads&bot=x → /hustler?tab=botleads&bot=x assert.ok(s.indexOf('path="/hustler"') < s.indexOf('path="*"')); assert.ok(s.indexOf('path="/workers"') < s.indexOf('path="*"')) }) test('WorkersPage: Titel Hustler (H1 und Tab-Titel), Reiter hochhaus und freigabe, Reiterleiste erst ab zwei Reitern, api-Instanz, Admin-Weitergabe', () => { const s = readFileSync(new URL('../../src/pages/WorkersPage.jsx', import.meta.url), 'utf8') assert.match(s, /title="Hustler"/); assert.match(s, /document\.title = 'Hustler'/) assert.match(s, /id: 'hochhaus'/); assert.match(s, /id: 'freigabe'/); assert.match(s, /WORKERS_TABS\.length > 1/) assert.match(s, /const api = workersApi/); assert.match(s, /pickTab\(/); assert.match(s, /isAdmin=\{isAdmin\}/) }) test('WorkersPage: Reiter botleads hinter freigabe zeigt die BotLeadList mit api, bot aus der Adresse und onClearBot, der den Reiter behält; ein Reiterwechsel lässt bot weg', () => { const s = readFileSync(new URL('../../src/pages/WorkersPage.jsx', import.meta.url), 'utf8') assert.match(s, /id: 'botleads', label: 'Bot-Leads'/); assert.ok(s.indexOf("id: 'freigabe'") < s.indexOf("id: 'botleads'")) assert.match(s, /import BotLeadList from '\.\.\/components\/workers\/BotLeadList'/); assert.match(s, /active\.id === 'botleads' && ]*api=\{api\}/) assert.match(s, /params\.get\('bot'\)/); assert.match(s, /]*\bbot=\{bot\}/); assert.match(s, /]*onClearBot=\{\(\) => setParams\(\{ tab: 'botleads' \}\)\}/) assert.match(s, /onChange=\{\(id\) => setParams\(\{ tab: id \}\)\}/) // setParams ersetzt alle Parameter: bot fällt beim Wechsel weg assert.doesNotMatch(s, /Später kommt botleads/) }) test('App: RouteErrorBoundary um die Routen im Inhaltsbereich (fehlender lazy-Chunk in altem Tab lässt nicht die ganze Oberfläche verschwinden), Pfad als resetKey', () => { const s = readFileSync(new URL('../../src/App.jsx', import.meta.url), 'utf8') assert.match(s, /import RouteErrorBoundary from '\.\/components\/RouteErrorBoundary'/) assert.match(s, /
<\/RouteErrorBoundary><\/main>/) // das Menü (Sidebar) steht außerhalb der Boundary und bleibt bei einem Fehler benutzbar assert.ok(s.indexOf('