Tracks the app that was already in place (capture, treatment, outreach, WhatsApp integration, server, frontend, tests, docs) so future feature work can branch and use isolated worktrees.
99 lines
4.2 KiB
JavaScript
99 lines
4.2 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { openDb, getSetting, seedSettings } from '../src/db.mjs';
|
|
import { createRouter } from '../src/server/router.mjs';
|
|
import { registerMetaRoutes } from '../src/server/routes/meta.mjs';
|
|
|
|
function setup({ whatsapp = { getStatus: () => ({ pendingSends: 0 }) } } = {}) {
|
|
const db = openDb(':memory:');
|
|
seedSettings(db);
|
|
const router = createRouter();
|
|
registerMetaRoutes(router, { db, jobs: { activeJobs: () => [] }, whatsapp });
|
|
return { db, router };
|
|
}
|
|
|
|
async function call(router, method, pathname, { body, user } = {}) {
|
|
const match = router.match(method, pathname);
|
|
let response;
|
|
await match.handler({}, {}, {
|
|
...match,
|
|
body,
|
|
user,
|
|
json(status, data) { response = { status, data }; }
|
|
});
|
|
return response;
|
|
}
|
|
|
|
test('somente admin altera configuracoes e apenas chaves permitidas', async () => {
|
|
const { db, router } = setup();
|
|
|
|
const denied = await call(router, 'PUT', '/api/settings', {
|
|
user: { role: 'comercial' },
|
|
body: { 'outreach.ativo': 'true' }
|
|
});
|
|
assert.equal(denied.status, 403);
|
|
assert.equal(getSetting(db, 'outreach.ativo'), 'false');
|
|
|
|
const unknown = await call(router, 'PUT', '/api/settings', {
|
|
user: { role: 'admin' },
|
|
body: { 'chave.arbitraria': 'valor' }
|
|
});
|
|
assert.equal(unknown.status, 400);
|
|
assert.equal(getSetting(db, 'chave.arbitraria'), null);
|
|
|
|
const allowed = await call(router, 'PUT', '/api/settings', {
|
|
user: { role: 'admin' },
|
|
body: { 'outreach.ativo': 'true', 'outreach.mensagensPorDia': '5' }
|
|
});
|
|
assert.equal(allowed.status, 200);
|
|
assert.equal(getSetting(db, 'outreach.ativo'), 'true');
|
|
assert.equal(getSetting(db, 'outreach.mensagensPorDia'), '5');
|
|
db.close();
|
|
});
|
|
|
|
test('settings valida meta, limite e booleano estritamente', async () => {
|
|
const { db, router } = setup();
|
|
for (const body of [
|
|
{ meta_diaria: '0' },
|
|
{ meta_diaria: '1.5' },
|
|
{ 'outreach.mensagensPorDia': '1001' },
|
|
{ 'outreach.ativo': 'sim' },
|
|
{ 'outreach.ativo': true }
|
|
]) assert.equal((await call(router, 'PUT', '/api/settings', { user: { role: 'admin' }, body })).status, 400);
|
|
assert.equal((await call(router, 'PUT', '/api/settings', { user: { role: 'admin' }, body: { meta_diaria: '500', 'outreach.mensagensPorDia': '20', 'outreach.ativo': 'false' } })).status, 200);
|
|
assert.equal(getSetting(db, 'meta_diaria'), '500');
|
|
db.close();
|
|
});
|
|
|
|
test('reset exige senha configurada e bloqueia enquanto ha job ativo', async () => {
|
|
const previous = process.env.APP_RESET_PASSWORD;
|
|
delete process.env.APP_RESET_PASSWORD;
|
|
const { db, router } = setup();
|
|
const admin = { role: 'admin' };
|
|
assert.equal((await call(router, 'POST', '/api/admin/reset', { user: admin, body: { senha: 'x' } })).status, 503);
|
|
process.env.APP_RESET_PASSWORD = 'segredo';
|
|
const busyRouter = createRouter();
|
|
registerMetaRoutes(busyRouter, { db, jobs: { activeJobs: () => [{ jobId: '1' }] }, whatsapp: { getStatus: () => ({ pendingSends: 0 }) } });
|
|
assert.equal((await call(busyRouter, 'POST', '/api/admin/reset', { user: admin, body: { senha: 'segredo' } })).status, 409);
|
|
if (previous === undefined) delete process.env.APP_RESET_PASSWORD;
|
|
else process.env.APP_RESET_PASSWORD = previous;
|
|
db.close();
|
|
});
|
|
|
|
test('reset bloqueia envio WhatsApp pendente e jobs persistentes fora do manager', async () => {
|
|
const previous = process.env.APP_RESET_PASSWORD;
|
|
process.env.APP_RESET_PASSWORD = 'segredo';
|
|
const admin = { role: 'admin' };
|
|
const sending = setup({ whatsapp: { getStatus: () => ({ pendingSends: 1 }) } });
|
|
assert.equal((await call(sending.router, 'POST', '/api/admin/reset', { user: admin, body: { senha: 'segredo' } })).status, 409);
|
|
sending.db.close();
|
|
|
|
const persistent = setup();
|
|
persistent.db.prepare("INSERT INTO exports (tipo, status) VALUES ('excel', 'pending')").run();
|
|
assert.equal((await call(persistent.router, 'POST', '/api/admin/reset', { user: admin, body: { senha: 'segredo' } })).status, 409);
|
|
assert.equal(persistent.db.prepare('SELECT COUNT(*) total FROM exports').get().total, 1);
|
|
persistent.db.close();
|
|
if (previous === undefined) delete process.env.APP_RESET_PASSWORD;
|
|
else process.env.APP_RESET_PASSWORD = previous;
|
|
});
|