feat: add application queue priority routing

This commit is contained in:
hectorzhao
2026-07-07 14:49:10 +08:00
parent 72f2c010ce
commit 4c8f7dd73f
17 changed files with 392 additions and 46 deletions
+39 -1
View File
@@ -8,6 +8,7 @@ function createPrismaMock() {
tenantId: 'tenant-1',
name: '应用A',
status: 'active',
queuePriority: 'normal',
tenant: { id: 'tenant-1', name: '租户A', code: 'TENANT-A' },
messageRecords: [{ status: 'delivered' }, { status: 'undelivered' }],
}]),
@@ -16,6 +17,7 @@ function createPrismaMock() {
tenantId: 'tenant-1',
name: '应用A',
status: 'active',
queuePriority: 'normal',
secretHash: 'secret-hash',
tenant: { id: 'tenant-1', name: '租户A', code: 'TENANT-A' },
}),
@@ -147,6 +149,7 @@ describe('SmsConfigService', () => {
expect.objectContaining({
id: 'app-1',
cmppStatus: 'connected',
queuePriority: 'normal',
sentToday: 2,
deliveryRate: 50,
cmppConnections: [expect.objectContaining({ connectionId: 'conn-a' })],
@@ -167,6 +170,40 @@ describe('SmsConfigService', () => {
}));
});
it('creates enterprise applications with persisted queue priority', async () => {
const prisma = createPrismaMock();
const service = new SmsConfigService(prisma as never);
await expect(service.createApplication({
tenantId: 'tenant-1',
name: '优先应用',
queuePriority: 'priority',
ipAllowlist: ['10.0.0.1/32'],
})).resolves.toEqual(expect.objectContaining({ id: 'app-new' }));
expect(prisma.smsApplication.create).toHaveBeenCalledWith(expect.objectContaining({
data: expect.objectContaining({
tenantId: 'tenant-1',
name: '优先应用',
queuePriority: 'priority',
ipAllowlist: { create: [{ ipCidr: '10.0.0.1/32' }] },
}),
}));
});
it('rejects invalid enterprise application queue priority', async () => {
const prisma = createPrismaMock();
const service = new SmsConfigService(prisma as never);
expect(() => service.createApplication({
tenantId: 'tenant-1',
name: '异常应用',
queuePriority: 'urgent',
})).toThrow('queuePriority must be normal or priority');
expect(prisma.smsApplication.create).not.toHaveBeenCalled();
});
it('updates enterprise application profile and allowlist through a transaction', async () => {
const prisma = createPrismaMock();
const tx = {
@@ -181,7 +218,7 @@ describe('SmsConfigService', () => {
prisma.$transaction.mockImplementationOnce((callback: (client: typeof tx) => unknown) => callback(tx));
const service = new SmsConfigService(prisma as never);
await expect(service.updateApplication('app-1', { name: '新应用', customerUnitPrice: 300, ipAllowlist: ['10.0.0.1/32'] }))
await expect(service.updateApplication('app-1', { name: '新应用', customerUnitPrice: 300, queuePriority: 'priority', ipAllowlist: ['10.0.0.1/32'] }))
.resolves.toEqual(expect.objectContaining({ id: 'app-1', name: '新应用' }));
expect(tx.smsApplicationIpAllowlist.deleteMany).toHaveBeenCalledWith({ where: { applicationId: 'app-1' } });
@@ -190,6 +227,7 @@ describe('SmsConfigService', () => {
data: expect.objectContaining({
name: '新应用',
customerUnitPrice: 300,
queuePriority: 'priority',
ipAllowlist: { create: [{ ipCidr: '10.0.0.1/32' }] },
}),
}));