'use strict'; const test = require('node:test'); const assert = require('node:assert/strict'); const http = require('node:http'); const { settings } = require('../src/settings'); const { fetchLiveStreams, liveUrlCandidates, parseM3u, resolveFallbackUrls, resetM3uCache, } = require('../src/xtream-client'); function listen(server) { return new Promise((resolve) => server.listen(0, '127.0.0.1', resolve)); } function close(server) { return new Promise((resolve) => server.close(resolve)); } test('fetches live streams from player_api and resolves get.php fallback URLs', async () => { const server = http.createServer((req, res) => { if (req.url.startsWith('/player_api.php')) { res.setHeader('Content-Type', 'application/json'); res.end( JSON.stringify([ { stream_id: 101, name: 'DAZN 01 [A - B | Jupiler Pro League (nl) (2026-11-06 19:25:00)]', }, ]) ); return; } if (req.url.startsWith('/get.php')) { res.setHeader('Content-Type', 'application/x-mpegurl'); res.end( [ '#EXTM3U', '#EXTINF:-1 tvg-id="dazn1" tvg-name="DAZN 01",DAZN 01 [A - B | Jupiler Pro League (nl) (2026-11-06 19:25:00)]', 'http://cdn.example/live/u/p/101.ts', ].join('\n') ); return; } res.statusCode = 404; res.end('nope'); }); await listen(server); const port = server.address().port; const previous = { ...settings }; settings.xtreamUrl = `http://127.0.0.1:${port}`; settings.xtreamUsername = 'user'; settings.xtreamPassword = 'pass'; resetM3uCache(); try { const streams = await fetchLiveStreams(); assert.equal(streams.length, 1); assert.equal(streams[0].stream_id, 101); const urls = liveUrlCandidates(101); assert.ok(urls.includes('http://127.0.0.1:' + port + '/live/user/pass/101.ts')); const fallbacks = await resolveFallbackUrls(101, 'DAZN 01'); assert.deepEqual(fallbacks, ['http://cdn.example/live/u/p/101.ts']); } finally { Object.assign(settings, previous); resetM3uCache(); await close(server); } }); test('parses M3U entries by stream id and tvg-name', () => { const index = parseM3u( [ '#EXTM3U', '#EXTINF:-1 tvg-id="x" tvg-name="DAZN 01 [A - B | Jupiler Pro League (nl) (2026-11-06 19:25:00)]",display', 'http://cdn.example/live/u/p/55.m3u8?token=1', ].join('\n') ); assert.equal(index.byStreamId.get('55'), 'http://cdn.example/live/u/p/55.m3u8?token=1'); assert.equal( index.byName.get('dazn 01 [a - b | jupiler pro league (nl) (2026-11-06 19:25:00)]'), 'http://cdn.example/live/u/p/55.m3u8?token=1' ); });