1
This commit is contained in:
@@ -12,10 +12,11 @@ import type {
|
||||
} from '../types';
|
||||
import { CustomWorldEntityCatalog } from './CustomWorldEntityCatalog';
|
||||
import {
|
||||
type CustomWorldEditorTarget,
|
||||
CustomWorldEntityEditorModal,
|
||||
} from './CustomWorldEntityEditorModal';
|
||||
type RpgCreationEditorTarget,
|
||||
RpgCreationEntityEditorModal,
|
||||
} from './rpg-creation-editor/RpgCreationEntityEditorModal';
|
||||
import * as customWorldCoverAssetService from '../services/customWorldCoverAssetService';
|
||||
import * as rpgCreationAssetClient from '../services/rpg-creation/rpgCreationAssetClient';
|
||||
|
||||
vi.mock('../data/characterPresets', async () => {
|
||||
const actual = await vi.importActual<typeof import('../data/characterPresets')>(
|
||||
@@ -37,12 +38,23 @@ vi.mock('./CharacterAnimator', () => ({
|
||||
CharacterAnimator: () => <div>角色预览</div>,
|
||||
}));
|
||||
|
||||
vi.mock('../services/aiService', () => ({
|
||||
generateCustomWorldSceneImage: vi.fn(),
|
||||
generateCustomWorldSceneNpc: vi.fn(),
|
||||
generateInitialStory: vi.fn(),
|
||||
generateNextStep: vi.fn(),
|
||||
}));
|
||||
vi.mock('../services/rpg-creation/rpgCreationAssetClient', () => {
|
||||
const generateSceneImage = vi.fn();
|
||||
const generateSceneNpc = vi.fn();
|
||||
|
||||
return {
|
||||
rpgCreationAssetClient: {
|
||||
generateSceneImage,
|
||||
generateSceneNpc,
|
||||
},
|
||||
generateCustomWorldSceneImage: generateSceneImage,
|
||||
generateCustomWorldSceneNpc: generateSceneNpc,
|
||||
};
|
||||
});
|
||||
|
||||
const mockedRpgCreationAssetClient = vi.mocked(
|
||||
rpgCreationAssetClient.rpgCreationAssetClient,
|
||||
);
|
||||
|
||||
vi.mock('./CustomWorldNpcVisualEditor', () => ({
|
||||
CustomWorldNpcPortrait: ({ npc }: { npc: { name: string } }) => (
|
||||
@@ -51,8 +63,8 @@ vi.mock('./CustomWorldNpcVisualEditor', () => ({
|
||||
CustomWorldNpcVisualEditor: () => <div>预设形象编辑器</div>,
|
||||
}));
|
||||
|
||||
vi.mock('./game-shell/GameShellRuntime', () => ({
|
||||
GameShellRuntime: ({
|
||||
vi.mock('./rpg-runtime-shell', () => ({
|
||||
RpgRuntimeShell: ({
|
||||
session,
|
||||
}: {
|
||||
session: { gameState: { currentScenePreset?: { name?: string } | null } };
|
||||
@@ -215,7 +227,7 @@ function createProfileWithLandmark(): CustomWorldProfile {
|
||||
|
||||
function LandmarkEditorFlowHarness() {
|
||||
const [profile, setProfile] = useState(createProfileWithLandmark());
|
||||
const [target, setTarget] = useState<CustomWorldEditorTarget | null>({
|
||||
const [target, setTarget] = useState<RpgCreationEditorTarget | null>({
|
||||
kind: 'landmark',
|
||||
mode: 'edit',
|
||||
id: 'landmark-1',
|
||||
@@ -236,7 +248,7 @@ function LandmarkEditorFlowHarness() {
|
||||
onDeleteStoryNpcs={() => {}}
|
||||
onDeleteLandmarks={() => {}}
|
||||
/>
|
||||
<CustomWorldEntityEditorModal
|
||||
<RpgCreationEntityEditorModal
|
||||
profile={profile}
|
||||
target={target}
|
||||
onClose={() => setTarget(null)}
|
||||
@@ -278,7 +290,7 @@ function CampEditorFlowHarness() {
|
||||
],
|
||||
},
|
||||
});
|
||||
const [target, setTarget] = useState<CustomWorldEditorTarget | null>({
|
||||
const [target, setTarget] = useState<RpgCreationEditorTarget | null>({
|
||||
kind: 'camp',
|
||||
});
|
||||
|
||||
@@ -297,7 +309,7 @@ function CampEditorFlowHarness() {
|
||||
onDeleteStoryNpcs={() => {}}
|
||||
onDeleteLandmarks={() => {}}
|
||||
/>
|
||||
<CustomWorldEntityEditorModal
|
||||
<RpgCreationEntityEditorModal
|
||||
profile={profile}
|
||||
target={target}
|
||||
onClose={() => setTarget(null)}
|
||||
@@ -316,7 +328,7 @@ function CoverEditorFlowHarness() {
|
||||
characterRoleIds: ['playable-1'],
|
||||
},
|
||||
});
|
||||
const [target, setTarget] = useState<CustomWorldEditorTarget | null>({
|
||||
const [target, setTarget] = useState<RpgCreationEditorTarget | null>({
|
||||
kind: 'cover',
|
||||
});
|
||||
|
||||
@@ -325,7 +337,7 @@ function CoverEditorFlowHarness() {
|
||||
<pre data-testid="cover-profile-json" className="hidden">
|
||||
{JSON.stringify(profile)}
|
||||
</pre>
|
||||
<CustomWorldEntityEditorModal
|
||||
<RpgCreationEntityEditorModal
|
||||
profile={profile}
|
||||
target={target}
|
||||
onClose={() => setTarget(null)}
|
||||
@@ -350,7 +362,7 @@ test('playable角色打开AI工坊后不会自动关闭', async () => {
|
||||
const handleClose = vi.fn();
|
||||
|
||||
render(
|
||||
<CustomWorldEntityEditorModal
|
||||
<RpgCreationEntityEditorModal
|
||||
profile={createProfile()}
|
||||
target={{ kind: 'playable', mode: 'edit', id: 'playable-1' }}
|
||||
onClose={handleClose}
|
||||
@@ -372,7 +384,7 @@ test('场景角色打开AI工坊后不会自动关闭', async () => {
|
||||
const handleClose = vi.fn();
|
||||
|
||||
render(
|
||||
<CustomWorldEntityEditorModal
|
||||
<RpgCreationEntityEditorModal
|
||||
profile={createProfile()}
|
||||
target={{ kind: 'story', mode: 'edit', id: 'story-1' }}
|
||||
onClose={handleClose}
|
||||
@@ -394,7 +406,7 @@ test('可扮演角色未修改时右上角关闭不会弹确认', async () => {
|
||||
const handleClose = vi.fn();
|
||||
|
||||
render(
|
||||
<CustomWorldEntityEditorModal
|
||||
<RpgCreationEntityEditorModal
|
||||
profile={createProfile()}
|
||||
target={{ kind: 'playable', mode: 'edit', id: 'playable-1' }}
|
||||
onClose={handleClose}
|
||||
@@ -413,7 +425,7 @@ test('可扮演角色修改后右上角关闭才弹确认', async () => {
|
||||
const handleClose = vi.fn();
|
||||
|
||||
render(
|
||||
<CustomWorldEntityEditorModal
|
||||
<RpgCreationEntityEditorModal
|
||||
profile={createProfile()}
|
||||
target={{ kind: 'playable', mode: 'edit', id: 'playable-1' }}
|
||||
onClose={handleClose}
|
||||
@@ -435,7 +447,7 @@ test('场景角色未修改时右上角关闭不会弹确认', async () => {
|
||||
const handleClose = vi.fn();
|
||||
|
||||
render(
|
||||
<CustomWorldEntityEditorModal
|
||||
<RpgCreationEntityEditorModal
|
||||
profile={createProfile()}
|
||||
target={{ kind: 'story', mode: 'edit', id: 'story-1' }}
|
||||
onClose={handleClose}
|
||||
@@ -454,7 +466,7 @@ test('场景角色修改后右上角关闭才弹确认', async () => {
|
||||
const handleClose = vi.fn();
|
||||
|
||||
render(
|
||||
<CustomWorldEntityEditorModal
|
||||
<RpgCreationEntityEditorModal
|
||||
profile={createProfile()}
|
||||
target={{ kind: 'story', mode: 'edit', id: 'story-1' }}
|
||||
onClose={handleClose}
|
||||
@@ -538,9 +550,8 @@ test('实体目录在空 id 列表项下不会触发重复 key 警告', () => {
|
||||
});
|
||||
|
||||
test('场景图片保存后会同步更新编辑页和场景列表', async () => {
|
||||
const aiService = await import('../services/aiService');
|
||||
vi.mocked(aiService.generateCustomWorldSceneImage).mockClear();
|
||||
vi.mocked(aiService.generateCustomWorldSceneImage).mockResolvedValue({
|
||||
mockedRpgCreationAssetClient.generateSceneImage.mockClear();
|
||||
mockedRpgCreationAssetClient.generateSceneImage.mockResolvedValue({
|
||||
imageSrc: '/generated-custom-world-scenes/updated-scene.png',
|
||||
assetId: 'asset-1',
|
||||
model: 'wan2.2-t2i-flash',
|
||||
@@ -573,7 +584,7 @@ test('场景图片保存后会同步更新编辑页和场景列表', async () =>
|
||||
|
||||
await user.click(screen.getByRole('button', { name: '开始生成' }));
|
||||
await waitFor(() => {
|
||||
expect(aiService.generateCustomWorldSceneImage).toHaveBeenCalledTimes(1);
|
||||
expect(mockedRpgCreationAssetClient.generateSceneImage).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
await user.click(screen.getByRole('button', { name: '保存' }));
|
||||
@@ -609,9 +620,8 @@ test('场景图片保存后会同步更新编辑页和场景列表', async () =>
|
||||
});
|
||||
|
||||
test('开局场景图片保存后会同步更新编辑页和场景列表', async () => {
|
||||
const aiService = await import('../services/aiService');
|
||||
vi.mocked(aiService.generateCustomWorldSceneImage).mockClear();
|
||||
vi.mocked(aiService.generateCustomWorldSceneImage).mockResolvedValue({
|
||||
mockedRpgCreationAssetClient.generateSceneImage.mockClear();
|
||||
mockedRpgCreationAssetClient.generateSceneImage.mockResolvedValue({
|
||||
imageSrc: '/generated-custom-world-scenes/updated-camp.png',
|
||||
assetId: 'asset-camp-1',
|
||||
model: 'wan2.2-t2i-flash',
|
||||
@@ -644,7 +654,7 @@ test('开局场景图片保存后会同步更新编辑页和场景列表', async
|
||||
|
||||
await user.click(screen.getByRole('button', { name: '开始生成' }));
|
||||
await waitFor(() => {
|
||||
expect(aiService.generateCustomWorldSceneImage).toHaveBeenCalledTimes(1);
|
||||
expect(mockedRpgCreationAssetClient.generateSceneImage).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
await user.click(screen.getByRole('button', { name: '保存' }));
|
||||
|
||||
Reference in New Issue
Block a user