fix(coding): restore sending after queued messages settle
This commit is contained in:
@@ -1169,6 +1169,67 @@ describe('CodingChatPanel first Conversation', () => {
|
||||
expect(conversationApi.recover).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it.each([
|
||||
['follow-up', 'completed'],
|
||||
['follow-up', 'aborted'],
|
||||
['steer', 'completed'],
|
||||
['steer', 'aborted'],
|
||||
] as const)('sends again after %s and %s settlement', async (mode, terminalReason) => {
|
||||
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);
|
||||
conversationApi.submit.mockImplementation(async (input) => ({
|
||||
accepted: true,
|
||||
conversationId: input.conversationId,
|
||||
clientRequestId: input.clientRequestId,
|
||||
runId: 'run-1',
|
||||
mode: input.mode,
|
||||
}));
|
||||
const { CodingChatPanel } = await import('@/pages/Chat/CodingChatPanel');
|
||||
const { createLocalConversationSnapshot } = await import('@/pages/Chat/coding-chat-snapshot');
|
||||
const { codingConversationStore } = await import('@/stores/coding-conversations');
|
||||
const runningSnapshot: ConversationSnapshot = {
|
||||
...createLocalConversationSnapshot(project.id, conversation),
|
||||
worker: { status: 'ready', generation: 1 },
|
||||
run: { status: 'running', runId: 'run-1', mode: 'prompt' },
|
||||
cursor: { workerGeneration: 1, seq: 1 },
|
||||
};
|
||||
conversationApi.snapshot.mockResolvedValue(runningSnapshot);
|
||||
render(<CodingChatPanel />);
|
||||
const textbox = await screen.findByRole('textbox');
|
||||
await screen.findByRole('button', { name: '中止生成' });
|
||||
fireEvent.change(textbox, { target: { value: '排队的消息' } });
|
||||
fireEvent.change(screen.getByRole('combobox', { name: '消息发送方式' }), {
|
||||
target: { value: mode },
|
||||
});
|
||||
fireEvent.click(screen.getByRole('button', { name: '发送' }));
|
||||
await waitFor(() => expect(conversationApi.submit).toHaveBeenCalledOnce());
|
||||
await waitFor(() => expect(screen.getByTestId('coding-file-attachment-input')).toBeEnabled());
|
||||
|
||||
act(() => codingConversationStore.getState().applySnapshotEvent({
|
||||
type: 'snapshot',
|
||||
conversationId: conversation.id,
|
||||
workerGeneration: 1,
|
||||
seq: 2,
|
||||
snapshot: {
|
||||
...runningSnapshot,
|
||||
cursor: { workerGeneration: 1, seq: 2 },
|
||||
run: { status: 'idle', runId: 'run-1', mode: 'prompt', terminalReason, settledAt: 2_000 },
|
||||
},
|
||||
}));
|
||||
fireEvent.change(textbox, { target: { value: '继续' } });
|
||||
expect(screen.getByRole('button', { name: '发送' })).toBeEnabled();
|
||||
expect(screen.queryByText(/条消息已被本地 Agent 接收/)).not.toBeInTheDocument();
|
||||
fireEvent.keyDown(textbox, { key: 'Enter', code: 'Enter' });
|
||||
await waitFor(() => expect(conversationApi.submit).toHaveBeenCalledTimes(2));
|
||||
expect(conversationApi.submit).toHaveBeenLastCalledWith(expect.objectContaining({
|
||||
conversationId: conversation.id,
|
||||
mode: 'prompt',
|
||||
text: '继续',
|
||||
}));
|
||||
});
|
||||
|
||||
it('shows the 202 acceptance and preserves Enter versus Shift+Enter behavior', async () => {
|
||||
const { CodingComposer } = await import('@/pages/Chat/CodingComposer');
|
||||
const onSubmit = vi.fn();
|
||||
|
||||
Reference in New Issue
Block a user