import { describe, it, expect } from 'vitest'; import { CONFIG_GROUPS } from './SettingsSidebar'; import { buildSettingsFieldSearchIndex, buildSettingsSearchIndex, searchSettings } from './settingsSearchIndex'; describe('searchSettings', () => { it('finds a section by a config-key keyword buried in a form', () => { expect(searchSettings('reserve_cap').map(r => r.sectionId)).toContain('safety'); expect(searchSettings('deadline').map(r => r.sectionId)).toContain('safety'); expect(searchSettings('max_stream_minutes').map(r => r.sectionId)).toContain('llm-workers'); }); it('finds a section by concept in English or Japanese', () => { expect(searchSettings('python').map(r => r.sectionId)).toContain('execution'); expect(searchSettings('tls').map(r => r.sectionId)).toContain('server-tls'); expect(searchSettings('証明書').map(r => r.sectionId)).toContain('server-tls'); expect(searchSettings('デッドライン').map(r => r.sectionId)).toContain('safety'); }); it('is AND across whitespace-separated terms', () => { const r = searchSettings('browser timeout'); expect(r.map(x => x.sectionId)).toContain('tools-browser'); // "browser timeout" should not match, say, safety (has neither pair). expect(r.every(x => `${x.label} ${x.keywords}`.toLowerCase().includes('browser'))).toBe(true); }); it('is case-insensitive and returns nothing for an empty query', () => { expect(searchSettings('SAFETY').map(r => r.sectionId)).toContain('safety'); expect(searchSettings(' ')).toEqual([]); expect(searchSettings('')).toEqual([]); }); it('can be scoped to a caller-supplied (e.g. non-admin) index subset', () => { const onlyPrefs = buildSettingsSearchIndex().filter(e => e.sectionId === 'preferences'); // "safety" is admin-only → absent from a preferences-only index. expect(searchSettings('safety', onlyPrefs)).toEqual([]); expect(searchSettings('preferences', onlyPrefs).map(r => r.sectionId)).toEqual(['preferences']); }); }); describe('field search index', () => { it('finds a fixed field by its config key and keeps the target section', () => { const results = searchSettings('searxng_url', buildSettingsFieldSearchIndex()); expect(results).toEqual(expect.arrayContaining([ expect.objectContaining({ sectionId: 'tools-web', fieldId: 'tools.searxngUrl' }), ])); }); }); describe('index integrity (drift guard)', () => { const allIds = CONFIG_GROUPS.flatMap(g => g.sections.map(s => s.id)); it('covers every sidebar section (no section left unsearchable)', () => { const index = buildSettingsSearchIndex(); const indexedIds = new Set(index.map(e => e.sectionId)); for (const id of allIds) expect(indexedIds.has(id)).toBe(true); }); it('every indexed section has non-empty keywords', () => { for (const e of buildSettingsSearchIndex()) { expect(e.keywords.trim().length, `section ${e.sectionId} has no keywords`).toBeGreaterThan(0); } }); });