修复图片编辑器生图登录提示
调整编辑器 API 鉴权策略,允许通过 refresh cookie 静默补 access token 真实生图遇到未授权时显示登录提示,不再直接暴露 requestId 补充编辑器组件和客户端测试,并更新方案文档与跟踪记录
This commit is contained in:
@@ -4,6 +4,7 @@ import { fireEvent, render, screen, waitFor, within } from '@testing-library/rea
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { ApiClientError } from '../../services/apiClient';
|
||||
import { ImageCanvasEditorView } from './ImageCanvasEditorView';
|
||||
|
||||
const generateEditorImageMock = vi.hoisted(() => vi.fn());
|
||||
@@ -341,6 +342,30 @@ describe('ImageCanvasEditorView', () => {
|
||||
expect(screen.queryByAltText(/画布图片:生成图片/)).toBeNull();
|
||||
});
|
||||
|
||||
it('asks the user to log in when real generation is unauthorized', async () => {
|
||||
generateEditorImageMock.mockRejectedValueOnce(
|
||||
new ApiClientError({
|
||||
message: '未授权访问(requestId: web-login-required)',
|
||||
status: 401,
|
||||
code: 'UNAUTHORIZED',
|
||||
}),
|
||||
);
|
||||
render(<ImageCanvasEditorView />);
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '生成工具' }));
|
||||
fireEvent.change(screen.getByLabelText('生成提示词'), {
|
||||
target: { value: '一张需要登录生成的图' },
|
||||
});
|
||||
fireEvent.click(screen.getByRole('button', { name: '生成' }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole('alert').textContent).toBe(
|
||||
'请先登录后再生成图片',
|
||||
);
|
||||
});
|
||||
expect(screen.queryByText(/requestId/u)).toBeNull();
|
||||
});
|
||||
|
||||
it('switches tools and restores the previous tool after holding Space', async () => {
|
||||
const user = userEvent.setup();
|
||||
render(<ImageCanvasEditorView />);
|
||||
|
||||
@@ -43,6 +43,7 @@ import {
|
||||
loadOrCreateRecentEditorProject,
|
||||
saveEditorProjectLayout,
|
||||
} from '../../services/image-editor/editorProjectClient';
|
||||
import { ApiClientError } from '../../services/apiClient';
|
||||
|
||||
type EditorAsset = {
|
||||
id: string;
|
||||
@@ -427,6 +428,19 @@ function getPointerId(event: ReactPointerEvent<HTMLElement>) {
|
||||
return Number.isFinite(nativeId) ? nativeId : -1;
|
||||
}
|
||||
|
||||
function resolveImageGenerationErrorMessage(error: unknown) {
|
||||
if (
|
||||
error instanceof ApiClientError &&
|
||||
(error.status === 401 || error.status === 403)
|
||||
) {
|
||||
return '请先登录后再生成图片';
|
||||
}
|
||||
|
||||
return error instanceof Error && error.message.trim()
|
||||
? error.message
|
||||
: '生成图片失败';
|
||||
}
|
||||
|
||||
export function ImageCanvasEditorView() {
|
||||
const canvasViewportRef = useRef<HTMLDivElement | null>(null);
|
||||
const uploadInputRef = useRef<HTMLInputElement | null>(null);
|
||||
@@ -1016,10 +1030,7 @@ export function ImageCanvasEditorView() {
|
||||
...dialog,
|
||||
prompt: normalizedPrompt,
|
||||
status: 'failed',
|
||||
errorMessage:
|
||||
error instanceof Error && error.message.trim()
|
||||
? error.message
|
||||
: '生成图片失败',
|
||||
errorMessage: resolveImageGenerationErrorMessage(error),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user