hbox-docs/backend/tests-comentarios.sh
Leopoldo Rodríguez 62c037f198 Pendientes: comentarios en cada tarjeta y «¿por qué?» al moverla
Pedido de Leo (28-oct, 12:57 y 16:12). El detalle tiene «Comentarios» (hilo + caja; cualquiera con sesión comenta, aunque
no sea el campeón) y la tarjeta dice cuántos. Al mover pregunta «¿por qué?»: a Hecho (la evidencia, D-27-6), al reabrir
desde Hecho, a Bloqueado y de En curso a Por hacer; «Cancelar» o Esc la deja donde estaba. Vale para arrastrar, la franja,
las flechas, «Mover a…» y los botones del detalle. En el teléfono el detalle cabe en la pantalla.
Backend: _nota hasta 1000 caracteres y guardada aparte en historial[-1].nota. Pruebas: tests-comentarios.sh (16) +
1027 (55) + 1028 Compras (58) + 1023 (35) + campeón (25) + tests-actas-documentos.sh (15, antes tests-1028.sh, nombre que
pasó a Compras). Desplegado (DESPLIEGUE A13). Lote 2026-10-28_comentarios-pendientes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013SfRSvDd335NPYEbBrDFGE
2026-10-28 16:23:43 -06:00

54 lines
4.1 KiB
Bash
Executable File

#!/usr/bin/env bash
# Pruebas del 28-oct (Leo): comentarios en los pendientes y el «¿por qué?» al moverlos. PATCH /api/tarea con «_nota»:
# solo el comentario (cualquiera con sesión, aunque no sea el campeón) o junto con el cambio de columna (solo el campeón).
# La nota queda en el historial en «cambio» (como siempre, para la Actividad) y aparte en «nota» (el hilo del detalle).
# Arranca app.py con datos temporales; no toca el servidor.
# Uso: bash backend/tests-comentarios.sh <ruta-a-hbox-docs> [puerto]
set -u
REPO=${1:?ruta a hbox-docs}; PORT=${2:-8095}
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
echo '{"id":"t-a","titulo":"Cotizar gabinetes","responsable":"adriana, jesus","campeon":"adriana","estado":"en-curso","pista":"compras","sitios":["qro"],"orden":0,"historial":[]}' > $T/tareas/t-a.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}"; }
ultimo() { python3 -c "import json,sys; d=json.load(sys.stdin); h=d['tarea']['historial'][-1]; print(json.dumps(h, ensure_ascii=False))"; }
echo "## comentar"
R=$(as michelle -X PATCH -d '{"_nota":"Ya pedí la cotización a dos proveedores."}' "$U/api/tarea?id=t-a")
check "quien no es campeón comenta" '"ok":true' "$R"
check "el comentario queda en «nota»" '"nota": "Ya pedí la cotización a dos proveedores."' "$(echo "$R" | ultimo)"
check "y en «cambio» (para la Actividad)" '"cambio": "Ya pedí la cotización a dos proveedores."' "$(echo "$R" | ultimo)"
check "con su autor" '"quien": "michelle"' "$(echo "$R" | ultimo)"
check "comentar no mueve la columna" '"estado":"en-curso"' "$R"
LARGO=$(python3 -c "print('x'*1200)")
R=$(as michelle -X PATCH -d "{\"_nota\":\"$LARGO\"}" "$U/api/tarea?id=t-a")
check "un comentario largo se recorta a 1000" "1000" "$(echo "$R" | python3 -c "import json,sys; print(len(json.load(sys.stdin)['tarea']['historial'][-1]['nota']))")"
check "sin sesión no se comenta" '"ok":false' "$(curl -s -H 'Content-Type: application/json' -X PATCH -d '{"_nota":"hola"}' "$U/api/tarea?id=t-a")"
check "un comentario vacío no deja rastro" '"sin_cambios":true' "$(as michelle -X PATCH -d '{"_nota":" "}' "$U/api/tarea?id=t-a")"
echo "## mover con su porqué"
check "quien no es campeón no mueve, aunque traiga porqué" 'campe' "$(as michelle -X PATCH -d '{"estado":"hecho","_nota":"listo"}' "$U/api/tarea?id=t-a")"
R=$(as adriana -X PATCH -d '{"estado":"hecho","_nota":"Evidencia: cotización COT-123 en el cotizador."}' "$U/api/tarea?id=t-a")
check "el campeón mueve a Hecho con la evidencia" '"estado":"hecho"' "$R"
check "el historial dice el cambio y la nota" 'estado: en-curso → hecho — Evidencia: cotización COT-123' "$(echo "$R" | ultimo)"
check "y la nota sola en «nota»" '"nota": "Evidencia: cotización COT-123 en el cotizador."' "$(echo "$R" | ultimo)"
R=$(as adriana -X PATCH -d '{"estado":"en-curso","_nota":"Faltó la firma del proveedor."}' "$U/api/tarea?id=t-a")
check "reabrir con lo que faltó" 'estado: hecho → en-curso — Faltó la firma del proveedor.' "$(echo "$R" | ultimo)"
R=$(as adriana -X PATCH -d '{"estado":"bloqueado"}' "$U/api/tarea?id=t-a")
check "mover sin nota sigue funcionando (lotes, standup)" '"estado":"bloqueado"' "$R"
check "y sin nota no hay «nota»" 'None' "$(echo "$R" | python3 -c "import json,sys; print(json.load(sys.stdin)['tarea']['historial'][-1].get('nota'))")"
echo "## la Actividad sigue leyendo el historial"
check "la Actividad muestra el comentario" 'a dos proveedores' "$(as leo "$U/api/actividad?dias=2")"
echo
echo "RESULTADO: $ok correctas · $fail fallidas · datos en $T"
[ $fail -eq 0 ]