import { vi, describe, it, expect, beforeEach } from 'vitest'; import { InMemorySponsorshipRequestRepository } from './InMemorySponsorshipRequestRepository'; import { SponsorshipRequest, SponsorableEntityType, SponsorshipRequestStatus } from '@core/racing/domain/entities/SponsorshipRequest'; import { Money } from '@core/racing/domain/value-objects/Money'; import { SponsorshipTier } from '@core/racing/domain/entities/season/SeasonSponsorship'; import type { Logger } from '@core/shared/application'; describe('InMemorySponsorshipRequestRepository', () => { let repository: InMemorySponsorshipRequestRepository; let mockLogger: Logger; beforeEach(() => { mockLogger = { debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn(), }; repository = new InMemorySponsorshipRequestRepository(mockLogger); }); const createTestRequest = ( id: string, sponsorId: string = 'sponsor-1', entityType: SponsorableEntityType = 'team', entityId: string = 'entity-1', status: SponsorshipRequestStatus = 'pending', tier: SponsorshipTier = 'main', offeredAmount: Money = Money.create(1000, 'USD') ): SponsorshipRequest => { return SponsorshipRequest.create({ id, sponsorId, entityType, entityId, tier, offeredAmount, status, createdAt: new Date(), }); }; describe('constructor', () => { it('should initialize with a logger', () => { expect(repository).toBeDefined(); expect(mockLogger.info).toHaveBeenCalledWith('InMemorySponsorshipRequestRepository initialized.'); }); it('should seed initial requests', () => { const request = createTestRequest('req-1'); const repoWithSeed = new InMemorySponsorshipRequestRepository(mockLogger, [request]); expect(mockLogger.debug).toHaveBeenCalledWith('Seeded sponsorship request: req-1.'); }); }); describe('findById', () => { it('should return the request if found', async () => { const request = createTestRequest('req-1'); await repository.create(request); const result = await repository.findById('req-1'); expect(result).toEqual(request); expect(mockLogger.info).toHaveBeenCalledWith('Found request by ID: req-1.'); }); it('should return null if not found', async () => { const result = await repository.findById('nonexistent'); expect(result).toBeNull(); expect(mockLogger.warn).toHaveBeenCalledWith('Request with ID nonexistent not found.'); }); }); describe('findByEntity', () => { it('should return requests for the entity', async () => { const request1 = createTestRequest('req-1', 'sponsor-1', 'team', 'entity-1'); const request2 = createTestRequest('req-2', 'sponsor-2', 'team', 'entity-1'); const request3 = createTestRequest('req-3', 'sponsor-1', 'driver', 'entity-2'); await repository.create(request1); await repository.create(request2); await repository.create(request3); const result = await repository.findByEntity('team', 'entity-1'); expect(result).toHaveLength(2); expect(result).toContain(request1); expect(result).toContain(request2); expect(mockLogger.info).toHaveBeenCalledWith('Found 2 requests for entity team:entity-1.'); }); it('should return empty array if no requests', async () => { const result = await repository.findByEntity('team', 'nonexistent'); expect(result).toEqual([]); expect(mockLogger.info).toHaveBeenCalledWith('Found 0 requests for entity team:nonexistent.'); }); }); describe('findPendingByEntity', () => { it('should return pending requests for the entity', async () => { const pending = createTestRequest('req-1', 'sponsor-1', 'team', 'entity-1', 'pending'); const accepted = createTestRequest('req-2', 'sponsor-1', 'team', 'entity-1', 'accepted'); await repository.create(pending); await repository.create(accepted); const result = await repository.findPendingByEntity('team', 'entity-1'); expect(result).toHaveLength(1); expect(result[0]).toEqual(pending); expect(mockLogger.info).toHaveBeenCalledWith('Found 1 pending requests for entity team:entity-1.'); }); }); describe('findBySponsorId', () => { it('should return requests by sponsor', async () => { const request1 = createTestRequest('req-1', 'sponsor-1'); const request2 = createTestRequest('req-2', 'sponsor-1'); const request3 = createTestRequest('req-3', 'sponsor-2'); await repository.create(request1); await repository.create(request2); await repository.create(request3); const result = await repository.findBySponsorId('sponsor-1'); expect(result).toHaveLength(2); expect(result).toContain(request1); expect(result).toContain(request2); expect(mockLogger.info).toHaveBeenCalledWith('Found 2 requests by sponsor ID: sponsor-1.'); }); }); describe('findByStatus', () => { it('should return requests by status', async () => { const pending = createTestRequest('req-1', 'sponsor-1', 'team', 'entity-1', 'pending'); const accepted = createTestRequest('req-2', 'sponsor-1', 'team', 'entity-1', 'accepted'); await repository.create(pending); await repository.create(accepted); const result = await repository.findByStatus('pending'); expect(result).toHaveLength(1); expect(result[0]).toEqual(pending); expect(mockLogger.info).toHaveBeenCalledWith('Found 1 requests with status: pending.'); }); }); describe('findBySponsorIdAndStatus', () => { it('should return requests by sponsor and status', async () => { const pending1 = createTestRequest('req-1', 'sponsor-1', 'team', 'entity-1', 'pending'); const accepted1 = createTestRequest('req-2', 'sponsor-1', 'team', 'entity-1', 'accepted'); const pending2 = createTestRequest('req-3', 'sponsor-2', 'team', 'entity-1', 'pending'); await repository.create(pending1); await repository.create(accepted1); await repository.create(pending2); const result = await repository.findBySponsorIdAndStatus('sponsor-1', 'pending'); expect(result).toHaveLength(1); expect(result[0]).toEqual(pending1); expect(mockLogger.info).toHaveBeenCalledWith('Found 1 requests by sponsor ID sponsor-1 and status pending.'); }); }); describe('hasPendingRequest', () => { it('should return true if pending request exists', async () => { const request = createTestRequest('req-1', 'sponsor-1', 'team', 'entity-1', 'pending'); await repository.create(request); const result = await repository.hasPendingRequest('sponsor-1', 'team', 'entity-1'); expect(result).toBe(true); expect(mockLogger.info).toHaveBeenCalledWith('Pending request for sponsor sponsor-1, entity team:entity-1 exists: true.'); }); it('should return false if no pending request', async () => { const result = await repository.hasPendingRequest('sponsor-1', 'team', 'entity-1'); expect(result).toBe(false); expect(mockLogger.info).toHaveBeenCalledWith('Pending request for sponsor sponsor-1, entity team:entity-1 exists: false.'); }); }); describe('countPendingByEntity', () => { it('should count pending requests for entity', async () => { const request1 = createTestRequest('req-1', 'sponsor-1', 'team', 'entity-1', 'pending'); const request2 = createTestRequest('req-2', 'sponsor-2', 'team', 'entity-1', 'pending'); const accepted = createTestRequest('req-3', 'sponsor-3', 'team', 'entity-1', 'accepted'); await repository.create(request1); await repository.create(request2); await repository.create(accepted); const result = await repository.countPendingByEntity('team', 'entity-1'); expect(result).toBe(2); expect(mockLogger.info).toHaveBeenCalledWith('Count of pending requests for entity team:entity-1: 2.'); }); }); describe('create', () => { it('should create a new request', async () => { const request = createTestRequest('req-1'); const result = await repository.create(request); expect(result).toEqual(request); expect(mockLogger.info).toHaveBeenCalledWith('Sponsorship request req-1 created successfully.'); }); it('should throw if request already exists', async () => { const request = createTestRequest('req-1'); await repository.create(request); await expect(repository.create(request)).rejects.toThrow('Sponsorship request already exists'); expect(mockLogger.warn).toHaveBeenCalledWith('Request with ID req-1 already exists.'); }); }); describe('update', () => { it('should update existing request', async () => { const request = createTestRequest('req-1'); await repository.create(request); const updated = request.accept('responder-1'); const result = await repository.update(updated); expect(result).toEqual(updated); expect(mockLogger.info).toHaveBeenCalledWith('Sponsorship request req-1 updated successfully.'); }); it('should throw if request not found', async () => { const request = createTestRequest('req-1'); await expect(repository.update(request)).rejects.toThrow('Sponsorship request not found'); expect(mockLogger.warn).toHaveBeenCalledWith('Request with ID req-1 not found for update.'); }); }); describe('delete', () => { it('should delete existing request', async () => { const request = createTestRequest('req-1'); await repository.create(request); await repository.delete('req-1'); expect(mockLogger.info).toHaveBeenCalledWith('Sponsorship request req-1 deleted successfully.'); const found = await repository.findById('req-1'); expect(found).toBeNull(); }); it('should not throw if request not found', async () => { await repository.delete('nonexistent'); expect(mockLogger.warn).toHaveBeenCalledWith('Request with ID nonexistent not found for deletion.'); }); }); describe('exists', () => { it('should return true if exists', async () => { const request = createTestRequest('req-1'); await repository.create(request); const result = await repository.exists('req-1'); expect(result).toBe(true); }); it('should return false if not exists', async () => { const result = await repository.exists('nonexistent'); expect(result).toBe(false); }); }); });