import assert from 'node:assert/strict' import { test } from 'node:test' import { mkdtemp, readFile, readdir, rm, stat, writeFile } from 'node:fs/promises' import { join } from 'node:path' import { tmpdir } from 'node:os' import { DiagnosticLog } from './diagnostics.js' test('журнал сохраняет только разрешённые поля и значения без секретов', async (t) => { const dir = await mkdtemp(join(tmpdir(), 'screen-log-')) t.after(() => rm(dir, { recursive: true, force: true })) const log = new DiagnosticLog(dir) log.record('app-start', { version: '0.2.0-rc.1', electron: '42.11.15', platform: 'linux', arch: 'x64', token: 'SECRET', }) log.record('output-close', { reason: 'renderer', password: 'SECRET', error: new Error('SECRET') }) log.record('output-close', { reason: 'https://secret.example/SECRET' }) log.record('package', { action: 'download', status: 'failed', response: 'SECRET' }) log.record('request-error', { path: '/api/games/{id}/music', reason: 'ENOTFOUND', token: 'SECRET', error: new Error('SECRET'), }) log.record('request-error', { path: '/api/games/7?token=SECRET', reason: 'ENOTFOUND' }) log.record('request-error', { path: '/api/games/{id}', reason: 'SECRET' }) const content = await readFile(join(dir, 'diagnostic.jsonl'), 'utf8') assert.equal(content.includes('SECRET'), false) const lines = content .trim() .split('\n') .map((s) => JSON.parse(s)) assert.equal(lines.length, 4) assert.equal(lines[0].version, '0.2.0-rc.1') assert.deepEqual(Object.keys(lines[1]).sort(), ['event', 'reason', 'time']) }) test('ротация ограничивает журнал тремя файлами; ошибка записи не ломает приложение', async (t) => { const dir = await mkdtemp(join(tmpdir(), 'screen-log-')) t.after(() => rm(dir, { recursive: true, force: true })) const log = new DiagnosticLog(dir, 256) for (let i = 0; i < 100; i++) log.record('output-open') const files = await readdir(dir) assert.equal(files.length, 3) for (const file of files) assert.ok((await stat(join(dir, file))).size <= 256) const blocked = join(dir, 'not-a-directory') await writeFile(blocked, 'file') const broken = new DiagnosticLog(blocked) assert.doesNotThrow(() => broken.record('output-open')) assert.doesNotThrow(() => broken.record('app-stop')) })