// check.js (test de lecture, vérification des cookies), settings (env verrouillé), index (init, getStatus) const fs = require('fs'); const path = require('path'); const { BACKEND, __glob, isolateData, check, done, req, chopinTmpDirs } = require('./_setup'); const dataDir = isolateData('check'); process.env.YTDLP_POT_PROVIDER = 'http://user:pw@bgutil-provider:4416'; process.env.YTDLP_SEEK_STRATEGY = 'nimportequoi'; // Pas de mise à jour automatique pendant ce test (limite de l'API GitHub) process.env.YTDLP_AUTO_UPDATE = 'false'; const youtube = req('src/youtube'); const { settings, cookies, check: ytcheck, ytdlp } = youtube; (async () => { console.log('# settings'); const pub = settings.getPublic(); check('potProviderUrl verrouillé + masqué', pub.potProviderUrl.locked && pub.potProviderUrl.value === 'http://***@bgutil-provider:4416', pub.potProviderUrl); check('env invalide ignoré (seekStrategy)', pub.seekStrategy.locked === false && pub.seekStrategy.value === 'auto'); let err = null; try { settings.update({ potProviderUrl: 'http://x' }); } catch (e) { err = e; } check('clé verrouillée refusée', err?.code === 'INVALID_PARAMS', err?.message); err = null; try { settings.update({ playerClients: 'web;rm -rf' }); } catch (e) { err = e; } check('clients invalides refusés', err?.code === 'INVALID_PARAMS'); err = null; try { settings.update({ testUrl: 'https://evil.com/watch?v=x' }); } catch (e) { err = e; } check('testUrl non YouTube refusée', err?.code === 'INVALID_PARAMS'); err = null; try { settings.update({ inconnu: 1 }); } catch (e) { err = e; } check('clé inconnue refusée', err?.code === 'INVALID_PARAMS'); settings.update({ cookiesOnProxy: 'true', playerClients: ' Web , mweb ' }, { username: 'test' }); check('normalisation + écriture', settings.get().cookiesOnProxy === true && settings.get().playerClients === 'web,mweb' && JSON.parse(fs.readFileSync(__glob.YOUTUBE_SETTINGS, 'utf8')).playerClients === 'web,mweb'); check('env non écrit dans settings.json', !('potProviderUrl' in JSON.parse(fs.readFileSync(__glob.YOUTUBE_SETTINGS, 'utf8')))); settings.update({ playerClients: '', cookiesOnProxy: false }); const base = ytdlp.baseArgs({ proxy: 'http://warp:1080', cookiesPath: '/tmp/x', playerClients: 'mweb' }); console.log(' baseArgs :', youtube.errors.sanitize(base.join(' '))); check('baseArgs : pot + client + proxy + cookies + -4', base.includes('-4') && base.includes('youtubepot-bgutilhttp:base_url=http://user:pw@bgutil-provider:4416') && base.includes('youtube:player_client=mweb') && base.includes('--proxy') && base.includes('--cookies') && !base.includes('--no-cache-dir')); // Pas de bgutil local pour les essais réels delete process.env.YTDLP_POT_PROVIDER; settings.reload(); console.log('# init + getStatus'); await youtube.init(); const st = youtube.getStatus(); console.log(' getStatus :', JSON.stringify({ ytdlp: { ...st.ytdlp, path: path.basename(st.ytdlp.path) }, ffmpeg: st.ffmpeg.source, cookies: { present: st.cookies.present, valid: st.cookies.valid }, pot: st.pot, activeProcesses: st.activeProcesses, diagnostics: st.diagnostics.total })); check('getStatus : clés attendues', ['ytdlp', 'ffmpeg', 'cookies', 'settings', 'pot', 'diagnostics', 'activeProcesses'].every(k => k in st)); check('dossier cache créé', fs.existsSync(__glob.YOUTUBE_CACHE)); console.log('# testPlayback (anonyme, directe)'); const t = await ytcheck.testPlayback({ route: 'direct', identity: 'anon' }); console.log(' ', JSON.stringify(t)); check('testPlayback ok + format', t.ok && t.format && t.format.id, t); let busy = null; const p1 = ytcheck.testPlayback({ route: 'direct', identity: 'anon' }); try { await ytcheck.testPlayback({}); } catch (e) { busy = e.code; } await p1; check('testPlayback : un seul à la fois (BUSY)', busy === 'BUSY'); const bad = await ytcheck.testPlayback({ url: '--exec=calc' }); check('testPlayback : URL refusée', bad.ok === false && /URL/.test(bad.message)); console.log('# checkCookies (sans cookies puis anciens cookies)'); const none = await ytcheck.checkCookies(); check('checkCookies sans cookies', none.ok === false && /Aucun cookie/.test(none.message)); __glob.COOKIES = path.join(BACKEND, 'data', 'cookies.txt'); __glob.COOKIES_JSON = path.join(BACKEND, 'data', 'cookies.json'); cookies.migrateLegacy(); const [c1, c2] = await Promise.all([ytcheck.checkCookies(), ytcheck.checkCookies()]); console.log(' ', JSON.stringify({ ok: c1.ok, loggedIn: c1.loggedIn, rotated: c1.rotated, cls: c1.cls, message: c1.message, route: c1.route, ms: c1.ms })); check('checkCookies : appel unique partagé', c1 === c2); check('checkCookies : lastCheck enregistré', cookies.getStatus().lastCheck?.at && cookies.getStatus().lastCheck.message === c1.message); check('aucune copie chopin-ytc-* restante', chopinTmpDirs().length === 0, chopinTmpDirs()); check('aucun processus actif', ytdlp.activeCount() === 0); fs.rmSync(dataDir, { recursive: true, force: true }); done(); })().catch((e) => { console.error(e); process.exitCode = 1; });