hbox-docs/backend/TESTS-1014.md

105 lines
6.2 KiB
Markdown

# Pruebas del 14-oct — equipo, accesos y responsables
Complementa a `TESTS-1013.md`. Todo corrió en el sandbox contra `backend/app.py` con carpetas temporales,
un **htpasswd temporal** (`HTPASSWD_FILE`, permisos 640, hashes `$apr1$` generados con la misma rutina
del backend) y `ACTAS_ADMINS=leo,alan`. El usuario llega por `X-Remote-User`, como lo fija nginx.
## 1 · Backend — `backend/tests-1014.sh` (57 comprobaciones)
```bash
bash backend/tests-1014.sh /ruta/a/hbox-docs 8097
```
```
## siembra (incluye equipo) — con un pendiente viejo sin responsable y sin responsable_ids
✓ equipo sembrado (9)
✓ pendientes nuevos (12 de 13: t-caja-ethernet ya existía)
✓ responsable vacío completado a leo
✓ responsable_ids recalculado
✓ t-caja-ethernet → leo con historial
✓ segunda corrida: equipo no duplica
✓ segunda corrida: nada que completar
✓ t-ferreteria-eit-timsa sembrada para adriana
## equipo
✓ GET equipo (cualquiera)
✓ tiene_login derivado del htpasswd (leo sí)
✓ adriana sin login
✓ es_admin desde ACTAS_ADMINS
✓ pendientes abiertos por miembro
✓ logins sin miembro solo para admin (bob no admin → [])
✓ logins sin miembro para admin (bob)
✓ POST equipo no admin → 403
✓ POST equipo (admin)
✓ POST equipo duplicado → 409
✓ POST equipo área inválida → 400
✓ PATCH miembro no admin → 403
✓ PATCH miembro (admin) → historial
✓ PATCH activo=false (desactivar, nunca borrar)
✓ GET equipo oculta inactivos
✓ GET equipo?todos=1 los muestra
✓ PATCH inexistente → 404
## accesos (htpasswd temporal)
✓ POST usuarios no admin → 403
✓ contraseña corta → 400
✓ usuario con espacios/mayúsculas → 400
✓ crea acceso a miembro existente (adriana)
✓ línea en el htpasswd con apr1
✓ el hash valida con apr1 (misma rutina que /api/password)
✓ permisos del archivo conservados (640)
✓ duplicado → 409
✓ crea usuario Y miembro nuevos
✓ GET /api/usuarios sigue igual (lista del htpasswd)
✓ la cuenta nueva cambia su propia contraseña por /api/password
✓ bitácora _accesos.csv
✓ DELETE no admin → 403
✓ DELETE a sí mismo → 400
✓ DELETE inexistente → 404
✓ último admin con acceso (alan admin sin login quita a leo) → 409
✓ con dos admins con acceso, alan sí puede quitar a leo
✓ leo ya no está en el htpasswd
✓ miembro leo desactivado (no borrado)
✓ DELETE nuevo1 (admin alan)
## responsable obligatorio y resumen
✓ crear sin responsable → 400
✓ crear con ids (y 'Jesús' con acento → jesus)
✓ texto libre → se acepta con aviso
✓ lista como array también vale
✓ PATCH responsable vacío → 400
✓ PATCH sin tocar responsable sigue funcionando
✓ filtro por id
✓ filtro con acento
✓ GET tareas trae el mapa equipo
✓ resumen por_responsable (jesus)
✓ resumen por_responsable cuenta abiertos
✓ resumen conserva por_pista
RESULTADO: 57 correctas · 0 fallidas · datos en <tmp>
```
| Área | Probado |
|---|---|
| siembra | con un pendiente viejo sin `responsable` ni `responsable_ids`: la primera corrida crea los 9 miembros y 12 pendientes (el viejo se respeta), completa el responsable vacío a `leo` con historial y recalcula `responsable_ids`; la segunda corrida no crea ni cambia nada |
| equipo | GET para cualquiera con `tiene_login` (derivado del htpasswd), `es_admin` (de `ACTAS_ADMINS`) y pendientes por miembro; `logins_sin_miembro` solo para admin; POST/PATCH 403 para no admin; 409 duplicado; 400 área inválida; PATCH con historial; `activo:false` oculta sin borrar (`?todos=1` lo muestra); 404 |
| accesos | POST 403 no admin; 400 contraseña corta y usuario inválido; alta sobre miembro existente (`nuevo_miembro:false`) y alta de usuario+miembro nuevos; línea `$apr1$` verificada con `apr1()`; permisos 640 conservados; 409 duplicado; `GET /api/usuarios` igual que antes; la cuenta nueva cambia su contraseña por `/api/password`; bitácora `_accesos.csv`; DELETE 403 no admin, 400 a sí mismo, 404 inexistente, **409 último administrador con acceso**, ok con dos admins; miembro queda `activo:false` |
| pendientes | crear sin responsable → 400; `"Michelle, Jesús"` → `["michelle","jesus"]`; texto libre aceptado con `aviso`; lista como array; PATCH con responsable vacío → 400; PATCH sin tocar responsable sigue igual; filtro por id y con acento; `GET /api/tareas` trae `equipo`; `resumen.por_responsable` con nombre y abiertos; `por_pista` se conserva |
`backend/tests-1013.sh` se volvió a correr contra este backend (61/61) tras ajustar sus altas de pendientes
a la regla nueva (responsable obligatorio) y el conteo de la siembra (13 pendientes).
## 2 · Páginas — Chromium headless (Playwright), teléfono y escritorio
| Página | Probado | Resultado |
|---|---|---|
| `tableros/equipo.html` (alan) | ve la lista de miembros sin ningún botón ni «Nuevo usuario»; toca «Jesús» y ve sus 2 pendientes con enlace al tablero filtrado | ✓ |
| `tableros/kanban.html` (alan) | las tarjetas muestran el **nombre** («Michelle Márquez», no `michelle`); crear sin responsable → mensaje de validación y no se envía; con dos chips (Adriana, Alán) se crea y la tarjeta muestra ambos nombres; `?responsable=adriana` filtra por id | ✓ |
| `tableros/equipo.html` (leo) | «Nuevo usuario / miembro» con «crear acceso» marcado y contraseña generada → se muestra **una sola vez**; la fila nueva dice acceso «sí»; el hash del htpasswd valida con `apr1()`; «Quitar acceso» → acceso «no» e inactivo; «Editar» guarda el correo; leo no tiene botón para quitarse el acceso | ✓ |
| `tableros/produccion.html` / `ingenieria.html` | los bloqueos y las tarjetas muestran el nombre del responsable | ✓ |
| suite del 13-oct (`test_kanban.py`) | repetida con la regla nueva (elige un chip al crear): drag&drop, Mover a…, historial, borrar admin, plan | ✓ sin errores de consola |
## 3 · Sitio estático
`mkdocs build --strict` sobre una copia: las mismas 55 advertencias preexistentes (PDF/binarios ausentes
en la copia); ninguna sobre `tableros/equipo.html` ni los archivos tocados. Referencias `src`/`href` de
`equipo.html`, `kanban.html`, `ingenieria.html`, `produccion.html`, `admin.html`, `cuenta.html`: 0 rotas.
`node --check tableros/kanban.js`: sin errores.