import { describe, expect, it } from 'vitest'; import { assertCanDeleteCityPartner, assertCanDeleteStore, validatePartnerCityBinding, validatePartnerCommissionRates, } from './city-partner'; describe('validatePartnerCityBinding', () => { it('rejects duplicate partner', () => { const result = validatePartnerCityBinding( [{ id: '1', partnerAccountId: '10', scopeType: 'CITY_WIDE' }], { partnerAccountId: '10', scopeType: 'DISTRICT', districtCodes: ['410105'] }, ); expect(result.ok).toBe(false); }); it('rejects second city-wide partner', () => { const result = validatePartnerCityBinding( [{ id: '1', partnerAccountId: '10', scopeType: 'CITY_WIDE' }], { partnerAccountId: '11', scopeType: 'CITY_WIDE' }, ); expect(result.ok).toBe(false); }); it('allows overlapping district codes as labels', () => { const result = validatePartnerCityBinding( [ { id: '1', partnerAccountId: '10', scopeType: 'DISTRICT', districtCodes: ['410105'], companyName: '甲公司', }, ], { partnerAccountId: '11', scopeType: 'DISTRICT', districtCodes: ['410105'] }, ); expect(result.ok).toBe(true); }); it('allows district partner without district codes', () => { const result = validatePartnerCityBinding( [], { partnerAccountId: '11', scopeType: 'DISTRICT', districtCodes: [] }, ); expect(result.ok).toBe(true); }); it('allows valid district binding', () => { const result = validatePartnerCityBinding( [{ id: '1', partnerAccountId: '10', scopeType: 'DISTRICT', districtCodes: ['410105'] }], { partnerAccountId: '11', scopeType: 'DISTRICT', districtCodes: ['410106'] }, ); expect(result.ok).toBe(true); }); }); describe('validatePartnerCommissionRates', () => { it('allows sum within default 5% cap', () => { expect(validatePartnerCommissionRates(0.02, 0.03).ok).toBe(true); }); it('rejects sum above cap', () => { const result = validatePartnerCommissionRates(0.03, 0.03, 0.05); expect(result.ok).toBe(false); expect(result.message).toContain('5.00%'); }); it('respects custom city cap', () => { expect(validatePartnerCommissionRates(0.04, 0.04, 0.08).ok).toBe(true); expect(validatePartnerCommissionRates(0.05, 0.04, 0.08).ok).toBe(false); }); }); describe('assertCanDeleteCityPartner', () => { it('requires stores to be deleted first', () => { const result = assertCanDeleteCityPartner({ storeCount: 2, orderCount: 0, redeemCount: 0 }); expect(result.ok).toBe(false); expect(result.message).toContain('请先删除门店'); }); it('blocks when orders exist', () => { const result = assertCanDeleteCityPartner({ storeCount: 0, orderCount: 1, redeemCount: 0 }); expect(result.ok).toBe(false); expect(result.message).toContain('关联订单'); }); it('allows delete when empty', () => { expect(assertCanDeleteCityPartner({ storeCount: 0, orderCount: 0, redeemCount: 0 }).ok).toBe(true); }); }); describe('assertCanDeleteStore', () => { it('blocks when redeem records exist', () => { const result = assertCanDeleteStore({ orderCount: 0, redeemCount: 3 }); expect(result.ok).toBe(false); expect(result.message).toContain('关联核销单'); }); it('allows delete when no orders or redeems', () => { expect(assertCanDeleteStore({ orderCount: 0, redeemCount: 0 }).ok).toBe(true); }); });