import { Car } from '@core/racing/domain/entities/Car'; import { CarClass } from '@core/racing/domain/entities/CarClass'; import { CarLicense } from '@core/racing/domain/entities/CarLicense'; import type { Logger } from '@core/shared/domain/Logger'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { InMemoryCarRepository } from './InMemoryCarRepository'; describe('InMemoryCarRepository', () => { let repository: InMemoryCarRepository; let mockLogger: Logger; beforeEach(() => { mockLogger = { debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn(), }; repository = new InMemoryCarRepository(mockLogger); }); const createTestCar = (id: string, name: string, manufacturer: string, gameId: string) => { return Car.create({ id, name, manufacturer, gameId, }); }; describe('constructor', () => { it('should initialize with a logger', () => { expect(repository).toBeDefined(); expect(mockLogger.info).toHaveBeenCalledWith('InMemoryCarRepository initialized'); }); }); describe('findById', () => { it('should return null if car not found', async () => { const result = await repository.findById('nonexistent'); expect(result).toBeNull(); expect(mockLogger.debug).toHaveBeenCalledWith('Attempting to find car with ID: nonexistent.'); expect(mockLogger.warn).toHaveBeenCalledWith('Car with ID: nonexistent not found.'); }); it('should return the car if found', async () => { const car = createTestCar('1', 'Test Car', 'Test Manufacturer', 'iracing'); await repository.create(car); const result = await repository.findById('1'); expect(result).toEqual(car); expect(mockLogger.info).toHaveBeenCalledWith('Successfully found car with ID: 1.'); }); }); describe('findAll', () => { it('should return all cars', async () => { const car1 = createTestCar('1', 'Car 1', 'Manufacturer 1', 'iracing'); const car2 = createTestCar('2', 'Car 2', 'Manufacturer 2', 'iracing'); await repository.create(car1); await repository.create(car2); const result = await repository.findAll(); expect(result).toHaveLength(2); expect(result).toContain(car1); expect(result).toContain(car2); }); }); describe('findByGameId', () => { it('should return cars filtered by game ID', async () => { const car1 = createTestCar('1', 'Car 1', 'Manufacturer 1', 'iracing'); const car2 = createTestCar('2', 'Car 2', 'Manufacturer 2', 'assetto'); await repository.create(car1); await repository.create(car2); const result = await repository.findByGameId('iracing'); expect(result).toHaveLength(1); expect(result[0]).toEqual(car1); }); }); describe('findByClass', () => { it('should return cars filtered by class', async () => { const car1 = Car.create({ id: '1', name: 'Car 1', manufacturer: 'Manufacturer 1', gameId: 'iracing', carClass: 'gt', }); const car2 = Car.create({ id: '2', name: 'Car 2', manufacturer: 'Manufacturer 2', gameId: 'iracing', carClass: 'formula', }); await repository.create(car1); await repository.create(car2); const result = await repository.findByClass(CarClass.create('gt')); expect(result).toHaveLength(1); expect(result[0]).toEqual(car1); }); }); describe('findByLicense', () => { it('should return cars filtered by license', async () => { const car1 = Car.create({ id: '1', name: 'Car 1', manufacturer: 'Manufacturer 1', gameId: 'iracing', license: 'D', }); const car2 = Car.create({ id: '2', name: 'Car 2', manufacturer: 'Manufacturer 2', gameId: 'iracing', license: 'C', }); await repository.create(car1); await repository.create(car2); const result = await repository.findByLicense(CarLicense.create('D')); expect(result).toHaveLength(1); expect(result[0]).toEqual(car1); }); }); describe('findByManufacturer', () => { it('should return cars filtered by manufacturer (case insensitive)', async () => { const car1 = createTestCar('1', 'Car 1', 'Ferrari', 'iracing'); const car2 = createTestCar('2', 'Car 2', 'ferrari', 'iracing'); const car3 = createTestCar('3', 'Car 3', 'BMW', 'iracing'); await repository.create(car1); await repository.create(car2); await repository.create(car3); const result = await repository.findByManufacturer('FERRARI'); expect(result).toHaveLength(2); expect(result).toContain(car1); expect(result).toContain(car2); }); }); describe('searchByName', () => { it('should return cars matching the query in name, shortName, or manufacturer', async () => { const car1 = Car.create({ id: '1', name: 'Ferrari 488', shortName: '488', manufacturer: 'Ferrari', gameId: 'iracing', }); const car2 = createTestCar('2', 'BMW M3', 'BMW', 'iracing'); await repository.create(car1); await repository.create(car2); const result = await repository.searchByName('ferrari'); expect(result).toHaveLength(1); expect(result[0]).toEqual(car1); }); }); describe('create', () => { it('should create a new car', async () => { const car = createTestCar('1', 'Test Car', 'Test Manufacturer', 'iracing'); const result = await repository.create(car); expect(result).toEqual(car); expect(mockLogger.info).toHaveBeenCalledWith('Car 1 created successfully.'); }); it('should throw error if car already exists', async () => { const car = createTestCar('1', 'Test Car', 'Test Manufacturer', 'iracing'); await repository.create(car); await expect(repository.create(car)).rejects.toThrow('Car with ID 1 already exists'); }); }); describe('update', () => { it('should update an existing car', async () => { const car = createTestCar('1', 'Test Car', 'Test Manufacturer', 'iracing'); await repository.create(car); const updatedCar = Car.create({ id: '1', name: 'Updated Car', manufacturer: 'Test Manufacturer', gameId: 'iracing', }); const result = await repository.update(updatedCar); expect(result).toEqual(updatedCar); expect(mockLogger.info).toHaveBeenCalledWith('Car 1 updated successfully.'); }); it('should throw error if car does not exist', async () => { const car = createTestCar('1', 'Test Car', 'Test Manufacturer', 'iracing'); await expect(repository.update(car)).rejects.toThrow('Car with ID 1 not found'); }); }); describe('delete', () => { it('should delete an existing car', async () => { const car = createTestCar('1', 'Test Car', 'Test Manufacturer', 'iracing'); await repository.create(car); await repository.delete('1'); expect(mockLogger.info).toHaveBeenCalledWith('Car 1 deleted successfully.'); const found = await repository.findById('1'); expect(found).toBeNull(); }); it('should throw error if car does not exist', async () => { await expect(repository.delete('nonexistent')).rejects.toThrow('Car with ID nonexistent not found'); }); }); describe('exists', () => { it('should return true if car exists', async () => { const car = createTestCar('1', 'Test Car', 'Test Manufacturer', 'iracing'); await repository.create(car); const result = await repository.exists('1'); expect(result).toBe(true); }); it('should return false if car does not exist', async () => { const result = await repository.exists('nonexistent'); expect(result).toBe(false); }); }); });