import { describe, it, expect, vi, beforeEach } from 'vitest'; const USE_REAL = process.env.REAL_ES === "1"; if (!USE_REAL) { // ------------------------------ // MOCK MODE (default) // ------------------------------ vi.mock('@elastic/elasticsearch', () => { return { Client: vi.fn().mockImplementation(() => { return { search: vi.fn(async (opts) => { if (opts.query?.match) { return { hits: { hits: [ { _id: 'bm25-1', _score: 2.0, _source: { content: 'A' } }, { _id: 'bm25-2', _score: 1.0, _source: { content: 'B' } }, ] } }; } if (opts.knn) { return { hits: { hits: [ { _id: 'vec-1', _score: 0.9, _source: { content: 'X' } }, { _id: 'vec-2', _score: 0.8, _source: { content: 'Y' } }, ] } }; } return { hits: { hits: [] } }; }) }; }) }; }); vi.mock('node-fetch', () => { return { default: vi.fn(async () => { return { ok: true, json: async () => ({ embedding: [0.1, 0.2, 0.3] }) }; }) }; }); } else { console.log("🔵 REAL_ES=1 → Using live Elasticsearch + real fetch"); } // Import AFTER mock decisions import { embed, bm25Search, vectorSearch, hybridSearch } from '../src/retrieval/retrieval.mjs'; describe('retrieval.mjs', () => { if (USE_REAL) { it('real ES hybridSearch returns results', async () => { const res = await hybridSearch('love and unity', 3); expect(res.length).toBeGreaterThan(0); }); return; // Only run this block in REAL mode } // ------------------------------ // MOCK MODE TESTS // ------------------------------ beforeEach(() => { vi.clearAllMocks(); }); it('embed() returns an embedding array', async () => { const emb = await embed('test'); expect(emb).toEqual([0.1, 0.2, 0.3]); }); it('bm25Search() returns valid results', async () => { const res = await bm25Search('love', 2); expect(res[0].id).toBe('bm25-1'); }); it('vectorSearch() returns vector-based results', async () => { const res = await vectorSearch('unity', 2); expect(res[0].id).toBe('vec-1'); }); it('hybridSearch() fuses BM25 and vector results', async () => { const res = await hybridSearch('seeking', 3); const ids = res.map(r => r.id); expect(ids).toContain('vec-1'); expect(ids).toContain('bm25-1'); }); });