Files
COMERCIAL-GTI/maquina-comercial-pessoal/tests/meta-security.test.mjs
T
GustavoandClaude Sonnet 5 417da56bd6 chore: import maquina-comercial-pessoal history via subtree
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

git-subtree-dir: maquina-comercial-pessoal
git-subtree-mainline: f5af038e19
git-subtree-split: a9ef4d776d
2026-09-28 15:50:17 -03:00

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;
});