feat: refine template deletion and channel group filters
This commit is contained in:
@@ -666,6 +666,22 @@ describe('SendChainService', () => {
|
||||
expect(prisma.smsBatchTask.create).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('rejects a new task that selects a deleted template', async () => {
|
||||
const { service, prisma } = createService();
|
||||
prisma.smsTemplate.findUnique.mockResolvedValue({
|
||||
id: 'tpl-1', tenantId: 'tenant-1', applicationId: 'app-1', signatureId: 'sig-1',
|
||||
content: 'hello', auditStatus: 'deleted',
|
||||
signature: { id: 'sig-1', name: '【签名】', auditStatus: 'approved' },
|
||||
});
|
||||
|
||||
await expect(service.createBatchTask({
|
||||
tenantId: 'tenant-1', applicationId: 'app-1', templateId: 'tpl-1',
|
||||
content: 'hello', phones: ['13800000001'],
|
||||
})).rejects.toThrow('短信模板不存在、未通过审核或不属于当前应用');
|
||||
|
||||
expect(prisma.smsBatchTask.create).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('rejects free content without an approved leading signature', async () => {
|
||||
const { service, prisma } = createService();
|
||||
prisma.smsApplication.findUnique.mockResolvedValue({
|
||||
@@ -927,6 +943,47 @@ describe('SendChainService', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('dispatches an accepted scheduled task from its snapshot after the template is deleted', async () => {
|
||||
const { service, prisma, billing } = createService();
|
||||
prisma.smsTemplate.findUnique.mockResolvedValue({
|
||||
id: 'tpl-1', tenantId: 'tenant-1', applicationId: 'app-1', auditStatus: 'deleted',
|
||||
signature: { id: 'sig-1', auditStatus: 'approved' },
|
||||
});
|
||||
prisma.smsBatchTask.findMany.mockResolvedValue([{
|
||||
id: 'task-1', tenantId: 'tenant-1', applicationId: 'app-1', templateId: 'tpl-1', status: 'scheduled',
|
||||
}]);
|
||||
prisma.smsMessageRecord.findMany.mockResolvedValue([{ id: 'record-1', amountCents: 3, billingUnits: 1 }]);
|
||||
service.enqueueBatchTask = jest.fn().mockResolvedValue({ taskId: 'task-1', enqueued: 1 });
|
||||
|
||||
await expect(service.dispatchDueScheduledTasks(new Date())).resolves.toEqual({
|
||||
dispatched: 1,
|
||||
results: [{ taskId: 'task-1', status: 'queued', enqueued: 1 }],
|
||||
});
|
||||
|
||||
expect(billing.freeze).toHaveBeenCalledWith(expect.objectContaining({ relatedId: 'task-1' }));
|
||||
expect(service.enqueueBatchTask).toHaveBeenCalledWith('task-1');
|
||||
});
|
||||
|
||||
it('still blocks scheduled dispatch when the persisted template signature is no longer approved', async () => {
|
||||
const { service, prisma, billing } = createService();
|
||||
service.enqueueBatchTask = jest.fn().mockResolvedValue({ taskId: 'task-1', enqueued: 1 });
|
||||
prisma.smsTemplate.findUnique.mockResolvedValue({
|
||||
id: 'tpl-1', tenantId: 'tenant-1', applicationId: 'app-1', auditStatus: 'deleted',
|
||||
signature: { id: 'sig-1', auditStatus: 'deleted' },
|
||||
});
|
||||
prisma.smsBatchTask.findMany.mockResolvedValue([{
|
||||
id: 'task-1', tenantId: 'tenant-1', applicationId: 'app-1', templateId: 'tpl-1', status: 'scheduled',
|
||||
}]);
|
||||
|
||||
await expect(service.dispatchDueScheduledTasks(new Date())).resolves.toEqual({
|
||||
dispatched: 0,
|
||||
results: [{ taskId: 'task-1', status: 'failed', reason: '短信签名未审核通过' }],
|
||||
});
|
||||
|
||||
expect(billing.freeze).not.toHaveBeenCalled();
|
||||
expect(service.enqueueBatchTask).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('terminates non-final tasks by canceling unsubmitted messages', async () => {
|
||||
const { service, prisma } = createService();
|
||||
prisma.smsBatchTask.findUnique.mockResolvedValue({ id: 'task-1', status: 'sending' });
|
||||
|
||||
Reference in New Issue
Block a user