first commit
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
import * as React from 'react'
|
||||
import { createElement } from 'react'
|
||||
import { renderToStaticMarkup } from 'react-dom/server'
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import { NextIntlClientProvider } from 'next-intl'
|
||||
import type { AbstractIntlMessages } from 'next-intl'
|
||||
|
||||
vi.mock('@/components/ui/icons', () => ({
|
||||
AppIcon: (props: { className?: string }) => createElement('span', { className: props.className }),
|
||||
}))
|
||||
|
||||
vi.mock('@/components/task/TaskStatusInline', () => ({
|
||||
default: () => createElement('span', null, 'loading'),
|
||||
}))
|
||||
|
||||
vi.mock('@/lib/task/presentation', () => ({
|
||||
resolveTaskPresentationState: () => null,
|
||||
}))
|
||||
|
||||
vi.mock('@/lib/query/hooks', () => ({
|
||||
useUpdateCharacterName: () => ({ isPending: false, mutateAsync: vi.fn() }),
|
||||
useUpdateProjectCharacterName: () => ({ isPending: false, mutateAsync: vi.fn() }),
|
||||
useUpdateCharacterAppearanceDescription: () => ({ mutateAsync: vi.fn() }),
|
||||
useUpdateProjectAppearanceDescription: () => ({ mutateAsync: vi.fn() }),
|
||||
useUpdateProjectCharacterIntroduction: () => ({ mutateAsync: vi.fn() }),
|
||||
useAiModifyCharacterDescription: () => ({ mutateAsync: vi.fn() }),
|
||||
useAiModifyProjectAppearanceDescription: () => ({ mutateAsync: vi.fn() }),
|
||||
useUpdateLocationName: () => ({ isPending: false, mutateAsync: vi.fn() }),
|
||||
useUpdateProjectLocationName: () => ({ isPending: false, mutateAsync: vi.fn() }),
|
||||
useUpdateLocationSummary: () => ({ mutateAsync: vi.fn() }),
|
||||
useUpdateProjectLocationDescription: () => ({ mutateAsync: vi.fn() }),
|
||||
useAiModifyLocationDescription: () => ({ mutateAsync: vi.fn() }),
|
||||
useAiModifyProjectLocationDescription: () => ({ mutateAsync: vi.fn() }),
|
||||
useAiModifyPropDescription: () => ({ mutateAsync: vi.fn() }),
|
||||
useAiModifyProjectPropDescription: () => ({ mutateAsync: vi.fn() }),
|
||||
useAssetActions: () => ({
|
||||
update: vi.fn(),
|
||||
updateVariant: vi.fn(),
|
||||
generate: vi.fn(),
|
||||
}),
|
||||
}))
|
||||
|
||||
const messages = {
|
||||
assets: {
|
||||
common: {
|
||||
cancel: '取消',
|
||||
},
|
||||
character: {
|
||||
name: '角色名',
|
||||
appearance: '形象',
|
||||
},
|
||||
location: {
|
||||
name: '场景名',
|
||||
description: '场景描述',
|
||||
},
|
||||
prop: {
|
||||
name: '道具名',
|
||||
summary: '简要说明',
|
||||
summaryPlaceholder: '一句话说明这是什么道具,不写剧情用途',
|
||||
description: '图片描述',
|
||||
descriptionPlaceholder: '只写道具本体的材质、颜色、结构和装饰细节',
|
||||
},
|
||||
modal: {
|
||||
editCharacter: '编辑角色',
|
||||
editLocation: '编辑场景',
|
||||
editProp: '编辑道具',
|
||||
namePlaceholder: '输入名称',
|
||||
appearancePrompt: '形象描述提示词',
|
||||
descPlaceholder: '输入描述',
|
||||
modifyDescription: 'AI修改描述',
|
||||
modifyPlaceholder: '改成夜晚',
|
||||
modifyPlaceholderCharacter: '改成黑色西装',
|
||||
modifyPlaceholderProp: '改成磨砂银质',
|
||||
saveName: '保存名字',
|
||||
saveOnly: '仅保存',
|
||||
saveAndGenerate: '保存并生成',
|
||||
introduction: '角色介绍',
|
||||
introductionPlaceholder: '输入角色介绍',
|
||||
introductionTip: '介绍角色在故事中的身份',
|
||||
},
|
||||
smartImport: {
|
||||
preview: {
|
||||
saving: '保存中',
|
||||
},
|
||||
},
|
||||
errors: {
|
||||
saveFailed: '保存失败',
|
||||
failed: '失败',
|
||||
},
|
||||
},
|
||||
} as const
|
||||
|
||||
const TestIntlProvider = NextIntlClientProvider as React.ComponentType<{
|
||||
locale: string
|
||||
messages: AbstractIntlMessages
|
||||
timeZone: string
|
||||
children?: React.ReactNode
|
||||
}>
|
||||
|
||||
function renderWithMessages(node: React.ReactElement) {
|
||||
return renderToStaticMarkup(
|
||||
createElement(
|
||||
TestIntlProvider,
|
||||
{
|
||||
locale: 'zh',
|
||||
messages: messages as unknown as AbstractIntlMessages,
|
||||
timeZone: 'Asia/Shanghai',
|
||||
},
|
||||
node,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
describe('asset edit modal AI layout', () => {
|
||||
it('renders character AI modify action inside the description composer instead of a standalone smart-modify card', async () => {
|
||||
Reflect.set(globalThis, 'React', React)
|
||||
const { CharacterEditModal } = await import('@/components/shared/assets/CharacterEditModal')
|
||||
const html = renderWithMessages(
|
||||
createElement(CharacterEditModal, {
|
||||
mode: 'project',
|
||||
characterId: 'character-1',
|
||||
characterName: '沈烬',
|
||||
description: '冷峻禁欲的男性角色形象描述',
|
||||
appearanceId: 'appearance-1',
|
||||
onClose: () => undefined,
|
||||
onSave: () => undefined,
|
||||
}),
|
||||
)
|
||||
|
||||
expect(html).toContain('AI修改描述')
|
||||
expect(html).not.toContain('改成黑色西装')
|
||||
expect(html).not.toContain('智能修改')
|
||||
})
|
||||
|
||||
it('renders prop AI modify action with the prop-specific placeholder', async () => {
|
||||
Reflect.set(globalThis, 'React', React)
|
||||
const { PropEditModal } = await import('@/components/shared/assets/PropEditModal')
|
||||
const html = renderWithMessages(
|
||||
createElement(PropEditModal, {
|
||||
mode: 'project',
|
||||
propId: 'prop-1',
|
||||
propName: '遗物匕首',
|
||||
summary: '旧时代留下的金属短刃',
|
||||
description: '青铜短刃,刃面斑驳,手柄有细密雕纹',
|
||||
variantId: 'prop-variant-1',
|
||||
projectId: 'project-1',
|
||||
onClose: () => undefined,
|
||||
}),
|
||||
)
|
||||
|
||||
expect(html).toContain('AI修改描述')
|
||||
expect(html).not.toContain('改成磨砂银质')
|
||||
expect(html).not.toContain('智能修改')
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user