fix(classification): avoid duplicate uncategorized label

This commit is contained in:
jxxghp
2026-09-06 10:47:57 +08:00
parent bb6cdb2ece
commit dc2dd8d3b0
3 changed files with 24 additions and 3 deletions
@@ -189,6 +189,18 @@ describe('ClassificationCategoryEditor', () => {
await waitFor(() => expect(events.updateFallbacks).toHaveBeenCalledWith({ : 'music.lossless' })) await waitFor(() => expect(events.updateFallbacks).toHaveBeenCalledWith({ : 'music.lossless' }))
}) })
it('默认分类选项不会重复显示路径中的分类名称', async () => {
const user = userEvent.setup()
await renderEditor({
categories: [createCategory('tv.uncategorized', '电视剧', '未分类', ['未分类', '通用'])],
})
await user.click(screen.getByRole('combobox', { name: '电视剧默认分类' }))
expect(await screen.findByRole('option', { name: '未分类 · 通用' })).toBeInTheDocument()
expect(screen.queryByRole('option', { name: '未分类 · 未分类 / 通用' })).not.toBeInTheDocument()
})
it('路径超过最大深度时保留草稿并拒绝发出分类更新', async () => { it('路径超过最大深度时保留草稿并拒绝发出分类更新', async () => {
const user = userEvent.setup() const user = userEvent.setup()
const { events } = await renderEditor({ maxDepth: 2 }) const { events } = await renderEditor({ maxDepth: 2 })
@@ -27,6 +27,16 @@ describe('formatClassificationCategoryOptionTitle', () => {
).toBe('华语电影 · 电影') ).toBe('华语电影 · 电影')
}) })
it('removes a repeated category name from any path segment', () => {
expect(
formatClassificationCategoryOptionTitle({
id: 'tv.uncategorized',
name: '未分类',
path: ['未分类', '通用'],
}),
).toBe('未分类 · 通用')
})
it('can preserve a caller-specific path separator and stable ID', () => { it('can preserve a caller-specific path separator and stable ID', () => {
expect( expect(
formatClassificationCategoryOptionTitle( formatClassificationCategoryOptionTitle(
+2 -3
View File
@@ -14,13 +14,12 @@ interface ClassificationCategoryOptionTitleOptions {
pathSeparator?: string pathSeparator?: string
} }
/** 生成分类选择器标题,避免分类名与路径末级名称重复显示。 */ /** 生成分类选择器标题,避免分类名与路径中的同名段重复显示。 */
export function formatClassificationCategoryOptionTitle( export function formatClassificationCategoryOptionTitle(
category: Pick<ClassificationCategory, 'name' | 'path' | 'id'>, category: Pick<ClassificationCategory, 'name' | 'path' | 'id'>,
options: ClassificationCategoryOptionTitleOptions = {}, options: ClassificationCategoryOptionTitleOptions = {},
): string { ): string {
const pathSegments = [...category.path] const pathSegments = category.path.filter(segment => segment !== category.name)
while (pathSegments[pathSegments.length - 1] === category.name) pathSegments.pop()
const path = pathSegments.join(options.pathSeparator ?? ' / ') const path = pathSegments.join(options.pathSeparator ?? ' / ')
const displayPath = path || (category.path.length ? '' : (options.emptyPathLabel ?? '')) const displayPath = path || (category.path.length ? '' : (options.emptyPathLabel ?? ''))
const parts = [category.name, displayPath] const parts = [category.name, displayPath]