1
This commit is contained in:
@@ -32,6 +32,8 @@ vi.mock('./Match3DModelPreview', () => ({
|
||||
}));
|
||||
|
||||
vi.mock('../../services/assetReadUrlService', () => ({
|
||||
isGeneratedLegacyPath: (value: string) =>
|
||||
/^\/?generated-[^/?#]+\/.+/u.test(value.trim()),
|
||||
readAssetBytes: vi.fn(() =>
|
||||
Promise.resolve(
|
||||
new Response(new Uint8Array([104, 101, 108, 108, 111]), {
|
||||
@@ -47,6 +49,7 @@ vi.mock('../../services/assetReadUrlService', () => ({
|
||||
vi.mock('../../services/match3d-works', () => ({
|
||||
generateMatch3DWorkTags: vi.fn(),
|
||||
publishMatch3DWork: vi.fn(),
|
||||
updateMatch3DGeneratedItemAssets: vi.fn(),
|
||||
updateMatch3DWork: vi.fn(),
|
||||
}));
|
||||
|
||||
@@ -180,6 +183,53 @@ describe('Match3DResultView', () => {
|
||||
expect(match3dWorksService.publishMatch3DWork).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('试玩前保存响应缺少素材时仍把当前生成模型带入运行态', async () => {
|
||||
const generatedItemAssets = [
|
||||
{
|
||||
itemId: 'match3d-item-1',
|
||||
itemName: '草莓',
|
||||
imageSrc:
|
||||
'/generated-match3d-assets/session/profile/items/match3d-item-1-item/image.png',
|
||||
imageObjectKey:
|
||||
'generated-match3d-assets/session/profile/items/match3d-item-1-item/image.png',
|
||||
modelSrc:
|
||||
'/generated-match3d-assets/session/profile/items/match3d-item-1-item/model/model.glb',
|
||||
modelObjectKey:
|
||||
'generated-match3d-assets/session/profile/items/match3d-item-1-item/model/model.glb',
|
||||
modelFileName: 'strawberry.glb',
|
||||
taskUuid: 'task-strawberry',
|
||||
subscriptionKey: 'sub-strawberry',
|
||||
status: 'model_ready',
|
||||
error: null,
|
||||
},
|
||||
];
|
||||
const profile = createProfile({ generatedItemAssets });
|
||||
const savedProfile = createProfile({ generatedItemAssets: [] });
|
||||
const onStartTestRun = vi.fn();
|
||||
vi.mocked(match3dWorksService.updateMatch3DWork).mockResolvedValue({
|
||||
item: savedProfile,
|
||||
});
|
||||
|
||||
render(
|
||||
<Match3DResultView
|
||||
profile={profile}
|
||||
onBack={() => {}}
|
||||
onStartTestRun={onStartTestRun}
|
||||
/>,
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '试玩' }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(onStartTestRun).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
profileId: profile.profileId,
|
||||
generatedItemAssets,
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('发布仍要求封面和标签数量满足门槛', () => {
|
||||
render(
|
||||
<Match3DResultView
|
||||
@@ -277,6 +327,44 @@ describe('Match3DResultView', () => {
|
||||
);
|
||||
});
|
||||
|
||||
test('历史素材只有 modelObjectKey 时仍能进入模型预览', () => {
|
||||
const modelObjectKey =
|
||||
'generated-match3d-assets/session/profile/items/strawberry/model/model.glb';
|
||||
render(
|
||||
<Match3DResultView
|
||||
profile={createProfile({
|
||||
clearCount: 3,
|
||||
generatedItemAssets: [
|
||||
{
|
||||
itemId: 'match3d-item-1',
|
||||
itemName: '草莓',
|
||||
imageSrc:
|
||||
'/generated-match3d-assets/session/profile/items/strawberry/image.png',
|
||||
imageObjectKey:
|
||||
'generated-match3d-assets/session/profile/items/strawberry/image.png',
|
||||
modelSrc: null,
|
||||
modelObjectKey,
|
||||
modelFileName: 'strawberry.glb',
|
||||
taskUuid: 'task-strawberry',
|
||||
subscriptionKey: 'sub-strawberry',
|
||||
status: 'model_ready',
|
||||
error: null,
|
||||
},
|
||||
],
|
||||
})}
|
||||
onBack={() => {}}
|
||||
onStartTestRun={() => {}}
|
||||
/>,
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '3D素材' }));
|
||||
fireEvent.click(screen.getByRole('button', { name: /草莓/u }));
|
||||
|
||||
expect(
|
||||
screen.getByTestId('match3d-model-preview').getAttribute('data-model-src'),
|
||||
).toBe(modelObjectKey);
|
||||
});
|
||||
|
||||
test('草稿阶段仅有切割图片时模型预览为空', () => {
|
||||
render(
|
||||
<Match3DResultView
|
||||
@@ -364,6 +452,82 @@ describe('Match3DResultView', () => {
|
||||
expect(screen.queryByRole('button', { name: /水果核心物件/u })).toBeNull();
|
||||
});
|
||||
|
||||
test('历史草稿同时带旧 draft 和 profile 模型时以 profile 模型补齐试玩资产', async () => {
|
||||
const draftAsset = {
|
||||
itemId: 'match3d-item-1',
|
||||
itemName: '草莓',
|
||||
imageSrc:
|
||||
'/generated-match3d-assets/session/profile/items/match3d-item-1-item/image.png',
|
||||
imageObjectKey:
|
||||
'generated-match3d-assets/session/profile/items/match3d-item-1-item/image.png',
|
||||
modelSrc: null,
|
||||
modelObjectKey: null,
|
||||
modelFileName: null,
|
||||
taskUuid: null,
|
||||
subscriptionKey: null,
|
||||
status: 'image_ready',
|
||||
error: null,
|
||||
};
|
||||
const profileAsset = {
|
||||
...draftAsset,
|
||||
modelSrc: null,
|
||||
modelObjectKey:
|
||||
'generated-match3d-assets/session/profile/items/match3d-item-1-item/model/model.glb',
|
||||
modelFileName: 'strawberry.glb',
|
||||
taskUuid: 'task-strawberry',
|
||||
subscriptionKey: 'sub-strawberry',
|
||||
status: 'model_ready',
|
||||
};
|
||||
const profile = createProfile({ generatedItemAssets: [profileAsset] });
|
||||
const onStartTestRun = vi.fn();
|
||||
vi.mocked(match3dWorksService.updateMatch3DWork).mockResolvedValue({
|
||||
item: createProfile({ generatedItemAssets: [] }),
|
||||
});
|
||||
|
||||
render(
|
||||
<Match3DResultView
|
||||
profile={profile}
|
||||
draft={{
|
||||
profileId: profile.profileId,
|
||||
gameName: profile.gameName,
|
||||
themeText: profile.themeText,
|
||||
summary: profile.summary,
|
||||
tags: profile.tags,
|
||||
coverImageSrc: null,
|
||||
referenceImageSrc: null,
|
||||
clearCount: profile.clearCount,
|
||||
difficulty: profile.difficulty,
|
||||
generatedItemAssets: [draftAsset],
|
||||
}}
|
||||
onBack={() => {}}
|
||||
onStartTestRun={onStartTestRun}
|
||||
/>,
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '3D素材' }));
|
||||
fireEvent.click(screen.getByRole('button', { name: /草莓/u }));
|
||||
|
||||
expect(
|
||||
screen.getByTestId('match3d-model-preview').getAttribute('data-model-src'),
|
||||
).toBe(profileAsset.modelObjectKey);
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '试玩' }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(onStartTestRun).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
generatedItemAssets: [
|
||||
expect.objectContaining({
|
||||
itemId: 'match3d-item-1',
|
||||
modelObjectKey: profileAsset.modelObjectKey,
|
||||
status: 'model_ready',
|
||||
}),
|
||||
],
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('Rodin 图生模型提交前会把 generated 参考图转成 data URL', async () => {
|
||||
vi.mocked(hyper3dService.submitHyper3dImageToModel).mockResolvedValue({
|
||||
ok: true,
|
||||
@@ -393,6 +557,28 @@ describe('Match3DResultView', () => {
|
||||
],
|
||||
raw: {},
|
||||
});
|
||||
vi.mocked(match3dWorksService.updateMatch3DGeneratedItemAssets)
|
||||
.mockResolvedValue({
|
||||
item: createProfile({
|
||||
generatedItemAssets: [
|
||||
{
|
||||
itemId: 'match3d-item-1',
|
||||
itemName: '草莓',
|
||||
imageSrc:
|
||||
'/generated-match3d-assets/session/profile/items/match3d-item-1-item/image.png',
|
||||
imageObjectKey:
|
||||
'generated-match3d-assets/session/profile/items/match3d-item-1-item/image.png',
|
||||
modelSrc: 'https://cdn.example.com/strawberry.glb',
|
||||
modelObjectKey: null,
|
||||
modelFileName: 'strawberry.glb',
|
||||
taskUuid: 'task-image',
|
||||
subscriptionKey: 'sub-image',
|
||||
status: 'model_ready',
|
||||
error: null,
|
||||
},
|
||||
],
|
||||
}),
|
||||
});
|
||||
vi.stubGlobal('fetch', vi.fn());
|
||||
|
||||
render(
|
||||
@@ -440,6 +626,23 @@ describe('Match3DResultView', () => {
|
||||
expect(hyper3dService.getHyper3dDownloads).toHaveBeenCalledWith({
|
||||
taskUuid: 'task-image',
|
||||
});
|
||||
expect(
|
||||
match3dWorksService.updateMatch3DGeneratedItemAssets,
|
||||
).toHaveBeenCalledWith(
|
||||
'match3d-profile-1',
|
||||
expect.objectContaining({
|
||||
generatedItemAssets: [
|
||||
expect.objectContaining({
|
||||
itemId: 'match3d-item-1',
|
||||
modelSrc: 'https://cdn.example.com/strawberry.glb',
|
||||
modelFileName: 'strawberry.glb',
|
||||
status: 'model_ready',
|
||||
taskUuid: 'task-image',
|
||||
subscriptionKey: 'sub-image',
|
||||
}),
|
||||
],
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user