64 lines
2.9 KiB
TypeScript
64 lines
2.9 KiB
TypeScript
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);
|
|
}
|
|
});
|
|
});
|