import test from 'node:test'; import assert from 'node:assert/strict'; import fs from 'node:fs/promises'; import path from 'node:path'; import os from 'node:os'; import { openDb, createLeadInserter, seedSettings } from '../src/db.mjs'; import { exportExcel } from '../src/export/excel.mjs'; import { exportOportunidades, exportBulkDataInput } from '../src/export/zpro.mjs'; import { stripBom } from '../src/util/csv.mjs'; function seedLeads(db) { const insert = createLeadInserter(db); insert({ lead_uid: 'GTI-1', dedup_key: 'cnpj:57557263000113', empresa: 'PREMIUM EXPRESS', legal_name: 'PREMIUM EXPRESS LTDA', whatsapp: '557193335451', ddd: '71', email: '', cidade: 'Salvador', uf: 'BA', segmento: 'restaurantes', segmento_label: 'Restaurantes', interesse: 'Autoatendimento para WhatsApp', cnpj: '57557263000113', cnae: '5611203', endereco: '', website: '', pains_json: '[]', origem: 'cnpj-base', telefone_valido: 1, cnpj_valido: 1, empresa_valida: 1, score: 100, classificacao: 'bom', motivo_classificacao: 'ok', capture_run_id: null, captured_at: null, exported_at: null }); insert({ lead_uid: 'GTI-2', dedup_key: 'name:sem telefone:salvador', empresa: 'SEM TELEFONE', legal_name: '', whatsapp: '', ddd: '', email: '', cidade: 'Salvador', uf: 'BA', segmento: 'restaurantes', segmento_label: 'Restaurantes', interesse: '', cnpj: '', cnae: '', endereco: '', website: '', pains_json: '[]', origem: 'cnpj-base', telefone_valido: 0, cnpj_valido: 0, empresa_valida: 1, score: 35, classificacao: 'ruim', motivo_classificacao: 'score baixo', capture_run_id: null, captured_at: null, exported_at: null }); } async function withTempDir(fn) { const dir = await fs.mkdtemp(path.join(os.tmpdir(), 'gti-export-')); try { return await fn(dir); } finally { await fs.rm(dir, { recursive: true, force: true }); } } test('exportExcel gera CSV com formulas de texto e xls HTML', async () => { const db = openDb(':memory:'); seedLeads(db); await withTempDir(async (dir) => { const ids = []; const result = await exportExcel({ db, filtro: { uf: 'BA' }, dir, baseName: 'teste', collectIds: ids }); assert.equal(result.total, 2); assert.deepEqual(result.files, ['teste.csv', 'teste.xls']); assert.equal(ids.length, 2); const csv = stripBom(await fs.readFile(path.join(dir, 'teste.csv'), 'utf8')); const lines = csv.trim().split('\n'); assert.ok(lines[0].startsWith('empresa;whatsapp;ddd;cidade;uf;segmento;segmento_legivel')); assert.ok(lines[1].includes('"=""557193335451"""'), 'whatsapp deve ser formula de texto'); assert.ok(lines[1].includes('"=""57557263000113"""'), 'cnpj deve ser formula de texto'); assert.ok(lines[1].includes('cnpj:57557263000113'), 'chave_duplicidade presente'); const xls = await fs.readFile(path.join(dir, 'teste.xls'), 'utf8'); assert.ok(xls.includes('mso-number-format')); assert.ok(xls.includes('557193335451')); }); db.close(); }); test('exportOportunidades gera JSONL no formato Z-PRO testado', async () => { const db = openDb(':memory:'); seedSettings(db); seedLeads(db); await withTempDir(async (dir) => { const result = await exportOportunidades({ db, filtro: { classificacao: 'bom' }, params: {}, dir, baseName: 'op' }); assert.equal(result.total, 1); const lines = (await fs.readFile(path.join(dir, 'op.jsonl'), 'utf8')).trim().split('\n'); const payload = JSON.parse(lines[0]); assert.equal(payload.number, '557193335451'); assert.equal(payload.contactName, 'PREMIUM EXPRESS'); assert.equal(payload.name, 'PREMIUM EXPRESS - Autoatendimento para WhatsApp'); assert.equal(payload.pipelineId, 1); assert.equal(payload.stageId, 1); assert.equal(payload.responsibleId, 15); assert.equal(payload.status, 'open'); assert.equal(payload.validateNumber, true); assert.match(payload.closingForecast, /^\d{4}-\d{2}-\d{2}$/); assert.ok(payload.description.includes('CNPJ: 57557263000113')); }); db.close(); }); test('exportBulkDataInput inclui apenas leads com whatsapp', async () => { const db = openDb(':memory:'); seedSettings(db); seedLeads(db); await withTempDir(async (dir) => { const result = await exportBulkDataInput({ db, filtro: {}, params: { mensagem: 'Ola {empresa}!' }, dir, baseName: 'bulk' }); assert.equal(result.total, 1, 'lead sem whatsapp deve ficar de fora'); const csv = (await fs.readFile(path.join(dir, 'bulk-datainput.csv'), 'utf8')).trim(); assert.equal(csv, '557193335451,PREMIUM EXPRESS,Salvador,Restaurantes'); const info = await fs.readFile(path.join(dir, 'bulk-instrucoes.txt'), 'utf8'); assert.ok(info.includes('Ola {empresa}!')); assert.ok(info.includes('bulkSendMessageWithVariable')); }); db.close(); });