Files
gridpilot.gg/adapters/racing/persistence/inmemory/InMemoryTrackRepository.test.ts
2026-01-16 15:20:25 +01:00

411 lines
13 KiB
TypeScript

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');
});
});
});