Files
brain/tools/brain-dashboard-server.test.mjs

47 lines
1.8 KiB
JavaScript

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');
});
});