# Plan de cobertura de tests (pendientes y prioritarios)

Este documento recoge huecos relevantes de cobertura detectados al revisar la suite actual. La intención es prevenir regresiones en flujos críticos, no añadir tests por añadir.

## Áreas de mejora propuestas

### 1) Comandos y asignaciones
- [ ] Creación con menciones en grupos: si el mensaje incluye @menciones (contextInfo.mentionedJid), asignar a esos usuarios:
  - Normalizar IDs a dígitos.
  - Evitar duplicados.
  - Crear usuarios inexistentes (ensureUserExists).
  - Verificar ACK de creación refleja destinatarios asignados.
- [ ] “Tomar” cuando ya hay otro responsable:
  - Definir contrato: ¿multi-asignación permitida o bloqueo con mensaje (“ya tiene responsable”)? Añadir test y ajustar si aplica.
- [ ] “Soltar” con varios responsables:
  - Verificar que al soltar uno, la tarea no queda “sin responsable” si siguen existiendo otros asignados.

### 2) WebhookServer
- [ ] Integración de menciones: extraer contextInfo.mentionedJid y pasar “mentions” normalizadas a CommandService (end-to-end).
- [ ] getMessageText: cubrir videoMessage.caption además de conversation/extendedText/image caption.
- [ ] Cuerpo JSON inválido con Content-Type: application/json:
  - Devolver 400 sin lanzar excepción no controlada.
- [ ] /metrics con METRICS_ENABLED=false:
  - Debe devolver 404 (ya hay test para enabled=true).
- [ ] Eventos desconocidos:
  - Debe responder 200 (o el comportamiento esperado) sin efectos colaterales.

### 3) TaskService
- [ ] ON DELETE CASCADE: borrar una tarea elimina sus asignaciones (task_assignments).
- [ ] FK en createTask con group_id inexistente:
  - Debe fallar por FK (asegura integridad y que las FKs siguen activas).
- [ ] Descripciones con caracteres especiales/SQL:
  - Asegurar persistencia literal usando parámetros (no concatenación) y sin truncado.
- [ ] padTaskId:
  - Formateo con ancho y no truncar IDs largos.

### 4) GroupSyncService
- [ ] fetchGroupMembersFromAPI:
  - Fallo de red o JSON corrupto ⇒ snapshot vacío y sin romper flujo superior.
- [ ] syncGroups:
  - 200 con contenido no-JSON o estructura inesperada ⇒ error claro y log.
- [ ] Caché de grupos activos:
  - Si hay vencimiento/actualización, test de refresco para evitar caché desfasado.

### 5) RemindersService
- [ ] start/stop:
  - No arranca en test (ya lo respeta), y cuando retentionDays <= 0 no programa.
- [ ] Bordes de horario/TZ:
  - Exactamente a la hora configurada (p. ej., 08:30 exacto).
  - Transición fin de día (23:59 → 00:00) en la TZ configurada.
  - Fija el comportamiento de ymdInTZ/hmInTZ.

### 6) ResponseQueue
- [ ] Concurrencia de claimNextBatch:
  - Dos llamadas simultáneas no deben reclamar el mismo ítem.
- [ ] markSent (si existe):
  - Marca “sent”, actualiza updated_at y deja de ser reclamable.

### 7) MaintenanceService
- [ ] retentionDays = 0 o < 0:
  - No debe borrar nada.
- [ ] Sin inactivos:
  - cleanupInactiveMembersOnce devuelve 0 y no toca filas activas.

### 8) Metrics
- [ ] enabled():
  - Cubrir combinaciones: true/1/yes, false/0/no, undefined en test/prod.
  - Evitar emisión accidental en entornos no deseados.

### 9) DB/Pragmas y utilidades
- [ ] getDb:
  - Crea directorio data (manejar EEXIST) y aplica PRAGMAs por defecto.
- [ ] tableHasColumn (migraciones condicionales):
  - Comportamiento correcto con tablas parciales.

### 10) Salud y endpoints
- [ ] /health sin ?full=1:
  - Respuesta básica “ok” sin suponer tablas opcionales.

## Priorización sugerida

1. Asignaciones por menciones (grupo) e integración desde WebhookServer.
2. Concurrencia de claimNextBatch en ResponseQueue.
3. Integridad referencial: cascada en task_assignments y FK de createTask con group inexistente.
4. Robustez WebhookServer: JSON inválido y /metrics disabled.
5. GroupSync: errores en fetchGroupMembersFromAPI y contenidos inesperados en syncGroups.
6. Reminders: bordes de horario exacto y retención desactivada.
7. “Tomar/soltar” con múltiples responsables.

## Notas de implementación

- Preferir tests end-to-end donde aporten valor (WebhookServer → CommandService → ResponseQueue/DB).
- Aislar concurrencia con transacciones/estados consistentes; si procede, usar transacciones en claimNextBatch.
- Mantener NODE_ENV y banderas (METRICS_ENABLED, TZ) explícitas por test.
- Reutilizar DB en memoria con initializeDatabase y limpiar tablas entre casos.
- Usar factories/helpers (p. ej., ensureUserExists) para preparar datos evitando duplicación.
