/** @jest-environment node */ import { desktopAgentRules } from '../desktop-client/agent-rules' import { createHash } from 'node:crypto' import { emptyBrief, validateBrief } from '../desktop-client/creation.mjs' describe('desktop Agent versioned rule catalog', () => { test('lists only real ready combinations and returns an exact scoped package', () => { const index = desktopAgentRules(null) as any expect(index.items).toHaveLength(2) expect(index.items[0].label).toBe('顾家 · 电脑桌') const selected = desktopAgentRules(index.items[0].id) as any expect(selected.catalog.brands).toHaveLength(1) expect(selected.catalog.shops[0].id).toBe(index.items[0].shopId) expect(selected.catalog.categories[0].id).toBe(index.items[0].categoryId) expect(selected.catalog.bindings).toHaveLength(1) const canonical = JSON.stringify(selected.catalog, (_, item) => item && typeof item === 'object' && !Array.isArray(item) ? Object.fromEntries(Object.keys(item).sort().map(key => [key,item[key]])) : item) expect(selected.contentHash).toBe(createHash('sha256').update(canonical).digest('hex')) expect(index.items[0].contentHash).toBe(selected.contentHash) expect(index.items[0].projectBrandId).toBe(index.items[0].shopId) expect(index.categories.some((c: any) => c.name === '化妆台')).toBe(true) expect(index.items.some((c: any) => c.categoryName === '化妆台')).toBe(false) expect(() => desktopAgentRules('unknown')).toThrow('尚未配置') expect(() => desktopAgentRules('../other')).toThrow('编号无效') }) test('Yijiada rules use their own official brand and cannot inherit Gujia branding', () => { const index = desktopAgentRules(null) as any const gujia = index.items.find((item: any) => item.id === 'GJ-DESK-DNZ0385') const yijiada = index.items.find((item: any) => item.id === 'YJD-DESK-DNZ0385-NATIVE') expect(yijiada.label).toBe('亿家达 · 电脑桌') expect(yijiada.projectBrandId).toBe('2c6d91fd-5a7f-4e95-adcc-7f4437c6772b') expect(yijiada.projectBrandId).not.toBe(gujia.projectBrandId) const selected = desktopAgentRules(yijiada.id) as any expect(selected.catalog.brands).toHaveLength(1) expect(selected.catalog.brands[0]).toMatchObject({ id: yijiada.brandId, name: '亿家达' }) expect(selected.catalog.shops).toHaveLength(1) expect(selected.catalog.shops[0]).toMatchObject({ id: yijiada.projectBrandId, name: '亿家达' }) expect(selected.catalog.bindings).toHaveLength(1) expect(selected.catalog.bindings[0].id).toBe(yijiada.id) expect(JSON.stringify(selected.catalog)).not.toContain(gujia.brandId) expect(JSON.stringify(selected.catalog)).not.toContain(gujia.projectBrandId) expect(selected.contentHash).toBe(yijiada.contentHash) expect(selected.contentHash).not.toBe(gujia.contentHash) }) test('old briefs keep an empty category, while an explicit category survives cloud validation', () => { const old = emptyBrief() as any delete old.categoryId; delete old.categoryName expect(validateBrief(old)).toMatchObject({ categoryId: '', categoryName: '' }) expect(validateBrief({ ...old, categoryId: 'real-category', categoryName: '电脑桌' })).toMatchObject({ categoryId: 'real-category', categoryName: '电脑桌' }) expect(() => validateBrief({ ...old, categoryId: false })).toThrow('品类格式无效') }) })