import { Penalty } from '@core/racing/domain/entities/penalty/Penalty'; import type { Logger } from '@core/shared/domain/Logger'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { InMemoryPenaltyRepository } from './InMemoryPenaltyRepository'; describe('InMemoryPenaltyRepository', () => { let repository: InMemoryPenaltyRepository; let mockLogger: Logger; beforeEach(() => { mockLogger = { debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn(), }; repository = new InMemoryPenaltyRepository(mockLogger); }); const createTestPenalty = (id: string, raceId: string, driverId: string, issuedBy: string) => { return Penalty.create({ id, leagueId: 'league1', raceId, driverId, type: 'time_penalty', value: 5, reason: 'Test reason', issuedBy, }); }; describe('constructor', () => { it('should initialize with a logger', () => { expect(repository).toBeDefined(); expect(mockLogger.info).toHaveBeenCalledWith('InMemoryPenaltyRepository initialized.'); }); }); describe('findById', () => { it('should return null if penalty not found', async () => { const result = await repository.findById('nonexistent'); expect(result).toBeNull(); expect(mockLogger.debug).toHaveBeenCalledWith('Finding penalty by id: nonexistent'); expect(mockLogger.warn).toHaveBeenCalledWith('Penalty with id nonexistent not found.'); }); it('should return the penalty if found', async () => { const penalty = createTestPenalty('1', 'race1', 'driver1', 'steward1'); await repository.create(penalty); const result = await repository.findById('1'); expect(result).toEqual(penalty); expect(mockLogger.info).toHaveBeenCalledWith('Found penalty with id: 1.'); }); }); describe('findByRaceId', () => { it('should return penalties filtered by race ID', async () => { const penalty1 = createTestPenalty('1', 'race1', 'driver1', 'steward1'); const penalty2 = createTestPenalty('2', 'race2', 'driver2', 'steward1'); await repository.create(penalty1); await repository.create(penalty2); const result = await repository.findByRaceId('race1'); expect(result).toHaveLength(1); expect(result[0]).toEqual(penalty1); }); }); describe('findByDriverId', () => { it('should return penalties filtered by driver ID', async () => { const penalty1 = createTestPenalty('1', 'race1', 'driver1', 'steward1'); const penalty2 = createTestPenalty('2', 'race1', 'driver2', 'steward1'); await repository.create(penalty1); await repository.create(penalty2); const result = await repository.findByDriverId('driver1'); expect(result).toHaveLength(1); expect(result[0]).toEqual(penalty1); }); }); describe('findByProtestId', () => { it('should return penalties filtered by protest ID', async () => { const penalty1 = Penalty.create({ id: '1', leagueId: 'league1', raceId: 'race1', driverId: 'driver1', type: 'time_penalty', value: 5, reason: 'Test reason', protestId: 'protest1', issuedBy: 'steward1', }); const penalty2 = createTestPenalty('2', 'race1', 'driver2', 'steward1'); await repository.create(penalty1); await repository.create(penalty2); const result = await repository.findByProtestId('protest1'); expect(result).toHaveLength(1); expect(result[0]).toEqual(penalty1); }); }); describe('findPending', () => { it('should return only pending penalties', async () => { const penalty1 = createTestPenalty('1', 'race1', 'driver1', 'steward1'); const penalty2 = Penalty.create({ id: '2', leagueId: 'league1', raceId: 'race1', driverId: 'driver2', type: 'time_penalty', value: 5, reason: 'Test reason', issuedBy: 'steward1', status: 'applied', }); await repository.create(penalty1); await repository.create(penalty2); const result = await repository.findPending(); expect(result).toHaveLength(1); expect(result[0]).toEqual(penalty1); }); }); describe('findIssuedBy', () => { it('should return penalties issued by a specific steward', async () => { const penalty1 = createTestPenalty('1', 'race1', 'driver1', 'steward1'); const penalty2 = createTestPenalty('2', 'race1', 'driver2', 'steward2'); await repository.create(penalty1); await repository.create(penalty2); const result = await repository.findIssuedBy('steward1'); expect(result).toHaveLength(1); expect(result[0]).toEqual(penalty1); }); }); describe('create', () => { it('should create a new penalty', async () => { const penalty = createTestPenalty('1', 'race1', 'driver1', 'steward1'); await repository.create(penalty); expect(mockLogger.info).toHaveBeenCalledWith('Penalty 1 created successfully.'); }); it('should throw error if penalty already exists', async () => { const penalty = createTestPenalty('1', 'race1', 'driver1', 'steward1'); await repository.create(penalty); await expect(repository.create(penalty)).rejects.toThrow('Penalty with ID 1 already exists'); }); }); describe('update', () => { it('should update an existing penalty', async () => { const penalty = createTestPenalty('1', 'race1', 'driver1', 'steward1'); await repository.create(penalty); const updatedPenalty = penalty.markAsApplied(); await repository.update(updatedPenalty); expect(mockLogger.info).toHaveBeenCalledWith('Penalty 1 updated successfully.'); }); it('should throw error if penalty does not exist', async () => { const penalty = createTestPenalty('1', 'race1', 'driver1', 'steward1'); await expect(repository.update(penalty)).rejects.toThrow('Penalty with ID 1 not found'); }); }); describe('exists', () => { it('should return true if penalty exists', async () => { const penalty = createTestPenalty('1', 'race1', 'driver1', 'steward1'); await repository.create(penalty); const result = await repository.exists('1'); expect(result).toBe(true); }); it('should return false if penalty does not exist', async () => { const result = await repository.exists('nonexistent'); expect(result).toBe(false); }); }); });