import test from 'node:test'; import assert from 'node:assert/strict'; import { openDb, createLeadInserter, transaction, getSetting, setSetting, seedSegments, seedMunicipios, seedGeoCache, seedSettings, seedMessageTemplates, updateMessageTemplate } from '../src/db.mjs'; function sampleLead(overrides = {}) { return { lead_uid: 'GTI-TEST-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: 'RUA X, 1', website: '', pains_json: '["atendimento"]', 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: '2026-07-09T14:26:18.560Z', exported_at: null, ...overrides }; } test('openDb cria esquema e aplica migrations uma unica vez', () => { const db = openDb(':memory:'); const version = db.prepare('SELECT MAX(version) AS v FROM schema_migrations').get().v; assert.ok(version >= 1); const tables = db.prepare("SELECT name FROM sqlite_master WHERE type='table'").all().map((r) => r.name); for (const table of ['leads', 'capture_runs', 'extractions', 'exports', 'export_leads', 'segments', 'municipios', 'geo_cache', 'settings']) { assert.ok(tables.includes(table), `tabela ${table} ausente`); } db.close(); }); test('createLeadInserter insere e ignora duplicata pela dedup_key', () => { const db = openDb(':memory:'); const insert = createLeadInserter(db); assert.equal(insert(sampleLead()), 'inserted'); assert.equal(insert(sampleLead({ empresa: 'OUTRO NOME' })), 'duplicate'); const total = db.prepare('SELECT COUNT(*) AS t FROM leads').get().t; assert.equal(total, 1); db.close(); }); test('transaction faz rollback em erro', () => { const db = openDb(':memory:'); const insert = createLeadInserter(db); assert.throws(() => transaction(db, () => { insert(sampleLead()); throw new Error('boom'); }) ); assert.equal(db.prepare('SELECT COUNT(*) AS t FROM leads').get().t, 0); db.close(); }); test('settings: get/set e seed com defaults Z-PRO', () => { const db = openDb(':memory:'); seedSettings(db); assert.equal(getSetting(db, 'zpro.pipelineId'), '1'); assert.equal(getSetting(db, 'zpro.stageId'), '1'); assert.equal(getSetting(db, 'zpro.responsibleId'), '15'); setSetting(db, 'zpro.pipelineId', '9'); assert.equal(getSetting(db, 'zpro.pipelineId'), '9'); // seed nao sobrescreve valor ja definido pelo usuario seedSettings(db); assert.equal(getSetting(db, 'zpro.pipelineId'), '9'); db.close(); }); test('message_templates salva variaveis WABA automaticas por produto', () => { const db = openDb(':memory:'); seedMessageTemplates(db, ['ERP']); const updated = updateMessageTemplate(db, 'ERP', { canal: 'oficial', templateWabaNome: 'gti_inicio_atendimento_solicitado', templateWabaIdioma: 'pt_BR', templateWabaVariaveis: ['{empresa}', 'Assunto: {produto}', ''] }); assert.equal(updated.template_waba_nome, 'gti_inicio_atendimento_solicitado'); assert.deepEqual(JSON.parse(updated.template_waba_variaveis_json), ['{empresa}', 'Assunto: {produto}']); db.close(); }); test('seeds de segments, municipios e geo_cache', () => { const db = openDb(':memory:'); seedSegments(db, [ { name: 'clinicas_medicas', queries: ['clinica'], cnaeCodes: ['8630501'], overpassTags: [{ key: 'amenity', value: 'clinic' }], interest: 'gestao de TI', pains: ['agenda'] } ]); const segment = db.prepare('SELECT * FROM segments WHERE name = ?').get('clinicas_medicas'); assert.equal(segment.label, 'Clinicas Medicas'); assert.deepEqual(JSON.parse(segment.cnae_codes_json), ['8630501']); seedMunicipios(db, [{ codigo_ibge: '2928703', nome: 'Santo Antônio de Jesus', uf: 'BA' }]); const municipio = db.prepare('SELECT * FROM municipios WHERE uf = ?').get('BA'); assert.equal(municipio.nome_clean, 'santo antonio de jesus'); seedGeoCache(db, [{ name: 'Santo Antonio de Jesus', state: 'BA', bbox: [-12.995, -39.325, -12.925, -39.225] }]); const bbox = db.prepare('SELECT * FROM geo_cache WHERE key = ?').get('bbox:BA:santo antonio de jesus'); assert.equal(bbox.south, -12.995); assert.equal(bbox.provider, 'config-legacy'); db.close(); }); test('migracao v8 cria as tabelas de campanha de outreach', () => { const db = openDb(':memory:'); const tabelas = db.prepare( `SELECT name FROM sqlite_master WHERE type='table' AND name LIKE 'outreach_%'` ).all().map((r) => r.name); for (const nome of [ 'outreach_campaigns', 'outreach_campaign_variants', 'outreach_campaign_queue', 'outreach_lead_states', 'outreach_stage_events', 'outreach_appointments', 'outreach_opt_out' ]) { assert.ok(tabelas.includes(nome), `tabela ${nome} deveria existir`); } db.prepare(`INSERT INTO outreach_campaigns (nome, produto, segmentos_json) VALUES ('Teste', 'ERP', '["oficinas"]')`).run(); const campanha = db.prepare('SELECT * FROM outreach_campaigns').get(); assert.equal(campanha.status, 'rascunho'); assert.equal(campanha.limite_diario_atual, 10); db.close(); });