335 lines
9.6 KiB
TypeScript
335 lines
9.6 KiB
TypeScript
import { describe, expect, test } from 'vitest';
|
|
|
|
import type { BigFishWorkSummary } from '../../../packages/shared/src/contracts/bigFishWorkSummary';
|
|
import type { CustomWorldWorkSummary } from '../../../packages/shared/src/contracts/customWorldWorkSummary';
|
|
import type { BabyObjectMatchDraft } from '../../../packages/shared/src/contracts/edutainmentBabyObject';
|
|
import type { Match3DWorkSummary } from '../../../packages/shared/src/contracts/match3dWorks';
|
|
import type { PuzzleWorkSummary } from '../../../packages/shared/src/contracts/puzzleWorkSummary';
|
|
import type { SquareHoleWorkSummary } from '../../../packages/shared/src/contracts/squareHoleWorks';
|
|
import type { VisualNovelWorkSummary } from '../../../packages/shared/src/contracts/visualNovel';
|
|
import { resolvePlatformCreationWorkDeleteConfirmationModel } from './platformCreationWorkDeleteFlow';
|
|
|
|
describe('platformCreationWorkDeleteFlow', () => {
|
|
test('resolves RPG library delete confirmation without draft notice keys', () => {
|
|
expect(
|
|
resolvePlatformCreationWorkDeleteConfirmationModel({
|
|
kind: 'rpg-library',
|
|
entry: {
|
|
profileId: 'rpg-profile',
|
|
worldName: '潮雾列岛',
|
|
},
|
|
}),
|
|
).toEqual({
|
|
id: 'rpg-profile',
|
|
title: '潮雾列岛',
|
|
detail: '删除后会从你的作品列表和公开广场中移除。',
|
|
noticeKeys: [],
|
|
});
|
|
});
|
|
|
|
test('resolves RPG work delete detail and notice keys by work status', () => {
|
|
expect(
|
|
resolvePlatformCreationWorkDeleteConfirmationModel({
|
|
kind: 'rpg',
|
|
work: buildRpgWork(),
|
|
}),
|
|
).toEqual({
|
|
id: 'rpg-work',
|
|
title: 'RPG 草稿',
|
|
detail: '删除后会从你的作品列表中移除。',
|
|
noticeKeys: ['rpg:rpg-work', 'rpg:rpg-session', 'rpg:rpg-profile'],
|
|
});
|
|
|
|
expect(
|
|
resolvePlatformCreationWorkDeleteConfirmationModel({
|
|
kind: 'rpg',
|
|
work: buildRpgWork({ status: 'published' }),
|
|
}).detail,
|
|
).toBe('删除后会从你的作品列表和公开广场中移除。');
|
|
});
|
|
|
|
test('resolves mini game delete models with shared public and private detail copy', () => {
|
|
expect(
|
|
resolvePlatformCreationWorkDeleteConfirmationModel({
|
|
kind: 'big-fish',
|
|
work: buildBigFishWork({ status: 'published' }),
|
|
}),
|
|
).toMatchObject({
|
|
id: 'big-fish-work',
|
|
title: '大鱼作品',
|
|
detail: '删除后会从你的作品列表和公开广场中移除。',
|
|
noticeKeys: ['big-fish:big-fish-work', 'big-fish:big-fish-session'],
|
|
});
|
|
|
|
expect(
|
|
resolvePlatformCreationWorkDeleteConfirmationModel({
|
|
kind: 'match3d',
|
|
work: buildMatch3DWork(),
|
|
}).detail,
|
|
).toBe('删除后会从你的作品列表中移除。');
|
|
expect(
|
|
resolvePlatformCreationWorkDeleteConfirmationModel({
|
|
kind: 'square-hole',
|
|
work: buildSquareHoleWork({ publicationStatus: 'published' }),
|
|
}).noticeKeys,
|
|
).toEqual([
|
|
'square-hole:square-hole-work',
|
|
'square-hole:square-hole-profile',
|
|
'square-hole:square-hole-session',
|
|
]);
|
|
});
|
|
|
|
test('resolves puzzle title fallback and stable result notice keys', () => {
|
|
expect(
|
|
resolvePlatformCreationWorkDeleteConfirmationModel({
|
|
kind: 'puzzle',
|
|
work: buildPuzzleWork({
|
|
workTitle: ' ',
|
|
levelName: ' 雾港第一关 ',
|
|
sourceSessionId: 'puzzle-session-ocean',
|
|
}),
|
|
}),
|
|
).toEqual({
|
|
id: 'puzzle-work',
|
|
title: '雾港第一关',
|
|
detail: '删除后会从你的作品列表中移除。',
|
|
noticeKeys: [
|
|
'puzzle:puzzle-work',
|
|
'puzzle:puzzle-profile',
|
|
'puzzle:puzzle-session-ocean',
|
|
'puzzle:puzzle-work-ocean',
|
|
'puzzle:puzzle-profile-ocean',
|
|
],
|
|
});
|
|
|
|
expect(
|
|
resolvePlatformCreationWorkDeleteConfirmationModel({
|
|
kind: 'puzzle',
|
|
work: buildPuzzleWork({ workTitle: '', levelName: ' ' }),
|
|
}).title,
|
|
).toBe('未命名拼图');
|
|
});
|
|
|
|
test('resolves visual novel and baby object match special delete copy', () => {
|
|
expect(
|
|
resolvePlatformCreationWorkDeleteConfirmationModel({
|
|
kind: 'visual-novel',
|
|
work: buildVisualNovelWork({ title: '', publishStatus: 'published' }),
|
|
}),
|
|
).toEqual({
|
|
id: 'visual-novel-profile',
|
|
title: '未命名视觉小说',
|
|
detail: '删除后会从你的作品列表和公开广场中移除。',
|
|
noticeKeys: ['visual-novel:visual-novel-profile'],
|
|
});
|
|
|
|
expect(
|
|
resolvePlatformCreationWorkDeleteConfirmationModel({
|
|
kind: 'baby-object-match',
|
|
work: buildBabyObjectMatchDraft({
|
|
workTitle: ' ',
|
|
publicationStatus: 'published',
|
|
}),
|
|
}),
|
|
).toEqual({
|
|
id: 'baby-profile',
|
|
title: '宝贝识物',
|
|
detail: '删除后会从你的作品列表和寓教于乐板块中移除。',
|
|
noticeKeys: [
|
|
'baby-object-match:baby-profile',
|
|
'baby-object-match:baby-draft',
|
|
],
|
|
});
|
|
});
|
|
});
|
|
|
|
function buildRpgWork(
|
|
overrides: Partial<CustomWorldWorkSummary> = {},
|
|
): CustomWorldWorkSummary {
|
|
return {
|
|
workId: 'rpg-work',
|
|
sourceType: 'agent_session',
|
|
status: 'draft',
|
|
title: 'RPG 草稿',
|
|
subtitle: '待完善',
|
|
summary: 'RPG 摘要。',
|
|
coverImageSrc: null,
|
|
updatedAt: '2026-06-04T00:00:00.000Z',
|
|
publishedAt: null,
|
|
stage: 'draft',
|
|
stageLabel: '草稿',
|
|
playableNpcCount: 1,
|
|
landmarkCount: 1,
|
|
sessionId: 'rpg-session',
|
|
profileId: 'rpg-profile',
|
|
canResume: true,
|
|
canEnterWorld: false,
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
function buildBigFishWork(
|
|
overrides: Partial<BigFishWorkSummary> = {},
|
|
): BigFishWorkSummary {
|
|
return {
|
|
workId: 'big-fish-work',
|
|
sourceSessionId: 'big-fish-session',
|
|
ownerUserId: 'user-1',
|
|
authorDisplayName: '玩家',
|
|
title: '大鱼作品',
|
|
subtitle: '大鱼吃小鱼',
|
|
summary: '大鱼摘要。',
|
|
coverImageSrc: null,
|
|
status: 'draft',
|
|
updatedAt: '2026-06-04T00:00:00.000Z',
|
|
publishedAt: null,
|
|
publishReady: false,
|
|
levelCount: 1,
|
|
levelMainImageReadyCount: 0,
|
|
levelMotionReadyCount: 0,
|
|
backgroundReady: true,
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
function buildPuzzleWork(
|
|
overrides: Partial<PuzzleWorkSummary> = {},
|
|
): PuzzleWorkSummary {
|
|
return {
|
|
workId: 'puzzle-work',
|
|
profileId: 'puzzle-profile',
|
|
ownerUserId: 'user-1',
|
|
sourceSessionId: 'puzzle-session',
|
|
authorDisplayName: '玩家',
|
|
workTitle: '拼图作品',
|
|
workDescription: '拼图摘要。',
|
|
levelName: '拼图第一关',
|
|
summary: '拼图摘要。',
|
|
themeTags: [],
|
|
coverImageSrc: null,
|
|
coverAssetId: null,
|
|
publicationStatus: 'draft',
|
|
updatedAt: '2026-06-04T00:00:00.000Z',
|
|
publishedAt: null,
|
|
playCount: 0,
|
|
remixCount: 0,
|
|
likeCount: 0,
|
|
publishReady: false,
|
|
levels: [],
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
function buildMatch3DWork(
|
|
overrides: Partial<Match3DWorkSummary> = {},
|
|
): Match3DWorkSummary {
|
|
return {
|
|
workId: 'match3d-work',
|
|
profileId: 'match3d-profile',
|
|
ownerUserId: 'user-1',
|
|
sourceSessionId: 'match3d-session',
|
|
gameName: '抓大鹅作品',
|
|
themeText: '糖果厨房',
|
|
summary: '抓大鹅摘要。',
|
|
tags: [],
|
|
coverImageSrc: null,
|
|
referenceImageSrc: null,
|
|
clearCount: 12,
|
|
difficulty: 4,
|
|
publicationStatus: 'draft',
|
|
playCount: 0,
|
|
updatedAt: '2026-06-04T00:00:00.000Z',
|
|
publishedAt: null,
|
|
publishReady: false,
|
|
generatedItemAssets: [],
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
function buildSquareHoleWork(
|
|
overrides: Partial<SquareHoleWorkSummary> = {},
|
|
): SquareHoleWorkSummary {
|
|
return {
|
|
workId: 'square-hole-work',
|
|
profileId: 'square-hole-profile',
|
|
ownerUserId: 'user-1',
|
|
sourceSessionId: 'square-hole-session',
|
|
gameName: '方洞作品',
|
|
themeText: '图形',
|
|
twistRule: '反直觉',
|
|
summary: '方洞摘要。',
|
|
tags: [],
|
|
coverImageSrc: null,
|
|
backgroundPrompt: '背景',
|
|
backgroundImageSrc: null,
|
|
shapeOptions: [],
|
|
holeOptions: [],
|
|
shapeCount: 8,
|
|
difficulty: 4,
|
|
publicationStatus: 'draft',
|
|
playCount: 0,
|
|
updatedAt: '2026-06-04T00:00:00.000Z',
|
|
publishedAt: null,
|
|
publishReady: false,
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
function buildVisualNovelWork(
|
|
overrides: Partial<VisualNovelWorkSummary> = {},
|
|
): VisualNovelWorkSummary {
|
|
return {
|
|
runtimeKind: 'visual-novel',
|
|
profileId: 'visual-novel-profile',
|
|
ownerUserId: 'user-1',
|
|
title: '视觉小说作品',
|
|
description: '视觉小说摘要。',
|
|
coverImageSrc: null,
|
|
tags: [],
|
|
publishStatus: 'draft',
|
|
publishReady: false,
|
|
playCount: 0,
|
|
updatedAt: '2026-06-04T00:00:00.000Z',
|
|
publishedAt: null,
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
function buildBabyObjectMatchDraft(
|
|
overrides: Partial<BabyObjectMatchDraft> = {},
|
|
): BabyObjectMatchDraft {
|
|
return {
|
|
draftId: 'baby-draft',
|
|
profileId: 'baby-profile',
|
|
templateId: 'baby-object-match',
|
|
templateName: '宝贝识物',
|
|
workTitle: '宝贝识物作品',
|
|
workDescription: '宝贝识物摘要。',
|
|
itemNames: ['苹果', '香蕉'],
|
|
itemAssets: [
|
|
{
|
|
itemId: 'apple',
|
|
itemName: '苹果',
|
|
imageSrc: '/apple.png',
|
|
assetObjectId: null,
|
|
generationProvider: 'placeholder',
|
|
prompt: '苹果',
|
|
},
|
|
{
|
|
itemId: 'banana',
|
|
itemName: '香蕉',
|
|
imageSrc: '/banana.png',
|
|
assetObjectId: null,
|
|
generationProvider: 'placeholder',
|
|
prompt: '香蕉',
|
|
},
|
|
],
|
|
themeTags: [],
|
|
publicationStatus: 'draft',
|
|
createdAt: '2026-06-04T00:00:00.000Z',
|
|
updatedAt: '2026-06-04T00:00:00.000Z',
|
|
publishedAt: null,
|
|
...overrides,
|
|
};
|
|
}
|