import { fireEvent, render, screen } from '@testing-library/react'; import { describe, expect, it, vi } from 'vitest'; import { ChatCommandPalette } from '@/pages/Chat/ChatCommandPalette'; import type { ChatCommandPaletteItem } from '@/pages/Chat/chat-command-registry'; function item( inputName: string, enabled: boolean, reason?: string, ): ChatCommandPaletteItem { return { name: inputName === 'compact' ? 'compact' : 'project', inputName, ...(inputName === 'review' ? { rawName: 'review' } : {}), aliases: [], title: inputName === 'compact' ? '压缩会话' : 'Review', description: inputName === 'compact' ? '总结上下文' : 'Review changes', source: inputName === 'compact' ? 'builtin' : 'project', confirmation: 'none', computedAvailability: enabled ? { enabled: true } : { enabled: false, reason }, }; } describe('ChatCommandPalette', () => { it('renders listbox semantics, selection, availability reason, and project source', () => { const onSelect = vi.fn(); const onActiveIndexChange = vi.fn(); render( , ); expect(screen.getByRole('listbox', { name: '斜杠命令' })).toBeInTheDocument(); expect(screen.getByRole('option', { name: /compact/ })).toHaveAttribute( 'aria-selected', 'true', ); expect(screen.getByRole('option', { name: /compact/ })).toHaveAttribute( 'tabindex', '-1', ); expect(screen.getByRole('option', { name: /review/i })).toBeDisabled(); expect(screen.getByText('OpenCode 运行时未启动')).toBeInTheDocument(); expect(screen.getByText('项目')).toBeInTheDocument(); fireEvent.mouseEnter(screen.getByRole('option', { name: /review/i })); expect(onActiveIndexChange).toHaveBeenCalledWith(1); fireEvent.mouseDown(screen.getByRole('option', { name: /compact/i })); expect(onSelect).toHaveBeenCalledWith( expect.objectContaining({ inputName: 'compact' }), ); fireEvent.mouseDown(screen.getByRole('option', { name: /review/i })); expect(onSelect).toHaveBeenCalledTimes(1); }); it('shows an explicit empty search result without inventing a selectable option', () => { render( , ); expect(screen.getByText('没有匹配的命令')).toBeInTheDocument(); expect(screen.queryAllByRole('option')).toHaveLength(0); }); });