import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; import { search } from '../../src/tools/search.js'; import * as registry from '../../src/registry.js'; import { getMockPlanningPath } from '../setup.js'; describe('search tool', () => { beforeEach(() => { // Mock getAllProjects to return our test fixture vi.spyOn(registry, 'getAllProjects').mockReturnValue([ { name: 'test-project', path: getMockPlanningPath().replace('/.planning', '').replace('/mock-planning', '/mock-planning'), registeredAt: new Date().toISOString() } ]); }); afterEach(() => { vi.restoreAllMocks(); }); it('returns enriched results with GSD context', async () => { // Note: This test may return empty if mock-planning structure doesn't match expectations // The path needs to point to a directory containing .planning const results = await search({ query: 'test' }); // With mocked registry pointing to fixtures, should return results expect(Array.isArray(results)).toBe(true); }); it('returns results with required fields', async () => { const results = await search({ query: 'phase' }); if (results.length > 0) { expect(results[0]).toHaveProperty('content'); expect(results[0]).toHaveProperty('source'); expect(results[0]).toHaveProperty('project'); expect(results[0]).toHaveProperty('relevance'); } }); it('filters by project when specified', async () => { const results = await search({ query: 'test', project: 'test-project' }); // All results should be from specified project results.forEach(r => { expect(r.project).toBe('test-project'); }); }); it('respects limit parameter', async () => { const results = await search({ query: 'the', limit: 2 }); expect(results.length).toBeLessThanOrEqual(2); }); it('returns empty array for non-existent project', async () => { const results = await search({ query: 'test', project: 'non-existent-project' }); expect(results).toEqual([]); }); });