fix: 修复画布资源定位状态误报

让 focusResource 返回资源匹配结果
未找到画布图层时向右键菜单返回失败状态
补充资源定位成功与失败的回归测试
This commit is contained in:
2026-07-31 13:34:29 +08:00
parent 65fabe51ab
commit cfd129a0bf
5 changed files with 20 additions and 9 deletions
@@ -51,6 +51,7 @@ function renderMessage(
describe('MessageBubble', () => {
beforeEach(() => {
vi.clearAllMocks();
focusResourceMock.mockReturnValue({ found: true });
vi.mocked(copyTextToClipboard).mockResolvedValue(true);
});
@@ -448,6 +449,13 @@ describe('MessageBubble', () => {
);
}
expect(focusResourceMock).toHaveBeenCalledTimes(3);
focusResourceMock.mockReturnValueOnce({ found: false });
fireEvent.contextMenu(imageCard!, { clientX: 30, clientY: 40 });
fireEvent.click(screen.getByRole('menuitem', { name: '在画布中定位' }));
expect(focusResourceMock).toHaveBeenLastCalledWith('resource-image');
expect(screen.getByRole('menuitem', { name: '定位失败' })).toBeTruthy();
});
it('exports right-click images through the native HostBridge', async () => {
@@ -4,6 +4,7 @@ import {
useState,
} from 'react';
import type { ImageCanvasActions } from '@/src/components/image-editor/ImageCanvasActionsContext.ts';
import { readAssetBytes } from '@/src/services/assetReadUrlService.ts';
import { copyTextToClipboard } from '@/src/services/clipboard.ts';
import {
@@ -234,7 +235,7 @@ async function downloadAsset(asset: EditorAgentContextAsset) {
function focusAssetOnCanvas(
asset: EditorAgentContextAsset,
onFocusResource?: (resourceId: string) => void,
onFocusResource?: ImageCanvasActions['focusResource'],
) {
if (asset.kind !== 'generated_media' || !onFocusResource) {
return false;
@@ -243,8 +244,7 @@ function focusAssetOnCanvas(
if (!resourceId) {
return false;
}
onFocusResource(resourceId);
return true;
return onFocusResource(resourceId).found;
}
export function useRightClickMenu({
@@ -252,7 +252,7 @@ export function useRightClickMenu({
onFocusResource,
}: {
onReferenceImage?: (asset: EditorAgentContextAsset) => boolean;
onFocusResource?: (resourceId: string) => void;
onFocusResource?: ImageCanvasActions['focusResource'];
} = {}) {
const [rightClickMenu, setRightClickMenu] =
useState<RightClickMenuState | null>(null);
@@ -11,7 +11,7 @@ import { ImageCanvasActionsProvider } from './ImageCanvasActionsProvider';
describe('ImageCanvasActionsContext', () => {
it('exposes the editor-scoped canvas actions', () => {
const focusResource = vi.fn();
const focusResource = vi.fn(() => ({ found: true }));
const refreshCanvas = vi.fn();
const { result } = renderHook(useImageCanvasActions, {
wrapper: ({ children }: { children: ReactNode }) => (
@@ -24,11 +24,13 @@ describe('ImageCanvasActionsContext', () => {
),
});
let focusResult: { found: boolean } | undefined;
act(() => {
result.current.focusResource('resource-a');
focusResult = result.current.focusResource('resource-a');
result.current.refreshCanvas();
});
expect(focusResult).toEqual({ found: true });
expect(focusResource).toHaveBeenCalledWith('resource-a');
expect(refreshCanvas).toHaveBeenCalledTimes(1);
});
@@ -1,7 +1,7 @@
import { createContext, useContext } from 'react';
export type ImageCanvasActions = {
focusResource: (resourceId: string) => void;
focusResource: (resourceId: string) => { found: boolean };
refreshCanvas: () => void;
};
@@ -904,15 +904,16 @@ export function ImageCanvasEditorView({
(resourceId: string) => {
const normalizedResourceId = resourceId.trim();
if (!normalizedResourceId) {
return;
return { found: false };
}
const targetLayer = layersRef.current.find(
(layer) => layer.resourceId === normalizedResourceId,
);
if (!targetLayer) {
return;
return { found: false };
}
focusCanvasBounds(targetLayer, { animate: true });
return { found: true };
},
[focusCanvasBounds],
);