137 lines
4.3 KiB
TypeScript
137 lines
4.3 KiB
TypeScript
import * as React from 'react'
|
|
import { createElement } from 'react'
|
|
import type { ComponentProps, ReactElement } from 'react'
|
|
import { describe, expect, it } from 'vitest'
|
|
import { renderToStaticMarkup } from 'react-dom/server'
|
|
import { NextIntlClientProvider } from 'next-intl'
|
|
import type { AbstractIntlMessages } from 'next-intl'
|
|
import ScriptViewAssetsPanel from '@/app/[locale]/workspace/[projectId]/modes/novel-promotion/components/script-view/ScriptViewAssetsPanel'
|
|
|
|
const messages = {
|
|
scriptView: {
|
|
inSceneAssets: '出场资产',
|
|
assetView: {
|
|
allClips: '全部片段',
|
|
},
|
|
segment: {
|
|
title: '片段 {index}',
|
|
},
|
|
asset: {
|
|
activeCharacters: '出场角色',
|
|
activeLocations: '出场场景',
|
|
defaultAppearance: '默认形象',
|
|
},
|
|
screenplay: {
|
|
noCharacter: '当前片段未选择角色',
|
|
noLocation: '当前片段未选择场景',
|
|
},
|
|
generate: {
|
|
startGenerate: '开始生成',
|
|
},
|
|
},
|
|
assets: {
|
|
character: {
|
|
primary: '初始形象',
|
|
},
|
|
},
|
|
novelPromotion: {
|
|
buttons: {
|
|
assetLibrary: '资产库',
|
|
},
|
|
},
|
|
common: {
|
|
edit: '编辑',
|
|
cancel: '取消',
|
|
confirm: '确定',
|
|
},
|
|
} as const
|
|
|
|
function renderWithIntl(node: ReactElement) {
|
|
const providerProps: ComponentProps<typeof NextIntlClientProvider> = {
|
|
locale: 'zh',
|
|
messages: messages as unknown as AbstractIntlMessages,
|
|
timeZone: 'Asia/Shanghai',
|
|
children: node,
|
|
}
|
|
|
|
return renderToStaticMarkup(
|
|
createElement(NextIntlClientProvider, providerProps),
|
|
)
|
|
}
|
|
|
|
function renderPanel(propsCount: number) {
|
|
Reflect.set(globalThis, 'React', React)
|
|
|
|
const props = Array.from({ length: propsCount }, (_, index) => ({
|
|
id: `prop-${index + 1}`,
|
|
name: `道具${index + 1}`,
|
|
summary: `道具描述${index + 1}`,
|
|
selectedImageId: null,
|
|
images: [],
|
|
}))
|
|
|
|
return renderWithIntl(
|
|
createElement(ScriptViewAssetsPanel, {
|
|
clips: [{ id: 'clip-1', location: null, props: null }],
|
|
assetViewMode: 'all',
|
|
setAssetViewMode: () => undefined,
|
|
setSelectedClipId: () => undefined,
|
|
characters: [],
|
|
locations: [],
|
|
props,
|
|
activeCharIds: [],
|
|
activeLocationIds: [],
|
|
activePropIds: [],
|
|
selectedAppearanceKeys: new Set<string>(),
|
|
onUpdateClipAssets: async () => undefined,
|
|
onOpenAssetLibrary: () => undefined,
|
|
assetsLoading: false,
|
|
assetsLoadingState: null,
|
|
allAssetsHaveImages: true,
|
|
globalCharIds: [],
|
|
globalLocationIds: [],
|
|
globalPropIds: [],
|
|
missingAssetsCount: 0,
|
|
onGenerateStoryboard: () => undefined,
|
|
isSubmittingStoryboardBuild: false,
|
|
getSelectedAppearances: () => [],
|
|
tScript: (key: string, values?: Record<string, unknown>) => {
|
|
if (key === 'inSceneAssets') return '出场资产'
|
|
if (key === 'assetView.allClips') return '全部片段'
|
|
if (key === 'segment.title') return `片段 ${String(values?.index ?? '')}`
|
|
if (key === 'asset.activeCharacters') return '出场角色'
|
|
if (key === 'asset.activeLocations') return '出场场景'
|
|
if (key === 'screenplay.noCharacter') return '当前片段未选择角色'
|
|
if (key === 'screenplay.noLocation') return '当前片段未选择场景'
|
|
if (key === 'generate.startGenerate') return '开始生成'
|
|
if (key === 'asset.defaultAppearance') return '默认形象'
|
|
return key
|
|
},
|
|
tAssets: (key: string) => (key === 'character.primary' ? '初始形象' : key),
|
|
tNP: (key: string) => (key === 'buttons.assetLibrary' ? '资产库' : key),
|
|
tCommon: (key: string) => {
|
|
if (key === 'edit') return '编辑'
|
|
if (key === 'cancel') return '取消'
|
|
if (key === 'confirm') return '确定'
|
|
return key
|
|
},
|
|
}),
|
|
)
|
|
}
|
|
|
|
describe('ScriptViewAssetsPanel', () => {
|
|
it('hides the prop section when the project has no prop assets', () => {
|
|
const html = renderPanel(0)
|
|
|
|
expect(html).not.toContain('道具 (0)')
|
|
expect(html).not.toContain('当前片段未选择道具')
|
|
})
|
|
|
|
it('keeps the prop section visible when the project has prop assets even if none are selected in the current clip', () => {
|
|
const html = renderPanel(1)
|
|
|
|
expect(html).toContain('道具 (0)')
|
|
expect(html).toContain('当前片段未选择道具')
|
|
})
|
|
})
|