8.0 KiB
Pruebas del 13-oct — backend (tareas, plan, inventario, sitios) y páginas
Todo se corrió en el sandbox contra backend/app.py arrancado con carpetas temporales
(ACTAS_DIR=<tmp>/actas; las demás colecciones se deducen de ahí). Sin nginx: el usuario se
inyecta con la cabecera X-Remote-User tal como la fija nginx en producción. Nada de lo de
abajo toca el servidor real.
1 · Backend — backend/tests-1013.sh (61 comprobaciones)
El script arranca app.py en un puerto libre, ejercita cada endpoint nuevo con curl como
leo (admin) y como alan (técnico), corre la siembra dos veces y una importación --extra.
Se puede repetir en cualquier máquina con Python 3 + Flask:
bash backend/tests-1013.sh /ruta/a/hbox-docs 8098
Resultado de la corrida (13-oct-2026):
## salud y endpoints viejos
✓ salud
✓ whoami leo admin
✓ actas vacías
## tareas
✓ sin usuario → 403
✓ POST (alan)
✓ POST id duplicado → 409
✓ POST pista inválida → 400
✓ POST fecha inválida → 400
✓ GET filtro pista
✓ GET filtro responsable
✓ vencida calculada
✓ PATCH mover (alan) → historial con quién
✓ PATCH sin cambios
✓ PATCH estado inválido → 400
✓ PATCH inexistente → 404
✓ POST orden (renumera columna: t-b cambia de columna, t-a de posición)
✓ resumen
✓ resumen vencidas
✓ DELETE alan → 403
✓ DELETE leo → ok
✓ índice CSV escrito
## plan
✓ GET sin archivo → por omisión
✓ PUT alan → 403
✓ PUT leo
✓ PUT conserva etapas
✓ PUT sin versiones → 400
## inventario
✓ POST ítem (alan)
✓ POST código duplicado → 409
✓ POST categoría inválida → 400
✓ POST con stock_inicial → entrada
✓ salida sin stock → 409
✓ entrada
✓ salida
✓ ajuste (conteo 4 → delta −3)
✓ sin motivo → 400
✓ alerta = stock < mínimo
✓ PATCH stock a mano → 400
✓ PATCH ubicación → historial
✓ movimientos del ítem
✓ export CSV
✓ export CSV cabecera
## sitios
✓ POST alan → 403
✓ POST leo
✓ POST duplicado → 409
✓ PATCH alan → 403
✓ PATCH leo → historial
✓ GET sitios
✓ unidades del sitio
✓ coincidencia por slug
✓ coincidencia por texto (terminal/destino)
✓ instalada con fecha
✓ marca de daño en la unidad
✓ sitio inexistente → 404
✓ /api/unidad trae sitio
✓ /api/actas trae sitio
## siembra (idempotente)
✓ primera corrida crea
✓ sitios: 3 nuevos (icave ya existía)
✓ segunda corrida no duplica
✓ inventario no duplica
✓ --extra importa
✓ resumen tras siembra (1 + 12 sembrados + 1 extra)
RESULTADO: 61 correctas · 0 fallidas · datos en <tmp>
Qué cubre, por colección:
| Colección | Probado |
|---|---|
tareas |
403 sin usuario; POST con y sin id; 409 por id duplicado; 400 por pista/estado/fecha inválidos; filtros pista, responsable; vencida; PATCH que mueve de columna y deja historial con quién; PATCH sin cambios; 404; POST /api/tareas/orden; resumen (conteo y vencidas); DELETE 403 para técnico y ok para admin; _indice.csv |
plan |
GET devuelve el plan por omisión (_default) sin archivo; PUT 403 para técnico; PUT admin guarda actualizado_por y conserva las etapas; 400 sin versiones |
inventario |
POST ítem; 409 código duplicado (insensible a mayúsculas); 400 categoría inválida; stock_inicial → entrada; salida mayor al stock → 409; entrada/salida/ajuste con delta y stock_despues; 400 sin motivo; alerta = stock < mínimo; PATCH stock rechazado; PATCH con historial; listado de movimientos; CSV con cabecera text/csv |
sitios |
POST/PATCH 403 para técnico; POST admin; 409 duplicado; PATCH con historial; GET; /api/sitio/unidades con coincidencia por slug (sitio) y por texto (terminal, destino de envío), fecha de instalación, marca de daño; 404 |
| actas existentes | /api/actas y /api/unidad ahora traen sitio (y fecha, componentes en las propias) sin romper lo demás |
seed_1013.py |
primera corrida crea plan, 4 sitios, 18 ítems, 12 pendientes; la segunda no duplica nada; --extra archivo.json importa pendientes adicionales (Notion) de forma idempotente |
Además, antes del script: python3 -m py_compile backend/app.py sin errores; los endpoints
viejos (/api/salud, /api/whoami, /api/actas, /api/acta, /api/adjuntos, /api/unidad,
/api/series, /api/estado, /api/danos) se usaron desde las páginas durante las pruebas de
navegador sin cambios de comportamiento.
2 · Páginas — navegador real (Chromium headless con Playwright)
Se sirvió docs/ tal cual con un proxy que reenvía /api/ al backend y pone X-Remote-User
(un servidor como leo y otro como alan). Pruebas en teléfono (390×844, táctil) y escritorio.
| Página | Probado | Resultado |
|---|---|---|
tableros/kanban.html |
carga 12 pendientes sembrados; en teléfono se ve «Mover a…» y mueve de columna; el historial del detalle dice alan · estado: por-hacer → en-curso; alan no ve «Borrar»; crear pendiente con fecha pasada → tarjeta roja (vencida); filtro por pista; en escritorio arrastrar y soltar a Hecho; leo borra con confirmación |
✓ sin errores de consola |
tableros/ingenieria.html |
4 tarjetas de versión con enlaces; pendientes filtrados a Ingeniería; contador por versión | ✓ |
tableros/produccion.html |
KPIs, plan vs real, embudo, bloqueos, alertas, daños; leo ve «Editar plan» y guarda una fecha objetivo; alan no ve el botón | ✓ |
inventario/inventario.html |
18 ítems; ajuste a 15 desde el diálogo; salida de 99 → error visible «No hay stock suficiente»; historial del ítem; nuevo ítem con stock inicial 3; filtro «solo alertas»; export CSV con Content-Disposition |
✓ (el único mensaje de consola es el 409 esperado) |
formularios/instalacion.html |
lista de sitios desde /api/sitios; técnico precargado; unidad «otra»; exige las 3 fotos obligatorias; con fotos subidas envía: «Registro enviado … con 3 foto(s)»; segunda visita muestra el historial |
✓ |
formularios/envio.html · dano.html |
el select de sitio existe; en daño solo aparece al elegir «En campo / transporte / no se sabe» | ✓ |
sitios/sitio.html |
LZC muestra la unidad recién instalada; ICAVE muestra RTK-014 «por texto» (acta vieja sin sitio) y DAÑADA; alan no ve «Editar sitio»; leo edita ubicación + contacto y crea un sitio nuevo desde el selector | ✓ |
unidad.html |
bloque «Trazabilidad»: cadena de producción (módulos deducidos del número de unidad cuando no hay ensamble) y cadena de campo con sitio y fecha | ✓ |
Artefactos de Playwright (no van al repo): capturas kanban-leo.png, produccion.png,
inventario-movil.png, instalacion-movil.png, sitio-icave.png, unidad.png.
Dos falsos negativos que salieron en el camino y son del arnés de prueba, no de las páginas:
(1) Playwright hace scroll entre mousedown y dragstart, así que con una ventana corta
arrastraba la tarjeta equivocada — se resolvió con una ventana alta; (2) disparar change
sintético en el campo «otra unidad» y luego el change nativo al perder el foco hacía dos
loadSerie() — se resolvió haciendo blur normal (Tab), como lo haría un usuario.
3 · Sitio estático
mkdocs build --strictsobre una copia: 55 advertencias, las mismas 55 de antes (PDF y binarios que no existen en esta copia). Ninguna mencionatableros/,inventario/,sitios/,instalacion.htmlniunidad.html. Las tres páginas.mdnuevas se construyen (quedan fuera delnavhasta que se aplique la nueva navegación; verNUEVOS-1013.md).- Comprobación de referencias en los HTML nuevos y modificados (todo
src/hrefrelativo y los enlaces../hardware/…/dentro del JS): 0 rotas. node --checksobretableros/kanban.jsyformularios/acta.js: sin errores de sintaxis.- El
<script>embebido ensitios/index.mdsobrevive al render de Markdown (verificado en el HTML generado).