Files
COMERCIAL-GTI/tests/alerts.test.mjs
T
2026-09-28 15:48:44 -03:00

90 lines
3.7 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs/promises';
import os from 'node:os';
import path from 'node:path';
import { createTelegramAlerter } from '../src/alerts/telegram.mjs';
import { loadDotEnv, telegramConfig } from '../src/env.mjs';
test('telegram alert skips when disabled or missing config', async () => {
const calls = [];
const alerter = createTelegramAlerter({ enabled: false, token: '', chatId: '', fetchImpl: async (...args) => calls.push(args) });
assert.deepEqual(await alerter.alert('qr', 'QR necessario'), { sent: false, reason: 'disabled' });
assert.equal(calls.length, 0);
const missingConfigAlerter = createTelegramAlerter({ enabled: true, token: '', chatId: '', fetchImpl: async (...args) => calls.push(args) });
assert.deepEqual(await missingConfigAlerter.alert('qr', 'QR necessario'), { sent: false, reason: 'not_configured' });
assert.equal(calls.length, 0);
});
test('telegram alert sends message without leaking token to text', async () => {
const calls = [];
const fetchImpl = async (url, options) => {
calls.push({ url, options });
return { ok: true, json: async () => ({ ok: true }) };
};
const alerter = createTelegramAlerter({ enabled: true, token: '123:SECRET', chatId: '456', fetchImpl });
assert.deepEqual(await alerter.alert('qr', 'WhatsApp precisa de QR'), { sent: true });
assert.equal(calls.length, 1);
assert.match(calls[0].url, /sendMessage$/);
const payload = JSON.parse(calls[0].options.body);
assert.equal(payload.chat_id, '456');
assert.equal(payload.text, 'WhatsApp precisa de QR');
assert.doesNotMatch(payload.text, /SECRET/);
});
test('telegram alert deduplicates per key within cooldown', async () => {
let current = 1000;
const calls = [];
const fetchImpl = async (...args) => {
calls.push(args);
return { ok: true, json: async () => ({ ok: true }) };
};
const alerter = createTelegramAlerter({ enabled: true, token: 't', chatId: 'c', fetchImpl, now: () => current, cooldownMs: 1000 });
assert.equal((await alerter.alert('same', 'A')).sent, true);
assert.deepEqual(await alerter.alert('same', 'A again'), { sent: false, reason: 'cooldown' });
current = 2501;
assert.equal((await alerter.alert('same', 'A later')).sent, true);
assert.equal(calls.length, 2);
});
test('telegram alert sends first message when clock starts at zero', async () => {
const calls = [];
const fetchImpl = async (...args) => {
calls.push(args);
return { ok: true, json: async () => ({ ok: true }) };
};
const alerter = createTelegramAlerter({ enabled: true, token: 't', chatId: 'c', fetchImpl, now: () => 0, cooldownMs: 1000 });
assert.equal((await alerter.alert('zero', 'First')).sent, true);
assert.deepEqual(await alerter.alert('zero', 'Second'), { sent: false, reason: 'cooldown' });
assert.equal(calls.length, 1);
});
test('telegram config reflects values loaded from dotenv', async () => {
const keys = ['TELEGRAM_ALERTS_ENABLED', 'TELEGRAM_BOT_TOKEN', 'TELEGRAM_CHAT_ID'];
const previous = Object.fromEntries(keys.map((key) => [key, process.env[key]]));
const rootDir = await fs.mkdtemp(path.join(os.tmpdir(), 'telegram-env-'));
try {
for (const key of keys) delete process.env[key];
await fs.writeFile(
path.join(rootDir, '.env'),
'TELEGRAM_ALERTS_ENABLED=true\nTELEGRAM_BOT_TOKEN=123:SECRET\nTELEGRAM_CHAT_ID=456\n'
);
await loadDotEnv(rootDir);
assert.deepEqual(telegramConfig(), {
enabled: true,
botToken: '123:SECRET',
chatId: '456'
});
} finally {
for (const key of keys) {
if (previous[key] === undefined) delete process.env[key];
else process.env[key] = previous[key];
}
}
});