Merge remote main preserving project chats and reply recovery
This commit is contained in:
commit
efff238a75
54 files changed
+3189
-1713
No files matched your search
@@ -42,6 +42,38 @@ const props = { projectId: 'project-a', projectName: '天气', sourceId: 'source
|
||||
async function mount() { let view!: ReturnType<typeof render>; await act(async () => { view = render(<TeacherChatPanel {...props} />); }); return view; }
|
||||
|
||||
describe('continuous agent panel', () => {
|
||||
it('retries incomplete prose only in its original project/source and keeps current drafts and one send identity', async () => {
|
||||
const original = { ...request('broken', '现在项目是什么阶段?'), response: '它早就不是', replyIncomplete: true,
|
||||
references: [{ kind: 'code' as const, text: '原项目代码' }] };
|
||||
api.conversation.mockImplementation(async projectId => ({ topic: projectId === 'project-a' ? topic([original]) : null, before: null }));
|
||||
api.seenConversation.mockImplementation(async () => topic([original]));
|
||||
let finish!: (value: TeacherTopic) => void;
|
||||
api.sendConversation.mockImplementation(() => new Promise<TeacherTopic>(resolve => { finish = resolve; }));
|
||||
const view = await mount();
|
||||
expect(screen.getByRole('status')).toHaveTextContent('这次回复未能完整显示');
|
||||
expect(screen.queryByTestId('teacher-reply')).toBeNull();
|
||||
expect(api.sendConversation).not.toHaveBeenCalled();
|
||||
fireEvent.change(screen.getByRole('textbox'), { target: { value: '仍在编辑的草稿' } });
|
||||
await act(async () => view.rerender(<TeacherChatPanel {...props} projectId="project-b" sourceId="source-b" />));
|
||||
expect(screen.queryByRole('button', { name: '重新回答' })).toBeNull();
|
||||
expect(screen.getByRole('textbox')).toHaveValue('');
|
||||
await act(async () => view.rerender(<TeacherChatPanel {...props} sourceId="another-source" />));
|
||||
expect(screen.getByRole('button', { name: '重新回答' })).toBeDisabled();
|
||||
view.rerender(<TeacherChatPanel {...props} />);
|
||||
const retry = screen.getByRole('button', { name: '重新回答' });
|
||||
fireEvent.click(retry); fireEvent.click(retry);
|
||||
expect(api.sendConversation).toHaveBeenCalledTimes(1);
|
||||
const sent = api.sendConversation.mock.calls[0][2];
|
||||
expect(sent).toEqual({ requestId: expect.any(String), projectId: 'project-a', sourceConversationId: 'source-a',
|
||||
text: original.text, references: original.references });
|
||||
expect(sent.requestId).not.toBe(original.id);
|
||||
fireEvent.change(screen.getByRole('textbox'), { target: { value: '等待时补充的草稿' } });
|
||||
await act(async () => finish({ ...topic([original, { ...request(sent.requestId), response: '完整回答' }]), revision: 2 }));
|
||||
expect(screen.getByText('完整回答')).toBeVisible();
|
||||
expect(screen.getByRole('textbox')).toHaveValue('等待时补充的草稿');
|
||||
expect(JSON.parse(localStorage.getItem(`makelore-consultation-draft:kid-${identity.id}:project:project-a:agent:agent-a`)!)).toMatchObject({ text: '等待时补充的草稿' });
|
||||
});
|
||||
|
||||
it('ignores a previous project fetch and external snapshot after a project switch', async () => {
|
||||
let resolve!: (value: { topic: TeacherTopic; before: null }) => void;
|
||||
const delayed = new Promise<{ topic: TeacherTopic; before: null }>(done => { resolve = done; });
|
||||
|
||||
Reference in new issue
Block a user