====================================================== TDD: VoltarItemPendente — reset-item-missao ====================================================== --- BLOCO 1: AcaoExtrato::MISSAO_REABERTA --- ✅ [PASS] AcaoExtrato deve ter case MISSAO_REABERTA = 'MISSAO_REABERTA' ✅ [PASS] AcaoExtrato::descricao() deve retornar texto para MISSAO_REABERTA ✅ [PASS] AcaoExtrato::icon() deve retornar ícone para MISSAO_REABERTA ✅ [PASS] AcaoExtrato::categoria() deve classificar MISSAO_REABERTA como 'missao' ✅ [PASS] AcaoExtrato::MISSAO_REABERTA->value deve ser 'MISSAO_REABERTA' ✅ [PASS] descricao() retorna texto correto ✅ [PASS] icon() retorna ícone correto ✅ [PASS] categoria() retorna 'missao' --- BLOCO 2: StatusMissao — invariantes de gating --- ✅ [PASS] Status em_andamento deve estar na lista de permitidos ✅ [PASS] Status aguardando_aprovacao deve estar na lista de permitidos ✅ [PASS] Status pausada deve estar na lista de permitidos ✅ [PASS] Status pendente deve estar na lista de permitidos ✅ [PASS] Status rascunho deve estar na lista de permitidos ✅ [PASS] Status concluida NÃO deve estar na lista de permitidos ✅ [PASS] Status cancelada NÃO deve estar na lista de permitidos ✅ [PASS] Status em_andamento NÃO deve disparar rebote da missão ✅ [PASS] Status pausada NÃO deve disparar rebote da missão ✅ [PASS] Status pendente NÃO deve disparar rebote da missão ✅ [PASS] Status rascunho NÃO deve disparar rebote da missão ✅ [PASS] AGUARDANDO_APROVACAO e EM_ANDAMENTO são estados distintos (rebote é uma mudança real) ✅ [PASS] StatusItem::PENDENTE->value é 'pendente' --- BLOCO 3: Análise estática de MissoesItensEdicao::voltarItemPendente --- ✅ [PASS] Método voltarItemPendente deve existir em MissoesItensEdicao ✅ [PASS] voltarItemPendente deve zerar 'quantidade_bipada' => 0 ✅ [PASS] voltarItemPendente deve zerar 'dados_coletados' => null ✅ [PASS] voltarItemPendente NÃO deve alterar 'dados_adicionais' ✅ [PASS] voltarItemPendente deve zerar concluido_em e concluido_por ✅ [PASS] voltarItemPendente deve zerar iniciado_em e iniciado_por ✅ [PASS] voltarItemPendente deve zerar 'tempo_execucao' ✅ [PASS] voltarItemPendente deve zerar 'solicitou_recomeco' => 0 ✅ [PASS] voltarItemPendente deve definir status = StatusItem::PENDENTE->value ✅ [PASS] voltarItemPendente deve appendar observação '[Resetado p/ pendente por ...]' preservando o histórico ✅ [PASS] voltarItemPendente deve registrar extrato ITEM_REINICIADO ✅ [PASS] voltarItemPendente deve retornar info quando item já está pendente ✅ [PASS] voltarItemPendente deve verificar statusPermitidos antes de agir ✅ [PASS] voltarItemPendente deve testar StatusMissao::AGUARDANDO_APROVACAO para rebote ✅ [PASS] voltarItemPendente NÃO deve chamar transicionar() — rebote é via update direto ✅ [PASS] voltarItemPendente deve registrar extrato MISSAO_REABERTA no rebote ✅ [PASS] voltarItemPendente deve retornar mensagem mencionando rebote da missão ✅ [PASS] voltarItemPendente deve retornar mensagem simples quando missão não rebotou ✅ [PASS] voltarItemPendente deve tentar reverter o item se update da missão falhar ✅ [PASS] MissoesItensEdicao deve importar MissaoLogistica para o rebote --- BLOCO 4: Lógica pura de campos zerados (simulação sem banco) --- ✅ [PASS] Campo status zerado para 'pendente' ✅ [PASS] Campo quantidade_bipada zerado para 0 ✅ [PASS] Campo dados_coletados zerado para null ✅ [PASS] Campo concluido_em zerado para null ✅ [PASS] Campo concluido_por zerado para null ✅ [PASS] Campo iniciado_em zerado para null ✅ [PASS] Campo iniciado_por zerado para null ✅ [PASS] Campo tempo_execucao zerado para null ✅ [PASS] Campo solicitou_recomeco zerado para 0 ✅ [PASS] Observacoes preserva histórico e appenda o registro de reset ✅ [PASS] dados_adicionais NÃO deve estar no array de update (metadado de domínio intocado) --- BLOCO 5: Regras de gating por status da missão (lógica pura) --- ✅ [PASS] em_andamento + concluido → ok ✅ [PASS] em_andamento NÃO dispara rebote ✅ [PASS] aguardando_aprovacao + concluido → ok ✅ [PASS] aguardando_aprovacao dispara rebote ✅ [PASS] Mensagem de rebote correta ✅ [PASS] item já pendente → noop ✅ [PASS] concluida → bloqueado ✅ [PASS] cancelada → bloqueado ✅ [PASS] pausada + em_andamento → ok ✅ [PASS] pausada NÃO dispara rebote ✅ [PASS] pendente → ok ✅ [PASS] pendente NÃO dispara rebote ✅ [PASS] rascunho → ok ✅ [PASS] rascunho NÃO dispara rebote --- BLOCO 6: data-confirm-msg no designacao_painel.php --- ✅ [PASS] designacao_painel.php deve existir ✅ [PASS] data-confirm-msg deve mencionar Aguardando Aprovação ✅ [PASS] data-confirm-msg deve mencionar retorno para Em Andamento ✅ [PASS] Botão Reiniciar / voltarItemPendente ainda deve existir no painel ====================================================== RESULTADO: ✅ SUCESSO Passaram: 70 | Falharam: 0 ======================================================