import test from 'node:test' import assert from 'node:assert/strict' import { readSource } from './helpers.ts' import { isCategoryPlaceholderNode, toProductCategoryNode, makeCategoryPlaceholderNode, makeCategoryLoadMoreNode } from '../src/pages/asin/product-category-model.ts' // 验收反馈:类目树太紧凑、没有折叠展开、父子级效果对齐旧版(旧版为缩进树形表格带 +/- 展开)。 // 不变式:childCount>0 的未加载节点带占位子级(children 非空),el-tree 因此显示展开箭头; // 节点间距加大(:indent 28 + node-row padding),父子级视觉与旧版缩进树一致。 test('align_category_tree_normal_primary_path', () => { // 有子级但未返回 children 数据时,解析为带占位子级的节点(el-tree 显示展开箭头)。 const node = toProductCategoryNode({ id: 5, name: '父类目', child_count: 3, path: '父类目' }) assert.ok(node && node.children.length > 0, 'childCount>0 节点需带占位子级以显示展开箭头') assert.ok(node && node.children.every((child) => isCategoryPlaceholderNode(child)), '占位子级可识别') }) test('align_category_tree_normal_variant_input', () => { // 占位节点 id 与真实节点不冲突(负数域),且不可被误认为真实类目。 const placeholder = makeCategoryPlaceholderNode(5) assert.ok(placeholder.id < 0, '占位节点 id 用负数域避免与真实 id 冲突') assert.ok(isCategoryPlaceholderNode(placeholder)) assert.equal(isCategoryPlaceholderNode({ id: 1, parentId: null, name: '真实', categoryKey: '', sortOrder: 0, description: '', isBuiltin: false, childCount: 0, level: 0, path: '', children: [] }), false) }) test('align_category_tree_boundary_empty_input', () => { // 无子级节点保持叶子形态(children 空)。 const leaf = toProductCategoryNode({ id: 9, name: '叶子', child_count: 0, path: '叶子' }) assert.ok(leaf && leaf.children.length === 0, '叶子节点无占位子级') }) test('align_category_tree_boundary_single_item', () => { const page = readSource('src/pages/asin/ProductCategoryPage.vue') assert.match(page, /:indent="28"/, '树缩进加大(28px/级)') assert.match(page, /isCategoryPlaceholderNode/, '模板渲染占位节点分支') // 展开加载需识别"只有占位子级"的节点(children 全占位也触发懒加载)。 assert.match(page, /some\(.*isCategoryPlaceholderNode/, '展开判断兼容占位子级') }) test('align_category_tree_dependency_failure_returns_actionable_message', () => { // 视觉:节点行加 padding 不再紧凑;箭头样式放大加色。 const page = readSource('src/pages/asin/ProductCategoryPage.vue') assert.match(page, /\.node-row\s*\{[^}]*padding/, '节点行有 padding') assert.match(page, /el-tree-node__expand-icon|expand-icon/, '展开图标样式定制') }) test('align_category_tree_synthetic_ids_are_unique', () => { // 修复回归:合成节点 id 唯一——根级 loadMore 与父级1的 loadMore 不得同 key(曾因 -1 撞 key 致子级挂错父级)。 const ids = new Set() const samples = [ makeCategoryLoadMoreNode(null, 1, 2).id, makeCategoryLoadMoreNode(1, 1, 2).id, makeCategoryLoadMoreNode(2, 1, 2).id, makeCategoryPlaceholderNode(null).id, makeCategoryPlaceholderNode(1).id, makeCategoryPlaceholderNode(2).id, ] for (const id of samples) ids.add(id) assert.equal(ids.size, samples.length, '合成节点 id 两两唯一') assert.ok(makeCategoryLoadMoreNode(null, 1, 2).id !== -1, '根级 loadMore 不得使用 -1(与父级1的旧式 -parentId 撞 key)') })