refactor: 收口抓大鹅运行资料模型
This commit is contained in:
@@ -0,0 +1,268 @@
|
||||
import { expect, test } from 'vitest';
|
||||
|
||||
import type { Match3DAgentSessionSnapshot } from '../../../packages/shared/src/contracts/match3dAgent';
|
||||
import type { Match3DRunSnapshot } from '../../../packages/shared/src/contracts/match3dRuntime';
|
||||
import type {
|
||||
Match3DGeneratedBackgroundAsset,
|
||||
Match3DGeneratedItemAsset,
|
||||
Match3DWorkProfile,
|
||||
} from '../../../packages/shared/src/contracts/match3dWorks';
|
||||
import type { PlatformMatch3DGalleryCard } from '../rpg-entry/rpgEntryWorldPresentation';
|
||||
import {
|
||||
buildMatch3DProfileFromSession,
|
||||
mapPublicWorkDetailToMatch3DWork,
|
||||
resolveActiveMatch3DRuntimeProfile,
|
||||
resolveMatch3DRuntimeBackgroundImageSrc,
|
||||
resolveMatch3DRuntimeGeneratedBackgroundAsset,
|
||||
resolveMatch3DRuntimeGeneratedItemAssets,
|
||||
} from './platformMatch3DRuntimeProfile';
|
||||
|
||||
function buildBackgroundAsset(
|
||||
overrides: Partial<Match3DGeneratedBackgroundAsset> = {},
|
||||
): Match3DGeneratedBackgroundAsset {
|
||||
return {
|
||||
prompt: '森林棋盘',
|
||||
imageSrc: '/generated/match3d/background.png',
|
||||
imageObjectKey: null,
|
||||
status: 'ready',
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
function buildItemAsset(
|
||||
overrides: Partial<Match3DGeneratedItemAsset> = {},
|
||||
): Match3DGeneratedItemAsset {
|
||||
return {
|
||||
itemId: 'item-1',
|
||||
itemName: '蘑菇',
|
||||
imageSrc: '/generated/match3d/item.png',
|
||||
imageObjectKey: null,
|
||||
status: 'image_ready',
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
function buildProfile(
|
||||
overrides: Partial<Match3DWorkProfile> = {},
|
||||
): Match3DWorkProfile {
|
||||
return {
|
||||
workId: 'match3d-work-1',
|
||||
profileId: 'match3d-profile-1',
|
||||
ownerUserId: 'user-1',
|
||||
sourceSessionId: 'match3d-session-1',
|
||||
gameName: '森林抓鹅',
|
||||
themeText: '森林',
|
||||
summary: '找出蘑菇。',
|
||||
tags: ['森林', '蘑菇'],
|
||||
coverImageSrc: '/cover.png',
|
||||
referenceImageSrc: null,
|
||||
clearCount: 12,
|
||||
difficulty: 4,
|
||||
publicationStatus: 'published',
|
||||
playCount: 1,
|
||||
updatedAt: '2026-05-20T00:00:00.000Z',
|
||||
publishedAt: '2026-05-20T00:00:00.000Z',
|
||||
publishReady: true,
|
||||
backgroundPrompt: null,
|
||||
backgroundImageSrc: null,
|
||||
backgroundImageObjectKey: null,
|
||||
generatedBackgroundAsset: null,
|
||||
generatedItemAssets: [buildItemAsset()],
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
function buildRun(overrides: Partial<Match3DRunSnapshot> = {}): Match3DRunSnapshot {
|
||||
return {
|
||||
runId: 'match3d-run-1',
|
||||
profileId: 'match3d-profile-1',
|
||||
status: 'running',
|
||||
snapshotVersion: 1,
|
||||
startedAtMs: 1000,
|
||||
durationLimitMs: 60000,
|
||||
remainingMs: 55000,
|
||||
clearCount: 12,
|
||||
totalItemCount: 12,
|
||||
clearedItemCount: 0,
|
||||
items: [],
|
||||
traySlots: [],
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
function buildPublicWork(
|
||||
overrides: Partial<PlatformMatch3DGalleryCard> = {},
|
||||
): PlatformMatch3DGalleryCard {
|
||||
return {
|
||||
sourceType: 'match3d',
|
||||
workId: 'match3d-work-1',
|
||||
profileId: 'match3d-profile-1',
|
||||
sourceSessionId: 'match3d-session-1',
|
||||
publicWorkCode: 'M3D-00000001',
|
||||
ownerUserId: 'user-1',
|
||||
authorDisplayName: '玩家',
|
||||
worldName: '森林抓鹅',
|
||||
subtitle: '抓大鹅',
|
||||
summaryText: '找出蘑菇。',
|
||||
coverImageSrc: '/cover.png',
|
||||
backgroundPrompt: null,
|
||||
backgroundImageSrc: null,
|
||||
backgroundImageObjectKey: null,
|
||||
generatedBackgroundAsset: null,
|
||||
generatedItemAssets: [buildItemAsset()],
|
||||
themeTags: ['森林', '蘑菇'],
|
||||
visibility: 'published',
|
||||
publishedAt: '2026-05-20T00:00:00.000Z',
|
||||
updatedAt: '2026-05-20T00:00:00.000Z',
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
test('Match3D runtime profile maps public detail and promotes item background asset', () => {
|
||||
const backgroundAsset = buildBackgroundAsset({
|
||||
imageSrc: '/generated/match3d/background-from-item.png',
|
||||
imageObjectKey: 'oss/background-from-item.png',
|
||||
});
|
||||
const work = mapPublicWorkDetailToMatch3DWork(
|
||||
buildPublicWork({
|
||||
generatedBackgroundAsset: null,
|
||||
backgroundImageSrc: null,
|
||||
generatedItemAssets: [
|
||||
buildItemAsset({
|
||||
backgroundAsset,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
);
|
||||
|
||||
expect(work?.generatedBackgroundAsset).toEqual(backgroundAsset);
|
||||
expect(work?.backgroundImageSrc).toBe(
|
||||
'/generated/match3d/background-from-item.png',
|
||||
);
|
||||
expect(work?.backgroundImageObjectKey).toBe('oss/background-from-item.png');
|
||||
});
|
||||
|
||||
test('Match3D runtime profile builds draft profile from session snapshot', () => {
|
||||
const backgroundAsset = buildBackgroundAsset({
|
||||
imageSrc: '/generated/match3d/draft-background.png',
|
||||
});
|
||||
const session: Match3DAgentSessionSnapshot = {
|
||||
sessionId: 'match3d-session-draft',
|
||||
currentTurn: 2,
|
||||
progressPercent: 100,
|
||||
stage: 'draft_compiled',
|
||||
anchorPack: {
|
||||
theme: { key: 'theme', label: '主题', value: '森林', status: 'confirmed' },
|
||||
clearCount: {
|
||||
key: 'clearCount',
|
||||
label: '消除数',
|
||||
value: '12',
|
||||
status: 'confirmed',
|
||||
},
|
||||
difficulty: {
|
||||
key: 'difficulty',
|
||||
label: '难度',
|
||||
value: '4',
|
||||
status: 'confirmed',
|
||||
},
|
||||
},
|
||||
messages: [],
|
||||
lastAssistantReply: null,
|
||||
updatedAt: '2026-05-21T00:00:00.000Z',
|
||||
draft: {
|
||||
profileId: 'match3d-draft-profile',
|
||||
gameName: '草稿抓鹅',
|
||||
themeText: '森林',
|
||||
summaryText: '草稿摘要',
|
||||
tags: ['森林'],
|
||||
coverImageSrc: null,
|
||||
referenceImageSrc: '/reference.png',
|
||||
clearCount: 12,
|
||||
difficulty: 4,
|
||||
publishReady: true,
|
||||
generatedItemAssets: [
|
||||
buildItemAsset({
|
||||
backgroundAsset,
|
||||
}),
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const profile = buildMatch3DProfileFromSession(session);
|
||||
|
||||
expect(profile?.profileId).toBe('match3d-draft-profile');
|
||||
expect(profile?.sourceSessionId).toBe('match3d-session-draft');
|
||||
expect(profile?.publicationStatus).toBe('draft');
|
||||
expect(profile?.coverImageSrc).toBe('/reference.png');
|
||||
expect(profile?.generatedBackgroundAsset).toEqual(backgroundAsset);
|
||||
expect(profile?.backgroundImageSrc).toBe(
|
||||
'/generated/match3d/draft-background.png',
|
||||
);
|
||||
});
|
||||
|
||||
test('Match3D runtime profile selects active profile by run profile id', () => {
|
||||
const runtimeProfile = buildProfile({
|
||||
profileId: 'runtime-profile',
|
||||
gameName: '运行态抓鹅',
|
||||
});
|
||||
const draftProfile = buildProfile({
|
||||
profileId: 'draft-profile',
|
||||
gameName: '旧草稿抓鹅',
|
||||
});
|
||||
|
||||
expect(
|
||||
resolveActiveMatch3DRuntimeProfile(
|
||||
buildRun({ profileId: 'runtime-profile' }),
|
||||
runtimeProfile,
|
||||
draftProfile,
|
||||
),
|
||||
).toBe(runtimeProfile);
|
||||
expect(
|
||||
resolveActiveMatch3DRuntimeProfile(
|
||||
buildRun({ profileId: 'draft-profile' }),
|
||||
runtimeProfile,
|
||||
draftProfile,
|
||||
),
|
||||
).toBe(draftProfile);
|
||||
});
|
||||
|
||||
test('Match3D runtime profile resolves generated assets from matching public detail', () => {
|
||||
const staleProfile = buildProfile({
|
||||
profileId: 'stale-profile',
|
||||
generatedBackgroundAsset: buildBackgroundAsset({
|
||||
imageSrc: '/generated/match3d/stale-background.png',
|
||||
}),
|
||||
generatedItemAssets: [
|
||||
buildItemAsset({
|
||||
itemId: 'stale-item',
|
||||
imageSrc: '/generated/match3d/stale-item.png',
|
||||
}),
|
||||
],
|
||||
});
|
||||
const publicBackground = buildBackgroundAsset({
|
||||
imageSrc: '/generated/match3d/public-background.png',
|
||||
});
|
||||
const publicWork = buildPublicWork({
|
||||
profileId: 'public-profile',
|
||||
generatedBackgroundAsset: publicBackground,
|
||||
generatedItemAssets: [
|
||||
buildItemAsset({
|
||||
itemId: 'public-item',
|
||||
imageSrc: '/generated/match3d/public-item.png',
|
||||
}),
|
||||
],
|
||||
});
|
||||
const run = buildRun({ profileId: 'public-profile' });
|
||||
|
||||
expect(
|
||||
resolveMatch3DRuntimeGeneratedItemAssets(run, staleProfile, publicWork).some(
|
||||
(asset) => asset.imageSrc === '/generated/match3d/public-item.png',
|
||||
),
|
||||
).toBe(true);
|
||||
expect(
|
||||
resolveMatch3DRuntimeGeneratedBackgroundAsset(run, staleProfile, publicWork),
|
||||
).toEqual(publicBackground);
|
||||
expect(resolveMatch3DRuntimeBackgroundImageSrc(run, staleProfile, publicWork)).toBe(
|
||||
'/generated/match3d/public-background.png',
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user