feat: add report material workflows and gateway safeguards
This commit is contained in:
@@ -96,6 +96,7 @@ function createPrismaMock() {
|
||||
},
|
||||
drainageField: {
|
||||
findUnique: jest.fn().mockResolvedValue({ id: 'library-1', code: 'license', name: '营业执照', fieldType: 'file', required: true, status: 'active', description: '执照文件' }),
|
||||
findMany: jest.fn().mockResolvedValue([{ id: 'library-1', code: 'license', name: '营业执照', fieldType: 'file', required: true, status: 'active', description: '执照文件' }]),
|
||||
},
|
||||
signatureReportMaterial: {
|
||||
findMany: jest.fn().mockResolvedValue([{ signatureId: 'sig-1', fieldCode: 'license', fieldValue: '营业执照', fileObjectId: 'file-1' }]),
|
||||
@@ -178,6 +179,26 @@ describe('ChannelsService', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('replaces one report type while preserving legacy both fields for the opposite type', async () => {
|
||||
const prisma = createPrismaMock();
|
||||
const legacyBoth = { id: 'legacy-1', channelId: 'channel-1', drainageFieldId: 'library-1', reportType: 'both', code: 'license', name: '营业执照', exportName: '旧表头', fieldType: 'file', required: true, description: null, sortOrder: 10, columnWidth: 18, imageWidth: 120, imageHeight: 80, defaultValue: null, transform: null, status: 'active', createdAt: new Date(), updatedAt: new Date() };
|
||||
const tx = {
|
||||
channelReportField: {
|
||||
findMany: jest.fn().mockResolvedValueOnce([legacyBoth]).mockResolvedValueOnce([]).mockResolvedValueOnce([{ id: 'signature-field' }]),
|
||||
deleteMany: jest.fn(),
|
||||
create: jest.fn().mockImplementation(({ data }) => Promise.resolve({ id: `created-${data.reportType}`, ...data })),
|
||||
},
|
||||
};
|
||||
prisma.$transaction.mockImplementation((callback) => callback(tx));
|
||||
const service = new ChannelsService(prisma as never);
|
||||
|
||||
await service.replaceReportFields('channel-1', 'signature', { fields: [{ drainageFieldId: 'library-1', exportName: '新签名表头', required: true }] });
|
||||
|
||||
expect(tx.channelReportField.deleteMany).toHaveBeenCalledWith({ where: { channelId: 'channel-1', reportType: { in: ['signature', 'both'] } } });
|
||||
expect(tx.channelReportField.create).toHaveBeenCalledWith({ data: expect.objectContaining({ channelId: 'channel-1', code: 'license', reportType: 'drainage', exportName: '旧表头' }) });
|
||||
expect(tx.channelReportField.create).toHaveBeenCalledWith({ data: expect.objectContaining({ channelId: 'channel-1', code: 'license', reportType: 'signature', exportName: '新签名表头' }) });
|
||||
});
|
||||
|
||||
it('lists report tasks for one real channel', async () => {
|
||||
const prisma = createPrismaMock();
|
||||
prisma.channelSignatureReportTask.findMany.mockResolvedValue([]);
|
||||
@@ -460,6 +481,7 @@ describe('ChannelsService', () => {
|
||||
expect(prisma.smsChannelGroupItem.create).toHaveBeenCalledWith({
|
||||
data: expect.objectContaining({ groupId: 'group-1', channelId: 'channel-1', carrier: 'mobile', province: '山东' }),
|
||||
});
|
||||
expect(prisma.smsChannelGroupItem.create.mock.calls[0][0].data).not.toHaveProperty('rateLimitPerSecond');
|
||||
|
||||
await expect(service.addGroupItem({ groupId: 'group-1', channelId: 'channel-1', carrier: 'unicom' }))
|
||||
.rejects.toThrow('Channel group items must use the same carrier');
|
||||
@@ -545,6 +567,9 @@ describe('ChannelsService', () => {
|
||||
where: { id: 'group-1' },
|
||||
data: expect.objectContaining({ retryTimeLimitHours: 13, retryTimeLimitMinutes: 750 }),
|
||||
});
|
||||
for (const item of tx.smsChannelGroupItem.createMany.mock.calls[0][0].data) {
|
||||
expect(item).not.toHaveProperty('rateLimitPerSecond');
|
||||
}
|
||||
|
||||
await expect(service.updateGroup('group-1', {
|
||||
carrier: 'mobile',
|
||||
|
||||
Reference in New Issue
Block a user