/**
 * Тест refresh-session.js — поведение при ОТКАЗЕ запуска браузера.
 *
 * FN-SESSION (приёмка 22.06.2026): на проде browserType.launch падал (не было
 * исполняемого файла headless-shell в кэше www-data). Из-за того, что
 * chromium.launch() стоял ВНЕ try/catch, отказ становился unhandled promise
 * rejection → Node выходил с кодом 1 + сырой стек в stderr — неотличимо от
 * честного «login rejected» (тоже exit 1). Этот тест фиксирует контракт:
 * отказ запуска браузера = exit 4 + структурированный JSON {error} в stderr.
 *
 * Runner: встроенный node:test (Node 18+). Запуск: `node --test refresh-session.test.js`.
 */
const { test } = require('node:test');
const assert = require('node:assert');
const { execFile } = require('node:child_process');
const path = require('node:path');

const SCRIPT = path.resolve(__dirname, 'refresh-session.js');

/** Спавнить refresh-session.js с заданным env, подать JSON на stdin, вернуть {code, stdout, stderr}. */
function runScript(input, extraEnv) {
    return new Promise((resolve, reject) => {
        const child = execFile(
            'node',
            [SCRIPT],
            { timeout: 90_000, env: { ...process.env, ...extraEnv } },
            (err, stdout, stderr) => {
                if (err && err.killed) return reject(new Error('Process killed / timed out'));
                resolve({
                    code: err ? err.code : 0,
                    stdout: stdout.toString(),
                    stderr: stderr.toString(),
                });
            },
        );
        child.stdin.write(JSON.stringify(input));
        child.stdin.end();
    });
}

test('отказ запуска браузера → чистый exit 4 + JSON {error} в stderr (не опасный exit 1)', async () => {
    // Форсируем отказ chromium.launch: указываем кэш браузеров в несуществующий
    // путь — Playwright не найдёт исполняемый файл (та же ошибка, что была на проде).
    const result = await runScript(
        { login: 'x', password: 'y', url: 'http://127.0.0.1:1/' },
        { PLAYWRIGHT_BROWSERS_PATH: path.resolve(__dirname, '__nonexistent_browsers__') },
    );

    // Отказ запуска должен классифицироваться как exit 4 (другая ошибка),
    // а НЕ как exit 1 (login rejected) и не как unhandled-rejection exit 1.
    assert.strictEqual(result.code, 4, `Expected exit 4, got ${result.code}. stderr: ${result.stderr}`);

    // stderr должен быть валидным JSON с ключом error (а не сырым стеком Node).
    let parsed;
    try {
        parsed = JSON.parse(result.stderr.trim());
    } catch (e) {
        assert.fail(`stderr не валидный JSON (сырой стек?): ${result.stderr}`);
    }
    assert.ok(typeof parsed.error === 'string' && parsed.error.length > 0, `expected {error}, got ${result.stderr}`);
});
