feat(admin+api): 代理停用默认、结算加固与冒烟配置探针
- 代理层级默认授信比例与停用冻结/禁登全局默认 - 结算预览去重、比分校验、串关当场判负与市场类型校验 - 站内信 Banner/公告自动通知开关;开发环境动态 API 端口 - 扩充 RBAC/结算/认证/返现单元测试与 agent skills
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
import { Decimal } from '@prisma/client/runtime/library';
|
||||
import { CashbackService } from './cashback.service';
|
||||
|
||||
describe('CashbackService previewBatch', () => {
|
||||
const tx = {
|
||||
cashbackBatch: {
|
||||
findMany: jest.fn(),
|
||||
create: jest.fn(),
|
||||
},
|
||||
cashbackItem: {
|
||||
create: jest.fn(),
|
||||
},
|
||||
cashbackBet: {
|
||||
create: jest.fn(),
|
||||
},
|
||||
};
|
||||
const prisma = {
|
||||
cashbackBatch: {
|
||||
findFirst: jest.fn(),
|
||||
},
|
||||
cashbackBet: {
|
||||
findMany: jest.fn(),
|
||||
},
|
||||
bet: {
|
||||
findMany: jest.fn(),
|
||||
},
|
||||
cashbackRule: {
|
||||
findMany: jest.fn(),
|
||||
},
|
||||
agentProfile: {
|
||||
findMany: jest.fn(),
|
||||
},
|
||||
user: {
|
||||
findMany: jest.fn(),
|
||||
},
|
||||
wallet: {
|
||||
findMany: jest.fn(),
|
||||
},
|
||||
$transaction: jest.fn(async (fn: (client: typeof tx) => Promise<unknown>) => fn(tx)),
|
||||
};
|
||||
const funds = {};
|
||||
const systemConfig = {
|
||||
getPlatformDirectCashbackSettings: jest.fn(),
|
||||
};
|
||||
|
||||
let service: CashbackService;
|
||||
|
||||
const platformPlayerId = 100n;
|
||||
const adminInvitePlayerId = 101n;
|
||||
const adminSponsorId = 200n;
|
||||
const periodStart = new Date('2026-06-01T00:00:00.000Z');
|
||||
const periodEnd = new Date('2026-06-01T23:59:59.999Z');
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
service = new CashbackService(prisma as never, funds as never, systemConfig as never);
|
||||
systemConfig.getPlatformDirectCashbackSettings.mockResolvedValue({
|
||||
platformDirectRate: 0.02,
|
||||
adminInviteRate: 0.05,
|
||||
});
|
||||
prisma.cashbackBatch.findFirst.mockResolvedValue(null);
|
||||
prisma.cashbackBet.findMany.mockResolvedValue([]);
|
||||
prisma.cashbackRule.findMany.mockResolvedValue([]);
|
||||
prisma.agentProfile.findMany.mockResolvedValue([]);
|
||||
tx.cashbackBatch.findMany.mockResolvedValue([]);
|
||||
tx.cashbackItem.create.mockResolvedValue({});
|
||||
tx.cashbackBet.create.mockResolvedValue({});
|
||||
tx.cashbackBatch.create.mockImplementation(({ data }: { data: Record<string, unknown> }) =>
|
||||
Promise.resolve({ id: 1n, batchNo: 'CB-TEST', ...data }),
|
||||
);
|
||||
});
|
||||
|
||||
it('uses platformDirectRate for platform-direct players', async () => {
|
||||
prisma.bet.findMany.mockResolvedValue([
|
||||
{
|
||||
id: 1n,
|
||||
userId: platformPlayerId,
|
||||
stake: new Decimal(1000),
|
||||
status: 'WON',
|
||||
settledAt: new Date('2026-06-01T12:00:00.000Z'),
|
||||
user: { id: platformPlayerId, parentId: null, inviteSponsorId: null },
|
||||
selections: [{ marketType: 'FT_1X2' }],
|
||||
},
|
||||
]);
|
||||
prisma.user.findMany.mockResolvedValue([
|
||||
{ id: platformPlayerId, username: 'pd1', parent: null },
|
||||
]);
|
||||
prisma.wallet.findMany.mockResolvedValue([
|
||||
{ userId: platformPlayerId, availableBalance: new Decimal(0) },
|
||||
]);
|
||||
|
||||
const result = await service.previewBatch(periodStart, periodEnd);
|
||||
expect(result.items).toHaveLength(1);
|
||||
expect(result.items[0].amount.toString()).toBe('20');
|
||||
expect(result.totalAmount.toString()).toBe('20');
|
||||
});
|
||||
|
||||
it('uses adminInviteRate for admin-invited platform-direct players', async () => {
|
||||
prisma.bet.findMany.mockResolvedValue([
|
||||
{
|
||||
id: 2n,
|
||||
userId: adminInvitePlayerId,
|
||||
stake: new Decimal(1000),
|
||||
status: 'LOST',
|
||||
settledAt: new Date('2026-06-01T12:00:00.000Z'),
|
||||
user: {
|
||||
id: adminInvitePlayerId,
|
||||
parentId: null,
|
||||
inviteSponsorId: adminSponsorId,
|
||||
},
|
||||
selections: [{ marketType: 'FT_1X2' }],
|
||||
},
|
||||
]);
|
||||
prisma.user.findMany
|
||||
.mockResolvedValueOnce([{ id: adminSponsorId, userType: 'ADMIN' }])
|
||||
.mockResolvedValueOnce([{ id: adminInvitePlayerId, username: 'inv1', parent: null }]);
|
||||
prisma.wallet.findMany.mockResolvedValue([
|
||||
{ userId: adminInvitePlayerId, availableBalance: new Decimal(0) },
|
||||
]);
|
||||
|
||||
const result = await service.previewBatch(periodStart, periodEnd);
|
||||
expect(result.items).toHaveLength(1);
|
||||
expect(result.items[0].amount.toString()).toBe('50');
|
||||
expect(result.totalAmount.toString()).toBe('50');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user