From f166c28bc92dcb87095637d5c4b5ff1893b0014a Mon Sep 17 00:00:00 2001 From: kvtodev Date: Tue, 7 Jul 2026 13:18:35 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B5=8B=E8=AF=95:=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E7=B2=98=E8=B4=B4=E5=9B=BE=E7=89=87=E4=B8=8A=E4=BC=A0=E5=8F=8A?= =?UTF-8?q?=E8=B5=84=E6=BA=90=E5=88=9B=E5=BB=BA=E7=9A=84=E5=8D=95=E5=85=83?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EditorAgentConversationPanelView.test.tsx | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/src/components/image-editor/EditorAgentConversationPanelView.test.tsx b/src/components/image-editor/EditorAgentConversationPanelView.test.tsx index 25108f430..30bf11244 100644 --- a/src/components/image-editor/EditorAgentConversationPanelView.test.tsx +++ b/src/components/image-editor/EditorAgentConversationPanelView.test.tsx @@ -14,6 +14,34 @@ import { EditorAgentConversationPanelView } from './EditorAgentConversationPanel import { useImageCanvasContextStore } from './useImageCanvasContextStore.ts'; import type { EditorAgentConversationClient } from './useEditorAgentConversation'; +const createEditorProjectResourceMock = vi.hoisted(() => vi.fn()); +const uploadEditorMediaAssetFileMock = vi.hoisted(() => vi.fn()); +const probeImageFileDimensionsMock = vi.hoisted(() => vi.fn()); + +vi.mock('../../services/image-editor/editorProjectClient', async () => { + const actual = await vi.importActual< + typeof import('../../services/image-editor/editorProjectClient') + >('../../services/image-editor/editorProjectClient'); + return { + ...actual, + createEditorProjectResource: createEditorProjectResourceMock, + }; +}); + +vi.mock('../../services/image-editor/editorMediaAssetUploadClient', () => ({ + uploadEditorMediaAssetFile: uploadEditorMediaAssetFileMock, +})); + +vi.mock('./ImageCanvasFileModel', async () => { + const actual = await vi.importActual( + './ImageCanvasFileModel', + ); + return { + ...actual, + probeImageFileDimensions: probeImageFileDimensionsMock, + }; +}); + function createClient(): EditorAgentConversationClient { return { listConversations: vi.fn().mockResolvedValue([ @@ -88,6 +116,24 @@ function createClient(): EditorAgentConversationClient { describe('EditorAgentConversationPanelView', () => { beforeEach(() => { useImageCanvasContextStore.getState().setProjectId('project-1'); + uploadEditorMediaAssetFileMock.mockReset(); + uploadEditorMediaAssetFileMock.mockResolvedValue({ + src: '/generated/pasted.png', + objectKey: 'generated-character-drafts/editor/agent-paste/image/pasted.png', + assetObjectId: 'asset-object-pasted', + legacyPublicPath: '/generated/pasted.png', + }); + probeImageFileDimensionsMock.mockReset(); + probeImageFileDimensionsMock.mockResolvedValue({ width: 320, height: 240 }); + createEditorProjectResourceMock.mockReset(); + createEditorProjectResourceMock.mockResolvedValue({ + resourceId: 'resource-pasted', + imageSrc: '/generated/pasted.png', + objectKey: 'generated-character-drafts/editor/agent-paste/image/pasted.png', + label: '粘贴图片', + width: 320, + height: 240, + }); }); it('manages conversations, attachments and message sending inside the panel', async () => { @@ -195,6 +241,79 @@ describe('EditorAgentConversationPanelView', () => { ); }); + it('uploads pasted images as canvas attachments before sending', async () => { + const client = createClient(); + + render( + , + ); + + await waitFor(() => { + expect(screen.getByText('已经看到画布内容')).toBeTruthy(); + }); + + const pastedImage = new File(['pasted-image'], 'pasted.png', { + type: 'image/png', + }); + const input = screen.getByLabelText('发送给画布 Agent'); + fireEvent.paste(input, { + clipboardData: { + files: [pastedImage], + }, + }); + + await waitFor(() => { + expect(uploadEditorMediaAssetFileMock).toHaveBeenCalledWith( + pastedImage, + 'image', + expect.objectContaining({ + entityId: 'project-1', + metadata: { source: 'agent-input-paste' }, + }), + ); + }); + expect(probeImageFileDimensionsMock).toHaveBeenCalledWith(pastedImage); + expect(createEditorProjectResourceMock).toHaveBeenCalledWith( + 'project-1', + expect.objectContaining({ + imageSrc: '/generated/pasted.png', + objectKey: 'generated-character-drafts/editor/agent-paste/image/pasted.png', + assetObjectId: 'asset-object-pasted', + width: 320, + height: 240, + sourceType: 'uploaded', + }), + ); + await waitFor(() => { + expect(screen.getByText('粘贴图片')).toBeTruthy(); + }); + + fireEvent.click(screen.getByRole('button', { name: '发送' })); + + await waitFor(() => { + expect(client.streamMessage).toHaveBeenCalledWith( + 'conversation-1', + expect.objectContaining({ + text: '', + attachments: [ + expect.objectContaining({ + source: 'canvas_resource', + referenceId: 'resource-pasted', + imageSrc: '/generated/pasted.png', + width: 320, + height: 240, + }), + ], + }), + expect.any(Object), + ); + }); + }); + it('sends selected attachments even when the text input is empty', async () => { const client = createClient();