import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import { SessionStore } from './store.js'; import { SessionIndexer } from './indexer.js'; import { SessionSearch } from './search.js'; import { unlinkSync, existsSync } from 'fs'; import { join } from 'path'; import { tmpdir } from 'os'; describe('SessionSearch', () => { const dbPath = join(tmpdir(), 'flynn-test-search.db'); let store: SessionStore; let search: SessionSearch; beforeEach(() => { store = new SessionStore(dbPath); const indexer = new SessionIndexer({ maxKeywords: 8 }); store.addMessage('session:a', { role: 'user', content: 'deploy backend service' }, indexer.indexText('deploy backend service')); store.addMessage('session:a', { role: 'assistant', content: 'backend deployment completed' }, indexer.indexText('backend deployment completed')); store.addMessage('session:b', { role: 'user', content: 'buy groceries tonight' }, indexer.indexText('buy groceries tonight')); search = new SessionSearch(store, { limit: 10, minScore: 0.1, }); }); afterEach(() => { store.close(); if (existsSync(dbPath)) { unlinkSync(dbPath); } }); it('returns ranked results for overlapping keywords', () => { const results = search.search('deploy backend'); expect(results.length).toBeGreaterThan(0); expect(results[0].sessionId).toBe('session:a'); expect(results[0].score).toBeGreaterThan(0); }); it('supports session-specific filtering', () => { const results = search.search('deploy', { sessionId: 'session:b' }); expect(results).toEqual([]); }); });