fix: record cmpp business failures with receipts
This commit is contained in:
@@ -106,6 +106,7 @@ function createPrismaMock() {
|
||||
findMany: jest.fn(),
|
||||
},
|
||||
smsMessageRecord: {
|
||||
create: jest.fn().mockImplementation(({ data }) => Promise.resolve({ ...message, ...data })),
|
||||
createMany: jest.fn().mockResolvedValue({ count: 2 }),
|
||||
findMany: jest.fn().mockResolvedValue([{ id: 'record-1', batchTaskId: 'task-1' }]),
|
||||
findUnique: jest.fn().mockResolvedValue(message),
|
||||
@@ -149,6 +150,7 @@ function createPrismaMock() {
|
||||
},
|
||||
smsReceiptRecord: {
|
||||
create: jest.fn().mockResolvedValue({ id: 'receipt-1' }),
|
||||
findFirst: jest.fn().mockResolvedValue(null),
|
||||
findMany: jest.fn(),
|
||||
},
|
||||
smsUplinkMessage: {
|
||||
@@ -474,7 +476,7 @@ describe('SendChainService', () => {
|
||||
})).rejects.toThrow('CMPP interface is disabled for this application');
|
||||
});
|
||||
|
||||
it('rejects Gateway submit when application interface is disabled', async () => {
|
||||
it('records and acknowledges Gateway submit with a failure receipt when the application interface was disabled after bind', async () => {
|
||||
const { service, prisma } = createService();
|
||||
prisma.smsApplication.findFirst.mockResolvedValue({
|
||||
id: 'app-1',
|
||||
@@ -493,9 +495,35 @@ describe('SendChainService', () => {
|
||||
phoneNumber: '13800000001',
|
||||
content: 'hello',
|
||||
remoteIp: '127.0.0.1',
|
||||
})).rejects.toThrow('CMPP interface is disabled for this application');
|
||||
})).resolves.toEqual(expect.objectContaining({ accepted: true, messageRecordId: 'record-1' }));
|
||||
|
||||
expect(prisma.smsBatchTask.create).not.toHaveBeenCalled();
|
||||
expect(prisma.smsMessageRecord.create).toHaveBeenCalledWith({ data: expect.objectContaining({ status: 'validating' }) });
|
||||
expect(prisma.smsReceiptRecord.create).toHaveBeenCalledWith({
|
||||
data: expect.objectContaining({ messageRecordId: 'record-1', receiptStatus: 'undelivered', errorCode: 'INTERFACE' }),
|
||||
});
|
||||
expect(prisma.cmppDownstreamDelivery.create).toHaveBeenCalledWith({
|
||||
data: expect.objectContaining({ messageRecordId: 'record-1', deliveryType: 'receipt', status: 'pending' }),
|
||||
});
|
||||
});
|
||||
|
||||
it('records an unreported CMPP message and returns success before delivering the template failure receipt', async () => {
|
||||
const { service, prisma } = createService();
|
||||
prisma.smsTemplate.findFirst.mockResolvedValue(null);
|
||||
|
||||
await expect(service.submitInboundMessage({
|
||||
account: '100001',
|
||||
phoneNumber: '13800000001',
|
||||
content: 'unreported content',
|
||||
remoteIp: '127.0.0.1',
|
||||
})).resolves.toEqual(expect.objectContaining({ accepted: true, messageRecordId: 'record-1' }));
|
||||
|
||||
expect(prisma.smsReceiptRecord.create).toHaveBeenCalledWith({
|
||||
data: expect.objectContaining({ receiptStatus: 'undelivered', rawStatus: 'REJECTD', errorCode: 'TEMPLATE' }),
|
||||
});
|
||||
expect(service['postGatewayControl']).toHaveBeenCalledWith(
|
||||
'/downstream/receipt',
|
||||
expect.objectContaining({ receiptStatus: 'undelivered', rawStatus: 'REJECTD', errorCode: 'TEMPLATE' }),
|
||||
);
|
||||
});
|
||||
|
||||
it('previews imported phone files with duplicate, invalid, blacklist, and variable errors', async () => {
|
||||
@@ -896,11 +924,31 @@ describe('SendChainService', () => {
|
||||
service['waitForChannelRateLimit'] = jest.fn().mockResolvedValue(undefined);
|
||||
service['getGatewayQueue'] = jest.fn().mockReturnValue({ add: gatewayAdd });
|
||||
prisma.channelSignatureReportTask.findFirst.mockResolvedValue(null);
|
||||
prisma.smsMessageRecord.findUnique.mockResolvedValue({
|
||||
id: 'record-1',
|
||||
tenantId: 'tenant-1',
|
||||
batchTaskId: 'task-1',
|
||||
applicationId: 'app-1',
|
||||
templateId: 'tpl-1',
|
||||
messageId: 'MSG-1',
|
||||
phoneNumber: '13800000001',
|
||||
content: 'hello',
|
||||
billingUnits: 1,
|
||||
unitPrice: 3,
|
||||
amountCents: 3,
|
||||
status: 'queued',
|
||||
queuePriority: 'normal',
|
||||
batchTask: { sourceType: 'cmpp' },
|
||||
template: { signature: { id: 'sig-1', name: '签名' } },
|
||||
});
|
||||
|
||||
await expect(service.processSendJob({ messageRecordId: 'record-1' })).resolves.toEqual(
|
||||
expect.objectContaining({ submitted: false, status: 'failed', reason: '短信签名未在最终通道报备通过' }),
|
||||
);
|
||||
expect(gatewayAdd).not.toHaveBeenCalled();
|
||||
expect(prisma.smsReceiptRecord.create).toHaveBeenCalledWith({
|
||||
data: expect.objectContaining({ receiptStatus: 'undelivered', errorCode: 'ROUTE' }),
|
||||
});
|
||||
});
|
||||
|
||||
it('only selects channel group items allocated to the matched carrier', async () => {
|
||||
|
||||
Reference in New Issue
Block a user