import { vi, describe, it, expect, beforeEach } from 'vitest'; import { InMemoryProtestRepository } from './InMemoryProtestRepository'; import { Protest } from '@core/racing/domain/entities/Protest'; import type { Logger } from '@core/shared/application'; describe('InMemoryProtestRepository', () => { let repository: InMemoryProtestRepository; let mockLogger: Logger; beforeEach(() => { mockLogger = { debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn(), }; repository = new InMemoryProtestRepository(mockLogger); }); const createTestProtest = (id: string, raceId: string, protestingDriverId: string, accusedDriverId: string, status?: string) => { const baseProps = { id, raceId, protestingDriverId, accusedDriverId, incident: { lap: 1, description: 'Test incident' }, }; if (status) { return Protest.create({ ...baseProps, status }); } return Protest.create(baseProps); }; describe('constructor', () => { it('should initialize with a logger', () => { expect(repository).toBeDefined(); expect(mockLogger.info).toHaveBeenCalledWith('InMemoryProtestRepository initialized.'); }); }); describe('findById', () => { it('should return null if protest not found', async () => { const result = await repository.findById('nonexistent'); expect(result).toBeNull(); expect(mockLogger.debug).toHaveBeenCalledWith('[InMemoryProtestRepository] Finding protest by ID: nonexistent'); expect(mockLogger.warn).toHaveBeenCalledWith('Protest with ID nonexistent not found.'); }); it('should return the protest if found', async () => { const protest = createTestProtest('1', 'race1', 'driver1', 'driver2'); await repository.create(protest); const result = await repository.findById('1'); expect(result).toEqual(protest); expect(mockLogger.info).toHaveBeenCalledWith('Found protest by ID: 1.'); }); }); describe('findByRaceId', () => { it('should return protests filtered by race ID', async () => { const protest1 = createTestProtest('1', 'race1', 'driver1', 'driver2'); const protest2 = createTestProtest('2', 'race2', 'driver3', 'driver4'); await repository.create(protest1); await repository.create(protest2); const result = await repository.findByRaceId('race1'); expect(result).toHaveLength(1); expect(result[0]).toEqual(protest1); }); }); describe('findByProtestingDriverId', () => { it('should return protests filtered by protesting driver ID', async () => { const protest1 = createTestProtest('1', 'race1', 'driver1', 'driver2'); const protest2 = createTestProtest('2', 'race1', 'driver3', 'driver1'); await repository.create(protest1); await repository.create(protest2); const result = await repository.findByProtestingDriverId('driver1'); expect(result).toHaveLength(1); expect(result[0]).toEqual(protest1); }); }); describe('findByAccusedDriverId', () => { it('should return protests filtered by accused driver ID', async () => { const protest1 = createTestProtest('1', 'race1', 'driver1', 'driver2'); const protest2 = createTestProtest('2', 'race1', 'driver2', 'driver3'); await repository.create(protest1); await repository.create(protest2); const result = await repository.findByAccusedDriverId('driver2'); expect(result).toHaveLength(1); expect(result[0]).toEqual(protest1); }); }); describe('findPending', () => { it('should return only pending protests', async () => { const protest1 = createTestProtest('1', 'race1', 'driver1', 'driver2'); const protest2 = createTestProtest('2', 'race1', 'driver3', 'driver4', 'dismissed'); await repository.create(protest1); await repository.create(protest2); const result = await repository.findPending(); expect(result).toHaveLength(1); expect(result[0]).toEqual(protest1); }); }); describe('findUnderReviewBy', () => { it('should return protests under review by a specific steward', async () => { const protest1 = Protest.create({ id: '1', raceId: 'race1', protestingDriverId: 'driver1', accusedDriverId: 'driver2', incident: { lap: 1, description: 'Test incident' }, status: 'under_review', reviewedBy: 'steward1', }); const protest2 = createTestProtest('2', 'race1', 'driver3', 'driver4'); await repository.create(protest1); await repository.create(protest2); const result = await repository.findUnderReviewBy('steward1'); expect(result).toHaveLength(1); expect(result[0]).toEqual(protest1); }); }); describe('create', () => { it('should create a new protest', async () => { const protest = createTestProtest('1', 'race1', 'driver1', 'driver2'); await repository.create(protest); expect(mockLogger.info).toHaveBeenCalledWith('Protest 1 created successfully.'); }); it('should throw error if protest already exists', async () => { const protest = createTestProtest('1', 'race1', 'driver1', 'driver2'); await repository.create(protest); await expect(repository.create(protest)).rejects.toThrow('Protest already exists'); }); }); describe('update', () => { it('should update an existing protest', async () => { const protest = createTestProtest('1', 'race1', 'driver1', 'driver2'); await repository.create(protest); const updatedProtest = protest.startReview('steward1'); await repository.update(updatedProtest); expect(mockLogger.info).toHaveBeenCalledWith('Protest 1 updated successfully.'); }); it('should throw error if protest does not exist', async () => { const protest = createTestProtest('1', 'race1', 'driver1', 'driver2'); await expect(repository.update(protest)).rejects.toThrow('Protest not found'); }); }); describe('exists', () => { it('should return true if protest exists', async () => { const protest = createTestProtest('1', 'race1', 'driver1', 'driver2'); await repository.create(protest); const result = await repository.exists('1'); expect(result).toBe(true); }); it('should return false if protest does not exist', async () => { const result = await repository.exists('nonexistent'); expect(result).toBe(false); }); }); });