b920c894b9
CI / verify (pull_request) Has been cancelled
Allow deleting open cities after listing partners/stores; company name, address, and districts optional on partner create. Co-authored-by: Cursor <cursoragent@cursor.com>
113 lines
3.4 KiB
TypeScript
113 lines
3.4 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import {
|
|
resolveOrderCityPartner,
|
|
validatePartnerCityBinding,
|
|
validatePartnerCommissionRates,
|
|
} from './city-partner';
|
|
|
|
describe('resolveOrderCityPartner', () => {
|
|
const bindings = [
|
|
{
|
|
id: '1',
|
|
partnerAccountId: '10',
|
|
scopeType: 'CITY_WIDE' as const,
|
|
districtCodes: null,
|
|
orderCommissionRate: 0,
|
|
redeemCommissionRate: 0.03,
|
|
bindingStatus: 'ACTIVE' as const,
|
|
},
|
|
{
|
|
id: '2',
|
|
partnerAccountId: '20',
|
|
scopeType: 'DISTRICT' as const,
|
|
districtCodes: ['410105', '金水区'],
|
|
orderCommissionRate: 0.01,
|
|
redeemCommissionRate: 0.03,
|
|
bindingStatus: 'ACTIVE' as const,
|
|
},
|
|
];
|
|
|
|
it('prefers district partner when district matches adcode', () => {
|
|
const ref = resolveOrderCityPartner(bindings, '410105');
|
|
expect(ref?.partnerAccountId).toBe('20');
|
|
expect(ref?.scopeType).toBe('DISTRICT');
|
|
});
|
|
|
|
it('falls back to city-wide partner', () => {
|
|
const ref = resolveOrderCityPartner(bindings, '410102');
|
|
expect(ref?.partnerAccountId).toBe('10');
|
|
expect(ref?.scopeType).toBe('CITY_WIDE');
|
|
});
|
|
|
|
it('returns null when no bindings', () => {
|
|
expect(resolveOrderCityPartner([], '410105')).toBeNull();
|
|
});
|
|
});
|
|
|
|
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);
|
|
});
|
|
});
|