hbox-docs/backend/TESTS-1013.md

8.0 KiB
Raw Permalink Blame History

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 --strict sobre una copia: 55 advertencias, las mismas 55 de antes (PDF y binarios que no existen en esta copia). Ninguna menciona tableros/, inventario/, sitios/, instalacion.html ni unidad.html. Las tres páginas .md nuevas se construyen (quedan fuera del nav hasta que se aplique la nueva navegación; ver NUEVOS-1013.md).
  • Comprobación de referencias en los HTML nuevos y modificados (todo src/href relativo y los enlaces ../hardware/…/ dentro del JS): 0 rotas.
  • node --check sobre tableros/kanban.js y formularios/acta.js: sin errores de sintaxis.
  • El <script> embebido en sitios/index.md sobrevive al render de Markdown (verificado en el HTML generado).