303 lines
8.6 KiB
TypeScript
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);
|
|
});
|
|
});
|
|
}); |