const assert = require('node:assert/strict'); const test = require('node:test'); const withCampaignService = async (queryHandler, callback) => { const dbPath = require.resolve('../db'); const servicePath = require.resolve('../services/campaignService'); const originalDbCache = require.cache[dbPath]; const originalServiceCache = require.cache[servicePath]; const queries = []; delete require.cache[servicePath]; require.cache[dbPath] = { id: dbPath, filename: dbPath, loaded: true, exports: { pool: { query: async (sql, params = []) => { queries.push({ sql, params }); return queryHandler(sql, params); } } } }; try { const service = require('../services/campaignService'); return await callback(service, queries); } finally { delete require.cache[servicePath]; if (originalServiceCache) { require.cache[servicePath] = originalServiceCache; } if (originalDbCache) { require.cache[dbPath] = originalDbCache; } else { delete require.cache[dbPath]; } } }; test('getTopClientsForCampaign returns top clients for an explicit date range', async () => { await withCampaignService(async () => ({ rows: [ { nome: 'Cliente A', fone: '5516999999901', total_gasto: '1234.50', total_comprado: '18', total_pedidos: 4, ultima_compra: '2026-07-27', telefones: ['5516999999901', '5516999999902'] } ] }), async ({ getTopClientsForCampaign }, queries) => { const result = await getTopClientsForCampaign({ start: '2026-06-28', end: '2026-07-27', limit: '1000' }); assert.equal(result.start, '2026-06-28'); assert.equal(result.end, '2026-07-27'); assert.equal(result.limit, 1000); assert.equal(result.count, 1); assert.deepEqual(result.customers[0], { nome: 'Cliente A', fone: '5516999999901', total_gasto: 1234.5, total_comprado: 18, total_pedidos: 4, ultima_compra: '2026-07-27', telefones: ['5516999999901', '5516999999902'] }); assert.equal(queries.length, 1); assert.deepEqual(queries[0].params, ['2026-06-28', '2026-07-27', 1000]); assert.match(queries[0].sql, /GROUP BY whatsapp_phone/); assert.doesNotMatch(queries[0].sql, /GROUP BY COALESCE\(canonical_customer_name, whatsapp_phone\)/); assert.match(queries[0].sql, /ARRAY_AGG\(DISTINCT whatsapp_phone\)/); assert.match(queries[0].sql, /ORDER BY total_gasto DESC/); }); }); test('getTopClientsForCampaign derives an inclusive 30 day range from the end date', async () => { await withCampaignService(async () => ({ rows: [] }), async ({ getTopClientsForCampaign }, queries) => { const result = await getTopClientsForCampaign({ days: '30', end: '2026-07-27' }); assert.equal(result.start, '2026-06-28'); assert.equal(result.end, '2026-07-27'); assert.equal(result.limit, 1000); assert.deepEqual(queries[0].params, ['2026-06-28', '2026-07-27', 1000]); }); }); test('getTopClientsForCampaign normalizes phones and groups one row per WhatsApp number', async () => { await withCampaignService(async () => ({ rows: [] }), async ({ getTopClientsForCampaign }, queries) => { await getTopClientsForCampaign({ days: '30', end: '2026-07-27' }); assert.match(queries[0].sql, /regexp_replace\(COALESCE\(cliente_fone, ''\), '\\D', '', 'g'\)/); assert.match(queries[0].sql, /WHEN length\(/); assert.match(queries[0].sql, /'55' \|\|/); assert.match(queries[0].sql, /GROUP BY whatsapp_phone/); }); });