fix: stabilize ai design history switching

This commit is contained in:
2026-08-19 10:31:36 +08:00
parent abece81fdb
commit bf0b805d9f
14 changed files with 573 additions and 48 deletions

View File

@@ -51,6 +51,14 @@ function createRequest(method: string, body?: unknown): IncomingMessage {
return request;
}
function deferred<T>(): { promise: Promise<T>; resolve(value: T): void } {
let resolve!: (value: T) => void;
const promise = new Promise<T>((accept) => {
resolve = accept;
});
return { promise, resolve };
}
class MediaResponse extends Writable {
statusCode = 0;
readonly chunks: Buffer[] = [];
@@ -224,6 +232,21 @@ describe('AI design Main route boundary', () => {
data: { conversationId: 'conversation/one' },
});
const olderConversationResponse = createResponse();
await handleImageWorkspaceRoutes(
createRequest('GET'),
olderConversationResponse.res,
new URL(
'http://127.0.0.1/api/works/image-workspace/workspaces/workspace%2Fone/conversations/conversation%2Fone?before=opaque-cursor',
),
ctx,
);
expect(workspace.getConversation).toHaveBeenLastCalledWith(
'workspace/one',
'conversation/one',
'opaque-cursor',
);
const updateQuoteResponse = createResponse();
await handleImageWorkspaceRoutes(
createRequest('PATCH', {
@@ -637,4 +660,33 @@ describe('AI design Main route boundary', () => {
].join('\n'));
expect(close).toHaveBeenCalledOnce();
});
it('closes an event subscription that finishes opening after the renderer disconnects', async () => {
const opening = deferred<{
events: AsyncIterable<never>;
close(): void;
}>();
const close = vi.fn();
const openWorkspaceEvents = vi.fn().mockReturnValue(opening.promise);
const response = new MediaResponse();
const handled = handleImageWorkspaceRoutes(
createRequest('GET'),
response as unknown as ServerResponse,
new URL(
'http://127.0.0.1/api/works/image-workspace/workspaces/workspace%2Fone/conversations/conversation%2Fone/events',
),
{ imageWorkspace: { openWorkspaceEvents } } as unknown as HostApiContext,
);
await vi.waitFor(() => expect(openWorkspaceEvents).toHaveBeenCalledOnce());
response.emit('close');
opening.resolve({
events: (async function* () {})(),
close,
});
await expect(handled).resolves.toBe(true);
expect(close).toHaveBeenCalledOnce();
expect(response.statusCode).toBe(0);
});
});