@@ -1,137 +1,67 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { toGuideStopInfo } from '@/data/adapters/guideStopInfoAdapter'
|
||||
import { toGuideStopDetail } from '@/data/adapters/guideStopInfoAdapter'
|
||||
|
||||
describe('guide stop-info adapter', () => {
|
||||
it('normalizes aggregated language variants and exposes only displayable languages', () => {
|
||||
const result = toGuideStopInfo({
|
||||
available: true,
|
||||
targetType: 'STOP',
|
||||
targetId: '9001',
|
||||
lang: 'zh-CN',
|
||||
const languages = ['zh-CN', 'en-US', 'yue-HK'] as const
|
||||
|
||||
describe('unified guide stop detail adapter', () => {
|
||||
it('preserves snowflake IDs, synthesizes stable track codes, and ignores images marked missing', () => {
|
||||
const textVariants = languages.map((languageCode) => ({
|
||||
version: 'standard',
|
||||
languageCode,
|
||||
text: `standard-${languageCode}`
|
||||
}))
|
||||
const audioTracks = languages.flatMap((languageCode) => (
|
||||
languageCode === 'yue-HK'
|
||||
? [{ version: 'standard', languageCode, gender: 'female', playUrl: `/standard-${languageCode}-female.mp3` }]
|
||||
: ['female', 'male'].map((gender) => ({ version: 'standard', languageCode, gender, playUrl: `/standard-${languageCode}-${gender}.mp3` }))
|
||||
))
|
||||
const detail = toGuideStopDetail({
|
||||
id: '865546647764037632',
|
||||
version: 'standard',
|
||||
outlineId: '7467940240901013505',
|
||||
linkedExhibits: [{ id: '865546647764037633', name: '关联展品' }],
|
||||
name: '青铜神树',
|
||||
coverImageUrl: '/should-not-be-used.webp',
|
||||
galleryUrls: '["/should-not-be-used-gallery.webp"]',
|
||||
imageStatus: 'MISSING',
|
||||
recommendedTrackCode: 'standard.zh-CN.female',
|
||||
textVariants,
|
||||
audioTracks,
|
||||
textVariantCount: 3,
|
||||
audioTrackCount: 5
|
||||
})
|
||||
|
||||
expect(detail.id).toBe('865546647764037632')
|
||||
expect(detail.version).toBe('standard')
|
||||
expect(detail.outlineId).toBe('7467940240901013505')
|
||||
expect(detail.linkedExhibits[0]?.id).toBe('865546647764037633')
|
||||
expect(detail.coverImageUrl).toBeUndefined()
|
||||
expect(detail.galleryUrls).toEqual([])
|
||||
expect(detail.textVariants).toHaveLength(3)
|
||||
expect(detail.audioTracks).toHaveLength(5)
|
||||
expect(detail.recommendedTrackCode).toBe('standard.zh-CN.female')
|
||||
expect(detail.audioTracks.find((track) => track.channelCode === 'standard.zh-CN.female')?.playUrl)
|
||||
.toBe('/standard-zh-CN-female.mp3')
|
||||
})
|
||||
|
||||
it('drops unusable tracks while retaining a Chinese text variant for Cantonese fallback', () => {
|
||||
const detail = toGuideStopDetail({
|
||||
id: 'stop-1',
|
||||
version: 'extended',
|
||||
name: '测试',
|
||||
imageStatus: 'READY',
|
||||
coverImageUrl: '/museum-assets/cover.webp',
|
||||
languageVariants: [
|
||||
{
|
||||
lang: 'zh',
|
||||
enabled: true,
|
||||
playable: true,
|
||||
audioStatus: 'READY',
|
||||
playUrl: '/museum-assets/audio/zh.mp3',
|
||||
duration: '50',
|
||||
audioId: 12,
|
||||
hasText: true,
|
||||
textAvailable: true,
|
||||
text: '普通话讲解词',
|
||||
textLength: '6',
|
||||
textHash: 'zh-hash'
|
||||
},
|
||||
{
|
||||
lang: 'yue-HK',
|
||||
enabled: true,
|
||||
playable: false,
|
||||
audioStatus: 'MISSING',
|
||||
textAvailable: true,
|
||||
text: '粤语使用普通话文案',
|
||||
reason: 'NO_PUBLISHED_AUDIO'
|
||||
},
|
||||
{
|
||||
lang: 'en-US',
|
||||
enabled: false,
|
||||
playable: true,
|
||||
playUrl: '/museum-assets/audio/en.mp3'
|
||||
}
|
||||
textVariants: [{ version: 'extended', languageCode: 'zh-CN', text: '普通话正文' }],
|
||||
audioTracks: [
|
||||
{ version: 'extended', languageCode: 'yue-HK', gender: 'female', playUrl: '/cantonese.mp3' },
|
||||
{ version: 'extended', languageCode: 'zh-CN', gender: 'female' }
|
||||
]
|
||||
}, {
|
||||
targetType: 'STOP',
|
||||
targetId: '9001',
|
||||
lang: 'zh-CN'
|
||||
})
|
||||
|
||||
expect(result.supportedLanguages).toEqual(['zh-CN', 'yue-HK'])
|
||||
expect(result.languageVariants['zh-CN']).toMatchObject({
|
||||
playable: true,
|
||||
playUrl: '/museum-assets/audio/zh.mp3',
|
||||
duration: 50,
|
||||
audioId: '12',
|
||||
text: '普通话讲解词',
|
||||
textLength: 6
|
||||
})
|
||||
expect(result.languageVariants['yue-HK']).toMatchObject({
|
||||
playable: false,
|
||||
textAvailable: true,
|
||||
reason: 'NO_PUBLISHED_AUDIO'
|
||||
})
|
||||
})
|
||||
|
||||
it('keeps supportedLanguages as the compatibility fallback when variants are absent', () => {
|
||||
const result = toGuideStopInfo({
|
||||
supportedLanguages: ['zh-CN', 'en-US']
|
||||
}, {
|
||||
targetType: 'STOP',
|
||||
targetId: '9001',
|
||||
lang: 'zh-CN'
|
||||
})
|
||||
|
||||
expect(result.supportedLanguages).toEqual(['zh-CN', 'en-US'])
|
||||
expect(result.languageVariants).toEqual({})
|
||||
})
|
||||
|
||||
it('uses playable audio options as the primary language and voice contract', () => {
|
||||
const result = toGuideStopInfo({
|
||||
supportedLanguages: ['zh-CN', 'yue-HK'],
|
||||
audioOptions: [
|
||||
{
|
||||
channelCode: 'standard.zh-CN.male',
|
||||
displayName: '普通话男声',
|
||||
languageCode: 'zh-CN',
|
||||
gender: 'male',
|
||||
playUrl: '/museum-assets/audio/zh-male.mp3',
|
||||
duration: '51',
|
||||
isDefault: false,
|
||||
sortOrder: 11
|
||||
},
|
||||
{
|
||||
channelCode: 'standard.en-US.female',
|
||||
displayName: '英文女声',
|
||||
languageCode: 'en-US',
|
||||
gender: 'female',
|
||||
playUrl: '/museum-assets/audio/en-female.mp3',
|
||||
duration: 49,
|
||||
isDefault: true,
|
||||
sortOrder: 20
|
||||
},
|
||||
{
|
||||
channelCode: 'standard.zh-CN.female',
|
||||
displayName: '普通话女声',
|
||||
languageCode: 'zh-CN',
|
||||
gender: 'female',
|
||||
playUrl: '/museum-assets/audio/zh-female.mp3',
|
||||
isDefault: true,
|
||||
sortOrder: 10
|
||||
},
|
||||
{
|
||||
channelCode: 'invalid',
|
||||
languageCode: 'zh-CN',
|
||||
gender: 'female'
|
||||
}
|
||||
]
|
||||
}, {
|
||||
targetType: 'STOP',
|
||||
targetId: '9001',
|
||||
lang: 'zh-CN'
|
||||
})
|
||||
|
||||
expect(result.supportedLanguages).toEqual(['zh-CN', 'en-US'])
|
||||
expect(result.audioOptions.map((option) => option.channelCode)).toEqual([
|
||||
'standard.zh-CN.female',
|
||||
'standard.zh-CN.male',
|
||||
'standard.en-US.female'
|
||||
])
|
||||
expect(result.audioOptions[0]).toMatchObject({
|
||||
displayName: '普通话女声',
|
||||
gender: 'female',
|
||||
playUrl: '/museum-assets/audio/zh-female.mp3',
|
||||
isDefault: true
|
||||
})
|
||||
expect(detail.version).toBe('extended')
|
||||
expect(detail.textVariants[0]?.text).toBe('普通话正文')
|
||||
expect(detail.audioTracks).toEqual([expect.objectContaining({
|
||||
channelCode: 'extended.yue-HK.female',
|
||||
gender: 'female'
|
||||
})])
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user