K
Kodama Vault
knowledge hub
Vault
HomeBoardMap of ContentChatConversasAuditoria
Agentes
AgentsIssuesTerminalPreviews
Sistema
MCPSetup MCPSettings
Brain
Global agent instructions
Análise custos migração — evitar senha no payloadLevantamento fluxo registro + duplicados StripeRelatório segurança + pentes finos (Cláudio)Revisão security concerns e race conditionsMagic link / esqueceu senha via SupabaseCorrigir erros pós-upgrade TypeScriptTestar PRs do agente Vault para mergeAnálise de 3 issues para iniciarErro no terminal do VSCodePR #173 — aguardando aprovação do LeoTestar fluxo ponta a ponta — criação de clients no StripePR #172 — testar e subir correção de funções deprecatedPitch de vendas SaaS — agendar call de conversãoOrganizar issues e bugs rápidos para a semanaMerge PR cadastro-novo — funcionalidades e correçõesCorrigir bugs PR #173 e #172 — image domainsPR mesosóico — página de acesso mobile + segurança OTPRefatoração de códigos — PR #202Ajustes em PRs abertos de ontemEstudo de jornada de compra e técnicas de fechamentoDefinir preço e entregável do produtoProspecção de reuniões para esta semanaAgente anti AI slop — centralização de conhecimento ConnfitPR #179 — resolver conflitos e erros de teste CLIAlinhamento de preços e usos da ConffitFix adicional para PR #183 — perfil do usuárioCorrigir estilização da Connfit para identidade visualSubir modificações no copy da ConnfitCriação de 4 campanhas no Meta AdsRevisão de PRs do GilinesExploração do Roblox EditorRelatório João — devolutiva TikTok ShopReunião presencial Zassi Uniformes — diagnóstico automaçõesCriar repositório de diagnósticos e relatórios de entrevistasDiagnóstico da ZassiGeração de relatórios para reuniões de fechamentoProposta Zassi — apresentação amanhãProspecção — Clínica Odontológica Dr. But
VPS Hermes — acesso e estrutura
Always Commit Push DeployHermes Voice GeminiHermes VPSKodama Prospects TrackerMEMORYObsidian VaultRoblox Mining Sim
OpenSpec -- Spec-Driven Development no VaultPlano de Teste — OpenSpec Vault Persistence
CaumzitoNyxzZanini
Claude Code — Setup MCP VaultClaude Desktop — Setup MCP Vault (remote)VS Code + Copilot — Setup MCP Vault
Skill — Carousel Designer (Paper Style)
Standup 2026-05-14Standup 2026-05-15Standup 2026-05-16Standup 2026-05-17Standup 2026-05-18Standup 2026-05-19Standup 2026-05-20Standup 2026-05-21Standup 2026-05-22Standup 2026-05-25Standup 2026-05-26Standup 2026-05-27Standup 2026-05-28Standup 2026-05-29Standup 2026-06-01Standup 2026-06-02Standup 2026-06-03Standup 2026-06-05Standup 2026-06-11Standup 2026-06-15Standup 2026-06-16Standup 2026-06-17Standups
MOCWelcome
v0.3
K
Kodama Vault
← Conversas
💬

Skip to content kodama1 connfit Repository navigation Code I...

▶ Continuar conversa
📅 15 de junho de 2026 às 17:15 🔄 1 turns 🆔 cugsafpjwy0p

👤 User

Skip to content
kodama1
connfit
Repository navigation
Code
Issues
18
(18)
Pull requests
5
(5)
Agents
Actions
Projects
Security and quality
Insights
Settings
Back to pull request #183
#173: #173: [AGENDA] Componente eager de verificação de disponibilidade dinamica dentr #445
All jobs
Run details
Annotations
1 error and 1 warning
Jest Unit Tests
failed last week in 1m 55s
Search logs
1s
1s
5s
51s
53s
Run npm test
npm warn using --force Recommended protections disabled.

connfit@1.2.2 test
jest --verbose

console.error
An update to TestComponent inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at src/hooks/use-event-sheet.ts:6361:9

console.error
An update to TestComponent inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at src/hooks/use-event-sheet.ts:6361:9

console.log
🔄 Reset form com selectedDate: {
selectedDate: { date: 2024-12-15T00:00:00.000Z },
startTime: '00:00',
endTime: '01:00',
startDateBeforeAppend: 2024-12-15T00:00:00.000Z,
startDateAfterAppend: 2024-12-15T00:00:00.000Z,
endDateAfterAppend: 2024-12-15T01:00:00.000Z
}

  at src/hooks/use-event-sheet.ts:7066:17

console.log
{ isValid: true, reason: undefined }

  at src/hooks/use-event-sheet.ts:6276:15

console.log
{ isValid: false, reason: 'ALREADY_BOOKED' }

  at src/hooks/use-event-sheet.ts:6276:15

console.log
{ isValid: false, reason: 'DATA_IN_PAST' }

  at src/hooks/use-event-sheet.ts:6276:15

console.log
{ isValid: false, reason: 'TIME_IN_PAST' }

  at src/hooks/use-event-sheet.ts:6276:15

console.log
{ isValid: false, reason: 'INVALID_TIME_RANGE' }

  at src/hooks/use-event-sheet.ts:6276:15

console.error
Erro na validação: Error: Erro de rede
at Object. (/home/runner/work/connfit/connfit/src/hooks/tests/use-event-sheet.test.tsx:354:58)
at Promise.then.completed (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:298:28)
at new Promise ()
at callAsyncCircusFn (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:231:10)
at _callCircusTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:316:40)
at async _runTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:252:3)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:126:9)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:121:9)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:121:9)
at async run (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:71:3)
at async runAndTransformResultsToJestFormat (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
at async jestAdapter (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
at async runTestInternal (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:367:16)
at async runTest (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:444:34)

  at src/hooks/use-event-sheet.ts:6309:15

console.error
An update to TestComponent inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at src/hooks/use-event-sheet.ts:6361:9

console.error
Erro ao carregar slots: Error: Erro na API
at Object. (/home/runner/work/connfit/connfit/src/hooks/tests/use-event-sheet.test.tsx:440:51)
at Promise.then.completed (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:298:28)
at new Promise ()
at callAsyncCircusFn (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:231:10)
at _callCircusTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:316:40)
at async _runTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:252:3)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:126:9)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:121:9)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:121:9)
at async run (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:71:3)
at async runAndTransformResultsToJestFormat (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
at async jestAdapter (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
at async runTestInternal (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:367:16)
at async runTest (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:444:34)

  at src/hooks/use-event-sheet.ts:6371:15

console.error
An update to TestComponent inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at src/hooks/use-event-sheet.ts:6361:9

console.error
Erro ao buscar paciente: Error: Network error
at Object. (/home/runner/work/connfit/connfit/src/hooks/tests/use-event-sheet.test.tsx:904:72)
at Promise.then.completed (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:298:28)
at new Promise ()
at callAsyncCircusFn (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:231:10)
at _callCircusTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:316:40)
at async _runTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:252:3)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:126:9)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:121:9)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:121:9)
at async run (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:71:3)
at async runAndTransformResultsToJestFormat (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
at async jestAdapter (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
at async runTestInternal (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:367:16)
at async runTest (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:444:34)

  at fetchPatient (src/hooks/use-event-sheet.ts:7316:19)

console.log
{ isValid: true, reason: undefined }

  at src/hooks/use-event-sheet.ts:6276:15

console.log
{ isValid: true, reason: undefined }

  at src/hooks/use-event-sheet.ts:6276:15

console.log
{ isValid: false, reason: 'UNKNOWN_ERROR' }

  at src/hooks/use-event-sheet.ts:6276:15

PASS src/hooks/tests/use-event-sheet.test.tsx (7.66 s)
useEventSheet Hook - Cobertura Completa
Estado inicial e inicialização
✓ deve inicializar com valores padrão (29 ms)
✓ deve inicializar com evento existente (77 ms)
✓ deve inicializar com paciente pré-selecionado (84 ms)
✓ deve inicializar com data selecionada (57 ms)
Validação de time slots
✓ deve validar time slot com sucesso (528 ms)
✓ deve mostrar erro para horário já ocupado (511 ms)
✓ deve mostrar erro para data no passado (512 ms)
✓ deve mostrar erro para horário no passado (561 ms)
✓ deve mostrar erro para range de tempo inválido (564 ms)
✓ deve tratar erro na validação (579 ms)
isTimeSlotDisabled
✓ deve retornar false quando não há startDate (5 ms)
✓ deve usar isTimeSlotInPast quando há startDate (16 ms)
Carregamento de slots disponíveis
✓ deve carregar slots disponíveis quando data é definida (59 ms)
✓ deve limpar slots quando não há data (61 ms)
✓ deve tratar erro no carregamento de slots (11 ms)
✓ deve tratar resposta sem sucesso (6 ms)
Submissão de formulário - Criação
✓ deve criar consulta com sucesso (7 ms)
✓ deve retornar early se horário de fim for antes do início (7 ms)
✓ deve retornar early se dados de data/hora estão faltando (3 ms)
✓ deve validar time slot antes de criar consulta (4 ms)
✓ deve tratar erro na criação (5 ms)
✓ deve tratar exceção na criação (5 ms)
Submissão de formulário - Atualização
✓ deve atualizar consulta existente com sucesso (6 ms)
✓ deve tratar erro na atualização (5 ms)
Deleção de consulta
✓ deve deletar consulta com sucesso (5 ms)
✓ deve tratar erro quando não há eventIdToDelete (3 ms)
✓ deve tratar erro na deleção (3 ms)
✓ deve tratar exceção na deleção (3 ms)
hasChanges
✓ deve retornar true para novo evento (2 ms)
✓ deve retornar false quando não há mudanças (9 ms)
✓ deve retornar true quando há mudanças (18 ms)
Integração com selectedPatients
✓ deve atualizar formulário quando paciente é selecionado (7 ms)
✓ deve atualizar header para edição quando há evento e paciente (7 ms)
searchParams - busca de paciente
✓ deve buscar e pré-preencher dados do paciente via searchParams (56 ms)
✓ deve tratar erro quando paciente não é encontrado (58 ms)
✓ deve tratar exceção na busca do paciente (56 ms)
✓ não deve buscar paciente se já existe evento ou patient prop (108 ms)
Modal states
✓ deve controlar estado do modal de deleção (4 ms)
Callback onClose
✓ deve chamar onClose após criação bem-sucedida (7 ms)
✓ deve chamar onClose ao abrir modal de deleção (3 ms)
✓ deve chamar onClose após deleção bem-sucedida (não embedded) (5 ms)
✓ não deve chamar onClose após deleção quando embedded=true (5 ms)
Estados de loading
✓ deve gerenciar isLoading durante submissão (106 ms)
✓ deve gerenciar isValidatingSlot durante validação (562 ms)
Edge cases e cleanup
✓ deve limpar validationMessage quando campos obrigatórios estão faltando (1018 ms)
✓ deve usar razão padrão para erro de validação desconhecido (511 ms)

console.log
Generated slots: [
'08:00', '09:00',
'10:00', '11:00',
'13:30', '14:30',
'15:30', '16:30'
]

  at Object.<anonymous> (src/__tests__/integration-complete.test.ts:584:21)

console.log
Available slots for migration test: [ '14:00', '15:00', '16:00' ]

  at Object.<anonymous> (src/__tests__/integration-complete.test.ts:754:21)

console.log
✅ System correctly prioritizes newTimeSlots over legacy timeSlots

  at Object.<anonymous> (src/__tests__/integration-complete.test.ts:761:21)

console.log
Available slots for range-only test: [ '10:00', '11:00', '12:00', '13:00' ]

  at Object.<anonymous> (src/__tests__/integration-complete.test.ts:848:21)

PASS src/tests/integration-complete.test.ts
🔄 TESTE DE INTEGRAÇÃO COMPLETA
🎯 Cenários de Uso Real
✓ ✅ Fluxo completo: Consultar → Validar → Agendar (28 ms)
✓ ✅ Múltiplas consultas no mesmo dia (9 ms)
✓ ✅ Reagendamento de consulta existente (4 ms)
✓ ✅ Consultas consecutivas com intervalo mínimo (7 ms)
🔀 Cenários de Concorrência
✓ ✅ Dois usuários tentando agendar o mesmo horário (2 ms)
✓ ✅ Atualização de disponibilidade durante agendamento (6 ms)
🌍 Cenários Multi-timezone
✓ ✅ Agendamento com diferentes fusos horários (4 ms)
🚨 Cenários de Recovery
✓ ✅ Sistema deve funcionar com dados inconsistentes (2 ms)
✓ ✅ Sistema deve lidar com disponibilidade vazia (1 ms)
📊 Métricas de Sistema
✓ ✅ Deve fornecer estatísticas de uso (3 ms)
🆕 newTimeSlots Range Format Tests
✓ ✅ isWithinAvailability should accept newTimeSlots ranges (2 ms)
✓ ✅ getAvailableTimeSlotsUnified should interpret newTimeSlots ranges (3 ms)
✓ ✅ Edge case: Appointment spanning range boundaries (1 ms)
✓ ✅ Format parsing: HH:MM validation (1 ms)
🔄 Backward Compatibility Tests
✓ ✅ Should handle mixed availability data with migration simulation (1 ms)
✓ ✅ getAvailableTimeSlotsUnified prioritizes newTimeSlots (3 ms)
🛤️ Migration Path Tests
✓ ✅ Migration from discrete points to ranges (1 ms)
✓ ✅ Should work with newTimeSlots only (migration complete) (3 ms)
✓ ✅ Complex migration scenario: multiple ranges and validation (2 ms)

PASS src/tests/e2e-appointment-booking.test.ts
🎯 TESTE END-TO-END COMPLETO - Sistema de Agendamento
📅 Lógica de Disponibilidade Dinâmica
✓ ✅ Deve agrupar timeSlots consecutivos em ranges corretamente (5 ms)
✓ ✅ Deve subtrair consultas existentes dos ranges disponíveis (11 ms)
✓ ✅ Deve gerar slots diferentes para diferentes durações de serviço (6 ms)
✓ ✅ Deve respeitar timezone brasileiro (America/Sao_Paulo) (3 ms)
✓ ✅ Deve filtrar horários passados para data de hoje (6 ms)
🔒 Validação Backend (isWithinAvailability)
✓ ✅ Deve validar horário disponível corretamente (4 ms)
✓ ❌ Deve rejeitar horário em conflito com consulta existente (1 ms)
✓ ❌ Deve rejeitar horário fora da disponibilidade configurada (1 ms)
✓ ❌ Deve rejeitar duração incompatível (1 ms)
✓ ❌ Deve rejeitar datas inválidas (1 ms)
⚡ Detecção de Conflitos (scheduledTimeHasConflict)
✓ ✅ Deve detectar conflito de sobreposição total (2 ms)
✓ ✅ Deve detectar conflito de sobreposição parcial (início) (1 ms)
✓ ✅ Deve detectar conflito de sobreposição parcial (fim) (11 ms)
✓ ✅ Não deve detectar conflito em horários adjacentes (1 ms)
✓ ✅ Deve lidar com múltiplas consultas (1 ms)
💾 Ações de Banco de Dados
✓ ✅ createAppointment - deve criar nova consulta com sucesso (2 ms)
✓ ❌ createAppointment - deve falhar em horário indisponível (1 ms)
✓ ✅ updateAppointment - deve atualizar consulta existente (1 ms)
✓ ✅ deleteAppointment - deve excluir consulta (1 ms)
✓ ❌ Deve tratar erros de API corretamente (1 ms)
👤 Gestão de Pacientes
✓ ✅ Deve buscar paciente existente por email (1 ms)
✓ ✅ Deve criar novo paciente quando não existir (1 ms)
✓ ❌ Deve tratar erro ao criar paciente com email duplicado (10 ms)
🔄 Integração Frontend-Backend (Race Conditions)
✓ ✅ Frontend e Backend devem ter mesma lógica de disponibilidade (5 ms)
✓ ✅ Deve prevenir race condition em agendamento simultâneo (1 ms)
🚨 Edge Cases Extremos
✓ ❌ Deve rejeitar consulta no passado (1 ms)
✓ ❌ Deve rejeitar consulta com duração muito longa (>4h) (2 ms)
✓ ❌ Deve lidar com timezone de verão/inverno (3 ms)
✓ ❌ Deve rejeitar dados malformados (1 ms)
✓ ✅ Deve lidar com múltiplos fusos horários (2 ms)
✓ ✅ Deve otimizar performance com muitas consultas (1236 ms)
🎯 Cobertura de Código Completa
✓ ✅ Deve cobrir todos os cenários de uso real (1 ms)

console.error
Erro ao buscar disponibilidade: { message: 'Database error' }

  at getAvailableTimeSlots (src/actions/availability.ts:7085:15)
  at async Object.<anonymous> (src/actions/__tests__/availability-time-validation.test.ts:492:28)

PASS src/actions/tests/availability-time-validation.test.ts

🕐 TDD - Validação de Horários e Disponibilidade
📅 Validação de Datas Passadas
✓ deve retornar true para datas do passado (2 ms)
✓ deve retornar false para hoje (1 ms)
✓ deve retornar false para datas futuras (1 ms)
🕐 Validação de Horários Passados
✓ deve retornar true para horários que já passaram hoje (1 ms)
✓ deve retornar false para horários futuros hoje (1 ms)
✓ deve retornar false para qualquer horário em datas futuras (1 ms)
✓ deve retornar true para qualquer horário em datas passadas (1 ms)
✅ Validação de Disponibilidade por TimeSlot
✓ deve retornar false para data no passado (2 ms)
✓ deve retornar false para horário no passado (1 ms)
✓ deve retornar false para horário fora da disponibilidade (2 ms)
✓ deve retornar false para horário já ocupado (6 ms)
✓ deve retornar true para horário válido e disponível (2 ms)
📋 Obtenção de Slots Disponíveis
✓ deve retornar array vazio para data no passado (2 ms)
✓ deve filtrar horários que já passaram para hoje (2 ms)
✓ deve excluir horários já ocupados (4 ms)
✓ deve incluir apenas horários dentro da disponibilidade (3 ms)
✓ deve retornar slots com diferentes durações (10 ms)
✓ deve tratar erro na busca de availability (8 ms)
🐛 Bug #173 - Horários Não-Discretos (quebrados como 8:30, 9:30)
✓ deve aceitar horário 08:30 quando range é 08:00-18:00 (2 ms)
✓ deve aceitar horário 09:30 quando range é 08:00-18:00 (1 ms)
✓ deve aceitar horário 10:30 quando range é 08:00-18:00 (2 ms)
✓ deve aceitar horário exatamente na borda inicial do range (08:00-09:00) (1 ms)
✓ deve aceitar horário exatamente na borda final do range (17:00-18:00) (1 ms)
✓ deve rejeitar horário que começa antes do range (07:30 quando range inicia em 08:00) (1 ms)
✓ deve rejeitar horário que termina após o range (17:30 quando range termina em 18:00 mas start+duration extrapola) (1 ms)
✓ deve rejeitar horário 08:30-09:30 quando há consulta conflitante às 08:30-09:30 (2 ms)
✓ deve rejeitar 09:00-10:00 quando existe consulta às 09:30-10:30 (overlap parcial) (2 ms)
✓ deve aceitar 08:00-09:00 quando consulta existe às 09:30-10:30 (sem overlap) (2 ms)
✓ deve aceitar 10:30-11:30 quando consulta existe às 09:30-10:30 (exatamente após) (1 ms)
🚫 Casos Limite e Edge Cases
✓ deve validar horário de início posterior ao fim (1 ms)
✓ deve tratar nutritionistId inexistente (1 ms)
✓ deve tratar dia da semana sem availability configurada (1 ms)

console.error
Erro ao obter sessão: { message: 'Session expired' }

  at resolveToken (src/lib/api-client.ts:3257:15)
  at async /home/runner/work/connfit/connfit/src/lib/api-client.ts:3361:30
  at async Object.<anonymous> (src/lib/__tests__/api-client.test.ts:324:28)

console.error
Erro ao renovar sessão: { message: 'Refresh failed' }

  at src/lib/api-client.ts:3469:17
  at async Object.<anonymous> (src/lib/__tests__/api-client.test.ts:426:13)

console.error
Error: Not implemented: navigation (except hash changes)
at (src/lib/api-client.ts:3479:32)
at async Object. (src/lib/tests/api-client.test.ts:426:13) {
type: 'not implemented'
}

  at VirtualConsole.<anonymous> (node_modules/@jest/environment-jsdom-abstract/build/index.js:87:23)
  at module.exports (node_modules/jsdom/lib/jsdom/browser/not-implemented.js:12:26)
  at navigateFetch (node_modules/jsdom/lib/jsdom/living/window/navigation.js:77:3)
  at exports.navigate (node_modules/jsdom/lib/jsdom/living/window/navigation.js:55:3)
  at LocationImpl._locationObjectNavigate (node_modules/jsdom/lib/jsdom/living/window/Location-impl.js:30:5)
  at LocationImpl._locationObjectSetterNavigate (node_modules/jsdom/lib/jsdom/living/window/Location-impl.js:24:17)
  at set href [as href] (node_modules/jsdom/lib/jsdom/living/window/Location-impl.js:46:10)
  at set href [as href] (node_modules/jsdom/lib/jsdom/living/generated/Location.js:125:37)
  at src/lib/api-client.ts:3479:32
  at async Object.<anonymous> (src/lib/__tests__/api-client.test.ts:426:13)

console.error
Erro ao renovar sessão: { message: 'Refresh failed' }

  at src/lib/api-client.ts:3469:17
  at async Object.<anonymous> (src/lib/__tests__/api-client.test.ts:464:13)

console.error
Error: Not implemented: navigation (except hash changes)
at (src/lib/api-client.ts:3479:32)
at async Object. (src/lib/tests/api-client.test.ts:464:13) {
type: 'not implemented'
}

  at VirtualConsole.<anonymous> (node_modules/@jest/environment-jsdom-abstract/build/index.js:87:23)
  at module.exports (node_modules/jsdom/lib/jsdom/browser/not-implemented.js:12:26)
  at navigateFetch (node_modules/jsdom/lib/jsdom/living/window/navigation.js:77:3)
  at exports.navigate (node_modules/jsdom/lib/jsdom/living/window/navigation.js:55:3)
  at LocationImpl._locationObjectNavigate (node_modules/jsdom/lib/jsdom/living/window/Location-impl.js:30:5)
  at LocationImpl._locationObjectSetterNavigate (node_modules/jsdom/lib/jsdom/living/window/Location-impl.js:24:17)
  at set href [as href] (node_modules/jsdom/lib/jsdom/living/window/Location-impl.js:46:10)
  at set href [as href] (node_modules/jsdom/lib/jsdom/living/generated/Location.js:125:37)
  at src/lib/api-client.ts:3479:32
  at async Object.<anonymous> (src/lib/__tests__/api-client.test.ts:464:13)

console.error
Error: Not implemented: navigation (except hash changes)
at (src/lib/api-client.ts:3543:32)
at async Object. (src/lib/tests/api-client.test.ts:502:13) {
type: 'not implemented'
}

  at VirtualConsole.<anonymous> (node_modules/@jest/environment-jsdom-abstract/build/index.js:87:23)
  at module.exports (node_modules/jsdom/lib/jsdom/browser/not-implemented.js:12:26)
  at navigateFetch (node_modules/jsdom/lib/jsdom/living/window/navigation.js:77:3)
  at exports.navigate (node_modules/jsdom/lib/jsdom/living/window/navigation.js:55:3)
  at LocationImpl._locationObjectNavigate (node_modules/jsdom/lib/jsdom/living/window/Location-impl.js:30:5)
  at LocationImpl._locationObjectSetterNavigate (node_modules/jsdom/lib/jsdom/living/window/Location-impl.js:24:17)
  at set href [as href] (node_modules/jsdom/lib/jsdom/living/window/Location-impl.js:46:10)
  at set href [as href] (node_modules/jsdom/lib/jsdom/living/generated/Location.js:125:37)
  at src/lib/api-client.ts:3543:32
  at async Object.<anonymous> (src/lib/__tests__/api-client.test.ts:502:13)

console.error
Erro ao renovar token: Error: Network error
at Object. (/home/runner/work/connfit/connfit/src/lib/tests/api-client.test.ts:527:55)
at Promise.then.completed (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:298:28)
at new Promise ()
at callAsyncCircusFn (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:231:10)
at _callCircusTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:316:40)
at async _runTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:252:3)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:126:9)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:121:9)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:121:9)
at async run (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:71:3)
at async runAndTransformResultsToJestFormat (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
at async jestAdapter (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
at async runTestInternal (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:367:16)
at async runTest (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:444:34)

  at src/lib/api-client.ts:3553:15
  at async Object.<anonymous> (src/lib/__tests__/api-client.test.ts:535:13)

console.error
Error: Not implemented: navigation (except hash changes)
at (src/lib/api-client.ts:3563:30)
at async Object. (src/lib/tests/api-client.test.ts:535:13) {
type: 'not implemented'
}

  at VirtualConsole.<anonymous> (node_modules/@jest/environment-jsdom-abstract/build/index.js:87:23)
  at module.exports (node_modules/jsdom/lib/jsdom/browser/not-implemented.js:12:26)
  at navigateFetch (node_modules/jsdom/lib/jsdom/living/window/navigation.js:77:3)
  at exports.navigate (node_modules/jsdom/lib/jsdom/living/window/navigation.js:55:3)
  at LocationImpl._locationObjectNavigate (node_modules/jsdom/lib/jsdom/living/window/Location-impl.js:30:5)
  at LocationImpl._locationObjectSetterNavigate (node_modules/jsdom/lib/jsdom/living/window/Location-impl.js:24:17)
  at set href [as href] (node_modules/jsdom/lib/jsdom/living/window/Location-impl.js:46:10)
  at set href [as href] (node_modules/jsdom/lib/jsdom/living/generated/Location.js:125:37)
  at src/lib/api-client.ts:3563:30
  at async Object.<anonymous> (src/lib/__tests__/api-client.test.ts:535:13)

PASS src/lib/tests/api-client.test.ts
🔒 api-client interceptors
📋 Request Interceptor
✓ deve injetar *** quando ha sessao ativa (2 ms)
✓ nao deve enviar o header X-API-Key em nenhuma requisicao (1 ms)
✓ deve enviar x-public-request-api-key quando REQUEST_API_KEY_FOR_PUBLIC_ROUTES esta definido (1 ms)
✓ nao deve enviar x-public-request-api-key quando REQUEST_API_KEY_FOR_PUBLIC_ROUTES nao esta definido (2 ms)
✓ nao deve enviar Authorization header quando nao ha sessao (1 ms)
✓ nao deve enviar Authorization header quando getSession retorna erro (2 ms)
✓ deve usar token em cache quando valido (1 ms)
✓ deve usar manualToken quando definido via setManualToken (1 ms)
🔄 Response Interceptor
✓ deve retornar response normalmente em caso de sucesso (1 ms)
✓ deve limpar token em cache quando recebe 401 (16 ms)
✓ deve redirecionar para /auth em caso de 401 apos falha de refresh (8 ms)
✓ deve redirecionar para /auth quando refresh retorna sessao sem token (7 ms)
✓ deve redirecionar para /auth quando refreshSession lanca excecao (21 ms)
✓ nao deve tentar refresh quando _retry ja e true (1 ms)
✓ nao deve tentar refresh quando ha manualToken definido (2 ms)
✓ deve rejeitar erros que nao sao 401 sem tentar refresh (1 ms)
🛡️ Seguranca - X-API-Key nunca e enviado
✓ nao deve enviar X-API-Key mesmo com CONNFIT_API_KEY definido (1 ms)
✓ nao deve enviar X-API-Key mesmo com NEXT_PUBLIC_CONNFIT_API_KEY definido (2 ms)
✓ nao deve enviar X-API-Key mesmo com ambas env vars definidas (2 ms)
🔧 Funcoes utilitarias de token
✓ clearCachedToken deve invalidar token em cache (1 ms)
✓ getTokenInfo deve retornar informacoes corretas do token (1 ms)

console.log
[Stripe] Setup inicial via checkout: 30 dias adicionados.

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:223:29)

console.log
[Supabase] Subscription atualizada: {"status":"active","plan":"price_1test_price","stripe_subscription_id":"sub_test_subscription_456","trial_end":null,"current_period_end":"2026-07-09T17:32:39.080Z","updated_at":"2026-06-09T17:32:39.080Z"}

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:313:21)

console.log
[Stripe] Setup inicial via checkout: 365 dias adicionados.

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:223:29)

console.log
[Supabase] Subscription atualizada: {"status":"active","plan":"price_1test_price_promo","stripe_subscription_id":"sub_test_subscription_promo","trial_end":null,"current_period_end":"9999-12-31T23:59:59.999Z","updated_at":"2026-06-09T17:32:39.084Z"}

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:313:21)

console.log
[Stripe] Setup já realizado via invoice. Pulando update no checkout.

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:196:33)

console.log
[Stripe] Pagamento sucedido. Período até: 2026-07-09T17:32:39.000Z

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:275:29)

console.log
[Supabase] Subscription atualizada: {"status":"active","current_period_end":"2026-07-09T17:32:39.000Z","updated_at":"2026-06-09T17:32:39.092Z"}

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:313:21)

console.log
[Stripe] Subscription cancelada. Pulando pagamento.

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:261:33)

console.log
[Stripe] Pagamento sucedido. Período até: 2026-07-09T17:32:39.000Z

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:275:29)

console.log
[Supabase] Subscription atualizada: {"status":"active","current_period_end":"2026-07-09T17:32:39.000Z","updated_at":"2026-06-09T17:32:39.101Z"}

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:313:21)

console.log
[Stripe] Pagamento falhou. Status: past_due

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:293:29)

console.log
[Supabase] Subscription atualizada: {"status":"past_due","updated_at":"2026-06-09T17:32:39.103Z"}

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:313:21)

console.log
[Stripe] Subscription cancelada: sub_test_subscription_456

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:243:29)

console.log
[Supabase] Subscription atualizada: {"status":"canceled","cancel_at_period_end":"2026-06-16T17:32:39.000Z","current_period_end":"2026-07-09T17:32:39.000Z","updated_at":"2026-06-09T17:32:39.106Z"}

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:313:21)

console.log
[Stripe] Subscription cancelada: sub_test_subscription_456

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:243:29)

console.log
[Supabase] Subscription atualizada: {"status":"canceled","cancel_at_period_end":"2026-06-16T17:32:39.000Z","current_period_end":"2026-07-09T17:32:39.000Z","updated_at":"2026-06-09T17:32:39.108Z"}

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:313:21)

console.log
[Stripe] Evento ignorado: unknown.event.type

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:297:25)

console.log
[Stripe] Setup inicial via checkout: 30 dias adicionados.

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:223:29)

console.log
[Supabase] Subscription atualizada: {"status":"active","plan":"price_1test_price","stripe_subscription_id":"sub_object_subscription_789","trial_end":null,"current_period_end":"2026-07-09T17:32:39.113Z","updated_at":"2026-06-09T17:32:39.113Z"}

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:313:21)

console.log
[Stripe] Setup inicial via checkout: 30 dias adicionados.

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:223:29)

console.log
[Supabase] Subscription atualizada: {"status":"active","plan":"price_1test_price","stripe_subscription_id":"sub_test_subscription_456","trial_end":null,"current_period_end":"2026-07-09T17:32:39.115Z","updated_at":"2026-06-09T17:32:39.115Z"}

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:313:21)

console.log
[Stripe] Setup já realizado via invoice. Pulando update no checkout.

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:196:33)

console.log
[Stripe] Subscription cancelada. Pulando pagamento.

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:261:33)

console.log
[Stripe] Setup inicial via checkout: 30 dias adicionados.

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:223:29)

console.log
[Supabase] Subscription atualizada: {"status":"active","plan":"price_1test_price","stripe_subscription_id":"sub_test_subscription_456","trial_end":null,"current_period_end":"2026-07-09T17:32:39.119Z","updated_at":"2026-06-09T17:32:39.119Z"}

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:313:21)

console.log
[Stripe] Setup inicial via checkout: 90 dias adicionados.

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:223:29)

console.log
[Supabase] Subscription atualizada: {"status":"active","plan":"price_1test_price","stripe_subscription_id":"sub_test_subscription_456","trial_end":null,"current_period_end":"2026-09-07T17:32:39.122Z","updated_at":"2026-06-09T17:32:39.122Z"}

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:313:21)

console.log
[Stripe] Setup inicial via checkout: 30 dias adicionados.

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:223:29)

console.log
[Supabase] Subscription atualizada: {"status":"active","plan":"price_1test_price","stripe_subscription_id":"sub_test_subscription_456","trial_end":null,"current_period_end":"2026-07-09T17:32:39.124Z","updated_at":"2026-06-09T17:32:39.124Z"}

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:313:21)

console.log
[Stripe] Pagamento sucedido. Período até: 2026-07-09T17:32:39.000Z

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:275:29)

console.log
[Supabase] Subscription atualizada: {"status":"active","current_period_end":"2026-07-09T17:32:39.000Z","updated_at":"2026-06-09T17:32:39.141Z"}

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:313:21)

console.log
[Stripe] Subscription cancelada: sub_test_subscription_456

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:243:29)

console.log
[Supabase] Subscription atualizada: {"status":"canceled","cancel_at_period_end":"2026-06-16T17:32:39.000Z","current_period_end":"2026-07-09T17:32:39.000Z","updated_at":"2026-06-09T17:32:39.144Z"}

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:313:21)

console.log
[Stripe] Pagamento falhou. Status: past_due

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:293:29)

console.log
[Supabase] Subscription atualizada: {"status":"past_due","updated_at":"2026-06-09T17:32:39.146Z"}

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:313:21)

console.log
[Stripe] Evento ignorado: unknown.event.type

  at StripeWebhookTester.processWebhook (src/utils/__tests__/stripe-webhook-comprehensive.test.ts:297:25)

PASS src/utils/tests/stripe-webhook-comprehensive.test.ts
🔔 Stripe Webhook Handler - Testes Abrangentes
📋 checkout.session.completed
✓ ✅ deve processar checkout inicial com sucesso (4 ms)
✓ 🎁 deve processar checkout com código promocional especial (3 ms)
✓ 🚫 deve pular checkout se subscription já tem stripe_subscription_id (2 ms)
✓ ❌ deve retornar erro se não houver userId na metadata (1 ms)
✓ ⚠️ deve retornar erro se não houver subscription ID (1 ms)
💰 invoice.payment_succeeded
✓ ✅ deve processar pagamento de fatura com sucesso (6 ms)
✓ 🚫 deve pular pagamento se subscription estiver cancelada (3 ms)
✓ 📅 deve calcular período corretamente a partir da fatura (3 ms)
❌ invoice.payment_failed
✓ ⚠️ deve processar falha de pagamento (2 ms)
🗑️ customer.subscription.deleted
✓ 🚫 deve processar cancelamento de subscription (3 ms)
✓ 📅 deve calcular datas de cancelamento corretamente (2 ms)
🔒 Validações de Segurança e Edge Cases
✓ 🚫 deve ignorar eventos sem customer ID (1 ms)
✓ ❓ deve ignorar eventos desconhecidos (1 ms)
✓ 📊 deve funcionar com subscription ID como objeto (2 ms)
🔄 Prevenção de Duplicidade
✓ 🛡️ deve evitar processar o mesmo evento duas vezes (checkout) (3 ms)
✓ 🛡️ deve evitar processamento quando subscription cancelada (invoice) (2 ms)
⏰ Cálculos de Tempo
✓ 📅 deve calcular período de 30 dias por padrão (2 ms)
✓ 📅 deve usar dias customizados da metadata (2 ms)
🗄️ Lógica de Query do Banco (TDD Fiel ao Código Original)
✓ 📋 checkout.session.completed deve usar user_id para busca (3 ms)
✓ 💰 invoice.payment_succeeded deve usar customer_id + subscription_id (17 ms)
✓ 🗑️ customer.subscription.deleted deve usar customer_id + subscription_id (3 ms)
✓ ❌ invoice.payment_failed deve usar customer_id + subscription_id (2 ms)
✓ 🔄 deve validar que só atualiza se houver mudanças E subscription existir (2 ms)
✓ 🛡️ deve validar condição: Object.keys(updates).length > 0 && subscription (1 ms)

console.error
An update to MedicalInsights inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at src/components/medical-record/medical-insights.tsx:2191:11

console.error
An update to MedicalInsights inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at src/components/medical-record/medical-insights.tsx:2245:7

console.error
An update to MedicalInsights inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at src/hooks/use-debounce.ts:327:7
  at callTimer (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:806:24)
  at doTickInner (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1413:29)
  at doTick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1494:20)
  at Object.tick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1502:20)
  at Object.runToLast (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1661:26)
  at FakeTimers.runOnlyPendingTimers (node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers/build/index.js:542:19)
  at Object.<anonymous> (src/components/medical-record/__tests__/medical-insights.test.tsx:147:14)

console.error
An update to MedicalInsights inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at src/components/medical-record/medical-insights.tsx:2191:11

console.error
An update to MedicalInsights inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at src/components/medical-record/medical-insights.tsx:2245:7

console.error
An update to MedicalInsights inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at src/hooks/use-debounce.ts:327:7
  at callTimer (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:806:24)
  at doTickInner (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1413:29)
  at doTick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1494:20)
  at Object.tick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1502:20)
  at Object.runToLast (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1661:26)
  at FakeTimers.runOnlyPendingTimers (node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers/build/index.js:542:19)
  at Object.<anonymous> (src/components/medical-record/__tests__/medical-insights.test.tsx:147:14)

console.error
An update to MedicalInsights inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at src/hooks/use-debounce.ts:327:7
  at callTimer (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:806:24)
  at doTickInner (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1413:29)
  at doTick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1494:20)
  at Object.tick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1502:20)
  at Object.runToLast (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1661:26)
  at FakeTimers.runOnlyPendingTimers (node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers/build/index.js:542:19)
  at Object.<anonymous> (src/components/medical-record/__tests__/medical-insights.test.tsx:147:14)

console.error
An update to MedicalInsights inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at src/hooks/use-debounce.ts:327:7
  at callTimer (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:806:24)
  at doTickInner (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1413:29)
  at doTick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1494:20)
  at Object.tick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1502:20)
  at Object.runToLast (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1661:26)
  at FakeTimers.runOnlyPendingTimers (node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers/build/index.js:542:19)
  at Object.<anonymous> (src/components/medical-record/__tests__/medical-insights.test.tsx:147:14)

console.error
Erro de conexão com a IA

  at src/components/medical-record/medical-insights.tsx:2175:17

console.error
An update to MedicalInsights inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at src/hooks/use-debounce.ts:327:7
  at callTimer (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:806:24)
  at doTickInner (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1413:29)
  at doTick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1494:20)
  at Object.tick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1502:20)
  at Object.runToLast (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1661:26)
  at FakeTimers.runOnlyPendingTimers (node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers/build/index.js:542:19)
  at Object.<anonymous> (src/components/medical-record/__tests__/medical-insights.test.tsx:147:14)

console.error
Erro ao gerar insights: Error: Network timeout
at Object. (/home/runner/work/connfit/connfit/src/components/medical-record/tests/medical-insights.test.tsx:519:46)
at Promise.then.completed (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:298:28)
at new Promise ()
at callAsyncCircusFn (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:231:10)
at _callCircusTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:316:40)
at async _runTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:252:3)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:126:9)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:121:9)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:121:9)
at async run (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:71:3)
at async runAndTransformResultsToJestFormat (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
at async jestAdapter (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
at async runTestInternal (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:367:16)
at async runTest (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:444:34)

  at src/components/medical-record/medical-insights.tsx:2235:15

console.error
An update to MedicalInsights inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at src/hooks/use-debounce.ts:327:7
  at callTimer (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:806:24)
  at doTickInner (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1413:29)
  at doTick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1494:20)
  at Object.tick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1502:20)
  at Object.runToLast (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1661:26)
  at FakeTimers.runOnlyPendingTimers (node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers/build/index.js:542:19)
  at Object.<anonymous> (src/components/medical-record/__tests__/medical-insights.test.tsx:147:14)

console.error
Erro temporário

  at src/components/medical-record/medical-insights.tsx:2175:17

console.error
An update to MedicalInsights inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at src/hooks/use-debounce.ts:327:7
  at callTimer (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:806:24)
  at doTickInner (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1413:29)
  at doTick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1494:20)
  at Object.tick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1502:20)
  at Object.runToLast (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1661:26)
  at FakeTimers.runOnlyPendingTimers (node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers/build/index.js:542:19)
  at Object.<anonymous> (src/components/medical-record/__tests__/medical-insights.test.tsx:147:14)

console.error
An update to MedicalInsights inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at src/hooks/use-debounce.ts:327:7
  at callTimer (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:806:24)
  at doTickInner (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1413:29)
  at doTick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1494:20)
  at Object.tick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1502:20)
  at Object.runToLast (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1661:26)
  at FakeTimers.runOnlyPendingTimers (node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers/build/index.js:542:19)
  at Object.<anonymous> (src/components/medical-record/__tests__/medical-insights.test.tsx:147:14)

console.error
An update to MedicalInsights inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at src/hooks/use-debounce.ts:327:7
  at callTimer (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:806:24)
  at doTickInner (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1413:29)
  at doTick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1494:20)
  at Object.tick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1502:20)
  at Object.runToLast (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1661:26)
  at FakeTimers.runOnlyPendingTimers (node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers/build/index.js:542:19)
  at Object.<anonymous> (src/components/medical-record/__tests__/medical-insights.test.tsx:147:14)

PASS src/components/medical-record/tests/medical-insights.test.tsx
🧩 MedicalInsights
Renderização inicial
✓ deve exibir o cabeçalho "Insights Clínicos" (43 ms)
✓ deve exibir botão "Analisar" quando não há insights (71 ms)
✓ deve exibir botão "Reanalisar" quando já há insights (32 ms)
✓ deve exibir insights existentes imediatamente sem chamar a API (16 ms)
Geração automática no primeiro carregamento
✓ deve gerar insights automaticamente quando não há initialInsights e o conteúdo é suficiente (27 ms)
✓ deve salvar os insights após gerá-los quando há recordId (19 ms)
✓ deve exibir toast de sucesso após salvar insights (23 ms)
✓ deve chamar onInsightsSaved após salvar com sucesso (23 ms)
✓ não deve gerar insights quando conteúdo tem <= 20 caracteres (8 ms)
✓ não deve gerar insights quando conteúdo está vazio (7 ms)
Com initialInsights existentes
✓ não deve chamar generateMedicalInsights ao montar com insights existentes (21 ms)
✓ deve re-analisar quando o conteúdo muda após montagem com insights existentes (47 ms)
Botão de análise manual
✓ deve chamar generateMedicalInsights ao clicar em "Reanalisar" com insights existentes (44 ms)
✓ deve chamar generateMedicalInsights ao clicar em "Analisar" após análise automática concluída (78 ms)
✓ deve desabilitar o botão quando o conteúdo é insuficiente (15 ms)
✓ deve desabilitar o botão quando o conteúdo está vazio (12 ms)
✓ deve desabilitar o botão durante análise (63 ms)
Tratamento de erros
✓ deve exibir toast de erro quando a API retorna erro (41 ms)
✓ deve exibir toast de erro quando a API lança exceção (33 ms)
✓ deve permitir nova tentativa após erro (não bloqueia re-análise) (45 ms)
✓ deve exibir toast de aviso quando insights gerados mas não salvos (30 ms)
Exibição dos insights
✓ deve exibir as possíveis causas após análise bem-sucedida (62 ms)
✓ deve exibir os exames recomendados após análise automática (17 ms)
✓ deve exibir as recomendações após análise automática (21 ms)
✓ deve exibir o resumo da análise (33 ms)
✓ deve exibir estado "Nenhuma análise realizada" quando conteúdo é insuficiente (6 ms)
Sem recordId (prontuário novo)
✓ deve gerar insights sem salvar quando não há recordId (14 ms)
✓ deve exibir toast de sucesso sem mencionar salvamento quando não há recordId (13 ms)

console.error
Erro inesperado ao buscar planos alimentares: Error: Network error
at Object. (/home/runner/work/connfit/connfit/src/actions/tests/meals.test.ts:125:57)
at Promise.then.completed (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:298:28)
at new Promise ()
at callAsyncCircusFn (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:231:10)
at _callCircusTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:316:40)
at async _runTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:252:3)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:126:9)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:121:9)
at async run (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:71:3)
at async runAndTransformResultsToJestFormat (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
at async jestAdapter (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
at async runTestInternal (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:367:16)
at async runTest (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:444:34)

  at getMealPlans (src/actions/meals.ts:3477:13)
  at async Object.<anonymous> (src/actions/__tests__/meals.test.ts:111:24)

console.error
Erro inesperado ao criar plano alimentar: Error: Server error
at Object. (/home/runner/work/connfit/connfit/src/actions/tests/meals.test.ts:188:59)
at Promise.then.completed (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:298:28)
at new Promise ()
at callAsyncCircusFn (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:231:10)
at _callCircusTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:316:40)
at async _runTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:252:3)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:126:9)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:121:9)
at async run (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:71:3)
at async runAndTransformResultsToJestFormat (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
at async jestAdapter (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
at async runTestInternal (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:367:16)
at async runTest (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:444:34)

  at createMealPlan (src/actions/meals.ts:3428:13)
  at async Object.<anonymous> (src/actions/__tests__/meals.test.ts:168:24)

console.error
Erro inesperado ao deletar plano: Error: DB error
at Object. (/home/runner/work/connfit/connfit/src/actions/tests/meals.test.ts:227:59)
at Promise.then.completed (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:298:28)
at new Promise ()
at callAsyncCircusFn (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:231:10)
at _callCircusTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:316:40)
at async _runTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:252:3)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:126:9)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:121:9)
at async run (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:71:3)
at async runAndTransformResultsToJestFormat (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
at async jestAdapter (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
at async runTestInternal (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:367:16)
at async runTest (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:444:34)

  at deleteMealPlan (src/actions/meals.ts:3670:13)
  at async Object.<anonymous> (src/actions/__tests__/meals.test.ts:201:24)

console.error
Erro inesperado ao buscar alimentos: Error: Timeout
at Object. (/home/runner/work/connfit/connfit/src/actions/tests/meals.test.ts:323:59)
at Promise.then.completed (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:298:28)
at new Promise ()
at callAsyncCircusFn (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:231:10)
at _callCircusTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:316:40)
at async _runTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:252:3)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:126:9)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:121:9)
at async run (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:71:3)
at async runAndTransformResultsToJestFormat (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
at async jestAdapter (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
at async runTestInternal (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:367:16)
at async runTest (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:444:34)

  at searchFoodItems (src/actions/meals.ts:4061:13)
  at async Object.<anonymous> (src/actions/__tests__/meals.test.ts:282:24)

console.error
Erro inesperado ao duplicar plano: Error: Server error
at Object. (/home/runner/work/connfit/connfit/src/actions/tests/meals.test.ts:387:62)
at Promise.then.completed (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:298:28)
at new Promise ()
at callAsyncCircusFn (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:231:10)
at _callCircusTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:316:40)
at async _runTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:252:3)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:126:9)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:121:9)
at async run (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:71:3)
at async runAndTransformResultsToJestFormat (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
at async jestAdapter (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
at async runTestInternal (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:367:16)
at async runTest (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:444:34)

  at duplicateMealPlan (src/actions/meals.ts:3714:13)
  at async Object.<anonymous> (src/actions/__tests__/meals.test.ts:336:24)

console.error
Erro ao recalcular totais: Error: Timeout
at Object. (/home/runner/work/connfit/connfit/src/actions/tests/meals.test.ts:698:64)
at Promise.then.completed (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:298:28)
at new Promise ()
at callAsyncCircusFn (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:231:10)
at _callCircusTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:316:40)
at async _runTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:252:3)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:126:9)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:121:9)
at async run (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:71:3)
at async runAndTransformResultsToJestFormat (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
at async jestAdapter (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
at async runTestInternal (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:367:16)
at async runTest (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:444:34)

  at recalculatePlanTotals (src/actions/meals.ts:4101:13)
  at async Object.<anonymous> (src/actions/__tests__/meals.test.ts:654:24)

PASS src/actions/tests/meals.test.ts
🍽️ getMealPlans
✓ deve retornar { success: true, data: [...] } quando a API responde com sucesso (2 ms)
✓ deve retornar { success: false, data: [] } quando a API retorna erro (2 ms)
✓ deve retornar { success: false, data: [] } quando a API lanca excecao (7 ms)
✓ deve retornar data: [] quando a API retorna data undefined (1 ms)
📝 createMealPlan
✓ deve retornar sucesso e chamar revalidatePath ao criar plano (2 ms)
✓ deve retornar erro quando a API retorna error (2 ms)
✓ deve retornar erro quando a API lanca excecao (3 ms)
🗑️ deleteMealPlan
✓ deve retornar sucesso e chamar revalidatePath ao deletar plano (2 ms)
✓ deve retornar erro quando a API retorna error (1 ms)
✓ deve retornar erro quando a API lanca excecao (2 ms)
🔍 searchFoodItems
✓ deve retornar [] quando query tem menos de 2 caracteres (1 ms)
✓ deve retornar [] quando query e string vazia (7 ms)
✓ deve retornar [] quando query e apenas espacos (1 ms)
✓ deve buscar alimentos quando query tem 2 ou mais caracteres (1 ms)
✓ deve retornar erro quando a API retorna error (1 ms)
✓ deve retornar erro quando a API lanca excecao (3 ms)
✓ deve retornar data: [] quando a API retorna data undefined (1 ms)
📋 duplicateMealPlan
✓ deve duplicar plano com sucesso e chamar revalidatePath (2 ms)
✓ deve retornar erro quando a API retorna error (1 ms)
✓ deve retornar erro quando a API lanca excecao (3 ms)
✏️ updateMealPlan
✓ deve atualizar plano com sucesso e chamar revalidatePath (1 ms)
✓ deve retornar erro quando a API retorna error (1 ms)
🍴 addMealToPlan
✓ deve adicionar refeicao ao plano com sucesso (2 ms)
✓ deve enviar description null quando nao fornecida (1 ms)
🔄 updateMeal
✓ deve atualizar refeicao com sucesso (1 ms)
🚫 removeMealFromPlan
✓ deve remover refeicao do plano com sucesso (2 ms)
✓ deve retornar erro quando a API retorna error (1 ms)
➕ addMealItem
✓ deve adicionar item a refeicao com sucesso (2 ms)
✏️ updateMealItem
✓ deve atualizar item com sucesso (1 ms)
🗑️ removeMealItem
✓ deve remover item com sucesso (1 ms)
📊 getMealPlanWithMeals
✓ deve retornar plano com refeicoes transformadas corretamente (1 ms)
✓ deve filtrar entries sem meal (1 ms)
✓ deve retornar erro quando a API retorna error
📈 recalculatePlanTotals
✓ deve recalcular totais com sucesso (1 ms)
✓ deve retornar erro quando a API retorna error (1 ms)
✓ deve retornar erro quando a API lanca excecao (7 ms)

PASS src/tests/patient-form-utils.test.ts
Patient Form Utils
patientFormSchema
✓ deve validar nome com mínimo 2 caracteres (2 ms)
✓ deve validar email válido (1 ms)
✓ deve aceitar email válido
✓ deve validar telefone com mínimo 10 dígitos
✓ deve aceitar telefone válido (1 ms)
✓ deve aceitar telefone formatado (1 ms)
✓ deve validar idade máxima de 99 anos (1 ms)
✓ deve aceitar todos os objetivos válidos (1 ms)
✓ deve aceitar todos os tipos sanguíneos válidos (2 ms)
✓ deve aceitar peso e altura positivos (1 ms)
✓ deve rejeitar peso negativo (1 ms)
✓ deve aceitar campos nullable como null (1 ms)
patientToFormValues
✓ deve converter Patient para FormValues corretamente (3 ms)
✓ deve converter arrays para texto separado por vírgula (1 ms)
✓ deve lidar com arrays vazios (1 ms)
✓ deve lidar com campos null (1 ms)
formValuesToPatient
✓ deve converter FormValues para Patient corretamente (2 ms)
✓ deve converter texto separado por vírgula em arrays
✓ deve remover espaços extras ao converter texto em arrays
✓ deve converter strings vazias em null para arrays (1 ms)
✓ deve manter dados originais ao atualizar (1 ms)
defaultPatientFormValues
✓ deve ter valores padrão corretos (1 ms)
✓ deve ser válido segundo o schema (apenas campos obrigatórios) (1 ms)
Conversão bidirecional
✓ deve manter dados após conversão Patient -> Form -> Patient (7 ms)

console.error
An update to TestComponent inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at updateElapsedTime (src/hooks/use-medical-record-page.ts:1589:7)
  at callTimer (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:806:24)
  at doTickInner (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1413:29)
  at doTick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1494:20)
  at Object.tick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1502:20)
  at Object.runToLast (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1661:26)
  at FakeTimers.runOnlyPendingTimers (node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers/build/index.js:542:19)
  at Object.<anonymous> (src/hooks/__tests__/use-medical-record-page.test.tsx:94:14)

console.error
An update to TestComponent inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at updateElapsedTime (src/hooks/use-medical-record-page.ts:1589:7)
  at callTimer (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:806:24)
  at doTickInner (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1413:29)
  at doTick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1494:20)
  at Object.tick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1502:20)
  at Object.runToLast (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1661:26)
  at FakeTimers.runOnlyPendingTimers (node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers/build/index.js:542:19)
  at Object.<anonymous> (src/hooks/__tests__/use-medical-record-page.test.tsx:94:14)

console.error
An update to TestComponent inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at updateElapsedTime (src/hooks/use-medical-record-page.ts:1589:7)
  at callTimer (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:806:24)
  at doTickInner (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1413:29)
  at doTick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1494:20)
  at Object.tick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1502:20)
  at Object.runToLast (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1661:26)
  at FakeTimers.runOnlyPendingTimers (node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers/build/index.js:542:19)
  at Object.<anonymous> (src/hooks/__tests__/use-medical-record-page.test.tsx:94:14)

console.error
An update to TestComponent inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at updateElapsedTime (src/hooks/use-medical-record-page.ts:1589:7)
  at callTimer (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:806:24)
  at doTickInner (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1413:29)
  at doTick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1494:20)
  at Object.tick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1502:20)
  at Object.runToLast (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1661:26)
  at FakeTimers.runOnlyPendingTimers (node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers/build/index.js:542:19)
  at Object.<anonymous> (src/hooks/__tests__/use-medical-record-page.test.tsx:94:14)

console.error
An update to TestComponent inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at updateElapsedTime (src/hooks/use-medical-record-page.ts:1589:7)
  at callTimer (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:806:24)
  at doTickInner (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1413:29)
  at doTick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1494:20)
  at Object.tick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1502:20)
  at Object.runToLast (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1661:26)
  at FakeTimers.runOnlyPendingTimers (node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers/build/index.js:542:19)
  at Object.<anonymous> (src/hooks/__tests__/use-medical-record-page.test.tsx:94:14)

console.error
An update to TestComponent inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at updateElapsedTime (src/hooks/use-medical-record-page.ts:1589:7)
  at callTimer (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:806:24)
  at doTickInner (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1413:29)
  at doTick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1494:20)
  at Object.tick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1502:20)
  at Object.runToLast (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1661:26)
  at FakeTimers.runOnlyPendingTimers (node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers/build/index.js:542:19)
  at Object.<anonymous> (src/hooks/__tests__/use-medical-record-page.test.tsx:94:14)

console.error
An update to TestComponent inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at updateElapsedTime (src/hooks/use-medical-record-page.ts:1589:7)
  at callTimer (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:806:24)
  at doTickInner (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1413:29)
  at doTick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1494:20)
  at Object.tick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1502:20)
  at Object.runToLast (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1661:26)
  at FakeTimers.runOnlyPendingTimers (node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers/build/index.js:542:19)
  at Object.<anonymous> (src/hooks/__tests__/use-medical-record-page.test.tsx:94:14)

console.error
An update to TestComponent inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at updateElapsedTime (src/hooks/use-medical-record-page.ts:1589:7)
  at callTimer (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:806:24)
  at doTickInner (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1413:29)
  at doTick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1494:20)
  at Object.tick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1502:20)
  at Object.runToLast (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1661:26)
  at FakeTimers.runOnlyPendingTimers (node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers/build/index.js:542:19)
  at Object.<anonymous> (src/hooks/__tests__/use-medical-record-page.test.tsx:94:14)

console.error
An update to TestComponent inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at updateElapsedTime (src/hooks/use-medical-record-page.ts:1589:7)
  at callTimer (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:806:24)
  at doTickInner (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1413:29)
  at doTick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1494:20)
  at Object.tick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1502:20)
  at Object.runToLast (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1661:26)
  at FakeTimers.runOnlyPendingTimers (node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers/build/index.js:542:19)
  at Object.<anonymous> (src/hooks/__tests__/use-medical-record-page.test.tsx:94:14)

console.error
An update to TestComponent inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at updateElapsedTime (src/hooks/use-medical-record-page.ts:1589:7)
  at callTimer (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:806:24)
  at doTickInner (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1413:29)
  at doTick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1494:20)
  at Object.tick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1502:20)
  at Object.runToLast (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1661:26)
  at FakeTimers.runOnlyPendingTimers (node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers/build/index.js:542:19)
  at Object.<anonymous> (src/hooks/__tests__/use-medical-record-page.test.tsx:94:14)

console.error
An update to TestComponent inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at updateElapsedTime (src/hooks/use-medical-record-page.ts:1589:7)
  at callTimer (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:806:24)
  at doTickInner (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1413:29)
  at doTick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1494:20)
  at Object.tick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1502:20)
  at Object.runToLast (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1661:26)
  at FakeTimers.runOnlyPendingTimers (node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers/build/index.js:542:19)
  at Object.<anonymous> (src/hooks/__tests__/use-medical-record-page.test.tsx:94:14)

console.error
An update to TestComponent inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at updateElapsedTime (src/hooks/use-medical-record-page.ts:1589:7)
  at callTimer (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:806:24)
  at doTickInner (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1413:29)
  at doTick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1494:20)
  at Object.tick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1502:20)
  at Object.runToLast (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1661:26)
  at FakeTimers.runOnlyPendingTimers (node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers/build/index.js:542:19)
  at Object.<anonymous> (src/hooks/__tests__/use-medical-record-page.test.tsx:94:14)

console.error
An update to TestComponent inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at updateElapsedTime (src/hooks/use-medical-record-page.ts:1589:7)
  at callTimer (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:806:24)
  at doTickInner (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1413:29)
  at doTick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1494:20)
  at Object.tick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1502:20)
  at Object.runToLast (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1661:26)
  at FakeTimers.runOnlyPendingTimers (node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers/build/index.js:542:19)
  at Object.<anonymous> (src/hooks/__tests__/use-medical-record-page.test.tsx:94:14)

console.error
An update to TestComponent inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at updateElapsedTime (src/hooks/use-medical-record-page.ts:1589:7)
  at callTimer (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:806:24)
  at doTickInner (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1413:29)
  at doTick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1494:20)
  at Object.tick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1502:20)
  at Object.runToLast (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1661:26)
  at FakeTimers.runOnlyPendingTimers (node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers/build/index.js:542:19)
  at Object.<anonymous> (src/hooks/__tests__/use-medical-record-page.test.tsx:94:14)

console.error
An update to TestComponent inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at updateElapsedTime (src/hooks/use-medical-record-page.ts:1589:7)
  at callTimer (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:806:24)
  at doTickInner (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1413:29)
  at doTick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1494:20)
  at Object.tick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1502:20)
  at Object.runToLast (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1661:26)
  at FakeTimers.runOnlyPendingTimers (node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers/build/index.js:542:19)
  at Object.<anonymous> (src/hooks/__tests__/use-medical-record-page.test.tsx:94:14)

console.error
An update to TestComponent inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at updateElapsedTime (src/hooks/use-medical-record-page.ts:1589:7)
  at callTimer (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:806:24)
  at doTickInner (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1413:29)
  at doTick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1494:20)
  at Object.tick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1502:20)
  at Object.runToLast (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1661:26)
  at FakeTimers.runOnlyPendingTimers (node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers/build/index.js:542:19)
  at Object.<anonymous> (src/hooks/__tests__/use-medical-record-page.test.tsx:94:14)

console.error
An update to TestComponent inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at updateElapsedTime (src/hooks/use-medical-record-page.ts:1589:7)
  at callTimer (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:806:24)
  at doTickInner (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1413:29)
  at doTick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1494:20)
  at Object.tick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1502:20)
  at Object.runToLast (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1661:26)
  at FakeTimers.runOnlyPendingTimers (node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers/build/index.js:542:19)
  at Object.<anonymous> (src/hooks/__tests__/use-medical-record-page.test.tsx:94:14)

console.error
An update to TestComponent inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at updateElapsedTime (src/hooks/use-medical-record-page.ts:1589:7)
  at callTimer (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:806:24)
  at doTickInner (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1413:29)
  at doTick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1494:20)
  at Object.tick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1502:20)
  at Object.runToLast (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1661:26)
  at FakeTimers.runOnlyPendingTimers (node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers/build/index.js:542:19)
  at Object.<anonymous> (src/hooks/__tests__/use-medical-record-page.test.tsx:94:14)

console.error
PASS src/hooks/tests/use-medical-record-page.test.tsx
An update to TestComponent inside a test was not wrapped in act(...).
🪝 useMedicalRecordPage

Estado inicial
When testing, code that causes React state updates should be wrapped into act(...):
  ✓ deve inicializar editorContent com o conteúdo do prontuário (7 ms)

  ✓ deve inicializar editorContent vazio quando não há prontuário (3 ms)
act(() => {
  ✓ deve inicializar lastSavedContent com o conteúdo do prontuário (4 ms)
  /* fire events that update state */
  ✓ deve inicializar currentRecord com o prontuário fornecido (5 ms)
});
  ✓ deve inicializar patient com o paciente fornecido (5 ms)
/* assert on the output */
  ✓ deve inicializar isFinishModalOpen como false (6 ms)

handleRecordSave
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act
  ✓ deve atualizar currentRecord ao salvar (6 ms)

  ✓ deve atualizar lastSavedContent ao salvar (6 ms)

  ✓ não deve resetar editorContent ao salvar (bug #178 — useEffect removido) (12 ms)

handleInsightsSaved
  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  ✓ deve chamar getMedicalRecord para recarregar o prontuário após salvar insights (7 ms)
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  ✓ deve atualizar currentRecord com os insights após recarregar (5 ms)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  ✓ não deve lançar erro quando currentRecord não tem id (4 ms)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  ✓ deve tratar erro silenciosamente quando getMedicalRecord falha (4 ms)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  ✓ não deve resetar editorContent após handleInsightsSaved (bug #178) (8 ms)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
handleSuggestionClick
  at updateElapsedTime (src/hooks/use-medical-record-page.ts:1589:7)
  ✓ deve adicionar a sugestão ao conteúdo do editor (6 ms)
  at callTimer (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:806:24)
  ✓ deve adicionar a categoria da sugestão ao conteúdo (6 ms)
  at doTickInner (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1413:29)
  ✓ deve exibir toast de sucesso ao adicionar sugestão (5 ms)
  at doTick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1494:20)
  ✓ deve iniciar o conteúdo com a sugestão quando editor está vazio (4 ms)
  at Object.tick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1502:20)
handlePatientUpdate
  at Object.runToLast (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1661:26)
  ✓ deve atualizar os dados do paciente ao chamar handlePatientUpdate (11 ms)
  at FakeTimers.runOnlyPendingTimers (node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers/build/index.js:542:19)
  ✓ deve tratar erro silenciosamente quando fetchPatientById falha (4 ms)
  at Object.<anonymous> (src/hooks/__tests__/use-medical-record-page.test.tsx:94:14)
handleFinishAppointment

  ✓ deve abrir o modal quando há appointmentId (5 ms)

console.error
✓ deve exibir toast de erro quando não há appointmentId (6 ms)
An update to TestComponent inside a test was not wrapped in act(...).
✓ deve fechar o modal ao chamar closeFinishModal (7 ms)

setEditorContent
When testing, code that causes React state updates should be wrapped into act(...):
  ✓ deve atualizar editorContent ao chamar setEditorContent (5 ms)

Timer de consulta (elapsedTime)
act(() => {
  ✓ deve inicializar elapsedTime como 00:00:00 (6 ms)
  /* fire events that update state */
  ✓ deve incrementar elapsedTime a cada segundo quando há appointmentId (6 ms)
});

/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at updateElapsedTime (src/hooks/use-medical-record-page.ts:1589:7)
  at callTimer (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:806:24)
  at doTickInner (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1413:29)
  at doTick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1494:20)
  at Object.tick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1502:20)
  at Object.runToLast (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1661:26)
  at FakeTimers.runOnlyPendingTimers (node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers/build/index.js:542:19)
  at Object.<anonymous> (src/hooks/__tests__/use-medical-record-page.test.tsx:94:14)

console.error
An update to TestComponent inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act



  at node_modules/react-dom/cjs/react-dom-client.development.js:18758:19
  at runWithFiberInDEV (node_modules/react-dom/cjs/react-dom-client.development.js:874:13)
  at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom-client.development.js:18757:9)
  at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom-client.development.js:16409:11)
  at dispatchSetStateInternal (node_modules/react-dom/cjs/react-dom-client.development.js:9170:13)
  at dispatchSetState (node_modules/react-dom/cjs/react-dom-client.development.js:9127:7)
  at updateElapsedTime (src/hooks/use-medical-record-page.ts:1589:7)
  at callTimer (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:806:24)
  at doTickInner (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1413:29)
  at doTick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1494:20)
  at Object.tick (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1502:20)
  at Object.runToLast (node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1661:26)
  at FakeTimers.runOnlyPendingTimers (node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers/build/index.js:542:19)
  at Object.<anonymous> (src/hooks/__tests__/use-medical-record-page.test.tsx:94:14)

console.log
Auto-migrated availability avail-1 to new format (manual fallback)

  at autoMigrateLegacyAvailability (src/actions/availability.ts:6063:13)
      at async Promise.allSettled (index 0)

console.log
Auto-migrated 1/1 availability records

  at getAvailability (src/actions/availability.ts:6542:15)

console.log
Auto-migrated availability avail-3 to new format (manual fallback)

  at autoMigrateLegacyAvailability (src/actions/availability.ts:6063:13)
      at async Promise.allSettled (index 0)

console.log
Auto-migrated 1/1 availability records

  at getAvailability (src/actions/availability.ts:6542:15)

console.log
Auto-migrated availability avail-7 to new format (manual fallback)

  at autoMigrateLegacyAvailability (src/actions/availability.ts:6063:13)
      at async Promise.all (index 0)

console.log
Auto-migrated 1 availability records for nutritionist other-nutritionist-id

  at getAvailabilityWithMigration (src/actions/availability.ts:6692:15)

console.error
Erro ao buscar disponibilidade: { message: 'Database connection error' }

  at getAvailability (src/actions/availability.ts:6432:15)
  at async Object.<anonymous> (src/__tests__/availability-auto-migration-integration.test.ts:594:28)

PASS src/tests/availability-auto-migration-integration.test.ts
Availability Auto-Migration Integration Tests
Legacy Data Auto-Migration on Read
✓ should auto-migrate legacy timeSlots on first access (4 ms)
✓ should not migrate if newTimeSlots already exists (1 ms)
✓ should handle mixed legacy and migrated data (12 ms)
Create Availability with New Format Only
✓ should create availability with only newTimeSlots (no legacy column) (2 ms)
✓ should merge with existing availability using upsert (1 ms)
Update Availability Clears Legacy Format
✓ should clear timeSlots column on update (1 ms)
GetAvailabilityWithMigration for Appointments
✓ should auto-migrate for appointment booking flow (2 ms)
Edge Cases and Error Handling
✓ should handle empty legacy timeSlots (1 ms)
✓ should handle database errors gracefully (4 ms)
Upsert Logic Analysis
✓ should prevent conflicts with upsert onConflict (1 ms)

FAIL src/tests/dynamic-availability-ranges.test.ts
Dynamic Availability - Ranges (New Format)
convertTimeSlotRangesToMinutes
✓ ✅ Deve converter ranges simples para minutos (2 ms)
✓ ✅ Deve filtrar ranges inativos
✓ ✅ Deve converter range com horários quebrados (13:30, 14:20)
✓ ✅ Deve retornar array vazio se não houver ranges ativos (1 ms)
getAvailableTimeSlotsFromRanges - Durações Não-Padrão
✓ ✅ Serviço de 50min deve caber no range 13:30-14:20 (3 ms)
✓ ✅ Serviço de 45min deve gerar múltiplos slots em range grande (1 ms)
✕ ✅ Serviço de 75min (1h15) deve respeitar limite do range (2 ms)
✓ ✅ Serviço de 60min em range quebrado (13:30-15:30) (3 ms)
✕ ✅ Serviço de 50min com múltiplos ranges (2 ms)
getAvailableTimeSlotsFromRanges - Com Consultas Existentes
✓ ✅ Deve subtrair consulta existente do meio do range (4 ms)
✓ ✅ Serviço de 50min não deve caber em gap de 45min (3 ms)
✓ ✅ Deve respeitar breakTime após consulta (2 ms)
getAvailableTimeSlotsFromRanges - Edge Cases
✓ ✅ Range exatamente do tamanho do serviço (1 ms)
✓ ✅ Range menor que duração do serviço (1 ms)
✓ ✅ Múltiplas consultas fragmentando o range (6 ms)
✓ ✅ Deve filtrar slots passados se for hoje (1 ms)
✓ ✅ Serviços de durações muito curtas (15min) (10 ms)
✕ ✅ Serviços de durações muito longas (180min = 3h) (2 ms)
🐛 Regression Test - Bug Reportado
✓ ✅ CENÁRIO EXATO DO BUG: 50min service em range 13:30-14:20 (1 ms)
✓ ✅ VALIDAÇÃO INTEGRADA: Frontend + Backend com 50min (2 ms)
✓ ✅ EDGE CASE: Serviço que cabe EXATAMENTE no range (1 ms)
✓ ✅ EDGE CASE: Serviço NÃO cabe por 1 minuto (1 ms)

● Dynamic Availability - Ranges (New Format) › getAvailableTimeSlotsFromRanges - Durações Não-Padrão › ✅ Serviço de 75min (1h15) deve respeitar limite do range

expect(received).not.toContain(expected) // indexOf

Expected value: not "15:15"
Received array:     ["14:00", "15:15"]

  120 |       // 15:15 + 75min = 16:30 ✗ (ultrapassa)
  121 |       expect(slots).toContain('14:00');
> 122 |       expect(slots).not.toContain('15:15'); // Não cabe mais
      |                         ^
  123 |       expect(slots).toHaveLength(1);
  124 |     });
  125 |

  at Object.<anonymous> (src/__tests__/dynamic-availability-ranges.test.ts:122:25)

● Dynamic Availability - Ranges (New Format) › getAvailableTimeSlotsFromRanges - Durações Não-Padrão › ✅ Serviço de 50min com múltiplos ranges

expect(received).not.toContain(expected) // indexOf

Expected value: not "15:50"
Received array:     ["08:00", "08:50", "13:30", "15:00", "15:50"]

  157 |       // Range 3: 15:00 + 50min = 15:50 ✓, 15:50 + 50min = 16:40 ✗
  158 |       expect(slots).toContain('15:00');
> 159 |       expect(slots).not.toContain('15:50'); // Não cabe
      |                         ^
  160 |
  161 |       expect(slots.length).toBeGreaterThanOrEqual(3);
  162 |     });

  at Object.<anonymous> (src/__tests__/dynamic-availability-ranges.test.ts:159:25)

● Dynamic Availability - Ranges (New Format) › getAvailableTimeSlotsFromRanges - Edge Cases › ✅ Serviços de durações muito longas (180min = 3h)

expect(received).not.toContain(expected) // indexOf

Expected value: not "17:00"
Received array:     ["08:00", "11:00", "14:00", "17:00"]

  337 |       expect(slots).toContain('11:00');
  338 |       expect(slots).toContain('14:00');
> 339 |       expect(slots).not.toContain('17:00'); // 17:00 + 180min = 20:00 (ultrapassa)
      |                         ^
  340 |       expect(slots).toHaveLength(3);
  341 |     });
  342 |   });

  at Object.<anonymous> (src/__tests__/dynamic-availability-ranges.test.ts:339:25)

LOGGING RETRY ERRORS ⚡ TESTE DE PERFORMANCE E STRESS 💥 Stress Tests ✅ Deve lidar com consultas extremamente longas
RETRY 1

expect(received).toHaveLength(expected)

Expected length: 1
Received length: 2
Received array:  ["08:00", "16:00"]

  209 |       const slots8h = getAvailableTimeSlotsUnified(timeSlots, appointments, 480, targetDate);
  210 |       expect(slots8h).toContain('08:00'); // Única que cabe
> 211 |       expect(slots8h).toHaveLength(1);
      |                       ^
  212 |
  213 |       // Consulta de 12 horas (impossível)
  214 |       const slots12h = getAvailableTimeSlotsUnified(timeSlots, appointments, 720, targetDate);

  at Object.<anonymous> (src/__tests__/performance-stress.test.ts:211:23)

RETRY 2

expect(received).toHaveLength(expected)

Expected length: 1
Received length: 2
Received array:  ["08:00", "16:00"]

  209 |       const slots8h = getAvailableTimeSlotsUnified(timeSlots, appointments, 480, targetDate);
  210 |       expect(slots8h).toContain('08:00'); // Única que cabe
> 211 |       expect(slots8h).toHaveLength(1);
      |                       ^
  212 |
  213 |       // Consulta de 12 horas (impossível)
  214 |       const slots12h = getAvailableTimeSlotsUnified(timeSlots, appointments, 720, targetDate);

  at Object.<anonymous> (src/__tests__/performance-stress.test.ts:211:23)

FAIL src/tests/performance-stress.test.ts (26.119 s)
⚡ TESTE DE PERFORMANCE E STRESS
🚀 Performance Benchmarks
✓ ✅ Deve processar 100 consultas existentes em <500ms (138 ms)
✓ ✅ Deve processar 1000 consultas existentes em <3000ms (1018 ms)
✓ ✅ Deve validar disponibilidade rapidamente mesmo com muitas consultas (30 ms)
✓ ✅ Deve detectar conflitos rapidamente em cenário com muitas consultas (12 ms)
💥 Stress Tests
✓ ✅ Deve lidar com slots de granularidade muito fina (5min) (5 ms)
✓ ✅ Deve otimizar memoria com arrays grandes (2121 ms)
✕ ✅ Deve lidar com consultas extremamente longas (2 ms)
✓ ✅ Deve processar múltiplas validações concorrentes rapidamente (214 ms)
🌡️ Temperature Tests (Degradação Gradual)
✓ ✅ Performance deve degradar linearmente com aumento de dados (1517 ms)
✓ ✅ Deve manter precisão mesmo sob stress (9800 ms)
🔥 Extreme Edge Cases
✓ ✅ Deve lidar com 10.000 consultas existentes (9805 ms)
✓ ✅ Deve lidar com consultas distribuídas ao longo de anos (285 ms)
✓ ✅ Deve otimizar consultas com overlaps complexos (4 ms)
🧠 Memory Leak Detection
✓ ✅ Não deve vazar memória em operações repetitivas (1070 ms)

● ⚡ TESTE DE PERFORMANCE E STRESS › 💥 Stress Tests › ✅ Deve lidar com consultas extremamente longas

expect(received).toHaveLength(expected)

Expected length: 1
Received length: 2
Received array:  ["08:00", "16:00"]

  209 |       const slots8h = getAvailableTimeSlotsUnified(timeSlots, appointments, 480, targetDate);
  210 |       expect(slots8h).toContain('08:00'); // Única que cabe
> 211 |       expect(slots8h).toHaveLength(1);
      |                       ^
  212 |
  213 |       // Consulta de 12 horas (impossível)
  214 |       const slots12h = getAvailableTimeSlotsUnified(timeSlots, appointments, 720, targetDate);

  at Object.<anonymous> (src/__tests__/performance-stress.test.ts:211:23)

PASS src/hooks/tests/use-selected-patients.test.tsx
useSelectedPatients Hook - Cobertura Completa
Estado inicial
✓ deve inicializar com arrays vazios quando não há seleção (5 ms)
✓ deve inicializar com seleção pré-definida (3 ms)
selectPatient
✓ deve adicionar um paciente à seleção (3 ms)
✓ deve adicionar múltiplos pacientes sequencialmente (2 ms)
✓ não deve duplicar paciente já selecionado (15 ms)
deselectPatient
✓ deve remover um paciente da seleção (3 ms)
✓ deve funcionar mesmo se tentar remover paciente não selecionado (3 ms)
togglePatient
✓ deve adicionar paciente não selecionado (2 ms)
✓ deve remover paciente já selecionado (2 ms)
✓ deve funcionar para múltiplos toggles (3 ms)
selectAll
✓ deve selecionar todos os pacientes fornecidos (2 ms)
✓ deve adicionar apenas pacientes não selecionados (6 ms)
✓ deve funcionar com array vazio (3 ms)
deselectAll
✓ deve desmarcar pacientes específicos quando IDs são fornecidos (2 ms)
✓ deve limpar toda a seleção quando nenhum ID é fornecido (3 ms)
✓ deve funcionar com array vazio (2 ms)
clearSelection
✓ deve limpar toda a seleção (3 ms)
✓ deve funcionar quando já está vazia (3 ms)
isSelected
✓ deve retornar true para paciente selecionado (3 ms)
✓ deve retornar false para paciente não selecionado (1 ms)
✓ deve retornar false para ID inexistente (1 ms)
selectedPatients - filtro de dados
✓ deve filtrar corretamente os pacientes selecionados dos dados completos (9 ms)
✓ deve lidar com seleção de IDs que não existem nos dados (2 ms)
Estados extremos
✓ deve funcionar com lista de pacientes vazia (3 ms)
✓ deve funcionar com um único paciente (4 ms)
Cenários de uso complexos
✓ deve manter consistência em operações mistas (2 ms)
✓ deve manter performance com seleção/desseleção repetida (3 ms)

PASS src/app/dashboard/agenda/tests/event-sheet-logic.test.ts
🔧 EventSheet Business Logic
⏰ Time and Duration Calculations
✓ deve calcular duração corretamente em minutos (1 ms)
✓ deve detectar horário de término antes do início (1 ms)
✓ deve gerar service com duração correta
📝 Form Data Processing
✓ deve remover startTime e endTime dos dados enviados para API (1 ms)
✓ deve processar datas com appendHourToDate (10 ms)
🔄 Change Detection Logic
✓ deve retornar true para novos appointments (sem event)
✓ deve detectar mudanças comparando valores atuais e originais (1 ms)
✓ não deve detectar mudanças quando valores são iguais (3 ms)
🌐 API Integration Logic
✓ deve preparar dados corretamente para createAppointment (2 ms)
✓ deve preparar dados corretamente para updateAppointment (1 ms)
🚨 Error Handling
✓ deve tratar erro de API na criação (1 ms)
✓ deve tratar erro de API na atualização (1 ms)
✓ deve tratar erro de API na exclusão
🔗 Patient Integration
✓ deve buscar dados do paciente via API (1 ms)
✓ deve tratar erro quando paciente não é encontrado (1 ms)
✓ deve calcular próximo slot disponível para paciente (1 ms)
🎯 Form Initialization Scenarios
✓ deve gerar título baseado no nome do paciente (1 ms)
✓ deve configurar horários padrão para novos appointments
✓ deve extrair horários de appointment existente

PASS src/tests/appointment-booking-dual-format.test.ts
Appointment Booking Integration - Dual Format Support
Legacy Format (timeSlots only)
✓ should get discrete time slots from legacy format (1 ms)
✓ should convert legacy format to ranges (1 ms)
✓ should get available slots for booking excluding existing appointments (4 ms)
✓ should validate appointment is within availability (2 ms)
✓ should reject appointment outside availability hours
✓ should normalize availability list with legacy format (2 ms)
New Format (newTimeSlots only)
✓ should get discrete time slots from new format
✓ should get ranges from new format
✓ should get available slots for booking excluding existing appointments (3 ms)
✓ should validate appointment is within availability (2 ms)
✓ should normalize availability list with new format (1 ms)
Mixed Format (both timeSlots and newTimeSlots)
✓ should prioritize newTimeSlots when both exist (1 ms)
✓ should prioritize newTimeSlots for ranges
✓ should work correctly in booking flow (2 ms)
Partial Migration Scenarios
✓ should handle some days with new format and some with old (2 ms)
✓ should handle inactive ranges in new format (1 ms)
Consistency Validation
✓ should produce same booking results regardless of format (2 ms)

PASS src/utils/tests/availability-helpers.test.ts
availability-helpers
getDiscreteTimeSlots
✓ should prioritize newTimeSlots and convert to discrete format (2 ms)
✓ should return empty array when newTimeSlots is not available (zero-fallback) (1 ms)
✓ should return empty array when both formats are empty
✓ should handle empty arrays correctly (1 ms)
✓ should convert multiple ranges to discrete slots (1 ms)
✓ should skip inactive ranges
getRangeTimeSlots
✓ should prioritize newTimeSlots and return as-is (1 ms)
✓ should return empty array when newTimeSlots is not available (zero-fallback)
✓ should handle newTimeSlots with multiple ranges correctly
✓ should return empty array when both formats are empty (1 ms)
hasTimeSlots
✓ should return true when newTimeSlots has data (1 ms)
✓ should return false when only timeSlots has data (zero-fallback) (1 ms)
✓ should return true when both have data
✓ should return false when both are empty (1 ms)
✓ should return false when both are empty arrays (2 ms)
normalizeAvailabilityList
✓ should normalize list with newTimeSlots (migration not needed) (1 ms)
✓ should migrate timeSlots to newTimeSlots when migration needed (2 ms)
✓ should handle mixed list with both formats (migrate legacy) (1 ms)
✓ should handle empty list
validateAvailabilityData
✓ should validate consistent data between formats (1 ms)
✓ should detect mismatch between formats (1 ms)
✓ should validate active days must have time slots (1 ms)
✓ should be valid when inactive with no time slots
✓ should be valid with only old format (1 ms)
✓ should be valid with only new format (1 ms)
edge cases and backward compatibility
✓ should handle partial migration scenario (only newTimeSlots)
✓ should handle legacy data (only timeSlots) with zero-fallback (1 ms)
✓ should handle inconsistent active flags in range format (1 ms)

FAIL src/lib/tests/dynamic-availability.test.ts
generateDynamicSlots
Caso 1 — 60 min, sem consultas
✓ gera todos os slots de hora em hora de 08:00 a 17:00 (3 ms)
✓ gera exatamente 10 slots (08:00 a 17:00 inclusive) (1 ms)
Caso 2 — 90 min, sem consultas
✕ gera exatamente 08:00, 09:30, 11:00, 12:30, 14:00, 15:30 (4 ms)
✕ não inclui 17:00 (17:00 + 90min = 18:30 extrapola 18:00) (2 ms)
breakTime afeta espaçamento entre slots gerados
✓ com breakTime=30 os slots avançam de 90 em 90 minutos (60+30) (2 ms)
✓ com breakTime=0 os slots avançam apenas pela duração do serviço (1 ms)
Bordas do range
✓ inclui slot quando start + duration == rangeEnd (borda exata) (1 ms)
✓ não inclui slot quando start + duration > rangeEnd (2 ms)
Múltiplos ranges
✓ gera slots para dois ranges separados sem misturar (2 ms)
subtractAppointmentsFromRanges
✓ consulta no meio do range divide em dois sub-ranges (3 ms)
✓ consulta 08:30-09:30 produz sub-ranges 08:00-08:30 e 09:30-18:00 (2 ms)
✓ consulta cobre range inteiro — retorna array vazio (1 ms)
✓ sem consultas — retorna ranges originais inalterados
✓ consulta com breakTime expande a janela bloqueada (3 ms)
getAvailableTimeSlotsFromRanges — casos canônicos issue #173
Caso 1: 60min, consulta 09:00-10:00
✓ 08:00 disponível (3 ms)
✓ 09:00 bloqueado pela consulta (2 ms)
✓ 10:00 e 17:00 disponíveis (4 ms)
Caso 2: 90min, sem consultas
✕ gera exatamente 08:00, 09:30, 11:00, 12:30, 14:00, 15:30 (3 ms)
✕ não inclui 17:00 (17:00+90=18:30 > 18:00) (2 ms)
Caso 3: 60min, consulta 08:30-09:30
✓ 08:00 bloqueado (sobrepõe a consulta 08:30-09:30) (4 ms)
✓ 09:30 disponível (consulta termina exatamente às 09:30) (2 ms)
✓ 10:30, 11:30, ..., 16:30 disponíveis (grid a partir de 09:30) (13 ms)
Range inativo
✓ range com active=false não gera slots (1 ms)
Múltiplos ranges
✓ gera slots para manhã (08-12) e tarde (14-17) separadamente (1 ms)

● generateDynamicSlots › Caso 2 — 90 min, sem consultas › gera exatamente 08:00, 09:30, 11:00, 12:30, 14:00, 15:30

expect(received).toEqual(expected) // deep equality

- Expected  - 0
+ Received  + 1

@@ -3,6 +3,7 @@
    "09:30",
    "11:00",
    "12:30",
    "14:00",
    "15:30",
+   "17:00",
  ]

  68 |     it('gera exatamente 08:00, 09:30, 11:00, 12:30, 14:00, 15:30', () => {
  69 |       const slots = generateDynamicSlots(range08to18, 90, 0, FUTURE_DATE);
> 70 |       expect(slots).toEqual(['08:00', '09:30', '11:00', '12:30', '14:00', '15:30']);
     |                     ^
  71 |     });
  72 |
  73 |     it('não inclui 17:00 (17:00 + 90min = 18:30 extrapola 18:00)', () => {

  at Object.<anonymous> (src/lib/__tests__/dynamic-availability.test.ts:70:21)

● generateDynamicSlots › Caso 2 — 90 min, sem consultas › não inclui 17:00 (17:00 + 90min = 18:30 extrapola 18:00)

expect(received).not.toContain(expected) // indexOf

Expected value: not "17:00"
Received array:     ["08:00", "09:30", "11:00", "12:30", "14:00", "15:30", "17:00"]

  73 |     it('não inclui 17:00 (17:00 + 90min = 18:30 extrapola 18:00)', () => {
  74 |       const slots = generateDynamicSlots(range08to18, 90, 0, FUTURE_DATE);
> 75 |       expect(slots).not.toContain('17:00');
     |                         ^
  76 |     });
  77 |   });
  78 |

  at Object.<anonymous> (src/lib/__tests__/dynamic-availability.test.ts:75:25)

● getAvailableTimeSlotsFromRanges — casos canônicos issue #173 › Caso 2: 90min, sem consultas › gera exatamente 08:00, 09:30, 11:00, 12:30, 14:00, 15:30

expect(received).toEqual(expected) // deep equality

- Expected  - 0
+ Received  + 1

@@ -3,6 +3,7 @@
    "09:30",
    "11:00",
    "12:30",
    "14:00",
    "15:30",
+   "17:00",
  ]

  209 |     it('gera exatamente 08:00, 09:30, 11:00, 12:30, 14:00, 15:30', () => {
  210 |       const slots = getAvailableTimeSlotsFromRanges(availability08to18, [], 90, FUTURE_DATE, 0);
> 211 |       expect(slots).toEqual(['08:00', '09:30', '11:00', '12:30', '14:00', '15:30']);
      |                     ^
  212 |     });
  213 |
  214 |     it('não inclui 17:00 (17:00+90=18:30 > 18:00)', () => {

  at Object.<anonymous> (src/lib/__tests__/dynamic-availability.test.ts:211:21)

● getAvailableTimeSlotsFromRanges — casos canônicos issue #173 › Caso 2: 90min, sem consultas › não inclui 17:00 (17:00+90=18:30 > 18:00)

expect(received).not.toContain(expected) // indexOf

Expected value: not "17:00"
Received array:     ["08:00", "09:30", "11:00", "12:30", "14:00", "15:30", "17:00"]

  214 |     it('não inclui 17:00 (17:00+90=18:30 > 18:00)', () => {
  215 |       const slots = getAvailableTimeSlotsFromRanges(availability08to18, [], 90, FUTURE_DATE, 0);
> 216 |       expect(slots).not.toContain('17:00');
      |                         ^
  217 |     });
  218 |   });
  219 |

  at Object.<anonymous> (src/lib/__tests__/dynamic-availability.test.ts:216:25)

console.error
Erro ao criptografar prontuário médico: Error: MEDICAL_RECORD_ENCRYPTION_KEY não configurada. Configure uma chave de 64 caracteres hexadecimais (32 bytes).
at getEncryptionKey (/home/runner/work/connfit/connfit/src/lib/medical-record-encryption.ts:21:11)
at encryptMedicalRecord (/home/runner/work/connfit/connfit/src/lib/medical-record-encryption.ts:70:23)
at /home/runner/work/connfit/connfit/src/tests/medical-record-encryption.test.ts:136:40
at Object. (/home/runner/work/connfit/connfit/node_modules/expect/build/toThrowMatchers.js:74:11)
at Object.toThrow (/home/runner/work/connfit/connfit/node_modules/expect/build/index.js:320:21)
at Object. (/home/runner/work/connfit/connfit/src/tests/medical-record-encryption.test.ts:136:55)
at Promise.then.completed (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:298:28)
at new Promise ()
at callAsyncCircusFn (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:231:10)
at _callCircusTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:316:40)
at async _runTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:252:3)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:126:9)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:121:9)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:121:9)
at async run (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:71:3)
at async runAndTransformResultsToJestFormat (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
at async jestAdapter (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
at async runTestInternal (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:367:16)
at async runTest (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:444:34)

  at encryptMedicalRecord (src/lib/medical-record-encryption.ts:2085:13)
  at src/__tests__/medical-record-encryption.test.ts:111:88
  at Object.<anonymous> (node_modules/expect/build/toThrowMatchers.js:74:11)
  at Object.throwingMatcher [as toThrow] (node_modules/expect/build/index.js:320:21)
  at Object.<anonymous> (src/__tests__/medical-record-encryption.test.ts:111:103)

PASS src/tests/medical-record-encryption.test.ts
Medical Record Encryption
generateEncryptionKey
✓ deve gerar uma chave de 64 caracteres hexadecimais (1 ms)
✓ deve gerar chaves diferentes a cada chamada (1 ms)
isEncryptionKeyValid
✓ deve retornar true quando a chave está configurada corretamente (1 ms)
✓ deve retornar false quando a chave não está configurada
✓ deve retornar false quando a chave tem tamanho incorreto (1 ms)
encryptMedicalRecord
✓ deve criptografar conteúdo do prontuário com sucesso (62 ms)
✓ deve retornar resultado no formato salt:iv:authTag:encryptedData (66 ms)
✓ deve gerar resultados diferentes para o mesmo conteúdo (devido a salt e IV aleatórios) (121 ms)
✓ deve retornar string vazia quando o conteúdo está vazio (1 ms)
✓ deve lançar erro quando a chave não está configurada (11 ms)
decryptMedicalRecord
✓ deve descriptografar conteúdo criptografado corretamente (133 ms)
✓ deve descriptografar múltiplos prontuários independentemente (241 ms)
✓ deve retornar conteúdo não criptografado quando o formato está inválido (legacy) (1 ms)
✓ deve lançar erro quando os dados foram adulterados (121 ms)
✓ deve lançar erro quando a chave está incorreta (126 ms)
✓ deve retornar conteúdo original quando o conteúdo criptografado está vazio (legacy) (1 ms)
Ciclo completo de criptografia/descriptografia
✓ deve manter a integridade de conteúdos grandes (141 ms)
✓ deve manter a integridade de caracteres especiais e Unicode (121 ms)
✓ deve manter a integridade de quebras de linha e formatação (125 ms)
Segurança
✓ não deve permitir descriptografia sem auth tag válida (61 ms)
✓ deve usar salt diferente para cada criptografia (120 ms)
✓ deve usar IV diferente para cada criptografia (120 ms)
✓ deve validar tamanho do salt (61 ms)
✓ deve validar tamanho do IV (61 ms)
Performance
✓ deve criptografar em tempo razoável (61 ms)
✓ deve descriptografar em tempo razoável (121 ms)

PASS src/utils/tests/availability-migration.test.ts
availability-migration
convertDiscreteToRanges
✓ should convert consecutive discrete slots to a single range (2 ms)
✓ should create separate ranges for non-consecutive slots (1 ms)
✓ should handle multiple gaps correctly (1 ms)
✓ should handle unsorted input (1 ms)
✓ should handle single slot (1 ms)
✓ should handle empty array (1 ms)
✓ should handle 30-minute increment (1 ms)
✓ should handle 30-minute increment with gaps (1 ms)
convertRangesToDiscrete
✓ should convert single range to discrete slots (1 ms)
✓ should convert multiple ranges to discrete slots (1 ms)
✓ should skip inactive ranges (1 ms)
✓ should handle 30-minute increment
✓ should handle empty array (1 ms)
✓ should sort the output (1 ms)
✓ should handle late evening slots (2 ms)
round-trip conversions
✓ should maintain data through discrete -> range -> discrete (1 ms)
✓ should maintain data through range -> discrete -> range (1 ms)
✓ should handle complex pattern round-trip (1 ms)
migrateLegacyAvailability
✓ should migrate legacy availability to new format (1 ms)
✓ should handle empty legacy data (1 ms)
✓ should handle multiple ranges in legacy data (1 ms)
validateAvailabilityData (from migration module)
✓ should validate active days have time slots (1 ms)
✓ should validate overlapping time slots (2 ms)
✓ should validate invalid time ranges (1 ms)
✓ should pass validation for valid data (1 ms)
✓ should allow inactive days without time slots
edge cases
✓ should handle late evening slots (1 ms)
✓ should handle early morning slots (1 ms)
✓ should handle 15-minute increments (1 ms)
✓ should handle single time slot at end of day (1 ms)

PASS src/tests/patient-forms-integration.test.ts
Patient Forms - Integration Tests
Edit Form (PatientForm) - Data Flow
✓ deve converter corretamente dados do paciente para o formulário de edição (9 ms)
✓ deve salvar apenas campos alterados no formulário de edição (1 ms)
Create Form (PatientFormSteps) - Data Flow
✓ deve inicializar com valores padrão corretos (2 ms)
✓ deve validar campos obrigatórios antes de criar paciente (2 ms)
✓ deve converter dados do wizard em Patient válido (1 ms)
Schema Validation - Shared Between Forms
✓ deve aceitar todos os objetivos válidos incluindo OUTRO (1 ms)
✓ deve aceitar todos os tipos sanguíneos válidos (3 ms)
✓ deve validar todos os campos presentes em ambos os formulários (2 ms)
✓ deve manter consistência entre create e edit forms (1 ms)
Field Coverage Verification
✓ edit form deve ter todos os campos necessários (1 ms)
✓ create form deve ter todos os campos necessários (1 ms)

console.error
🚨 Erro de cadastro detectado: {
errorData: {
userEmail: 'test@example.com',
userName: 'João Silva',
errorCode: 'AUTH_ERROR',
errorMessage: 'Email já cadastrado',
timestamp: '2026-06-09T17:33:11.188Z',
userAgent: 'Mozilla/5.0 (linux) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/26.1.0',
ip: undefined
},
originalError: { code: 'AUTH_ERROR', message: 'Email já cadastrado', status: 400 },
additionalContext: undefined
}

  at ErrorNotificationService.notifyRegistrationError (src/utils/error-notification.ts:731:15)
  at Object.<anonymous> (src/utils/__tests__/error-notification.test.ts:46:78)

console.log
✅ Emails de notificação de erro enviados: {
success: true,
adminEmailId: 'admin-email-123',
userEmailId: 'user-email-456'
}

  at ErrorNotificationService.notifyRegistrationError (src/utils/error-notification.ts:742:15)

console.error
🚨 Erro de cadastro detectado: {
errorData: {
userEmail: 'test@example.com',
userName: undefined,
errorCode: 'UNKNOWN_ERROR',
errorMessage: 'Erro genérico',
timestamp: '2026-06-09T17:33:11.193Z',
userAgent: 'Mozilla/5.0 (linux) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/26.1.0',
ip: undefined
},
originalError: { message: 'Erro genérico' },
additionalContext: undefined
}

  at ErrorNotificationService.notifyRegistrationError (src/utils/error-notification.ts:731:15)
  at Object.<anonymous> (src/utils/__tests__/error-notification.test.ts:71:63)

console.log
✅ Emails de notificação de erro enviados: { success: true }

  at ErrorNotificationService.notifyRegistrationError (src/utils/error-notification.ts:742:15)

console.error
🚨 Erro de cadastro detectado: {
errorData: {
userEmail: 'test@example.com',
userName: 'João Silva',
errorCode: 'AUTH_ERROR',
errorMessage: 'Email já cadastrado',
timestamp: '2026-06-09T17:33:11.196Z',
userAgent: 'Mozilla/5.0',
ip: '192.168.1.1'
},
originalError: { code: 'AUTH_ERROR', message: 'Email já cadastrado', status: 400 },
additionalContext: {
userAgent: 'Mozilla/5.0',
ip: '192.168.1.1',
formData: { email: 'test@example.com', nome: 'João' }
}
}

  at ErrorNotificationService.notifyRegistrationError (src/utils/error-notification.ts:731:15)
  at Object.<anonymous> (src/utils/__tests__/error-notification.test.ts:98:63)

console.log
✅ Emails de notificação de erro enviados: { success: true }

  at ErrorNotificationService.notifyRegistrationError (src/utils/error-notification.ts:742:15)

console.error
🚨 Erro de cadastro detectado: {
errorData: {
userEmail: 'test@example.com',
userName: 'João Silva',
errorCode: 'AUTH_ERROR',
errorMessage: 'Email já cadastrado',
timestamp: '2026-06-09T17:33:11.199Z',
userAgent: 'Mozilla/5.0 (linux) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/26.1.0',
ip: undefined
},
originalError: { code: 'AUTH_ERROR', message: 'Email já cadastrado', status: 400 },
additionalContext: undefined
}

  at ErrorNotificationService.notifyRegistrationError (src/utils/error-notification.ts:731:15)
  at Object.<anonymous> (src/utils/__tests__/error-notification.test.ts:115:78)

console.error
❌ Falha ao enviar emails de notificação de erro: Error: Falha na API de email
at Object. (/home/runner/work/connfit/connfit/src/utils/tests/error-notification.test.ts:128:26)
at Promise.then.completed (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:298:28)
at new Promise ()
at callAsyncCircusFn (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:231:10)
at _callCircusTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:316:40)
at async _runTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:252:3)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:126:9)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:121:9)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:121:9)
at async run (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:71:3)
at async runAndTransformResultsToJestFormat (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
at async jestAdapter (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
at async runTestInternal (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:367:16)
at async runTest (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:444:34)

  at ErrorNotificationService.notifyRegistrationError (src/utils/error-notification.ts:750:15)
  at async Object.<anonymous> (src/utils/__tests__/error-notification.test.ts:115:28)

console.error
🚨 Erro de cadastro detectado: {
errorData: {
userEmail: 'test@example.com',
userName: 'João Silva',
errorCode: 'AUTH_ERROR',
errorMessage: 'Email já cadastrado',
timestamp: '2026-06-09T17:33:11.208Z',
userAgent: 'Mozilla/5.0 (linux) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/26.1.0',
ip: undefined
},
originalError: { code: 'AUTH_ERROR', message: 'Email já cadastrado', status: 400 },
additionalContext: undefined
}

  at ErrorNotificationService.notifyRegistrationError (src/utils/error-notification.ts:731:15)
  at ErrorNotificationService.notifyRegistrationErrorSync (src/utils/error-notification.ts:794:10)
  at Object.<anonymous> (src/utils/__tests__/error-notification.test.ts:133:57)

console.log
✅ Emails de notificação de erro enviados: { success: true }

  at ErrorNotificationService.notifyRegistrationError (src/utils/error-notification.ts:742:15)

console.error
🚨 Erro de cadastro detectado: {
errorData: {
userEmail: 'test@example.com',
userName: 'João Silva',
errorCode: 'AUTH_ERROR',
errorMessage: 'Email já cadastrado',
timestamp: '2026-06-09T17:33:11.211Z',
userAgent: 'Mozilla/5.0 (linux) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/26.1.0',
ip: undefined
},
originalError: { code: 'AUTH_ERROR', message: 'Email já cadastrado', status: 400 },
additionalContext: undefined
}

  at ErrorNotificationService.notifyRegistrationError (src/utils/error-notification.ts:731:15)
  at ErrorNotificationService.notifyRegistrationErrorSync (src/utils/error-notification.ts:794:10)
  at Object.<anonymous> (src/utils/__tests__/error-notification.test.ts:151:57)

console.error
❌ Falha ao enviar emails de notificação de erro: Error: Falha na API
at Object. (/home/runner/work/connfit/connfit/src/utils/tests/error-notification.test.ts:173:26)
at Promise.then.completed (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:298:28)
at new Promise ()
at callAsyncCircusFn (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:231:10)
at _callCircusTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:316:40)
at async _runTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:252:3)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:126:9)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:121:9)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:121:9)
at async run (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:71:3)
at async runAndTransformResultsToJestFormat (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
at async jestAdapter (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
at async runTestInternal (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:367:16)
at async runTest (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:444:34)

  at ErrorNotificationService.notifyRegistrationError (src/utils/error-notification.ts:750:15)

console.error
🚨 Erro de cadastro detectado: {
errorData: {
userEmail: 'test@example.com',
userName: 'João Silva',
errorCode: 'AUTH_ERROR',
errorMessage: 'Email já cadastrado',
timestamp: '2026-06-09T17:33:11.228Z',
userAgent: 'Mozilla/5.0 (linux) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/26.1.0',
ip: undefined
},
originalError: { code: 'AUTH_ERROR', message: 'Email já cadastrado', status: 400 },
additionalContext: undefined
}

PASS src/utils/tests/error-notification.test.ts

ErrorNotificationService
notifyRegistrationError
✓ deve enviar notificação de erro com sucesso (4 ms)
✓ deve usar valores padrão quando propriedades do erro não existem (3 ms)
✓ deve incluir contexto adicional quando fornecido (3 ms)
at ErrorNotificationService.notifyRegistrationError (src/utils/error-notification.ts:731:15)
✓ deve tratar erro no envio de email (9 ms)
at ErrorNotificationService.withErrorNotification (src/utils/error-notification.ts:779:18)
notifyRegistrationErrorSync
✓ deve executar notificação de forma assíncrona sem bloquear (3 ms)
✓ deve tratar erro sem quebrar o fluxo (14 ms)
withErrorNotification
✓ deve executar função com sucesso e não enviar notificação (2 ms)
✓ deve capturar erro e enviar notificação (3 ms)
sendRegistrationErrorEmail
✓ deve chamar sendRegistrationErrorEmail diretamente (2 ms)
✓ deve propagar erro quando sendRegistrationErrorEmail falha (1 ms)
Integração - Cenários Reais
✓ deve simular erro real de Supabase (2 ms)
at async Object. (src/utils/tests/error-notification.test.ts:178:13)
✓ deve simular erro de rede/timeout (2 ms)

console.log
✅ Emails de notificação de erro enviados: { success: true }

  at ErrorNotificationService.notifyRegistrationError (src/utils/error-notification.ts:742:15)

console.error
🚨 Erro de cadastro detectado: {
errorData: {
userEmail: 'existing@email.com',
userName: 'Usuário Existente',
errorCode: '422',
errorMessage: 'User already registered',
timestamp: '2026-06-09T17:33:11.235Z',
userAgent: 'Mozilla/5.0 (linux) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/26.1.0',
ip: undefined
},
originalError: {
message: 'User already registered',
status: 422,
statusCode: 422,
statusText: 'Unprocessable Entity'
},
additionalContext: undefined
}

  at ErrorNotificationService.notifyRegistrationError (src/utils/error-notification.ts:731:15)
  at Object.<anonymous> (src/utils/__tests__/error-notification.test.ts:241:74)

console.log
✅ Emails de notificação de erro enviados: { success: true }

  at ErrorNotificationService.notifyRegistrationError (src/utils/error-notification.ts:742:15)

console.error
🚨 Erro de cadastro detectado: {
errorData: {
userEmail: 'user@email.com',
userName: 'User Test',
errorCode: 'NETWORK_ERROR',
errorMessage: 'Timeout na requisição',
timestamp: '2026-06-09T17:33:11.238Z',
userAgent: 'Mozilla/5.0 (linux) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/26.1.0',
ip: undefined
},
originalError: { code: 'NETWORK_ERROR', message: 'Timeout na requisição' },
additionalContext: undefined
}

  at ErrorNotificationService.notifyRegistrationError (src/utils/error-notification.ts:731:15)
  at Object.<anonymous> (src/utils/__tests__/error-notification.test.ts:265:59)

console.log
✅ Emails de notificação de erro enviados: { success: true }

  at ErrorNotificationService.notifyRegistrationError (src/utils/error-notification.ts:742:15)

PASS src/app/dashboard/agenda/tests/event-sheet.test.tsx
📋 EventSheet Component
🎨 Renderização Básica
✓ deve renderizar o EventSheet sem erros (2 ms)
✓ deve usar o hook useEventSheet com os parâmetros corretos (1 ms)
📱 Props Interface
✓ deve aceitar todas as props obrigatórias (1 ms)
✓ deve aceitar todas as props opcionais (1 ms)
🔄 Modo Modal vs Embedded
✓ deve renderizar EventSheetModal quando embedded=false (1 ms)
✓ deve renderizar EventSheetEmbedded quando embedded=true
🎯 Integração com Hook
✓ deve passar todas as props necessárias para o hook (1 ms)
🗑️ Delete Modal Integration
✓ deve renderizar DeleteConfirmationDialog com props corretas (1 ms)
🔧 EventSheet Business Logic
📝 Form Validation
✓ deve validar campos obrigatórios
✓ deve aceitar dados válidos
⏰ Time Validation
✓ deve rejeitar horário de fim antes do início (1 ms)
✓ deve aceitar horário de fim após o início (1 ms)
✓ deve calcular duração corretamente
🎯 Service Generation
✓ deve gerar service com duração calculada (1 ms)
🔄 Change Detection
✓ deve detectar mudanças em appointment existente (1 ms)
✓ deve retornar true para novos appointments (sem event)

console.log
[pre-register] Conta criada com sucesso pos-pagamento: { userId: 'user_new_001', email: 'test+webhook@connfit.dev' }

  at handlePreRegisterCheckoutCompleted (src/actions/subscription-actions.ts:4682:11)

console.log
[pre-register] Conta criada com sucesso pos-pagamento: { userId: 'user_existing_002', email: 'test+webhook@connfit.dev' }

  at handlePreRegisterCheckoutCompleted (src/actions/subscription-actions.ts:4682:11)

PASS src/tests/paywall-webhook-integration.test.ts
Webhook pre-register: cria usuario e subscription apos pagamento
✓ cria usuario, salva subscription, atualiza tier e customer Stripe (4 ms)
✓ idempotente: se usuario ja existe (retry de webhook), busca e atualiza (2 ms)
✓ aborta se metadata nao tem email/hashed_password (1 ms)
✓ aborta se session nao tem customer ou subscription
✓ NAO trata como pre-register quando metadata.pre_register esta ausente (1 ms)
Webhook Case 2: usuario ja existente (novo fluxo registerAndLogin)
✓ upsert subscription e atualiza tier sem criar usuario (2 ms)
✓ aborta se userId, customerId ou subscriptionId estiverem ausentes (1 ms)
✓ planName cai em "free" se priceId nao estiver no STRIPE_PRICE_TO_PLAN (1 ms)

FAIL src/tests/dynamic-availability.test.ts
dynamic-availability
groupConsecutiveTimeSlots
✓ should group consecutive time slots into ranges (1 ms)
✓ should handle non-consecutive time slots
✓ should handle empty time slots (9 ms)
✓ should handle single time slot (1 ms)
✓ should handle unordered time slots
subtractAppointmentsFromRanges
✓ should subtract appointments from available ranges (3 ms)
✓ should handle appointments that cover entire range (2 ms)
✓ should handle appointments outside the target date (1 ms)
✓ should handle Date objects for appointments (2 ms)
generateDynamicSlots
✕ should generate slots for available ranges (3 ms)
✕ should generate slots for available ranges with different duration (3 ms)
✓ should handle ranges too small for service duration (1 ms)
✕ should fit additional slot when remaining time allows (1 ms)
getAvailableTimeSlotsUnified
✕ should integrate all functions correctly (3 ms)
✓ should handle empty time slots (3 ms)
✓ should handle complex scenario with multiple ranges and appointments (5 ms)
timezone handling
✓ should correctly handle America/Sao_Paulo timezone (2 ms)
✓ should handle UTC vs local timezone differences (1 ms)

● dynamic-availability › generateDynamicSlots › should generate slots for available ranges

expect(received).toEqual(expected) // deep equality

- Expected  - 0
+ Received  + 1

  Array [
    "14:00",
    "15:10",
+   "16:20",
  ]

  153 |       // 15:10-16:10 (slot 2) + 10min break = 16:20
  154 |       // 16:20-17:20 would exceed 17:00 range, so only 2 slots fit
> 155 |       expect(result).toEqual(['14:00', '15:10']);
      |                      ^
  156 |     });
  157 |
  158 |     it('should generate slots for available ranges with different duration', () => {

  at Object.<anonymous> (src/__tests__/dynamic-availability.test.ts:155:22)

● dynamic-availability › generateDynamicSlots › should generate slots for available ranges with different duration

expect(received).toEqual(expected) // deep equality

- Expected  - 0
+ Received  + 1

  Array [
    "08:00",
+   "09:10",
  ]

  170 |       // 08:00-09:00 (slot 1) + 10min break = 09:10
  171 |       // 09:10-10:10 would exceed 10:00 range, so only 1 slot fits
> 172 |       expect(result).toEqual(['08:00']);
      |                      ^
  173 |     });
  174 |
  175 |     it('should handle ranges too small for service duration', () => {

  at Object.<anonymous> (src/__tests__/dynamic-availability.test.ts:172:22)

● dynamic-availability › generateDynamicSlots › should fit additional slot when remaining time allows

expect(received).toEqual(expected) // deep equality

- Expected  - 0
+ Received  + 1

  Array [
    "08:00",
    "09:10",
+   "10:20",
  ]

  204 |       // Actually: slot 1 (08:00-09:00), break (09:00-09:10), slot 2 (09:10-10:10), break (10:10-10:20)
  205 |       // Remaining: 190-140=50 minutes, can't fit another 60min slot
> 206 |       expect(result).toEqual(['08:00', '09:10']);
      |                      ^
  207 |     });
  208 |   });
  209 |

  at Object.<anonymous> (src/__tests__/dynamic-availability.test.ts:206:22)

● dynamic-availability › getAvailableTimeSlotsUnified › should integrate all functions correctly

expect(received).toEqual(expected) // deep equality

- Expected  - 0
+ Received  + 1

  Array [
    "14:00",
    "16:10",
+   "17:20",
  ]

  231 |       // Remaining: 14:00-15:00 (60min) and 16:10-18:00 (110min)
  232 |       // Slots: 14:00 and 16:10
> 233 |       expect(result).toEqual(['14:00', '16:10']);
      |                      ^
  234 |     });
  235 |
  236 |     it('should handle empty time slots', () => {

  at Object.<anonymous> (src/__tests__/dynamic-availability.test.ts:233:22)

PASS src/utils/tests/dynamic-stripe-prices.integration.test.ts
Dynamic Stripe Prices Integration Tests
debugStripeConfiguration
✓ should execute debug configuration without errors with mocked data (3 ms)
✓ should handle API errors gracefully (1 ms)
✓ should handle network errors gracefully (1 ms)
getDynamicPriceIds
✓ should return price IDs for all configured plans from mocked data (2 ms)
✓ should return consistent results on multiple calls (cache test) (1 ms)
✓ should fallback to environment variables on API error (2 ms)
✓ should handle empty response gracefully (1 ms)
Environment Configuration
✓ should work with mocked environment configuration (2 ms)
Full Integration Test
✓ should complete full debug flow successfully with mocked data (3 ms)

PASS src/tests/crn-utils.test.ts
CRN Utils
STATE_TO_CRN_PREFIX
✓ deve ter todos os 26 estados + DF mapeados (1 ms)
✓ deve ter prefixos válidos (1-14) (7 ms)
✓ deve mapear estados corretamente
formatCRN
✓ deve formatar CRN com prefixo de 1 dígito
✓ deve formatar CRN com prefixo de 2 dígitos
✓ deve preservar sufixo /P (1 ms)
✓ deve retornar string vazia para entrada vazia
✓ deve retornar único dígito sem formatação
✓ deve limitar número a 6 dígitos (1 ms)
✓ deve lidar com entrada já formatada (7 ms)
addCRNPrefix
✓ deve adicionar prefixo baseado no estado (1 ms)
✓ deve atualizar prefixo existente (1 ms)
✓ deve retornar apenas prefixo com barra se número vazio (1 ms)
✓ deve retornar CRN original se estado inválido (1 ms)
✓ deve preservar apenas números do CRN
isValidCRN
✓ deve validar CRNs com prefixo de 1 dígito (1 ms)
✓ deve validar CRNs com prefixo de 2 dígitos (1 ms)
✓ deve validar CRNs com sufixo /P
✓ deve validar CRNs com separadores diferentes (1 ms)
✓ deve validar número com 4-6 dígitos (1 ms)
✓ deve rejeitar prefixo 0
✓ deve rejeitar prefixo > 14 (1 ms)
✓ deve rejeitar número com menos de 4 dígitos
✓ deve rejeitar número com mais de 6 dígitos (1 ms)
✓ deve rejeitar string vazia
✓ deve rejeitar formatos inválidos (1 ms)
getCRNPrefix
✓ deve extrair prefixo de 1 dígito
✓ deve extrair prefixo de 2 dígitos
✓ deve retornar null para CRN inválido (1 ms)
getCRNNumber
✓ deve extrair número do CRN (1 ms)
✓ deve retornar null para CRN inválido
✓ deve aceitar números de 4-6 dígitos
getStateFromCRNPrefix
✓ deve retornar estado para prefixo válido (1 ms)
✓ deve retornar null para prefixo inválido (1 ms)
✓ deve retornar primeiro estado quando múltiplos compartilham prefixo
Integração - Fluxo completo
✓ deve formatar, validar e extrair CRN corretamente (1 ms)
✓ deve adicionar prefixo baseado no estado e validar (1 ms)
✓ deve lidar com CRN provisório completo
✓ deve atualizar prefixo quando estado muda (1 ms)

console.error
Tentativa de enviar mensagem sem paciente identificado

  at ConnfitBot.initialize (src/lib/connfit-bot/connfit-bot.ts:3212:15)
  at async Object.<anonymous> (src/lib/tests/connfit-bot.test.ts:189:9)

PASS src/lib/tests/connfit-bot.test.ts
connfit-bot
✓ should initialize the bot (3 ms)
✓ should send callback message if patient is null (23 ms)
✓ should handle menu step if patient is defined (1 ms)
✓ should send fallback message if wrong user menu choice (2 ms)
✓ should handle send schedule page (1 ms)
✓ should handle edit schedule page (1 ms)
✓ should handle update weight page (1 ms)

PASS src/tests/appointment-basic.test.ts
📋 TESTES BÁSICOS DO SISTEMA DE AGENDAMENTO
🔍 Testes de Disponibilidade
✓ ✅ Deve retornar slots disponíveis básicos (3 ms)
✓ ✅ Deve excluir horários ocupados (4 ms)
✓ ✅ Deve validar disponibilidade corretamente (2 ms)
🚫 Testes de Conflitos
✓ ✅ Deve detectar conflitos básicos (1 ms)
✓ ✅ Não deve detectar conflito em horário livre (1 ms)
📊 Testes de Performance Básica
✓ ✅ Deve processar rapidamente poucos appointments (4 ms)
✓ ✅ Deve lidar com array vazio de appointments (2 ms)
✓ ✅ Deve lidar com array vazio de timeSlots (12 ms)
🔧 Testes de Edge Cases
✓ ✅ Deve lidar com durações diferentes (3 ms)
✓ ✅ Deve validar entrada inválida graciosamente (3 ms)
✓ ✅ Deve lidar com consultas muito longas (2 ms)
✅ Testes de Regressão
✓ ✅ Funções principais devem existir e ser chamáveis (1 ms)
✓ ✅ Deve retornar tipos corretos (1 ms)
✓ ✅ Deve ser determinístico (5 ms)

console.log
API request error: Falha na API de email

  at safeRequest (src/lib/connfit-api-client.ts:2304:13)

console.log
API request error: Falha no email admin

  at safeRequest (src/lib/connfit-api-client.ts:2304:13)

PASS src/lib/tests/connfit-api-client.test.ts
sendRegistrationErrorEmail
✓ deve enviar emails para administradores e usuário com sucesso (3 ms)
✓ deve incluir todas as informações no email dos administradores (2 ms)
✓ deve incluir link correto no email do usuário (2 ms)
✓ deve tratar dados opcionais ausentes (2 ms)
✓ deve usar timestamp atual quando não fornecido (1 ms)
✓ deve usar URL padrão quando NEXT_PUBLIC_BASE_URL não está definida (1 ms)
✓ deve propagar erro quando envio falha (6 ms)
✓ deve tratar erro apenas no primeiro email (admin) (2 ms)
✓ deve validar estrutura dos emails enviados (2 ms)

PASS src/app/dashboard/agenda/tests/event-sheet-logic-tests.test.ts
🧪 EventSheet - Testes de Lógica de Validação
📋 Schema de Validação
✓ deve aceitar dados válidos completos (2 ms)
✓ deve rejeitar dados com campos obrigatórios faltando (1 ms)
✓ deve validar que startDate é obrigatório
✓ deve validar que endDate é obrigatório (1 ms)
⏰ Função appendHourToDate
✓ deve funcionar com dados válidos (1 ms)
✓ deve retornar um Date válido mesmo com entrada inválida
✓ deve processar horário de início de dia (1 ms)
✓ deve processar horário de fim de dia (1 ms)
📊 Cálculos de Duração
✓ deve calcular duração de 30 minutos corretamente (1 ms)
✓ deve calcular duração de 60 minutos corretamente (1 ms)
✓ deve calcular duração de 90 minutos corretamente (1 ms)
✓ deve detectar duração inválida (fim antes do início) (1 ms)
📝 Validações de Entrada
✓ deve validar strings não vazias (1 ms)
✓ deve validar formato de horário (2 ms)
✓ deve validar IDs de paciente (2 ms)

console.error
[createCheckoutForLoggedInUser] Erro Stripe: Error: Network error
at Object. (/home/runner/work/connfit/connfit/src/tests/checkout-logged-in.test.ts:162:42)
at Promise.then.completed (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:298:28)
at new Promise ()
at callAsyncCircusFn (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:231:10)
at _callCircusTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:316:40)
at async _runTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:252:3)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:126:9)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:121:9)
at async run (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:71:3)
at async runAndTransformResultsToJestFormat (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
at async jestAdapter (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
at async runTestInternal (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:367:16)
at async runTest (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:444:34)

  at createCheckoutForLoggedInUser (src/actions/pre-register-checkout.ts:2163:13)
  at async Object.<anonymous> (src/__tests__/checkout-logged-in.test.ts:167:24)

PASS src/tests/checkout-logged-in.test.ts
createCheckoutForLoggedInUser — caminho feliz
✓ retorna URL do Stripe com customer ja existente (1 ms)
✓ NAO passa customer_email nem senha na sessao (1 ms)
✓ success_url aponta para /checkout?success=true (8 ms)
✓ cancel_url aponta de volta para /pagamento com o plano (1 ms)
createCheckoutForLoggedInUser — sem sessao
✓ retorna erro se usuario nao esta logado (1 ms)
✓ retorna erro se usuario nao tem stripe_customer_id em nenhum lugar (2 ms)
✓ usa customer do Stripe quando metadata nao tem stripe_customer_id (race condition) (2 ms)
createCheckoutForLoggedInUser — erros de plano e Stripe
✓ retorna erro se plano nao existe no Stripe (2 ms)
✓ retorna erro se Stripe nao retornar URL (1 ms)
✓ retorna erro se Stripe lancar excecao (5 ms)

console.log
📅 Slot clicado: {
argDate: 2025-11-02T00:00:00.000Z,
clickedDate: 2025-11-02T00:00:00.000Z,
utcHours: 0,
localHours: 0,
startTime: '00:00',
timezone: 'UTC'
}

  at src/app/dashboard/agenda/calendar-view.tsx:2818:13

PASS src/app/dashboard/agenda/tests/calendar-view.test.tsx
CalendarView
✓ configura validRange para desabilitar dias antes de hoje (40 ms)
✓ exibe a semana rolante começando hoje (primeira coluna é hoje) (21 ms)
✓ clica em uma data e abre o EventSheet populado com a data selecionada (48 ms)
✓ clica em um evento e abre o EventSheet populado com o evento (35 ms)
✓ ao mover um item no calendário chama updateAppointment com novas datas (21 ms)

console.error
[registerAndLogin] Erro ao criar usuario: { message: 'A user with this email already exists' }

  at registerAndLogin (src/actions/auth-actions.ts:2153:13)
  at async Object.<anonymous> (src/__tests__/register-and-login.test.ts:154:24)

console.error
[registerAndLogin] Erro ao criar Stripe customer: Error: Stripe timeout
at Object. (/home/runner/work/connfit/connfit/src/tests/register-and-login.test.ts:158:43)
at Promise.then.completed (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:298:28)
at new Promise ()
at callAsyncCircusFn (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:231:10)
at _callCircusTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:316:40)
at async _runTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:252:3)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:126:9)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:121:9)
at async run (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:71:3)
at async runAndTransformResultsToJestFormat (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
at async jestAdapter (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
at async runTestInternal (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:367:16)
at async runTest (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:444:34)

  at registerAndLogin (src/actions/auth-actions.ts:2233:13)
  at async Object.<anonymous> (src/__tests__/register-and-login.test.ts:162:24)

console.error
[registerAndLogin] Erro ao logar apos criacao: { message: 'Invalid credentials' }

  at registerAndLogin (src/actions/auth-actions.ts:2254:13)
  at async Object.<anonymous> (src/__tests__/register-and-login.test.ts:173:24)

console.error
[registerAndLogin] Erro ao criar usuario: { message: 'Database connection lost' }

  at registerAndLogin (src/actions/auth-actions.ts:2153:13)
  at async Object.<anonymous> (src/__tests__/register-and-login.test.ts:184:24)

PASS src/tests/register-and-login.test.ts
registerAndLogin — caminho feliz
✓ cria usuario, customer Stripe, atualiza metadata e loga (3 ms)
✓ nome sem sobrenome gera fullName so com nome (1 ms)
registerAndLogin — email duplicado
✓ retorna erro se email ja existe na tabela nutritionist (2 ms)
✓ retorna erro se createUser falha com "already exists" (3 ms)
registerAndLogin — falhas parciais
✓ falha no Stripe customer nao bloqueia — usuario e logado mesmo assim (4 ms)
✓ falha ao logar apos criacao retorna erro descritivo (6 ms)
✓ erro generico de createUser retorna a mensagem original (3 ms)

PASS src/components/tests/date-time-picker.test.tsx
DateTimePicker
✓ renderiza o rótulo e a data formatada (60 ms)
✓ abre o calendário e permite selecionar uma nova data (212 ms)
✓ não exibe o campo de hora quando allDay=true (11 ms)
✓ exibe e atualiza o campo de hora quando allDay=false (23 ms)
✓ desabilita o campo de hora e aplica estilos quando isTimeSlotDisabled retorna true (17 ms)

PASS src/tests/profile-form-crn.test.tsx
ProfileForm - CRN Fields Unit Tests
Separação de CRN existente
✓ deve separar CRN em prefixo e número (1 ms)
✓ deve separar CRN com sufixo /P (1 ms)
✓ deve lidar com CRN undefined (1 ms)
✓ deve lidar com CRN de prefixo duplo (1 ms)
Combinação de campos para salvar
✓ deve combinar prefixo e número ao salvar (1 ms)
✓ deve combinar com sufixo /P (1 ms)
✓ deve retornar undefined se campos vazios
✓ deve retornar undefined se apenas um campo preenchido
Auto-preenchimento de prefixo
✓ deve obter prefixo correto para MA (1 ms)
✓ deve obter prefixo correto para SP (1 ms)
✓ deve retornar undefined para estado não mapeado (1 ms)
Validação de entrada
✓ deve limitar prefixo a 2 dígitos (1 ms)
✓ deve aceitar apenas números no prefixo (1 ms)
✓ deve limitar número a 8 caracteres
✓ deve converter para maiúscula e filtrar caracteres inválidos
Fluxo completo - end to end
✓ deve carregar CRN existente, modificar e salvar
✓ deve permitir adicionar sufixo /P

PASS src/app/dashboard/agenda/tests/event-sheet-component.test.tsx
EventSheet Component
✓ deve renderizar o componente básico com DeleteConfirmationDialog (5 ms)
✓ deve renderizar o EventSheetModal por padrão (2 ms)
✓ deve renderizar o EventSheetEmbedded quando embedded=true (3 ms)
✓ deve chamar useEventSheet corretamente (2 ms)
✓ deve passar event quando fornecido (2 ms)
✓ deve passar selectedDate quando fornecido (2 ms)

PASS src/components/tests/register-form-integration.test.ts
Register Form - Error Notification Integration
✓ deve processar notificação de erro corretamente (2 ms)
✓ deve simular captura de dados do formulário (1 ms)
✓ deve funcionar com dados mínimos (1 ms)
✓ deve tratar erro de API graciosamente (1 ms)

console.error
🚨 Erro de cadastro detectado: {
errorData: {
userEmail: 'test@example.com',
userName: 'João Silva',
errorCode: 'AUTH_ERROR',
errorMessage: 'Email já cadastrado',
timestamp: '2026-06-09T17:33:15.690Z',
userAgent: 'Mozilla/5.0 (linux) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/26.1.0',
ip: undefined
},
originalError: { code: 'AUTH_ERROR', message: 'Email já cadastrado' },
additionalContext: undefined
}

  at ErrorNotificationService.notifyRegistrationError (src/utils/error-notification.ts:731:15)
  at Object.<anonymous> (src/utils/__tests__/error-notification-simple.test.ts:40:74)

console.log
✅ Emails de notificação de erro enviados: { success: true, adminEmailId: 'admin-123', userEmailId: 'user-456' }

  at ErrorNotificationService.notifyRegistrationError (src/utils/error-notification.ts:742:15)

console.error
🚨 Erro de cadastro detectado: {
errorData: {
userEmail: 'user@test.com',
userName: undefined,
errorCode: 'UNKNOWN_ERROR',
errorMessage: 'Erro sem código',
timestamp: '2026-06-09T17:33:15.693Z',
userAgent: 'Mozilla/5.0 (linux) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/26.1.0',
ip: undefined
},
originalError: { message: 'Erro sem código' },
additionalContext: undefined
}

  at ErrorNotificationService.notifyRegistrationError (src/utils/error-notification.ts:731:15)
  at Object.<anonymous> (src/utils/__tests__/error-notification-simple.test.ts:62:59)

console.log
✅ Emails de notificação de erro enviados: { success: true }

  at ErrorNotificationService.notifyRegistrationError (src/utils/error-notification.ts:742:15)

console.error
🚨 Erro de cadastro detectado: {
errorData: {
userEmail: 'user@example.com',
userName: 'Nome Usuario',
errorCode: 'AUTH_ERROR',
errorMessage: 'Email já cadastrado',
timestamp: '2026-06-09T17:33:15.696Z',
userAgent: 'Mozilla/5.0',
ip: '192.168.1.1'
},
originalError: { code: 'AUTH_ERROR', message: 'Email já cadastrado' },
additionalContext: {
userAgent: 'Mozilla/5.0',
ip: '192.168.1.1',
formData: { campo: 'valor' }
}
}

  at ErrorNotificationService.notifyRegistrationError (src/utils/error-notification.ts:731:15)
  at Object.<anonymous> (src/utils/__tests__/error-notification-simple.test.ts:82:59)

console.log
✅ Emails de notificação de erro enviados: { success: true }

  at ErrorNotificationService.notifyRegistrationError (src/utils/error-notification.ts:742:15)

console.error
🚨 Erro de cadastro detectado: {
errorData: {
userEmail: 'test@example.com',
userName: undefined,
errorCode: 'AUTH_ERROR',
errorMessage: 'Email já cadastrado',
timestamp: '2026-06-09T17:33:15.699Z',
userAgent: 'Mozilla/5.0 (linux) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/26.1.0',
ip: undefined
},
originalError: { code: 'AUTH_ERROR', message: 'Email já cadastrado' },
additionalContext: undefined
}

  at ErrorNotificationService.notifyRegistrationError (src/utils/error-notification.ts:731:15)
  at Object.<anonymous> (src/utils/__tests__/error-notification-simple.test.ts:99:74)

console.error
❌ Falha ao enviar emails de notificação de erro: Error: API indisponível
at Object. (/home/runner/work/connfit/connfit/src/utils/tests/error-notification-simple.test.ts:113:22)
at Promise.then.completed (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:298:28)
at new Promise ()
at callAsyncCircusFn (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/utils.js:231:10)
at _callCircusTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:316:40)
at async _runTest (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:252:3)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:126:9)
at async _runTestsForDescribeBlock (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:121:9)
at async run (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/run.js:71:3)
at async runAndTransformResultsToJestFormat (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
at async jestAdapter (/home/runner/work/connfit/connfit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
at async runTestInternal (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:367:16)
at async runTest (/home/runner/work/connfit/connfit/node_modules/jest-runner/build/runTest.js:444:34)

  at ErrorNotificationService.notifyRegistrationError (src/utils/error-notification.ts:750:15)
  at async Object.<anonymous> (src/utils/__tests__/error-notification-simple.test.ts:99:24)

console.error
🚨 Erro de cadastro detectado: {
errorData: {
userEmail: 'test@example.com',
userName: 'Test User',
errorCode: 'AUTH_ERROR',
errorMessage: 'Email já cadastrado',
timestamp: '2026-06-09T17:33:15.704Z',
userAgent: 'Mozilla/5.0 (linux) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/26.1.0',
ip: undefined
},
originalError: { code: 'AUTH_ERROR', message: 'Email já cadastrado' },
additionalContext: undefined
}

  at ErrorNotificationService.notifyRegistrationError (src/utils/error-notification.ts:731:15)
  at ErrorNotificationService.notifyRegistrationErrorSync (src/utils/error-notification.ts:794:10)
  at Object.<anonymous> (src/utils/__tests__/error-notification-simple.test.ts:112:53)

console.log
✅ Emails de notificação de erro enviados: { success: true }

  at ErrorNotificationService.notifyRegistrationError (src/utils/error-notification.ts:742:15)

PASS src/utils/tests/error-notification-simple.test.ts
Error Notification - Testes Básicos
✓ deve processar erro básico corretamente (3 ms)
✓ deve usar errorCode padrão quando não fornecido (3 ms)
✓ deve incluir contexto adicional quando fornecido (2 ms)
✓ deve retornar erro quando API falha (5 ms)
✓ notifyRegistrationErrorSync deve funcionar sem bloquear (12 ms)

PASS src/tests/paywall-trial-removal.test.ts
Paywall - trial removido do Checkout API
✓ rota de checkout nao deve passar trial_period_days (1 ms)
✓ rota de checkout nao deve aceitar parametro useTrial
Paywall - useTrial removido dos helpers
✓ src/utils/subscription-token-client.ts nao deve mais ter parametro useTrial (1 ms)
✓ src/utils/subscription-client.ts nao deve mais ter parametro useTrial
✓ src/actions/subscription-actions.ts nao deve mais ter parametro useTrial (1 ms)
Paywall - server action de pre-register
✓ deve exportar createPreRegisterCheckout (1 ms)
✓ deve setar metadata pre_register na Checkout Session
✓ deve passar mode subscription pra Stripe (1 ms)
✓ NAO deve passar trial_period_days na Checkout Session (1 ms)
✓ webhook deve tratar pre_register em handleCheckoutSessionCompleted (1 ms)
Paywall - register-form-checkout (fluxo novo)
✓ deve importar registerAndLogin de auth-actions (1 ms)
✓ deve redirecionar para /pagamento apos criacao de conta
✓ NAO deve usar Trigger.dev hooks (1 ms)
✓ NAO deve passar senha para createPreRegisterCheckout (1 ms)
Paywall - rota /cadastro-novo (fluxo paywall)
✓ pagina /cadastro-novo existe
✓ client wrapper usa RegisterFormCheckout (1 ms)

PASS src/tests/register-form-crn.test.tsx
RegisterForm - CRN Fields Unit Tests
Validação de máscara CRN
✓ deve limitar prefixo a 2 dígitos (1 ms)
✓ deve filtrar caracteres não numéricos do prefixo (1 ms)
✓ deve converter "p" para "P" maiúsculo
✓ deve filtrar caracteres inválidos do número (1 ms)
✓ deve limitar número a 8 caracteres
Combinação de campos CRN
✓ deve combinar prefixo e número (1 ms)
✓ deve combinar com prefixo de 2 dígitos
✓ deve combinar com sufixo /P (1 ms)
✓ deve lidar com campos vazios
Validação de prefixo CRN
✓ deve aceitar prefixo entre 1-14 (2 ms)
✓ deve rejeitar prefixo 0 (1 ms)
✓ deve rejeitar prefixo maior que 14 (1 ms)
Validação de número CRN
✓ deve aceitar número com 4 dígitos (1 ms)
✓ deve aceitar número com 6 dígitos (1 ms)
✓ deve aceitar número com sufixo /P
✓ deve rejeitar número com menos de 4 dígitos (9 ms)

PASS src/tests/paywall-pricing.test.ts
Paywall - precos catalogo (plans.ts)
✓ Essencial deve ter price R$ 119,90 (1 ms)
✓ Pro deve ter price R$ 349,90 (1 ms)
✓ Pro deve ter highlightedFeature de redes sociais
✓ Essencial nao deve ter mais buttonText "Teste Gratuito" (1 ms)
Paywall - parseBRL
✓ parseia "R$ 119,90" para 119.9 (1 ms)
✓ parseia "R$ 349,90" para 349.9
✓ parseia milhar com ponto: "R$ 1.249,00" para 1249 (1 ms)
✓ retorna 0 para string invalida
Paywall - calculateDiscount (logica de getPromotionalSavings)
✓ retorna null quando precos sao iguais (sem promo) (1 ms)
✓ retorna null quando preco atual e maior (sem promo)
✓ Essencial 119,90 -> 49,90 deve render ~58% OFF (1 ms)
✓ Pro 349,90 -> 179,00 deve render ~49% OFF (1 ms)
✓ arredonda corretamente: 100 -> 50 = 50% OFF (1 ms)
✓ retorna null quando preco invalido (1 ms)

console.error
Error: Not implemented: navigation (except hash changes)
at Object.replace (src/hooks/use-logout.ts:493:28)
at Object.logout (src/hooks/use-logout.ts:529:16)
at async (src/hooks/tests/use-logout.test.tsx:36:13) {
type: 'not implemented'
}

  at VirtualConsole.<anonymous> (node_modules/@jest/environment-jsdom-abstract/build/index.js:87:23)
  at module.exports (node_modules/jsdom/lib/jsdom/browser/not-implemented.js:12:26)
  at navigateFetch (node_modules/jsdom/lib/jsdom/living/window/navigation.js:77:3)
  at exports.navigate (node_modules/jsdom/lib/jsdom/living/window/navigation.js:55:3)
  at LocationImpl._locationObjectNavigate (node_modules/jsdom/lib/jsdom/living/window/Location-impl.js:30:5)
  at LocationImpl.replace (node_modules/jsdom/lib/jsdom/living/window/Location-impl.js:220:10)
  at Location.replace (node_modules/jsdom/lib/jsdom/living/generated/Location.js:94:36)
  at Object.replace (src/hooks/use-logout.ts:493:28)
  at Object.logout (src/hooks/use-logout.ts:529:16)
  at async /home/runner/work/connfit/connfit/src/hooks/__tests__/use-logout.test.tsx:36:13

console.error
Error: Not implemented: navigation (except hash changes)
at Object.replace (src/hooks/use-logout.ts:493:28)
at Object.logout (src/hooks/use-logout.ts:529:16)
at async (src/hooks/tests/use-logout.test.tsx:43:13) {
type: 'not implemented'
}

  at VirtualConsole.<anonymous> (node_modules/@jest/environment-jsdom-abstract/build/index.js:87:23)
  at module.exports (node_modules/jsdom/lib/jsdom/browser/not-implemented.js:12:26)
  at navigateFetch (node_modules/jsdom/lib/jsdom/living/window/navigation.js:77:3)
  at exports.navigate (node_modules/jsdom/lib/jsdom/living/window/navigation.js:55:3)
  at LocationImpl._locationObjectNavigate (node_modules/jsdom/lib/jsdom/living/window/Location-impl.js:30:5)
  at LocationImpl.replace (node_modules/jsdom/lib/jsdom/living/window/Location-impl.js:220:10)
  at Location.replace (node_modules/jsdom/lib/jsdom/living/generated/Location.js:94:36)
  at Object.replace (src/hooks/use-logout.ts:493:28)
  at Object.logout (src/hooks/use-logout.ts:529:16)
  at async /home/runner/work/connfit/connfit/src/hooks/__tests__/use-logout.test.tsx:43:13

console.error
Error: Not implemented: navigation (except hash changes)
at Object.replace (src/hooks/use-logout.ts:493:28)
at Object.logout (src/hooks/use-logout.ts:529:16)
at async (src/hooks/tests/use-logout.test.tsx:50:13) {
type: 'not implemented'
}

  at VirtualConsole.<anonymous> (node_modules/@jest/environment-jsdom-abstract/build/index.js:87:23)
  at module.exports (node_modules/jsdom/lib/jsdom/browser/not-implemented.js:12:26)

PASS src/hooks/tests/use-logout.test.tsx
at navigateFetch (node_modules/jsdom/lib/jsdom/living/window/navigation.js:77:3)
useLogout
at exports.navigate (node_modules/jsdom/lib/jsdom/living/window/navigation.js:55:3)
✓ deve limpar token cache ao deslogar (8 ms)
at LocationImpl._locationObjectNavigate (node_modules/jsdom/lib/jsdom/living/window/Location-impl.js:30:5)
✓ deve setar user atom pra null ao deslogar (4 ms)
at LocationImpl.replace (node_modules/jsdom/lib/jsdom/living/window/Location-impl.js:220:10)
✓ deve chamar signOut do supabase ao deslogar (4 ms)
at Location.replace (node_modules/jsdom/lib/jsdom/living/generated/Location.js:94:36)
✓ deve limpar connfit_user do localStorage ao deslogar (5 ms)
at Object.replace (src/hooks/use-logout.ts:493:28)
✓ deve redirecionar pra /auth ao deslogar via hard navigation (3 ms)
at Object.logout (src/hooks/use-logout.ts:529:16)

  at async /home/runner/work/connfit/connfit/src/hooks/__tests__/use-logout.test.tsx:50:13

console.error
Error: Not implemented: navigation (except hash changes)
at Object.replace (src/hooks/use-logout.ts:493:28)
at Object.logout (src/hooks/use-logout.ts:529:16)
at async (src/hooks/tests/use-logout.test.tsx:58:13) {
type: 'not implemented'
}

  at VirtualConsole.<anonymous> (node_modules/@jest/environment-jsdom-abstract/build/index.js:87:23)
  at module.exports (node_modules/jsdom/lib/jsdom/browser/not-implemented.js:12:26)
  at navigateFetch (node_modules/jsdom/lib/jsdom/living/window/navigation.js:77:3)
  at exports.navigate (node_modules/jsdom/lib/jsdom/living/window/navigation.js:55:3)
  at LocationImpl._locationObjectNavigate (node_modules/jsdom/lib/jsdom/living/window/Location-impl.js:30:5)
  at LocationImpl.replace (node_modules/jsdom/lib/jsdom/living/window/Location-impl.js:220:10)
  at Location.replace (node_modules/jsdom/lib/jsdom/living/generated/Location.js:94:36)
  at Object.replace (src/hooks/use-logout.ts:493:28)
  at Object.logout (src/hooks/use-logout.ts:529:16)
  at async /home/runner/work/connfit/connfit/src/hooks/__tests__/use-logout.test.tsx:58:13

PASS src/tests/orphan-customer-check.test.ts
resolveOrphanStatus — detecta se o usuário é orphan no Stripe
não é orphan
✓ tem stripe_customer_id na subscription (2 ms)
✓ tem stripe_customer_id no user_metadata (caso típico do fluxo novo: webhook ainda não chegou)
✓ tem stripe_customer_id nos dois lugares
✓ subscription sem o campo mas metadata com id (1 ms)
é orphan
✓ subscription null e metadata null
✓ subscription null e metadata sem stripe_customer_id (1 ms)
✓ subscription sem stripe_customer_id e metadata vazio
✓ subscription sem stripe_customer_id e metadata null (1 ms)

PASS src/tests/paywall-update-user-metadata.test.ts
updateUserMetadataTask (legacy flow)
✓ salva customer_id e subscription_id no user_metadata (2 ms)

PASS src/lib/route.test.ts
Switch of tests to route protect functions
✓ should match protected routes (13 ms)
✓ should not match unprotected routes (2 ms)

PASS src/tests/patients-list-new-features.test.tsx
PatientsInfiniteList - New Atoms
✓ should have multipleSelectionEnabledAtom with default value true (1 ms)
✓ should have urlSyncEnabledAtom with default value true
✓ should export the new atoms correctly (1 ms)

PASS src/tests/paywall-registration-flow.test.ts
Paywall - REGISTRATION_STEPS legacy estrutura
✓ deve conter todos os steps esperados (1 ms)

---------------------------------|---------|----------|---------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

File % Stmts % Branch % Funcs % Lines Uncovered Line #s
All files 55 47.45 47.5 56.45
actions 56.07 42.65 61.66 56.47
auth-actions.ts 56.92 65.51 25 56.92 8-57,80-85,102
availability.ts 77.07 63.73 100 77.41 98,107-125,141,153,158,169,185-186,202,243-247,275-276,283-284,290-291,316-317,324-325,359,385,391-392,411-412,429,444,458-459,525,541-543,583-584,597,627-628,670,684,703-704,772-773
calendar-action.ts 15.1 0 0 11.81 17-54,71-143,151-163,168-184,196-297,302-314,327-402
meals.ts 84.21 80.48 100 84.21 86-87,100-101,147,152-153,161,166-167,180-181,193,198-199,207,212-213,221,226-227
pre-register-checkout.ts 46.96 22.85 50 46.96 38-128,148
services.ts 10.86 0 0 12.19 7-35,39-45,49-101
subscription-actions.ts 50.72 37.07 37.5 50.72 12-37,50-58,63-64,122-253,337-338,343-344,352-355,396
app/dashboard/agenda 63.31 32 43.18 63.15
calendar-view.tsx 65 40.9 57.69 65.51 57-90,114-115,124-126,133-146,188,200-228
event-sheet.tsx 76.92 57.14 16.66 75 11-16,95
share-appointment-link.tsx 60.71 33.33 25 61.53 25-34,43-55
upcoming-appointments.tsx 53.57 6.66 25 51.85 23,27-36,41,88-131
components 70.37 90 20 73.07
date-time-picker.tsx 80 87.5 33.33 80 60-61,82
no-services-dialog.tsx 44.44 100 0 50 13-17
with-tooltip.tsx 100 100 100 100
components/medical-record 96.66 97.95 100 96.61
medical-insights.tsx 96.66 97.95 100 96.61 62-63
components/subscription 12.32 2.4 7.14 12.85
subscription-blocker.tsx 18.75 0 0 19.56 41-165
subscription-check.tsx 9.18 4.25 16.66 9.57 19-230
components/ui 84.21 75 86.66 86.41
alert-dialog.tsx 57.69 100 100 57.69 110-120
badge.tsx 83.33 100 100 100
button.tsx 100 66.66 100 100 184
calendar.tsx 100 100 100 100
card.tsx 81.81 100 71.42 100
input.tsx 100 100 100 100
label.tsx 100 100 100 100
popover.tsx 90.9 100 100 100
separator.tsx 100 75 100 100 22
tooltip.tsx 100 50 100 100 35
constants 83.33 100 100 100
plans.ts 100 100 100 100
tour-steps.ts 75 100 100 100
constants/emails 100 100 100 100
admin-email-data.ts 100 100 100 100
user-email-data.ts 100 100 100 100
forms/schemas 100 100 100 100
create-event-and-update.ts 100 100 100 100
hooks 80.57 72 70 82
use-debounce.ts 100 100 100 100
use-event-sheet.ts 88 78.57 86.95 90.52 251-275,288-306,335-336
use-logout.ts 100 100 100 100
use-medical-record-page.ts 89.23 78.57 76.92 88.88 53-54,108-109,142-145
use-selected-patients.ts 100 100 100 100
use-toast.ts 17.54 0 0 18.86 29-30,60-72,76-123,133-190
jotai/atoms 18.47 1.08 2.94 20.46
ai-chat.ts 66.66 100 100 100
alerts.ts 18.42 0 0 23.72 19-38,44-45,53-61,65-71,75-79,84-106,114-128
amazing-sidebar.ts 62.5 50 100 100 9
index.ts 100 100 100 100
leads.ts 66.66 100 100 100
nutritionist.ts 13.15 0 0 13.51 11-94
onboarding.ts 36.11 0 0 52 34-36,41-60
page-context.ts 12.19 0 0 13.51 52-141,147-149
page-header.ts 25 0 0 27.27 111-121,132-149
patients.ts 9.37 0 0 9.09 11-12,17-21,26-142,152-166,172-394,426-433,439-446,452-458,473-516,522-563,569-610,622-636,647-659,670-695,710-738
sidebar.ts 41.66 0 0 55.55 12-17
tour.ts 62.5 0 50 83.33 21-22
user-persistent.ts 19.64 7.69 20 20 29-30,35-67,74-131,139-156
lib 60 66.85 39.7 61.22
api-client.ts 78.84 65.11 62.5 79.38 77,127-129,150,159,192-204,221,236-238,249-256
appendHourToDate.ts 87.5 66.66 100 86.66 4,21
auth-server.ts 21.95 0 0 22.5 10-12,20-25,34-68,76-77,85-89,97-99
captcha.ts 0 0 0 0 1-16
connfit-api-client.ts 31.08 45.45 4.87 29.16 95-253,276
crn-utils.ts 96.29 92.85 100 97.82 62
dynamic-availability.ts 97.05 80.76 100 97.93 171-172
getIsoInterval.ts 20 0 0 25 2-7
intervalsChecker.ts 74.11 80.32 100 73.49 65,79-84,92-93,116-123,132-137,174-185,202-203,222-226,232
medical-record-encryption.ts 79.01 60 83.33 79.01 39,43,176-179,217-239
patient-form-utils.ts 100 97.29 100 100 63,67
route.ts 81.25 0 100 80 3,28,35
utils.ts 12.9 0 6.89 14.5 8-9,13,17-86,90-97,102-111,115-122,126-143,152-170,180-186,190-198,205,211-225,230-238,243-258
lib/connfit-bot 63.28 47.82 69.56 63.41
connfit-bot.ts 61.15 47.72 66.66 61.86 65,112,134-137,153-154,171-257,282-289,301-341,358-365,377-384
messages.ts 100 50 100 100 49
trigger 100 100 100 100
register-nutritionist-types.ts 100 100 100 100
update-user-metadata-task.ts 100 100 100 100
types/supabase 60 100 100 100
enums.ts 60 100 100 100
utils 70.84 67.4 73.91 71.14
availability-helpers.ts 90.56 98.11 100 90.56 18,41,49,116,176
availability-migration.ts 88.88 92.1 87.5 88.05 58,141-142,153-154,213-214,259
date-validations.ts 100 100 100 100
dayJs.ts 92.85 100 100 92.3 15
duration.ts 0 0 0 0 15-112
dynamic-stripe-prices.ts 84.16 78.78 68.42 85.59 32,37-39,88,189-201,218-219,307-317
error-notification.ts 90 70 75 90 105-112
subscription-token-client.ts 3.7 0 0 3.7 5-69
utils/supabase 26.66 0 0 28.57
client.ts 14.28 0 0 14.28 3-16
server.ts 30.43 100 0 33.33 7-20,29,36,43-59
--------------------------------- --------- ---------- --------- --------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Summary of all failing tests
FAIL src/tests/dynamic-availability-ranges.test.ts
● Dynamic Availability - Ranges (New Format) › getAvailableTimeSlotsFromRanges - Durações Não-Padrão › ✅ Serviço de 75min (1h15) deve respeitar limite do range
expect(received).not.toContain(expected) // indexOf

Expected value: not "15:15"
Received array:     ["14:00", "15:15"]

  120 |       // 15:15 + 75min = 16:30 ✗ (ultrapassa)
  121 |       expect(slots).toContain('14:00');
> 122 |       expect(slots).not.toContain('15:15'); // Não cabe mais
      |                         ^
  123 |       expect(slots).toHaveLength(1);
  124 |     });
  125 |

  at Object.<anonymous> (src/__tests__/dynamic-availability-ranges.test.ts:122:25)

● Dynamic Availability - Ranges (New Format) › getAvailableTimeSlotsFromRanges - Durações Não-Padrão › ✅ Serviço de 50min com múltiplos ranges

expect(received).not.toContain(expected) // indexOf

Expected value: not "15:50"
Received array:     ["08:00", "08:50", "13:30", "15:00", "15:50"]

  157 |       // Range 3: 15:00 + 50min = 15:50 ✓, 15:50 + 50min = 16:40 ✗
  158 |       expect(slots).toContain('15:00');
> 159 |       expect(slots).not.toContain('15:50'); // Não cabe
      |                         ^
  160 |
  161 |       expect(slots.length).toBeGreaterThanOrEqual(3);
  162 |     });

  at Object.<anonymous> (src/__tests__/dynamic-availability-ranges.test.ts:159:25)

● Dynamic Availability - Ranges (New Format) › getAvailableTimeSlotsFromRanges - Edge Cases › ✅ Serviços de durações muito longas (180min = 3h)

expect(received).not.toContain(expected) // indexOf

Expected value: not "17:00"
Received array:     ["08:00", "11:00", "14:00", "17:00"]

  337 |       expect(slots).toContain('11:00');
  338 |       expect(slots).toContain('14:00');
> 339 |       expect(slots).not.toContain('17:00'); // 17:00 + 180min = 20:00 (ultrapassa)
      |                         ^
  340 |       expect(slots).toHaveLength(3);
  341 |     });
  342 |   });

  at Object.<anonymous> (src/__tests__/dynamic-availability-ranges.test.ts:339:25)

FAIL src/tests/performance-stress.test.ts (26.119 s)
● ⚡ TESTE DE PERFORMANCE E STRESS › �� Stress Tests › ✅ Deve lidar com consultas extremamente longas

expect(received).toHaveLength(expected)

Expected length: 1
Received length: 2
Received array:  ["08:00", "16:00"]

  209 |       const slots8h = getAvailableTimeSlotsUnified(timeSlots, appointments, 480, targetDate);
  210 |       expect(slots8h).toContain('08:00'); // Única que cabe
> 211 |       expect(slots8h).toHaveLength(1);
      |                       ^
  212 |
  213 |       // Consulta de 12 horas (impossível)
  214 |       const slots12h = getAvailableTimeSlotsUnified(timeSlots, appointments, 720, targetDate);

  at Object.<anonymous> (src/__tests__/performance-stress.test.ts:211:23)

FAIL src/lib/tests/dynamic-availability.test.ts
● generateDynamicSlots › Caso 2 — 90 min, sem consultas › gera exatamente 08:00, 09:30, 11:00, 12:30, 14:00, 15:30

expect(received).toEqual(expected) // deep equality

- Expected  - 0
+ Received  + 1

@@ -3,6 +3,7 @@
    "09:30",
    "11:00",
    "12:30",
    "14:00",
    "15:30",
+   "17:00",
  ]

  68 |     it('gera exatamente 08:00, 09:30, 11:00, 12:30, 14:00, 15:30', () => {
  69 |       const slots = generateDynamicSlots(range08to18, 90, 0, FUTURE_DATE);
> 70 |       expect(slots).toEqual(['08:00', '09:30', '11:00', '12:30', '14:00', '15:30']);
     |                     ^
  71 |     });
  72 |
  73 |     it('não inclui 17:00 (17:00 + 90min = 18:30 extrapola 18:00)', () => {

  at Object.<anonymous> (src/lib/__tests__/dynamic-availability.test.ts:70:21)

● generateDynamicSlots › Caso 2 — 90 min, sem consultas › não inclui 17:00 (17:00 + 90min = 18:30 extrapola 18:00)

expect(received).not.toContain(expected) // indexOf

Expected value: not "17:00"
Received array:     ["08:00", "09:30", "11:00", "12:30", "14:00", "15:30", "17:00"]

  73 |     it('não inclui 17:00 (17:00 + 90min = 18:30 extrapola 18:00)', () => {
  74 |       const slots = generateDynamicSlots(range08to18, 90, 0, FUTURE_DATE);
> 75 |       expect(slots).not.toContain('17:00');
     |                         ^
  76 |     });
  77 |   });
  78 |

  at Object.<anonymous> (src/lib/__tests__/dynamic-availability.test.ts:75:25)

● getAvailableTimeSlotsFromRanges — casos canônicos issue #173 › Caso 2: 90min, sem consultas › gera exatamente 08:00, 09:30, 11:00, 12:30, 14:00, 15:30

expect(received).toEqual(expected) // deep equality

- Expected  - 0
+ Received  + 1

@@ -3,6 +3,7 @@
    "09:30",
    "11:00",
    "12:30",
    "14:00",
    "15:30",
+   "17:00",
  ]

  209 |     it('gera exatamente 08:00, 09:30, 11:00, 12:30, 14:00, 15:30', () => {
  210 |       const slots = getAvailableTimeSlotsFromRanges(availability08to18, [], 90, FUTURE_DATE, 0);
> 211 |       expect(slots).toEqual(['08:00', '09:30', '11:00', '12:30', '14:00', '15:30']);
      |                     ^
  212 |     });
  213 |
  214 |     it('não inclui 17:00 (17:00+90=18:30 > 18:00)', () => {

  at Object.<anonymous> (src/lib/__tests__/dynamic-availability.test.ts:211:21)

● getAvailableTimeSlotsFromRanges — casos canônicos issue #173 › Caso 2: 90min, sem consultas › não inclui 17:00 (17:00+90=18:30 > 18:00)

expect(received).not.toContain(expected) // indexOf

Expected value: not "17:00"
Received array:     ["08:00", "09:30", "11:00", "12:30", "14:00", "15:30", "17:00"]

  214 |     it('não inclui 17:00 (17:00+90=18:30 > 18:00)', () => {
  215 |       const slots = getAvailableTimeSlotsFromRanges(availability08to18, [], 90, FUTURE_DATE, 0);
> 216 |       expect(slots).not.toContain('17:00');
      |                         ^
  217 |     });
  218 |   });
  219 |

  at Object.<anonymous> (src/lib/__tests__/dynamic-availability.test.ts:216:25)

FAIL src/tests/dynamic-availability.test.ts
● dynamic-availability › generateDynamicSlots › should generate slots for available ranges

expect(received).toEqual(expected) // deep equality

- Expected  - 0
+ Received  + 1

  Array [
    "14:00",
    "15:10",
+   "16:20",
  ]

  153 |       // 15:10-16:10 (slot 2) + 10min break = 16:20
  154 |       // 16:20-17:20 would exceed 17:00 range, so only 2 slots fit
> 155 |       expect(result).toEqual(['14:00', '15:10']);
      |                      ^
  156 |     });
  157 |
  158 |     it('should generate slots for available ranges with different duration', () => {

  at Object.<anonymous> (src/__tests__/dynamic-availability.test.ts:155:22)

● dynamic-availability › generateDynamicSlots › should generate slots for available ranges with different duration

expect(received).toEqual(expected) // deep equality

- Expected  - 0
+ Received  + 1

  Array [
    "08:00",
+   "09:10",
  ]

  170 |       // 08:00-09:00 (slot 1) + 10min break = 09:10
  171 |       // 09:10-10:10 would exceed 10:00 range, so only 1 slot fits
> 172 |       expect(result).toEqual(['08:00']);
      |                      ^
  173 |     });
  174 |
  175 |     it('should handle ranges too small for service duration', () => {

  at Object.<anonymous> (src/__tests__/dynamic-availability.test.ts:172:22)

● dynamic-availability › generateDynamicSlots › should fit additional slot when remaining time allows

expect(received).toEqual(expected) // deep equality

- Expected  - 0
+ Received  + 1

  Array [
    "08:00",
    "09:10",
+   "10:20",
  ]

  204 |       // Actually: slot 1 (08:00-09:00), break (09:00-09:10), slot 2 (09:10-10:10), break (10:10-10:20)
  205 |       // Remaining: 190-140=50 minutes, can't fit another 60min slot
> 206 |       expect(result).toEqual(['08:00', '09:10']);
      |                      ^
  207 |     });
  208 |   });
  209 |

  at Object.<anonymous> (src/__tests__/dynamic-availability.test.ts:206:22)

● dynamic-availability › getAvailableTimeSlotsUnified › should integrate all functions correctly

expect(received).toEqual(expected) // deep equality

- Expected  - 0
+ Received  + 1

  Array [
    "14:00",
    "16:10",
+   "17:20",
  ]

  231 |       // Remaining: 14:00-15:00 (60min) and 16:10-18:00 (110min)
  232 |       // Slots: 14:00 and 16:10
> 233 |       expect(result).toEqual(['14:00', '16:10']);
      |                      ^
  234 |     });
  235 |
  236 |     it('should handle empty time slots', () => {

  at Object.<anonymous> (src/__tests__/dynamic-availability.test.ts:233:22)

Test Suites: 4 failed, 44 passed, 48 total
Tests: 12 failed, 776 passed, 788 total
Snapshots: 0 total
Time: 49.474 s
Ran all test suites.
Error: Process completed with exit code 1.
1s
0s
0s
0s

analise os testes e me retorne um prompt para o agent que ajuste os erros, nao quero que passe o teste apenas, quero que conserte as partes erradas