Workers P3: Nachträge aus der P2-Endprüfung (Kennungen, JWT-Sperre, Abmelden, Bestätigung)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c6c022678f
commit
777d5272bf
6 files changed
+279
-19
No files matched your search
@@ -82,3 +82,47 @@ test('Karte und Board: Auswahl setzt den Fokus auf den Namen und holt die Karte
|
||||
assert.match(board, /onClose=\{closeCard\}/); assert.match(board, /data-wk-worker/); assert.match(board, /button\.focus\(\)/)
|
||||
assert.doesNotMatch(board, /onClose=\{\(\) => setSelectedId\(null\)\}/)
|
||||
})
|
||||
|
||||
// ---- P3-T21: Abmelden setzt das JWT zurück, „Alles anhalten“ fragt vorher nach ----
|
||||
|
||||
const readSrc = (p) => readFileSync(new URL('../../src/' + p, import.meta.url), 'utf8')
|
||||
|
||||
test('Abmelden: AuthContext ruft resetWorkersJwt() auf, workersClient setzt JWT-Cache und Sperre zurück (P3-T21)', () => {
|
||||
const auth = readSrc('context/AuthContext.jsx')
|
||||
assert.match(auth, /import \{ resetWorkersJwt \} from '\.\.\/lib\/workersClient'/)
|
||||
const start = auth.indexOf('async function logout()')
|
||||
assert.ok(start > 0)
|
||||
const logout = auth.slice(start, auth.indexOf('const isAdmin', start))
|
||||
assert.match(logout, /resetWorkersJwt\(\)/)
|
||||
// im finally: auch ein fehlgeschlagenes deleteSessions lässt das JWT des alten Nutzers nicht im Cache
|
||||
assert.ok(logout.indexOf('finally') > 0 && logout.indexOf('resetWorkersJwt()') > logout.indexOf('finally'))
|
||||
const client = readSrc('lib/workersClient.js')
|
||||
assert.match(client, /export function resetWorkersJwt\(\)/)
|
||||
const fn = client.slice(client.indexOf('export function resetWorkersJwt()'))
|
||||
assert.match(fn, /jwtCache\.invalidate\(\)/); assert.match(fn, /workersApi\.resetAuth\(\)/)
|
||||
})
|
||||
|
||||
test('WorkersBoard: „Alles anhalten“ öffnet erst einen Bestätigungsdialog, „Fortsetzen“ geht sofort (P3-T21)', () => {
|
||||
const s = read('WorkersBoard.jsx')
|
||||
assert.match(s, /import Dialog from '\.\.\/ui\/Dialog'/)
|
||||
assert.match(s, /<Dialog\b[^>]*title="Alles anhalten\?"/)
|
||||
assert.ok(s.includes('Die Worker hören sofort auf, bis jemand fortsetzt.'))
|
||||
// beide Knöpfe des Dialogs: type="button", Beschriftung „Anhalten“ und „Abbrechen“
|
||||
assert.match(s, /<Button type="button" onClick=\{[^}]*\}[^>]*>Abbrechen<\/Button>/)
|
||||
assert.match(s, /<Button variant="primary" type="button" onClick=\{confirmHalt\}[^>]*>Anhalten<\/Button>/)
|
||||
// Der Knopf der Leiste fragt nur beim Anhalten nach; Fortsetzen ruft den Dienst ohne Dialog
|
||||
assert.match(s, /<Button type="button" onClick=\{requestPause\}/)
|
||||
assert.match(s, /const requestPause = \(\) => \{\s*if \(paused\) setPause\(false\)\s*else setConfirmOpen\(true\)\s*\}/)
|
||||
// Bestätigen schließt den Dialog und hält an; der Zielwert steht fest (nicht !paused: sonst setzte ein veralteter Dialog die Arbeit wieder fort)
|
||||
assert.match(s, /const confirmHalt = \(\) => \{\s*setConfirmOpen\(false\)\s*setPause\(true\)\s*\}/)
|
||||
assert.match(s, /api\.pause\(target\)/); assert.doesNotMatch(s, /api\.pause\(!paused\)/)
|
||||
// der Dialog steht nur offen, solange nicht schon angehalten ist (hat jemand anderes angehalten, entfällt die Frage)
|
||||
assert.match(s, /\{confirmOpen && !paused && \(/)
|
||||
// und die Frage taucht nach einem späteren Fortsetzen nicht von selbst wieder auf
|
||||
assert.match(s, /useEffect\(\(\) => \{\s*if \(haltedByState\) setConfirmOpen\(false\)\s*\}, \[haltedByState\]\)/)
|
||||
// Hooks vor der frühen Rückgabe
|
||||
assert.ok(s.indexOf('useState(false)') < s.indexOf('if (!loaded || !state)') && s.indexOf('const [confirmOpen') < s.indexOf('if (!loaded || !state)'))
|
||||
// PF-08 gilt weiter: jeder Knopf ein type="button"
|
||||
assert.equal((s.match(/<Button\b/g) || []).length, (s.match(/<Button\b[^>]*type="button"/g) || []).length)
|
||||
assert.doesNotMatch(s, /window\.confirm|confirm\(/)
|
||||
})
|
||||
Reference in new issue
Block a user