'use strict'; const test = require('node:test'); const assert = require('node:assert/strict'); const { formatFallbackMessage, computeOperationalStatus, buildDestaques, formatShortMessage, } = require('../src/v2/format'); const { loadConfig } = require('../src/v2/config'); const config = loadConfig(); test('formatFallbackMessage reproduz o formato atual da V1 (numeros do exemplo da missao, 20/08)', () => { const row = { tipo_periodo: 'diario', periodo_label: '2026-08-20', abertos: 12, fechados: 11, pendentes: 22, alta_prioridade_pendentes: 3, saldo: -1, categorias_recorrentes: 'Software / SO: 4\nBug / Falha do Sistema: 2', clientes_volume: 'IMDI: 2 chamados\nLaboratorio da Cidade: 2 chamados', }; const texto = formatFallbackMessage(row); assert.match(texto, /Resumo diario do suporte GLPI/); assert.match(texto, /Data do relatorio: 2026-08-20/); assert.match(texto, /Chamados abertos no dia: 12/); assert.match(texto, /Chamados fechados no dia: 11/); assert.match(texto, /Pendentes atuais: 22/); assert.match(texto, /Alta prioridade ainda pendentes: 3/); assert.match(texto, /Saldo fechados - abertos: -1/); assert.match(texto, /Software \/ SO: 4/); assert.match(texto, /IMDI: 2 chamados/); }); test('formatFallbackMessage nunca lanca excecao com dados vazios (fallback tem que ser sempre seguro)', () => { assert.doesNotThrow(() => { formatFallbackMessage({ tipo_periodo: 'diario', periodo_label: '2026-08-20', abertos: 0, fechados: 0, pendentes: 0, alta_prioridade_pendentes: 0, saldo: 0, categorias_recorrentes: '', clientes_volume: '', }); }); }); test('computeOperationalStatus: sem insights e backlog estavel -> NORMAL', () => { const s = computeOperationalStatus({ insightsAceitos: [], tendenciaBacklog: { direcao: 'estavel' } }); assert.equal(s, 'NORMAL'); }); test('computeOperationalStatus: insight severity high -> CRITICAL mesmo com backlog estavel', () => { const s = computeOperationalStatus({ insightsAceitos: [{ severity: 'high' }], tendenciaBacklog: { direcao: 'estavel' }, }); assert.equal(s, 'CRITICAL'); }); test('computeOperationalStatus: backlog aumentando sem insights -> ATTENTION', () => { const s = computeOperationalStatus({ insightsAceitos: [], tendenciaBacklog: { direcao: 'aumentando' } }); assert.equal(s, 'ATTENTION'); }); test('buildDestaques nao produz mais itens que MAX_REPORT_INSIGHTS', () => { const insightsAceitos = Array.from({ length: 10 }, (_, i) => ({ title: `Insight ${i}`, occurrenceText: null })); const destaques = buildDestaques( { topCategoria: null, concentracoesCliente: [], altaPrioridadeDelta: null, insightsAceitos, unidade: 'no dia' }, config ); assert.ok(destaques.length <= config.MAX_REPORT_INSIGHTS); }); test('buildDestaques nao inventa destaque de alta prioridade quando o valor nao mudou', () => { const destaques = buildDestaques( { topCategoria: null, concentracoesCliente: [], altaPrioridadeDelta: { anterior: 3, atual: 3 }, insightsAceitos: [], unidade: 'no dia', }, config ); assert.equal(destaques.length, 0); }); test('formatShortMessage: mensagem diaria contem os numeros oficiais e fica curta (sem paragrafos longos)', () => { const { texto, status } = formatShortMessage( { tipo_periodo: 'diario', data_inicio: '2026-08-20', data_fim: '2026-08-20', abertos: 12, fechados: 11, saldo: -1, pendentes: 22, alta_prioridade_pendentes: 3, topCategoria: { nome: 'Software / SO', total: 4 }, concentracoesCliente: [], altaPrioridadeDelta: { anterior: 2, atual: 3 }, insightsAceitos: [], tendenciaBacklog: { direcao: 'aumentando', delta: 2 }, }, config ); assert.match(texto, /Resumo do suporte — 20\/08/); assert.match(texto, /12 abertos \| 11 fechados \| saldo -1/); assert.match(texto, /22 pendentes \| 3 alta prioridade/); assert.match(texto, /Software \/ SO liderou no dia com 4 chamados\./); assert.match(texto, /subiram de 2 para 3/); assert.equal(status, 'ATTENTION'); assert.ok(texto.length < 700, `mensagem deveria ser curta, tinha ${texto.length} chars`); }); test('formatShortMessage: sem nenhum destaque real, mostra a frase padrao (nao inventa observacao)', () => { const { texto } = formatShortMessage( { tipo_periodo: 'diario', data_inicio: '2026-08-20', data_fim: '2026-08-20', abertos: 5, fechados: 5, saldo: 0, pendentes: 10, alta_prioridade_pendentes: 1, topCategoria: null, concentracoesCliente: [], altaPrioridadeDelta: null, insightsAceitos: [], tendenciaBacklog: { direcao: 'estavel', delta: 0 }, }, config ); assert.match(texto, /Sem anomalias relevantes no periodo\./); }); test('formatShortMessage: mensagem semanal usa titulo e secao "Leitura"', () => { const { texto } = formatShortMessage( { tipo_periodo: 'semanal', data_inicio: '2026-08-17', data_fim: '2026-08-23', abertos: 51, fechados: 52, saldo: 1, pendentes: 21, alta_prioridade_pendentes: 3, topCategoria: { nome: 'Bug / Falha do Sistema', total: 9 }, concentracoesCliente: [], altaPrioridadeDelta: null, insightsAceitos: [], tendenciaBacklog: { direcao: 'estavel', delta: 0 }, }, config ); assert.match(texto, /Resumo semanal do suporte — 17\/08 a 23\/08/); assert.match(texto, /51 abertos \| 52 fechados \| saldo \+1/); assert.match(texto, /Leitura/); assert.match(texto, /→ Semana equilibrada/); });