import { SponsorshipRequest, SponsorableEntityType, SponsorshipRequestProps } from './SponsorshipRequest'; import { SponsorshipTier } from './season/SeasonSponsorship'; import { Money } from '../value-objects/Money'; import { RacingDomainValidationError, RacingDomainInvariantError } from '../errors/RacingDomainError'; describe('SponsorshipRequest', () => { const validMoney = Money.create(1000, 'USD'); const validProps = { id: 'request-123', sponsorId: 'sponsor-456', entityType: 'driver', entityId: 'driver-789', tier: 'main', offeredAmount: validMoney, }; describe('create', () => { it('should create a SponsorshipRequest with valid props', () => { const request = SponsorshipRequest.create(validProps); expect(request.id).toBe('request-123'); expect(request.sponsorId).toBe('sponsor-456'); expect(request.entityType).toBe('driver'); expect(request.entityId).toBe('driver-789'); expect(request.tier).toBe('main'); expect(request.offeredAmount).toEqual(validMoney); expect(request.status).toBe('pending'); expect(request.createdAt).toBeInstanceOf(Date); }); it('should use provided createdAt and status', () => { const customDate = new Date('2023-01-01'); const request = SponsorshipRequest.create({ ...validProps, createdAt: customDate, status: 'accepted', }); expect(request.createdAt).toBe(customDate); expect(request.status).toBe('accepted'); }); it('should throw for invalid id', () => { expect(() => SponsorshipRequest.create({ ...validProps, id: '' })).toThrow(RacingDomainValidationError); }); it('should throw for invalid sponsorId', () => { expect(() => SponsorshipRequest.create({ ...validProps, sponsorId: '' })).toThrow(RacingDomainValidationError); }); it('should throw for invalid entityId', () => { expect(() => SponsorshipRequest.create({ ...validProps, entityId: '' })).toThrow(RacingDomainValidationError); }); it('should throw for zero offeredAmount', () => { const zeroMoney = Money.create(0, 'USD'); expect(() => SponsorshipRequest.create({ ...validProps, offeredAmount: zeroMoney })).toThrow(RacingDomainValidationError); }); it('should throw for negative offeredAmount', () => { expect(() => Money.create(-100, 'USD')).toThrow(RacingDomainValidationError); }); }); describe('accept', () => { it('should accept a pending request', () => { const request = SponsorshipRequest.create(validProps); const accepted = request.accept('responder-123'); expect(accepted.status).toBe('accepted'); expect(accepted.respondedAt).toBeInstanceOf(Date); expect(accepted.respondedBy).toBe('responder-123'); }); it('should throw for non-pending request', () => { const acceptedRequest = SponsorshipRequest.create({ ...validProps, status: 'accepted' }); expect(() => acceptedRequest.accept('responder-123')).toThrow(RacingDomainInvariantError); }); it('should throw for empty respondedBy', () => { const request = SponsorshipRequest.create(validProps); expect(() => request.accept('')).toThrow(RacingDomainValidationError); }); }); describe('reject', () => { it('should reject a pending request with reason', () => { const request = SponsorshipRequest.create(validProps); const rejected = request.reject('responder-123', 'Not interested'); expect(rejected.status).toBe('rejected'); expect(rejected.respondedAt).toBeInstanceOf(Date); expect(rejected.respondedBy).toBe('responder-123'); expect(rejected.rejectionReason).toBe('Not interested'); }); it('should reject without reason', () => { const request = SponsorshipRequest.create(validProps); const rejected = request.reject('responder-123'); expect(rejected.status).toBe('rejected'); expect(rejected.rejectionReason).toBeUndefined(); }); it('should throw for non-pending request', () => { const rejectedRequest = SponsorshipRequest.create({ ...validProps, status: 'rejected' }); expect(() => rejectedRequest.reject('responder-123')).toThrow(RacingDomainInvariantError); }); }); describe('withdraw', () => { it('should withdraw a pending request', () => { const request = SponsorshipRequest.create(validProps); const withdrawn = request.withdraw(); expect(withdrawn.status).toBe('withdrawn'); expect(withdrawn.respondedAt).toBeInstanceOf(Date); }); it('should throw for non-pending request', () => { const acceptedRequest = SponsorshipRequest.create({ ...validProps, status: 'accepted' }); expect(() => acceptedRequest.withdraw()).toThrow(RacingDomainInvariantError); }); }); describe('isPending', () => { it('should return true for pending status', () => { const request = SponsorshipRequest.create(validProps); expect(request.isPending()).toBe(true); }); it('should return false for non-pending status', () => { const acceptedRequest = SponsorshipRequest.create({ ...validProps, status: 'accepted' }); expect(acceptedRequest.isPending()).toBe(false); }); }); describe('isAccepted', () => { it('should return true for accepted status', () => { const acceptedRequest = SponsorshipRequest.create({ ...validProps, status: 'accepted' }); expect(acceptedRequest.isAccepted()).toBe(true); }); it('should return false for non-accepted status', () => { const request = SponsorshipRequest.create(validProps); expect(request.isAccepted()).toBe(false); }); }); describe('getPlatformFee', () => { it('should calculate platform fee', () => { const request = SponsorshipRequest.create(validProps); const fee = request.getPlatformFee(); expect(fee.amount).toBe(100); // 10% of 1000 expect(fee.currency).toBe('USD'); }); }); describe('getNetAmount', () => { it('should calculate net amount', () => { const request = SponsorshipRequest.create(validProps); const net = request.getNetAmount(); expect(net.amount).toBe(900); // 1000 - 100 expect(net.currency).toBe('USD'); }); }); });