#!/usr/bin/env bash # Pruebas del 27-oct (Leo): campeón de cada pendiente — solo él, los administradores y TAREAS_MUEVEN_SIEMPRE (claude) # lo cambian de columna o le pasan el campeón a otra persona. Arranca app.py con datos temporales; no toca el servidor. # Uso: bash backend/tests-campeon.sh [puerto] set -u REPO=${1:?ruta a hbox-docs}; PORT=${2:-8098} T=$(mktemp -d); export ACTAS_DIR=$T/actas HTPASSWD_FILE=$T/htpasswd HTPASSWD_LOCK=$T/.lock ACTAS_ADMINS=leo PORT mkdir -p $ACTAS_DIR $T/equipo $T/tareas; : > $T/htpasswd for u in leo adriana jesus michelle claude; do echo "{\"id\":\"$u\",\"nombre\":\"$u\",\"area\":\"ingenieria\",\"activo\":true}" > $T/equipo/$u.json done # t-a: de antes (sin campo campeon): el campeón es el primero, adriana echo '{"id":"t-a","titulo":"Cotizar gabinetes","responsable":"adriana, jesus","estado":"por-hacer","pista":"compras","sitios":["qro"],"orden":0,"historial":[]}' > $T/tareas/t-a.json echo '{"id":"t-b","titulo":"Solo de Jesús","responsable":"jesus","estado":"por-hacer","pista":"compras","sitios":["qro"],"orden":1,"historial":[]}' > $T/tareas/t-b.json echo '{"id":"t-c","titulo":"Texto libre","responsable":"Proveedor X","estado":"por-hacer","pista":"compras","sitios":["qro"],"orden":2,"historial":[]}' > $T/tareas/t-c.json python3 $REPO/backend/app.py > $T/app.log 2>&1 & APP=$!; trap "kill $APP 2>/dev/null" EXIT; sleep 1.8 U="http://127.0.0.1:$PORT" ok=0; fail=0 check() { if [[ "$3" == *"$2"* ]]; then ok=$((ok+1)); echo " ✓ $1"; else fail=$((fail+1)); echo " ✕ $1 — esperaba «$2», obtuve: ${3:0:220}"; fi; } as() { curl -s -H "X-Remote-User: $1" -H "Content-Type: application/json" "${@:2}"; } campo() { python3 -c "import json,sys; d=json.load(sys.stdin); t=[x for x in d['tareas'] if x['id']=='$1'][0]; print(t.get('$2'))"; } echo "## campeón por omisión" check "pendiente viejo: el primero de la lista" "adriana" "$(as leo $U/api/tareas | campo t-a campeon)" check "GET /api/tareas trae mueven_siempre" '"mueven_siempre":["claude","leo"]' "$(as leo $U/api/tareas)" check "alta: campeón = primer responsable" '"campeon":"michelle"' "$(as leo -X POST -d '{"id":"t-n","titulo":"Nuevo","responsable":"michelle, jesus","pista":"ingenieria"}' $U/api/tareas)" check "alta con campeón elegido" '"campeon":"jesus"' "$(as leo -X POST -d '{"id":"t-n2","titulo":"Nuevo 2","responsable":"michelle, jesus","campeon":"jesus","pista":"ingenieria"}' $U/api/tareas)" check "campeón que no es responsable: error" "tiene que ser uno de los responsables" "$(as leo -X POST -d '{"id":"t-n3","titulo":"Nuevo 3","responsable":"michelle","campeon":"jesus","pista":"ingenieria"}' $U/api/tareas)" echo "## quién mueve" check "otro responsable (jesus) no mueve t-a" "Solo adriana, campe" "$(as jesus -X PATCH -d '{"estado":"en-curso"}' "$U/api/tarea?id=t-a")" check "…y el pendiente no cambió" "por-hacer" "$(as leo $U/api/tareas | campo t-a estado)" check "el campeón (adriana) sí mueve" '"estado":"en-curso"' "$(as adriana -X PATCH -d '{"estado":"en-curso"}' "$U/api/tarea?id=t-a")" check "un administrador (leo) sí mueve" '"estado":"bloqueado"' "$(as leo -X PATCH -d '{"estado":"bloqueado"}' "$U/api/tarea?id=t-a")" check "claude (lotes) sí mueve" '"estado":"en-curso"' "$(as claude -X PATCH -d '{"estado":"en-curso","_nota":"lote"}' "$U/api/tarea?id=t-a")" check "alguien que no es responsable no mueve t-b" "403" "$(as michelle -o /dev/null -w '%{http_code}' -X PATCH -d '{"estado":"hecho"}' "$U/api/tarea?id=t-b")" check "sin campeón (solo texto libre) cualquiera mueve" '"estado":"en-curso"' "$(as michelle -X PATCH -d '{"estado":"en-curso"}' "$U/api/tarea?id=t-c")" check "los demás campos sí los edita otro responsable" '"fecha_limite":"2026-11-05"' "$(as jesus -X PATCH -d '{"fecha_limite":"2026-11-05"}' "$U/api/tarea?id=t-a")" echo "## pasar el campeón" check "otro responsable no se puede quedar el campeón" "puede cambiar el campe" "$(as jesus -X PATCH -d '{"campeon":"jesus"}' "$U/api/tarea?id=t-a")" check "quitar al campeón de los responsables tampoco" "puede cambiar el campe" "$(as jesus -X PATCH -d '{"responsable":"jesus"}' "$U/api/tarea?id=t-a")" check "agregar a alguien sin tocar al campeón sí" '"campeon":"adriana"' "$(as jesus -X PATCH -d '{"responsable":"adriana, jesus, michelle"}' "$U/api/tarea?id=t-a")" check "el campeón lo pasa a jesus" '"campeon":"jesus"' "$(as adriana -X PATCH -d '{"campeon":"jesus"}' "$U/api/tarea?id=t-a")" check "queda en el historial" "campeon: adriana → jesus" "$(cat $T/tareas/t-a.json)" check "ahora adriana ya no mueve" "Solo jesus, campe" "$(as adriana -X PATCH -d '{"estado":"hecho"}' "$U/api/tarea?id=t-a")" check "y jesus sí" '"estado":"hecho"' "$(as jesus -X PATCH -d '{"estado":"hecho"}' "$U/api/tarea?id=t-a")" check "si el campeón sale de los responsables (admin), pasa al primero" '"campeon":"michelle"' "$(as leo -X PATCH -d '{"responsable":"michelle, adriana"}' "$U/api/tarea?id=t-a")" echo "## orden de columna (arrastre)" r=$(as adriana -X POST -d '{"estado":"hecho","ids":["t-b","t-c"]}' $U/api/tareas/orden) check "orden: a t-b (de jesus) no lo cambia de columna" '"negados":["t-b"]' "$r" check "…t-b sigue en por-hacer" "por-hacer" "$(as leo $U/api/tareas | campo t-b estado)" check "…t-c (sin campeón) sí pasó" "hecho" "$(as leo $U/api/tareas | campo t-c estado)" echo "## lotes" check "tablero.py acepta «campeon» en poner" "campeon" "$(grep -o '"campeon"' $REPO/backend/tablero.py | head -1)" echo; echo "Resultado: $ok bien, $fail mal"; [ $fail -eq 0 ]