Kundenansicht neu P2: Passwort ändern als Etage

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-10-16 17:12:32 +00:00
1 parent d99c29b6c6
commit 861b74f70e
2 files changed
+156 -4

No files matched your search

+48
View File
@@ -0,0 +1,48 @@
import { test } from 'node:test'
import assert from 'node:assert/strict'
import { zeigePasswort, passwortProblem } from '../public/neu/ansicht-passwort.js'
import { mit, me, neueWurzel } from './support/knDaten.js'
test('passwortProblem: Texte wörtlich, Reihenfolge der Prüfungen', () => {
const p = passwortProblem
assert.deepEqual(p('', 'x', 'x', ''), ['pw-current', 'Bitte gib dein aktuelles Passwort ein.'])
assert.deepEqual(p('a', '', '', ''), ['pw-new', 'Bitte gib ein neues Passwort ein.'])
assert.deepEqual(p('a', 'kurz', 'kurz', ''), ['pw-new', 'Das neue Passwort muss mindestens 8 Zeichen haben.'])
assert.deepEqual(p('a', ' ', ' ', ''), ['pw-new', 'Das neue Passwort darf nicht nur aus Leerzeichen bestehen.'])
assert.deepEqual(p('abcdefgh', 'abcdefgh', 'abcdefgh', ''), ['pw-new', 'Das neue Passwort muss sich vom aktuellen unterscheiden.'])
assert.deepEqual(p('a', 'Anna@Example.com', 'Anna@Example.com', 'anna@example.com'), ['pw-new', 'Bitte nimm nicht deine E-Mail-Adresse als Passwort.'])
assert.deepEqual(p('a', 'neues-passwort', 'anderes-passwort', ''), ['pw-repeat', 'Die beiden neuen Passwörter stimmen nicht überein.'])
assert.equal(p('a', 'neues-passwort', 'neues-passwort', ''), null)
assert.deepEqual(p('a', 'x'.repeat(257), 'x'.repeat(257), ''), ['pw-new', 'Das neue Passwort ist zu lang (höchstens 256 Zeichen).'])
})
const felder = (fx, w) => ({ alt: fx.finde(w, 'input[name="current-password"]'), neu: fx.finde(w, 'input[name="new-password"]'), wdh: fx.finde(w, 'input[name="new-password-repeat"]') })
const zeigeNeu = async (fx, m = me(), nav = 'push') => { const w = neueWurzel(fx); await zeigePasswort(w, { route: { bereich: 'website', etage: 'passwort', query: '' }, me: m, nav }); return w }
test('Passwort ändern: Problem zeigt Text ohne Aufruf, Erfolg sendet und räumt auf, Fertig geht zurück', mit({ 'POST /api/auth/password': { success: true } }, async (fx) => {
let zurueck = 0; fx.window.history.back = () => { zurueck += 1 }
const w = await zeigeNeu(fx); const f = felder(fx, w); assert.equal(fx.finde(w, 'input[name="username"]').value, 'anna@example.com')
assert.equal(fx.finde(w, 'a[data-view="chat"]').textContent, 'Schreib uns im Chat')
await fx.klick(fx.finde(w, 'button[type="submit"]')); assert.match(fx.text(w), /Bitte gib dein aktuelles Passwort ein\./); assert.equal(fx.fetchLog.length, 0)
await fx.setze(f.alt, 'altes-passwort'); await fx.setze(f.neu, 'neues-passwort'); await fx.setze(f.wdh, 'neues-passwort'); await fx.klick(fx.finde(w, 'button[type="submit"]')); await fx.ruhe()
assert.deepEqual(fx.fetchLog.at(-1).body, { currentPassword: 'altes-passwort', newPassword: 'neues-passwort' }); assert.equal(f.neu.value, '')
assert.match(fx.text(w), /Dein Passwort wurde geändert\./); await fx.klick(fx.finde(w, (e) => e.textContent === 'Fertig')); assert.equal(zurueck, 1)
}))
test('Falsches Passwort fokussiert das Feld; Ansichtsmodus sperrt alles', mit({ 'POST /api/auth/password': () => ({ status: 400, body: { error: 'Das aktuelle Passwort stimmt nicht.', code: 'wrong_password' } }) }, async (fx) => {
const w = await zeigeNeu(fx); const f = felder(fx, w)
await fx.setze(f.alt, 'x'); await fx.setze(f.neu, 'neues-passwort'); await fx.setze(f.wdh, 'neues-passwort'); await fx.klick(fx.finde(w, 'button[type="submit"]')); await fx.ruhe()
assert.match(fx.text(w), /Das aktuelle Passwort stimmt nicht\./); assert.equal(fx.document.activeElement, f.alt)
const v = await zeigeNeu(fx, me({ viewAs: true })); assert.ok(fx.alle(v, 'input, button').every((e) => e.hasAttribute('disabled'))); assert.match(fx.text(v), /Im Ansichtsmodus kann das Passwort nicht geändert werden\./)
}))
test('Passwort: neues Passwort ungültig fokussiert das neue Feld, Anzeige-Schalter; im Ansichtsmodus kein Aufruf', mit({ 'POST /api/auth/password': () => ({ status: 400, body: { error: 'Zu schwach.', code: 'new_invalid' } }) }, async (fx) => {
const w = await zeigeNeu(fx, me(), 'tab'); const f = felder(fx, w)
await fx.setze(f.alt, 'x'); await fx.setze(f.neu, 'neues-passwort'); await fx.setze(f.wdh, 'neues-passwort'); await fx.klick(fx.finde(w, 'button[type="submit"]')); await fx.ruhe()
assert.match(fx.text(w), /Zu schwach\./); assert.equal(fx.document.activeElement, f.neu); assert.equal(fx.finde(w, 'button[type="submit"]').hasAttribute('disabled'), false)
await fx.klick(fx.finde(w, '#pw-show')); assert.deepEqual([f.alt.type, f.neu.type, f.wdh.type], ['text', 'text', 'text']); await fx.klick(fx.finde(w, '#pw-show')); assert.equal(f.neu.type, 'password')
const v = await zeigeNeu(fx, me({ viewAs: true })); const vf = felder(fx, v); const vorher = fx.fetchLog.length
await fx.setze(vf.alt, 'x'); await fx.klick(fx.finde(v, 'button[type="submit"]')); assert.equal(fx.fetchLog.length, vorher)
}))
test('Fertig ohne eigenen Verlaufseintrag (Einstieg per Link) geht zur Website', mit({ 'POST /api/auth/password': { success: true } }, async (fx) => {
fx.window.history.back = () => assert.fail('history.back darf hier nicht laufen')
const w = await zeigeNeu(fx, me(), 'tab'); const f = felder(fx, w)
await fx.setze(f.alt, 'altes-passwort'); await fx.setze(f.neu, 'neues-passwort'); await fx.setze(f.wdh, 'neues-passwort'); await fx.klick(fx.finde(w, 'button[type="submit"]')); await fx.ruhe()
await fx.klick(fx.finde(w, (e) => e.textContent === 'Fertig')); assert.equal(fx.window.location.hash, '#')
}))