feat: 按老师发布配置渲染快捷提示

This commit is contained in:
2026-09-29 17:04:55 +08:00
committed by 鲨鱼辣椒
parent 78cfde6734
commit bb96941461
6 changed files with 100 additions and 2 deletions

View File

@@ -101,6 +101,56 @@ async function ready() {
await waitFor(() => expect(streams.has('first')).toBe(true));
}
describe('teacher side chat', () => {
it('renders published shortcut labels in order and sends each actual prompt with independent retry identity', async () => {
const shortcuts = [{ label: '看看进展', prompt: '请分析当前项目的进展。' }, { label: '解释代码', prompt: '请解释刚才的代码改动。' }];
const agent = { teacher_id: 'shortcuts', version: 1, is_default: true, definition: { ...definition, config_id: 'shortcuts', shortcuts } };
api.catalog.mockResolvedValue({ items: [agent] });
api.sendConversation.mockRejectedValue(new Error('结果暂未确认'));
render(<TeacherChatPanel projectId="p" sourceId="c" selectedAgent={agent} />);
await waitFor(() => expect(screen.getByRole('button', { name: '看看进展' })).toBeEnabled());
expect([...screen.getByTestId('consultation-composer-actions').querySelectorAll('.consultation-hint')].map(el => el.textContent)).toEqual(shortcuts.map(item => item.label));
expect(screen.queryByRole('button', { name: '继续看看👀' })).not.toBeInTheDocument();
expect(screen.queryByText(shortcuts[0].prompt)).not.toBeInTheDocument();
fireEvent.click(screen.getByRole('button', { name: '看看进展' }));
await screen.findByText('结果暂未确认');
const original = api.sendConversation.mock.calls[0][2];
expect(original).toMatchObject({ text: shortcuts[0].prompt, projectId: 'p', sourceConversationId: 'c', references: [] });
expect(original.intent).toBeUndefined();
fireEvent.click(screen.getByRole('button', { name: '看看进展' }));
await waitFor(() => expect(api.sendConversation).toHaveBeenCalledTimes(2));
await waitFor(() => expect(screen.getByRole('button', { name: '解释代码' })).toBeEnabled());
expect(api.sendConversation.mock.calls[1][2]).toEqual(original);
fireEvent.click(screen.getByRole('button', { name: '解释代码' }));
await waitFor(() => expect(api.sendConversation).toHaveBeenCalledTimes(3));
expect(api.sendConversation.mock.calls[2][2].text).toBe(shortcuts[1].prompt);
expect(api.sendConversation.mock.calls[2][2].requestId).not.toBe(original.requestId);
});
it('updates published shortcuts without replacing chat history or a composed draft, and supports clearing the list', async () => {
const old = { teacher_id: 'shortcut-refresh', version: 1, is_default: true, definition: { ...definition, config_id: 'shortcut-refresh', shortcuts: [{ label: '旧入口', prompt: '旧提示词' }] } };
const conversation = { ...topic('shortcut-chat'), definition: old.definition,
conversation: { agentId: old.teacher_id, segmentTurns: 1, discussions: {}, seenThrough: 'past' },
requests: [request({ id: 'past', text: '之前的问题', response: '之前的回答' })] };
api.conversation.mockResolvedValue({ topic: conversation, before: null });
const state = (agent: typeof old) => ({ catalog: { revision: agent.version, items: [agent] }, config: { enabled: true, published_version: agent.version, revision: agent.version, definition: agent.definition } });
const view = render(<TeacherChatPanel projectId="p" sourceId="c" selectedAgent={old} catalogState={state(old)} />);
await screen.findByText('之前的回答');
await waitFor(() => expect(screen.getByRole('button', { name: '旧入口' })).toBeEnabled());
fireEvent.change(screen.getByLabelText('向智能体提问'), { target: { value: '尚未发出的草稿' } });
const updated = { ...old, version: 2, definition: { ...old.definition, shortcuts: [{ label: '新入口', prompt: '新的实际提示词' }] } };
view.rerender(<TeacherChatPanel projectId="p" sourceId="c" selectedAgent={updated} catalogState={state(updated)} />);
expect(screen.getByLabelText('向智能体提问')).toHaveValue('尚未发出的草稿');
expect(screen.queryByRole('button', { name: '新入口' })).not.toBeInTheDocument();
fireEvent.change(screen.getByLabelText('向智能体提问'), { target: { value: '' } });
expect(screen.getByRole('button', { name: '新入口' })).toBeVisible();
expect(screen.queryByRole('button', { name: '旧入口' })).not.toBeInTheDocument();
const cleared = { ...updated, version: 3, definition: { ...updated.definition, shortcuts: [] } };
view.rerender(<TeacherChatPanel projectId="p" sourceId="c" selectedAgent={cleared} catalogState={state(cleared)} />);
expect(screen.getByTestId('consultation-composer-actions').querySelectorAll('.consultation-hint')).toHaveLength(0);
expect(screen.getByText('之前的回答')).toBeVisible();
expect(api.sendConversation).not.toHaveBeenCalled();
});
it('opens directly into the consultation and puts new topics inside expanded history', async () => {
render(<TeacherChatPanel projectId="p" sourceId="c" />);
const history = await screen.findByRole('button', { name: '以往讨论' });