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 { 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 { 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 { 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 { 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 { 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 { 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 { 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, }; }