修正画布无效项目跳转
显式项目读取失败时返回项目页 403 和 404 项目访问错误不再停留在画布 补充无效项目 ID 回项目页测试
This commit is contained in:
@@ -4,6 +4,7 @@ import { act, render, screen, waitFor } from '@testing-library/react';
|
||||
import { useCallback, useMemo, useRef, useState } from 'react';
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { ApiClientError } from '../../services/apiClient';
|
||||
import type { EditorProjectSnapshot } from '../../services/image-editor/editorProjectClient';
|
||||
import type {
|
||||
CanvasGenerationDialogState,
|
||||
@@ -1243,4 +1244,34 @@ describe('useImageCanvasProjectPersistence', () => {
|
||||
expect(loadEditorProjectMock).not.toHaveBeenCalled();
|
||||
expect(screen.getByTestId('project-id').textContent).toBe('-');
|
||||
});
|
||||
|
||||
it.each([
|
||||
[404, '项目不存在'],
|
||||
[403, '无权访问项目'],
|
||||
])(
|
||||
'returns to the project page when an explicit project fails with %i',
|
||||
async (status, message) => {
|
||||
window.history.replaceState(
|
||||
null,
|
||||
'',
|
||||
'/editor/canvas?projectid=missing-project',
|
||||
);
|
||||
loadEditorProjectMock.mockRejectedValueOnce(
|
||||
new ApiClientError({
|
||||
message,
|
||||
status,
|
||||
code: status === 404 ? 'not_found' : 'forbidden',
|
||||
}),
|
||||
);
|
||||
|
||||
render(<ProjectPersistenceHarness />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(window.location.pathname).toBe('/project');
|
||||
});
|
||||
expect(window.location.search).toBe('');
|
||||
expect(loadEditorProjectMock).toHaveBeenCalledWith('missing-project');
|
||||
expect(loadOrCreateRecentEditorProjectMock).not.toHaveBeenCalled();
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
} from 'react';
|
||||
|
||||
import { ApiClientError } from '../../services/apiClient';
|
||||
import { replaceAppHistoryPath } from '../../routing/appPageRoutes';
|
||||
import { uploadEditorMediaAssetFile } from '../../services/image-editor/editorMediaAssetUploadClient';
|
||||
import { putEditorProjectCoverCache } from '../../services/image-editor/editorProjectCoverCache';
|
||||
import {
|
||||
@@ -80,7 +81,14 @@ type ImageCanvasProjectPersistenceSetters = {
|
||||
function isEditorAuthError(error: unknown) {
|
||||
return (
|
||||
error instanceof ApiClientError &&
|
||||
(error.status === 401 || error.status === 403)
|
||||
error.status === 401
|
||||
);
|
||||
}
|
||||
|
||||
function isEditorProjectAccessError(error: unknown) {
|
||||
return (
|
||||
error instanceof ApiClientError &&
|
||||
(error.status === 403 || error.status === 404)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -166,6 +174,18 @@ function readEditorProjectSessionCache(projectId: string | null) {
|
||||
}
|
||||
}
|
||||
|
||||
function removeEditorProjectSessionCache(projectId: string) {
|
||||
const storage = getEditorProjectSessionStorage();
|
||||
if (!storage) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
storage.removeItem(editorProjectSessionCacheKey(projectId));
|
||||
} catch {
|
||||
// ignore storage cleanup errors
|
||||
}
|
||||
}
|
||||
|
||||
function writeEditorProjectSessionCache(project: EditorProjectSnapshot) {
|
||||
if (projectSnapshotContainsInlineMedia(project)) {
|
||||
return;
|
||||
@@ -673,6 +693,11 @@ export function useImageCanvasProjectPersistence({
|
||||
openEditorLoginModal(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (projectIdFromQuery && isEditorProjectAccessError(error)) {
|
||||
removeEditorProjectSessionCache(projectIdFromQuery);
|
||||
replaceAppHistoryPath('/project');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user