Files
gridpilot.gg/core/racing/domain/entities/prize/Prize.test.ts
2025-12-17 00:33:13 +01:00

303 lines
8.6 KiB
TypeScript

import { Prize } from './Prize';
import { Money } from '../../value-objects/Money';
import { RacingDomainValidationError, RacingDomainInvariantError } from '../../errors/RacingDomainError';
describe('Prize', () => {
describe('create', () => {
it('should create a prize with required fields', () => {
const amount = Money.create(1000, 'USD');
const prize = Prize.create({
id: 'prize-1',
seasonId: 'season-1',
position: 1,
amount,
});
expect(prize.id.toString()).toBe('prize-1');
expect(prize.seasonId.toString()).toBe('season-1');
expect(prize.position.toNumber()).toBe(1);
expect(prize.amount).toEqual(amount);
expect(prize.driverId).toBeUndefined();
expect(prize.status.toString()).toBe('pending');
expect(prize.awardedAt).toBeUndefined();
expect(prize.paidAt).toBeUndefined();
expect(prize.description).toBeUndefined();
});
it('should create a prize with all fields', () => {
const amount = Money.create(2000, 'USD');
const createdAt = new Date('2023-01-01');
const awardedAt = new Date('2023-01-02');
const paidAt = new Date('2023-01-03');
const prize = Prize.create({
id: 'prize-1',
seasonId: 'season-1',
position: 2,
amount,
driverId: 'driver-1',
status: 'paid',
createdAt,
awardedAt,
paidAt,
description: 'First place prize',
});
expect(prize.id.toString()).toBe('prize-1');
expect(prize.seasonId.toString()).toBe('season-1');
expect(prize.position.toNumber()).toBe(2);
expect(prize.amount).toEqual(amount);
expect(prize.driverId!.toString()).toBe('driver-1');
expect(prize.status.toString()).toBe('paid');
expect(prize.createdAt).toEqual(createdAt);
expect(prize.awardedAt).toEqual(awardedAt);
expect(prize.paidAt).toEqual(paidAt);
expect(prize.description).toBe('First place prize');
});
it('should throw error for invalid id', () => {
const amount = Money.create(1000, 'USD');
expect(() => Prize.create({
id: '',
seasonId: 'season-1',
position: 1,
amount,
})).toThrow(RacingDomainValidationError);
});
it('should throw error for invalid seasonId', () => {
const amount = Money.create(1000, 'USD');
expect(() => Prize.create({
id: 'prize-1',
seasonId: '',
position: 1,
amount,
})).toThrow(RacingDomainValidationError);
});
it('should throw error for invalid position', () => {
const amount = Money.create(1000, 'USD');
expect(() => Prize.create({
id: 'prize-1',
seasonId: 'season-1',
position: 0,
amount,
})).toThrow(RacingDomainValidationError);
});
it('should throw error for non-integer position', () => {
const amount = Money.create(1000, 'USD');
expect(() => Prize.create({
id: 'prize-1',
seasonId: 'season-1',
position: 1.5,
amount,
})).toThrow(RacingDomainValidationError);
});
it('should throw error for zero amount', () => {
const amount = Money.create(0, 'USD');
expect(() => Prize.create({
id: 'prize-1',
seasonId: 'season-1',
position: 1,
amount,
})).toThrow(RacingDomainValidationError);
});
});
describe('awardTo', () => {
it('should award prize to a driver', () => {
const amount = Money.create(1000, 'USD');
const prize = Prize.create({
id: 'prize-1',
seasonId: 'season-1',
position: 1,
amount,
});
const awarded = prize.awardTo('driver-1');
expect(awarded.driverId!.toString()).toBe('driver-1');
expect(awarded.status.toString()).toBe('awarded');
expect(awarded.awardedAt).toBeInstanceOf(Date);
});
it('should throw error for empty driverId', () => {
const amount = Money.create(1000, 'USD');
const prize = Prize.create({
id: 'prize-1',
seasonId: 'season-1',
position: 1,
amount,
});
expect(() => prize.awardTo('')).toThrow(RacingDomainValidationError);
});
it('should throw error if not pending', () => {
const amount = Money.create(1000, 'USD');
const prize = Prize.create({
id: 'prize-1',
seasonId: 'season-1',
position: 1,
amount,
status: 'awarded',
});
expect(() => prize.awardTo('driver-1')).toThrow(RacingDomainInvariantError);
});
});
describe('markAsPaid', () => {
it('should mark prize as paid', () => {
const amount = Money.create(1000, 'USD');
const prize = Prize.create({
id: 'prize-1',
seasonId: 'season-1',
position: 1,
amount,
driverId: 'driver-1',
status: 'awarded',
});
const paid = prize.markAsPaid();
expect(paid.status.toString()).toBe('paid');
expect(paid.paidAt).toBeInstanceOf(Date);
});
it('should throw error if not awarded', () => {
const amount = Money.create(1000, 'USD');
const prize = Prize.create({
id: 'prize-1',
seasonId: 'season-1',
position: 1,
amount,
});
expect(() => prize.markAsPaid()).toThrow(RacingDomainInvariantError);
});
it('should throw error if no driverId', () => {
const amount = Money.create(1000, 'USD');
const prize = Prize.create({
id: 'prize-1',
seasonId: 'season-1',
position: 1,
amount,
status: 'awarded',
});
expect(() => prize.markAsPaid()).toThrow(RacingDomainInvariantError);
});
});
describe('cancel', () => {
it('should cancel pending prize', () => {
const amount = Money.create(1000, 'USD');
const prize = Prize.create({
id: 'prize-1',
seasonId: 'season-1',
position: 1,
amount,
});
const cancelled = prize.cancel();
expect(cancelled.status.toString()).toBe('cancelled');
});
it('should cancel awarded prize', () => {
const amount = Money.create(1000, 'USD');
const prize = Prize.create({
id: 'prize-1',
seasonId: 'season-1',
position: 1,
amount,
driverId: 'driver-1',
status: 'awarded',
});
const cancelled = prize.cancel();
expect(cancelled.status.toString()).toBe('cancelled');
});
it('should throw error if paid', () => {
const amount = Money.create(1000, 'USD');
const prize = Prize.create({
id: 'prize-1',
seasonId: 'season-1',
position: 1,
amount,
driverId: 'driver-1',
status: 'paid',
});
expect(() => prize.cancel()).toThrow(RacingDomainInvariantError);
});
});
describe('isPending', () => {
it('should return true for pending status', () => {
const amount = Money.create(1000, 'USD');
const prize = Prize.create({
id: 'prize-1',
seasonId: 'season-1',
position: 1,
amount,
});
expect(prize.isPending()).toBe(true);
});
it('should return false for awarded status', () => {
const amount = Money.create(1000, 'USD');
const prize = Prize.create({
id: 'prize-1',
seasonId: 'season-1',
position: 1,
amount,
status: 'awarded',
});
expect(prize.isPending()).toBe(false);
});
});
describe('isAwarded', () => {
it('should return true for awarded status', () => {
const amount = Money.create(1000, 'USD');
const prize = Prize.create({
id: 'prize-1',
seasonId: 'season-1',
position: 1,
amount,
status: 'awarded',
});
expect(prize.isAwarded()).toBe(true);
});
it('should return false for pending status', () => {
const amount = Money.create(1000, 'USD');
const prize = Prize.create({
id: 'prize-1',
seasonId: 'season-1',
position: 1,
amount,
});
expect(prize.isAwarded()).toBe(false);
});
});
describe('isPaid', () => {
it('should return true for paid status', () => {
const amount = Money.create(1000, 'USD');
const prize = Prize.create({
id: 'prize-1',
seasonId: 'season-1',
position: 1,
amount,
status: 'paid',
});
expect(prize.isPaid()).toBe(true);
});
it('should return false for awarded status', () => {
const amount = Money.create(1000, 'USD');
const prize = Prize.create({
id: 'prize-1',
seasonId: 'season-1',
position: 1,
amount,
status: 'awarded',
});
expect(prize.isPaid()).toBe(false);
});
});
});