Files
COMERCIAL-GTI/tests/export.test.mjs
T
DESKTOP-F2O4A80\UserandClaude b8d10b210c Commit inicial: GTI Maquina Comercial
App local (Node + SQLite) para captura, tratamento e exportacao de leads
comerciais, com dashboard de gestao, login/usuarios e integracao Z-PRO.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-12 14:22:21 -03:00

120 lines
4.8 KiB
JavaScript

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('<td class="text">557193335451</td>'));
});
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();
});