import { Track } from '@core/racing/domain/entities/Track'; import type { Logger } from '@core/shared/domain/Logger'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { InMemoryTrackRepository } from './InMemoryTrackRepository'; describe('InMemoryTrackRepository', () => { let repository: InMemoryTrackRepository; let mockLogger: Logger; beforeEach(() => { mockLogger = { debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn(), }; repository = new InMemoryTrackRepository(mockLogger); }); describe('constructor', () => { it('should initialize with a logger', () => { expect(repository).toBeDefined(); expect(mockLogger.info).toHaveBeenCalledWith('InMemoryTrackRepository initialized.'); }); }); describe('findById', () => { it('should return null if track not found', async () => { const result = await repository.findById('nonexistent'); expect(result).toBeNull(); expect(mockLogger.debug).toHaveBeenCalledWith('Finding track by id: nonexistent'); expect(mockLogger.warn).toHaveBeenCalledWith('Track with id nonexistent not found.'); }); it('should return the track if found', async () => { const track = Track.create({ id: 'track1', name: 'Monza Circuit', shortName: 'MON', country: 'Italy', category: 'road', difficulty: 'advanced', lengthKm: 5.793, turns: 11, imageUrl: 'https://example.com/monza.jpg', gameId: 'iracing', }); await repository.create(track); const result = await repository.findById('track1'); expect(result).toEqual(track); expect(mockLogger.debug).toHaveBeenCalledWith('Finding track by id: track1'); expect(mockLogger.info).toHaveBeenCalledWith('Found track: track1.'); }); }); describe('findAll', () => { it('should return an empty array when no tracks', async () => { const result = await repository.findAll(); expect(result).toEqual([]); expect(mockLogger.debug).toHaveBeenCalledWith('Finding all tracks.'); expect(mockLogger.info).toHaveBeenCalledWith('Found 0 tracks.'); }); it('should return all tracks', async () => { const track1 = Track.create({ id: 'track1', name: 'Monza Circuit', country: 'Italy', category: 'road', lengthKm: 5.793, turns: 11, gameId: 'iracing', }); const track2 = Track.create({ id: 'track2', name: 'Silverstone', country: 'UK', category: 'road', lengthKm: 5.891, turns: 18, gameId: 'iracing', }); await repository.create(track1); await repository.create(track2); const result = await repository.findAll(); expect(result).toEqual([track1, track2]); expect(mockLogger.debug).toHaveBeenCalledWith('Finding all tracks.'); expect(mockLogger.info).toHaveBeenCalledWith('Found 2 tracks.'); }); }); describe('findByGameId', () => { it('should return empty array if no tracks for game id', async () => { const result = await repository.findByGameId('iracing'); expect(result).toEqual([]); expect(mockLogger.debug).toHaveBeenCalledWith('Finding tracks by game id: iracing'); expect(mockLogger.info).toHaveBeenCalledWith('Found 0 tracks for game id: iracing.'); }); it('should return tracks for the game id', async () => { const track1 = Track.create({ id: 'track1', name: 'Monza Circuit', country: 'Italy', category: 'road', lengthKm: 5.793, turns: 11, gameId: 'iracing', }); const track2 = Track.create({ id: 'track2', name: 'Silverstone', country: 'UK', category: 'road', lengthKm: 5.891, turns: 18, gameId: 'iracing', }); const track3 = Track.create({ id: 'track3', name: 'Daytona', country: 'USA', category: 'oval', lengthKm: 4.0, turns: 4, gameId: 'assetto', }); await repository.create(track1); await repository.create(track2); await repository.create(track3); const result = await repository.findByGameId('iracing'); expect(result).toEqual([track1, track2]); expect(mockLogger.debug).toHaveBeenCalledWith('Finding tracks by game id: iracing'); expect(mockLogger.info).toHaveBeenCalledWith('Found 2 tracks for game id: iracing.'); }); }); describe('findByCategory', () => { it('should return empty array if no tracks in category', async () => { const result = await repository.findByCategory('oval'); expect(result).toEqual([]); expect(mockLogger.debug).toHaveBeenCalledWith('Finding tracks by category: oval'); expect(mockLogger.info).toHaveBeenCalledWith('Found 0 tracks for category: oval.'); }); it('should return tracks in the category', async () => { const track1 = Track.create({ id: 'track1', name: 'Monza Circuit', country: 'Italy', category: 'road', lengthKm: 5.793, turns: 11, gameId: 'iracing', }); const track2 = Track.create({ id: 'track2', name: 'Daytona', country: 'USA', category: 'oval', lengthKm: 4.0, turns: 4, gameId: 'iracing', }); await repository.create(track1); await repository.create(track2); const result = await repository.findByCategory('road'); expect(result).toEqual([track1]); expect(mockLogger.debug).toHaveBeenCalledWith('Finding tracks by category: road'); expect(mockLogger.info).toHaveBeenCalledWith('Found 1 tracks for category: road.'); }); }); describe('findByCountry', () => { it('should return empty array if no tracks in country', async () => { const result = await repository.findByCountry('France'); expect(result).toEqual([]); expect(mockLogger.debug).toHaveBeenCalledWith('Finding tracks by country: France'); expect(mockLogger.info).toHaveBeenCalledWith('Found 0 tracks for country: France.'); }); it('should return tracks in the country', async () => { const track1 = Track.create({ id: 'track1', name: 'Monza Circuit', country: 'Italy', category: 'road', lengthKm: 5.793, turns: 11, gameId: 'iracing', }); const track2 = Track.create({ id: 'track2', name: 'Imola', country: 'Italy', category: 'road', lengthKm: 4.909, turns: 17, gameId: 'iracing', }); const track3 = Track.create({ id: 'track3', name: 'Silverstone', country: 'UK', category: 'road', lengthKm: 5.891, turns: 18, gameId: 'iracing', }); await repository.create(track1); await repository.create(track2); await repository.create(track3); const result = await repository.findByCountry('Italy'); expect(result).toEqual([track2, track1]); expect(mockLogger.debug).toHaveBeenCalledWith('Finding tracks by country: Italy'); expect(mockLogger.info).toHaveBeenCalledWith('Found 2 tracks for country: Italy.'); }); }); describe('searchByName', () => { it('should return empty array if no matches', async () => { const result = await repository.searchByName('nonexistent'); expect(result).toEqual([]); expect(mockLogger.debug).toHaveBeenCalledWith('Searching tracks by name query: nonexistent'); expect(mockLogger.info).toHaveBeenCalledWith('Found 0 tracks matching search query: nonexistent.'); }); it('should return tracks matching the query in name', async () => { const track1 = Track.create({ id: 'track1', name: 'Monza Circuit', shortName: 'MON', country: 'Italy', category: 'road', lengthKm: 5.793, turns: 11, gameId: 'iracing', }); const track2 = Track.create({ id: 'track2', name: 'Silverstone Circuit', shortName: 'SIL', country: 'UK', category: 'road', lengthKm: 5.891, turns: 18, gameId: 'iracing', }); await repository.create(track1); await repository.create(track2); const result = await repository.searchByName('Circuit'); expect(result).toEqual([track1, track2]); expect(mockLogger.debug).toHaveBeenCalledWith('Searching tracks by name query: Circuit'); expect(mockLogger.info).toHaveBeenCalledWith('Found 2 tracks matching search query: Circuit.'); }); it('should return tracks matching the query in short name', async () => { const track = Track.create({ id: 'track1', name: 'Monza Circuit', shortName: 'MON', country: 'Italy', category: 'road', lengthKm: 5.793, turns: 11, gameId: 'iracing', }); await repository.create(track); const result = await repository.searchByName('mon'); expect(result).toEqual([track]); expect(mockLogger.debug).toHaveBeenCalledWith('Searching tracks by name query: mon'); expect(mockLogger.info).toHaveBeenCalledWith('Found 1 tracks matching search query: mon.'); }); }); describe('create', () => { it('should create a new track', async () => { const track = Track.create({ id: 'track1', name: 'Monza Circuit', country: 'Italy', category: 'road', lengthKm: 5.793, turns: 11, gameId: 'iracing', }); const result = await repository.create(track); expect(result).toEqual(track); expect(mockLogger.debug).toHaveBeenCalledWith('Creating track: track1'); expect(mockLogger.info).toHaveBeenCalledWith('Track track1 created successfully.'); }); it('should throw error if track already exists', async () => { const track = Track.create({ id: 'track1', name: 'Monza Circuit', country: 'Italy', category: 'road', lengthKm: 5.793, turns: 11, gameId: 'iracing', }); await repository.create(track); await expect(repository.create(track)).rejects.toThrow('Track with ID track1 already exists'); expect(mockLogger.warn).toHaveBeenCalledWith('Track with ID track1 already exists.'); }); }); describe('update', () => { it('should update an existing track', async () => { const track = Track.create({ id: 'track1', name: 'Monza Circuit', country: 'Italy', category: 'road', lengthKm: 5.793, turns: 11, gameId: 'iracing', }); await repository.create(track); const updatedTrack = Track.create({ id: 'track1', name: 'Monza Grand Prix Circuit', country: 'Italy', category: 'road', lengthKm: 5.793, turns: 11, gameId: 'iracing', }); const result = await repository.update(updatedTrack); expect(result).toEqual(updatedTrack); expect(mockLogger.debug).toHaveBeenCalledWith('Updating track: track1'); expect(mockLogger.info).toHaveBeenCalledWith('Track track1 updated successfully.'); }); it('should throw error if track does not exist', async () => { const track = Track.create({ id: 'track1', name: 'Monza Circuit', country: 'Italy', category: 'road', lengthKm: 5.793, turns: 11, gameId: 'iracing', }); await expect(repository.update(track)).rejects.toThrow('Track with ID track1 not found'); expect(mockLogger.warn).toHaveBeenCalledWith('Track with ID track1 not found for update.'); }); }); describe('delete', () => { it('should delete an existing track', async () => { const track = Track.create({ id: 'track1', name: 'Monza Circuit', country: 'Italy', category: 'road', lengthKm: 5.793, turns: 11, gameId: 'iracing', }); await repository.create(track); await repository.delete('track1'); expect(await repository.exists('track1')).toBe(false); expect(mockLogger.debug).toHaveBeenCalledWith('Deleting track: track1'); expect(mockLogger.info).toHaveBeenCalledWith('Track track1 deleted successfully.'); }); it('should throw error if track does not exist', async () => { await expect(repository.delete('nonexistent')).rejects.toThrow('Track with ID nonexistent not found'); expect(mockLogger.warn).toHaveBeenCalledWith('Track with ID nonexistent not found for deletion.'); }); }); describe('exists', () => { it('should return true if track exists', async () => { const track = Track.create({ id: 'track1', name: 'Monza Circuit', country: 'Italy', category: 'road', lengthKm: 5.793, turns: 11, gameId: 'iracing', }); await repository.create(track); const result = await repository.exists('track1'); expect(result).toBe(true); expect(mockLogger.debug).toHaveBeenCalledWith('Checking existence of track with id: track1'); }); it('should return false if track does not exist', async () => { const result = await repository.exists('nonexistent'); expect(result).toBe(false); expect(mockLogger.debug).toHaveBeenCalledWith('Checking existence of track with id: nonexistent'); }); }); });