# Guia de Testes — AgenciaPsi

## Testes Automatizados

### Pré-requisito
Vitest já instalado (`npm install` resolve). Não precisa de banco, Supabase ou variáveis de ambiente.

### Comandos

| Comando | Descrição |
|---|---|
| `npm test` | Roda todos os testes uma vez e exibe resultado |
| `npm run test:watch` | Modo watch — re-roda ao salvar arquivos |
| `npm run test:ui` | Abre UI visual no browser (`http://localhost:51204`) |

### Arquivos de teste

| Arquivo | O que cobre |
|---|---|
| `src/features/agenda/composables/__tests__/useRecurrence.spec.js` | Geração de datas por tipo de regra, max_occurrences global, exceções, remarcação cross-range |
| `src/features/agenda/services/__tests__/agendaMappers.spec.js` | Mapeamento para FullCalendar, ícones de status, cores, buildNextSessions, minutesToDuration, buildWeeklyBreakBackgroundEvents |

### Quando rodar
- Antes de commitar qualquer mudança em `useRecurrence.js` ou `agendaMappers.js`
- Ao adicionar novo tipo de frequência (mensal, quinzenal, etc.)
- Ao mexer em exceções de recorrência
- Em CI/CD antes do deploy

---

## Testes Manuais

### Preparação
1. Limpar dados de teste no banco:
```sql
TRUNCATE TABLE recurrence_exceptions CASCADE;
TRUNCATE TABLE recurrence_rules CASCADE;
TRUNCATE TABLE agenda_eventos CASCADE;
TRUNCATE TABLE agendador_solicitacoes CASCADE;
```
2. Fazer login com seu usuário real
3. Selecionar a clínica/tenant correto

---

### 1. Evento Avulso

| Passo | Esperado |
|---|---|
| Clicar em um horário livre na agenda | Dialog de criação abre |
| Preencher paciente, horário, modalidade → Salvar | Evento aparece no calendário |
| Clicar no evento → Editar horário → Salvar | Horário atualiza |
| Clicar no evento → Marcar como "Faltou" | Cor muda para vermelho, ícone ✗ |
| Clicar no evento → Marcar como "Realizado" | Cor muda para cinza, ícone ✓ |
| Clicar no evento → Cancelar sessão | Cor muda para laranja, ícone ∅ |
| Clicar no evento → Excluir | Evento some do calendário |

---

### 2. Recorrência Semanal

| Passo | Esperado |
|---|---|
| Criar evento com frequência "Semanal" | Ocorrências aparecem em todas as semanas seguintes com ícone ↻ |
| Navegar para a semana seguinte | Ocorrências continuam aparecendo |
| Navegar para além do end_date | Não aparecem ocorrências após a data final |
| Criar série com "4 sessões" (max_occurrences) | Exatamente 4 ocorrências visíveis no calendário |

---

### 3. Recorrência Quinzenal e Dias Específicos

| Passo | Esperado |
|---|---|
| Criar série "Quinzenal" | Ocorrências aparecem a cada 2 semanas |
| Criar série "Dias específicos" (ex: seg + qua) | Ambos os dias aparecem toda semana |
| Navegar para semanas futuras | Padrão se mantém |

---

### 4. Edição de Série

| Passo | Esperado |
|---|---|
| Clicar em ocorrência → Editar → "Somente este" → mudar horário | Só aquela data muda; as outras continuam iguais |
| Clicar em ocorrência → Cancelar → "Somente este" | Só aquela data some (ou aparece cancelada) |
| Clicar em ocorrência → Cancelar → "Este e os seguintes" | A partir daquela data, sem mais ocorrências |
| Clicar em ocorrência → Cancelar → "Todos" | Série inteira some |

---

### 5. Remarcação Cross-Range ⭐

Este é o caso mais importante a testar.

| Passo | Esperado |
|---|---|
| Criar série semanal (ex: toda segunda) | Ocorrências nas segundas |
| Clicar na sessão da **semana 1** → Remarcar para **terça da semana 2** | — |
| Navegar para a **semana 1** | Segunda da semana 1 aparece vazia ou como "remarcado" |
| Navegar para a **semana 2** | Terça aparece com ícone ↺ e status "remarcado" |

---

### 6. Bloqueio de Agenda

| Passo | Esperado |
|---|---|
| Criar bloqueio de horário | Aparece no calendário com visual diferente (ícone ⊘) |
| Tentar agendar no horário bloqueado | Aviso de conflito |

---

### 7. Agendamento Online (Agendador Público)

| Passo | Esperado |
|---|---|
| Acessar URL pública do agendador | Página pública abre sem login |
| Selecionar data/horário disponível → Enviar solicitação | Confirmação exibida |
| No painel do terapeuta → "Agendamentos Recebidos" | Solicitação aparece na lista |
| Clicar em "Confirmar" | Evento criado na agenda |
| Clicar em "Recusar" | Solicitação removida, sem evento na agenda |

---

### 8. Suporte Técnico SaaS

| Passo | Esperado |
|---|---|
| Logar como `saas_admin` → Menu "Suporte Técnico" | Página de suporte abre |
| Selecionar um tenant → "Criar Sessão de Suporte" | URL com token é gerada |
| Copiar URL e abrir em outra aba | Agenda do terapeuta abre com banner de debug no rodapé |
| No banner → filtrar logs por categoria | Logs filtram corretamente |
| No banner → "Desativar suporte" | Banner some |
| No painel SaaS → "Revogar" na sessão ativa | Token invalidado |

---

### 9. Multi-Tenancy (se você tem 2 clínicas cadastradas)

| Passo | Esperado |
|---|---|
| Criar evento na clínica A | Evento aparece na agenda da clínica A |
| Trocar para clínica B | Evento da clínica A **não aparece** |
| Criar evento na clínica B | Aparece apenas na clínica B |

---

## Pedindo ao Claude para Executar os Testes

### Como usar o Claude Code para rodar e corrigir testes

O Claude Code (este agente) consegue rodar os testes, ler os erros e corrigir os problemas automaticamente. Basta iniciar a conversa com o contexto certo.

### Prompt de retomada recomendado

Cole isso no início de uma nova sessão com o Claude:

---

> Estou desenvolvendo o AgenciaPsi. Temos testes automatizados com Vitest.
>
> **Arquivos de teste:**
> - `src/features/agenda/composables/__tests__/useRecurrence.spec.js` — testa `generateDates`, `expandRules`, `mergeWithStoredSessions`
> - `src/features/agenda/services/__tests__/agendaMappers.spec.js` — testa mapeamento para FullCalendar
>
> **Rodar os testes:** `npm test`
>
> Por favor, rode os testes agora e me informe o resultado. Se houver falhas, analise a causa e corrija.

---

### O que o Claude consegue fazer automaticamente

| Pedido | O Claude faz |
|---|---|
| "Rode os testes" | Executa `npm test` e exibe o resultado |
| "Tem algum teste falhando?" | Roda e diagnóstica a causa raiz |
| "Corrija os testes que falham" | Analisa erro, ajusta o código ou o teste e re-roda |
| "Adicionei a funcionalidade X, crie testes para ela" | Lê o código e escreve novos casos no spec |
| "O teste Y está errado, o comportamento correto é Z" | Atualiza a asserção e confirma que passa |

### Boas práticas ao pedir testes ao Claude

- **Forneça o `AUDITORIA.md`** no início da sessão — dá contexto sobre a arquitetura e decisões já tomadas
- **Descreva o comportamento esperado** em português, não o código — o Claude escreve o código do teste
- **Se um teste falhar e você achar que o código está certo**, diga isso explicitamente: *"o teste está errado, não o código"* — o Claude vai ajustar a asserção
- **Se um teste falhar e você achar que o código está errado**, diga: *"o comportamento esperado é X"* — o Claude vai corrigir a implementação

### Exemplo de sessão típica

```
Você: Rodei npm test e 2 testes falharam. Analise e corrija.

Claude: [roda npm test, lê os erros, corrige o código ou as asserções, re-roda até 63/63 passarem]
```

---

## Adicionando Novos Testes

### Para `useRecurrence.spec.js`

```js
import { generateDates, expandRules, mergeWithStoredSessions } from '../useRecurrence.js'

it('meu novo caso', () => {
  const r = {
    id: 'rule-1', type: 'weekly', weekdays: [1], interval: 1,
    start_date: '2026-03-02', end_date: null, max_occurrences: null,
    status: 'ativo', start_time: '09:00', end_time: '10:00',
    // ... outros campos necessários
  }
  const dates = generateDates(r, new Date(2026, 2, 1), new Date(2026, 2, 31))
  expect(dates.length).toBe(/* esperado */)
})
```

### Para `agendaMappers.spec.js`

```js
import { mapAgendaEventosToCalendarEvents } from '../agendaMappers.js'

it('meu novo caso de mapeamento', () => {
  const [ev] = mapAgendaEventosToCalendarEvents([{
    id: 'ev-1', titulo: 'Teste', tipo: 'sessao', status: 'agendado',
    inicio_em: '2026-03-10T09:00:00', fim_em: '2026-03-10T10:00:00',
    owner_id: 'owner-1',
  }])
  expect(ev.extendedProps./* campo */).toBe(/* esperado */)
})
```
