import { dictItemSnapshotSchema } from '@lingxi/shared'; import { describe, expect, it } from 'vitest'; import { mapDictGroup, mapDictKind, mapDictStatus, toDictItem, toDictSnapshot, toDictTypeSummary, } from './dict.mapper'; describe('dict.mapper · Prisma 行 -> 共享 DTO', () => { it('类型统计与枚举转换:group / kind / status 映射为契约小写值', () => { const summary = toDictTypeSummary( { code: 'script_direction', name: '脚本方向', groupKey: 'content', kind: 'LIST', description: '脚本与素材的结构化方向', industryScoped: true, builtin: true, status: 'ACTIVE', sortOrder: 60, updatedAt: new Date('2026-11-04T02:00:00.000Z'), updatedBy: '江岚', }, { itemCount: 11, activeItemCount: 10, industryCount: 2 }, ); expect(summary).toEqual({ code: 'script_direction', name: '脚本方向', group: 'content', kind: 'list', description: '脚本与素材的结构化方向', industryScoped: true, builtin: true, status: 'active', sortOrder: 60, itemCount: 11, activeItemCount: 10, industryCount: 2, updatedAt: '2026-11-04T02:00:00.000Z', updatedBy: '江岚', }); }); it('库内异常分组回退 content;kind / status 只映射两个分支', () => { expect(mapDictGroup('unknown_group')).toBe('content'); expect(mapDictGroup('quality')).toBe('quality'); expect(mapDictKind('TREE')).toBe('tree'); expect(mapDictKind('LIST')).toBe('list'); expect(mapDictStatus('ACTIVE')).toBe('active'); expect(mapDictStatus('DISABLED')).toBe('disabled'); }); it('条目映射:source / overridden / parentName / industryPath / refCount=0', () => { const item = toDictItem( { id: '01HZZZZZZZZZZZZZZZZZZZZZZZ', code: 'seeding', name: '种草短视频', parentCode: null, industryId: 'ec', sortOrder: 40, status: 'ACTIVE', remark: '父行业覆盖通用层', updatedAt: new Date('2026-11-04T02:00:00.000Z'), updatedBy: '江岚', }, { typeCode: 'script_direction', source: 'parent', overridden: true, parentName: null, industryPath: '电商', }, ); expect(item).toMatchObject({ typeCode: 'script_direction', code: 'seeding', name: '种草短视频', parentName: null, industryId: 'ec', industryPath: '电商', status: 'active', source: 'parent', overridden: true, refCount: 0, updatedAt: '2026-11-04T02:00:00.000Z', updatedBy: '江岚', }); }); it('快照 R-10:先取快照再改字典名称,快照保留填写时名称', () => { const item = toDictItem( { id: '01HZZZZZZZZZZZZZZZZZZZZZZZ', code: 'oral', name: '口播', parentCode: null, industryId: null, sortOrder: 10, status: 'ACTIVE', remark: '', updatedAt: new Date('2026-11-04T02:00:00.000Z'), updatedBy: '江岚', }, { typeCode: 'script_direction', source: 'generic', overridden: false, parentName: null, industryPath: null, }, ); const snapshot = toDictSnapshot(item, '2026-11-04T10:00:00.000Z'); // 模拟字典改名 / 停用(历史引用方不感知) const renamed = { ...item, name: '口播(改名后)', status: 'disabled' as const }; expect(renamed.name).not.toBe(snapshot.name); expect(snapshot.name).toBe('口播'); expect(snapshot).toEqual({ typeCode: 'script_direction', code: 'oral', name: '口播', parentCode: null, industryId: null, capturedAt: '2026-11-04T10:00:00.000Z', }); expect(dictItemSnapshotSchema.parse(snapshot)).toEqual(snapshot); }); });