import test from 'node:test'; import assert from 'node:assert/strict'; import { openDb } from '../src/db.mjs'; import { createCampaign, getCampaign, listCampaigns, setCampaignStatus, resumeCampaign, escalateWeeklyLimits, isOptedOut, addOptOut, removeOptOut } from '../src/outreach/campaign-store.mjs'; function campanhaBase(overrides = {}) { return { nome: 'ERP oficinas', produto: 'ERP', segmentos: ['oficinas_mecanicas', 'autopecas'], variantes: [{ code: 'A', mensagem: 'Ola {empresa}' }, { code: 'B', mensagem: 'Oi {empresa}' }], ...overrides }; } test('createCampaign grava campanha, segmentos e variantes', () => { const db = openDb(':memory:'); const campanha = createCampaign(db, campanhaBase()); assert.equal(campanha.status, 'rascunho'); assert.equal(campanha.produto, 'ERP'); assert.deepEqual(campanha.segmentos, ['oficinas_mecanicas', 'autopecas']); assert.equal(campanha.variants.length, 2); assert.equal(campanha.variants[0].code, 'A'); db.close(); }); test('listCampaigns retorna mais recente primeiro', () => { const db = openDb(':memory:'); createCampaign(db, campanhaBase({ nome: 'Primeira' })); createCampaign(db, campanhaBase({ nome: 'Segunda' })); const campanhas = listCampaigns(db); assert.equal(campanhas.length, 2); assert.equal(campanhas[0].nome, 'Segunda'); db.close(); }); test('setCampaignStatus pausa e resumeCampaign retoma limpando o motivo', () => { const db = openDb(':memory:'); const campanha = createCampaign(db, campanhaBase()); setCampaignStatus(db, campanha.id, 'rodando'); const pausada = setCampaignStatus(db, campanha.id, 'pausado', 'high_failure_rate'); assert.equal(pausada.status, 'pausado'); assert.equal(pausada.pause_reason, 'high_failure_rate'); const retomada = resumeCampaign(db, campanha.id); assert.equal(retomada.status, 'rodando'); assert.equal(retomada.pause_reason, null); db.close(); }); test('setCampaignStatus rodando stamps semana_iniciada_em on first transition', () => { const db = openDb(':memory:'); const campanha = createCampaign(db, campanhaBase()); assert.equal(campanha.semana_iniciada_em, null); const rodando = setCampaignStatus(db, campanha.id, 'rodando'); assert.notEqual(rodando.semana_iniciada_em, null, 'semana_iniciada_em should be set on first rodando transition'); db.close(); }); test('setCampaignStatus rodando does not reset already-set semana_iniciada_em', () => { const db = openDb(':memory:'); const campanha = createCampaign(db, campanhaBase()); // Set to rodando first time, which stamps semana_iniciada_em setCampaignStatus(db, campanha.id, 'rodando'); // Manually set to a known past value via raw SQL const knownTime = '2026-07-15 10:00:00'; db.prepare(`UPDATE outreach_campaigns SET semana_iniciada_em = ? WHERE id = ?`).run(knownTime, campanha.id); // Call setCampaignStatus again while already 'rodando' const unchanged = setCampaignStatus(db, campanha.id, 'rodando'); // Verify semana_iniciada_em was not changed assert.equal(unchanged.semana_iniciada_em, knownTime, 'semana_iniciada_em should not be reset on subsequent rodando calls'); db.close(); }); test('resumeCampaign nao faz nada se a campanha nao estiver pausada', () => { const db = openDb(':memory:'); const campanha = createCampaign(db, campanhaBase()); const resultado = resumeCampaign(db, campanha.id); assert.equal(resultado.status, 'rascunho'); db.close(); }); test('escalateWeeklyLimits dobra o limite apos 7 dias rodando, respeitando o teto', () => { const db = openDb(':memory:'); const campanha = createCampaign(db, campanhaBase({ limiteDiarioInicial: 10, limiteDiarioTeto: 15 })); setCampaignStatus(db, campanha.id, 'rodando'); db.prepare(`UPDATE outreach_campaigns SET semana_iniciada_em = datetime('now', '-8 days') WHERE id = ?`).run(campanha.id); const escaladas = escalateWeeklyLimits(db); assert.equal(escaladas, 1); const atualizada = getCampaign(db, campanha.id); assert.equal(atualizada.limite_diario_atual, 15); // dobraria pra 20, mas o teto e 15 db.close(); }); test('escalateWeeklyLimits nao avanca campanha pausada nem antes de 7 dias', () => { const db = openDb(':memory:'); const rodando = createCampaign(db, campanhaBase({ nome: 'Rodando ha pouco' })); setCampaignStatus(db, rodando.id, 'rodando'); db.prepare(`UPDATE outreach_campaigns SET semana_iniciada_em = datetime('now', '-2 days') WHERE id = ?`).run(rodando.id); const pausada = createCampaign(db, campanhaBase({ nome: 'Pausada' })); setCampaignStatus(db, pausada.id, 'rodando'); setCampaignStatus(db, pausada.id, 'pausado', 'manual'); db.prepare(`UPDATE outreach_campaigns SET semana_iniciada_em = datetime('now', '-10 days') WHERE id = ?`).run(pausada.id); const escaladas = escalateWeeklyLimits(db); assert.equal(escaladas, 0); db.close(); }); test('opt-out: addOptOut bloqueia, removeOptOut libera', () => { const db = openDb(':memory:'); assert.equal(isOptedOut(db, '5511999990001'), false); addOptOut(db, '5511999990001', 'pediu pra parar'); assert.equal(isOptedOut(db, '5511999990001'), true); removeOptOut(db, '5511999990001'); assert.equal(isOptedOut(db, '5511999990001'), false); db.close(); });