fix: route through reported signature channels

This commit is contained in:
hectorzhao
2026-07-13 10:02:48 +08:00
parent 7703873346
commit ade06058f5
5 changed files with 70 additions and 19 deletions
+27 -5
View File
@@ -84,7 +84,7 @@ function createPrismaMock() {
tenantId: 'tenant-1',
applicationId: 'app-1',
auditStatus: 'approved',
signature: { auditStatus: 'approved', reportStatus: 'approved' },
signature: { auditStatus: 'approved', reportStatus: 'reporting' },
}),
findFirst: jest.fn().mockResolvedValue({
id: 'tpl-1',
@@ -92,11 +92,11 @@ function createPrismaMock() {
applicationId: 'app-1',
content: 'hello',
auditStatus: 'approved',
signature: { auditStatus: 'approved', reportStatus: 'approved' },
signature: { auditStatus: 'approved', reportStatus: 'reporting' },
}),
},
smsSignature: {
findFirst: jest.fn().mockResolvedValue({ id: 'sig-1', name: '签名', auditStatus: 'approved', reportStatus: 'approved' }),
findFirst: jest.fn().mockResolvedValue({ id: 'sig-1', name: '签名', auditStatus: 'approved', reportStatus: 'reporting' }),
},
smsSendTask: {
findUnique: jest.fn().mockResolvedValue(null),
@@ -154,6 +154,7 @@ function createPrismaMock() {
},
channelSignatureReportTask: {
findFirst: jest.fn().mockResolvedValue({ id: 'report-task-1' }),
findMany: jest.fn().mockImplementation(({ where }) => Promise.resolve((where.channelId?.in ?? []).map((channelId: string) => ({ channelId })))),
},
smsReceiptRecord: {
create: jest.fn().mockResolvedValue({ id: 'receipt-1' }),
@@ -720,6 +721,27 @@ describe('SendChainService', () => {
expect(service['postGatewayControl']).not.toHaveBeenCalledWith('/upstream/submit', expect.anything());
});
it('routes a partially reported signature only through its approved backup channel', async () => {
const { service, prisma } = createService();
const baseRoute = await prisma.channelRouteRule.findFirst();
const primary = baseRoute.group.items[0].channel;
const backup = { ...primary, id: 'channel-backup', code: 'CMPP-B' };
prisma.channelRouteRule.findFirst.mockResolvedValue({
...baseRoute,
group: { ...baseRoute.group, items: [
{ ...baseRoute.group.items[0], channelId: primary.id, priority: 1, channel: primary },
{ ...baseRoute.group.items[0], id: 'item-2', channelId: backup.id, priority: 2, channel: backup },
] },
});
prisma.channelSignatureReportTask.findMany.mockResolvedValue([{ channelId: backup.id }]);
const gatewayAdd = jest.fn().mockResolvedValue(undefined);
service['waitForChannelRateLimit'] = jest.fn().mockResolvedValue(undefined);
service['getGatewayQueue'] = jest.fn().mockReturnValue({ add: gatewayAdd });
await expect(service.processSendJob({ messageRecordId: 'record-1' })).resolves.toEqual(expect.objectContaining({ submitted: true, channelId: backup.id }));
expect(prisma.smsMessageRecord.update).toHaveBeenCalledWith(expect.objectContaining({ data: expect.objectContaining({ channelId: backup.id }) }));
});
it('persists identified carrier and province before a route lookup fails', async () => {
const { service, prisma } = createService();
prisma.channelRouteRule.findFirst.mockResolvedValueOnce(null);
@@ -1047,7 +1069,7 @@ describe('SendChainService', () => {
const gatewayAdd = jest.fn().mockResolvedValue(undefined);
service['waitForChannelRateLimit'] = jest.fn().mockResolvedValue(undefined);
service['getGatewayQueue'] = jest.fn().mockReturnValue({ add: gatewayAdd });
prisma.channelSignatureReportTask.findFirst.mockResolvedValue(null);
prisma.channelSignatureReportTask.findMany.mockResolvedValue([]);
prisma.smsMessageRecord.findUnique.mockResolvedValue({
id: 'record-1',
tenantId: 'tenant-1',
@@ -1067,7 +1089,7 @@ describe('SendChainService', () => {
});
await expect(service.processSendJob({ messageRecordId: 'record-1' })).resolves.toEqual(
expect.objectContaining({ submitted: false, status: 'failed', reason: '短信签名未在最终通道报备通过' }),
expect.objectContaining({ submitted: false, status: 'failed', reason: '无已报备通过且在线的可用通道' }),
);
expect(gatewayAdd).not.toHaveBeenCalled();
expect(prisma.smsReceiptRecord.create).toHaveBeenCalledWith({