101 lines
9.9 KiB
Bash
Executable File
101 lines
9.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# Pruebas del backend 13-oct: arranca app.py con carpetas temporales y ejercita cada endpoint nuevo.
|
||
# Uso: bash tests-1013.sh <ruta-a-hbox-docs> [puerto]
|
||
set -u
|
||
REPO=${1:?ruta a hbox-docs}; PORT=${2:-8098}
|
||
T=$(mktemp -d); export ACTAS_DIR=$T/actas PORT
|
||
mkdir -p $ACTAS_DIR
|
||
python3 $REPO/backend/app.py > $T/app.log 2>&1 &
|
||
APP=$!; trap "kill $APP 2>/dev/null" EXIT; sleep 1.5
|
||
U="http://127.0.0.1:$PORT"
|
||
LEO=(-s -H "X-Remote-User: leo" -H "Content-Type: application/json")
|
||
ALAN=(-s -H "X-Remote-User: alan" -H "Content-Type: application/json")
|
||
ok=0; fail=0
|
||
check() { # check "nombre" "esperado" "obtenido"
|
||
if [[ "$3" == *"$2"* ]]; then ok=$((ok+1)); echo " ✓ $1"; else fail=$((fail+1)); echo " ✕ $1 — esperaba «$2», obtuve: ${3:0:160}"; fi; }
|
||
|
||
echo "## salud y endpoints viejos"
|
||
check "salud" '"servicio":"actas-hbox"' "$(curl -s $U/api/salud)"
|
||
check "whoami leo admin" '"admin":true' "$(curl "${LEO[@]}" $U/api/whoami)"
|
||
check "actas vacías" '"total":0' "$(curl -s $U/api/actas)"
|
||
|
||
echo "## tareas"
|
||
check "sin usuario → 403" "No puedo identificarte" "$(curl -s -H 'Content-Type: application/json' -X POST $U/api/tareas -d '{"titulo":"x"}')"
|
||
check "POST (alan)" '"id":"t-a"' "$(curl "${ALAN[@]}" -X POST $U/api/tareas -d '{"id":"t-a","titulo":"Pendiente A","pista":"ingenieria","responsable":"michelle","fecha_limite":"2026-10-01","version_tarjeta":"V5.6","enlaces":[{"titulo":"ECO","url":"/hardware/v56-eco/"}]}')"
|
||
check "POST id duplicado → 409" '"existe":true' "$(curl "${ALAN[@]}" -X POST $U/api/tareas -d '{"id":"t-a","titulo":"dup"}')"
|
||
check "POST pista inválida → 400" "Pista inv" "$(curl "${ALAN[@]}" -X POST $U/api/tareas -d '{"titulo":"x","pista":"ventas"}')"
|
||
check "POST fecha inválida → 400" "AAAA-MM-DD" "$(curl "${ALAN[@]}" -X POST $U/api/tareas -d '{"titulo":"x","fecha_limite":"13/10/2026"}')"
|
||
curl "${LEO[@]}" -X POST $U/api/tareas -d '{"id":"t-b","titulo":"Pendiente B","pista":"compras","bloqueada_por":["t-a"]}' > /dev/null
|
||
check "GET filtro pista" '"total":1' "$(curl -s "$U/api/tareas?pista=compras")"
|
||
check "GET filtro responsable" '"total":1' "$(curl -s "$U/api/tareas?responsable=mich")"
|
||
check "vencida calculada" '"vencida":true' "$(curl -s "$U/api/tareas?pista=ingenieria")"
|
||
check "PATCH mover (alan) → historial con quién" '"quien":"alan"' "$(curl "${ALAN[@]}" -X PATCH "$U/api/tarea?id=t-a" -d '{"estado":"en-curso","orden":0}')"
|
||
check "PATCH sin cambios" '"sin_cambios":true' "$(curl "${ALAN[@]}" -X PATCH "$U/api/tarea?id=t-a" -d '{"estado":"en-curso"}')"
|
||
check "PATCH estado inválido → 400" "Estado inv" "$(curl "${ALAN[@]}" -X PATCH "$U/api/tarea?id=t-a" -d '{"estado":"listo"}')"
|
||
check "PATCH inexistente → 404" "No existe" "$(curl "${ALAN[@]}" -X PATCH "$U/api/tarea?id=nada" -d '{"titulo":"x"}')"
|
||
check "POST orden (renumera columna: t-b cambia de columna, t-a de posición)" '"actualizadas":2' "$(curl "${ALAN[@]}" -X POST $U/api/tareas/orden -d '{"estado":"en-curso","ids":["t-b","t-a"]}')"
|
||
check "resumen" '"en-curso": 1' "$(curl -s $U/api/tareas/resumen | python3 -c 'import sys,json; print(json.dumps(json.load(sys.stdin)["por_pista"]["ingenieria"]))')"
|
||
check "resumen vencidas" '"id":"t-a"' "$(curl -s $U/api/tareas/resumen)"
|
||
check "DELETE alan → 403" "Solo un administrador" "$(curl "${ALAN[@]}" -X DELETE "$U/api/tarea?id=t-b")"
|
||
check "DELETE leo → ok" '"borrado":"t-b"' "$(curl "${LEO[@]}" -X DELETE "$U/api/tarea?id=t-b")"
|
||
check "índice CSV escrito" "t-a" "$(cat $T/tareas/_indice.csv)"
|
||
|
||
echo "## plan"
|
||
check "GET sin archivo → por omisión" '"_default":true' "$(curl -s $U/api/plan)"
|
||
check "PUT alan → 403" "Solo un administrador" "$(curl "${ALAN[@]}" -X PUT $U/api/plan -d '{"pedido_total":570}')"
|
||
check "PUT leo" '"actualizado_por":"leo"' "$(curl "${LEO[@]}" -X PUT $U/api/plan -d '{"pedido_total":570,"versiones":[{"version":"V5.6","objetivo":113,"serie_prefijo":"V56","fecha":"2026-11-30"},{"version":"V5.7","objetivo":327},{"version":"v6","objetivo":130}]}')"
|
||
check "PUT conserva etapas" '"clave":"instalacion"' "$(curl -s $U/api/plan)"
|
||
check "PUT sin versiones → 400" "al menos una versi" "$(curl "${LEO[@]}" -X PUT $U/api/plan -d '{"versiones":[]}')"
|
||
|
||
echo "## inventario"
|
||
check "POST ítem (alan)" '"id":"EB-V56"' "$(curl "${ALAN[@]}" -X POST $U/api/inventario -d '{"codigo":"EB-V56","descripcion":"EinarBoard V5.6","categoria":"tarjeta","aplica_a":["V5.6"],"minimo":5}')"
|
||
check "POST código duplicado → 409" '"existe":true' "$(curl "${ALAN[@]}" -X POST $U/api/inventario -d '{"codigo":"eb-v56","descripcion":"dup"}')"
|
||
check "POST categoría inválida → 400" "inv\\u00e1lida: tornillo" "$(curl "${ALAN[@]}" -X POST $U/api/inventario -d '{"codigo":"X1","descripcion":"x","categoria":"tornillo"}')"
|
||
check "POST con stock_inicial → entrada" '"stock": 7' "$(curl "${ALAN[@]}" -X POST $U/api/inventario -d '{"codigo":"SD-15B-05","descripcion":"Mean Well","categoria":"fuente","minimo":113,"stock_inicial":7}' | python3 -c 'import sys,json; print(json.dumps(json.load(sys.stdin)["item"]))')"
|
||
check "salida sin stock → 409" "No hay stock suficiente" "$(curl "${ALAN[@]}" -X POST $U/api/inventario/movimiento -d '{"item_id":"EB-V56","tipo":"salida","cantidad":3,"motivo":"ensamble"}')"
|
||
check "entrada" '"stock_despues":10' "$(curl "${ALAN[@]}" -X POST $U/api/inventario/movimiento -d '{"item_id":"EB-V56","tipo":"entrada","cantidad":10,"motivo":"llegó pedido","referencia":"OC-1"}')"
|
||
check "salida" '"stock_despues":7' "$(curl "${ALAN[@]}" -X POST $U/api/inventario/movimiento -d '{"item_id":"EB-V56","tipo":"salida","cantidad":3,"motivo":"ensamble","referencia":"HBOX5-E01-A001-R0001"}')"
|
||
check "ajuste (conteo 4 → delta −3)" '"delta":-3' "$(curl "${ALAN[@]}" -X POST $U/api/inventario/movimiento -d '{"item_id":"EB-V56","tipo":"ajuste","cantidad":4,"motivo":"conteo físico"}')"
|
||
check "sin motivo → 400" "Escribe el motivo" "$(curl "${ALAN[@]}" -X POST $U/api/inventario/movimiento -d '{"item_id":"EB-V56","tipo":"entrada","cantidad":1}')"
|
||
check "alerta = stock < mínimo" '"alerta": true' "$(curl -s "$U/api/inventario?alertas=1" | python3 -c 'import sys,json; j=json.load(sys.stdin); print(json.dumps([i for i in j["items"] if i["id"]=="EB-V56"]))')"
|
||
check "PATCH stock a mano → 400" "no se edita a mano" "$(curl "${ALAN[@]}" -X PATCH "$U/api/inventario/item?id=EB-V56" -d '{"stock":99}')"
|
||
check "PATCH ubicación → historial" "ubicacion:" "$(curl "${ALAN[@]}" -X PATCH "$U/api/inventario/item?id=EB-V56" -d '{"ubicacion":"Anaquel A2","minimo":3}')"
|
||
check "movimientos del ítem" '"total":3' "$(curl -s "$U/api/inventario/movimientos?item_id=EB-V56")"
|
||
check "export CSV" 'codigo,descripcion' "$(curl -s $U/api/inventario/export.csv)"
|
||
check "export CSV cabecera" 'text/csv' "$(curl -s -D - -o /dev/null $U/api/inventario/export.csv)"
|
||
|
||
echo "## sitios"
|
||
check "POST alan → 403" "Solo un administrador" "$(curl "${ALAN[@]}" -X POST $U/api/sitios -d '{"id":"icave","nombre":"ICAVE"}')"
|
||
check "POST leo" '"id":"icave"' "$(curl "${LEO[@]}" -X POST $U/api/sitios -d '{"id":"icave","nombre":"ICAVE","cliente":"Hutchison Ports","ubicacion":"Veracruz","alias":["ICAVE (Veracruz)"],"contactos":[{"nombre":"Abraham","rol":"supervisor"}]}')"
|
||
check "POST duplicado → 409" '"existe":true' "$(curl "${LEO[@]}" -X POST $U/api/sitios -d '{"id":"icave","nombre":"ICAVE"}')"
|
||
check "PATCH alan → 403" "Solo un administrador" "$(curl "${ALAN[@]}" -X PATCH "$U/api/sitio?id=icave" -d '{"ubicacion":"x"}')"
|
||
check "PATCH leo → historial" "ubicacion: Veracruz" "$(curl "${LEO[@]}" -X PATCH "$U/api/sitio?id=icave" -d '{"ubicacion":"Veracruz, Ver."}')"
|
||
check "GET sitios" '"nombre":"ICAVE"' "$(curl -s $U/api/sitios)"
|
||
curl "${ALAN[@]}" -X POST $U/api/actas -d '{"tipo":"instalacion-campo","serie":"HBOX5-E01-A001-R0001","tecnico":"Alan","conforme":true,"resultado":"OK","fecha":"2026-10-10","sitio":"icave","maquina_id":"FL-JUN-060","accion":"Instalada y reportando"}' > /dev/null
|
||
curl "${ALAN[@]}" -X POST $U/api/actas -d '{"tipo":"diagnostico-campo","serie":"RTK-014","tecnico":"Alan","conforme":true,"resultado":"FALLA","fecha":"2026-10-11","terminal":"ICAVE","maquina_id":"FL-JUN-060"}' > /dev/null
|
||
curl "${ALAN[@]}" -X POST $U/api/actas -d '{"tipo":"dano","serie":"RTK-014","tecnico":"Alan","conforme":true,"resultado":"REGISTRADO","fecha":"2026-10-11","sitio":"icave","clasificacion":"Agua","accion":"Marcada como dañada","resumen":"agua adentro"}' > /dev/null
|
||
curl "${ALAN[@]}" -X POST $U/api/actas -d '{"tipo":"envio","serie":"HBOX5-E02-A002-R0002","tecnico":"Alan","conforme":true,"resultado":"ENVIADA","fecha":"2026-10-12","clasificacion":"ICAVE (Veracruz)","accion":"Enviada"}' > /dev/null
|
||
R=$(curl -s "$U/api/sitio/unidades?id=icave")
|
||
check "unidades del sitio" '"total_unidades":3' "$R"
|
||
check "coincidencia por slug" '"coincidencia":"sitio"' "$R"
|
||
check "coincidencia por texto (terminal/destino)" '"coincidencia":"texto"' "$R"
|
||
check "instalada con fecha" '"instalada":"2026-10-10"' "$R"
|
||
check "marca de daño en la unidad" '"marca":"DANADA"' "$R"
|
||
check "sitio inexistente → 404" "No existe el sitio" "$(curl -s "$U/api/sitio/unidades?id=nada")"
|
||
check "/api/unidad trae sitio" '"sitio":"icave"' "$(curl -s "$U/api/unidad?serie=HBOX5-E01-A001-R0001")"
|
||
check "/api/actas trae sitio" '"sitio":"icave"' "$(curl -s "$U/api/actas")"
|
||
|
||
echo "## siembra (idempotente)"
|
||
S1=$(python3 $REPO/backend/seed_1013.py --usuario leo 2>&1)
|
||
check "primera corrida crea" "pendientes (seed_1013): 12 creados" "$S1"
|
||
check "sitios: 3 nuevos (icave ya existía)" "sitios: 3 creados, 1 ya existían" "$S1"
|
||
S2=$(python3 $REPO/backend/seed_1013.py --usuario leo 2>&1)
|
||
check "segunda corrida no duplica" "12 ya existían" "$S2"
|
||
check "inventario no duplica" "0 ítems creados" "$S2"
|
||
echo '[{"id":"t-notion-1","titulo":"Importado de Notion","pista":"ingenieria","estado":"hecho"}]' > $T/extra.json
|
||
check "--extra importa" "extra.json): 1 creados" "$(python3 $REPO/backend/seed_1013.py --solo nada --extra $T/extra.json 2>&1)"
|
||
check "resumen tras siembra (1 + 12 sembrados + 1 extra)" '"total":14' "$(curl -s $U/api/tareas/resumen)"
|
||
|
||
echo; echo "RESULTADO: $ok correctas · $fail fallidas · datos en $T"
|
||
[ $fail -eq 0 ]
|