231 lines
6.9 KiB
TypeScript
231 lines
6.9 KiB
TypeScript
import { RacingDomainInvariantError, RacingDomainValidationError } from '../errors/RacingDomainError';
|
|
import { Penalty } from './Penalty';
|
|
|
|
describe('Penalty', () => {
|
|
describe('create', () => {
|
|
it('should create a penalty with required fields', () => {
|
|
const penalty = Penalty.create({
|
|
id: 'penalty-1',
|
|
leagueId: 'league-1',
|
|
raceId: 'race-1',
|
|
driverId: 'driver-1',
|
|
type: 'time_penalty',
|
|
value: 5,
|
|
reason: 'Speeding',
|
|
issuedBy: 'steward-1',
|
|
});
|
|
|
|
expect(penalty.id.toString()).toBe('penalty-1');
|
|
expect(penalty.leagueId).toBe('league-1');
|
|
expect(penalty.raceId).toBe('race-1');
|
|
expect(penalty.driverId).toBe('driver-1');
|
|
expect(penalty.type).toBe('time_penalty');
|
|
expect(penalty.value).toBe(5);
|
|
expect(penalty.reason).toBe('Speeding');
|
|
expect(penalty.issuedBy).toBe('steward-1');
|
|
expect(penalty.status).toBe('pending');
|
|
expect(penalty.appliedAt).toBeUndefined();
|
|
expect(penalty.notes).toBeUndefined();
|
|
});
|
|
|
|
it('should create a penalty with all fields', () => {
|
|
const issuedAt = new Date('2023-01-01');
|
|
const appliedAt = new Date('2023-01-02');
|
|
const penalty = Penalty.create({
|
|
id: 'penalty-1',
|
|
leagueId: 'league-1',
|
|
raceId: 'race-1',
|
|
driverId: 'driver-1',
|
|
type: 'disqualification',
|
|
reason: 'Unsafe driving',
|
|
protestId: 'protest-1',
|
|
issuedBy: 'steward-1',
|
|
status: 'applied',
|
|
issuedAt,
|
|
appliedAt,
|
|
notes: 'Applied after review',
|
|
});
|
|
|
|
expect(penalty.id.toString()).toBe('penalty-1');
|
|
expect(penalty.type).toBe('disqualification');
|
|
expect(penalty.value).toBeUndefined();
|
|
expect(penalty.protestId).toBe('protest-1');
|
|
expect(penalty.status).toBe('applied');
|
|
expect(penalty.issuedAt).toEqual(issuedAt);
|
|
expect(penalty.appliedAt).toEqual(appliedAt);
|
|
expect(penalty.notes).toBe('Applied after review');
|
|
});
|
|
|
|
it('should throw error for invalid id', () => {
|
|
expect(() => Penalty.create({
|
|
id: '',
|
|
leagueId: 'league-1',
|
|
raceId: 'race-1',
|
|
driverId: 'driver-1',
|
|
type: 'time_penalty',
|
|
value: 5,
|
|
reason: 'Speeding',
|
|
issuedBy: 'steward-1',
|
|
})).toThrow(RacingDomainValidationError);
|
|
});
|
|
|
|
it('should throw error for invalid type', () => {
|
|
expect(() => Penalty.create({
|
|
id: 'penalty-1',
|
|
leagueId: 'league-1',
|
|
raceId: 'race-1',
|
|
driverId: 'driver-1',
|
|
type: 'invalid_type',
|
|
value: 5,
|
|
reason: 'Speeding',
|
|
issuedBy: 'steward-1',
|
|
})).toThrow(RacingDomainValidationError);
|
|
});
|
|
|
|
it('should throw error for missing value on time_penalty', () => {
|
|
expect(() => Penalty.create({
|
|
id: 'penalty-1',
|
|
leagueId: 'league-1',
|
|
raceId: 'race-1',
|
|
driverId: 'driver-1',
|
|
type: 'time_penalty',
|
|
reason: 'Speeding',
|
|
issuedBy: 'steward-1',
|
|
})).toThrow(RacingDomainValidationError);
|
|
});
|
|
|
|
it('should throw error for zero value', () => {
|
|
expect(() => Penalty.create({
|
|
id: 'penalty-1',
|
|
leagueId: 'league-1',
|
|
raceId: 'race-1',
|
|
driverId: 'driver-1',
|
|
type: 'time_penalty',
|
|
value: 0,
|
|
reason: 'Speeding',
|
|
issuedBy: 'steward-1',
|
|
})).toThrow(RacingDomainValidationError);
|
|
});
|
|
});
|
|
|
|
describe('isPending', () => {
|
|
it('should return true for pending status', () => {
|
|
const penalty = Penalty.create({
|
|
id: 'penalty-1',
|
|
leagueId: 'league-1',
|
|
raceId: 'race-1',
|
|
driverId: 'driver-1',
|
|
type: 'warning',
|
|
reason: 'Warning',
|
|
issuedBy: 'steward-1',
|
|
});
|
|
expect(penalty.isPending()).toBe(true);
|
|
});
|
|
|
|
it('should return false for applied status', () => {
|
|
const penalty = Penalty.create({
|
|
id: 'penalty-1',
|
|
leagueId: 'league-1',
|
|
raceId: 'race-1',
|
|
driverId: 'driver-1',
|
|
type: 'warning',
|
|
reason: 'Warning',
|
|
issuedBy: 'steward-1',
|
|
status: 'applied',
|
|
});
|
|
expect(penalty.isPending()).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('markAsApplied', () => {
|
|
it('should mark penalty as applied', () => {
|
|
const penalty = Penalty.create({
|
|
id: 'penalty-1',
|
|
leagueId: 'league-1',
|
|
raceId: 'race-1',
|
|
driverId: 'driver-1',
|
|
type: 'warning',
|
|
reason: 'Warning',
|
|
issuedBy: 'steward-1',
|
|
});
|
|
const applied = penalty.markAsApplied('Applied successfully');
|
|
expect(applied.status).toBe('applied');
|
|
expect(applied.appliedAt).toBeInstanceOf(Date);
|
|
expect(applied.notes).toBe('Applied successfully');
|
|
});
|
|
|
|
it('should throw error if already applied', () => {
|
|
const penalty = Penalty.create({
|
|
id: 'penalty-1',
|
|
leagueId: 'league-1',
|
|
raceId: 'race-1',
|
|
driverId: 'driver-1',
|
|
type: 'warning',
|
|
reason: 'Warning',
|
|
issuedBy: 'steward-1',
|
|
status: 'applied',
|
|
});
|
|
expect(() => penalty.markAsApplied()).toThrow(RacingDomainInvariantError);
|
|
});
|
|
});
|
|
|
|
describe('overturn', () => {
|
|
it('should overturn the penalty', () => {
|
|
const penalty = Penalty.create({
|
|
id: 'penalty-1',
|
|
leagueId: 'league-1',
|
|
raceId: 'race-1',
|
|
driverId: 'driver-1',
|
|
type: 'warning',
|
|
reason: 'Warning',
|
|
issuedBy: 'steward-1',
|
|
});
|
|
const overturned = penalty.overturn('Appealed successfully');
|
|
expect(overturned.status).toBe('overturned');
|
|
expect(overturned.notes).toBe('Appealed successfully');
|
|
});
|
|
|
|
it('should throw error if already overturned', () => {
|
|
const penalty = Penalty.create({
|
|
id: 'penalty-1',
|
|
leagueId: 'league-1',
|
|
raceId: 'race-1',
|
|
driverId: 'driver-1',
|
|
type: 'warning',
|
|
reason: 'Warning',
|
|
issuedBy: 'steward-1',
|
|
status: 'overturned',
|
|
});
|
|
expect(() => penalty.overturn('Reason')).toThrow(RacingDomainInvariantError);
|
|
});
|
|
});
|
|
|
|
describe('getDescription', () => {
|
|
it('should return description for time_penalty', () => {
|
|
const penalty = Penalty.create({
|
|
id: 'penalty-1',
|
|
leagueId: 'league-1',
|
|
raceId: 'race-1',
|
|
driverId: 'driver-1',
|
|
type: 'time_penalty',
|
|
value: 5,
|
|
reason: 'Speeding',
|
|
issuedBy: 'steward-1',
|
|
});
|
|
expect(penalty.getDescription()).toBe('+5s time penalty');
|
|
});
|
|
|
|
it('should return description for disqualification', () => {
|
|
const penalty = Penalty.create({
|
|
id: 'penalty-1',
|
|
leagueId: 'league-1',
|
|
raceId: 'race-1',
|
|
driverId: 'driver-1',
|
|
type: 'disqualification',
|
|
reason: 'Unsafe',
|
|
issuedBy: 'steward-1',
|
|
});
|
|
expect(penalty.getDescription()).toBe('Disqualified from race');
|
|
});
|
|
});
|
|
}); |