import { expect, test } from 'vitest'; import { buildPlatformWorldDisplayTags, buildPuzzleWorkCoverSlides, EDUTAINMENT_BABY_OBJECT_MATCH_TEMPLATE_ID, EDUTAINMENT_BABY_OBJECT_MATCH_TEMPLATE_NAME, formatPlatformWorkDisplayName, formatPlatformWorkDisplayTags, formatPlatformWorldTime, isEdutainmentGalleryEntry, isVisualNovelGalleryEntry, mapBabyObjectMatchDraftToPlatformGalleryCard, mapVisualNovelWorkToPlatformGalleryCard, type PlatformEdutainmentGalleryCard, type PlatformPuzzleGalleryCard, resolvePlatformPublicWorkCode, resolvePlatformWorldFallbackCoverImage, } from './rpgEntryWorldPresentation'; test('formatPlatformWorldTime formats backend seconds timestamp text as date', () => { expect(formatPlatformWorldTime('1777110165.990127Z')).toBe('2026-04-25'); }); test('formatPlatformWorldTime keeps full year for iso date strings', () => { expect(formatPlatformWorldTime('2026-04-25T12:00:00.000Z')).toBe( '2026-04-25', ); }); test('formatPlatformWorldTime uses utc calendar date for zulu time', () => { expect(formatPlatformWorldTime('2026-04-25T00:30:00.000Z')).toBe( '2026-04-25', ); }); test('formatPlatformWorldTime keeps fallback text for invalid values', () => { expect(formatPlatformWorldTime(null)).toBe('未发布'); expect(formatPlatformWorldTime('not-a-date')).toBe('not-a-date'); }); test('platform work display text limits names and tags by character count', () => { expect(formatPlatformWorkDisplayName('热门高分拼图超长标题')).toBe( '热门高分拼图超长', ); expect( formatPlatformWorkDisplayTags(['超长机关标签', '星桥', '超长机关标签']), ).toEqual(['超长机关', '星桥']); }); test('platform public cards use play type reference images as cover fallback', () => { const puzzleCard: PlatformPuzzleGalleryCard = { sourceType: 'puzzle', workId: 'puzzle-work-1', profileId: 'puzzle-profile-1', publicWorkCode: 'PZ-PUZZLE1', ownerUserId: 'user-1', authorDisplayName: '玩家', worldName: '机关拼图', subtitle: '拼图关卡', summaryText: '公开作品', coverImageSrc: '/generated-puzzle-assets/session/cover/image.png', themeTags: ['拼图'], playCount: 1, remixCount: 0, likeCount: 0, visibility: 'published', publishedAt: '2026-05-18T00:00:00.000Z', updatedAt: '2026-05-18T00:00:00.000Z', }; expect(resolvePlatformWorldFallbackCoverImage(puzzleCard)).toBe( '/creation-type-references/puzzle.webp', ); }); test('buildPuzzleWorkCoverSlides prefers each level formal image', () => { const slides = buildPuzzleWorkCoverSlides({ workId: 'work-1', profileId: 'profile-1', ownerUserId: 'user-1', authorDisplayName: '玩家', levelName: '第一关', summary: '拼图摘要', themeTags: ['拼图'], coverImageSrc: '/cover.png', publicationStatus: 'published', updatedAt: '2026-04-25T00:00:00.000Z', publishedAt: '2026-04-25T00:00:00.000Z', publishReady: true, levels: [ { levelId: 'level-1', levelName: '石桥', pictureDescription: '石桥画面', selectedCandidateId: 'candidate-2', coverImageSrc: '/level-1-cover.png', coverAssetId: null, generationStatus: 'ready', candidates: [ { candidateId: 'candidate-1', imageSrc: '/level-1-a.png', assetId: 'asset-1', prompt: '', sourceType: 'generated', selected: false, }, { candidateId: 'candidate-2', imageSrc: '/level-1-b.png', assetId: 'asset-2', prompt: '', sourceType: 'generated', selected: false, }, ], }, { levelId: 'level-2', levelName: '星港', pictureDescription: '星港画面', selectedCandidateId: null, coverImageSrc: '/level-2-cover.png', coverAssetId: null, generationStatus: 'ready', candidates: [], }, ], }); expect(slides).toEqual([ { id: 'level-1', imageSrc: '/level-1-b.png', label: '石桥', }, { id: 'level-2', imageSrc: '/level-2-cover.png', label: '星港', }, ]); }); test('maps visual novel work to platform gallery card with VN public code', () => { const card = mapVisualNovelWorkToPlatformGalleryCard({ runtimeKind: 'visual-novel', profileId: 'vn-profile-demo-12345678', ownerUserId: 'user-1', title: '雨夜终章', description: '失踪列车上的选择。', coverImageSrc: '/vn-cover.png', tags: ['悬疑', '列车'], publishStatus: 'published', publishReady: true, playCount: 7, updatedAt: '2026-05-07T00:00:00.000Z', publishedAt: '2026-05-07T00:00:00.000Z', }); expect(isVisualNovelGalleryEntry(card)).toBe(true); expect(card.publicWorkCode).toBe('VN-12345678'); expect(resolvePlatformPublicWorkCode(card)).toBe('VN-12345678'); expect(buildPlatformWorldDisplayTags(card, 2)).toEqual(['悬疑', '列车']); }); test('keeps baby object match public card code and template label intact', () => { const card: PlatformEdutainmentGalleryCard = { sourceType: 'edutainment', templateId: EDUTAINMENT_BABY_OBJECT_MATCH_TEMPLATE_ID, templateName: EDUTAINMENT_BABY_OBJECT_MATCH_TEMPLATE_NAME, workId: 'baby-object-match-work-1', profileId: 'baby-object-match-profile-1', sourceSessionId: 'baby-object-match-session-1', publicWorkCode: 'EDU-BABY01', ownerUserId: 'user-1', authorDisplayName: '陶泥儿主', worldName: '宝贝识物水果篮', subtitle: EDUTAINMENT_BABY_OBJECT_MATCH_TEMPLATE_NAME, summaryText: '将物品放入对应的篮子里。', coverImageSrc: null, themeTags: ['寓教于乐'], playCount: 3, remixCount: 0, likeCount: 1, recentPlayCount7d: 3, visibility: 'published', publishedAt: '2026-05-11T10:00:00.000Z', updatedAt: '2026-05-11T10:00:00.000Z', }; expect(isEdutainmentGalleryEntry(card)).toBe(true); expect(resolvePlatformPublicWorkCode(card)).toBe('EDU-BABY01'); expect(buildPlatformWorldDisplayTags(card, 2)).toEqual(['寓教于乐']); }); test('maps baby object match draft to edutainment public card', () => { const card = mapBabyObjectMatchDraftToPlatformGalleryCard({ draftId: 'baby-object-draft-1', profileId: 'baby-object-profile-12345678', templateId: EDUTAINMENT_BABY_OBJECT_MATCH_TEMPLATE_ID, templateName: EDUTAINMENT_BABY_OBJECT_MATCH_TEMPLATE_NAME, workTitle: '宝贝识物水果篮', workDescription: '苹果和香蕉识物分类', itemNames: ['苹果', '香蕉'], itemAssets: [ { itemId: 'baby-object-item-1', itemName: '苹果', imageSrc: '/apple.png', assetObjectId: null, generationProvider: 'placeholder', prompt: '苹果', }, { itemId: 'baby-object-item-2', itemName: '香蕉', imageSrc: '/banana.png', assetObjectId: null, generationProvider: 'placeholder', prompt: '香蕉', }, ], visualPackage: null, themeTags: ['寓教于乐', '宝贝识物'], publicationStatus: 'published', createdAt: '2026-05-11T10:00:00.000Z', updatedAt: '2026-05-11T12:00:00.000Z', publishedAt: '2026-05-11T12:00:00.000Z', }); expect(isEdutainmentGalleryEntry(card)).toBe(true); expect(card.publicWorkCode).toBe('BO-12345678'); expect(card.coverImageSrc).toBe('/apple.png'); expect(card.themeTags[0]).toBe('寓教于乐'); });