trade360-nodejs-sdk
Version:
LSports Trade360 SDK for Node.js
596 lines • 32.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const class_transformer_1 = require("class-transformer");
const lossless_json_1 = require("lossless-json");
const base_bet_1 = require("../../../../src/entities/core-entities/market/base-bet");
const bet_status_1 = require("../../../../src/entities/core-entities/enums/bet-status");
const settlement_type_1 = require("../../../../src/entities/core-entities/enums/settlement-type");
const id_transformation_error_1 = require("../../../../src/entities/errors/id-transformation.error");
/**
* Custom number parser for lossless-json (same logic as in AxiosService)
*/
function customNumberParser(value) {
if ((0, lossless_json_1.isInteger)(value)) {
// For positive integers only (since IDs are always positive)
if (!value.startsWith('-')) {
// For very long numbers (17+ digits), definitely use BigInt
if (value.length > 16) {
return BigInt(value);
}
// For 16-digit numbers, compare against MAX_SAFE_INTEGER as string
if (value.length === 16) {
const maxSafeIntegerStr = '9007199254740991';
if (value > maxSafeIntegerStr) {
return BigInt(value);
}
}
}
// Safe to convert to number (includes all negative numbers and safe positive numbers)
return parseInt(value, 10);
}
return parseFloat(value);
}
describe('BaseBet Entity', () => {
it('should deserialize a plain object into a BaseBet instance', () => {
const plain = {
Id: 1,
Name: 'Base Bet',
Line: '2.5',
Status: bet_status_1.BetStatus.Open,
Settlement: settlement_type_1.SettlementType.Winner,
LastUpdate: '2024-06-01T12:00:00Z',
IsChanged: 1,
Probability: 0.75,
ParticipantId: 42,
PlayerName: 'Player X',
};
const baseBet = (0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plain, { excludeExtraneousValues: true });
expect(baseBet).toBeInstanceOf(base_bet_1.BaseBet);
expect(baseBet.id).toBe(1n);
expect(baseBet.name).toBe('Base Bet');
expect(baseBet.line).toBe('2.5');
expect(baseBet.status).toBe(bet_status_1.BetStatus.Open);
expect(baseBet.settlement).toBe(settlement_type_1.SettlementType.Winner);
expect(baseBet.lastUpdate).toBeInstanceOf(Date);
expect(baseBet.lastUpdate?.toISOString()).toBe('2024-06-01T12:00:00.000Z');
expect(baseBet.probability).toBe(0.75);
expect(baseBet.participantId).toBe(42);
expect(baseBet.playerName).toBe('Player X');
});
it('should handle missing properties', () => {
const plain = {};
expect(() => {
(0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plain, { excludeExtraneousValues: true });
}).toThrow(id_transformation_error_1.IdTransformationError);
try {
(0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plain, { excludeExtraneousValues: true });
}
catch (error) {
expect(error.message).toContain('Field is required but received null or undefined');
}
});
it('should handle missing properties with valid ID', () => {
const plain = { Id: 123 };
const baseBet = (0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plain, { excludeExtraneousValues: true });
expect(baseBet.id).toBe(123n);
expect(baseBet.name).toBeUndefined();
expect(baseBet.line).toBeUndefined();
expect(baseBet.baseLine).toBeUndefined();
expect(baseBet.status).toBeUndefined();
expect(baseBet.startPrice).toBeUndefined();
expect(baseBet.price).toBeUndefined();
expect(baseBet.priceVolume).toBeUndefined();
expect(baseBet.settlement).toBeUndefined();
expect(baseBet.lastUpdate).toBeUndefined();
expect(baseBet.priceIN).toBeUndefined();
expect(baseBet.priceUS).toBeUndefined();
expect(baseBet.priceUK).toBeUndefined();
expect(baseBet.priceMA).toBeUndefined();
expect(baseBet.priceHK).toBeUndefined();
expect(baseBet.probability).toBeUndefined();
expect(baseBet.participantId).toBeUndefined();
expect(baseBet.playerName).toBeUndefined();
});
it('should ignore extraneous properties', () => {
const plain = {
Id: 2,
Name: 'Test BaseBet',
Extra: 'ignore me',
};
const baseBet = (0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plain, { excludeExtraneousValues: true });
expect(baseBet.Extra).toBeUndefined();
});
it('should handle large ID numbers without precision loss', () => {
const plain = {
Id: '11060329315062111', // The example from the user - using string to avoid precision loss
Name: 'Large ID Bet',
};
const baseBet = (0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plain, { excludeExtraneousValues: true });
expect(baseBet).toBeInstanceOf(base_bet_1.BaseBet);
expect(baseBet.id).toBe(11060329315062111n);
expect(baseBet.name).toBe('Large ID Bet');
});
it('should handle the complete end-to-end scenario with lossless-json parsing', () => {
// Simulate the exact JSON response from the server
const jsonResponse = '{"Id":11060329315062111,"Name":"End-to-End Test","Status":1}';
// Parse using lossless-json (same as AxiosService does)
const parsedData = (0, lossless_json_1.parse)(jsonResponse, undefined, customNumberParser);
// Verify that the large number is preserved as BigInt
expect(typeof parsedData.Id).toBe('bigint');
expect(parsedData.Id).toBe(11060329315062111n);
// Verify that small numbers remain as regular numbers
expect(typeof parsedData.Status).toBe('number');
expect(parsedData.Status).toBe(1);
// Transform using class-transformer (as the application would)
const baseBet = (0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, parsedData, {
excludeExtraneousValues: true,
});
// Verify the final result maintains precision
expect(baseBet.id).toBe(11060329315062111n);
expect(baseBet.name).toBe('End-to-End Test');
expect(baseBet.status).toBe(1);
});
it('should demonstrate the precision bug fix', () => {
const problematicNumber = '11060329315062111';
// Show the BUG: Using parseInt before boundary check loses precision
const buggyParseInt = parseInt(problematicNumber, 10);
expect(buggyParseInt).toBe(11060329315062112); // Lost precision!
expect(buggyParseInt.toString()).not.toBe(problematicNumber);
// The old buggy logic would detect it needs BigInt but return wrong value
const wouldBeCorrectlyClassified = buggyParseInt > Number.MAX_SAFE_INTEGER;
expect(wouldBeCorrectlyClassified).toBe(true); // Would correctly identify as large
// But the BUG is that if the old code returned BigInt(buggyParseInt),
// it would create BigInt from the wrong number!
const buggyBigInt = BigInt(buggyParseInt);
expect(buggyBigInt.toString()).toBe('11060329315062112'); // Wrong value!
expect(buggyBigInt.toString()).not.toBe(problematicNumber);
// Show our FIX: String-based boundary check + BigInt from original string
const correctResult = customNumberParser(problematicNumber);
expect(typeof correctResult).toBe('bigint');
expect(correctResult).toBe(11060329315062111n);
expect(correctResult.toString()).toBe(problematicNumber); // Correct value!
});
it('should handle boundary cases correctly with string comparison', () => {
// Test exact MAX_SAFE_INTEGER boundary
expect(customNumberParser('9007199254740991')).toBe(9007199254740991);
expect(typeof customNumberParser('9007199254740991')).toBe('number');
// Test MAX_SAFE_INTEGER + 1 (should be BigInt)
expect(customNumberParser('9007199254740992')).toBe(9007199254740992n);
expect(typeof customNumberParser('9007199254740992')).toBe('bigint');
// Test large positive numbers
expect(customNumberParser('99999999999999999')).toBe(99999999999999999n);
expect(typeof customNumberParser('99999999999999999')).toBe('bigint');
// Test all negative numbers remain as regular numbers (using safe integer for test)
expect(customNumberParser('-1234567890123456')).toBe(-1234567890123456);
expect(typeof customNumberParser('-1234567890123456')).toBe('number');
});
it('should handle Transform decorator with both BigInt and number inputs', () => {
// Test with BigInt input (from lossless-json)
const plainWithBigInt = { Id: 11060329315062111n };
const baseBetFromBigInt = (0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plainWithBigInt, {
excludeExtraneousValues: true,
});
expect(baseBetFromBigInt.id).toBe(11060329315062111n);
// Test with string input (fallback case)
const plainWithString = { Id: '11060329315062111' };
const baseBetFromString = (0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plainWithString, {
excludeExtraneousValues: true,
});
expect(baseBetFromString.id).toBe(11060329315062111n);
// Test with number input (small numbers)
const plainWithNumber = { Id: 123 };
const baseBetFromNumber = (0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plainWithNumber, {
excludeExtraneousValues: true,
});
expect(baseBetFromNumber.id).toBe(123n);
});
it('should handle edge cases in string ID conversion', () => {
// Test string with leading/trailing whitespace
const plainWithWhitespaceString = { Id: ' 123456 ' };
const baseBetFromWhitespaceString = (0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plainWithWhitespaceString, {
excludeExtraneousValues: true,
});
expect(baseBetFromWhitespaceString.id).toBe(123456n);
// Test negative string ID
const plainWithNegativeString = { Id: '-123456' };
const baseBetFromNegativeString = (0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plainWithNegativeString, {
excludeExtraneousValues: true,
});
expect(baseBetFromNegativeString.id).toBe(-123456n);
// Test string with scientific notation (should fail validation)
expect(() => {
const plainWithScientific = { Id: '1e10' };
(0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plainWithScientific, { excludeExtraneousValues: true });
}).toThrow(id_transformation_error_1.IdTransformationError);
try {
const plainWithScientific = { Id: '1e10' };
(0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plainWithScientific, { excludeExtraneousValues: true });
}
catch (error) {
expect(error.message).toContain("Expected integer, got non-numeric string: '1e10'");
}
});
describe('Additional Edge Cases for ID Transformation', () => {
it('should handle zero values correctly', () => {
// Test zero as number
const plainWithZeroNumber = { Id: 0 };
const baseBetFromZeroNumber = (0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plainWithZeroNumber, {
excludeExtraneousValues: true,
});
expect(baseBetFromZeroNumber.id).toBe(0n);
// Test zero as string
const plainWithZeroString = { Id: '0' };
const baseBetFromZeroString = (0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plainWithZeroString, {
excludeExtraneousValues: true,
});
expect(baseBetFromZeroString.id).toBe(0n);
});
it('should handle string numbers with leading zeros', () => {
const plainWithLeadingZeros = { Id: '000123' };
const baseBet = (0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plainWithLeadingZeros, {
excludeExtraneousValues: true,
});
expect(baseBet.id).toBe(123n);
});
it('should reject hexadecimal and octal string formats', () => {
const testCases = ['0x123', '0X123', '0o123', '0O123', '0b101', '0B101'];
testCases.forEach((hexValue) => {
expect(() => {
(0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, { Id: hexValue }, { excludeExtraneousValues: true });
}).toThrow(id_transformation_error_1.IdTransformationError);
});
});
it('should reject float strings', () => {
const testCases = ['123.0', '123.45', '-456.78', '0.0'];
testCases.forEach((floatString) => {
expect(() => {
(0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, { Id: floatString }, { excludeExtraneousValues: true });
}).toThrow(id_transformation_error_1.IdTransformationError);
});
});
it('should handle very large negative numbers', () => {
const veryLargeNegative = '-99999999999999999';
const baseBet = (0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, { Id: veryLargeNegative }, {
excludeExtraneousValues: true,
});
expect(baseBet.id).toBe(-99999999999999999n);
});
it('should reject strings with unicode characters', () => {
const testCases = ['123α', '123', '123\u0000'];
testCases.forEach((unicodeString) => {
expect(() => {
(0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, { Id: unicodeString }, { excludeExtraneousValues: true });
}).toThrow(id_transformation_error_1.IdTransformationError);
});
});
it('should reject array inputs', () => {
const testCases = [[], [123], ['123'], [1, 2, 3]];
testCases.forEach((arrayValue) => {
expect(() => {
(0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, { Id: arrayValue }, { excludeExtraneousValues: true });
}).toThrow(id_transformation_error_1.IdTransformationError);
});
});
it('should handle mixed whitespace in strings', () => {
// Valid cases - should trim and work
const validCases = ['\t123\t', '\n456\n', '\r789\r', ' \t 123 \t '];
validCases.forEach((whitespaceString) => {
const baseBet = (0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, { Id: whitespaceString }, {
excludeExtraneousValues: true,
});
expect(typeof baseBet.id).toBe('bigint');
});
// Invalid cases - internal whitespace should fail
const invalidCases = ['1 23', '1\t23', '1\n23', '12 3'];
invalidCases.forEach((invalidString) => {
expect(() => {
(0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, { Id: invalidString }, { excludeExtraneousValues: true });
}).toThrow(id_transformation_error_1.IdTransformationError);
});
});
it('should handle function inputs', () => {
const functionValue = () => 123;
expect(() => {
(0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, { Id: functionValue }, { excludeExtraneousValues: true });
}).toThrow(id_transformation_error_1.IdTransformationError);
});
it('should handle symbol inputs', () => {
const symbolValue = Symbol('123');
expect(() => {
(0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, { Id: symbolValue }, { excludeExtraneousValues: true });
}).toThrow(id_transformation_error_1.IdTransformationError);
});
});
describe('Date Field Transformation', () => {
it('should transform valid date strings to Date objects', () => {
const plain = {
Id: 123,
LastUpdate: '2024-06-01T12:00:00Z',
};
const baseBet = (0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plain, { excludeExtraneousValues: true });
expect(baseBet.lastUpdate).toBeInstanceOf(Date);
expect(baseBet.lastUpdate?.toISOString()).toBe('2024-06-01T12:00:00.000Z');
});
it('should handle Date objects as input', () => {
const testDate = new Date('2024-06-01T12:00:00Z');
const plain = {
Id: 123,
LastUpdate: testDate,
};
const baseBet = (0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plain, { excludeExtraneousValues: true });
expect(baseBet.lastUpdate).toBeInstanceOf(Date);
expect(baseBet.lastUpdate?.getTime()).toBe(testDate.getTime());
});
it('should handle invalid date strings gracefully', () => {
const plain = {
Id: 123,
LastUpdate: 'invalid-date',
};
const baseBet = (0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plain, { excludeExtraneousValues: true });
expect(baseBet.lastUpdate).toBeInstanceOf(Date);
expect(baseBet.lastUpdate?.toString()).toBe('Invalid Date');
});
it('should handle null/undefined for optional date field', () => {
const plainWithNull = { Id: 123, LastUpdate: null };
const baseBetFromNull = (0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plainWithNull, {
excludeExtraneousValues: true,
});
expect(baseBetFromNull.lastUpdate).toBeNull();
const plainWithUndefined = { Id: 123, LastUpdate: undefined };
const baseBetFromUndefined = (0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plainWithUndefined, {
excludeExtraneousValues: true,
});
expect(baseBetFromUndefined.lastUpdate).toBeUndefined();
});
});
describe('Enum Field Validation', () => {
it('should handle valid enum values for Status', () => {
const validStatuses = [
bet_status_1.BetStatus.NotSet,
bet_status_1.BetStatus.Open,
bet_status_1.BetStatus.Suspended,
bet_status_1.BetStatus.Settled,
];
validStatuses.forEach((status) => {
const plain = { Id: 123, Status: status };
const baseBet = (0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plain, { excludeExtraneousValues: true });
expect(baseBet.status).toBe(status);
});
});
it('should handle valid enum values for Settlement', () => {
const validSettlements = [
settlement_type_1.SettlementType.Cancelled,
settlement_type_1.SettlementType.NotSettled,
settlement_type_1.SettlementType.Loser,
settlement_type_1.SettlementType.Winner,
settlement_type_1.SettlementType.Refund,
settlement_type_1.SettlementType.HalfLost,
settlement_type_1.SettlementType.HalfWon,
];
validSettlements.forEach((settlement) => {
const plain = { Id: 123, Settlement: settlement };
const baseBet = (0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plain, { excludeExtraneousValues: true });
expect(baseBet.settlement).toBe(settlement);
});
});
it('should handle invalid enum values by preserving them', () => {
// class-transformer doesn't validate enum values by default
const plain = { Id: 123, Status: 999, Settlement: -1 };
const baseBet = (0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plain, { excludeExtraneousValues: true });
expect(baseBet.status).toBe(999);
expect(baseBet.settlement).toBe(-1);
});
});
describe('Default Value Behavior', () => {
it('should handle IsChanged field when not provided', () => {
const plain = { Id: 123 };
const baseBet = (0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plain, { excludeExtraneousValues: true });
expect(baseBet.isChanged).toBeUndefined();
});
it('should handle explicit IsChanged value', () => {
const plain = { Id: 123, IsChanged: 5 };
const baseBet = (0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plain, { excludeExtraneousValues: true });
expect(baseBet.isChanged).toBe(5);
});
it('should handle IsChanged with default constructor behavior', () => {
// When creating new instance directly, default value applies
const baseBet = new base_bet_1.BaseBet();
expect(baseBet.isChanged).toBe(-1);
});
});
describe('Error Handling for Required ID Field', () => {
it('should throw IdTransformationError for null ID', () => {
const plainWithNullId = { Id: null };
expect(() => {
(0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plainWithNullId, { excludeExtraneousValues: true });
}).toThrow(id_transformation_error_1.IdTransformationError);
});
it('should throw IdTransformationError for undefined ID', () => {
const plainWithUndefinedId = { Id: undefined };
expect(() => {
(0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plainWithUndefinedId, { excludeExtraneousValues: true });
}).toThrow(id_transformation_error_1.IdTransformationError);
});
it('should throw IdTransformationError for empty string ID', () => {
const plainWithEmptyId = { Id: '' };
expect(() => {
(0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plainWithEmptyId, { excludeExtraneousValues: true });
}).toThrow(id_transformation_error_1.IdTransformationError);
});
it('should throw IdTransformationError for whitespace-only string ID', () => {
const plainWithWhitespaceId = { Id: ' ' };
expect(() => {
(0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plainWithWhitespaceId, { excludeExtraneousValues: true });
}).toThrow(id_transformation_error_1.IdTransformationError);
});
it('should throw IdTransformationError for non-numeric string ID', () => {
const plainWithInvalidId = { Id: 'not-a-number' };
expect(() => {
(0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plainWithInvalidId, { excludeExtraneousValues: true });
}).toThrow(id_transformation_error_1.IdTransformationError);
});
it('should throw IdTransformationError for decimal number ID', () => {
const plainWithDecimalId = { Id: 123.45 };
expect(() => {
(0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plainWithDecimalId, { excludeExtraneousValues: true });
}).toThrow(id_transformation_error_1.IdTransformationError);
});
it('should throw IdTransformationError for NaN ID', () => {
const plainWithNaNId = { Id: NaN };
expect(() => {
(0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plainWithNaNId, { excludeExtraneousValues: true });
}).toThrow(id_transformation_error_1.IdTransformationError);
});
it('should throw IdTransformationError for Infinity ID', () => {
const plainWithInfinityId = { Id: Infinity };
expect(() => {
(0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plainWithInfinityId, { excludeExtraneousValues: true });
}).toThrow(id_transformation_error_1.IdTransformationError);
});
it('should throw IdTransformationError for boolean ID', () => {
const plainWithBooleanId = { Id: true };
expect(() => {
(0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plainWithBooleanId, { excludeExtraneousValues: true });
}).toThrow(id_transformation_error_1.IdTransformationError);
});
it('should throw IdTransformationError for object ID', () => {
const plainWithObjectId = { Id: {} };
expect(() => {
(0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plainWithObjectId, { excludeExtraneousValues: true });
}).toThrow(id_transformation_error_1.IdTransformationError);
});
it('should provide detailed error information in IdTransformationError', () => {
const plainWithInvalidId = { Id: 123.45 };
try {
(0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plainWithInvalidId, { excludeExtraneousValues: true });
throw new Error('Expected IdTransformationError to be thrown');
}
catch (error) {
expect(error).toBeInstanceOf(id_transformation_error_1.IdTransformationError);
expect(error.fieldName).toBe('Id');
expect(error.originalValue).toBe(123.45);
expect(error.message).toContain("Invalid ID transformation for field 'Id'");
expect(error.message).toContain('decimal number');
}
});
it('should provide appropriate error message for different invalid types', () => {
const testCases = [
{ value: 'abc', expectedMessage: 'non-numeric string' },
{ value: NaN, expectedMessage: 'decimal number' },
{ value: Infinity, expectedMessage: 'decimal number' },
{ value: 123.45, expectedMessage: 'decimal number' },
{ value: true, expectedMessage: 'Invalid ID type' },
{ value: {}, expectedMessage: 'Invalid ID type' },
];
testCases.forEach(({ value, expectedMessage }) => {
try {
(0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, { Id: value }, { excludeExtraneousValues: true });
throw new Error(`Expected IdTransformationError to be thrown for value: ${value}`);
}
catch (error) {
expect(error).toBeInstanceOf(id_transformation_error_1.IdTransformationError);
expect(error.message).toContain(expectedMessage);
}
});
});
it('should handle string with scientific notation as invalid', () => {
const plainWithScientific = { Id: '1e10' };
expect(() => {
(0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plainWithScientific, { excludeExtraneousValues: true });
}).toThrow(id_transformation_error_1.IdTransformationError);
try {
(0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plainWithScientific, { excludeExtraneousValues: true });
}
catch (error) {
expect(error.message).toContain('non-numeric string');
}
});
});
describe('Backward Compatibility', () => {
it('should maintain backward compatibility for valid inputs', () => {
const validInputs = [
{ Id: 1 },
{ Id: '123' },
{ Id: 9007199254740991 }, // MAX_SAFE_INTEGER
{ Id: '9007199254740992' }, // MAX_SAFE_INTEGER + 1 as string
{ Id: 123n }, // BigInt input
];
validInputs.forEach((input) => {
expect(() => {
const result = (0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, input, { excludeExtraneousValues: true });
expect(typeof result.id).toBe('bigint');
}).not.toThrow();
});
});
it('should handle missing Id property by throwing error', () => {
const plainWithoutId = { Name: 'Test Bet' };
expect(() => {
(0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, plainWithoutId, { excludeExtraneousValues: true });
}).toThrow(id_transformation_error_1.IdTransformationError);
});
});
describe('Complex Scenarios', () => {
it('should handle complete bet data with all fields', () => {
const completeData = {
Id: '999999999999999999',
Name: 'Complete Bet',
Line: '1.5',
BaseLine: '1.0',
Status: bet_status_1.BetStatus.Open,
StartPrice: '2.50',
Price: '2.75',
PriceVolume: '1000.00',
Settlement: settlement_type_1.SettlementType.Winner,
SuspensionReason: 5,
LastUpdate: '2024-06-01T12:00:00Z',
PriceIN: '2.75',
PriceUS: '+175',
PriceUK: '7/4',
PriceMA: '1.75',
PriceHK: '1.75',
IsChanged: 1,
Probability: 0.36,
ParticipantId: 789,
PlayerName: 'Test Player',
};
const baseBet = (0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, completeData, { excludeExtraneousValues: true });
expect(baseBet.id).toBe(999999999999999999n);
expect(baseBet.name).toBe('Complete Bet');
expect(baseBet.line).toBe('1.5');
expect(baseBet.baseLine).toBe('1.0');
expect(baseBet.status).toBe(bet_status_1.BetStatus.Open);
expect(baseBet.startPrice).toBe('2.50');
expect(baseBet.price).toBe('2.75');
expect(baseBet.priceVolume).toBe('1000.00');
expect(baseBet.settlement).toBe(settlement_type_1.SettlementType.Winner);
expect(baseBet.suspensionReason).toBe(5);
expect(baseBet.lastUpdate).toBeInstanceOf(Date);
expect(baseBet.priceIN).toBe('2.75');
expect(baseBet.priceUS).toBe('+175');
expect(baseBet.priceUK).toBe('7/4');
expect(baseBet.priceMA).toBe('1.75');
expect(baseBet.priceHK).toBe('1.75');
expect(baseBet.isChanged).toBe(1);
expect(baseBet.probability).toBe(0.36);
expect(baseBet.participantId).toBe(789);
expect(baseBet.playerName).toBe('Test Player');
});
it('should handle partial data gracefully', () => {
const partialData = {
Id: 12345,
Name: 'Partial Bet',
Status: bet_status_1.BetStatus.Suspended,
};
const baseBet = (0, class_transformer_1.plainToInstance)(base_bet_1.BaseBet, partialData, { excludeExtraneousValues: true });
expect(baseBet.id).toBe(12345n);
expect(baseBet.name).toBe('Partial Bet');
expect(baseBet.status).toBe(bet_status_1.BetStatus.Suspended);
expect(baseBet.isChanged).toBeUndefined(); // Not provided in partial data
// All other fields should be undefined
expect(baseBet.line).toBeUndefined();
expect(baseBet.price).toBeUndefined();
expect(baseBet.lastUpdate).toBeUndefined();
});
});
});
//# sourceMappingURL=base-bet.spec.js.map