Backend - HealthResponse exposes inspectModeEnabled / chunksModeEnabled / askModeEnabled (additive; defaults true). main.py /api/health populates them from settings. - infra/settings.py: three new env-var-driven booleans (defaults true) parsed in from_env() like the existing reasoning_enabled flag. - tests/test_api_endpoints.py: extra assertion that /api/health surfaces the three new fields with their defaults. Frontend — flag store - features/feature-flags/store.ts: FeatureFlag union extended with inspectMode / chunksMode / askMode. New entries in featureRegistry are gated on context fields populated from health. Missing fields fall back to true so a frontend pointed at an older backend keeps every mode visible. - store gains a modeFlags() helper returning Record<DocMode, boolean> so the routing guard does not need to know the FeatureFlag union. Frontend — routing - shared/routing/resolveMode.ts: pure resolver. If the requested mode is enabled, return it; else first enabled in priority ask > chunks > inspect; else null. - app/router/index.ts: beforeEach guard scoped to ROUTES.DOC_WORKSPACE. Disabled mode → rewrite ?mode= to the first enabled one. All three off → redirect to /docs?reason=no-mode-enabled. Frontend — flash - pages/DocsLibraryPage.vue: shows a banner when ?reason=no-mode-enabled is set. #211 will move this into the proper library page banner. - i18n flags.allModesDisabled added in fr + en. Tests - shared/routing/resolveMode.test.ts (6 cases): every (requested, enabled) combination including all-disabled, priority order, missing requested. - features/feature-flags/store.test.ts: three new cases covering the new fields in /api/health, fall-back-to-true on missing fields, and modeFlags() shape. Refs #210
39 lines
1.6 KiB
TypeScript
39 lines
1.6 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
|
|
import type { DocMode } from './modes'
|
|
import { MODE_PRIORITY, resolveMode } from './resolveMode'
|
|
|
|
const allEnabled: Record<DocMode, boolean> = { ask: true, chunks: true, inspect: true }
|
|
const allDisabled: Record<DocMode, boolean> = { ask: false, chunks: false, inspect: false }
|
|
|
|
describe('resolveMode', () => {
|
|
it('returns the requested mode when it is enabled', () => {
|
|
expect(resolveMode('ask', allEnabled)).toBe('ask')
|
|
expect(resolveMode('chunks', allEnabled)).toBe('chunks')
|
|
expect(resolveMode('inspect', allEnabled)).toBe('inspect')
|
|
})
|
|
|
|
it('falls back to the highest-priority enabled mode when the requested one is disabled', () => {
|
|
expect(resolveMode('chunks', { ...allEnabled, chunks: false })).toBe('ask')
|
|
expect(resolveMode('chunks', { ask: false, chunks: false, inspect: true })).toBe('inspect')
|
|
})
|
|
|
|
it('honours the priority order ask > chunks > inspect', () => {
|
|
expect(resolveMode(undefined, allEnabled)).toBe('ask')
|
|
expect(resolveMode(undefined, { ask: false, chunks: true, inspect: true })).toBe('chunks')
|
|
expect(resolveMode(undefined, { ask: false, chunks: false, inspect: true })).toBe('inspect')
|
|
})
|
|
|
|
it('returns null when no mode is enabled', () => {
|
|
expect(resolveMode('ask', allDisabled)).toBeNull()
|
|
expect(resolveMode(undefined, allDisabled)).toBeNull()
|
|
})
|
|
|
|
it('handles missing requested gracefully', () => {
|
|
expect(resolveMode(undefined, allEnabled)).toBe('ask')
|
|
})
|
|
|
|
it('exposes the priority in the right order', () => {
|
|
expect(MODE_PRIORITY).toEqual(['ask', 'chunks', 'inspect'])
|
|
})
|
|
})
|