import { describe, it, expect } from 'vitest'; import { listEpisodeFiles, resolveStaticPath, contentType } from './brain-dashboard-server.mjs'; import { mkdtempSync, writeFileSync, mkdirSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; describe('listEpisodeFiles', () => { it('returns episodes-*.jsonl filenames sorted, ignores other files', () => { const root = mkdtempSync(join(tmpdir(), 'bd-')); const obs = join(root, 'docs', 'observer'); mkdirSync(obs, { recursive: true }); writeFileSync(join(obs, 'episodes-2026-05.jsonl'), ''); writeFileSync(join(obs, 'episodes-2026-04.jsonl'), ''); writeFileSync(join(obs, 'STATUS.md'), ''); expect(listEpisodeFiles(root)).toEqual(['episodes-2026-04.jsonl', 'episodes-2026-05.jsonl']); }); it('returns [] when the observer dir is missing', () => { const root = mkdtempSync(join(tmpdir(), 'bd-')); expect(listEpisodeFiles(root)).toEqual([]); }); }); describe('resolveStaticPath', () => { it('resolves a path inside root', () => { const root = '/srv/app'; expect(resolveStaticPath('/docs/observer/dashboard.html', root)) .toBe(join(root, 'docs', 'observer', 'dashboard.html')); }); it('rejects path traversal with null', () => { expect(resolveStaticPath('/../../etc/passwd', '/srv/app')).toBeNull(); expect(resolveStaticPath('/docs/../../secret', '/srv/app')).toBeNull(); }); }); describe('contentType', () => { it('maps known extensions', () => { expect(contentType('.html')).toBe('text/html; charset=utf-8'); expect(contentType('.js')).toBe('text/javascript; charset=utf-8'); expect(contentType('.jsonl')).toBe('application/x-ndjson; charset=utf-8'); }); it('falls back to octet-stream', () => { expect(contentType('.xyz')).toBe('application/octet-stream'); }); });