const assert = require('node:assert/strict'); const { readFileSync } = require('node:fs'); const { resolve } = require('node:path'); const { test } = require('node:test'); const { runInNewContext } = require('node:vm'); const root = resolve(__dirname, '../../'); const source = readFileSync(resolve(root, 'reproxy/web/minecraft/app.js'), 'utf8'); async function renderStatus(response, error) { const elements = Object.fromEntries(['server-status', 'build-status', 'build-download'].map(id => [id, {}])); const requests = []; let refresh; const context = { document: { getElementById: id => elements[id] }, AbortSignal, TextDecoder, Uint8Array, atob, fetch: async (url, options) => { requests.push({ url, options }); if (url.endsWith('/readme')) { return { ok: true, json: async () => ({ encoding: 'base64', content: Buffer.from('Актуальная версия — **1.2.3**: [Скачать 1.2.3](dist/minecraft-lab-neoforge-spike-1.2.3/minecraft-lab-neoforge-spike-1.2.3.mrpack)').toString('base64') }) }; } if (error) throw error; return response; }, setInterval: (callback, delay) => { refresh = { callback, delay }; }, }; runInNewContext(source, context); await new Promise(setImmediate); assert.equal(elements['build-download'].hidden, false); assert.match(elements['build-download'].href, /1\.2\.3\.mrpack$/); assert.equal(refresh.delay, 300000); await refresh.callback(); assert.equal(requests.filter(request => request.url === '/minecraft/api/status').length, 2); assert.ok(requests.every(request => request.options.signal instanceof AbortSignal)); return elements['server-status'].textContent; } for (const [name, data, expected] of [ ['positive count', { online: true, players: { online: 7 } }, 'Игроков онлайн: 7'], ['zero count', { online: true, players: { online: 0 } }, 'Игроков онлайн: 0'], ['offline', { online: false }, 'Сервер недоступен'], ...[null, {}, { online: true }, { online: true, players: { online: -1 } }, { online: true, players: { online: '2' } }].map(data => ['invalid response ' + JSON.stringify(data), data, 'Не удалось получить онлайн']), ]) { test(name, async () => assert.equal(await renderStatus({ ok: true, json: async () => data }), expected)); } test('HTTP failure', async () => assert.equal(await renderStatus({ ok: false }), 'Не удалось получить онлайн')); test('invalid JSON', async () => assert.equal(await renderStatus({ ok: true, json: async () => { throw new SyntaxError(); } }), 'Не удалось получить онлайн')); test('timeout', async () => assert.equal(await renderStatus(null, new DOMException('Timeout', 'TimeoutError')), 'Не удалось получить онлайн')); test('network failure', async () => assert.equal(await renderStatus(null, new TypeError('Failed to fetch')), 'Не удалось получить онлайн')); test('Telemost link and initial status', () => { const html = readFileSync(resolve(root, 'reproxy/web/minecraft/index.html'), 'utf8'); assert.match(html, /href="https:\/\/telemost\.yandex\.ru\/j\/76726739040099\?skip_app=1" target="_blank" rel="noopener noreferrer"/); assert.match(html, /id="server-status" role="status">Проверяем онлайн…/); });