fix: close sms scheduling and billing gaps

This commit is contained in:
hectorzhao
2026-07-01 18:56:05 +08:00
parent 8ba4ef8a13
commit f8c9b78c21
28 changed files with 1480 additions and 26 deletions
+59
View File
@@ -6,6 +6,8 @@ function createPrismaMock() {
smsChannel: {
findMany: jest.fn(),
create: jest.fn().mockImplementation(({ data }) => Promise.resolve({ id: 'channel-1', ...data })),
findUnique: jest.fn().mockResolvedValue({ id: 'channel-1', status: 'active' }),
update: jest.fn().mockImplementation(({ data }) => Promise.resolve({ id: 'channel-1', ...data })),
},
channelHealthMetric: { findMany: jest.fn() },
smsChannelGroup: {
@@ -46,6 +48,13 @@ function createPrismaMock() {
smsSignature: {
update: jest.fn(),
},
cmppConnectionState: {
findMany: jest.fn(),
upsert: jest.fn().mockImplementation(({ create }) => Promise.resolve({ id: 'conn-1', ...create })),
},
operationLog: {
create: jest.fn(),
},
};
}
@@ -134,4 +143,54 @@ describe('ChannelsService', () => {
data: { reportStatus: 'rejected' },
});
});
it('updates channel status with operation logs', async () => {
const prisma = createPrismaMock();
const service = new ChannelsService(prisma as never);
await service.changeChannelStatus('channel-1', { status: 'disabled', operatorId: 'admin-1', reason: 'maintenance' });
expect(prisma.smsChannel.update).toHaveBeenCalledWith({ where: { id: 'channel-1' }, data: { status: 'disabled' } });
expect(prisma.operationLog.create).toHaveBeenCalledWith({
data: expect.objectContaining({
userId: 'admin-1',
action: 'sms_channel.disabled',
resource: 'sms_channel',
resourceId: 'channel-1',
}),
});
});
it('upserts and lists CMPP connection states', async () => {
const prisma = createPrismaMock();
const service = new ChannelsService(prisma as never);
await service.upsertConnectionState({
tenantId: 'tenant-1',
channelId: 'channel-1',
connectionId: 'conn-a',
status: 'online',
desiredConnections: 2,
currentConnections: 1,
});
await service.listChannelConnections('channel-1');
await service.listTenantConnections('tenant-1');
expect(prisma.cmppConnectionState.upsert).toHaveBeenCalledWith({
where: { channelId_connectionId: { channelId: 'channel-1', connectionId: 'conn-a' } },
update: expect.objectContaining({ tenantId: 'tenant-1', status: 'online', desiredConnections: 2, currentConnections: 1 }),
create: expect.objectContaining({ channelId: 'channel-1', connectionId: 'conn-a', status: 'online' }),
});
expect(prisma.cmppConnectionState.findMany).toHaveBeenCalledWith({
where: { channelId: 'channel-1' },
orderBy: { updatedAt: 'desc' },
take: 100,
});
expect(prisma.cmppConnectionState.findMany).toHaveBeenCalledWith({
where: { tenantId: 'tenant-1' },
include: { channel: true },
orderBy: { updatedAt: 'desc' },
take: 100,
});
});
});