/** * Unit Tests — conversation-logger.js */ import { describe, it, expect, beforeAll, afterAll } from 'vitest'; import fs from 'fs'; import path from 'path'; const { ConversationLogger } = require('../../services/conversation-logger'); describe('ConversationLogger', () => { const TMP = '/tmp/test-conv-logger'; let logger; const convId = 'test-conv-001'; const msgId = 'msg-001'; beforeAll(() => { fs.mkdirSync(TMP, { recursive: true }); logger = new ConversationLogger(TMP, convId, msgId, { userId: 'user-123' }); }); afterAll(() => { try { fs.rmSync(TMP, { recursive: true }); } catch {} }); describe('constructor', () => { it('should create logger with correct properties', () => { expect(logger.conversationsDir).toBe(TMP); expect(logger.conversationId).toBe(convId); expect(logger.messageId).toBe(msgId); expect(logger.userId).toBe('user-123'); }); it('should create directories', () => { expect(fs.existsSync(logger.messageDir)).toBe(true); expect(fs.existsSync(logger.useDir)).toBe(true); expect(fs.existsSync(logger.trainDir)).toBe(true); }); }); describe('ensureMeta', () => { it('should create meta.json', () => { logger.ensureMeta('Test Conversation'); expect(fs.existsSync(logger._metaPath)).toBe(true); }); it('should not overwrite existing meta', () => { const before = JSON.parse(fs.readFileSync(logger._metaPath, 'utf-8')); logger.ensureMeta('Different Title'); const after = JSON.parse(fs.readFileSync(logger._metaPath, 'utf-8')); expect(after.title).toBe(before.title); // unchanged }); }); describe('logUserMessage', () => { it('should log without error', () => { expect(() => logger.logUserMessage('Hello, how are you?')).not.toThrow(); }); it('should persist to messages file', () => { const content = fs.readFileSync(logger._messagesPath, 'utf-8'); expect(content).toContain('Hello'); }); }); describe('logStreamChunk', () => { it('should log a stream chunk', () => { expect(() => logger.logStreamChunk('master', 'Processing...')).not.toThrow(); }); }); describe('logProgress', () => { it('should log progress step', () => { expect(() => logger.logProgress('hunt', 'Searching...')).not.toThrow(); }); }); describe('logToolCall', () => { it('should log tool calls', () => { expect(() => logger.logToolCall('read_file', '/path/to/file')).not.toThrow(); }); }); describe('logResult', () => { it('should log a result', () => { expect(() => logger.logResult({ success: true, output: 'Done' })).not.toThrow(); }); }); describe('logError', () => { it('should log an error', () => { expect(() => logger.logError({ message: 'Something failed', stack: 'trace' })).not.toThrow(); }); }); describe('addStats', () => { it('should add stats delta', () => { expect(() => logger.addStats({ tokensIn: 100, tokensOut: 200 })).not.toThrow(); }); }); describe('finalize', () => { it('should finalize with success status', () => { expect(() => logger.finalize('success')).not.toThrow(); }); }); });