import test from 'node:test'; import assert from 'node:assert/strict'; import { openDb, createLeadInserter, setSetting } from '../src/db.mjs'; import { dashboardSummary, dashboardDailyEvolution, dashboardMaiorOportunidade } from '../src/treatment/dashboard.mjs'; function seedLeads(db) { const insert = createLeadInserter(db); const base = { legal_name: '', whatsapp: '', ddd: '', email: '', segmento: '', segmento_label: '', interesse: '', cnpj: '', cnae: '', endereco: '', website: '', pains_json: '[]', origem: 'cnpj-base', telefone_valido: 0, cnpj_valido: 0, empresa_valida: 1, score: 50, classificacao: 'medio', motivo_classificacao: '', capture_run_id: null, captured_at: null }; const hoje = new Date().toISOString(); insert({ ...base, lead_uid: 'A', dedup_key: 'k1', empresa: 'A', cidade: 'Salvador', uf: 'BA', prioridade: 1, exported_at: hoje }); insert({ ...base, lead_uid: 'B', dedup_key: 'k2', empresa: 'B', cidade: 'Salvador', uf: 'BA', prioridade: 1, exported_at: null }); insert({ ...base, lead_uid: 'C', dedup_key: 'k3', empresa: 'C', cidade: 'Ilheus', uf: 'BA', prioridade: 2, exported_at: null }); insert({ ...base, lead_uid: 'D', dedup_key: 'k4', empresa: 'D', cidade: 'Ilheus', uf: 'BA', prioridade: 4, exported_at: null }); } test('dashboardSummary calcula totais, percentuais e meta diaria sobre a base toda', () => { const db = openDb(':memory:'); seedLeads(db); setSetting(db, 'meta_diaria', '2'); const s = dashboardSummary(db, {}); assert.equal(s.total, 4); assert.equal(s.p1, 2); assert.equal(s.p2, 1); assert.equal(s.p3, 0); assert.equal(s.p4, 1); assert.equal(s.potencial_pct, 50); assert.equal(s.p1_pct, 50); assert.equal(s.p4_pct, 25); assert.equal(s.exportados, 1); assert.equal(s.disponiveis, 3); assert.equal(s.cobertura_pct, 25); assert.equal(s.hoje_exportados, 1); assert.equal(s.meta_diaria, 2); assert.equal(s.meta_pct, 50); assert.equal(s.dias_estimados, 2); db.close(); }); test('dashboardSummary respeita o filtro (cidade) ao calcular percentuais', () => { const db = openDb(':memory:'); seedLeads(db); const s = dashboardSummary(db, { cidade: 'Ilheus' }); assert.equal(s.total, 2); assert.equal(s.p1, 0); assert.equal(s.p2, 1); assert.equal(s.p4, 1); assert.equal(s.p2_pct, 50); assert.equal(s.p4_pct, 50); assert.equal(s.exportados, 0); assert.equal(s.cobertura_pct, 0); db.close(); }); test('dashboardSummary com base vazia nao divide por zero', () => { const db = openDb(':memory:'); const s = dashboardSummary(db, {}); assert.equal(s.total, 0); assert.equal(s.potencial_pct, 0); assert.equal(s.cobertura_pct, 0); assert.equal(s.meta_pct, 0); assert.equal(s.dias_estimados, 0); db.close(); }); function seedLeadsComProdutos(db) { const insert = createLeadInserter(db); const base = { legal_name: '', whatsapp: '', ddd: '', email: '', segmento: '', segmento_label: '', interesse: '', cnpj: '', cnae: '', endereco: '', website: '', pains_json: '[]', origem: 'cnpj-base', telefone_valido: 0, cnpj_valido: 0, empresa_valida: 1, score: 50, classificacao: 'medio', motivo_classificacao: '', capture_run_id: null, captured_at: null, prioridade: 1, produtos_json: '[]' }; insert({ ...base, lead_uid: 'A', dedup_key: 'k1', empresa: 'A', cidade: 'Salvador', uf: 'BA', produto_principal: 'ERP', exported_at: '2026-07-10T10:00:00.000Z' }); insert({ ...base, lead_uid: 'B', dedup_key: 'k2', empresa: 'B', cidade: 'Salvador', uf: 'BA', produto_principal: 'ERP', exported_at: '2026-07-10T11:00:00.000Z' }); insert({ ...base, lead_uid: 'C', dedup_key: 'k3', empresa: 'C', cidade: 'Salvador', uf: 'BA', produto_principal: 'G-Chat', exported_at: '2026-07-11T09:00:00.000Z' }); insert({ ...base, lead_uid: 'D', dedup_key: 'k4', empresa: 'D', cidade: 'Ilheus', uf: 'BA', produto_principal: 'ERP', exported_at: null }); } test('dashboardDailyEvolution agrupa exportacoes por dia em ordem cronologica', () => { const db = openDb(':memory:'); seedLeadsComProdutos(db); const evolution = dashboardDailyEvolution(db, {}, 14).map((r) => ({ ...r })); assert.deepEqual(evolution, [ { dia: '2026-07-10', total: 2 }, { dia: '2026-07-11', total: 1 } ]); db.close(); }); test('dashboardDailyEvolution respeita o filtro', () => { const db = openDb(':memory:'); seedLeadsComProdutos(db); const evolution = dashboardDailyEvolution(db, { cidade: 'Ilheus' }, 14); assert.deepEqual(evolution, []); db.close(); }); test('dashboardMaiorOportunidade retorna a combinacao cidade+produto com mais empresas', () => { const db = openDb(':memory:'); seedLeadsComProdutos(db); const oportunidade = dashboardMaiorOportunidade(db, {}); assert.deepEqual({ ...oportunidade }, { cidade: 'Salvador', produto: 'ERP', total: 2 }); db.close(); }); test('dashboardMaiorOportunidade retorna null quando nao ha dados', () => { const db = openDb(':memory:'); assert.equal(dashboardMaiorOportunidade(db, {}), null); db.close(); });