import { describe, expect, it } from 'vitest'; import { applyCustomerFieldInputSchema, approveCustomerFieldInputSchema, createCustomerGroupInputSchema, createCustomerInputSchema, createIndustryInputSchema, customerFieldCodeSchema, customerFieldListQuerySchema, customerGroupListQuerySchema, customerListQuerySchema, customerNameSchema, customerShortNameSchema, industryListQuerySchema, setCustomerGroupsInputSchema, setCustomerStatusInputSchema, setIndustryStatusInputSchema, transferCustomerInputSchema, updateCustomerGroupInputSchema, updateCustomerGroupMembersInputSchema, updateCustomerInputSchema, updateIndustryInputSchema, } from './client.js'; const ULID = '01HZZZZZZZZZZZZZZZZZZZZZZ1'; const ULID2 = '01HZZZZZZZZZZZZZZZZZZZZZZ2'; describe('行业契约', () => { it('新建:一级 parentId 缺省、默认排序;二级必须带 parentId', () => { expect(createIndustryInputSchema.parse({ name: '电商' })).toEqual({ name: '电商', sortOrder: 10, remark: '', }); expect(createIndustryInputSchema.parse({ name: '服饰', parentId: ULID })).toMatchObject({ parentId: ULID, }); expect(createIndustryInputSchema.safeParse({ name: '电' }).success).toBe(false); expect(createIndustryInputSchema.safeParse({ name: '电商', unknown: 1 }).success).toBe(false); }); it('更新 / 状态 / 列表查询:层级与上级不可改,状态枚举与默认分页', () => { expect(updateIndustryInputSchema.safeParse({ parentId: ULID }).success).toBe(false); expect( updateIndustryInputSchema.parse({ name: '电商2', sortOrder: 20, remark: '说明' }), ).toEqual({ name: '电商2', sortOrder: 20, remark: '说明', }); expect(setIndustryStatusInputSchema.safeParse({ status: 'disabled' }).success).toBe(true); expect(setIndustryStatusInputSchema.safeParse({ status: 'deleted' }).success).toBe(false); expect(industryListQuerySchema.parse({})).toEqual({ limit: 20, status: 'all' }); }); }); describe('客户契约', () => { it('名称 / 简称:简称必填且限制字符', () => { expect(customerNameSchema.safeParse(' ').success).toBe(false); expect(customerShortNameSchema.safeParse('HJ').success).toBe(true); expect(customerShortNameSchema.safeParse('花间集').success).toBe(true); expect(customerShortNameSchema.safeParse('H').success).toBe(false); expect(customerShortNameSchema.safeParse('HJ!').success).toBe(false); }); it('新建:默认不写偏好与基础字段,未知字段拒绝', () => { const parsed = createCustomerInputSchema.parse({ industryId: ULID, name: '花间集', shortName: 'HJ', ownerUserId: ULID2, }); expect(parsed.preferences).toBeUndefined(); expect(parsed.baseFields).toBeUndefined(); expect( createCustomerInputSchema.safeParse({ industryId: ULID, name: '花间集', shortName: 'HJ', ownerUserId: ULID2, extra: true, }).success, ).toBe(false); }); it('新建:基础字段 ≤ 10,接受完整偏好', () => { const baseFields = Array.from({ length: 11 }, (_, index) => ({ key: `k${index}`, value: `v${index}`, })); expect( createCustomerInputSchema.safeParse({ industryId: ULID, name: '花间集', shortName: 'HJ', ownerUserId: ULID2, baseFields, }).success, ).toBe(false); const parsed = createCustomerInputSchema.parse({ industryId: ULID, name: '花间集', shortName: 'HJ', ownerUserId: ULID2, preferences: { naming: 'n', directory: 'd', specs: ['1080×1920'], taboo: ['绝对化用语'] }, baseFields: [{ key: '门店', value: '沪-001' }], }); expect(parsed.preferences?.specs).toHaveLength(1); }); it('更新不接受所属行业;状态 / 转交 / 组 / 列表查询口径', () => { expect(updateCustomerInputSchema.safeParse({ industryId: ULID }).success).toBe(false); expect(updateCustomerInputSchema.parse({ shortName: 'HJ2' })).toEqual({ shortName: 'HJ2' }); expect(setCustomerStatusInputSchema.safeParse({ status: 'paused' }).success).toBe(true); expect(setCustomerStatusInputSchema.safeParse({ status: 'deleted' }).success).toBe(false); expect(transferCustomerInputSchema.parse({ ownerUserId: ULID })).toEqual({ ownerUserId: ULID }); expect(setCustomerGroupsInputSchema.parse({ groupIds: [ULID] })).toEqual({ groupIds: [ULID] }); expect(customerListQuerySchema.parse({})).toEqual({ limit: 20, status: 'all' }); expect(customerListQuerySchema.parse({ status: 'ended', industry_id: ULID })).toMatchObject({ status: 'ended', industry_id: ULID, }); }); }); describe('客户组契约', () => { it('名称 / 说明 / 成员批量操作 / 列表查询', () => { expect(createCustomerGroupInputSchema.parse({ name: '电商核心组' })).toEqual({ name: '电商核心组', }); expect(createCustomerGroupInputSchema.safeParse({ name: '组' }).success).toBe(false); expect(updateCustomerGroupInputSchema.parse({ description: '说明' })).toEqual({ description: '说明', }); expect(updateCustomerGroupMembersInputSchema.parse({ addCustomerIds: [ULID] })).toEqual({ addCustomerIds: [ULID], removeCustomerIds: [], }); expect(customerGroupListQuerySchema.parse({})).toEqual({ limit: 20 }); }); }); describe('客户字段契约', () => { it('编码格式:小写字母开头,字母数字下划线', () => { expect(customerFieldCodeSchema.parse('campaign_code')).toBe('campaign_code'); expect(customerFieldCodeSchema.safeParse('Campaign').success).toBe(false); expect(customerFieldCodeSchema.safeParse('1abc').success).toBe(false); expect(customerFieldCodeSchema.safeParse('a').success).toBe(false); }); it('申请:单选必须有选项,进入生成默认 false', () => { const parsed = applyCustomerFieldInputSchema.parse({ name: '活动编码', code: 'campaign_code', type: 'text', purpose: '检索', }); expect(parsed.entersGeneration).toBe(false); expect(parsed.options).toEqual([]); expect( applyCustomerFieldInputSchema.safeParse({ name: '系列', code: 'series', type: 'select', purpose: '检索', }).success, ).toBe(false); expect( applyCustomerFieldInputSchema.parse({ name: '系列', code: 'series', type: 'select', options: ['秋冬'], purpose: '检索', entersGeneration: true, }).entersGeneration, ).toBe(true); }); it('审批:驳回必须带原因;列表状态枚举', () => { expect(approveCustomerFieldInputSchema.safeParse({ decision: 'reject' }).success).toBe(false); expect(approveCustomerFieldInputSchema.parse({ decision: 'reject', reason: '重复' })).toEqual({ decision: 'reject', reason: '重复', }); expect(approveCustomerFieldInputSchema.parse({ decision: 'approve' })).toEqual({ decision: 'approve', }); expect(customerFieldListQuerySchema.parse({})).toEqual({ limit: 20, status: 'all' }); }); });