git diff origin/develop -- reducers/authentication.test.jse67067aa7) zeigen auf den Fork MaurerAnton/projectforge (Branch draft43npm). Links auf alten Code (SHA 9ed5fbe0f) — auf das Haupt-Repository micromata/projectforge (develop).
unknown action → unknown action returns current state. Explizite Beschreibung: »Reducer kennt diese Action nicht → gibt aktuellen State unverändert zurück«. Der alte Test sagte nicht, was genau geprüft wird.
Änderung des Eingabe-States: alter Test prüfte { loading: true, loggedIn: false }, neuer — { loading: false, user: { name: 'test' } }. Eingeloggter Benutzer-State gewählt, um zu prüfen, dass user bei unbekannter Action nicht genullt wird — Garantie der Pure Function [Redux reducers].
Formatierung: alter Aufruf auf 3 Zeilen verteilt, neuer — eine Zeile. Nur Stil.
Object.freeze(state) [MDN] — Mutationsschutz: falls der Reducer den übergebenen State verändert (verletzt Reinheit), der Test mit Fehler fehlschlägt.
describe('handles USER_LOGIN_BEGIN') → describe('USER_LOGIN_BEGIN'). Wort handles entfernt — im neuen Stil heißen alle describe wie die Action. [neue Datei]⚡
2 von 3 Tests gelöscht.
«fresh state» — prüfte Übergang von { loading: false, error: null, ... } → { loading: true, error: null, ... }. [Zeile 34]
«error state» — prüfte Übergang von { loading: false, error: exampleError, ... } → { loading: true, error: null, ... }. [Zeile 53]
Beide Tests prüfen dasselbe: error wird genullt, loading wird true. Unterschied — der ursprüngliche error (null vs String). Redundant — ein Test deckt beide Fälle ab.
«loggedIn state» — Eingabe: { loading: false, error: null, loggedIn: false } — identisch mit »fresh state«. Möglicherweise ein Tippfehler (hätte loggedIn: true sein sollen). [Zeile 72]
Ein neuer Test: 'resets to loading with null user' [neue Datei]⚡
{ loading: false, error: 'some error', user: { name: 'old' } }{ loading: true, error: null, user: null }user genullt wird (strenger als loggedIn: false — vollständiger Reset)error wird genullt, loading wird true — wie in den alten TestsloggedIn: false durch user: null — entscheidender Unterschied im State ShapeAlter Test «loading state» — OHNE PAYLOAD.
Rief { type: 'USER_LOGIN_SUCCESS' } ohne drittes Argument (Payload) auf. Der alte Reducer setzte angeblich nur loggedIn: true und loading: false — Benutzerdaten wurden nicht gespeichert.
»weird state« gelöscht: { loading: false, error: exampleError, loggedIn: true } — sinnlose Kombination: error vorhanden bei loggedIn = true. [Zeile 115]
Neuer Test — mit echtem Payload:
Warum genau diese Felder: der Reducer in authentication.js:18-27 erwartet vier Payload-Felder — jedes wird direkt in den State geschrieben:
| Payload-Feld | → State-Feld | Zeile | Zweck |
|---|---|---|---|
payload.user | → state.user | L23 | Benutzerobjekt (Name, Admin?) |
payload.version | → state.version | L24 | Build-Version |
payload.buildTimestamp | → state.buildTimestamp | L25 | Build-Zeitpunkt |
payload.alertMessage | → state.alertMessage | L26 | Systemmeldung (MOTD) |
Der alte Test übergab überhaupt keinen Payload — prüfte also keines dieser Felder. Der neue Test prüft vollständige Übereinstimmung.
loggedIn: true → user: { name: 'testuser' }. Komponenten prüfen state.user !== null statt state.loggedIn === true — Teil der Migration auf react-redux hooks.
Ähnliche Änderungen: handles USER_LOGIN_FAILURE → USER_LOGIN_FAILURE, »weird state« gelöscht, ein Test statt zwei.
Neue Beschreibung: 'sets error and clears user/loading' — sagt explizit, was passiert: Fehler wird gespeichert, Benutzer wird zurückgesetzt, Spinner verschwindet.
loggedIn: false → user: null. Feld user wird bei Fehler null. Das ist strenger als loggedIn: false — der alte Ansatz ließ Benutzerdaten im State (markierte nur als nicht eingeloggt), der neue löscht vollständig. Entspricht case USER_LOGIN_FAILURE: user: null.
Payload-Formatierung: { error: exampleError } in einer Zeile statt drei. Nur Stil.
Komplett gelöscht (2 Tests, ~40 Zeilen).
Prüfte, dass USER_LOGOUT setzt zurück { loggedIn: true } b { loggedIn: false } und nullt den Fehler.
Warum gelöscht:
USER_LOGOUT existiert nicht mehr — wird nicht exportiert aus authentication.js (importiert nur USER_LOGIN_BEGIN, USER_LOGIN_FAILURE, USER_LOGIN_SUCCESS).USER_LOGOUT fehlt im Reducer-Switch [nur 3 case].USER_LOGIN_BEGIN abgedeckt — beide setzen den State zurück.USER_LOGOUT aus einem nicht existierenden Export — der Test war defekt.Historisch: USER_LOGOUT wurde aus dem Quellcode entfernt commit 7c60c2fbb (2019-07-13, «implemented logout check») — aus actions/authentication.js und aus dem Reducer. Aber der Test wurde nicht aktualisiert — er importierte und testete USER_LOGOUT noch 7 Jahre lang. Im neuen Reducer ist Logout einfach USER_LOGIN_BEGIN (Reset auf loading).
(state, action) → new State. Keine Side Effects, keine Mutationen. Object.freeze(state) im Test garantiert dies: mutiert der Reducer versehentlich den übergebenen State, schlägt der Test fehl. [Redux docs]{ loading, error, loggedIn }. Neu: { loading, error, user }. loggedIn: boolean sagte nur »ja/nein«. user: object|null liefert das vollständige Benutzerobjekt (id, name, locale, ...) — Komponenten erhalten über useSelector(state => state.authentication.user) alle Daten auf einmal.Object.freeze(state); reducer(state, action); — versucht der Reducer den State zu mutieren (statt ein neues Objekt zu erstellen), wirft JavaScript im Strict Mode einen Fehler. Dies prüft die Reinheit der Funktion. [MDN]| Aspekt | Alte Datei (216 Zeilen) | Neue Datei (98 Zeilen) |
|---|---|---|
| State Shape | { loading, error, loggedIn } |
{ loading, error, user } |
| Initial state | Im Test eingebettet, loading: false |
Konstante, identisch mit Reducer, loading: true |
| Anzahl describe | 5 (mit Präfix handles) |
3 (ohne Präfix) |
| Anzahl Tests | 9 | 4 |
| USER_LOGIN_BEGIN | 3 Tests (fresh, error, loggedIn — Duplikate) | 1 Test (resets to loading) |
| USER_LOGIN_SUCCESS | 2 Tests — ohne Payload | 1 Test — mit Payload (user, version usw.) |
| USER_LOGIN_FAILURE | 2 Tests (loading, weird) | 1 Test (sets error) |
| USER_LOGOUT | 2 Tests | Komplett gelöscht — Action existiert nicht |
| Beschreibung von unknown action | 'unknown action' — unklar |
'unknown action returns current state' — klar |
USER_LOGIN_BEGIN abgedeckt (beide setzen den State zurück). Action existiert nicht im Reducer.user, version, buildTimestamp, alertMessage), der neue prüft alle Felder.loggedIn: boolean ersetzt durch user: object|null als Teil der Migration connect() → useSelector [react-redux hooks].⚡ — Link auf Code im Branch draft43npm im Fork, nicht in develop gemergt. Code möglicherweise bis zum PR-Merge nicht auf GitHub verfügbar.
1.
initialStateals Konstante extrahiert.Vorher: Objekt war im Test
it('initial state')als{ loading: false, error: null, loggedIn: false }hartcodiert.Neu: Konstante
initialState, die zudem mitinitialStateaus dem Reducer selbst übereinstimmt [reducers/authentication.js:3].2.
loading: false→loading: true.Alter Init:
loading: false— Benutzer nicht eingeloggt, kein Spinner.Neuer Init:
loading: true— beim App-Start wird sofortloadUserStatus()ausgeführt, das die Session prüft. Startzustand — »Benutzer wird gesucht«. Diese Änderung des Reducers in commit 8b3b44be7 (2020-03-18).3.
loggedIn: false→user: null. HAUPTÄNDERUNG DES STATE SHAPE.{ loading: boolean, error: string|null, loggedIn: boolean }
{ loading: boolean, error: string|null, user: object|null }
loggedIn: truenach Login → jetztuser: { name: 'test', ... }loggedIn: falsevor Login → jetztuser: nulluser !== nullstattloggedIn === trueconnect()→useSelector[react-redux hooks]