This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
import { SendGatewaySubmitService } from './send-gateway-submit.service';
|
||||
|
||||
describe('shared dispatch night gate', () => {
|
||||
function setup() {
|
||||
const message = {
|
||||
id: 'm1',
|
||||
status: 'queued',
|
||||
tenantId: 't1',
|
||||
applicationId: 'a1',
|
||||
batchTaskId: 'b1',
|
||||
content: '任意内容',
|
||||
};
|
||||
const prisma = {
|
||||
smsMessageRecord: {
|
||||
findUnique: jest.fn().mockResolvedValue(message),
|
||||
findMany: jest.fn().mockResolvedValue([message, { ...message, id: 'm2' }]),
|
||||
update: jest.fn(),
|
||||
},
|
||||
};
|
||||
const risk = { guardNightSending: jest.fn().mockResolvedValue(new Set(['m1'])) };
|
||||
const facade = {
|
||||
refreshTaskProgress: jest.fn(),
|
||||
selectChannelForMessage: jest.fn(),
|
||||
submitMessageToGateway: jest.fn(),
|
||||
};
|
||||
const sut = new SendGatewaySubmitService(
|
||||
prisma as never,
|
||||
{} as never,
|
||||
risk as never,
|
||||
{} as never,
|
||||
{} as never,
|
||||
facade as never,
|
||||
{} as never,
|
||||
);
|
||||
return { sut, prisma, risk, facade };
|
||||
}
|
||||
it('holds single-message jobs before any channel or Submit operation', async () => {
|
||||
const { sut, facade } = setup();
|
||||
expect(await sut.processSendJob({ messageRecordId: 'm1' })).toMatchObject({
|
||||
status: 'pending_review',
|
||||
submitted: false,
|
||||
});
|
||||
expect(facade.selectChannelForMessage).not.toHaveBeenCalled();
|
||||
expect(facade.submitMessageToGateway).not.toHaveBeenCalled();
|
||||
});
|
||||
it('partitions the fast worker batch by persistent gate decisions', async () => {
|
||||
const { sut } = setup();
|
||||
const route = jest.spyOn(sut as never, 'planRoutesBatch').mockResolvedValue({ planned: [], failed: [] } as never);
|
||||
const result = await sut['processSendJobBatch']([{ messageRecordId: 'm1' }, { messageRecordId: 'm2' }]);
|
||||
expect(result.get('m1')).toMatchObject({ status: 'pending_review' });
|
||||
expect(route).toHaveBeenCalledWith([expect.objectContaining({ id: 'm2' })]);
|
||||
});
|
||||
it('propagates database failures without submitting or misclassifying them as routing failures', async () => {
|
||||
const { sut, risk, facade, prisma } = setup();
|
||||
risk.guardNightSending.mockRejectedValue(new Error('database unavailable'));
|
||||
await expect(sut.processSendJob({ messageRecordId: 'm1' })).rejects.toThrow('database unavailable');
|
||||
expect(prisma.smsMessageRecord.update).not.toHaveBeenCalled();
|
||||
expect(facade.submitMessageToGateway).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user