fix: restore coding history and quota feedback
This commit is contained in:
@@ -631,7 +631,83 @@ describe('CodingConversationTimeline', () => {
|
||||
.toBeVisible();
|
||||
});
|
||||
|
||||
it('windows long timelines and loads earlier nodes only on demand', async () => {
|
||||
it('shows an actionable non-retryable quota failure in the process summary', async () => {
|
||||
const { codingConversationStore } = await import('@/stores/coding-conversations');
|
||||
const { CodingConversationTimeline } = await import(
|
||||
'@/pages/Chat/CodingConversationTimeline'
|
||||
);
|
||||
const base = createProductSnapshot('conversation-quota-failure', 1);
|
||||
const snapshot = {
|
||||
...base,
|
||||
run: {
|
||||
status: 'idle' as const,
|
||||
runId: 'run-quota-failure',
|
||||
startedAt: 1_000,
|
||||
settledAt: 6_000,
|
||||
terminalReason: 'failed' as const,
|
||||
error: {
|
||||
code: 'CODING_PROVIDER_QUOTA_EXHAUSTED' as const,
|
||||
message: '词元点数余额不足,请充值后重试。',
|
||||
recoverable: false,
|
||||
},
|
||||
},
|
||||
nodes: [{
|
||||
kind: 'tool' as const,
|
||||
id: 'tool-quota-failure',
|
||||
toolCallId: 'call-quota-failure',
|
||||
toolName: 'bash',
|
||||
title: '执行命令',
|
||||
inputText: '',
|
||||
status: 'error' as const,
|
||||
output: [],
|
||||
}],
|
||||
};
|
||||
codingConversationStore.getState().applySnapshotEvent({
|
||||
type: 'snapshot',
|
||||
conversationId: 'conversation-quota-failure',
|
||||
workerGeneration: 1,
|
||||
seq: snapshot.cursor.seq,
|
||||
snapshot,
|
||||
});
|
||||
|
||||
render(<CodingConversationTimeline conversationId="conversation-quota-failure" />);
|
||||
|
||||
expect(within(screen.getByTestId('coding-process-group'))
|
||||
.getByText('词元点数余额不足,请充值后重试。 · 5 秒')).toBeVisible();
|
||||
});
|
||||
|
||||
it('shows an actionable persisted Provider failure after reopening a Conversation', async () => {
|
||||
const { codingConversationStore } = await import('@/stores/coding-conversations');
|
||||
const { CodingConversationTimeline } = await import(
|
||||
'@/pages/Chat/CodingConversationTimeline'
|
||||
);
|
||||
const base = createProductSnapshot('conversation-persisted-quota-failure', 1);
|
||||
const snapshot = {
|
||||
...base,
|
||||
run: { status: 'idle' as const },
|
||||
nodes: [{
|
||||
kind: 'notice' as const,
|
||||
id: 'persisted-quota-notice',
|
||||
code: 'CODING_PROVIDER_QUOTA_EXHAUSTED',
|
||||
level: 'error' as const,
|
||||
message: '词元点数余额不足,请充值后重试。',
|
||||
}],
|
||||
};
|
||||
codingConversationStore.getState().applySnapshotEvent({
|
||||
type: 'snapshot',
|
||||
conversationId: 'conversation-persisted-quota-failure',
|
||||
workerGeneration: 1,
|
||||
seq: snapshot.cursor.seq,
|
||||
snapshot,
|
||||
});
|
||||
|
||||
render(<CodingConversationTimeline conversationId="conversation-persisted-quota-failure" />);
|
||||
|
||||
expect(screen.getByTestId('coding-process-group').querySelector('summary'))
|
||||
.toHaveTextContent('词元点数余额不足,请充值后重试。');
|
||||
});
|
||||
|
||||
it('windows long timelines, loads near the top, and preserves the scroll anchor', async () => {
|
||||
const { codingConversationStore } = await import('@/stores/coding-conversations');
|
||||
const { CodingConversationTimeline } = await import(
|
||||
'@/pages/Chat/CodingConversationTimeline'
|
||||
@@ -659,8 +735,17 @@ describe('CodingConversationTimeline', () => {
|
||||
|
||||
expect(screen.queryByText('Notice 0')).not.toBeInTheDocument();
|
||||
expect(screen.getByText('Notice 30')).toBeInTheDocument();
|
||||
fireEvent.click(screen.getByRole('button', { name: '加载更早内容' }));
|
||||
expect(screen.getByText('Notice 0')).toBeInTheDocument();
|
||||
const timeline = screen.getByTestId('coding-conversation-timeline');
|
||||
Object.defineProperty(timeline, 'scrollHeight', {
|
||||
configurable: true,
|
||||
get: () => screen.queryByText('Notice 0') ? 1_600 : 1_000,
|
||||
});
|
||||
timeline.scrollTop = 0;
|
||||
|
||||
fireEvent.scroll(timeline);
|
||||
|
||||
await waitFor(() => expect(screen.getByText('Notice 0')).toBeInTheDocument());
|
||||
expect(timeline.scrollTop).toBe(600);
|
||||
});
|
||||
|
||||
it('does not commit the selected timeline when a hidden Conversation streams', async () => {
|
||||
|
||||
Reference in New Issue
Block a user