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);
});
});