import { applyCompletion, isUnsafeNavigateTarget, navigateTargetKeys, parseCommand, suggestCompletions, } from './terminal-commands'; describe('terminal command grammar', () => { it('parses help, history, clear, brew and rev', () => { expect(parseCommand('help')).toEqual({ kind: 'help' }); expect(parseCommand('history')).toEqual({ kind: 'history' }); expect(parseCommand('clear')).toEqual({ kind: 'clear' }); expect(parseCommand('brew')).toEqual({ kind: 'brew' }); expect(parseCommand('rev')).toEqual({ kind: 'rev' }); expect(parseCommand(' Hilfe ')).toEqual({ kind: 'help' }); expect(parseCommand('')).toEqual({ kind: 'empty' }); }); it('resolves navigate targets including the four service fragments', () => { expect(parseCommand('navigate home')).toEqual({ kind: 'navigate', resolution: { kind: 'route', routeId: 'home' }, targetKey: 'home', }); expect(parseCommand('navigate pitch')).toEqual({ kind: 'navigate', resolution: { kind: 'route', routeId: 'pitch' }, targetKey: 'pitch', }); expect(parseCommand('navigate services')).toEqual({ kind: 'navigate', resolution: { kind: 'route', routeId: 'services' }, targetKey: 'services', }); expect(parseCommand('navigate services ai')).toEqual({ kind: 'navigate', resolution: { kind: 'route', routeId: 'services', fragment: 'ai-workflows' }, targetKey: 'services ai', }); expect(parseCommand('navigate leistungen software')).toEqual({ kind: 'navigate', resolution: { kind: 'route', routeId: 'services', fragment: 'software-data' }, targetKey: 'services software', }); expect(parseCommand('navigate services infrastructure')).toEqual({ kind: 'navigate', resolution: { kind: 'route', routeId: 'services', fragment: 'infrastructure-network' }, targetKey: 'services infrastructure', }); expect(parseCommand('navigate services platform')).toEqual({ kind: 'navigate', resolution: { kind: 'route', routeId: 'services', fragment: 'platform-operations' }, targetKey: 'services platform', }); expect(parseCommand('navigate cv')).toEqual({ kind: 'navigate', resolution: { kind: 'cv' }, targetKey: 'cv', }); }); it('suggests valid targets for incomplete navigate input', () => { const parsed = parseCommand('navigate'); expect(parsed.kind).toBe('incomplete'); if (parsed.kind === 'incomplete') { expect(parsed.suggestions).toEqual([...navigateTargetKeys()]); } const unknown = parseCommand('navigate nowhere'); expect(unknown.kind).toBe('unknown-target'); if (unknown.kind === 'unknown-target') { expect(unknown.target).toBe('nowhere'); } }); it('completes the current token against commands and navigate targets', () => { expect(suggestCompletions('he')).toEqual(['help']); expect(applyCompletion('he')).toEqual({ value: 'help', candidates: ['help'] }); expect(suggestCompletions('navigate p')).toEqual(['pitch', 'profil', 'projects', 'projekte']); expect(applyCompletion('navigate pit')).toEqual({ value: 'navigate pitch', candidates: ['pitch'], }); expect(suggestCompletions('navigate services a')).toEqual(['services ai']); }); it('rejects unsafe navigate targets without treating them as routes', () => { const hostile = [ 'navigate https://example.com', 'navigate ../secret', 'navigate /etc/passwd', 'navigate javascript:alert(1)', ]; for (const input of hostile) { const target = input.slice('navigate '.length); expect(isUnsafeNavigateTarget(target), input).toBe(true); expect(parseCommand(input)).toEqual({ kind: 'unknown-target', input, target, }); } }); });