244 lines
7.9 KiB
TypeScript
244 lines
7.9 KiB
TypeScript
/**
|
|
* Data Factory for Integration Tests
|
|
* Uses TypeORM repositories to create test data
|
|
*/
|
|
|
|
import { DataSource } from 'typeorm';
|
|
import { LeagueOrmEntity } from '../../../adapters/racing/persistence/typeorm/entities/LeagueOrmEntity';
|
|
import { SeasonOrmEntity } from '../../../adapters/racing/persistence/typeorm/entities/SeasonOrmEntity';
|
|
import { DriverOrmEntity } from '../../../adapters/racing/persistence/typeorm/entities/DriverOrmEntity';
|
|
import { RaceOrmEntity } from '../../../adapters/racing/persistence/typeorm/entities/RaceOrmEntity';
|
|
import { ResultOrmEntity } from '../../../adapters/racing/persistence/typeorm/entities/ResultOrmEntity';
|
|
import { LeagueOrmMapper } from '../../../adapters/racing/persistence/typeorm/mappers/LeagueOrmMapper';
|
|
import { SeasonOrmMapper } from '../../../adapters/racing/persistence/typeorm/mappers/SeasonOrmMapper';
|
|
import { RaceOrmMapper } from '../../../adapters/racing/persistence/typeorm/mappers/RaceOrmMapper';
|
|
import { ResultOrmMapper } from '../../../adapters/racing/persistence/typeorm/mappers/ResultOrmMapper';
|
|
import { TypeOrmLeagueRepository } from '../../../adapters/racing/persistence/typeorm/repositories/TypeOrmLeagueRepository';
|
|
import { TypeOrmSeasonRepository } from '../../../adapters/racing/persistence/typeorm/repositories/TypeOrmSeasonRepository';
|
|
import { TypeOrmRaceRepository } from '../../../adapters/racing/persistence/typeorm/repositories/TypeOrmRaceRepository';
|
|
import { TypeOrmResultRepository } from '../../../adapters/racing/persistence/typeorm/repositories/TypeOrmResultRepository';
|
|
import { TypeOrmDriverRepository } from '../../../adapters/racing/persistence/typeorm/repositories/TypeOrmDriverRepository';
|
|
import { League } from '../../../core/racing/domain/entities/League';
|
|
import { Season } from '../../../core/racing/domain/entities/season/Season';
|
|
import { Driver } from '../../../core/racing/domain/entities/Driver';
|
|
import { Race } from '../../../core/racing/domain/entities/Race';
|
|
import { Result } from '../../../core/racing/domain/entities/result/Result';
|
|
import { v4 as uuidv4 } from 'uuid';
|
|
|
|
export class DataFactory {
|
|
private dataSource: DataSource;
|
|
private leagueRepo: TypeOrmLeagueRepository;
|
|
private seasonRepo: TypeOrmSeasonRepository;
|
|
private driverRepo: TypeOrmDriverRepository;
|
|
private raceRepo: TypeOrmRaceRepository;
|
|
private resultRepo: TypeOrmResultRepository;
|
|
|
|
constructor(private dbUrl: string) {
|
|
this.dataSource = new DataSource({
|
|
type: 'postgres',
|
|
url: dbUrl,
|
|
entities: [
|
|
LeagueOrmEntity,
|
|
SeasonOrmEntity,
|
|
DriverOrmEntity,
|
|
RaceOrmEntity,
|
|
ResultOrmEntity,
|
|
],
|
|
synchronize: false, // Don't sync, use existing schema
|
|
});
|
|
}
|
|
|
|
async initialize(): Promise<void> {
|
|
if (!this.dataSource.isInitialized) {
|
|
await this.dataSource.initialize();
|
|
}
|
|
|
|
const leagueMapper = new LeagueOrmMapper();
|
|
const seasonMapper = new SeasonOrmMapper();
|
|
const raceMapper = new RaceOrmMapper();
|
|
const resultMapper = new ResultOrmMapper();
|
|
|
|
this.leagueRepo = new TypeOrmLeagueRepository(this.dataSource, leagueMapper);
|
|
this.seasonRepo = new TypeOrmSeasonRepository(this.dataSource, seasonMapper);
|
|
this.driverRepo = new TypeOrmDriverRepository(this.dataSource, leagueMapper); // Reuse mapper
|
|
this.raceRepo = new TypeOrmRaceRepository(this.dataSource, raceMapper);
|
|
this.resultRepo = new TypeOrmResultRepository(this.dataSource, resultMapper);
|
|
}
|
|
|
|
async cleanup(): Promise<void> {
|
|
if (this.dataSource.isInitialized) {
|
|
await this.dataSource.destroy();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create a test league
|
|
*/
|
|
async createLeague(overrides: Partial<{
|
|
id: string;
|
|
name: string;
|
|
description: string;
|
|
ownerId: string;
|
|
}> = {}) {
|
|
const league = League.create({
|
|
id: overrides.id || uuidv4(),
|
|
name: overrides.name || 'Test League',
|
|
description: overrides.description || 'Integration Test League',
|
|
ownerId: overrides.ownerId || uuidv4(),
|
|
settings: {
|
|
enableDriverChampionship: true,
|
|
enableTeamChampionship: false,
|
|
enableNationsChampionship: false,
|
|
enableTrophyChampionship: false,
|
|
visibility: 'unranked',
|
|
maxDrivers: 32,
|
|
},
|
|
participantCount: 0,
|
|
});
|
|
|
|
await this.leagueRepo.create(league);
|
|
return league;
|
|
}
|
|
|
|
/**
|
|
* Create a test season
|
|
*/
|
|
async createSeason(leagueId: string, overrides: Partial<{
|
|
id: string;
|
|
name: string;
|
|
year: number;
|
|
status: string;
|
|
}> = {}) {
|
|
const season = Season.create({
|
|
id: overrides.id || uuidv4(),
|
|
leagueId,
|
|
gameId: 'iracing',
|
|
name: overrides.name || 'Test Season',
|
|
year: overrides.year || 2024,
|
|
order: 1,
|
|
status: overrides.status || 'active',
|
|
startDate: new Date(),
|
|
endDate: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000),
|
|
schedulePublished: false,
|
|
});
|
|
|
|
await this.seasonRepo.create(season);
|
|
return season;
|
|
}
|
|
|
|
/**
|
|
* Create a test driver
|
|
*/
|
|
async createDriver(overrides: Partial<{
|
|
id: string;
|
|
name: string;
|
|
iracingId: string;
|
|
country: string;
|
|
}> = {}) {
|
|
const driver = Driver.create({
|
|
id: overrides.id || uuidv4(),
|
|
iracingId: overrides.iracingId || `iracing-${uuidv4()}`,
|
|
name: overrides.name || 'Test Driver',
|
|
country: overrides.country || 'US',
|
|
});
|
|
|
|
// Need to insert directly since driver repo might not exist or be different
|
|
await this.dataSource.getRepository(DriverOrmEntity).save({
|
|
id: driver.id.toString(),
|
|
iracingId: driver.iracingId,
|
|
name: driver.name.toString(),
|
|
country: driver.country,
|
|
joinedAt: new Date(),
|
|
bio: null,
|
|
category: null,
|
|
avatarRef: null,
|
|
});
|
|
|
|
return driver;
|
|
}
|
|
|
|
/**
|
|
* Create a test race
|
|
*/
|
|
async createRace(overrides: Partial<{
|
|
id: string;
|
|
leagueId: string;
|
|
scheduledAt: Date;
|
|
status: string;
|
|
track: string;
|
|
car: string;
|
|
}> = {}) {
|
|
const race = Race.create({
|
|
id: overrides.id || uuidv4(),
|
|
leagueId: overrides.leagueId || uuidv4(),
|
|
scheduledAt: overrides.scheduledAt || new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
|
|
track: overrides.track || 'Laguna Seca',
|
|
car: overrides.car || 'Formula Ford',
|
|
status: overrides.status || 'scheduled',
|
|
});
|
|
|
|
await this.raceRepo.create(race);
|
|
return race;
|
|
}
|
|
|
|
/**
|
|
* Create a test result
|
|
*/
|
|
async createResult(raceId: string, driverId: string, overrides: Partial<{
|
|
id: string;
|
|
position: number;
|
|
fastestLap: number;
|
|
incidents: number;
|
|
startPosition: number;
|
|
}> = {}) {
|
|
const result = Result.create({
|
|
id: overrides.id || uuidv4(),
|
|
raceId,
|
|
driverId,
|
|
position: overrides.position || 1,
|
|
fastestLap: overrides.fastestLap || 0,
|
|
incidents: overrides.incidents || 0,
|
|
startPosition: overrides.startPosition || 1,
|
|
});
|
|
|
|
await this.resultRepo.create(result);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Create complete test scenario: league, season, drivers, races
|
|
*/
|
|
async createTestScenario() {
|
|
const league = await this.createLeague();
|
|
const season = await this.createSeason(league.id.toString());
|
|
const drivers = await Promise.all([
|
|
this.createDriver({ name: 'Driver 1' }),
|
|
this.createDriver({ name: 'Driver 2' }),
|
|
this.createDriver({ name: 'Driver 3' }),
|
|
]);
|
|
const races = await Promise.all([
|
|
this.createRace({
|
|
leagueId: league.id.toString(),
|
|
name: 'Race 1',
|
|
scheduledAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000)
|
|
}),
|
|
this.createRace({
|
|
leagueId: league.id.toString(),
|
|
name: 'Race 2',
|
|
scheduledAt: new Date(Date.now() + 14 * 24 * 60 * 60 * 1000)
|
|
}),
|
|
]);
|
|
|
|
return { league, season, drivers, races };
|
|
}
|
|
|
|
/**
|
|
* Clean up specific entities
|
|
*/
|
|
async deleteEntities(entities: { id: any }[], entityType: string) {
|
|
const repository = this.dataSource.getRepository(entityType);
|
|
for (const entity of entities) {
|
|
await repository.delete(entity.id);
|
|
}
|
|
}
|
|
} |