import { RaceEvent } from '@core/racing/domain/entities/RaceEvent'; import { Session } from '@core/racing/domain/entities/Session'; import { SessionType } from '@core/racing/domain/value-objects/SessionType'; import type { Logger } from '@core/shared/domain/Logger'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { InMemoryRaceEventRepository } from './InMemoryRaceEventRepository'; describe('InMemoryRaceEventRepository', () => { let repository: InMemoryRaceEventRepository; let mockLogger: Logger; const createMockSession = (overrides: Partial<{ id: string; raceEventId: string; sessionType: SessionType; status: 'scheduled' | 'running' | 'completed' | 'cancelled'; scheduledAt: Date; }> = {}): Session => { return Session.create({ id: overrides.id ?? 'session-1', raceEventId: overrides.raceEventId ?? 'race-event-1', scheduledAt: overrides.scheduledAt ?? new Date('2023-01-01T10:00:00Z'), track: 'Monza', car: 'Ferrari SF21', sessionType: overrides.sessionType ?? SessionType.main(), status: overrides.status ?? 'scheduled', }); }; const createTestRaceEvent = (id: string, seasonId: string, leagueId: string, name?: string, status?: 'scheduled' | 'in_progress' | 'awaiting_stewarding' | 'closed' | 'cancelled') => { const sessions = [createMockSession({ raceEventId: id, sessionType: SessionType.main() })]; const baseProps = { id, seasonId, leagueId, name: name ?? 'Test Race Event', sessions, }; if (status) { return RaceEvent.create({ ...baseProps, status }); } return RaceEvent.create(baseProps); }; beforeEach(() => { mockLogger = { debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn(), }; repository = new InMemoryRaceEventRepository(mockLogger); }); describe('constructor', () => { it('should initialize with a logger', () => { expect(repository).toBeDefined(); expect(mockLogger.info).toHaveBeenCalledWith('InMemoryRaceEventRepository initialized.'); }); }); describe('findById', () => { it('should return null if race event not found', async () => { const result = await repository.findById('nonexistent'); expect(result).toBeNull(); expect(mockLogger.debug).toHaveBeenCalledWith('Finding race event by id: nonexistent'); expect(mockLogger.warn).toHaveBeenCalledWith('Race event with id nonexistent not found.'); }); it('should return the race event if found', async () => { const raceEvent = createTestRaceEvent('1', 'season1', 'league1'); await repository.create(raceEvent); const result = await repository.findById('1'); expect(result).toEqual(raceEvent); expect(mockLogger.info).toHaveBeenCalledWith('Found race event: 1'); }); }); describe('findAll', () => { it('should return all race events', async () => { const raceEvent1 = createTestRaceEvent('1', 'season1', 'league1'); const raceEvent2 = createTestRaceEvent('2', 'season2', 'league2'); await repository.create(raceEvent1); await repository.create(raceEvent2); const result = await repository.findAll(); expect(result).toHaveLength(2); expect(result).toContain(raceEvent1); expect(result).toContain(raceEvent2); expect(mockLogger.info).toHaveBeenCalledWith('Found 2 race events.'); }); }); describe('findBySeasonId', () => { it('should return race events filtered by season ID', async () => { const raceEvent1 = createTestRaceEvent('1', 'season1', 'league1'); const raceEvent2 = createTestRaceEvent('2', 'season2', 'league1'); await repository.create(raceEvent1); await repository.create(raceEvent2); const result = await repository.findBySeasonId('season1'); expect(result).toHaveLength(1); expect(result[0]).toEqual(raceEvent1); }); }); describe('findByLeagueId', () => { it('should return race events filtered by league ID', async () => { const raceEvent1 = createTestRaceEvent('1', 'season1', 'league1'); const raceEvent2 = createTestRaceEvent('2', 'season1', 'league2'); await repository.create(raceEvent1); await repository.create(raceEvent2); const result = await repository.findByLeagueId('league1'); expect(result).toHaveLength(1); expect(result[0]).toEqual(raceEvent1); }); }); describe('findByStatus', () => { it('should return race events filtered by status', async () => { const raceEvent1 = createTestRaceEvent('1', 'season1', 'league1'); const raceEvent2 = createTestRaceEvent('2', 'season1', 'league1', 'Test', 'in_progress'); await repository.create(raceEvent1); await repository.create(raceEvent2); const result = await repository.findByStatus('scheduled'); expect(result).toHaveLength(1); expect(result[0]).toEqual(raceEvent1); }); }); describe('findAwaitingStewardingClose', () => { it('should return race events awaiting stewarding close', async () => { const pastDate = new Date(Date.now() - 3600000); const sessions = [createMockSession({ raceEventId: '1', sessionType: SessionType.main() })]; const raceEvent = RaceEvent.create({ id: '1', seasonId: 'season1', leagueId: 'league1', name: 'Test', sessions, status: 'awaiting_stewarding', stewardingClosesAt: pastDate, }); await repository.create(raceEvent); const result = await repository.findAwaitingStewardingClose(); expect(result).toHaveLength(1); expect(result[0]).toEqual(raceEvent); }); it('should not return race events not awaiting stewarding', async () => { const raceEvent = createTestRaceEvent('1', 'season1', 'league1'); await repository.create(raceEvent); const result = await repository.findAwaitingStewardingClose(); expect(result).toHaveLength(0); }); }); describe('create', () => { it('should create a new race event', async () => { const raceEvent = createTestRaceEvent('1', 'season1', 'league1'); await repository.create(raceEvent); expect(mockLogger.info).toHaveBeenCalledWith('Race event 1 created successfully.'); }); }); describe('update', () => { it('should update an existing race event', async () => { const raceEvent = createTestRaceEvent('1', 'season1', 'league1'); await repository.create(raceEvent); const updatedRaceEvent = raceEvent.start(); await repository.update(updatedRaceEvent); expect(mockLogger.info).toHaveBeenCalledWith('Race event 1 updated successfully.'); }); it('should create new if not exists', async () => { const raceEvent = createTestRaceEvent('1', 'season1', 'league1'); await repository.update(raceEvent); expect(mockLogger.warn).toHaveBeenCalledWith('Race event with id 1 not found for update. Creating new.'); }); }); describe('delete', () => { it('should delete an existing race event', async () => { const raceEvent = createTestRaceEvent('1', 'season1', 'league1'); await repository.create(raceEvent); await repository.delete('1'); expect(mockLogger.info).toHaveBeenCalledWith('Race event 1 deleted successfully.'); }); it('should warn if race event not found', async () => { await repository.delete('nonexistent'); expect(mockLogger.warn).toHaveBeenCalledWith('Race event with id nonexistent not found for deletion.'); }); }); describe('exists', () => { it('should return true if race event exists', async () => { const raceEvent = createTestRaceEvent('1', 'season1', 'league1'); await repository.create(raceEvent); const result = await repository.exists('1'); expect(result).toBe(true); }); it('should return false if race event does not exist', async () => { const result = await repository.exists('nonexistent'); expect(result).toBe(false); }); }); describe('clear', () => { it('should clear all race events', () => { repository.clear(); expect(mockLogger.debug).toHaveBeenCalledWith('Clearing all race events.'); expect(mockLogger.info).toHaveBeenCalledWith('All race events cleared.'); }); }); describe('getAll', () => { it('should return all race events', () => { const raceEvent = createTestRaceEvent('1', 'season1', 'league1'); repository.create(raceEvent); const result = repository.getAll(); expect(result).toHaveLength(1); expect(result[0]).toEqual(raceEvent); }); }); });