git diff origin/develop -- reducers/authentication.test.jse67067aa7) apuntan al fork MaurerAnton/projectforge (rama draft43npm). Los enlaces al código antiguo (SHA 9ed5fbe0f) apuntan al repositorio principal micromata/projectforge (develop).
unknown action → unknown action returns current state. Descripción explícita: «el reductor no reconoce esta acción → devuelve el estado actual sin cambios». El test antiguo no especificaba qué se estaba verificando exactamente.
Cambio en el estado de entrada: el test antiguo verificaba { loading: true, loggedIn: false }, el nuevo — { loading: false, user: { name: 'test' } }. Se ha elegido un estado con usuario logueado para comprobar que user no se establece en null ante una acción desconocida, garantizando así el comportamiento de función pura [Redux reducers].
Formato: la llamada antigua se dividía en 3 líneas, la nueva ocupa 1 sola línea. Se trata únicamente de estilo/codificación.
Object.freeze(state) [MDN] — protección contra mutaciones: si el reductor modifica accidentalmente el state recibido (violando el principio de pureza), el test fallará con un error.
describe('handles USER_LOGIN_BEGIN') → describe('USER_LOGIN_BEGIN'). Se ha eliminado la palabra handles — en el nuevo estilo todos los describe nombran la acción literalmente. [archivo nuevo]⚡
Eliminados 2 de 3 tests.
«fresh state» — verificaba la transición de { loading: false, error: null, ... } a { loading: true, error: null, ... }. [línea 34]
«error state» — verificaba la transición de { loading: false, error: exampleError, ... } a { loading: true, error: null, ... }. [línea 53]
Ambos tests verificaban lo mismo: error se establece a null, loading pasa a true. La única diferencia era el error inicial (null vs string). Es redundante, con un solo test se cubren ambos casos.
«loggedIn state» — entrada: { loading: false, error: null, loggedIn: false } — coincide completamente con «fresh state». Probablemente un error tipográfico (debería ser loggedIn: true). [línea 72]
Un nuevo test: 'resets to loading with null user' [archivo nuevo]⚡
{ loading: false, error: 'some error', user: { name: 'old' } }{ loading: true, error: null, user: null }user se establece a null (más estricto que loggedIn: false — limpieza completa)error se establece a null, loading pasa a true — igual que en los tests antiguosloggedIn: false por user: null es la diferencia clave en la estructura del estadoTest antiguo «loading state» — SIN PAYLOAD.
Llamaba a { type: 'USER_LOGIN_SUCCESS' } sin el tercer argumento (payload). El reductor antiguo supuestamente solo establecía loggedIn: true y loading: false — los datos del usuario no se conservaban.
Eliminado «weird state»: { loading: false, error: exampleError, loggedIn: true } — combinación sin sentido: hay error cuando loggedIn = true. [línea 115]
Nuevo test — con payload real:
Por qué exactamente estos campos: el reductor en authentication.js:18-27 espera un payload con cuatro campos — cada uno se escribe directamente en el estado:
| Campo payload | → campo estado | Línea | Propósito |
|---|---|---|---|
payload.user | → state.user | L23 | objeto de usuario (nombre, ¿es admin?...) |
payload.version | → state.version | L24 | versión de la build |
payload.buildTimestamp | → state.buildTimestamp | L25 | cuándo se compiló |
payload.alertMessage | → state.alertMessage | L26 | mensaje del sistema (MOTD) |
El test antiguo no pasaba payload en absoluto, por lo que no verificaba ninguno de estos campos. El nuevo test comprueba la correspondencia completa.
loggedIn: true → user: { name: 'testuser' }. Los componentes verifican state.user !== null en lugar de state.loggedIn === true — parte de la migración a react-redux hooks.
Cambios análogos: handles USER_LOGIN_FAILURE → USER_LOGIN_FAILURE, eliminado «weird state», un solo test en lugar de dos.
Nueva descripción: 'sets error and clears user/loading' — describe explícitamente lo que ocurre: se conserva el error, se reinicia el usuario, se detiene el spinner.
loggedIn: false → user: null. El campo user pasa a null en caso de error. Esto es más estricto que loggedIn: false — el enfoque antiguo dejaba los datos del usuario en el estado (solo marcaba que no estaba logueado), el nuevo los elimina por completo. Coincide con case USER_LOGIN_FAILURE: user: null.
Formato de payload: { error: exampleError } en una sola línea en lugar de tres. Solo es cuestión de estilo.
Eliminado por completo (2 tests, ~40 líneas).
Verificaba que USER_LOGOUT reseteaba { loggedIn: true } a { loggedIn: false } y establecía el error en null.
Por qué se eliminó:
USER_LOGOUT ya no existe — no se exporta desde authentication.js (solo se importan USER_LOGIN_BEGIN, USER_LOGIN_FAILURE, USER_LOGIN_SUCCESS).USER_LOGOUT no aparece en el switch del reductor [solo 3 case].USER_LOGIN_BEGIN — ambos reinician el estado.USER_LOGOUT de un export inexistente — el test estaba roto.Contexto histórico: USER_LOGOUT fue eliminado del código fuente en commit 7c60c2fbb (13/07/2019, «implemented logout check») — tanto en actions/authentication.js como en el reductor. Pero no se actualizó el test — siguió importando y probando USER_LOGOUT durante otros 7 años. En el nuevo enfoque, el logout se maneja simplemente con USER_LOGIN_BEGIN (reseteo a loading).
(state, action) → nuevo estado. Sin efectos secundarios, sin mutaciones. Object.freeze(state) en el test lo garantiza: si el reductor modifica accidentalmente el state recibido, el test fallará. [Redux docs]{ loading, error, loggedIn }. Nuevo: { loading, error, user }. loggedIn: boolean solo indicaba «sí/no». user: object|null proporciona el objeto completo del usuario (id, name, locale, ...) — los componentes obtienen todos los datos directamente mediante useSelector(state => state.authentication.user).Object.freeze(state); reducer(state, action); — si el reductor intenta modificar el estado (en lugar de crear uno nuevo), JavaScript lanzará un error en strict mode. Es una verificación de la pureza de la función. [MDN]| Aspecto | Archivo antiguo (216 líneas) | Archivo nuevo (98 líneas) |
|---|---|---|
| Estructura del estado | { loading, error, loggedIn } |
{ loading, error, user } |
| Estado inicial | Incrustado en el test, loading: false |
Constante, coincide con el reductor, loading: true |
| Cantidad de describe | 5 (con prefijo handles) |
3 (sin prefijo) |
| Cantidad de tests | 9 | 4 |
| USER_LOGIN_BEGIN | 3 tests (fresh, error, loggedIn — duplicados) | 1 test (resets to loading) |
| USER_LOGIN_SUCCESS | 2 tests — sin payload | 1 test — con payload (user, version, etc.) |
| USER_LOGIN_FAILURE | 2 tests (loading, weird) | 1 test (sets error) |
| USER_LOGOUT | 2 tests | Eliminado por completo — la acción no existe |
| Descripción de unknown action | 'unknown action' — poco claro |
'unknown action returns current state' — claro |
USER_LOGIN_BEGIN (ambos reinician el estado). La acción no existe en el reductor.user, version, buildTimestamp, alertMessage), el nuevo comprueba todos los campos.loggedIn: boolean se ha reemplazado por user: object|null como parte de la migración de connect() a useSelector [react-redux hooks].⚡ — enlace al código en la rama draft43npm del fork, que aún no se ha fusionado con develop. El código podría no estar disponible en GitHub hasta que se fusione el PR.
1.
initialStateextraído a una constante.Antes: el objeto estaba hardcodeado en el test
it('initial state')como{ loading: false, error: null, loggedIn: false }.Ahora: constante
initialState, que además coincide con elinitialStatedel propio reductor [reducers/authentication.js:3].2.
loading: false→loading: true.Init antiguo:
loading: false— el usuario no ha iniciado sesión, el spinner no está girando.Init nuevo:
loading: true— al cargar la aplicación se ejecuta inmediatamenteloadUserStatus(), que verifica la sesión. El estado inicial es «buscando al usuario». Este cambio corresponde al reductor en el commit 8b3b44be7 (18/03/2020).3.
loggedIn: false→user: null. CAMBIO PRINCIPAL EN LA ESTRUCTURA DEL ESTADO (STATE SHAPE).{ loading: boolean, error: string|null, loggedIn: boolean }
{ loading: boolean, error: string|null, user: object|null }
loggedIn: truetras el login → ahorauser: { name: 'test', ... }loggedIn: falseantes del login → ahorauser: nulluser !== nullen lugar deloggedIn === trueconnect()auseSelector[react-redux hooks]