# Task 012 — Testes TDD

**Depende de:** todas anteriores
**Bloqueia:** 013

## Objetivo

Cobertura mínima por arquivo `*TddTest.php` em `Testes/<espelho>/` no padrão dos demais sinais (executável via `php <arquivo>`, classe `Assert*` com contadores `passou`/`falhas`, exit code 1 se falhar).

## Arquivos

### `Testes/Enums/OtpStatusTransicoesTddTest.php`
- Cada transição válida e inválida (cobre §3.2 do PRD).
- `aceitaTentativaValidacao()` só em ENVIADO.
- `estadoFinal()` em todos os terminais.

### `Testes/Canais/OtpCanalRegistryTddTest.php`
- Registrar com classe que não implementa interface → `InvalidArgumentException`.
- Resolver canal não registrado → `RuntimeException`.
- `LogCanal::enviar()` retorna true e escreve no error_log (verificar via `error_get_last`/captura).
- Override em testes via Factory.

### `Testes/Eventos/OtpEventoRegistryTddTest.php`
- Registrar/resolver/erros (similar ao 012).
- `aoExpirar`/`aoCancelar` default são no-op (estende `OtpEventoBase` e não sobrescreve).

### `Testes/Configuracao/OtpConfigTddTest.php`
- Defaults globais.
- Override por contexto (merge).
- Validações: `tamanho_codigo` fora de [4,8] → exceção. `validade_segundos` < 30 → exceção.

### `Testes/Laboratorios/CriarEEnviarOtpLaboratorioTddTest.php`
**Sem DB real** — usar pattern de stub no namespace (igual `RomaneioVeiculoEdicaoRotaCallbackTddTest`):
- Stubar `OtpVerificacaoSonda` e `OtpEventoSonda` no namespace `GalaxiaMissoes\Mensageria\sinais\Otp\Sondas` antes de carregar o Laboratório.
- `OtpCanalFactory::setOverride(<spy>)` para capturar envio.
- Assertivas: payload chega ao canal, status `ENVIADO`, hash gerado, evento `criado` + `enviado` registrados, OTP anterior cancelado se já existia.

### `Testes/Laboratorios/ValidarOtpLaboratorioTddTest.php`
- Cada caminho da máquina: sucesso, código errado (incrementa tentativas), tentativas excedidas (status final), expirado, sem OTP ativo, já validado.
- Spy de Evento para confirmar `aoValidar` chamado em sucesso.
- Falha do Evento: status permanece VALIDADO; evento de auditoria `falha_evento` registrado.

### `Testes/Laboratorios/CancelarConsultarOtpLaboratorioTddTest.php`
- `Cancelar` idempotente (cancelar duas vezes → mesma resposta).
- `Consultar` não muda estado.
- `Consultar` com OTP inexistente → erro tipado.

## Critério de aceite

- Todos os testes verdes localmente (`php <arquivo>` retorna 0).
- Cobertura cruza todos os caminhos descritos nos PRDs §3.2 e §3.4.
