138 lines
4.2 KiB
TypeScript
138 lines
4.2 KiB
TypeScript
import { MarketsService } from './markets.service';
|
|
|
|
function selection(selectionCode: string, odds = 1.9) {
|
|
return {
|
|
selectionCode,
|
|
selectionName: selectionCode,
|
|
odds,
|
|
status: 'OPEN',
|
|
};
|
|
}
|
|
|
|
function errorCode(error: unknown) {
|
|
const response = (error as { getResponse?: () => unknown }).getResponse?.();
|
|
return (response as { code?: string } | undefined)?.code;
|
|
}
|
|
|
|
function createPrismaMock() {
|
|
let marketId = 100n;
|
|
let selectionId = 1000n;
|
|
return {
|
|
match: {
|
|
findUnique: jest.fn().mockResolvedValue({ id: 1n }),
|
|
},
|
|
market: {
|
|
findFirst: jest.fn().mockResolvedValue(null),
|
|
create: jest.fn().mockImplementation(async ({ data }) => ({ id: marketId++, ...data })),
|
|
update: jest.fn().mockImplementation(async ({ where, data }) => ({ id: where.id, ...data })),
|
|
findUnique: jest.fn().mockImplementation(async ({ where }) => ({ id: where.id, selections: [] })),
|
|
findMany: jest.fn().mockResolvedValue([]),
|
|
updateMany: jest.fn().mockResolvedValue({ count: 0 }),
|
|
},
|
|
marketSelection: {
|
|
findMany: jest.fn().mockResolvedValue([]),
|
|
create: jest.fn().mockImplementation(async ({ data }) => ({ id: selectionId++, ...data })),
|
|
update: jest.fn(),
|
|
updateMany: jest.fn().mockResolvedValue({ count: 0 }),
|
|
},
|
|
oddsChangeLog: {
|
|
create: jest.fn(),
|
|
},
|
|
};
|
|
}
|
|
|
|
describe('MarketsService line value rules', () => {
|
|
it('exposes usesLineValue in market definitions', () => {
|
|
const service = new MarketsService(createPrismaMock() as never);
|
|
|
|
const definitions = service.listMarketDefinitions();
|
|
|
|
expect(definitions.find((d) => d.marketType === 'FT_HANDICAP')?.usesLineValue).toBe(true);
|
|
expect(definitions.find((d) => d.marketType === 'FT_1X2')?.usesLineValue).toBe(false);
|
|
});
|
|
|
|
it('rejects line markets without a numeric line value', async () => {
|
|
const service = new MarketsService(createPrismaMock() as never);
|
|
|
|
let caughtCode: string | undefined;
|
|
try {
|
|
await service.saveMatchMarkets(1n, [
|
|
{
|
|
marketType: 'FT_HANDICAP',
|
|
lineValue: null,
|
|
selections: [selection('HOME'), selection('AWAY')],
|
|
},
|
|
]);
|
|
} catch (error) {
|
|
caughtCode = errorCode(error);
|
|
}
|
|
expect(caughtCode).toBe('MARKET_LINE_REQUIRED');
|
|
});
|
|
|
|
it('rejects non-line markets with a line value', async () => {
|
|
const service = new MarketsService(createPrismaMock() as never);
|
|
|
|
let caughtCode: string | undefined;
|
|
try {
|
|
await service.saveMatchMarkets(1n, [
|
|
{
|
|
marketType: 'FT_1X2',
|
|
lineValue: 1,
|
|
selections: [selection('HOME'), selection('DRAW'), selection('AWAY')],
|
|
},
|
|
]);
|
|
} catch (error) {
|
|
caughtCode = errorCode(error);
|
|
}
|
|
expect(caughtCode).toBe('MARKET_LINE_NOT_ALLOWED');
|
|
});
|
|
|
|
it('allows non-line markets with null line value', async () => {
|
|
const prisma = createPrismaMock();
|
|
const service = new MarketsService(prisma as never);
|
|
|
|
const result = await service.saveMatchMarkets(1n, [
|
|
{
|
|
marketType: 'FT_1X2',
|
|
lineValue: null,
|
|
selections: [selection('HOME'), selection('DRAW'), selection('AWAY')],
|
|
},
|
|
]);
|
|
|
|
expect(result).toEqual({ updated: 1, closed: 0 });
|
|
expect(prisma.market.create).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
data: expect.objectContaining({
|
|
marketType: 'FT_1X2',
|
|
lineKey: 'FT_1X2:none',
|
|
lineValue: null,
|
|
}),
|
|
}),
|
|
);
|
|
});
|
|
|
|
it('keeps distinct line keys for copied line markets', async () => {
|
|
const prisma = createPrismaMock();
|
|
const service = new MarketsService(prisma as never);
|
|
|
|
const result = await service.saveMatchMarkets(1n, [
|
|
{
|
|
marketType: 'FT_HANDICAP',
|
|
lineValue: -0.5,
|
|
selections: [selection('HOME'), selection('AWAY')],
|
|
},
|
|
{
|
|
marketType: 'FT_HANDICAP',
|
|
lineValue: -0.25,
|
|
selections: [selection('HOME'), selection('AWAY')],
|
|
},
|
|
]);
|
|
|
|
expect(result).toEqual({ updated: 2, closed: 0 });
|
|
expect(prisma.market.create.mock.calls.map(([arg]) => arg.data.lineKey)).toEqual([
|
|
'FT_HANDICAP:-0.50',
|
|
'FT_HANDICAP:-0.25',
|
|
]);
|
|
});
|
|
});
|