# 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 */) }) ```