#!/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 [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 echo '{"id":"t-m","titulo":"v6 bloque E","responsable":"michelle","campeon":"michelle","estado":"en-curso","pista":"ingenieria","sitios":["qro"],"orden":1,"historial":[]}' > $T/tareas/t-m.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 "## elegir uno de sus comentarios como el porqué (28-oct)" R=$(as michelle -X PATCH -d '{"_nota":"D12 quedó a 3.44 mm de U7.1 (se pedían 2 mm); L2 a 5 mm."}' "$U/api/tarea?id=t-m") CUANDO=$(echo "$R" | python3 -c "import json,sys; print(json.load(sys.stdin)['tarea']['historial'][-1]['cuando'])") sleep 1.1; as jesus -X PATCH -d '{"_nota":"Comentario de Jesús en el mismo pendiente."}' "$U/api/tarea?id=t-m" > /dev/null OTRO=$(as leo "$U/api/tareas" | python3 -c "import json,sys; t=[x for x in json.load(sys.stdin)['tareas'] if x['id']=='t-m'][0]; print(t['historial'][-1]['cuando'])") check "con el comentario de otra persona no" 'comentario tuyo' "$(as michelle -X PATCH -d "{\"estado\":\"hecho\",\"_nota_de\":\"$OTRO\"}" "$U/api/tarea?id=t-m")" check "con un comentario que no existe no" 'comentario tuyo' "$(as michelle -X PATCH -d '{"estado":"hecho","_nota_de":"2020-01-01T00:00:00"}' "$U/api/tarea?id=t-m")" check "…y no se movió" '"estado": "en-curso"' "$(as leo "$U/api/tareas" | python3 -c "import json,sys; t=[x for x in json.load(sys.stdin)['tareas'] if x['id']=='t-m'][0]; print(json.dumps({'estado': t['estado']}))")" R=$(as michelle -X PATCH -d "{\"estado\":\"hecho\",\"_nota_de\":\"$CUANDO\"}" "$U/api/tarea?id=t-m") check "con su propio comentario se mueve" '"estado":"hecho"' "$R" check "la entrada guarda «ref» con su «cuando»" "\"ref\": \"$CUANDO\"" "$(echo "$R" | ultimo)" check "y no repite el texto como comentario (sin «nota»)" 'None' "$(echo "$R" | python3 -c "import json,sys; print(json.load(sys.stdin)['tarea']['historial'][-1].get('nota'))")" check "la Actividad lleva el extracto" 'por su comentario del' "$(echo "$R" | ultimo)" R=$(as michelle -X PATCH -d "{\"estado\":\"en-curso\",\"_nota_de\":\"$CUANDO\",\"_nota\":\"Leo pidió revisar L2 otra vez.\"}" "$U/api/tarea?id=t-m") check "citar y además escribir: guarda las dos cosas" '"nota": "Leo pidió revisar L2 otra vez."' "$(echo "$R" | ultimo)" check "…con su «ref»" "\"ref\": \"$CUANDO\"" "$(echo "$R" | ultimo)" check "citar sin cambiar nada no deja rastro" '"sin_cambios":true' "$(as michelle -X PATCH -d "{\"_nota_de\":\"$CUANDO\"}" "$U/api/tarea?id=t-m")" 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 ]