fix seeds

This commit is contained in:
2025-12-27 01:53:36 +01:00
parent 901fb1ac83
commit 15435c93fc
12 changed files with 259 additions and 200 deletions

View File

@@ -1,4 +1,5 @@
import { Driver } from '@core/racing/domain/entities/Driver';
import { faker } from '@faker-js/faker';
export class RacingDriverFactory {
constructor(
@@ -7,7 +8,7 @@ export class RacingDriverFactory {
) {}
create(): Driver[] {
const countries = ['DE', 'NL', 'FR', 'GB', 'US', 'CA', 'SE', 'NO', 'IT', 'ES'] as const;
const countries = ['DE', 'NL', 'FR', 'GB', 'US', 'CA', 'SE', 'NO', 'IT', 'ES', 'AU', 'BR', 'JP', 'KR', 'RU', 'PL', 'CZ', 'HU', 'AT', 'CH'] as const;
return Array.from({ length: this.driverCount }, (_, idx) => {
const i = idx + 1;
@@ -15,15 +16,11 @@ export class RacingDriverFactory {
return Driver.create({
id: `driver-${i}`,
iracingId: String(100000 + i),
name: `Driver ${i}`,
country: countries[idx % countries.length]!,
bio: `Demo driver #${i} seeded for in-memory mode.`,
joinedAt: this.addDays(this.baseDate, -90 + i),
name: faker.person.fullName(),
country: faker.helpers.arrayElement(countries),
bio: faker.lorem.sentences(2),
joinedAt: faker.date.past({ years: 2, refDate: this.baseDate }),
});
});
}
private addDays(date: Date, days: number): Date {
return new Date(date.getTime() + days * 24 * 60 * 60 * 1000);
}
}

View File

@@ -1,100 +1,58 @@
import { League } from '@core/racing/domain/entities/League';
import { Driver } from '@core/racing/domain/entities/Driver';
import { faker } from '@faker-js/faker';
export class RacingLeagueFactory {
constructor(private readonly baseDate: Date) {}
constructor(
private readonly baseDate: Date,
private readonly drivers: Driver[],
) {}
create(): League[] {
const createdAtBase = this.baseDate;
const leagueCount = 20;
const pointsSystems = ['f1-2024', 'indycar', 'custom'] as const;
const qualifyingFormats = ['open', 'single-lap'] as const;
return [
League.create({
id: 'league-1',
name: 'GridPilot Sprint Series',
description: 'Weekly sprint races with stable grids.',
ownerId: 'driver-1',
settings: {
pointsSystem: 'f1-2024',
maxDrivers: 24,
sessionDuration: 60,
qualifyingFormat: 'open',
},
createdAt: this.addDays(createdAtBase, -200),
socialLinks: {
discordUrl: 'https://discord.gg/gridpilot-demo',
youtubeUrl: 'https://youtube.com/@gridpilot-demo',
websiteUrl: 'https://gridpilot-demo.example.com',
},
}),
League.create({
id: 'league-2',
name: 'GridPilot Endurance Cup',
description: 'Longer races with strategy and consistency.',
ownerId: 'driver-2',
settings: {
pointsSystem: 'indycar',
maxDrivers: 32,
sessionDuration: 120,
qualifyingFormat: 'open',
},
createdAt: this.addDays(createdAtBase, -180),
socialLinks: { discordUrl: 'https://discord.gg/gridpilot-endurance' },
}),
League.create({
id: 'league-3',
name: 'GridPilot Club Ladder',
description: 'Casual ladder with fast onboarding.',
ownerId: 'driver-3',
settings: {
pointsSystem: 'f1-2024',
maxDrivers: 48,
sessionDuration: 45,
qualifyingFormat: 'single-lap',
},
createdAt: this.addDays(createdAtBase, -160),
}),
League.create({
id: 'league-4',
name: 'Nordic Night Series',
description: 'Evening races with tight fields.',
ownerId: 'driver-4',
settings: {
pointsSystem: 'f1-2024',
maxDrivers: 32,
sessionDuration: 60,
qualifyingFormat: 'open',
},
createdAt: this.addDays(createdAtBase, -150),
}),
League.create({
id: 'league-5',
name: 'Demo League (Admin)',
description: 'Primary demo league owned by driver-1.',
ownerId: 'driver-1',
settings: {
pointsSystem: 'f1-2024',
maxDrivers: 24,
sessionDuration: 60,
qualifyingFormat: 'open',
},
createdAt: this.addDays(createdAtBase, -140),
}),
League.create({
id: 'league-6',
name: 'Sim Racing Alliance',
description: 'Mixed-format season with community events.',
ownerId: 'driver-5',
settings: {
pointsSystem: 'indycar',
maxDrivers: 40,
sessionDuration: 90,
qualifyingFormat: 'open',
},
createdAt: this.addDays(createdAtBase, -130),
}),
];
}
return Array.from({ length: leagueCount }, (_, idx) => {
const i = idx + 1;
const owner = faker.helpers.arrayElement(this.drivers);
const socialLinks: { discordUrl?: string; youtubeUrl?: string; websiteUrl?: string } = {};
if (faker.datatype.boolean()) socialLinks.discordUrl = faker.internet.url();
if (faker.datatype.boolean()) socialLinks.youtubeUrl = faker.internet.url();
if (faker.datatype.boolean()) socialLinks.websiteUrl = faker.internet.url();
private addDays(date: Date, days: number): Date {
return new Date(date.getTime() + days * 24 * 60 * 60 * 1000);
const leagueData: {
id: string;
name: string;
description: string;
ownerId: string;
settings: {
pointsSystem: 'f1-2024' | 'indycar' | 'custom';
maxDrivers: number;
sessionDuration: number;
qualifyingFormat: 'open' | 'single-lap';
};
createdAt: Date;
socialLinks?: { discordUrl?: string; youtubeUrl?: string; websiteUrl?: string };
} = {
id: `league-${i}`,
name: faker.company.name() + ' Racing League',
description: faker.lorem.sentences(2),
ownerId: owner.id.toString(),
settings: {
pointsSystem: faker.helpers.arrayElement(pointsSystems),
maxDrivers: faker.number.int({ min: 20, max: 50 }),
sessionDuration: faker.number.int({ min: 30, max: 180 }),
qualifyingFormat: faker.helpers.arrayElement(qualifyingFormats),
},
createdAt: faker.date.past({ years: 2, refDate: this.baseDate }),
};
if (Object.keys(socialLinks).length > 0) {
leagueData.socialLinks = socialLinks;
}
return League.create(leagueData);
});
}
}

View File

@@ -1,36 +1,31 @@
import { League } from '@core/racing/domain/entities/League';
import { Race } from '@core/racing/domain/entities/Race';
import { Track } from '@core/racing/domain/entities/Track';
export class RacingRaceFactory {
constructor(private readonly baseDate: Date) {}
create(leagues: League[]): Race[] {
const tracks = [
'Monza GP',
'Spa-Francorchamps',
'Suzuka',
'Mount Panorama',
'Silverstone GP',
'Interlagos',
'Imola',
'Laguna Seca',
];
create(leagues: League[], tracks: Track[]): Race[] {
const cars = ['GT3 Porsche 911', 'GT3 BMW M4', 'LMP3 Prototype', 'GT4 Alpine', 'Touring Civic'];
const leagueIds = leagues.map((l) => l.id.toString());
const trackIds = tracks.map((t) => t.id);
const demoLeagueId = 'league-5';
const races: Race[] = [];
for (let i = 1; i <= 25; i++) {
for (let i = 1; i <= 50; i++) {
const leagueId = leagueIds[(i - 1) % leagueIds.length] ?? demoLeagueId;
const trackId = trackIds[(i - 1) % trackIds.length]!;
const track = tracks.find(t => t.id === trackId)!;
const scheduledAt = this.addDays(this.baseDate, i <= 10 ? -35 + i : 1 + (i - 10) * 2);
const base = {
id: `race-${i}`,
leagueId,
scheduledAt,
track: tracks[(i - 1) % tracks.length]!,
track: track.name.toString(),
trackId: track.id,
car: cars[(i - 1) % cars.length]!,
};

View File

@@ -6,6 +6,7 @@ import { RaceRegistration } from '@core/racing/domain/entities/RaceRegistration'
import { Result as RaceResult } from '@core/racing/domain/entities/result/Result';
import { Standing } from '@core/racing/domain/entities/Standing';
import { Team } from '@core/racing/domain/entities/Team';
import { Track } from '@core/racing/domain/entities/Track';
import type { TeamMembership } from '@core/racing/domain/types/TeamMembership';
import type { FeedItem } from '@core/social/domain/types/FeedItem';
import { RacingDriverFactory } from './RacingDriverFactory';
@@ -17,6 +18,7 @@ import { RacingRaceFactory } from './RacingRaceFactory';
import { RacingResultFactory } from './RacingResultFactory';
import { RacingStandingFactory } from './RacingStandingFactory';
import { RacingTeamFactory } from './RacingTeamFactory';
import { RacingTrackFactory } from './RacingTrackFactory';
export type Friendship = {
driverId: string;
@@ -33,6 +35,7 @@ export type RacingSeed = {
raceRegistrations: RaceRegistration[];
teams: Team[];
teamMemberships: TeamMembership[];
tracks: Track[];
friendships: Friendship[];
feedEvents: FeedItem[];
};
@@ -45,7 +48,7 @@ export type RacingSeedOptions = {
export const racingSeedDefaults: Readonly<
Required<RacingSeedOptions>
> = {
driverCount: 32,
driverCount: 100,
baseDate: new Date('2025-01-15T12:00:00.000Z'),
};
@@ -60,23 +63,25 @@ class RacingSeedFactory {
create(): RacingSeed {
const driverFactory = new RacingDriverFactory(this.driverCount, this.baseDate);
const leagueFactory = new RacingLeagueFactory(this.baseDate);
const trackFactory = new RacingTrackFactory();
const raceFactory = new RacingRaceFactory(this.baseDate);
const resultFactory = new RacingResultFactory();
const standingFactory = new RacingStandingFactory();
const membershipFactory = new RacingMembershipFactory(this.baseDate);
const teamFactory = new RacingTeamFactory(this.baseDate);
const friendshipFactory = new RacingFriendshipFactory();
const feedFactory = new RacingFeedFactory(this.baseDate);
const drivers = driverFactory.create();
const tracks = trackFactory.create();
const leagueFactory = new RacingLeagueFactory(this.baseDate, drivers);
const leagues = leagueFactory.create();
const races = raceFactory.create(leagues);
const teamFactory = new RacingTeamFactory(this.baseDate, drivers, leagues);
const teams = teamFactory.createTeams();
const races = raceFactory.create(leagues, tracks);
const results = resultFactory.create(drivers, races);
const standings = standingFactory.create(leagues, races, results);
const leagueMemberships = membershipFactory.createLeagueMemberships(drivers, leagues);
const raceRegistrations = membershipFactory.createRaceRegistrations(races);
const teams = teamFactory.createTeams();
const teamMemberships = teamFactory.createTeamMemberships(drivers, teams);
const friendships = friendshipFactory.create(drivers);
const feedEvents = feedFactory.create(drivers, friendships, races, leagues);
@@ -91,6 +96,7 @@ class RacingSeedFactory {
raceRegistrations,
teams,
teamMemberships,
tracks,
friendships,
feedEvents,
};

View File

@@ -1,92 +1,72 @@
import { Driver } from '@core/racing/domain/entities/Driver';
import { League } from '@core/racing/domain/entities/League';
import { Team } from '@core/racing/domain/entities/Team';
import type { TeamMembership } from '@core/racing/domain/types/TeamMembership';
import { faker } from '@faker-js/faker';
export class RacingTeamFactory {
constructor(private readonly baseDate: Date) {}
constructor(
private readonly baseDate: Date,
private readonly drivers: Driver[],
private readonly leagues: League[],
) {}
createTeams(): Team[] {
return [
Team.create({
id: 'team-1',
name: 'Apex Racing',
tag: 'APEX',
description: 'Demo team focused on clean racing.',
ownerId: 'driver-1',
leagues: ['league-5'],
createdAt: this.addDays(this.baseDate, -100),
}),
Team.create({
id: 'team-2',
name: 'Night Owls',
tag: 'NITE',
description: 'Late-night grinders and endurance lovers.',
ownerId: 'driver-2',
leagues: ['league-4'],
createdAt: this.addDays(this.baseDate, -90),
}),
Team.create({
id: 'team-3',
name: 'Club Legends',
tag: 'CLUB',
description: 'A casual team for ladder climbing.',
ownerId: 'driver-3',
leagues: ['league-3'],
createdAt: this.addDays(this.baseDate, -80),
}),
];
const teamCount = 15;
return Array.from({ length: teamCount }, (_, idx) => {
const i = idx + 1;
const owner = faker.helpers.arrayElement(this.drivers);
const teamLeagues = faker.helpers.arrayElements(
this.leagues.map(l => l.id.toString()),
{ min: 0, max: 3 }
);
return Team.create({
id: `team-${i}`,
name: faker.company.name() + ' Racing',
tag: faker.string.alpha({ length: 4, casing: 'upper' }),
description: faker.lorem.sentences(2),
ownerId: owner.id,
leagues: teamLeagues,
createdAt: faker.date.past({ years: 2, refDate: this.baseDate }),
});
});
}
createTeamMemberships(drivers: Driver[], teams: Team[]): TeamMembership[] {
const memberships: TeamMembership[] = [];
const usedDrivers = new Set<string>();
const team1 = teams.find((t) => t.id === 'team-1');
const team2 = teams.find((t) => t.id === 'team-2');
const team3 = teams.find((t) => t.id === 'team-3');
teams.forEach((team) => {
const availableDrivers = drivers.filter(d => !usedDrivers.has(d.id.toString()) && d.id.toString() !== team.ownerId.toString());
const memberCount = faker.number.int({ min: 1, max: 8 });
const members = faker.helpers.arrayElements(availableDrivers, memberCount);
if (team1) {
const members = drivers.slice(0, 6);
members.forEach((d, idx) => {
memberships.push({
teamId: team1.id,
driverId: d.id,
role: d.id === team1.ownerId.toString() ? 'owner' : idx === 1 ? 'manager' : 'driver',
status: 'active',
joinedAt: this.addDays(this.baseDate, -50),
});
// Add owner
memberships.push({
teamId: team.id.toString(),
driverId: team.ownerId.toString(),
role: 'owner',
status: 'active',
joinedAt: faker.date.past({ years: 1, refDate: team.createdAt.toDate() }),
});
}
usedDrivers.add(team.ownerId.toString());
if (team2) {
const members = drivers.slice(6, 12);
members.forEach((d) => {
// Add members
members.forEach((driver) => {
memberships.push({
teamId: team2.id,
driverId: d.id,
role: d.id === team2.ownerId.toString() ? 'owner' : 'driver',
teamId: team.id.toString(),
driverId: driver.id.toString(),
role: faker.helpers.arrayElement(['driver', 'manager']),
status: 'active',
joinedAt: this.addDays(this.baseDate, -45),
joinedAt: faker.date.past({ years: 1, refDate: team.createdAt.toDate() }),
});
usedDrivers.add(driver.id.toString());
});
}
if (team3) {
const members = drivers.slice(12, 18);
members.forEach((d) => {
memberships.push({
teamId: team3.id,
driverId: d.id,
role: d.id === team3.ownerId.toString() ? 'owner' : 'driver',
status: 'active',
joinedAt: this.addDays(this.baseDate, -40),
});
});
}
});
return memberships;
}
private addDays(date: Date, days: number): Date {
return new Date(date.getTime() + days * 24 * 60 * 60 * 1000);
}
}

View File

@@ -0,0 +1,92 @@
import { Track } from '@core/racing/domain/entities/Track';
export class RacingTrackFactory {
create(): Track[] {
return [
Track.create({
id: 'track-spa',
name: 'Spa-Francorchamps',
shortName: 'SPA',
country: 'Belgium',
category: 'road',
difficulty: 'advanced',
lengthKm: 7.004,
turns: 19,
imageUrl: '/images/tracks/spa.jpg',
gameId: 'iracing',
}),
Track.create({
id: 'track-monza',
name: 'Autodromo Nazionale Monza',
shortName: 'MON',
country: 'Italy',
category: 'road',
difficulty: 'intermediate',
lengthKm: 5.793,
turns: 11,
imageUrl: '/images/tracks/monza.jpg',
gameId: 'iracing',
}),
Track.create({
id: 'track-nurburgring',
name: 'Nürburgring Grand Prix',
shortName: 'NUR',
country: 'Germany',
category: 'road',
difficulty: 'advanced',
lengthKm: 5.148,
turns: 15,
imageUrl: '/images/tracks/nurburgring.jpg',
gameId: 'iracing',
}),
Track.create({
id: 'track-silverstone',
name: 'Silverstone Circuit',
shortName: 'SIL',
country: 'United Kingdom',
category: 'road',
difficulty: 'intermediate',
lengthKm: 5.891,
turns: 18,
imageUrl: '/images/tracks/silverstone.jpg',
gameId: 'iracing',
}),
Track.create({
id: 'track-suzuka',
name: 'Suzuka International Racing Course',
shortName: 'SUZ',
country: 'Japan',
category: 'road',
difficulty: 'expert',
lengthKm: 5.807,
turns: 18,
imageUrl: '/images/tracks/suzuka.jpg',
gameId: 'iracing',
}),
Track.create({
id: 'track-daytona',
name: 'Daytona International Speedway',
shortName: 'DAY',
country: 'United States',
category: 'oval',
difficulty: 'intermediate',
lengthKm: 4.023,
turns: 4,
imageUrl: '/images/tracks/daytona.jpg',
gameId: 'iracing',
}),
Track.create({
id: 'track-laguna',
name: 'WeatherTech Raceway Laguna Seca',
shortName: 'LAG',
country: 'United States',
category: 'road',
difficulty: 'advanced',
lengthKm: 3.602,
turns: 11,
imageUrl: '/images/tracks/laguna.jpg',
gameId: 'iracing',
}),
];
}
}

View File

@@ -35,6 +35,7 @@ describe('CompleteDriverOnboardingUseCase', () => {
useCase = new CompleteDriverOnboardingUseCase(
driverRepository as unknown as IDriverRepository,
logger,
output,
);
});
@@ -65,7 +66,7 @@ describe('CompleteDriverOnboardingUseCase', () => {
const result = await useCase.execute(command);
expect(result.isOk()).toBe(true);
expect(result.unwrap()).toEqual({ driver: createdDriver });
expect(output.present).toHaveBeenCalledWith({ driver: createdDriver });
expect(driverRepository.findById).toHaveBeenCalledWith('user-1');
expect(driverRepository.create).toHaveBeenCalledWith(
expect.objectContaining({
@@ -143,7 +144,7 @@ describe('CompleteDriverOnboardingUseCase', () => {
const result = await useCase.execute(command);
expect(result.isOk()).toBe(true);
expect(result.unwrap()).toEqual({ driver: createdDriver });
expect(output.present).toHaveBeenCalledWith({ driver: createdDriver });
expect(driverRepository.create).toHaveBeenCalledWith(
expect.objectContaining({
id: 'user-1',

View File

@@ -7,6 +7,8 @@ import type { IDriverRepository } from '../../domain/repositories/IDriverReposit
import type { IRankingService } from '../../domain/services/IRankingService';
import type { IDriverStatsService } from '../../domain/services/IDriverStatsService';
import type { Logger } from '@core/shared/application';
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
import type { GetDriversLeaderboardResult } from './GetDriversLeaderboardUseCase';
describe('GetDriversLeaderboardUseCase', () => {
const mockDriverFindAll = vi.fn();
@@ -39,6 +41,10 @@ describe('GetDriversLeaderboardUseCase', () => {
error: vi.fn(),
};
const mockOutput: UseCaseOutputPort<GetDriversLeaderboardResult> = {
present: vi.fn(),
};
it('should return drivers leaderboard data', async () => {
const useCase = new GetDriversLeaderboardUseCase(
mockDriverRepo,
@@ -46,6 +52,7 @@ describe('GetDriversLeaderboardUseCase', () => {
mockDriverStatsService,
mockGetDriverAvatar,
mockLogger,
mockOutput,
);
const driver1 = { id: 'driver1', name: { value: 'Driver One' }, country: { value: 'US' } };
@@ -75,9 +82,8 @@ describe('GetDriversLeaderboardUseCase', () => {
const result = await useCase.execute(input);
expect(result.isOk()).toBe(true);
const presented = result.unwrap();
expect(presented).toEqual({
expect(mockOutput.present).toHaveBeenCalledWith({
items: [
expect.objectContaining({
driver: driver1,
@@ -115,6 +121,7 @@ describe('GetDriversLeaderboardUseCase', () => {
mockDriverStatsService,
mockGetDriverAvatar,
mockLogger,
mockOutput,
);
mockDriverFindAll.mockResolvedValue([]);
@@ -125,9 +132,8 @@ describe('GetDriversLeaderboardUseCase', () => {
const result = await useCase.execute(input);
expect(result.isOk()).toBe(true);
const presented = result.unwrap();
expect(presented).toEqual({
expect(mockOutput.present).toHaveBeenCalledWith({
items: [],
totalRaces: 0,
totalWins: 0,
@@ -142,6 +148,7 @@ describe('GetDriversLeaderboardUseCase', () => {
mockDriverStatsService,
mockGetDriverAvatar,
mockLogger,
mockOutput,
);
const driver1 = { id: 'driver1', name: { value: 'Driver One' }, country: { value: 'US' } };
@@ -157,9 +164,8 @@ describe('GetDriversLeaderboardUseCase', () => {
const result = await useCase.execute(input);
expect(result.isOk()).toBe(true);
const presented = result.unwrap();
expect(presented).toEqual({
expect(mockOutput.present).toHaveBeenCalledWith({
items: [
expect.objectContaining({
driver: driver1,
@@ -186,6 +192,7 @@ describe('GetDriversLeaderboardUseCase', () => {
mockDriverStatsService,
mockGetDriverAvatar,
mockLogger,
mockOutput,
);
const error = new Error('Repository error');

View File

@@ -3,21 +3,27 @@ import {
GetTotalDriversUseCase,
GetTotalDriversInput,
GetTotalDriversErrorCode,
GetTotalDriversResult,
} from './GetTotalDriversUseCase';
import { IDriverRepository } from '../../domain/repositories/IDriverRepository';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
describe('GetTotalDriversUseCase', () => {
let useCase: GetTotalDriversUseCase;
let driverRepository: {
findAll: Mock;
};
let output: UseCaseOutputPort<GetTotalDriversResult>;
beforeEach(() => {
driverRepository = {
findAll: vi.fn(),
};
output = {
present: vi.fn(),
};
useCase = new GetTotalDriversUseCase(driverRepository as unknown as IDriverRepository);
useCase = new GetTotalDriversUseCase(driverRepository as unknown as IDriverRepository, output);
});
it('should return total number of drivers', async () => {
@@ -30,7 +36,7 @@ describe('GetTotalDriversUseCase', () => {
const result = await useCase.execute(input);
expect(result.isOk()).toBe(true);
expect(result.unwrap()).toEqual({ totalDrivers: 2 });
expect(output.present).toHaveBeenCalledWith({ totalDrivers: 2 });
});
it('should return error on repository failure', async () => {

View File

@@ -3,10 +3,12 @@ import {
IsDriverRegisteredForRaceUseCase,
type IsDriverRegisteredForRaceInput,
type IsDriverRegisteredForRaceErrorCode,
type IsDriverRegisteredForRaceResult,
} from './IsDriverRegisteredForRaceUseCase';
import { IRaceRegistrationRepository } from '../../domain/repositories/IRaceRegistrationRepository';
import type { Logger } from '@core/shared/application';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
describe('IsDriverRegisteredForRaceUseCase', () => {
let useCase: IsDriverRegisteredForRaceUseCase;
@@ -19,6 +21,7 @@ describe('IsDriverRegisteredForRaceUseCase', () => {
warn: Mock;
error: Mock;
};
let output: UseCaseOutputPort<IsDriverRegisteredForRaceResult>;
beforeEach(() => {
registrationRepository = {
isRegistered: vi.fn(),
@@ -29,9 +32,13 @@ describe('IsDriverRegisteredForRaceUseCase', () => {
warn: vi.fn(),
error: vi.fn(),
};
output = {
present: vi.fn(),
};
useCase = new IsDriverRegisteredForRaceUseCase(
registrationRepository as unknown as IRaceRegistrationRepository,
logger as unknown as Logger,
output,
);
});
@@ -43,7 +50,7 @@ describe('IsDriverRegisteredForRaceUseCase', () => {
const result = await useCase.execute(params);
expect(result.isOk()).toBe(true);
expect(result.unwrap()).toEqual({
expect(output.present).toHaveBeenCalledWith({
raceId: params.raceId,
driverId: params.driverId,
isRegistered: true,
@@ -58,7 +65,7 @@ describe('IsDriverRegisteredForRaceUseCase', () => {
const result = await useCase.execute(params);
expect(result.isOk()).toBe(true);
expect(result.unwrap()).toEqual({
expect(output.present).toHaveBeenCalledWith({
raceId: params.raceId,
driverId: params.driverId,
isRegistered: false,

11
package-lock.json generated
View File

@@ -50,6 +50,7 @@
"eslint-import-resolver-typescript": "2.7.1",
"eslint-plugin-boundaries": "^5.3.1",
"eslint-plugin-import": "^2.32.0",
"faker": "^6.6.6",
"glob": "^13.0.0",
"husky": "^9.1.7",
"jsdom": "^22.1.0",
@@ -87,7 +88,8 @@
},
"devDependencies": {
"@nestjs/testing": "^10.4.20",
"ts-node-dev": "^2.0.0"
"ts-node-dev": "^2.0.0",
"tsconfig-paths": "^3.15.0"
}
},
"apps/api/node_modules/reflect-metadata": {
@@ -8126,6 +8128,13 @@
"@types/yauzl": "^2.9.1"
}
},
"node_modules/faker": {
"version": "6.6.6",
"resolved": "https://registry.npmjs.org/faker/-/faker-6.6.6.tgz",
"integrity": "sha512-9tCqYEDHI5RYFQigXFwF1hnCwcWCOJl/hmll0lr5D2Ljjb0o4wphb69wikeJDz5qCEzXCoPvG6ss5SDP6IfOdg==",
"dev": true,
"license": "MIT"
},
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",

View File

@@ -35,9 +35,10 @@
"commander": "^11.0.0",
"electron": "^39.2.7",
"eslint": "^8.0.0",
"eslint-import-resolver-typescript": "2.7.1",
"eslint-plugin-boundaries": "^5.3.1",
"eslint-plugin-import": "^2.32.0",
"eslint-import-resolver-typescript": "2.7.1",
"faker": "^6.6.6",
"glob": "^13.0.0",
"husky": "^9.1.7",
"jsdom": "^22.1.0",