Integrate project classroom with teacher and friend consultations
This commit is contained in:
@@ -205,6 +205,70 @@ describe('CodingChatPanel first Conversation', () => {
|
||||
vi.resetModules();
|
||||
});
|
||||
|
||||
it('keeps the operation draft when switching work tabs and reopening separate teacher and friend drafts', async () => {
|
||||
localStorage.clear();
|
||||
projectApi.list.mockResolvedValue({ projects: [project], activeProjectId: project.id });
|
||||
projectApi.config.mockResolvedValue({ project, config });
|
||||
projectApi.conversations.mockResolvedValue([conversation]);
|
||||
conversationApi.events.mockResolvedValue(new FakeEventSource() as unknown as EventSource);
|
||||
const { createLocalConversationSnapshot } = await import('@/pages/Chat/coding-chat-snapshot');
|
||||
conversationApi.snapshot.mockResolvedValue(createLocalConversationSnapshot(project.id, conversation));
|
||||
const { teacherApi } = await import('@/lib/coding-teacher');
|
||||
vi.spyOn(teacherApi, 'config').mockResolvedValue({ enabled: true, published_version: 1, revision: 1, definition: null });
|
||||
vi.spyOn(teacherApi, 'list').mockResolvedValue({ items: [], lastSelectedTopicId: null });
|
||||
const consultationSend = vi.spyOn(teacherApi, 'send');
|
||||
const consultationCreate = vi.spyOn(teacherApi, 'create');
|
||||
const browserApi = await import('@/lib/agent-browser');
|
||||
const closedBrowser = {
|
||||
browserId: null, projectId: project.id, projectPath: null, state: 'closed' as const,
|
||||
generation: 0, url: '', title: '', visible: false, bounds: null,
|
||||
canGoBack: false, canGoForward: false, eventCursor: 0,
|
||||
};
|
||||
vi.spyOn(browserApi, 'getAgentBrowserState').mockResolvedValue(closedBrowser);
|
||||
vi.spyOn(browserApi, 'closeAgentBrowser').mockResolvedValue(closedBrowser);
|
||||
const { CodingChatPanel } = await import('@/pages/Chat/CodingChatPanel');
|
||||
render(<CodingChatPanel />);
|
||||
const composer = await screen.findByTestId('coding-message-composer');
|
||||
const operationInput = within(composer).getByRole('textbox');
|
||||
fireEvent.change(operationInput, { target: { value: '我想先自己试一试' } });
|
||||
|
||||
const chatTab = screen.getByRole('tab', { name: '操作对话' });
|
||||
const workTab = screen.getByRole('tab', { name: '作品', exact: true });
|
||||
expect(chatTab).toHaveAttribute('aria-selected', 'true');
|
||||
fireEvent.keyDown(chatTab, { key: 'ArrowRight' });
|
||||
expect(workTab).toHaveFocus();
|
||||
expect(workTab).toHaveAttribute('aria-selected', 'true');
|
||||
expect(screen.getByRole('tabpanel', { name: '作品', exact: true })).toBeVisible();
|
||||
expect(operationInput).not.toBeVisible();
|
||||
fireEvent.keyDown(workTab, { key: 'ArrowLeft' });
|
||||
expect(chatTab).toHaveFocus();
|
||||
expect(operationInput).toBeVisible();
|
||||
expect(operationInput).toHaveValue('我想先自己试一试');
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '老师', exact: true }));
|
||||
const teacherInput = await screen.findByRole('textbox', { name: '向老师提问' });
|
||||
await waitFor(() => expect(teacherInput).toBeEnabled());
|
||||
fireEvent.change(teacherInput, { target: { value: '怎样判断规则清不清楚?' } });
|
||||
fireEvent.click(screen.getByRole('button', { name: '朋友', exact: true }));
|
||||
const friendInput = await screen.findByRole('textbox', { name: '向朋友提问' });
|
||||
await waitFor(() => expect(friendInput).toBeEnabled());
|
||||
expect(friendInput).toHaveValue('');
|
||||
fireEvent.change(friendInput, { target: { value: '第一次玩的感受是什么?' } });
|
||||
fireEvent.click(screen.getByRole('button', { name: '关闭朋友' }));
|
||||
expect(screen.queryByTestId('teacher-chat-panel')).not.toBeInTheDocument();
|
||||
fireEvent.click(screen.getByRole('button', { name: '朋友', exact: true }));
|
||||
expect(screen.getByRole('textbox', { name: '向朋友提问' })).toHaveValue('第一次玩的感受是什么?');
|
||||
fireEvent.click(screen.getByRole('button', { name: '老师', exact: true }));
|
||||
expect(screen.getByRole('textbox', { name: '向老师提问' })).toHaveValue('怎样判断规则清不清楚?');
|
||||
expect(screen.getByRole('button', { name: '老师', exact: true })).toHaveAttribute('aria-expanded', 'true');
|
||||
expect(screen.getByRole('button', { name: '朋友', exact: true })).toHaveAttribute('aria-expanded', 'false');
|
||||
expect(operationInput).toHaveValue('我想先自己试一试');
|
||||
expect(screen.queryByText(/记一下|项目共识|记入共识/)).not.toBeInTheDocument();
|
||||
expect(consultationCreate).not.toHaveBeenCalled();
|
||||
expect(consultationSend).not.toHaveBeenCalled();
|
||||
expect(conversationApi.submit).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('archives the last conversation without creating another, then restores the same running conversation', async () => {
|
||||
projectApi.list.mockResolvedValue({ projects: [project], activeProjectId: project.id });
|
||||
projectApi.config.mockResolvedValue({ project, config });
|
||||
|
||||
Reference in New Issue
Block a user