178 lines
7.6 KiB
JavaScript
178 lines
7.6 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import path from 'node:path';
|
|
import fs from 'node:fs/promises';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const root = path.dirname(path.dirname(fileURLToPath(import.meta.url)));
|
|
|
|
test('package e ambiente usam identidade e caminhos pessoais', async () => {
|
|
const pkg = JSON.parse(await fs.readFile(path.join(root, 'package.json'), 'utf8'));
|
|
assert.equal(pkg.name, 'maquina-comercial-pessoal');
|
|
assert.equal(pkg.dependencies.baileys, '7.0.0-rc14');
|
|
assert.equal(pkg.dependencies.qrcode, '1.5.4');
|
|
|
|
const previous = { ...process.env };
|
|
delete process.env.APP_PORT;
|
|
delete process.env.APP_DB_PATH;
|
|
delete process.env.APP_WHATSAPP_AUTH_DIR;
|
|
const env = await import(`../src/env.mjs?personal=${Date.now()}`);
|
|
assert.equal(env.APP_PORT, 3910);
|
|
assert.equal(env.paths.db, path.join(root, 'data', 'maquina-pessoal.db'));
|
|
assert.equal(env.paths.whatsappAuth, path.join(root, 'data', 'runtime', 'whatsapp-auth'));
|
|
process.env = previous;
|
|
});
|
|
|
|
test('schema pessoal possui opt-outs e identificador generico de mensagem', async () => {
|
|
const { openDb } = await import('../src/db.mjs');
|
|
const db = openDb(':memory:');
|
|
const tables = db.prepare("SELECT name FROM sqlite_master WHERE type='table'").all().map(({ name }) => name);
|
|
assert.ok(tables.includes('outreach_opt_outs'));
|
|
const columns = db.prepare('PRAGMA table_info(outreach_sends)').all().map(({ name }) => name);
|
|
assert.ok(columns.includes('provider_message_id'));
|
|
assert.ok(!columns.includes('zpro_ticket_id'));
|
|
db.close();
|
|
});
|
|
|
|
test('settings pessoais sao conservadores e nao incluem credenciais corporativas', async () => {
|
|
const { openDb, seedSettings, getSetting } = await import('../src/db.mjs');
|
|
const db = openDb(':memory:');
|
|
seedSettings(db);
|
|
assert.equal(getSetting(db, 'outreach.ativo'), 'false');
|
|
assert.equal(getSetting(db, 'outreach.mensagensPorDia'), '10');
|
|
assert.equal(getSetting(db, 'outreach.intervaloMinMs'), '5000');
|
|
assert.equal(getSetting(db, 'outreach.intervaloMaxMs'), '12000');
|
|
assert.equal(db.prepare("SELECT COUNT(*) total FROM settings WHERE key LIKE 'zpro.%' OR key LIKE 'gchat.%'").get().total, 0);
|
|
db.close();
|
|
});
|
|
|
|
test('helpers de opt-out adicionam, listam, consultam e removem sem o reset apagar', async () => {
|
|
const { openDb, addOptOut, listOptOuts, isOptedOut, removeOptOut, resetLeadsBase } = await import('../src/db.mjs');
|
|
const db = openDb(':memory:');
|
|
addOptOut(db, '55 (11) 99999-0001', 'pedido do contato');
|
|
assert.equal(isOptedOut(db, '5511999990001'), true);
|
|
assert.equal(listOptOuts(db)[0].motivo, 'pedido do contato');
|
|
resetLeadsBase(db);
|
|
assert.equal(isOptedOut(db, '5511999990001'), true);
|
|
assert.equal(removeOptOut(db, '5511999990001'), true);
|
|
assert.equal(isOptedOut(db, '5511999990001'), false);
|
|
db.close();
|
|
});
|
|
|
|
test('opt-out bloqueia e remove as formas equivalentes com e sem nono digito', async () => {
|
|
const { openDb, addOptOut, isOptedOut, removeOptOut } = await import('../src/db.mjs');
|
|
const db = openDb(':memory:');
|
|
addOptOut(db, '5575999091780', 'solicitado');
|
|
assert.equal(isOptedOut(db, '557599091780'), true);
|
|
assert.equal(removeOptOut(db, '557599091780'), true);
|
|
assert.equal(isOptedOut(db, '5575999091780'), false);
|
|
db.close();
|
|
});
|
|
|
|
test('listagem e detalhe derivam o estado da verificacao equivalente mais recente', async () => {
|
|
const { openDb, saveWhatsAppVerification } = await import('../src/db.mjs');
|
|
const { getLead, listLeads } = await import('../src/treatment/queries.mjs');
|
|
const db = openDb(':memory:');
|
|
const inserted = db.prepare(
|
|
`INSERT INTO leads (dedup_key, empresa, whatsapp, telefone_valido)
|
|
VALUES ('telefone:5575999091780', 'Lead verificado', '5575999091780', 1)`
|
|
).run();
|
|
|
|
saveWhatsAppVerification(db, {
|
|
numero: '5575999091780',
|
|
status: 'confirmado',
|
|
numeroResolvido: '5575999091780',
|
|
variante: 'exata'
|
|
});
|
|
saveWhatsAppVerification(db, {
|
|
numero: '557599091780',
|
|
status: 'nao_cadastrado'
|
|
});
|
|
db.prepare("UPDATE whatsapp_number_verifications SET checked_at = '2026-07-29 12:00:00'").run();
|
|
|
|
const cached = db.prepare(
|
|
'SELECT numero, rowid FROM whatsapp_number_verifications ORDER BY rowid'
|
|
).all();
|
|
assert.deepEqual(cached.map((row) => row.numero), ['5575999091780', '557599091780']);
|
|
assert.ok(cached[1].rowid > cached[0].rowid);
|
|
|
|
const detail = getLead(db, Number(inserted.lastInsertRowid));
|
|
assert.equal(detail.whatsapp_status, 'nao_cadastrado');
|
|
assert.equal(detail.whatsapp_numero_resolvido, null);
|
|
assert.equal(detail.whatsapp_checked_at, '2026-07-29 12:00:00');
|
|
assert.equal(detail.telefone_valido, 1);
|
|
|
|
const listed = listLeads(db).rows[0];
|
|
assert.equal(listed.whatsapp_status, 'nao_cadastrado');
|
|
assert.equal(listed.whatsapp_numero_resolvido, null);
|
|
assert.equal(listed.whatsapp_checked_at, '2026-07-29 12:00:00');
|
|
assert.equal(listed.telefone_valido, 1);
|
|
|
|
saveWhatsAppVerification(db, {
|
|
numero: '5575999091780',
|
|
status: 'confirmado',
|
|
numeroResolvido: '557599091780',
|
|
variante: 'sem_nono_digito'
|
|
});
|
|
db.prepare("UPDATE whatsapp_number_verifications SET checked_at = '2026-07-29 12:00:00'").run();
|
|
const updated = getLead(db, Number(inserted.lastInsertRowid));
|
|
assert.equal(updated.whatsapp_status, 'confirmado');
|
|
assert.equal(updated.whatsapp_numero_resolvido, '557599091780');
|
|
db.close();
|
|
});
|
|
|
|
test('lead sem verificacao equivalente permanece nao consultado', async () => {
|
|
const { openDb } = await import('../src/db.mjs');
|
|
const { getLead, listLeads } = await import('../src/treatment/queries.mjs');
|
|
const db = openDb(':memory:');
|
|
const inserted = db.prepare(
|
|
`INSERT INTO leads (dedup_key, empresa, whatsapp, telefone_valido)
|
|
VALUES ('telefone:5511999990001', 'Lead novo', '5511999990001', 1)`
|
|
).run();
|
|
|
|
const detail = getLead(db, Number(inserted.lastInsertRowid));
|
|
const listed = listLeads(db).rows[0];
|
|
for (const lead of [detail, listed]) {
|
|
assert.equal(lead.whatsapp_status, 'nao_consultado');
|
|
assert.equal(lead.whatsapp_numero_resolvido, null);
|
|
assert.equal(lead.whatsapp_checked_at, null);
|
|
assert.equal(lead.telefone_valido, 1);
|
|
}
|
|
db.close();
|
|
});
|
|
|
|
test('listagem e detalhe marcam numero compartilhado por mais de um lead', async () => {
|
|
const { openDb, addSharedNumberOverride } = await import('../src/db.mjs');
|
|
const { getLead, listLeads } = await import('../src/treatment/queries.mjs');
|
|
const db = openDb(':memory:');
|
|
const sharedA = db.prepare(
|
|
`INSERT INTO leads (dedup_key, empresa, whatsapp, telefone_valido)
|
|
VALUES ('shared-a', 'Contabilidade Cliente A', '5575999091780', 1)`
|
|
).run();
|
|
db.prepare(
|
|
`INSERT INTO leads (dedup_key, empresa, whatsapp, telefone_valido)
|
|
VALUES ('shared-b', 'Contabilidade Cliente B', '557599091780', 1)`
|
|
).run();
|
|
const solo = db.prepare(
|
|
`INSERT INTO leads (dedup_key, empresa, whatsapp, telefone_valido)
|
|
VALUES ('solo', 'Empresa Unica', '5511999990001', 1)`
|
|
).run();
|
|
|
|
const rows = listLeads(db).rows;
|
|
const shared = rows.find((row) => row.id === Number(sharedA.lastInsertRowid));
|
|
const unique = rows.find((row) => row.id === Number(solo.lastInsertRowid));
|
|
assert.equal(shared.numero_compartilhado, true);
|
|
assert.equal(shared.numero_compartilhado_total, 2);
|
|
assert.equal(shared.numero_compartilhado_liberado, false);
|
|
assert.equal(unique.numero_compartilhado, false);
|
|
assert.equal(unique.numero_compartilhado_total, 0);
|
|
|
|
const detail = getLead(db, Number(sharedA.lastInsertRowid));
|
|
assert.equal(detail.numero_compartilhado, true);
|
|
|
|
addSharedNumberOverride(db, '5575999091780', 'revisado');
|
|
const refreshed = getLead(db, Number(sharedA.lastInsertRowid));
|
|
assert.equal(refreshed.numero_compartilhado_liberado, true);
|
|
db.close();
|
|
});
|