import { Prize, PrizeType } from '@core/payments/domain/entities/Prize'; import { describe, expect, it } from 'vitest'; describe('payments/domain/entities/Prize', () => { describe('PrizeType enum', () => { it('should have correct prize type values', () => { expect(PrizeType.CASH).toBe('cash'); expect(PrizeType.MERCHANDISE).toBe('merchandise'); expect(PrizeType.OTHER).toBe('other'); }); }); describe('Prize interface', () => { it('should have all required properties', () => { const prize: Prize = { id: 'prize-123', leagueId: 'league-456', seasonId: 'season-789', position: 1, name: 'Champion Prize', amount: 1000, type: PrizeType.CASH, awarded: false, createdAt: new Date('2024-01-01'), }; expect(prize.id).toBe('prize-123'); expect(prize.leagueId).toBe('league-456'); expect(prize.seasonId).toBe('season-789'); expect(prize.position).toBe(1); expect(prize.name).toBe('Champion Prize'); expect(prize.amount).toBe(1000); expect(prize.type).toBe(PrizeType.CASH); expect(prize.awarded).toBe(false); expect(prize.createdAt).toEqual(new Date('2024-01-01')); }); it('should support optional description property', () => { const prize: Prize = { id: 'prize-123', leagueId: 'league-456', seasonId: 'season-789', position: 1, name: 'Champion Prize', amount: 1000, type: PrizeType.CASH, description: 'Awarded to the champion of the season', awarded: false, createdAt: new Date('2024-01-01'), }; expect(prize.description).toBe('Awarded to the champion of the season'); }); it('should support optional awardedTo and awardedAt properties', () => { const prize: Prize = { id: 'prize-123', leagueId: 'league-456', seasonId: 'season-789', position: 1, name: 'Champion Prize', amount: 1000, type: PrizeType.CASH, awarded: true, awardedTo: 'driver-999', awardedAt: new Date('2024-06-01'), createdAt: new Date('2024-01-01'), }; expect(prize.awardedTo).toBe('driver-999'); expect(prize.awardedAt).toEqual(new Date('2024-06-01')); }); }); describe('Prize.rehydrate', () => { it('should rehydrate a Prize from props', () => { const props: Prize = { id: 'prize-123', leagueId: 'league-456', seasonId: 'season-789', position: 1, name: 'Champion Prize', amount: 1000, type: PrizeType.CASH, awarded: false, createdAt: new Date('2024-01-01'), }; const rehydrated = Prize.rehydrate(props); expect(rehydrated).toEqual(props); expect(rehydrated.id).toBe('prize-123'); expect(rehydrated.leagueId).toBe('league-456'); expect(rehydrated.seasonId).toBe('season-789'); expect(rehydrated.position).toBe(1); expect(rehydrated.name).toBe('Champion Prize'); expect(rehydrated.amount).toBe(1000); expect(rehydrated.type).toBe(PrizeType.CASH); expect(rehydrated.awarded).toBe(false); expect(rehydrated.createdAt).toEqual(new Date('2024-01-01')); }); it('should preserve optional description when rehydrating', () => { const props: Prize = { id: 'prize-123', leagueId: 'league-456', seasonId: 'season-789', position: 1, name: 'Champion Prize', amount: 1000, type: PrizeType.CASH, description: 'Awarded to the champion of the season', awarded: false, createdAt: new Date('2024-01-01'), }; const rehydrated = Prize.rehydrate(props); expect(rehydrated.description).toBe('Awarded to the champion of the season'); }); it('should preserve optional awardedTo and awardedAt when rehydrating', () => { const props: Prize = { id: 'prize-123', leagueId: 'league-456', seasonId: 'season-789', position: 1, name: 'Champion Prize', amount: 1000, type: PrizeType.CASH, awarded: true, awardedTo: 'driver-999', awardedAt: new Date('2024-06-01'), createdAt: new Date('2024-01-01'), }; const rehydrated = Prize.rehydrate(props); expect(rehydrated.awardedTo).toBe('driver-999'); expect(rehydrated.awardedAt).toEqual(new Date('2024-06-01')); }); }); describe('Business rules and invariants', () => { it('should support different prize types', () => { const cashPrize: Prize = { id: 'prize-123', leagueId: 'league-456', seasonId: 'season-789', position: 1, name: 'Champion Prize', amount: 1000, type: PrizeType.CASH, awarded: false, createdAt: new Date('2024-01-01'), }; const merchandisePrize: Prize = { id: 'prize-124', leagueId: 'league-456', seasonId: 'season-789', position: 2, name: 'T-Shirt', amount: 50, type: PrizeType.MERCHANDISE, awarded: false, createdAt: new Date('2024-01-01'), }; const otherPrize: Prize = { id: 'prize-125', leagueId: 'league-456', seasonId: 'season-789', position: 3, name: 'Special Recognition', amount: 0, type: PrizeType.OTHER, awarded: false, createdAt: new Date('2024-01-01'), }; expect(cashPrize.type).toBe(PrizeType.CASH); expect(merchandisePrize.type).toBe(PrizeType.MERCHANDISE); expect(otherPrize.type).toBe(PrizeType.OTHER); }); it('should handle awarded and unawarded prizes', () => { const unawardedPrize: Prize = { id: 'prize-123', leagueId: 'league-456', seasonId: 'season-789', position: 1, name: 'Champion Prize', amount: 1000, type: PrizeType.CASH, awarded: false, createdAt: new Date('2024-01-01'), }; const awardedPrize: Prize = { id: 'prize-124', leagueId: 'league-456', seasonId: 'season-789', position: 1, name: 'Champion Prize', amount: 1000, type: PrizeType.CASH, awarded: true, awardedTo: 'driver-999', awardedAt: new Date('2024-06-01'), createdAt: new Date('2024-01-01'), }; expect(unawardedPrize.awarded).toBe(false); expect(unawardedPrize.awardedTo).toBeUndefined(); expect(unawardedPrize.awardedAt).toBeUndefined(); expect(awardedPrize.awarded).toBe(true); expect(awardedPrize.awardedTo).toBe('driver-999'); expect(awardedPrize.awardedAt).toEqual(new Date('2024-06-01')); }); it('should handle different positions', () => { const firstPlacePrize: Prize = { id: 'prize-123', leagueId: 'league-456', seasonId: 'season-789', position: 1, name: 'Champion Prize', amount: 1000, type: PrizeType.CASH, awarded: false, createdAt: new Date('2024-01-01'), }; const secondPlacePrize: Prize = { id: 'prize-124', leagueId: 'league-456', seasonId: 'season-789', position: 2, name: 'Runner-Up Prize', amount: 500, type: PrizeType.CASH, awarded: false, createdAt: new Date('2024-01-01'), }; const thirdPlacePrize: Prize = { id: 'prize-125', leagueId: 'league-456', seasonId: 'season-789', position: 3, name: 'Third Place Prize', amount: 250, type: PrizeType.CASH, awarded: false, createdAt: new Date('2024-01-01'), }; expect(firstPlacePrize.position).toBe(1); expect(secondPlacePrize.position).toBe(2); expect(thirdPlacePrize.position).toBe(3); }); it('should handle zero and negative amounts', () => { const zeroPrize: Prize = { id: 'prize-123', leagueId: 'league-456', seasonId: 'season-789', position: 1, name: 'Participation Prize', amount: 0, type: PrizeType.OTHER, awarded: false, createdAt: new Date('2024-01-01'), }; expect(zeroPrize.amount).toBe(0); }); it('should handle different league and season combinations', () => { const leagueOnlyPrize: Prize = { id: 'prize-123', leagueId: 'league-456', seasonId: 'season-789', position: 1, name: 'Champion Prize', amount: 1000, type: PrizeType.CASH, awarded: false, createdAt: new Date('2024-01-01'), }; expect(leagueOnlyPrize.leagueId).toBe('league-456'); expect(leagueOnlyPrize.seasonId).toBe('season-789'); }); }); });