Files
Autonomous-Bug-Explorer/tests/shared/infrastructure.test.ts
2026-03-04 16:26:32 -05:00

113 lines
3.4 KiB
TypeScript

import { loadConfig } from '../../src/shared/infrastructure/Config';
import { InProcessEventBus } from '../../src/shared/infrastructure/InProcessEventBus';
import { LocalStorageProvider } from '../../src/shared/infrastructure/StorageProvider';
import { createLogger } from '../../src/shared/infrastructure/Logger';
import { DomainEvent } from '../../src/shared/domain/DomainEvent';
import { randomUUID } from 'crypto';
import path from 'path';
import os from 'os';
import fs from 'fs';
// --- Config ---
describe('Config', () => {
it('loads with defaults when no env vars set', () => {
const config = loadConfig();
expect(config.port).toBe(3001);
expect(config.db.driver).toBe('sqlite');
expect(['development', 'test']).toContain(config.nodeEnv);
});
it('picks up PORT env var', () => {
process.env['ABE_PORT'] = '4000';
const config = loadConfig();
expect(config.port).toBe(4000);
delete process.env['ABE_PORT'];
});
});
// --- EventBus ---
describe('InProcessEventBus', () => {
const logger = createLogger({ level: 'silent', nodeEnv: 'test' });
it('publishes and subscribes to events', async () => {
const bus = new InProcessEventBus(logger);
const received: DomainEvent[] = [];
bus.subscribe('test.event', {
handle: async (event) => { received.push(event); },
});
const event: DomainEvent = {
eventId: randomUUID(),
eventName: 'test.event',
aggregateId: 'agg-1',
occurredOn: new Date(),
payload: { foo: 'bar' },
};
await bus.publish(event);
await new Promise(r => setTimeout(r, 10));
expect(received).toHaveLength(1);
expect(received[0]?.aggregateId).toBe('agg-1');
});
it('does not crash when handler throws', async () => {
const bus = new InProcessEventBus(logger);
bus.subscribe('error.event', {
handle: async () => { throw new Error('handler error'); },
});
const event: DomainEvent = {
eventId: randomUUID(),
eventName: 'error.event',
aggregateId: 'agg-2',
occurredOn: new Date(),
payload: {},
};
await expect(bus.publish(event)).resolves.not.toThrow();
});
});
// --- StorageProvider ---
describe('LocalStorageProvider', () => {
let tmpDir: string;
beforeEach(() => {
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'abe-test-'));
});
afterEach(() => {
fs.rmSync(tmpDir, { recursive: true, force: true });
});
it('saves and retrieves data', async () => {
const storage = new LocalStorageProvider(tmpDir);
const data = Buffer.from('hello world');
await storage.save('subdir/test.txt', data);
const result = await storage.get('subdir/test.txt');
expect(result?.toString()).toBe('hello world');
});
it('returns null for missing file', async () => {
const storage = new LocalStorageProvider(tmpDir);
const result = await storage.get('nonexistent.txt');
expect(result).toBeNull();
});
it('exists returns true after save', async () => {
const storage = new LocalStorageProvider(tmpDir);
await storage.save('file.bin', Buffer.from([1, 2, 3]));
expect(await storage.exists('file.bin')).toBe(true);
expect(await storage.exists('other.bin')).toBe(false);
});
it('delete removes file', async () => {
const storage = new LocalStorageProvider(tmpDir);
await storage.save('file.txt', Buffer.from('data'));
await storage.delete('file.txt');
expect(await storage.exists('file.txt')).toBe(false);
});
});