fix: make SMS retry side effects idempotent

This commit is contained in:
hectorzhao
2026-07-26 22:31:30 +08:00
parent 04f78695ed
commit e0f6eed0d4
11 changed files with 516 additions and 105 deletions
+12 -5
View File
@@ -65,13 +65,20 @@ describe('OpenApiService', () => {
const prisma = {
smsApplication: { findUnique: jest.fn().mockResolvedValue({ httpConfig: { enabled: true, receiptWebhookEnabled: true, receiptDeliveryMode: 'http' } }) },
httpWebhookEndpoint: { findUnique: jest.fn().mockResolvedValue({ id: 'endpoint-1', status: 'active' }) },
httpWebhookEvent: { create: jest.fn().mockResolvedValue({ id: 'event-row-1' }) },
httpWebhookDelivery: { create: jest.fn().mockResolvedValue({ id: 'delivery-1' }) },
httpWebhookEvent: { upsert: jest.fn().mockResolvedValue({ id: 'event-row-1' }) },
httpWebhookDelivery: { upsert: jest.fn().mockResolvedValue({ id: 'delivery-1', status: 'pending' }) },
};
const service = new OpenApiService(prisma as never, {} as never);
await service.queueWebhookEvent({ tenantId: 'tenant-1', applicationId: 'app-1', eventType: 'receipt', messageId: 'MSG-1', payload: { receiptStatus: 'delivered' } });
expect(prisma.httpWebhookEvent.create).toHaveBeenCalled();
expect(prisma.httpWebhookDelivery.create).toHaveBeenCalledWith({ data: { eventId: 'event-row-1', endpointId: 'endpoint-1' } });
const input = { tenantId: 'tenant-1', applicationId: 'app-1', eventType: 'receipt' as const, messageRecordId: 'record-1', messageId: 'MSG-1', payload: { receiptStatus: 'delivered' } };
await service.queueWebhookEvent(input);
await service.queueWebhookEvent(input);
expect(prisma.httpWebhookEvent.upsert).toHaveBeenCalledWith(expect.objectContaining({
where: { eventId: 'evt_receipt_record-1' },
}));
expect(prisma.httpWebhookEvent.upsert).toHaveBeenCalledTimes(2);
expect(prisma.httpWebhookDelivery.upsert).toHaveBeenCalledWith(expect.objectContaining({
create: { eventId: 'event-row-1', endpointId: 'endpoint-1' },
}));
});
it('defaults a newly enabled HTTP interface to all six capabilities and automatic dual delivery', async () => {