Files
gridpilot.gg/core/racing/domain/entities/SponsorshipRequest.test.ts
2025-12-23 15:38:50 +01:00

161 lines
6.1 KiB
TypeScript

import { SponsorshipRequest, SponsorableEntityType } 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' as SponsorableEntityType,
entityId: 'driver-789',
tier: 'main' as SponsorshipTier,
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');
});
});
});