import { RetrievalOrchestrator } from '../src/retrieval/index'; import * as fs from 'fs'; import * as utils from '../src/utils'; // Mocking dependencies jest.mock('fs'); jest.mock('../src/utils'); describe('Retrieval Orchestrator Phase 5 Integration Tests', () => { let orchestrator: RetrievalOrchestrator; const mockBrainPath = '/mock/brain'; beforeEach(() => { jest.clearAllMocks(); orchestrator = new RetrievalOrchestrator(); }); test('End-to-End Brain Search: should populate advanced scoring metadata in results', () => { // 1. Mock Brain Files const mockFiles = [ '/mock/brain/doc1.md', '/mock/brain/doc2.md' ]; (utils.findBrainFiles as jest.Mock).mockReturnValue(mockFiles); // 2. Mock File Content const fileContents: Record = { '/mock/brain/doc1.md': 'Astra 성능 최적화 전략에 대한 문서입니다.', '/mock/brain/doc2.md': '이 설계는 기존 아키텍처와 충돌하며 오류가 많고 논란이 있는 반대 의견입니다.' }; (fs.readFileSync as jest.Mock).mockImplementation((path: string) => fileContents[path]); (fs.statSync as jest.Mock).mockReturnValue({ mtimeMs: Date.now() }); // 3. Perform Retrieval const brain = { localBrainPath: mockBrainPath }; const result = orchestrator.retrieve('최적화 충돌', { brain: brain as any, memoryManager: { getLongTermMemory: () => ({ buildContext: () => null }), getProjectMemory: () => ({ buildContext: () => null }), getProceduralMemory: () => ({ buildContext: () => null }), getEpisodicMemory: () => ({ buildContext: () => null }) } as any, contextBudget: { totalBudget: 2000 } }); // 4. Verify Intelligence Metadata expect(result.selectedChunks.length).toBeGreaterThan(0); // Find doc2 (the conflicting one) const conflictChunk = result.selectedChunks.find(c => c.title.includes('doc2')); expect(conflictChunk).toBeDefined(); if (conflictChunk) { expect(conflictChunk.metadata.conflictDetected).toBe(true); expect(conflictChunk.metadata.conflictSeverity).toBe('HIGH'); // '충돌', '오류', '논란', '반대' -> 4 indicators } // Find doc1 (the dense one) const denseChunk = result.selectedChunks.find(c => c.title.includes('doc1')); expect(denseChunk).toBeDefined(); if (denseChunk) { expect(denseChunk.metadata.queryCoverage).toBeGreaterThan(0); expect(denseChunk.metadata.conflictDetected).toBe(false); } // 5. Verify Assembled Context String const contextString = orchestrator.buildContextString(result); expect(contextString).toContain('[⚠️ CONFLICT: HIGH]'); expect(contextString).toContain('(Coverage:'); }); test('Score Normalization: should normalize scores across brain sources', () => { (utils.findBrainFiles as jest.Mock).mockReturnValue(['/mock/brain/test.md']); (fs.readFileSync as jest.Mock).mockReturnValue('테스트 내용'); (fs.statSync as jest.Mock).mockReturnValue({ mtimeMs: Date.now() }); const result = orchestrator.retrieve('테스트', { brain: { localBrainPath: mockBrainPath } as any, memoryManager: { getLongTermMemory: () => ({ buildContext: () => null }), getProjectMemory: () => ({ buildContext: () => null }), getProceduralMemory: () => ({ buildContext: () => null }), getEpisodicMemory: () => ({ buildContext: () => null }) } as any }); // Scores should be boosted by source priority (brain-memory boost is 0.9) const chunk = result.selectedChunks[0]; expect(chunk.score).toBeCloseTo(0.9, 1); }); });