Multi-Hoster-Upload/tests/webhook-notify.test.js

83 lines
3.5 KiB
JavaScript

const test = require('node:test');
const assert = require('node:assert');
const { isDiscordWebhook, formatDurationShort, summarizePerHosterFromBatch, buildWebhookRequest } = require('../lib/webhook-notify');
const SAMPLE_SUMMARY = {
total: 10,
succeeded: 8,
failed: 2,
files: [
{ name: 'a.mkv', results: [
{ hoster: 'voe.sx', status: 'done' },
{ hoster: 'byse.sx', status: 'error', error: 'x' }
] },
{ name: 'b.mkv', results: [
{ hoster: 'voe.sx', status: 'done' },
{ hoster: 'byse.sx', status: 'done' }
] }
]
};
test('isDiscordWebhook recognizes discord URLs incl. ptb/canary/discordapp', () => {
assert.ok(isDiscordWebhook('https://discord.com/api/webhooks/123/abc'));
assert.ok(isDiscordWebhook('https://discordapp.com/api/webhooks/123/abc'));
assert.ok(isDiscordWebhook('https://ptb.discord.com/api/webhooks/123/abc'));
assert.ok(isDiscordWebhook('https://canary.discord.com/api/webhooks/123/abc'));
assert.strictEqual(isDiscordWebhook('https://example.com/hook'), false);
assert.strictEqual(isDiscordWebhook(''), false);
assert.strictEqual(isDiscordWebhook(null), false);
});
test('formatDurationShort formats h/m/s tiers', () => {
assert.strictEqual(formatDurationShort(45), '45s');
assert.strictEqual(formatDurationShort(125), '2m 5s');
assert.strictEqual(formatDurationShort(3 * 3600 + 12 * 60), '3h 12m');
assert.strictEqual(formatDurationShort(-5), '0s');
assert.strictEqual(formatDurationShort(undefined), '0s');
});
test('summarizePerHosterFromBatch counts ok/fail per hoster', () => {
const s = summarizePerHosterFromBatch(SAMPLE_SUMMARY);
assert.deepStrictEqual(s['voe.sx'], { ok: 2, fail: 0 });
assert.deepStrictEqual(s['byse.sx'], { ok: 1, fail: 1 });
});
test('summarizePerHosterFromBatch handles malformed input', () => {
assert.deepStrictEqual(summarizePerHosterFromBatch(null), {});
assert.deepStrictEqual(summarizePerHosterFromBatch({}), {});
assert.deepStrictEqual(summarizePerHosterFromBatch({ files: [{ results: null }] }), {});
});
test('buildWebhookRequest produces Discord content body for discord URLs', () => {
const req = buildWebhookRequest('https://discord.com/api/webhooks/1/x', SAMPLE_SUMMARY, { durationSec: 3700, appVersion: '3.3.59', machineName: 'srv-1' });
assert.strictEqual(req.method, 'POST');
assert.strictEqual(req.headers['Content-Type'], 'application/json');
const body = JSON.parse(req.body);
assert.ok(typeof body.content === 'string');
assert.match(body.content, /Batch fertig/);
assert.match(body.content, /srv-1/);
assert.match(body.content, /8 ok/);
assert.match(body.content, /2 Fehler/);
assert.match(body.content, /1h 1m/);
assert.match(body.content, /voe\.sx: 2\/2/);
});
test('buildWebhookRequest produces raw JSON payload for generic URLs', () => {
const req = buildWebhookRequest('https://example.com/hook', SAMPLE_SUMMARY, { durationSec: 60, appVersion: '3.3.59', timestamp: '2026-06-09T00:00:00Z' });
const body = JSON.parse(req.body);
assert.strictEqual(body.event, 'batch-done');
assert.strictEqual(body.total, 10);
assert.strictEqual(body.succeeded, 8);
assert.strictEqual(body.failed, 2);
assert.strictEqual(body.durationSec, 60);
assert.strictEqual(body.version, '3.3.59');
assert.deepStrictEqual(body.perHoster['byse.sx'], { ok: 1, fail: 1 });
});
test('buildWebhookRequest tolerates empty summary', () => {
const req = buildWebhookRequest('https://example.com/hook', null, {});
const body = JSON.parse(req.body);
assert.strictEqual(body.total, 0);
assert.strictEqual(body.succeeded, 0);
});