test: add first-version coverage

This commit is contained in:
hectorzhao
2026-07-01 14:46:35 +08:00
parent 924457a48e
commit 91d1e38a09
13 changed files with 5484 additions and 1 deletions
@@ -0,0 +1,100 @@
import { OperationsService } from './operations.service';
function createPrismaMock() {
return {
smsBatchTask: {
findMany: jest.fn(),
count: jest.fn().mockResolvedValue(3),
},
smsMessageRecord: {
findMany: jest.fn().mockResolvedValue([{ messageId: 'MSG-1' }]),
groupBy: jest.fn().mockResolvedValue([{ status: 'delivered', _count: { _all: 2 }, _sum: { amountCents: 20, billingUnits: 2 } }]),
aggregate: jest.fn().mockResolvedValue({ _count: { _all: 2 }, _sum: { amountCents: 20, billingUnits: 2 } }),
},
smsReceiptRecord: {
findMany: jest.fn().mockResolvedValue([]),
},
smsUplinkMessage: {
findMany: jest.fn().mockResolvedValue([{ id: 'uplink-1', messageId: 'MSG-1' }]),
count: jest.fn().mockResolvedValue(1),
},
smsBillingRecord: {
findMany: jest.fn().mockResolvedValue([{ id: 'bill-1', messageId: 'MSG-1' }]),
aggregate: jest.fn().mockResolvedValue({ _count: { _all: 2 }, _sum: { amountCents: 20, billingUnits: 2 } }),
},
accountTransaction: {
aggregate: jest.fn().mockResolvedValue({ _count: { _all: 2 }, _sum: { amountCents: -20, smsUnits: -2 } }),
},
operationLog: {
findMany: jest.fn(),
groupBy: jest.fn(),
},
};
}
describe('OperationsService', () => {
it('filters send-chain messages by tenant, application, channel, task, phone, and status', async () => {
const prisma = createPrismaMock();
const service = new OperationsService(prisma as never);
await service.listMessages({
tenantId: 'tenant-1',
applicationId: 'app-1',
channelId: 'channel-1',
taskId: 'task-1',
phoneNumber: '13800000001',
status: 'delivered',
});
expect(prisma.smsMessageRecord.findMany).toHaveBeenCalledWith({
where: {
tenantId: 'tenant-1',
applicationId: 'app-1',
channelId: 'channel-1',
batchTaskId: 'task-1',
phoneNumber: '13800000001',
status: 'delivered',
},
include: { submitRecords: true, receiptRecords: true },
orderBy: { queuedAt: 'desc' },
take: 500,
});
});
it('builds dashboard and statistics aggregates', async () => {
const prisma = createPrismaMock();
const service = new OperationsService(prisma as never);
await expect(service.dashboard({ tenantId: 'tenant-1' })).resolves.toEqual(
expect.objectContaining({ taskCount: 3, uplinkCount: 1 }),
);
await service.statistics({ tenantId: 'tenant-1', groupBy: 'application' });
expect(prisma.smsMessageRecord.groupBy).toHaveBeenCalledWith({
by: ['applicationId'],
where: expect.objectContaining({ tenantId: 'tenant-1' }),
_count: { _all: true },
_sum: { amountCents: true, billingUnits: true },
});
});
it('returns trace details and reconciliation diffs', async () => {
const prisma = createPrismaMock();
const service = new OperationsService(prisma as never);
await expect(service.trace({ tenantId: 'tenant-1', taskId: 'task-1', messageId: 'MSG-1' })).resolves.toEqual({
messages: [{ messageId: 'MSG-1' }],
billingRecords: [{ id: 'bill-1', messageId: 'MSG-1' }],
uplinks: [{ id: 'uplink-1', messageId: 'MSG-1' }],
});
await expect(service.reconciliation({ tenantId: 'tenant-1', taskId: 'task-1' })).resolves.toEqual(
expect.objectContaining({
diff: {
messageVsBillingAmountCents: 0,
billingVsTransactionAmountCents: 0,
messageVsBillingUnits: 0,
},
}),
);
});
});