fix: resolve confirmed character hidden bug, remove online font dependency, improve UI/UX experience
This commit is contained in:
80
tests/unit/components/asset-toolbar.test.ts
Normal file
80
tests/unit/components/asset-toolbar.test.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import * as React from 'react'
|
||||
import { createElement } from 'react'
|
||||
import type { ComponentProps, ReactElement } from 'react'
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import { renderToStaticMarkup } from 'react-dom/server'
|
||||
import { NextIntlClientProvider } from 'next-intl'
|
||||
import type { AbstractIntlMessages } from 'next-intl'
|
||||
import AssetToolbar from '@/app/[locale]/workspace/[projectId]/modes/novel-promotion/components/assets/AssetToolbar'
|
||||
|
||||
vi.mock('@/lib/query/hooks', () => ({
|
||||
useProjectAssets: vi.fn(() => ({ data: { characters: [], locations: [], props: [] } })),
|
||||
useProjectData: vi.fn(() => ({ data: { name: '项目A' } })),
|
||||
}))
|
||||
|
||||
const messages = {
|
||||
assets: {
|
||||
common: {
|
||||
refresh: '刷新',
|
||||
},
|
||||
filterBar: {
|
||||
allEpisodes: '全部集数',
|
||||
},
|
||||
toolbar: {
|
||||
assetManagement: '资产管理',
|
||||
assetCount: '共 {total} 个资产({appearances} 角色形象 + {locations} 场景 + {props} 道具)',
|
||||
globalAnalyze: '全局分析',
|
||||
globalAnalyzeHint: '分析所有资产',
|
||||
downloadAll: '下载全部',
|
||||
generateAll: '生成全部图片',
|
||||
regenerateAll: '重新生成全部',
|
||||
regenerateAllHint: '重新生成所有图片',
|
||||
},
|
||||
assetLibrary: {
|
||||
downloadEmpty: '没有可下载图片',
|
||||
downloadFailed: '下载失败',
|
||||
},
|
||||
},
|
||||
} as const
|
||||
|
||||
const 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),
|
||||
)
|
||||
}
|
||||
|
||||
describe('AssetToolbar', () => {
|
||||
it('删除批量生成与刷新按钮 -> 仅保留全局分析和下载入口', () => {
|
||||
Reflect.set(globalThis, 'React', React)
|
||||
|
||||
const html = renderWithIntl(
|
||||
createElement(AssetToolbar, {
|
||||
projectId: 'project-1',
|
||||
totalAssets: 24,
|
||||
totalAppearances: 11,
|
||||
totalLocations: 13,
|
||||
totalProps: 0,
|
||||
isBatchSubmitting: false,
|
||||
isAnalyzingAssets: false,
|
||||
isGlobalAnalyzing: false,
|
||||
onGlobalAnalyze: () => undefined,
|
||||
episodeId: null,
|
||||
onEpisodeChange: () => undefined,
|
||||
episodes: [],
|
||||
}),
|
||||
)
|
||||
|
||||
expect(html).toContain('全局分析')
|
||||
expect(html).toContain('title="下载全部"')
|
||||
expect(html).not.toContain('生成全部图片')
|
||||
expect(html).not.toContain('重新生成全部')
|
||||
expect(html).not.toContain('>刷新<')
|
||||
})
|
||||
})
|
||||
@@ -24,6 +24,9 @@ const messages = {
|
||||
waitingModelOutput: '等待模型输出...',
|
||||
reasoningNotProvided: '该步骤未返回思考过程',
|
||||
},
|
||||
streamStep: {
|
||||
analyzeProps: '道具分析',
|
||||
},
|
||||
runtime: {
|
||||
llm: {
|
||||
processing: '模型处理中...',
|
||||
@@ -69,4 +72,27 @@ describe('LLMStageStreamCard error rendering', () => {
|
||||
expect(html).not.toContain('Copy error detail')
|
||||
expect(html).not.toContain('Open feedback form')
|
||||
})
|
||||
|
||||
it('resolves analyze props progress keys without missing message errors', () => {
|
||||
Reflect.set(globalThis, 'React', React)
|
||||
const html = renderWithIntl(
|
||||
createElement(LLMStageStreamCard, {
|
||||
title: 'progress.streamStep.analyzeProps',
|
||||
stages: [{
|
||||
id: 'analyze_props',
|
||||
title: 'progress.streamStep.analyzeProps',
|
||||
subtitle: 'progress.streamStep.analyzeProps',
|
||||
status: 'processing',
|
||||
progress: 35,
|
||||
}],
|
||||
activeStageId: 'analyze_props',
|
||||
activeMessage: 'progress.streamStep.analyzeProps',
|
||||
outputText: '',
|
||||
}),
|
||||
)
|
||||
|
||||
expect(html).toContain('道具分析')
|
||||
expect(html).not.toContain('progress.streamStep.analyzeProps')
|
||||
expect(html).not.toContain('MISSING_MESSAGE')
|
||||
})
|
||||
})
|
||||
|
||||
29
tests/unit/components/segmented-control.test.ts
Normal file
29
tests/unit/components/segmented-control.test.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import * as React from 'react'
|
||||
import { createElement } from 'react'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { renderToStaticMarkup } from 'react-dom/server'
|
||||
import { SegmentedControl } from '@/components/ui/SegmentedControl'
|
||||
|
||||
describe('SegmentedControl', () => {
|
||||
it('compact 布局 -> 输出左对齐的非拉伸结构', () => {
|
||||
Reflect.set(globalThis, 'React', React)
|
||||
|
||||
const html = renderToStaticMarkup(
|
||||
createElement(SegmentedControl, {
|
||||
options: [
|
||||
{ value: 'all', label: '全部 (24)' },
|
||||
{ value: 'character', label: '角色 (11)' },
|
||||
{ value: 'location', label: '场景 (13)' },
|
||||
{ value: 'prop', label: '道具 (0)' },
|
||||
],
|
||||
value: 'all',
|
||||
onChange: () => undefined,
|
||||
layout: 'compact',
|
||||
}),
|
||||
)
|
||||
|
||||
expect(html).toContain('inline-block max-w-full')
|
||||
expect(html).toContain('inline-grid grid-flow-col auto-cols-[minmax(96px,max-content)]')
|
||||
expect(html).not.toContain('grid-template-columns:repeat(4,minmax(0,1fr))')
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user