website refactor
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import type { ApplicationError } from '@core/shared/errors/ApplicationError';
|
||||
import type { CommonApplicationErrorKind } from '@core/shared/errors/ApplicationError';
|
||||
import type { ApplicationError, CommonApplicationErrorKind } from '@core/shared/errors/ApplicationError';
|
||||
|
||||
export abstract class RacingApplicationError
|
||||
extends Error
|
||||
|
||||
@@ -2,15 +2,16 @@
|
||||
* Tests for GetTeamRatingLedgerQuery
|
||||
*/
|
||||
|
||||
import { describe, it, expect, beforeEach, vi, Mock } from 'vitest';
|
||||
import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
|
||||
import { GetTeamRatingLedgerQuery, GetTeamRatingLedgerQueryHandler } from './GetTeamRatingLedgerQuery';
|
||||
import { TeamRatingEvent } from '../../domain/entities/TeamRatingEvent';
|
||||
import { TeamRatingEventId } from '../../domain/value-objects/TeamRatingEventId';
|
||||
import { TeamRatingDimensionKey } from '../../domain/value-objects/TeamRatingDimensionKey';
|
||||
import { TeamRatingDelta } from '../../domain/value-objects/TeamRatingDelta';
|
||||
import type { TeamRatingEventRepository } from '../../domain/repositories/TeamRatingEventRepository';
|
||||
|
||||
describe('GetTeamRatingLedgerQuery', () => {
|
||||
let mockRatingEventRepo: any;
|
||||
let mockRatingEventRepo: { findEventsPaginated: Mock };
|
||||
let handler: GetTeamRatingLedgerQueryHandler;
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -18,7 +19,7 @@ describe('GetTeamRatingLedgerQuery', () => {
|
||||
findEventsPaginated: vi.fn(),
|
||||
};
|
||||
|
||||
handler = new GetTeamRatingLedgerQueryHandler(mockRatingEventRepo);
|
||||
handler = new GetTeamRatingLedgerQueryHandler(mockRatingEventRepo as unknown as TeamRatingEventRepository);
|
||||
});
|
||||
|
||||
describe('execute', () => {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Tests for GetTeamRatingsSummaryQuery
|
||||
*/
|
||||
|
||||
import { describe, it, expect, beforeEach, vi, Mock } from 'vitest';
|
||||
import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
|
||||
import { GetTeamRatingsSummaryQuery, GetTeamRatingsSummaryQueryHandler } from './GetTeamRatingsSummaryQuery';
|
||||
import { TeamRatingSnapshot } from '../../domain/services/TeamRatingSnapshotCalculator';
|
||||
import { TeamRatingValue } from '../../domain/value-objects/TeamRatingValue';
|
||||
@@ -10,10 +10,12 @@ import { TeamRatingEvent } from '../../domain/entities/TeamRatingEvent';
|
||||
import { TeamRatingEventId } from '../../domain/value-objects/TeamRatingEventId';
|
||||
import { TeamRatingDimensionKey } from '../../domain/value-objects/TeamRatingDimensionKey';
|
||||
import { TeamRatingDelta } from '../../domain/value-objects/TeamRatingDelta';
|
||||
import type { TeamRatingRepository } from '../../domain/repositories/TeamRatingRepository';
|
||||
import type { TeamRatingEventRepository } from '../../domain/repositories/TeamRatingEventRepository';
|
||||
|
||||
describe('GetTeamRatingsSummaryQuery', () => {
|
||||
let mockTeamRatingRepo: any;
|
||||
let mockRatingEventRepo: any;
|
||||
let mockTeamRatingRepo: { findByTeamId: Mock };
|
||||
let mockRatingEventRepo: { getAllByTeamId: Mock };
|
||||
let handler: GetTeamRatingsSummaryQueryHandler;
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -25,8 +27,8 @@ describe('GetTeamRatingsSummaryQuery', () => {
|
||||
};
|
||||
|
||||
handler = new GetTeamRatingsSummaryQueryHandler(
|
||||
mockTeamRatingRepo,
|
||||
mockRatingEventRepo
|
||||
mockTeamRatingRepo as unknown as TeamRatingRepository,
|
||||
mockRatingEventRepo as unknown as TeamRatingEventRepository
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -6,9 +6,15 @@
|
||||
*/
|
||||
|
||||
import type { NotificationService } from '@core/notifications/application/ports/NotificationService';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import { SeasonSponsorship } from '../../domain/entities/season/SeasonSponsorship';
|
||||
import { SponsorshipRequestRepository } from '../../domain/repositories/SponsorshipRequestRepository';
|
||||
import { SeasonSponsorshipRepository } from '../../domain/repositories/SeasonSponsorshipRepository';
|
||||
import { SeasonRepository } from '../../domain/repositories/SeasonRepository';
|
||||
import { WalletRepository } from '@core/payments/domain/repositories/WalletRepository';
|
||||
import { LeagueWalletRepository } from '../../domain/repositories/LeagueWalletRepository';
|
||||
|
||||
export interface AcceptSponsorshipRequestInput {
|
||||
requestId: string;
|
||||
|
||||
@@ -5,6 +5,8 @@ import { TeamRatingEvent } from '@core/racing/domain/entities/TeamRatingEvent';
|
||||
import { TeamRatingEventId } from '@core/racing/domain/value-objects/TeamRatingEventId';
|
||||
import { TeamRatingDimensionKey } from '@core/racing/domain/value-objects/TeamRatingDimensionKey';
|
||||
import { TeamRatingDelta } from '@core/racing/domain/value-objects/TeamRatingDelta';
|
||||
import { TeamRating } from '../../domain/entities/TeamRating';
|
||||
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
||||
|
||||
// Mock repositories
|
||||
class MockTeamRatingEventRepository implements TeamRatingEventRepository {
|
||||
@@ -27,7 +29,7 @@ class MockTeamRatingEventRepository implements TeamRatingEventRepository {
|
||||
return this.events.filter(e => e.teamId === teamId);
|
||||
}
|
||||
|
||||
async findEventsPaginated(teamId: string): Promise<any> {
|
||||
async findEventsPaginated(teamId: string): Promise<PaginatedResult<TeamRatingEvent>> {
|
||||
const events = await this.getAllByTeamId(teamId);
|
||||
return {
|
||||
items: events,
|
||||
@@ -44,13 +46,13 @@ class MockTeamRatingEventRepository implements TeamRatingEventRepository {
|
||||
}
|
||||
|
||||
class MockTeamRatingRepository implements TeamRatingRepository {
|
||||
private snapshots: Map<string, any> = new Map();
|
||||
private snapshots: Map<string, TeamRating> = new Map();
|
||||
|
||||
async findByTeamId(teamId: string): Promise<any | null> {
|
||||
async findByTeamId(teamId: string): Promise<TeamRating | null> {
|
||||
return this.snapshots.get(teamId) || null;
|
||||
}
|
||||
|
||||
async save(snapshot: any): Promise<any> {
|
||||
async save(snapshot: TeamRating): Promise<TeamRating> {
|
||||
this.snapshots.set(snapshot.teamId, snapshot);
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
@@ -5,11 +5,14 @@
|
||||
* (driver, team, race, or season/league).
|
||||
*/
|
||||
|
||||
import { Result } from '@/shared/domain/Result';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import { SponsorshipRequest } from '../../domain/entities/SponsorshipRequest';
|
||||
import { Money, isCurrency } from '../../domain/value-objects/Money';
|
||||
import { SponsorshipRequestRepository } from '../../domain/repositories/SponsorshipRequestRepository';
|
||||
import { SponsorshipPricingRepository } from '../../domain/repositories/SponsorshipPricingRepository';
|
||||
import { SponsorRepository } from '../../domain/repositories/SponsorRepository';
|
||||
|
||||
export interface ApplyForSponsorshipInput {
|
||||
sponsorId: string;
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
import { beforeEach, describe, expect, it, Mock, vi } from 'vitest';
|
||||
import { ApplyPenaltyUseCase } from './ApplyPenaltyUseCase';
|
||||
import { PenaltyRepository } from '../../domain/repositories/PenaltyRepository';
|
||||
import { ProtestRepository } from '../../domain/repositories/ProtestRepository';
|
||||
import { RaceRepository } from '../../domain/repositories/RaceRepository';
|
||||
import { LeagueMembershipRepository } from '../../domain/repositories/LeagueMembershipRepository';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
|
||||
describe('ApplyPenaltyUseCase', () => {
|
||||
let mockPenaltyRepo: {
|
||||
@@ -43,11 +48,13 @@ describe('ApplyPenaltyUseCase', () => {
|
||||
});
|
||||
|
||||
it('should return error when race does not exist', async () => {
|
||||
const useCase = new ApplyPenaltyUseCase(mockPenaltyRepo as any,
|
||||
mockProtestRepo as any,
|
||||
mockRaceRepo as any,
|
||||
mockLeagueMembershipRepo as any,
|
||||
mockLogger as any);
|
||||
const useCase = new ApplyPenaltyUseCase(
|
||||
mockPenaltyRepo as unknown as PenaltyRepository,
|
||||
mockProtestRepo as unknown as ProtestRepository,
|
||||
mockRaceRepo as unknown as RaceRepository,
|
||||
mockLeagueMembershipRepo as unknown as LeagueMembershipRepository,
|
||||
mockLogger as unknown as Logger
|
||||
);
|
||||
|
||||
mockRaceRepo.findById.mockResolvedValue(null);
|
||||
|
||||
@@ -65,11 +72,13 @@ describe('ApplyPenaltyUseCase', () => {
|
||||
});
|
||||
|
||||
it('should return error when steward does not have authority', async () => {
|
||||
const useCase = new ApplyPenaltyUseCase(mockPenaltyRepo as any,
|
||||
mockProtestRepo as any,
|
||||
mockRaceRepo as any,
|
||||
mockLeagueMembershipRepo as any,
|
||||
mockLogger as any);
|
||||
const useCase = new ApplyPenaltyUseCase(
|
||||
mockPenaltyRepo as unknown as PenaltyRepository,
|
||||
mockProtestRepo as unknown as ProtestRepository,
|
||||
mockRaceRepo as unknown as RaceRepository,
|
||||
mockLeagueMembershipRepo as unknown as LeagueMembershipRepository,
|
||||
mockLogger as unknown as Logger
|
||||
);
|
||||
|
||||
mockRaceRepo.findById.mockResolvedValue({ id: 'race1', leagueId: 'league1' });
|
||||
|
||||
@@ -95,11 +104,13 @@ describe('ApplyPenaltyUseCase', () => {
|
||||
});
|
||||
|
||||
it('should return error when protest does not exist', async () => {
|
||||
const useCase = new ApplyPenaltyUseCase(mockPenaltyRepo as any,
|
||||
mockProtestRepo as any,
|
||||
mockRaceRepo as any,
|
||||
mockLeagueMembershipRepo as any,
|
||||
mockLogger as any);
|
||||
const useCase = new ApplyPenaltyUseCase(
|
||||
mockPenaltyRepo as unknown as PenaltyRepository,
|
||||
mockProtestRepo as unknown as ProtestRepository,
|
||||
mockRaceRepo as unknown as RaceRepository,
|
||||
mockLeagueMembershipRepo as unknown as LeagueMembershipRepository,
|
||||
mockLogger as unknown as Logger
|
||||
);
|
||||
|
||||
mockRaceRepo.findById.mockResolvedValue({ id: 'race1', leagueId: 'league1' });
|
||||
|
||||
@@ -127,11 +138,13 @@ describe('ApplyPenaltyUseCase', () => {
|
||||
});
|
||||
|
||||
it('should return error when protest is not upheld', async () => {
|
||||
const useCase = new ApplyPenaltyUseCase(mockPenaltyRepo as any,
|
||||
mockProtestRepo as any,
|
||||
mockRaceRepo as any,
|
||||
mockLeagueMembershipRepo as any,
|
||||
mockLogger as any);
|
||||
const useCase = new ApplyPenaltyUseCase(
|
||||
mockPenaltyRepo as unknown as PenaltyRepository,
|
||||
mockProtestRepo as unknown as ProtestRepository,
|
||||
mockRaceRepo as unknown as RaceRepository,
|
||||
mockLeagueMembershipRepo as unknown as LeagueMembershipRepository,
|
||||
mockLogger as unknown as Logger
|
||||
);
|
||||
|
||||
mockRaceRepo.findById.mockResolvedValue({ id: 'race1', leagueId: 'league1' });
|
||||
|
||||
@@ -159,11 +172,13 @@ describe('ApplyPenaltyUseCase', () => {
|
||||
});
|
||||
|
||||
it('should return error when protest is not for this race', async () => {
|
||||
const useCase = new ApplyPenaltyUseCase(mockPenaltyRepo as any,
|
||||
mockProtestRepo as any,
|
||||
mockRaceRepo as any,
|
||||
mockLeagueMembershipRepo as any,
|
||||
mockLogger as any);
|
||||
const useCase = new ApplyPenaltyUseCase(
|
||||
mockPenaltyRepo as unknown as PenaltyRepository,
|
||||
mockProtestRepo as unknown as ProtestRepository,
|
||||
mockRaceRepo as unknown as RaceRepository,
|
||||
mockLeagueMembershipRepo as unknown as LeagueMembershipRepository,
|
||||
mockLogger as unknown as Logger
|
||||
);
|
||||
|
||||
mockRaceRepo.findById.mockResolvedValue({ id: 'race1', leagueId: 'league1' });
|
||||
|
||||
@@ -191,11 +206,13 @@ describe('ApplyPenaltyUseCase', () => {
|
||||
});
|
||||
|
||||
it('should create penalty and return result on success', async () => {
|
||||
const useCase = new ApplyPenaltyUseCase(mockPenaltyRepo as any,
|
||||
mockProtestRepo as any,
|
||||
mockRaceRepo as any,
|
||||
mockLeagueMembershipRepo as any,
|
||||
mockLogger as any);
|
||||
const useCase = new ApplyPenaltyUseCase(
|
||||
mockPenaltyRepo as unknown as PenaltyRepository,
|
||||
mockProtestRepo as unknown as ProtestRepository,
|
||||
mockRaceRepo as unknown as RaceRepository,
|
||||
mockLeagueMembershipRepo as unknown as LeagueMembershipRepository,
|
||||
mockLogger as unknown as Logger
|
||||
);
|
||||
|
||||
mockRaceRepo.findById.mockResolvedValue({ id: 'race1', leagueId: 'league1' });
|
||||
|
||||
@@ -223,7 +240,7 @@ describe('ApplyPenaltyUseCase', () => {
|
||||
expect(presented.penaltyId).toBeDefined();
|
||||
|
||||
expect(mockPenaltyRepo.create).toHaveBeenCalledTimes(1);
|
||||
const createdPenalty = (mockPenaltyRepo.create as Mock).mock.calls[0]?.[0] as any;
|
||||
const createdPenalty = (mockPenaltyRepo.create as Mock).mock.calls[0]?.[0] as Penalty;
|
||||
|
||||
type ToStringable = { toString(): string };
|
||||
const asString = (value: unknown): string => {
|
||||
|
||||
@@ -5,11 +5,15 @@
|
||||
* The penalty can be standalone or linked to an upheld protest.
|
||||
*/
|
||||
|
||||
import { Result } from '@/shared/domain/Result';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import { randomUUID } from 'crypto';
|
||||
import { Penalty } from '../../domain/entities/penalty/Penalty';
|
||||
import { PenaltyRepository } from '../../domain/repositories/PenaltyRepository';
|
||||
import { ProtestRepository } from '../../domain/repositories/ProtestRepository';
|
||||
import { RaceRepository } from '../../domain/repositories/RaceRepository';
|
||||
import { LeagueMembershipRepository } from '../../domain/repositories/LeagueMembershipRepository';
|
||||
|
||||
export interface ApplyPenaltyInput {
|
||||
raceId: string;
|
||||
@@ -62,7 +66,7 @@ export class ApplyPenaltyUseCase {
|
||||
// Validate steward has authority (owner or admin of the league)
|
||||
const memberships = await this.leagueMembershipRepository.getLeagueMembers(race.leagueId);
|
||||
const stewardMembership = memberships.find(
|
||||
m => m.driverId.toString() === command.stewardId && m.status.toString() === 'active'
|
||||
(m) => m.driverId.toString() === command.stewardId && m.status.toString() === 'active'
|
||||
);
|
||||
|
||||
if (!stewardMembership || (stewardMembership.role.toString() !== 'owner' && stewardMembership.role.toString() !== 'admin')) {
|
||||
@@ -110,7 +114,7 @@ export class ApplyPenaltyUseCase {
|
||||
`ApplyPenaltyUseCase: Successfully applied penalty ${penalty.id} for driver ${command.driverId} in race ${command.raceId}.`,
|
||||
);
|
||||
|
||||
const result: ApplyPenaltyResult = { penaltyId: penalty.id };
|
||||
const result: ApplyPenaltyResult = { penaltyId: penalty.id.toString() };
|
||||
|
||||
return Result.ok(result);
|
||||
}
|
||||
|
||||
@@ -3,11 +3,7 @@ import type { LeagueRepository } from '../../domain/repositories/LeagueRepositor
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import { randomUUID } from 'crypto';
|
||||
import { JoinedAt } from '../../domain/value-objects/JoinedAt';
|
||||
import { LeagueId } from '../../domain/entities/LeagueId';
|
||||
import { DriverId } from '../../domain/entities/DriverId';
|
||||
import { MembershipRole } from '../../domain/entities/MembershipRole';
|
||||
import { MembershipStatus } from '../../domain/entities/MembershipStatus';
|
||||
import { LeagueMembership } from '../../domain/entities/LeagueMembership';
|
||||
|
||||
export interface ApproveLeagueJoinRequestInput {
|
||||
leagueId: string;
|
||||
@@ -55,14 +51,16 @@ export class ApproveLeagueJoinRequestUseCase {
|
||||
}
|
||||
|
||||
await this.leagueMembershipRepository.removeJoinRequest(input.joinRequestId);
|
||||
await this.leagueMembershipRepository.saveMembership({
|
||||
id: randomUUID(),
|
||||
leagueId: LeagueId.create(input.leagueId),
|
||||
driverId: DriverId.create(request.driverId.toString()),
|
||||
role: MembershipRole.create('member'),
|
||||
status: MembershipStatus.create('active'),
|
||||
joinedAt: JoinedAt.create(new Date()),
|
||||
});
|
||||
await this.leagueMembershipRepository.saveMembership(
|
||||
LeagueMembership.create({
|
||||
id: randomUUID(),
|
||||
leagueId: input.leagueId,
|
||||
driverId: request.driverId.toString(),
|
||||
role: 'member',
|
||||
status: 'active',
|
||||
joinedAt: new Date(),
|
||||
})
|
||||
);
|
||||
|
||||
const result: ApproveLeagueJoinRequestResult = { success: true, message: 'Join request approved.' };
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@ import { beforeEach, describe, expect, it, Mock, vi } from 'vitest';
|
||||
import { Race } from '../../domain/entities/Race';
|
||||
import { SessionType } from '../../domain/value-objects/SessionType';
|
||||
import { CancelRaceUseCase } from './CancelRaceUseCase';
|
||||
import { RaceRepository } from '../../domain/repositories/RaceRepository';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
|
||||
describe('CancelRaceUseCase', () => {
|
||||
let useCase: CancelRaceUseCase;
|
||||
@@ -27,8 +29,8 @@ describe('CancelRaceUseCase', () => {
|
||||
info: vi.fn(),
|
||||
error: vi.fn(),
|
||||
};
|
||||
useCase = new CancelRaceUseCase(raceRepository as any,
|
||||
logger as any);
|
||||
useCase = new CancelRaceUseCase(raceRepository as unknown as RaceRepository,
|
||||
logger as unknown as Logger);
|
||||
});
|
||||
|
||||
it('should cancel race successfully', async () => {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import type { Race } from '../../domain/entities/Race';
|
||||
import { RaceRepository } from '../../domain/repositories/RaceRepository';
|
||||
|
||||
export type CancelRaceInput = {
|
||||
raceId: string;
|
||||
|
||||
@@ -3,6 +3,11 @@ import { RaceEvent } from '../../domain/entities/RaceEvent';
|
||||
import { Session } from '../../domain/entities/Session';
|
||||
import { SessionType } from '../../domain/value-objects/SessionType';
|
||||
import { CloseRaceEventStewardingUseCase } from './CloseRaceEventStewardingUseCase';
|
||||
import { RaceEventRepository } from '../../domain/repositories/RaceEventRepository';
|
||||
import { RaceRegistrationRepository } from '../../domain/repositories/RaceRegistrationRepository';
|
||||
import { PenaltyRepository } from '../../domain/repositories/PenaltyRepository';
|
||||
import { DomainEventPublisher } from '@core/shared/domain/DomainEvent';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
|
||||
describe('CloseRaceEventStewardingUseCase', () => {
|
||||
let useCase: CloseRaceEventStewardingUseCase;
|
||||
@@ -42,11 +47,11 @@ describe('CloseRaceEventStewardingUseCase', () => {
|
||||
logger = {
|
||||
error: vi.fn(),
|
||||
};
|
||||
useCase = new CloseRaceEventStewardingUseCase(logger as any,
|
||||
raceEventRepository as any,
|
||||
raceRegistrationRepository as any,
|
||||
penaltyRepository as any,
|
||||
domainEventPublisher as any);
|
||||
useCase = new CloseRaceEventStewardingUseCase(logger as unknown as Logger,
|
||||
raceEventRepository as unknown as RaceEventRepository,
|
||||
raceRegistrationRepository as unknown as RaceRegistrationRepository,
|
||||
penaltyRepository as unknown as PenaltyRepository,
|
||||
domainEventPublisher as unknown as DomainEventPublisher);
|
||||
});
|
||||
|
||||
it('should close stewarding for expired events successfully', async () => {
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import { DomainEventPublisher } from '@/shared/domain/DomainEvent';
|
||||
import { DomainEventPublisher } from '@core/shared/domain/DomainEvent';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import type { RaceEvent } from '../../domain/entities/RaceEvent';
|
||||
import { RaceEventStewardingClosedEvent } from '../../domain/events/RaceEventStewardingClosed';
|
||||
import { RaceEventRepository } from '../../domain/repositories/RaceEventRepository';
|
||||
import { RaceRegistrationRepository } from '../../domain/repositories/RaceRegistrationRepository';
|
||||
import { PenaltyRepository } from '../../domain/repositories/PenaltyRepository';
|
||||
|
||||
export type CloseRaceEventStewardingInput = {
|
||||
raceId: string;
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { DriverRepository } from '../../domain/repositories/DriverRepositor
|
||||
import { Driver } from '../../domain/entities/Driver';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import type { Logger } from '@core/shared/application/Logger';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
|
||||
export interface CompleteDriverOnboardingInput {
|
||||
userId: string;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, it, expect, beforeEach, vi, Mock } from 'vitest';
|
||||
import { CompleteRaceUseCase, type CompleteRaceInput, type CompleteRaceResult } from './CompleteRaceUseCase';
|
||||
import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
|
||||
import { CompleteRaceUseCase, type CompleteRaceInput } from './CompleteRaceUseCase';
|
||||
import type { RaceRepository } from '../../domain/repositories/RaceRepository';
|
||||
import type { RaceRegistrationRepository } from '../../domain/repositories/RaceRegistrationRepository';
|
||||
import type { ResultRepository } from '../../domain/repositories/ResultRepository';
|
||||
@@ -39,10 +39,10 @@ describe('CompleteRaceUseCase', () => {
|
||||
save: vi.fn(),
|
||||
};
|
||||
getDriverRating = vi.fn();
|
||||
useCase = new CompleteRaceUseCase(raceRepository as any,
|
||||
raceRegistrationRepository as any,
|
||||
resultRepository as any,
|
||||
standingRepository as any,
|
||||
useCase = new CompleteRaceUseCase(raceRepository as unknown as RaceRepository,
|
||||
raceRegistrationRepository as unknown as RaceRegistrationRepository,
|
||||
resultRepository as unknown as ResultRepository,
|
||||
standingRepository as unknown as StandingRepository,
|
||||
getDriverRating);
|
||||
});
|
||||
|
||||
|
||||
@@ -4,7 +4,16 @@ import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorC
|
||||
|
||||
import { Race } from '../../domain/entities/Race';
|
||||
import type { Season } from '../../domain/entities/season/Season';
|
||||
import { SeasonRepository } from '../../domain/repositories/SeasonRepository';
|
||||
import { RaceRepository } from '../../domain/repositories/RaceRepository';
|
||||
|
||||
export interface CreateLeagueSeasonScheduleRaceInput {
|
||||
leagueId: string;
|
||||
seasonId: string;
|
||||
track: string;
|
||||
car: string;
|
||||
scheduledAt: Date;
|
||||
}
|
||||
|
||||
export type CreateLeagueSeasonScheduleRaceResult = {
|
||||
raceId: string;
|
||||
@@ -88,6 +97,9 @@ export class CreateLeagueSeasonScheduleRaceUseCase {
|
||||
}
|
||||
|
||||
private isWithinSeasonWindow(season: Season, scheduledAt: Date): boolean {
|
||||
if (!season.startDate || !season.endDate) {
|
||||
return true;
|
||||
}
|
||||
return scheduledAt >= season.startDate && scheduledAt <= season.endDate;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { League } from '@/racing/domain/entities/League';
|
||||
import { League } from '../../domain/entities/League';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
@@ -13,6 +13,9 @@ import {
|
||||
MIN_RANKED_LEAGUE_DRIVERS,
|
||||
} from '../../domain/value-objects/LeagueVisibility';
|
||||
import { PointsTable } from '../../domain/value-objects/PointsTable';
|
||||
import { LeagueRepository } from '../../domain/repositories/LeagueRepository';
|
||||
import { SeasonRepository } from '../../domain/repositories/SeasonRepository';
|
||||
import { LeagueScoringConfigRepository } from '../../domain/repositories/LeagueScoringConfigRepository';
|
||||
|
||||
export type CreateLeagueWithSeasonAndScoringCommand = {
|
||||
name: string;
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
import { describe, it, expect, vi, Mock, beforeEach } from 'vitest';
|
||||
import { describe, it, expect, vi, type Mock, beforeEach } from 'vitest';
|
||||
import { Season } from '@core/racing/domain/entities/season/Season';
|
||||
import type { SeasonRepository } from '@core/racing/domain/repositories/SeasonRepository';
|
||||
import type { LeagueRepository } from '@core/racing/domain/repositories/LeagueRepository';
|
||||
import {
|
||||
CreateSeasonForLeagueUseCase,
|
||||
type CreateSeasonForLeagueInput,
|
||||
type CreateSeasonForLeagueResult,
|
||||
type LeagueConfigFormModel,
|
||||
} from '@core/racing/application/use-cases/CreateSeasonForLeagueUseCase';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
|
||||
function createLeagueConfigFormModel(overrides?: Partial<LeagueConfigFormModel>): LeagueConfigFormModel {
|
||||
return {
|
||||
@@ -68,13 +65,18 @@ function createLeagueConfigFormModel(overrides?: Partial<LeagueConfigFormModel>)
|
||||
};
|
||||
}
|
||||
|
||||
type CreateSeasonErrorCode = ApplicationErrorCode<'LEAGUE_NOT_FOUND' | 'VALIDATION_ERROR' | 'REPOSITORY_ERROR'> & {
|
||||
details?: { message: string };
|
||||
};
|
||||
|
||||
describe('CreateSeasonForLeagueUseCase', () => {
|
||||
const mockLeagueFindById = vi.fn();
|
||||
const mockLeagueRepo: any = {
|
||||
const mockLeagueRepo: {
|
||||
findById: Mock;
|
||||
findAll: Mock;
|
||||
findByOwnerId: Mock;
|
||||
create: Mock;
|
||||
update: Mock;
|
||||
delete: Mock;
|
||||
exists: Mock;
|
||||
searchByName: Mock;
|
||||
} = {
|
||||
findById: mockLeagueFindById,
|
||||
findAll: vi.fn(),
|
||||
findByOwnerId: vi.fn(),
|
||||
@@ -87,7 +89,15 @@ describe('CreateSeasonForLeagueUseCase', () => {
|
||||
|
||||
const mockSeasonFindById = vi.fn();
|
||||
const mockSeasonAdd = vi.fn();
|
||||
const mockSeasonRepo: any = {
|
||||
const mockSeasonRepo: {
|
||||
findById: Mock;
|
||||
findByLeagueId: Mock;
|
||||
create: Mock;
|
||||
add: Mock;
|
||||
update: Mock;
|
||||
listByLeague: Mock;
|
||||
listActiveByLeague: Mock;
|
||||
} = {
|
||||
findById: mockSeasonFindById,
|
||||
findByLeagueId: vi.fn(),
|
||||
create: vi.fn(),
|
||||
@@ -105,7 +115,10 @@ describe('CreateSeasonForLeagueUseCase', () => {
|
||||
mockLeagueFindById.mockResolvedValue({ id: 'league-1' });
|
||||
mockSeasonAdd.mockResolvedValue(undefined);
|
||||
|
||||
const useCase = new CreateSeasonForLeagueUseCase(mockLeagueRepo, mockSeasonRepo);
|
||||
const useCase = new CreateSeasonForLeagueUseCase(
|
||||
mockLeagueRepo as unknown as LeagueRepository,
|
||||
mockSeasonRepo as unknown as SeasonRepository
|
||||
);
|
||||
|
||||
const config = createLeagueConfigFormModel({
|
||||
basics: {
|
||||
@@ -157,7 +170,10 @@ describe('CreateSeasonForLeagueUseCase', () => {
|
||||
mockSeasonFindById.mockResolvedValue(sourceSeason);
|
||||
mockSeasonAdd.mockResolvedValue(undefined);
|
||||
|
||||
const useCase = new CreateSeasonForLeagueUseCase(mockLeagueRepo, mockSeasonRepo);
|
||||
const useCase = new CreateSeasonForLeagueUseCase(
|
||||
mockLeagueRepo as unknown as LeagueRepository,
|
||||
mockSeasonRepo as unknown as SeasonRepository
|
||||
);
|
||||
|
||||
const command: CreateSeasonForLeagueInput = {
|
||||
leagueId: 'league-1',
|
||||
@@ -177,7 +193,10 @@ describe('CreateSeasonForLeagueUseCase', () => {
|
||||
it('returns error when league not found', async () => {
|
||||
mockLeagueFindById.mockResolvedValue(null);
|
||||
|
||||
const useCase = new CreateSeasonForLeagueUseCase(mockLeagueRepo, mockSeasonRepo);
|
||||
const useCase = new CreateSeasonForLeagueUseCase(
|
||||
mockLeagueRepo as unknown as LeagueRepository,
|
||||
mockSeasonRepo as unknown as SeasonRepository
|
||||
);
|
||||
|
||||
const command: CreateSeasonForLeagueInput = {
|
||||
leagueId: 'missing-league',
|
||||
@@ -197,7 +216,10 @@ describe('CreateSeasonForLeagueUseCase', () => {
|
||||
mockLeagueFindById.mockResolvedValue({ id: 'league-1' });
|
||||
mockSeasonFindById.mockResolvedValue(undefined);
|
||||
|
||||
const useCase = new CreateSeasonForLeagueUseCase(mockLeagueRepo, mockSeasonRepo);
|
||||
const useCase = new CreateSeasonForLeagueUseCase(
|
||||
mockLeagueRepo as unknown as LeagueRepository,
|
||||
mockSeasonRepo as unknown as SeasonRepository
|
||||
);
|
||||
|
||||
const command: CreateSeasonForLeagueInput = {
|
||||
leagueId: 'league-1',
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
*
|
||||
* Creates a new sponsor.
|
||||
*/
|
||||
import { ApplicationErrorCode } from '@/shared/errors/ApplicationErrorCode';
|
||||
import { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { Sponsor } from '../../domain/entities/sponsor/Sponsor';
|
||||
import { SponsorRepository } from '../../domain/repositories/SponsorRepository';
|
||||
|
||||
export interface CreateSponsorInput {
|
||||
name: string;
|
||||
|
||||
@@ -3,6 +3,9 @@ import {
|
||||
CreateTeamUseCase,
|
||||
type CreateTeamInput
|
||||
} from './CreateTeamUseCase';
|
||||
import { TeamRepository } from '../../domain/repositories/TeamRepository';
|
||||
import { TeamMembershipRepository } from '../../domain/repositories/TeamMembershipRepository';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
|
||||
describe('CreateTeamUseCase', () => {
|
||||
let useCase: CreateTeamUseCase;
|
||||
@@ -34,9 +37,9 @@ describe('CreateTeamUseCase', () => {
|
||||
warn: vi.fn(),
|
||||
error: vi.fn(),
|
||||
};
|
||||
useCase = new CreateTeamUseCase(teamRepository as any,
|
||||
membershipRepository as any,
|
||||
logger as any);
|
||||
useCase = new CreateTeamUseCase(teamRepository as unknown as TeamRepository,
|
||||
membershipRepository as unknown as TeamMembershipRepository,
|
||||
logger as unknown as Logger);
|
||||
});
|
||||
|
||||
it('should create team successfully', async () => {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Creates a new team.
|
||||
*/
|
||||
import { Result } from '@/shared/domain/Result';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
@@ -13,6 +13,9 @@ import type {
|
||||
TeamMembershipStatus,
|
||||
TeamRole,
|
||||
} from '../../domain/types/TeamMembership';
|
||||
import { TeamRepository } from '../../domain/repositories/TeamRepository';
|
||||
import { TeamMembershipRepository } from '../../domain/repositories/TeamMembershipRepository';
|
||||
|
||||
export interface CreateTeamInput {
|
||||
name: string;
|
||||
tag: string;
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import { SeasonRepository } from '../../domain/repositories/SeasonRepository';
|
||||
import { RaceRepository } from '../../domain/repositories/RaceRepository';
|
||||
|
||||
|
||||
export interface DeleteLeagueSeasonScheduleRaceInput {
|
||||
leagueId: string;
|
||||
seasonId: string;
|
||||
raceId: string;
|
||||
}
|
||||
|
||||
export type DeleteLeagueSeasonScheduleRaceResult = {
|
||||
success: true;
|
||||
|
||||
@@ -3,7 +3,8 @@ import { beforeEach, describe, expect, it, Mock, vi } from 'vitest';
|
||||
import type { LeagueMembershipRepository } from '../../domain/repositories/LeagueMembershipRepository';
|
||||
import type { ProtestRepository } from '../../domain/repositories/ProtestRepository';
|
||||
import type { RaceRepository } from '../../domain/repositories/RaceRepository';
|
||||
import { FileProtestUseCase, type FileProtestErrorCode, type FileProtestInput, type FileProtestResult } from './FileProtestUseCase';
|
||||
import { FileProtestUseCase, type FileProtestErrorCode, type FileProtestInput } from './FileProtestUseCase';
|
||||
import { Protest } from '../../domain/entities/Protest';
|
||||
|
||||
describe('FileProtestUseCase', () => {
|
||||
let mockProtestRepo: {
|
||||
@@ -29,9 +30,11 @@ describe('FileProtestUseCase', () => {
|
||||
});
|
||||
|
||||
it('should return error when race does not exist', async () => {
|
||||
const useCase = new FileProtestUseCase(mockProtestRepo as any,
|
||||
mockRaceRepo as any,
|
||||
mockLeagueMembershipRepo as any);
|
||||
const useCase = new FileProtestUseCase(
|
||||
mockProtestRepo as unknown as ProtestRepository,
|
||||
mockRaceRepo as unknown as RaceRepository,
|
||||
mockLeagueMembershipRepo as unknown as LeagueMembershipRepository
|
||||
);
|
||||
|
||||
mockRaceRepo.findById.mockResolvedValue(null);
|
||||
|
||||
@@ -49,9 +52,11 @@ describe('FileProtestUseCase', () => {
|
||||
});
|
||||
|
||||
it('should return error when protesting against self', async () => {
|
||||
const useCase = new FileProtestUseCase(mockProtestRepo as any,
|
||||
mockRaceRepo as any,
|
||||
mockLeagueMembershipRepo as any);
|
||||
const useCase = new FileProtestUseCase(
|
||||
mockProtestRepo as unknown as ProtestRepository,
|
||||
mockRaceRepo as unknown as RaceRepository,
|
||||
mockLeagueMembershipRepo as unknown as LeagueMembershipRepository
|
||||
);
|
||||
|
||||
mockRaceRepo.findById.mockResolvedValue({ id: 'race1', leagueId: 'league1' });
|
||||
|
||||
@@ -69,9 +74,11 @@ describe('FileProtestUseCase', () => {
|
||||
});
|
||||
|
||||
it('should return error when protesting driver is not an active member', async () => {
|
||||
const useCase = new FileProtestUseCase(mockProtestRepo as any,
|
||||
mockRaceRepo as any,
|
||||
mockLeagueMembershipRepo as any);
|
||||
const useCase = new FileProtestUseCase(
|
||||
mockProtestRepo as unknown as ProtestRepository,
|
||||
mockRaceRepo as unknown as RaceRepository,
|
||||
mockLeagueMembershipRepo as unknown as LeagueMembershipRepository
|
||||
);
|
||||
|
||||
mockRaceRepo.findById.mockResolvedValue({ id: 'race1', leagueId: 'league1' });
|
||||
mockLeagueMembershipRepo.getLeagueMembers.mockResolvedValue([
|
||||
@@ -92,9 +99,11 @@ describe('FileProtestUseCase', () => {
|
||||
});
|
||||
|
||||
it('should create protest and return protestId on success', async () => {
|
||||
const useCase = new FileProtestUseCase(mockProtestRepo as any,
|
||||
mockRaceRepo as any,
|
||||
mockLeagueMembershipRepo as any);
|
||||
const useCase = new FileProtestUseCase(
|
||||
mockProtestRepo as unknown as ProtestRepository,
|
||||
mockRaceRepo as unknown as RaceRepository,
|
||||
mockLeagueMembershipRepo as unknown as LeagueMembershipRepository
|
||||
);
|
||||
|
||||
mockRaceRepo.findById.mockResolvedValue({ id: 'race1', leagueId: 'league1' });
|
||||
mockLeagueMembershipRepo.getLeagueMembers.mockResolvedValue([
|
||||
@@ -114,7 +123,7 @@ describe('FileProtestUseCase', () => {
|
||||
expect(result.isOk()).toBe(true);
|
||||
const presented = result.unwrap();
|
||||
expect(mockProtestRepo.create).toHaveBeenCalledTimes(1);
|
||||
const created = (mockProtestRepo.create as unknown as Mock).mock.calls[0]?.[0] as any;
|
||||
const created = (mockProtestRepo.create as unknown as Mock).mock.calls[0]?.[0] as Protest;
|
||||
|
||||
expect(created.raceId.toString()).toBe('race1');
|
||||
expect(created.protestingDriverId.toString()).toBe('driver1');
|
||||
|
||||
@@ -27,11 +27,11 @@ describe('GetAllLeaguesWithCapacityAndScoringUseCase', () => {
|
||||
|
||||
it('should return enriched leagues with capacity and scoring', async () => {
|
||||
const useCase = new GetAllLeaguesWithCapacityAndScoringUseCase(
|
||||
mockLeagueRepo as any,
|
||||
mockMembershipRepo as any,
|
||||
mockSeasonRepo as any,
|
||||
mockScoringConfigRepo as any,
|
||||
mockGameRepo as any,
|
||||
mockLeagueRepo as unknown as LeagueRepository,
|
||||
mockMembershipRepo as unknown as LeagueMembershipRepository,
|
||||
mockSeasonRepo as unknown as SeasonRepository,
|
||||
mockScoringConfigRepo as unknown as LeagueScoringConfigRepository,
|
||||
mockGameRepo as unknown as GameRepository,
|
||||
{ getPresetById: vi.fn().mockReturnValue({ id: 'preset1', name: 'Default' }) }
|
||||
);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { beforeEach, describe, expect, it, vi, type Mock } from 'vitest';
|
||||
import { League } from '../../domain/entities/League';
|
||||
import { Race } from '../../domain/entities/Race';
|
||||
import {
|
||||
@@ -7,9 +7,24 @@ import {
|
||||
type GetAllRacesPageDataInput
|
||||
} from './GetAllRacesPageDataUseCase';
|
||||
|
||||
import { RaceRepository } from '../../domain/repositories/RaceRepository';
|
||||
import { LeagueRepository } from '../../domain/repositories/LeagueRepository';
|
||||
|
||||
describe('GetAllRacesPageDataUseCase', () => {
|
||||
const mockRaceFindAll = vi.fn();
|
||||
const mockRaceRepo: any = {
|
||||
const mockRaceRepo: {
|
||||
findById: Mock;
|
||||
findAll: Mock;
|
||||
findByLeagueId: Mock;
|
||||
findUpcomingByLeagueId: Mock;
|
||||
findCompletedByLeagueId: Mock;
|
||||
findByStatus: Mock;
|
||||
findByDateRange: Mock;
|
||||
create: Mock;
|
||||
update: Mock;
|
||||
delete: Mock;
|
||||
exists: Mock;
|
||||
} = {
|
||||
findById: vi.fn(),
|
||||
findAll: mockRaceFindAll,
|
||||
findByLeagueId: vi.fn(),
|
||||
@@ -24,7 +39,16 @@ describe('GetAllRacesPageDataUseCase', () => {
|
||||
};
|
||||
|
||||
const mockLeagueFindAll = vi.fn();
|
||||
const mockLeagueRepo: any = {
|
||||
const mockLeagueRepo: {
|
||||
findById: Mock;
|
||||
findAll: Mock;
|
||||
findByOwnerId: Mock;
|
||||
create: Mock;
|
||||
update: Mock;
|
||||
delete: Mock;
|
||||
exists: Mock;
|
||||
searchByName: Mock;
|
||||
} = {
|
||||
findById: vi.fn(),
|
||||
findAll: mockLeagueFindAll,
|
||||
findByOwnerId: vi.fn(),
|
||||
@@ -47,9 +71,11 @@ describe('GetAllRacesPageDataUseCase', () => {
|
||||
});
|
||||
|
||||
it('should return races and filters data', async () => {
|
||||
const useCase = new GetAllRacesPageDataUseCase(mockRaceRepo,
|
||||
mockLeagueRepo,
|
||||
mockLogger);
|
||||
const useCase = new GetAllRacesPageDataUseCase(
|
||||
mockRaceRepo as unknown as RaceRepository,
|
||||
mockLeagueRepo as unknown as LeagueRepository,
|
||||
mockLogger
|
||||
);
|
||||
|
||||
const race1 = Race.create({
|
||||
id: 'race1',
|
||||
@@ -132,9 +158,11 @@ describe('GetAllRacesPageDataUseCase', () => {
|
||||
});
|
||||
|
||||
it('should return empty result when no races or leagues', async () => {
|
||||
const useCase = new GetAllRacesPageDataUseCase(mockRaceRepo,
|
||||
mockLeagueRepo,
|
||||
mockLogger);
|
||||
const useCase = new GetAllRacesPageDataUseCase(
|
||||
mockRaceRepo as unknown as RaceRepository,
|
||||
mockLeagueRepo as unknown as LeagueRepository,
|
||||
mockLogger
|
||||
);
|
||||
|
||||
mockRaceFindAll.mockResolvedValue([]);
|
||||
mockLeagueFindAll.mockResolvedValue([]);
|
||||
@@ -157,9 +185,11 @@ describe('GetAllRacesPageDataUseCase', () => {
|
||||
});
|
||||
|
||||
it('should return error when repository throws', async () => {
|
||||
const useCase = new GetAllRacesPageDataUseCase(mockRaceRepo,
|
||||
mockLeagueRepo,
|
||||
mockLogger);
|
||||
const useCase = new GetAllRacesPageDataUseCase(
|
||||
mockRaceRepo as unknown as RaceRepository,
|
||||
mockLeagueRepo as unknown as LeagueRepository,
|
||||
mockLogger
|
||||
);
|
||||
|
||||
const error = new Error('Repository error');
|
||||
mockRaceFindAll.mockRejectedValue(error);
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import type { RaceStatusValue } from '../../domain/entities/Race';
|
||||
import type { Race, RaceStatusValue } from '../../domain/entities/Race';
|
||||
import { RaceRepository } from '../../domain/repositories/RaceRepository';
|
||||
import { LeagueRepository } from '../../domain/repositories/LeagueRepository';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import type { League } from '../../domain/entities/League';
|
||||
|
||||
export type GetAllRacesPageDataInput = {};
|
||||
|
||||
@@ -46,12 +50,12 @@ export class GetAllRacesPageDataUseCase {
|
||||
]);
|
||||
this.logger.info(`Found ${allRaces.length} races and ${allLeagues.length} leagues.`);
|
||||
|
||||
const leagueMap = new Map(allLeagues.map(league => [league.id.toString(), league.name.toString()]));
|
||||
const leagueMap = new Map(allLeagues.map((league: League) => [league.id.toString(), league.name.toString()]));
|
||||
|
||||
const races: GetAllRacesPageRaceItem[] = allRaces
|
||||
.slice()
|
||||
.sort((a, b) => b.scheduledAt.getTime() - a.scheduledAt.getTime())
|
||||
.map(race => ({
|
||||
.sort((a: Race, b: Race) => b.scheduledAt.getTime() - a.scheduledAt.getTime())
|
||||
.map((race: Race) => ({
|
||||
id: race.id,
|
||||
track: race.track,
|
||||
car: race.car,
|
||||
|
||||
@@ -2,6 +2,9 @@ import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import type { League } from '../../domain/entities/League';
|
||||
import type { Race } from '../../domain/entities/Race';
|
||||
import { RaceRepository } from '../../domain/repositories/RaceRepository';
|
||||
import { LeagueRepository } from '../../domain/repositories/LeagueRepository';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
|
||||
export type GetAllRacesInput = {};
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { Team } from '@/racing/domain/entities/Team';
|
||||
import { Team } from '../../domain/entities/Team';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import { TeamRepository } from '../../domain/repositories/TeamRepository';
|
||||
import { TeamMembershipRepository } from '../../domain/repositories/TeamMembershipRepository';
|
||||
import { TeamStatsRepository } from '../../domain/repositories/TeamStatsRepository';
|
||||
|
||||
export interface GetAllTeamsInput {}
|
||||
|
||||
@@ -39,6 +42,7 @@ export class GetAllTeamsUseCase {
|
||||
async execute(
|
||||
_input: GetAllTeamsInput,
|
||||
): Promise<Result<GetAllTeamsResult, ApplicationErrorCode<GetAllTeamsErrorCode, { message: string }>>> {
|
||||
void _input;
|
||||
this.logger.debug('GetAllTeamsUseCase: Fetching all teams');
|
||||
|
||||
try {
|
||||
@@ -71,7 +75,7 @@ export class GetAllTeamsUseCase {
|
||||
rating: stats?.rating ?? 0,
|
||||
logoUrl: logoUrl ?? null,
|
||||
description: team.description.toString(),
|
||||
leagues: team.leagues.map(l => l.toString()),
|
||||
leagues: team.leagues.map((l) => l.toString()),
|
||||
isRecruiting: team.isRecruiting,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -4,11 +4,12 @@
|
||||
* Retrieves all liveries for a specific driver.
|
||||
*/
|
||||
|
||||
import { DriverLivery } from '@/racing/domain/entities/DriverLivery';
|
||||
import { DriverLivery } from '../../domain/entities/DriverLivery';
|
||||
import { UseCase } from '@core/shared/application/UseCase';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import { LiveryRepository } from '../../domain/repositories/LiveryRepository';
|
||||
|
||||
export interface GetDriverLiveriesInput {
|
||||
driverId: string;
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { TeamMembership } from '@/racing/domain/types/TeamMembership';
|
||||
import { TeamMembership } from '../../domain/types/TeamMembership';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import type { Team } from '../../domain/entities/Team';
|
||||
import { TeamRepository } from '../../domain/repositories/TeamRepository';
|
||||
import { TeamMembershipRepository } from '../../domain/repositories/TeamMembershipRepository';
|
||||
|
||||
export interface GetDriverTeamInput {
|
||||
driverId: string;
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorC
|
||||
import type { Driver } from '../../domain/entities/Driver';
|
||||
import type { Team } from '../../domain/entities/Team';
|
||||
import type { DriverRepository } from '../../domain/repositories/DriverRepository';
|
||||
import type { DriverStatsUseCase } from './DriverStatsUseCase';
|
||||
import type { DriverStats, DriverStatsUseCase } from './DriverStatsUseCase';
|
||||
import type { RankingUseCase } from './RankingUseCase';
|
||||
import { SkillLevelService, type SkillLevel } from '../../domain/services/SkillLevelService';
|
||||
import { MediaReference } from '@core/domain/media/MediaReference';
|
||||
@@ -71,10 +71,11 @@ export class GetDriversLeaderboardUseCase implements UseCase<GetDriversLeaderboa
|
||||
this.driverStatsUseCase.getDriverStats(driver.id)
|
||||
);
|
||||
const statsResults = await Promise.all(statsPromises);
|
||||
const statsMap = new Map<string, any>();
|
||||
const statsMap = new Map<string, DriverStats>();
|
||||
drivers.forEach((driver, idx) => {
|
||||
if (statsResults[idx]) {
|
||||
statsMap.set(driver.id, statsResults[idx]);
|
||||
const stats = statsResults[idx];
|
||||
if (stats) {
|
||||
statsMap.set(driver.id, stats);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import type { SponsorableEntityType } from '../../domain/entities/SponsorshipRequest';
|
||||
import { SponsorshipPricingRepository } from '../../domain/repositories/SponsorshipPricingRepository';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
|
||||
export type SponsorshipEntityType = SponsorableEntityType;
|
||||
|
||||
|
||||
@@ -2,7 +2,13 @@ import type { Logger } from '@core/shared/domain/Logger';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import type { League } from '../../domain/entities/League';
|
||||
import { LeagueRepository } from '../../domain/repositories/LeagueRepository';
|
||||
import { LeagueMembershipRepository } from '../../domain/repositories/LeagueMembershipRepository';
|
||||
|
||||
export interface GetLeagueAdminPermissionsInput {
|
||||
leagueId: string;
|
||||
performerDriverId: string;
|
||||
}
|
||||
|
||||
export type LeagueAdminPermissions = {
|
||||
canManageSchedule: boolean;
|
||||
|
||||
@@ -1,15 +1,23 @@
|
||||
import { describe, it, expect, beforeEach, vi, Mock } from 'vitest';
|
||||
import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
|
||||
import {
|
||||
GetLeagueAdminUseCase,
|
||||
type GetLeagueAdminInput,
|
||||
type GetLeagueAdminResult,
|
||||
type GetLeagueAdminErrorCode,
|
||||
} from './GetLeagueAdminUseCase';
|
||||
import type { LeagueRepository } from '../../domain/repositories/LeagueRepository';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
|
||||
describe('GetLeagueAdminUseCase', () => {
|
||||
let mockLeagueRepo: any;
|
||||
let mockLeagueRepo: {
|
||||
findById: Mock;
|
||||
findAll: Mock;
|
||||
create: Mock;
|
||||
update: Mock;
|
||||
delete: Mock;
|
||||
exists: Mock;
|
||||
findByOwnerId: Mock;
|
||||
searchByName: Mock;
|
||||
};
|
||||
let mockFindById: Mock;
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -26,7 +34,7 @@ describe('GetLeagueAdminUseCase', () => {
|
||||
};
|
||||
});
|
||||
|
||||
const createUseCase = () => new GetLeagueAdminUseCase(mockLeagueRepo);
|
||||
const createUseCase = () => new GetLeagueAdminUseCase(mockLeagueRepo as unknown as LeagueRepository);
|
||||
|
||||
const params: GetLeagueAdminInput = {
|
||||
leagueId: 'league1',
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { describe, it, expect, beforeEach, vi, Mock } from 'vitest';
|
||||
import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
|
||||
import {
|
||||
GetLeagueDriverSeasonStatsUseCase,
|
||||
type GetLeagueDriverSeasonStatsErrorCode,
|
||||
type GetLeagueDriverSeasonStatsInput,
|
||||
type GetLeagueDriverSeasonStatsResult,
|
||||
} from './GetLeagueDriverSeasonStatsUseCase';
|
||||
import type { StandingRepository } from '../../domain/repositories/StandingRepository';
|
||||
import type { ResultRepository } from '../../domain/repositories/ResultRepository';
|
||||
@@ -22,12 +21,70 @@ describe('GetLeagueDriverSeasonStatsUseCase', () => {
|
||||
const mockDriverFindById = vi.fn();
|
||||
|
||||
let useCase: GetLeagueDriverSeasonStatsUseCase;
|
||||
let standingRepository: any;
|
||||
let resultRepository: any;
|
||||
let penaltyRepository: any;
|
||||
let raceRepository: any;
|
||||
let driverRepository: any;
|
||||
let driverRatingPort: any;
|
||||
let standingRepository: {
|
||||
findByLeagueId: Mock;
|
||||
findByDriverIdAndLeagueId: Mock;
|
||||
findAll: Mock;
|
||||
save: Mock;
|
||||
saveMany: Mock;
|
||||
delete: Mock;
|
||||
deleteByLeagueId: Mock;
|
||||
exists: Mock;
|
||||
recalculate: Mock;
|
||||
};
|
||||
let resultRepository: {
|
||||
findById: Mock;
|
||||
findAll: Mock;
|
||||
findByRaceId: Mock;
|
||||
findByDriverId: Mock;
|
||||
findByDriverIdAndLeagueId: Mock;
|
||||
create: Mock;
|
||||
createMany: Mock;
|
||||
update: Mock;
|
||||
delete: Mock;
|
||||
deleteByRaceId: Mock;
|
||||
exists: Mock;
|
||||
existsByRaceId: Mock;
|
||||
};
|
||||
let penaltyRepository: {
|
||||
findById: Mock;
|
||||
findByDriverId: Mock;
|
||||
findByProtestId: Mock;
|
||||
findPending: Mock;
|
||||
findByRaceId: Mock;
|
||||
findIssuedBy: Mock;
|
||||
create: Mock;
|
||||
update: Mock;
|
||||
exists: Mock;
|
||||
};
|
||||
let raceRepository: {
|
||||
findById: Mock;
|
||||
findAll: Mock;
|
||||
findByLeagueId: Mock;
|
||||
findUpcomingByLeagueId: Mock;
|
||||
findCompletedByLeagueId: Mock;
|
||||
findByStatus: Mock;
|
||||
findByDateRange: Mock;
|
||||
create: Mock;
|
||||
update: Mock;
|
||||
delete: Mock;
|
||||
exists: Mock;
|
||||
};
|
||||
let driverRepository: {
|
||||
findById: Mock;
|
||||
findByIRacingId: Mock;
|
||||
findAll: Mock;
|
||||
create: Mock;
|
||||
update: Mock;
|
||||
delete: Mock;
|
||||
exists: Mock;
|
||||
existsByIRacingId: Mock;
|
||||
};
|
||||
let driverRatingPort: {
|
||||
getDriverRating: Mock;
|
||||
calculateRatingChange: Mock;
|
||||
updateDriverRating: Mock;
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
mockStandingFindByLeagueId.mockReset();
|
||||
@@ -102,12 +159,14 @@ describe('GetLeagueDriverSeasonStatsUseCase', () => {
|
||||
updateDriverRating: vi.fn(),
|
||||
};
|
||||
|
||||
useCase = new GetLeagueDriverSeasonStatsUseCase(standingRepository,
|
||||
resultRepository,
|
||||
penaltyRepository,
|
||||
raceRepository,
|
||||
driverRepository,
|
||||
driverRatingPort);
|
||||
useCase = new GetLeagueDriverSeasonStatsUseCase(
|
||||
standingRepository as unknown as StandingRepository,
|
||||
resultRepository as unknown as ResultRepository,
|
||||
penaltyRepository as unknown as PenaltyRepository,
|
||||
raceRepository as unknown as RaceRepository,
|
||||
driverRepository as unknown as DriverRepository,
|
||||
driverRatingPort as unknown as DriverRatingPort
|
||||
);
|
||||
});
|
||||
|
||||
it('should return league driver season stats for given league id', async () => {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { describe, it, expect, vi, beforeEach, type Mock } from 'vitest';
|
||||
import {
|
||||
GetLeagueFullConfigUseCase,
|
||||
type GetLeagueFullConfigInput,
|
||||
type GetLeagueFullConfigResult,
|
||||
type GetLeagueFullConfigErrorCode,
|
||||
} from './GetLeagueFullConfigUseCase';
|
||||
import type { LeagueRepository } from '../../domain/repositories/LeagueRepository';
|
||||
@@ -13,10 +12,10 @@ import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorC
|
||||
|
||||
describe('GetLeagueFullConfigUseCase', () => {
|
||||
let useCase: GetLeagueFullConfigUseCase;
|
||||
let leagueRepository: any;
|
||||
let seasonRepository: any;
|
||||
let leagueScoringConfigRepository: any;
|
||||
let gameRepository: any;
|
||||
let leagueRepository: { findById: Mock };
|
||||
let seasonRepository: { findByLeagueId: Mock };
|
||||
let leagueScoringConfigRepository: { findBySeasonId: Mock };
|
||||
let gameRepository: { findById: Mock };
|
||||
|
||||
beforeEach(() => {
|
||||
leagueRepository = {
|
||||
@@ -32,10 +31,12 @@ describe('GetLeagueFullConfigUseCase', () => {
|
||||
findById: vi.fn(),
|
||||
};
|
||||
|
||||
useCase = new GetLeagueFullConfigUseCase(leagueRepository,
|
||||
seasonRepository,
|
||||
leagueScoringConfigRepository,
|
||||
gameRepository);
|
||||
useCase = new GetLeagueFullConfigUseCase(
|
||||
leagueRepository as unknown as LeagueRepository,
|
||||
seasonRepository as unknown as SeasonRepository,
|
||||
leagueScoringConfigRepository as unknown as LeagueScoringConfigRepository,
|
||||
gameRepository as unknown as GameRepository
|
||||
);
|
||||
});
|
||||
|
||||
it('should return league config when league exists', async () => {
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
import { describe, it, expect, beforeEach, vi, Mock } from 'vitest';
|
||||
import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
|
||||
import {
|
||||
GetLeagueMembershipsUseCase,
|
||||
type GetLeagueMembershipsInput,
|
||||
type GetLeagueMembershipsResult,
|
||||
type GetLeagueMembershipsErrorCode,
|
||||
} from './GetLeagueMembershipsUseCase';
|
||||
import { LeagueMembership } from '../../domain/entities/LeagueMembership';
|
||||
import { Driver } from '../../domain/entities/Driver';
|
||||
import { League } from '../../domain/entities/League';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import type { LeagueMembershipRepository } from '../../domain/repositories/LeagueMembershipRepository';
|
||||
import type { DriverRepository } from '../../domain/repositories/DriverRepository';
|
||||
import type { LeagueRepository } from '../../domain/repositories/LeagueRepository';
|
||||
|
||||
describe('GetLeagueMembershipsUseCase', () => {
|
||||
let useCase: GetLeagueMembershipsUseCase;
|
||||
@@ -32,9 +34,11 @@ describe('GetLeagueMembershipsUseCase', () => {
|
||||
leagueRepository = {
|
||||
findById: vi.fn(),
|
||||
};
|
||||
useCase = new GetLeagueMembershipsUseCase(leagueMembershipRepository as any,
|
||||
driverRepository as any,
|
||||
leagueRepository as any);
|
||||
useCase = new GetLeagueMembershipsUseCase(
|
||||
leagueMembershipRepository as unknown as LeagueMembershipRepository,
|
||||
driverRepository as unknown as DriverRepository,
|
||||
leagueRepository as unknown as LeagueRepository
|
||||
);
|
||||
});
|
||||
|
||||
it('should return league memberships with drivers', async () => {
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
import { describe, it, expect, beforeEach, vi, Mock } from 'vitest';
|
||||
import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
|
||||
import {
|
||||
GetLeagueOwnerSummaryUseCase,
|
||||
type GetLeagueOwnerSummaryInput,
|
||||
type GetLeagueOwnerSummaryResult,
|
||||
type GetLeagueOwnerSummaryErrorCode,
|
||||
} from './GetLeagueOwnerSummaryUseCase';
|
||||
import { Driver } from '../../domain/entities/Driver';
|
||||
import { League } from '../../domain/entities/League';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import type { LeagueRepository } from '../../domain/repositories/LeagueRepository';
|
||||
import type { DriverRepository } from '../../domain/repositories/DriverRepository';
|
||||
import type { LeagueMembershipRepository } from '../../domain/repositories/LeagueMembershipRepository';
|
||||
import type { StandingRepository } from '../../domain/repositories/StandingRepository';
|
||||
|
||||
describe('GetLeagueOwnerSummaryUseCase', () => {
|
||||
let useCase: GetLeagueOwnerSummaryUseCase;
|
||||
@@ -40,10 +43,10 @@ describe('GetLeagueOwnerSummaryUseCase', () => {
|
||||
findByLeagueId: vi.fn(),
|
||||
};
|
||||
useCase = new GetLeagueOwnerSummaryUseCase(
|
||||
leagueRepository as any,
|
||||
driverRepository as any,
|
||||
leagueMembershipRepository as any,
|
||||
standingRepository as any
|
||||
leagueRepository as unknown as LeagueRepository,
|
||||
driverRepository as unknown as DriverRepository,
|
||||
leagueMembershipRepository as unknown as LeagueMembershipRepository,
|
||||
standingRepository as unknown as StandingRepository
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
|
||||
import {
|
||||
GetLeagueScheduleUseCase,
|
||||
type GetLeagueScheduleInput,
|
||||
type GetLeagueScheduleResult,
|
||||
type GetLeagueScheduleErrorCode,
|
||||
} from './GetLeagueScheduleUseCase';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
@@ -10,6 +9,8 @@ import type { League } from '../../domain/entities/League';
|
||||
import { Race } from '../../domain/entities/Race';
|
||||
import type { LeagueRepository } from '../../domain/repositories/LeagueRepository';
|
||||
import type { RaceRepository } from '../../domain/repositories/RaceRepository';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import type { SeasonRepository } from '../../domain/repositories/SeasonRepository';
|
||||
|
||||
describe('GetLeagueScheduleUseCase', () => {
|
||||
let useCase: GetLeagueScheduleUseCase;
|
||||
@@ -42,7 +43,7 @@ describe('GetLeagueScheduleUseCase', () => {
|
||||
error: vi.fn(),
|
||||
} as unknown as Logger;
|
||||
useCase = new GetLeagueScheduleUseCase(leagueRepository as unknown as LeagueRepository,
|
||||
seasonRepository as any,
|
||||
seasonRepository as unknown as SeasonRepository,
|
||||
raceRepository as unknown as RaceRepository,
|
||||
logger);
|
||||
});
|
||||
@@ -109,7 +110,7 @@ describe('GetLeagueScheduleUseCase', () => {
|
||||
raceRepository.findByLeagueId.mockResolvedValue([janRace, febRace]);
|
||||
|
||||
// Season 1 covers January
|
||||
const resultSeason1 = await useCase.execute({ leagueId, seasonId: 'season-jan' } as any);
|
||||
const resultSeason1 = await useCase.execute({ leagueId, seasonId: 'season-jan' });
|
||||
expect(resultSeason1.isOk()).toBe(true);
|
||||
const resultValue1 = resultSeason1.unwrap();
|
||||
expect(resultValue1.seasonId).toBe('season-jan');
|
||||
@@ -117,7 +118,7 @@ describe('GetLeagueScheduleUseCase', () => {
|
||||
expect(resultValue1.races.map(r => r.race.id)).toEqual(['race-jan']);
|
||||
|
||||
// Season 2 covers February
|
||||
const resultSeason2 = await useCase.execute({ leagueId, seasonId: 'season-feb' } as any);
|
||||
const resultSeason2 = await useCase.execute({ leagueId, seasonId: 'season-feb' });
|
||||
expect(resultSeason2.isOk()).toBe(true);
|
||||
const resultValue2 = resultSeason2.unwrap();
|
||||
expect(resultValue2.seasonId).toBe('season-feb');
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { SeasonScheduleGenerator } from '@/racing/domain/services/SeasonScheduleGenerator';
|
||||
import { SeasonScheduleGenerator } from '../../domain/services/SeasonScheduleGenerator';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import type { League } from '../../domain/entities/League';
|
||||
import type { Race } from '../../domain/entities/Race';
|
||||
import type { Season } from '../../domain/entities/season/Season';
|
||||
import { LeagueRepository } from '../../domain/repositories/LeagueRepository';
|
||||
import { SeasonRepository } from '../../domain/repositories/SeasonRepository';
|
||||
import { RaceRepository } from '../../domain/repositories/RaceRepository';
|
||||
|
||||
export type GetLeagueScheduleErrorCode =
|
||||
| 'LEAGUE_NOT_FOUND'
|
||||
@@ -51,7 +54,7 @@ export class GetLeagueScheduleUseCase {
|
||||
}
|
||||
|
||||
const seasons = await this.seasonRepository.findByLeagueId(params.leagueId);
|
||||
const activeSeason = seasons.find(s => s.status.isActive()) ?? seasons[0];
|
||||
const activeSeason = seasons.find((s: Season) => s.status.isActive()) ?? seasons[0];
|
||||
if (!activeSeason) {
|
||||
return Result.err({
|
||||
code: 'SEASON_NOT_FOUND',
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import { GetLeagueScoringConfigUseCase } from './GetLeagueScoringConfigUseCase';
|
||||
import type { LeagueRepository } from '../../domain/repositories/LeagueRepository';
|
||||
import type { SeasonRepository } from '../../domain/repositories/SeasonRepository';
|
||||
@@ -13,10 +12,26 @@ import type { LeagueScoringPreset } from '../../domain/types/LeagueScoringPreset
|
||||
|
||||
describe('GetLeagueScoringConfigUseCase', () => {
|
||||
let useCase: GetLeagueScoringConfigUseCase;
|
||||
let mockLeagueRepository: any;
|
||||
let mockSeasonRepository: any;
|
||||
let mockLeagueScoringConfigRepository: any;
|
||||
let mockGameRepository: any;
|
||||
let mockLeagueRepository: {
|
||||
findById: any;
|
||||
exists: any;
|
||||
save: any;
|
||||
findAll: any;
|
||||
};
|
||||
let mockSeasonRepository: {
|
||||
findByLeagueId: any;
|
||||
save: any;
|
||||
findById: any;
|
||||
};
|
||||
let mockLeagueScoringConfigRepository: {
|
||||
findBySeasonId: any;
|
||||
save: any;
|
||||
};
|
||||
let mockGameRepository: {
|
||||
findById: any;
|
||||
save: any;
|
||||
findAll: any;
|
||||
};
|
||||
let mockPresetProvider: { getPresetById: any };
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -49,11 +64,11 @@ describe('GetLeagueScoringConfigUseCase', () => {
|
||||
};
|
||||
|
||||
useCase = new GetLeagueScoringConfigUseCase(
|
||||
mockLeagueRepository,
|
||||
mockSeasonRepository,
|
||||
mockLeagueScoringConfigRepository,
|
||||
mockGameRepository,
|
||||
mockPresetProvider,
|
||||
mockLeagueRepository as unknown as LeagueRepository,
|
||||
mockSeasonRepository as unknown as SeasonRepository,
|
||||
mockLeagueScoringConfigRepository as unknown as LeagueScoringConfigRepository,
|
||||
mockGameRepository as unknown as GameRepository,
|
||||
mockPresetProvider as any,
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
|
||||
import {
|
||||
GetRaceDetailUseCase,
|
||||
type GetRaceDetailInput,
|
||||
type GetRaceDetailResult,
|
||||
type GetRaceDetailErrorCode,
|
||||
} from './GetRaceDetailUseCase';
|
||||
import type { RaceRepository } from '../../domain/repositories/RaceRepository';
|
||||
|
||||
@@ -2,7 +2,6 @@ import { describe, it, expect, beforeEach, vi, Mock } from 'vitest';
|
||||
import {
|
||||
GetRacePenaltiesUseCase,
|
||||
type GetRacePenaltiesInput,
|
||||
type GetRacePenaltiesResult,
|
||||
type GetRacePenaltiesErrorCode,
|
||||
} from './GetRacePenaltiesUseCase';
|
||||
import type { PenaltyRepository } from '../../domain/repositories/PenaltyRepository';
|
||||
|
||||
@@ -9,6 +9,9 @@ import { Protest } from '../../domain/entities/Protest';
|
||||
import { Driver } from '../../domain/entities/Driver';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
|
||||
import type { ProtestRepository } from '../../domain/repositories/ProtestRepository';
|
||||
import type { DriverRepository } from '../../domain/repositories/DriverRepository';
|
||||
|
||||
describe('GetRaceProtestsUseCase', () => {
|
||||
let useCase: GetRaceProtestsUseCase;
|
||||
let protestRepository: { findByRaceId: Mock };
|
||||
@@ -17,8 +20,10 @@ describe('GetRaceProtestsUseCase', () => {
|
||||
beforeEach(() => {
|
||||
protestRepository = { findByRaceId: vi.fn() };
|
||||
driverRepository = { findById: vi.fn() };
|
||||
useCase = new GetRaceProtestsUseCase(protestRepository as any,
|
||||
driverRepository as any);
|
||||
useCase = new GetRaceProtestsUseCase(
|
||||
protestRepository as unknown as ProtestRepository,
|
||||
driverRepository as unknown as DriverRepository
|
||||
);
|
||||
});
|
||||
|
||||
it('should return protests with drivers', async () => {
|
||||
|
||||
@@ -2,12 +2,13 @@ import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
|
||||
import {
|
||||
GetRaceRegistrationsUseCase,
|
||||
type GetRaceRegistrationsInput,
|
||||
type GetRaceRegistrationsResult,
|
||||
type GetRaceRegistrationsErrorCode,
|
||||
} from './GetRaceRegistrationsUseCase';
|
||||
import { RaceRegistration } from '@core/racing/domain/entities/RaceRegistration';
|
||||
import { Race } from '@core/racing/domain/entities/Race';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import type { RaceRepository } from '../../domain/repositories/RaceRepository';
|
||||
import type { RaceRegistrationRepository } from '../../domain/repositories/RaceRegistrationRepository';
|
||||
|
||||
describe('GetRaceRegistrationsUseCase', () => {
|
||||
let useCase: GetRaceRegistrationsUseCase;
|
||||
@@ -17,8 +18,10 @@ describe('GetRaceRegistrationsUseCase', () => {
|
||||
beforeEach(() => {
|
||||
raceRepository = { findById: vi.fn() };
|
||||
registrationRepository = { findByRaceId: vi.fn() };
|
||||
useCase = new GetRaceRegistrationsUseCase(raceRepository as any,
|
||||
registrationRepository as any);
|
||||
useCase = new GetRaceRegistrationsUseCase(
|
||||
raceRepository as unknown as RaceRepository,
|
||||
registrationRepository as unknown as RaceRegistrationRepository
|
||||
);
|
||||
});
|
||||
|
||||
it('should return race and registrations on success', async () => {
|
||||
|
||||
@@ -27,11 +27,13 @@ describe('GetRaceResultsDetailUseCase', () => {
|
||||
driverRepository = { findAll: vi.fn() };
|
||||
penaltyRepository = { findByRaceId: vi.fn() };
|
||||
|
||||
useCase = new GetRaceResultsDetailUseCase(raceRepository as any,
|
||||
leagueRepository as any,
|
||||
resultRepository as any,
|
||||
driverRepository as any,
|
||||
penaltyRepository as any);
|
||||
useCase = new GetRaceResultsDetailUseCase(
|
||||
raceRepository as unknown as RaceRepository,
|
||||
leagueRepository as unknown as LeagueRepository,
|
||||
resultRepository as unknown as ResultRepository,
|
||||
driverRepository as unknown as DriverRepository,
|
||||
penaltyRepository as unknown as PenaltyRepository
|
||||
);
|
||||
});
|
||||
|
||||
it('presents race results detail when race exists', async () => {
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
import { describe, it, expect, beforeEach, vi, Mock } from 'vitest';
|
||||
import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
|
||||
import {
|
||||
GetRaceWithSOFUseCase,
|
||||
type GetRaceWithSOFInput,
|
||||
type GetRaceWithSOFResult,
|
||||
type GetRaceWithSOFErrorCode,
|
||||
} from './GetRaceWithSOFUseCase';
|
||||
import { Race } from '../../domain/entities/Race';
|
||||
import { SessionType } from '../../domain/value-objects/SessionType';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import type { RaceRepository } from '../../domain/repositories/RaceRepository';
|
||||
import type { RaceRegistrationRepository } from '../../domain/repositories/RaceRegistrationRepository';
|
||||
import type { ResultRepository } from '../../domain/repositories/ResultRepository';
|
||||
|
||||
describe('GetRaceWithSOFUseCase', () => {
|
||||
let useCase: GetRaceWithSOFUseCase;
|
||||
@@ -34,10 +36,10 @@ describe('GetRaceWithSOFUseCase', () => {
|
||||
};
|
||||
getDriverRating = vi.fn();
|
||||
useCase = new GetRaceWithSOFUseCase(
|
||||
raceRepository as any,
|
||||
registrationRepository as any,
|
||||
resultRepository as any,
|
||||
getDriverRating
|
||||
raceRepository as unknown as RaceRepository,
|
||||
registrationRepository as unknown as RaceRegistrationRepository,
|
||||
resultRepository as unknown as ResultRepository,
|
||||
getDriverRating as any
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -2,7 +2,13 @@ import type { Logger } from '@core/shared/domain/Logger';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import type { Race } from '../../domain/entities/Race';
|
||||
import { RaceRepository } from '../../domain/repositories/RaceRepository';
|
||||
import { LeagueRepository } from '../../domain/repositories/LeagueRepository';
|
||||
import type { League } from '../../domain/entities/League';
|
||||
|
||||
export interface GetRacesPageDataInput {
|
||||
leagueId: string;
|
||||
}
|
||||
|
||||
export type GetRacesPageRaceItem = {
|
||||
race: Race;
|
||||
@@ -35,16 +41,16 @@ export class GetRacesPageDataUseCase {
|
||||
]);
|
||||
|
||||
const leagueMap = new Map(
|
||||
allLeagues.map(league => [league.id.toString(), league.name.toString()]),
|
||||
allLeagues.map((league: League) => [league.id.toString(), league.name.toString()]),
|
||||
);
|
||||
|
||||
const filteredRaces = input.leagueId
|
||||
? allRaces.filter(race => race.leagueId === input.leagueId)
|
||||
? allRaces.filter((race: Race) => race.leagueId === input.leagueId)
|
||||
: allRaces;
|
||||
|
||||
filteredRaces.sort((a, b) => a.scheduledAt.getTime() - b.scheduledAt.getTime());
|
||||
filteredRaces.sort((a: Race, b: Race) => a.scheduledAt.getTime() - b.scheduledAt.getTime());
|
||||
|
||||
const races: GetRacesPageRaceItem[] = filteredRaces.map(race => ({
|
||||
const races: GetRacesPageRaceItem[] = filteredRaces.map((race: Race) => ({
|
||||
race,
|
||||
leagueName: leagueMap.get(race.leagueId) ?? 'Unknown League',
|
||||
}));
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { describe, it, expect, beforeEach, vi, Mock } from 'vitest';
|
||||
import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
|
||||
import {
|
||||
GetSeasonDetailsUseCase,
|
||||
type GetSeasonDetailsInput,
|
||||
type GetSeasonDetailsResult,
|
||||
type GetSeasonDetailsErrorCode,
|
||||
} from './GetSeasonDetailsUseCase';
|
||||
import { Season } from '../../domain/entities/season/Season';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import type { SeasonRepository } from '../../domain/repositories/SeasonRepository';
|
||||
|
||||
describe('GetSeasonDetailsUseCase', () => {
|
||||
let useCase: GetSeasonDetailsUseCase;
|
||||
@@ -19,7 +19,7 @@ describe('GetSeasonDetailsUseCase', () => {
|
||||
findById: vi.fn(),
|
||||
};
|
||||
|
||||
useCase = new GetSeasonDetailsUseCase(seasonRepository as any);
|
||||
useCase = new GetSeasonDetailsUseCase(seasonRepository as unknown as SeasonRepository);
|
||||
});
|
||||
|
||||
it('returns full details for a season', async () => {
|
||||
|
||||
@@ -2,7 +2,6 @@ import { beforeEach, describe, expect, it, vi, type Mock } from 'vitest';
|
||||
import {
|
||||
GetSeasonSponsorshipsUseCase,
|
||||
type GetSeasonSponsorshipsInput,
|
||||
type GetSeasonSponsorshipsResult,
|
||||
type GetSeasonSponsorshipsErrorCode,
|
||||
} from './GetSeasonSponsorshipsUseCase';
|
||||
import type { SeasonSponsorshipRepository } from '../../domain/repositories/SeasonSponsorshipRepository';
|
||||
@@ -52,11 +51,13 @@ describe('GetSeasonSponsorshipsUseCase', () => {
|
||||
findByLeagueId: vi.fn(),
|
||||
};
|
||||
|
||||
useCase = new GetSeasonSponsorshipsUseCase(seasonSponsorshipRepository as any,
|
||||
seasonRepository as any,
|
||||
leagueRepository as any,
|
||||
leagueMembershipRepository as any,
|
||||
raceRepository as any);
|
||||
useCase = new GetSeasonSponsorshipsUseCase(
|
||||
seasonSponsorshipRepository as unknown as SeasonSponsorshipRepository,
|
||||
seasonRepository as unknown as SeasonRepository,
|
||||
leagueRepository as unknown as LeagueRepository,
|
||||
leagueMembershipRepository as unknown as LeagueMembershipRepository,
|
||||
raceRepository as unknown as RaceRepository
|
||||
);
|
||||
});
|
||||
|
||||
it('returns SEASON_NOT_FOUND when season does not exist', async () => {
|
||||
|
||||
@@ -15,6 +15,7 @@ export class GetSponsorsUseCase {
|
||||
constructor(private readonly sponsorRepository: SponsorRepository) {}
|
||||
|
||||
async execute(_input: GetSponsorsInput): Promise<Result<GetSponsorsResult, ApplicationErrorCode<GetSponsorsErrorCode, { message: string }>>> {
|
||||
void _input;
|
||||
try {
|
||||
const sponsors = await this.sponsorRepository.findAll();
|
||||
return Result.ok({ sponsors });
|
||||
|
||||
@@ -5,9 +5,9 @@ import {
|
||||
type GetTeamJoinRequestsResult,
|
||||
type GetTeamJoinRequestsErrorCode,
|
||||
} from './GetTeamJoinRequestsUseCase';
|
||||
import { TeamMembershipRepository } from '../../domain/repositories/TeamMembershipRepository';
|
||||
import { DriverRepository } from '../../domain/repositories/DriverRepository';
|
||||
import { TeamRepository } from '../../domain/repositories/TeamRepository';
|
||||
import type { TeamMembershipRepository } from '../../domain/repositories/TeamMembershipRepository';
|
||||
import type { DriverRepository } from '../../domain/repositories/DriverRepository';
|
||||
import type { TeamRepository } from '../../domain/repositories/TeamRepository';
|
||||
import { Driver } from '../../domain/entities/Driver';
|
||||
import { Team } from '../../domain/entities/Team';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
@@ -34,9 +34,11 @@ describe('GetTeamJoinRequestsUseCase', () => {
|
||||
findById: vi.fn(),
|
||||
};
|
||||
|
||||
useCase = new GetTeamJoinRequestsUseCase(membershipRepository as any,
|
||||
driverRepository as any,
|
||||
teamRepository as any);
|
||||
useCase = new GetTeamJoinRequestsUseCase(
|
||||
membershipRepository as unknown as TeamMembershipRepository,
|
||||
driverRepository as unknown as DriverRepository,
|
||||
teamRepository as unknown as TeamRepository
|
||||
);
|
||||
});
|
||||
|
||||
it('should return join requests with drivers when team exists', async () => {
|
||||
|
||||
@@ -7,6 +7,10 @@ import {
|
||||
type GetTeamMembersErrorCode,
|
||||
type GetTeamMembersInput
|
||||
} from './GetTeamMembersUseCase';
|
||||
import type { TeamMembershipRepository } from '../../domain/repositories/TeamMembershipRepository';
|
||||
import type { DriverRepository } from '../../domain/repositories/DriverRepository';
|
||||
import type { TeamRepository } from '../../domain/repositories/TeamRepository';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
|
||||
describe('GetTeamMembersUseCase', () => {
|
||||
let useCase: GetTeamMembersUseCase;
|
||||
@@ -41,10 +45,12 @@ describe('GetTeamMembersUseCase', () => {
|
||||
warn: vi.fn(),
|
||||
error: vi.fn(),
|
||||
};
|
||||
useCase = new GetTeamMembersUseCase(membershipRepository as any,
|
||||
driverRepository as any,
|
||||
teamRepository as any,
|
||||
logger as any);
|
||||
useCase = new GetTeamMembersUseCase(
|
||||
membershipRepository as unknown as TeamMembershipRepository,
|
||||
driverRepository as unknown as DriverRepository,
|
||||
teamRepository as unknown as TeamRepository,
|
||||
logger as unknown as Logger
|
||||
);
|
||||
});
|
||||
|
||||
it('should return team members with driver entities', async () => {
|
||||
|
||||
@@ -3,6 +3,10 @@ import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorC
|
||||
import type { Driver } from '../../domain/entities/Driver';
|
||||
import type { Team } from '../../domain/entities/Team';
|
||||
import type { TeamMembership } from '../../domain/types/TeamMembership';
|
||||
import { TeamMembershipRepository } from '../../domain/repositories/TeamMembershipRepository';
|
||||
import { DriverRepository } from '../../domain/repositories/DriverRepository';
|
||||
import { TeamRepository } from '../../domain/repositories/TeamRepository';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
|
||||
export type GetTeamMembersInput = {
|
||||
teamId: string;
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import {
|
||||
GetTeamMembershipUseCase,
|
||||
type GetTeamMembershipErrorCode,
|
||||
type GetTeamMembershipInput
|
||||
} from './GetTeamMembershipUseCase';
|
||||
import { TeamMembershipRepository } from '../../domain/repositories/TeamMembershipRepository';
|
||||
import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
|
||||
|
||||
describe('GetTeamMembershipUseCase', () => {
|
||||
const mockGetMembership = vi.fn();
|
||||
const mockMembershipRepo: any = {
|
||||
const mockMembershipRepo: {
|
||||
getMembership: Mock;
|
||||
getActiveMembershipForDriver: Mock;
|
||||
getTeamMembers: Mock;
|
||||
saveMembership: Mock;
|
||||
removeMembership: Mock;
|
||||
getJoinRequests: Mock;
|
||||
countByTeamId: Mock;
|
||||
saveJoinRequest: Mock;
|
||||
removeJoinRequest: Mock;
|
||||
} = {
|
||||
getMembership: mockGetMembership,
|
||||
getActiveMembershipForDriver: vi.fn(),
|
||||
getTeamMembers: vi.fn(),
|
||||
@@ -32,7 +38,7 @@ describe('GetTeamMembershipUseCase', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
useCase = new GetTeamMembershipUseCase(mockMembershipRepo, mockLogger);
|
||||
useCase = new GetTeamMembershipUseCase(mockMembershipRepo as unknown as TeamMembershipRepository, mockLogger);
|
||||
});
|
||||
|
||||
it('should return membership data when membership exists', async () => {
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import { TeamMembershipRepository } from '../../domain/repositories/TeamMembershipRepository';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
|
||||
export type GetTeamMembershipInput = {
|
||||
teamId: string;
|
||||
driverId: string;
|
||||
|
||||
@@ -7,10 +7,15 @@ import {
|
||||
type GetTeamsLeaderboardInput
|
||||
} from './GetTeamsLeaderboardUseCase';
|
||||
|
||||
import { TeamRepository } from '../../domain/repositories/TeamRepository';
|
||||
import { TeamMembershipRepository } from '../../domain/repositories/TeamMembershipRepository';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
|
||||
describe('GetTeamsLeaderboardUseCase', () => {
|
||||
let useCase: GetTeamsLeaderboardUseCase;
|
||||
let teamRepository: {
|
||||
findAll: Mock;
|
||||
findById: Mock;
|
||||
};
|
||||
let teamMembershipRepository: {
|
||||
getTeamMembers: Mock;
|
||||
@@ -26,6 +31,7 @@ describe('GetTeamsLeaderboardUseCase', () => {
|
||||
beforeEach(() => {
|
||||
teamRepository = {
|
||||
findAll: vi.fn(),
|
||||
findById: vi.fn(),
|
||||
};
|
||||
teamMembershipRepository = {
|
||||
getTeamMembers: vi.fn(),
|
||||
@@ -37,10 +43,11 @@ describe('GetTeamsLeaderboardUseCase', () => {
|
||||
warn: vi.fn(),
|
||||
error: vi.fn(),
|
||||
};
|
||||
useCase = new GetTeamsLeaderboardUseCase(teamRepository as any,
|
||||
teamMembershipRepository as any,
|
||||
useCase = new GetTeamsLeaderboardUseCase(
|
||||
teamRepository as unknown as TeamRepository,
|
||||
teamMembershipRepository as unknown as TeamMembershipRepository,
|
||||
getDriverStats as any,
|
||||
logger as any
|
||||
logger as unknown as Logger
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { Team } from '@/racing/domain/entities/Team';
|
||||
import { Team } from '../../domain/entities/Team';
|
||||
import { SkillLevelService, type SkillLevel } from '@core/racing/domain/services/SkillLevelService';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import { TeamRepository } from '../../domain/repositories/TeamRepository';
|
||||
import { TeamMembershipRepository } from '../../domain/repositories/TeamMembershipRepository';
|
||||
|
||||
interface DriverStatsAdapter {
|
||||
rating: number | null;
|
||||
@@ -55,7 +57,7 @@ export class GetTeamsLeaderboardUseCase {
|
||||
const items: TeamLeaderboardItem[] = [];
|
||||
|
||||
await Promise.all(
|
||||
allTeams.map(async (team) => {
|
||||
allTeams.map(async (team: Team) => {
|
||||
const memberships = await this.teamMembershipRepository.getTeamMembers(team.id);
|
||||
const memberCount = memberships.length;
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ export class GetTotalDriversUseCase {
|
||||
async execute(
|
||||
_input: GetTotalDriversInput,
|
||||
): Promise<Result<GetTotalDriversResult, ApplicationErrorCode<GetTotalDriversErrorCode, { message: string }>>> {
|
||||
void _input;
|
||||
try {
|
||||
const drivers = await this.driverRepository.findAll();
|
||||
const totalDrivers = drivers.length;
|
||||
|
||||
@@ -16,6 +16,7 @@ export class GetTotalLeaguesUseCase {
|
||||
async execute(
|
||||
_input: GetTotalLeaguesInput,
|
||||
): Promise<Result<GetTotalLeaguesResult, ApplicationErrorCode<GetTotalLeaguesErrorCode, { message: string }>>> {
|
||||
void _input;
|
||||
try {
|
||||
const leagues = await this.leagueRepository.findAll();
|
||||
const totalLeagues = leagues.length;
|
||||
|
||||
@@ -16,6 +16,7 @@ export class GetTotalRacesUseCase {
|
||||
async execute(
|
||||
_input: GetTotalRacesInput,
|
||||
): Promise<Result<GetTotalRacesResult, ApplicationErrorCode<GetTotalRacesErrorCode, { message: string }>>> {
|
||||
void _input;
|
||||
try {
|
||||
const races = await this.raceRepository.findAll();
|
||||
const totalRaces = races.length;
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import { Result as RaceResult } from '../../domain/entities/result/Result';
|
||||
import { RaceRepository } from '../../domain/repositories/RaceRepository';
|
||||
import { LeagueRepository } from '../../domain/repositories/LeagueRepository';
|
||||
import { ResultRepository } from '../../domain/repositories/ResultRepository';
|
||||
import { DriverRepository } from '../../domain/repositories/DriverRepository';
|
||||
import { StandingRepository } from '../../domain/repositories/StandingRepository';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
|
||||
export type ImportRaceResultDTO = {
|
||||
id: string;
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import { Result as RaceResult } from '../../domain/entities/result/Result';
|
||||
import { RaceRepository } from '../../domain/repositories/RaceRepository';
|
||||
import { LeagueRepository } from '../../domain/repositories/LeagueRepository';
|
||||
import { ResultRepository } from '../../domain/repositories/ResultRepository';
|
||||
import { DriverRepository } from '../../domain/repositories/DriverRepository';
|
||||
import { StandingRepository } from '../../domain/repositories/StandingRepository';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
|
||||
export type ImportRaceResultRow = {
|
||||
id: string;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Result } from '@/shared/domain/Result';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import { LeagueMembership } from '../../domain/entities/LeagueMembership';
|
||||
import { LeagueMembershipRepository } from '../../domain/repositories/LeagueMembershipRepository';
|
||||
|
||||
export type JoinLeagueErrorCode = 'ALREADY_MEMBER' | 'REPOSITORY_ERROR';
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { TeamMembership } from '@/racing/domain/types/TeamMembership';
|
||||
import { TeamMembership } from '../../domain/types/TeamMembership';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import type { Team } from '../../domain/entities/Team';
|
||||
import { TeamRepository } from '../../domain/repositories/TeamRepository';
|
||||
import { TeamMembershipRepository } from '../../domain/repositories/TeamMembershipRepository';
|
||||
|
||||
export type JoinTeamErrorCode =
|
||||
| 'ALREADY_IN_TEAM'
|
||||
|
||||
@@ -5,20 +5,26 @@ import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorC
|
||||
|
||||
import { Race } from '../../domain/entities/Race';
|
||||
import { Season } from '../../domain/entities/season/Season';
|
||||
import type { SeasonRepository } from '../../domain/repositories/SeasonRepository';
|
||||
import type { RaceRepository } from '../../domain/repositories/RaceRepository';
|
||||
|
||||
import {
|
||||
CreateLeagueSeasonScheduleRaceUseCase,
|
||||
type CreateLeagueSeasonScheduleRaceErrorCode
|
||||
} from './CreateLeagueSeasonScheduleRaceUseCase';
|
||||
import {
|
||||
DeleteLeagueSeasonScheduleRaceUseCase,
|
||||
type DeleteLeagueSeasonScheduleRaceErrorCode
|
||||
} from './DeleteLeagueSeasonScheduleRaceUseCase';
|
||||
import {
|
||||
PublishLeagueSeasonScheduleUseCase,
|
||||
type PublishLeagueSeasonScheduleErrorCode
|
||||
} from './PublishLeagueSeasonScheduleUseCase';
|
||||
import {
|
||||
UnpublishLeagueSeasonScheduleUseCase,
|
||||
type UnpublishLeagueSeasonScheduleErrorCode
|
||||
} from './UnpublishLeagueSeasonScheduleUseCase';
|
||||
import {
|
||||
UpdateLeagueSeasonScheduleRaceUseCase,
|
||||
type UpdateLeagueSeasonScheduleRaceErrorCode
|
||||
} from './UpdateLeagueSeasonScheduleRaceUseCase';
|
||||
@@ -60,8 +66,8 @@ describe('CreateLeagueSeasonScheduleRaceUseCase', () => {
|
||||
seasonRepository.findById.mockResolvedValue(season);
|
||||
raceRepository.create.mockImplementation(async (race: Race) => race);
|
||||
|
||||
const useCase = new CreateLeagueSeasonScheduleRaceUseCase(seasonRepository as any,
|
||||
raceRepository as any,
|
||||
const useCase = new CreateLeagueSeasonScheduleRaceUseCase(seasonRepository as unknown as SeasonRepository,
|
||||
raceRepository as unknown as RaceRepository,
|
||||
logger,
|
||||
{ generateRaceId: () => 'race-123' },
|
||||
);
|
||||
@@ -89,8 +95,8 @@ describe('CreateLeagueSeasonScheduleRaceUseCase', () => {
|
||||
const season = createSeasonWithinWindow({ leagueId: 'other-league' });
|
||||
seasonRepository.findById.mockResolvedValue(season);
|
||||
|
||||
const useCase = new CreateLeagueSeasonScheduleRaceUseCase(seasonRepository as any,
|
||||
raceRepository as any,
|
||||
const useCase = new CreateLeagueSeasonScheduleRaceUseCase(seasonRepository as unknown as SeasonRepository,
|
||||
raceRepository as unknown as RaceRepository,
|
||||
logger,
|
||||
{ generateRaceId: () => 'race-123' },
|
||||
);
|
||||
@@ -116,8 +122,8 @@ describe('CreateLeagueSeasonScheduleRaceUseCase', () => {
|
||||
const season = createSeasonWithinWindow();
|
||||
seasonRepository.findById.mockResolvedValue(season);
|
||||
|
||||
const useCase = new CreateLeagueSeasonScheduleRaceUseCase(seasonRepository as any,
|
||||
raceRepository as any,
|
||||
const useCase = new CreateLeagueSeasonScheduleRaceUseCase(seasonRepository as unknown as SeasonRepository,
|
||||
raceRepository as unknown as RaceRepository,
|
||||
logger,
|
||||
{ generateRaceId: () => 'race-123' },
|
||||
);
|
||||
@@ -165,8 +171,8 @@ describe('UpdateLeagueSeasonScheduleRaceUseCase', () => {
|
||||
raceRepository.findById.mockResolvedValue(existing);
|
||||
raceRepository.update.mockImplementation(async (race: Race) => race);
|
||||
|
||||
const useCase = new UpdateLeagueSeasonScheduleRaceUseCase(seasonRepository as any,
|
||||
raceRepository as any,
|
||||
const useCase = new UpdateLeagueSeasonScheduleRaceUseCase(seasonRepository as unknown as SeasonRepository,
|
||||
raceRepository as unknown as RaceRepository,
|
||||
logger);
|
||||
|
||||
const newScheduledAt = new Date('2025-01-20T20:00:00Z');
|
||||
@@ -189,8 +195,8 @@ describe('UpdateLeagueSeasonScheduleRaceUseCase', () => {
|
||||
const season = createSeasonWithinWindow({ leagueId: 'other-league' });
|
||||
seasonRepository.findById.mockResolvedValue(season);
|
||||
|
||||
const useCase = new UpdateLeagueSeasonScheduleRaceUseCase(seasonRepository as any,
|
||||
raceRepository as any,
|
||||
const useCase = new UpdateLeagueSeasonScheduleRaceUseCase(seasonRepository as unknown as SeasonRepository,
|
||||
raceRepository as unknown as RaceRepository,
|
||||
logger);
|
||||
|
||||
const result = await useCase.execute({
|
||||
@@ -223,8 +229,8 @@ describe('UpdateLeagueSeasonScheduleRaceUseCase', () => {
|
||||
});
|
||||
raceRepository.findById.mockResolvedValue(existing);
|
||||
|
||||
const useCase = new UpdateLeagueSeasonScheduleRaceUseCase(seasonRepository as any,
|
||||
raceRepository as any,
|
||||
const useCase = new UpdateLeagueSeasonScheduleRaceUseCase(seasonRepository as unknown as SeasonRepository,
|
||||
raceRepository as unknown as RaceRepository,
|
||||
logger);
|
||||
|
||||
const result = await useCase.execute({
|
||||
@@ -248,8 +254,8 @@ describe('UpdateLeagueSeasonScheduleRaceUseCase', () => {
|
||||
seasonRepository.findById.mockResolvedValue(season);
|
||||
raceRepository.findById.mockResolvedValue(null);
|
||||
|
||||
const useCase = new UpdateLeagueSeasonScheduleRaceUseCase(seasonRepository as any,
|
||||
raceRepository as any,
|
||||
const useCase = new UpdateLeagueSeasonScheduleRaceUseCase(seasonRepository as unknown as SeasonRepository,
|
||||
raceRepository as unknown as RaceRepository,
|
||||
logger);
|
||||
|
||||
const result = await useCase.execute({
|
||||
@@ -294,8 +300,8 @@ describe('DeleteLeagueSeasonScheduleRaceUseCase', () => {
|
||||
raceRepository.findById.mockResolvedValue(existing);
|
||||
raceRepository.delete.mockResolvedValue(undefined);
|
||||
|
||||
const useCase = new DeleteLeagueSeasonScheduleRaceUseCase(seasonRepository as any,
|
||||
raceRepository as any,
|
||||
const useCase = new DeleteLeagueSeasonScheduleRaceUseCase(seasonRepository as unknown as SeasonRepository,
|
||||
raceRepository as unknown as RaceRepository,
|
||||
logger);
|
||||
|
||||
const result = await useCase.execute({
|
||||
@@ -313,8 +319,8 @@ describe('DeleteLeagueSeasonScheduleRaceUseCase', () => {
|
||||
const season = createSeasonWithinWindow({ leagueId: 'other-league' });
|
||||
seasonRepository.findById.mockResolvedValue(season);
|
||||
|
||||
const useCase = new DeleteLeagueSeasonScheduleRaceUseCase(seasonRepository as any,
|
||||
raceRepository as any,
|
||||
const useCase = new DeleteLeagueSeasonScheduleRaceUseCase(seasonRepository as unknown as SeasonRepository,
|
||||
raceRepository as unknown as RaceRepository,
|
||||
logger);
|
||||
|
||||
const result = await useCase.execute({
|
||||
@@ -338,8 +344,8 @@ describe('DeleteLeagueSeasonScheduleRaceUseCase', () => {
|
||||
seasonRepository.findById.mockResolvedValue(season);
|
||||
raceRepository.findById.mockResolvedValue(null);
|
||||
|
||||
const useCase = new DeleteLeagueSeasonScheduleRaceUseCase(seasonRepository as any,
|
||||
raceRepository as any,
|
||||
const useCase = new DeleteLeagueSeasonScheduleRaceUseCase(seasonRepository as unknown as SeasonRepository,
|
||||
raceRepository as unknown as RaceRepository,
|
||||
logger);
|
||||
|
||||
const result = await useCase.execute({
|
||||
@@ -372,7 +378,7 @@ describe('PublishLeagueSeasonScheduleUseCase', () => {
|
||||
seasonRepository.findById.mockResolvedValue(season);
|
||||
seasonRepository.update.mockResolvedValue(undefined);
|
||||
|
||||
const useCase = new PublishLeagueSeasonScheduleUseCase(seasonRepository as any,
|
||||
const useCase = new PublishLeagueSeasonScheduleUseCase(seasonRepository as unknown as SeasonRepository,
|
||||
logger);
|
||||
|
||||
const result = await useCase.execute({ leagueId: 'league-1', seasonId: 'season-1' });
|
||||
@@ -388,7 +394,7 @@ describe('PublishLeagueSeasonScheduleUseCase', () => {
|
||||
const season = createSeasonWithinWindow({ leagueId: 'other-league' });
|
||||
seasonRepository.findById.mockResolvedValue(season);
|
||||
|
||||
const useCase = new PublishLeagueSeasonScheduleUseCase(seasonRepository as any,
|
||||
const useCase = new PublishLeagueSeasonScheduleUseCase(seasonRepository as unknown as SeasonRepository,
|
||||
logger);
|
||||
|
||||
const result = await useCase.execute({ leagueId: 'league-1', seasonId: 'season-1' });
|
||||
@@ -417,7 +423,7 @@ describe('UnpublishLeagueSeasonScheduleUseCase', () => {
|
||||
seasonRepository.findById.mockResolvedValue(season);
|
||||
seasonRepository.update.mockResolvedValue(undefined);
|
||||
|
||||
const useCase = new UnpublishLeagueSeasonScheduleUseCase(seasonRepository as any,
|
||||
const useCase = new UnpublishLeagueSeasonScheduleUseCase(seasonRepository as unknown as SeasonRepository,
|
||||
logger);
|
||||
|
||||
const result = await useCase.execute({ leagueId: 'league-1', seasonId: 'season-1' });
|
||||
@@ -433,7 +439,7 @@ describe('UnpublishLeagueSeasonScheduleUseCase', () => {
|
||||
const season = createSeasonWithinWindow({ leagueId: 'other-league' });
|
||||
seasonRepository.findById.mockResolvedValue(season);
|
||||
|
||||
const useCase = new UnpublishLeagueSeasonScheduleUseCase(seasonRepository as any,
|
||||
const useCase = new UnpublishLeagueSeasonScheduleUseCase(seasonRepository as unknown as SeasonRepository,
|
||||
logger);
|
||||
|
||||
const result = await useCase.execute({ leagueId: 'league-1', seasonId: 'season-1' });
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { TeamMembership } from '@/racing/domain/types/TeamMembership';
|
||||
import { TeamMembership } from '../../domain/types/TeamMembership';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import type { Team } from '../../domain/entities/Team';
|
||||
import { TeamRepository } from '../../domain/repositories/TeamRepository';
|
||||
import { TeamMembershipRepository } from '../../domain/repositories/TeamMembershipRepository';
|
||||
|
||||
export type LeaveTeamErrorCode =
|
||||
| 'TEAM_NOT_FOUND'
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import { SeasonRepository } from '../../domain/repositories/SeasonRepository';
|
||||
|
||||
|
||||
export interface PublishLeagueSeasonScheduleInput {
|
||||
leagueId: string;
|
||||
seasonId: string;
|
||||
}
|
||||
|
||||
export type PublishLeagueSeasonScheduleResult = {
|
||||
success: true;
|
||||
|
||||
@@ -5,11 +5,14 @@
|
||||
* Designed for fast, common penalty scenarios like track limits, warnings, etc.
|
||||
*/
|
||||
|
||||
import { Result } from '@/shared/domain/Result';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import { randomUUID } from 'crypto';
|
||||
import { Penalty } from '../../domain/entities/penalty/Penalty';
|
||||
import { PenaltyRepository } from '../../domain/repositories/PenaltyRepository';
|
||||
import { RaceRepository } from '../../domain/repositories/RaceRepository';
|
||||
import { LeagueMembershipRepository } from '../../domain/repositories/LeagueMembershipRepository';
|
||||
|
||||
export type QuickPenaltyErrorCode = 'RACE_NOT_FOUND' | 'UNAUTHORIZED' | 'UNKNOWN_INFRACTION' | 'REPOSITORY_ERROR';
|
||||
|
||||
@@ -55,7 +58,7 @@ export class QuickPenaltyUseCase {
|
||||
// Validate admin has authority
|
||||
const memberships = await this.leagueMembershipRepository.getLeagueMembers(race.leagueId);
|
||||
const adminMembership = memberships.find(
|
||||
m => m.driverId.toString() === input.adminId && m.status.toString() === 'active'
|
||||
(m: any) => m.driverId.toString() === input.adminId && m.status.toString() === 'active'
|
||||
);
|
||||
|
||||
if (!adminMembership || (adminMembership.role.toString() !== 'owner' && adminMembership.role.toString() !== 'admin')) {
|
||||
@@ -99,7 +102,7 @@ export class QuickPenaltyUseCase {
|
||||
await this.penaltyRepository.create(penalty);
|
||||
|
||||
const result: QuickPenaltyResult = {
|
||||
penaltyId: penalty.id,
|
||||
penaltyId: penalty.id.toString(),
|
||||
raceId: input.raceId,
|
||||
driverId: input.driverId,
|
||||
type,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
import { ChampionshipStanding } from '@/racing/domain/entities/championship/ChampionshipStanding';
|
||||
import { ChampionshipStanding } from '../../domain/entities/championship/ChampionshipStanding';
|
||||
import { ChampionshipAggregator } from '@core/racing/domain/services/ChampionshipAggregator';
|
||||
import { EventScoringService } from '@core/racing/domain/services/EventScoringService';
|
||||
import type { ChampionshipConfig } from '@core/racing/domain/types/ChampionshipConfig';
|
||||
@@ -8,6 +8,13 @@ import type { SessionType } from '@core/racing/domain/types/SessionType';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import { LeagueRepository } from '../../domain/repositories/LeagueRepository';
|
||||
import { SeasonRepository } from '../../domain/repositories/SeasonRepository';
|
||||
import { LeagueScoringConfigRepository } from '../../domain/repositories/LeagueScoringConfigRepository';
|
||||
import { RaceRepository } from '../../domain/repositories/RaceRepository';
|
||||
import { ResultRepository } from '../../domain/repositories/ResultRepository';
|
||||
import { PenaltyRepository } from '../../domain/repositories/PenaltyRepository';
|
||||
import { ChampionshipStandingRepository } from '../../domain/repositories/ChampionshipStandingRepository';
|
||||
|
||||
export type RecalculateChampionshipStandingsInput = {
|
||||
leagueId: string;
|
||||
@@ -48,7 +55,7 @@ export class RecalculateChampionshipStandingsUseCase {
|
||||
input: RecalculateChampionshipStandingsInput,
|
||||
): Promise<
|
||||
Result<
|
||||
void,
|
||||
RecalculateChampionshipStandingsResult,
|
||||
ApplicationErrorCode<RecalculateChampionshipStandingsErrorCode, { message: string }>
|
||||
>
|
||||
> {
|
||||
|
||||
@@ -5,6 +5,7 @@ import { TeamRatingEvent } from '@core/racing/domain/entities/TeamRatingEvent';
|
||||
import { TeamRatingEventId } from '@core/racing/domain/value-objects/TeamRatingEventId';
|
||||
import { TeamRatingDimensionKey } from '@core/racing/domain/value-objects/TeamRatingDimensionKey';
|
||||
import { TeamRatingDelta } from '@core/racing/domain/value-objects/TeamRatingDelta';
|
||||
import { TeamRating } from '../../domain/entities/TeamRating';
|
||||
|
||||
// Mock repositories
|
||||
class MockTeamRatingEventRepository implements TeamRatingEventRepository {
|
||||
@@ -48,13 +49,13 @@ class MockTeamRatingEventRepository implements TeamRatingEventRepository {
|
||||
}
|
||||
|
||||
class MockTeamRatingRepository implements TeamRatingRepository {
|
||||
private snapshots: Map<string, any> = new Map();
|
||||
private snapshots: Map<string, TeamRating> = new Map();
|
||||
|
||||
async findByTeamId(teamId: string): Promise<any | null> {
|
||||
async findByTeamId(teamId: string): Promise<TeamRating | null> {
|
||||
return this.snapshots.get(teamId) || null;
|
||||
}
|
||||
|
||||
async save(snapshot: any): Promise<any> {
|
||||
async save(snapshot: TeamRating): Promise<TeamRating> {
|
||||
this.snapshots.set(snapshot.teamId, snapshot);
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
@@ -6,14 +6,14 @@ import { AppendTeamRatingEventsUseCase } from './AppendTeamRatingEventsUseCase';
|
||||
import { TeamDrivingRaceFactsDto } from '@core/racing/domain/services/TeamDrivingRatingEventFactory';
|
||||
import { TeamRatingEvent } from '@core/racing/domain/entities/TeamRatingEvent';
|
||||
import { TeamRatingEventId } from '@core/racing/domain/value-objects/TeamRatingEventId';
|
||||
import { TeamRatingDimensionKey } from '@core/racing/domain/value-objects/TeamRatingDimensionKey';
|
||||
import { TeamRatingDelta } from '@core/racing/domain/value-objects/TeamRatingDelta';
|
||||
import { TeamRating } from '../../domain/entities/TeamRating';
|
||||
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
||||
|
||||
// Mock repositories
|
||||
class MockTeamRaceResultsProvider implements TeamRaceResultsProvider {
|
||||
private results: TeamDrivingRaceFactsDto | null = null;
|
||||
|
||||
async getTeamRaceResults(raceId: string): Promise<TeamDrivingRaceFactsDto | null> {
|
||||
async getTeamRaceResults(_raceId: string): Promise<TeamDrivingRaceFactsDto | null> {
|
||||
return this.results;
|
||||
}
|
||||
|
||||
@@ -59,13 +59,13 @@ class MockTeamRatingEventRepository implements TeamRatingEventRepository {
|
||||
}
|
||||
|
||||
class MockTeamRatingRepository implements TeamRatingRepository {
|
||||
private snapshots: Map<string, any> = new Map();
|
||||
private snapshots: Map<string, TeamRating> = new Map();
|
||||
|
||||
async findByTeamId(teamId: string): Promise<any | null> {
|
||||
async findByTeamId(teamId: string): Promise<TeamRating | null> {
|
||||
return this.snapshots.get(teamId) || null;
|
||||
}
|
||||
|
||||
async save(snapshot: any): Promise<any> {
|
||||
async save(snapshot: TeamRating): Promise<TeamRating> {
|
||||
this.snapshots.set(snapshot.teamId, snapshot);
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { describe, it, expect, vi, type Mock, beforeEach } from 'vitest';
|
||||
import {
|
||||
RejectLeagueJoinRequestUseCase,
|
||||
type RejectLeagueJoinRequestResult,
|
||||
} from './RejectLeagueJoinRequestUseCase';
|
||||
import type { LeagueMembershipRepository } from '../../domain/repositories/LeagueMembershipRepository';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
@@ -22,7 +21,7 @@ describe('RejectLeagueJoinRequestUseCase', () => {
|
||||
it('reject removes request only', async () => {
|
||||
const output: { present: Mock } = {
|
||||
present: vi.fn(),
|
||||
} as any;
|
||||
};
|
||||
|
||||
const useCase = new RejectLeagueJoinRequestUseCase(leagueMembershipRepository as unknown as LeagueMembershipRepository);
|
||||
|
||||
@@ -32,7 +31,6 @@ describe('RejectLeagueJoinRequestUseCase', () => {
|
||||
|
||||
const result = await useCase.execute(
|
||||
{ leagueId: 'league-1', joinRequestId: 'jr-1' },
|
||||
output,
|
||||
);
|
||||
|
||||
expect(result.isOk()).toBe(true);
|
||||
@@ -42,7 +40,7 @@ describe('RejectLeagueJoinRequestUseCase', () => {
|
||||
it('reject returns error when request missing', async () => {
|
||||
const output: { present: Mock } = {
|
||||
present: vi.fn(),
|
||||
} as any;
|
||||
};
|
||||
|
||||
const useCase = new RejectLeagueJoinRequestUseCase(leagueMembershipRepository as unknown as LeagueMembershipRepository);
|
||||
|
||||
@@ -50,7 +48,6 @@ describe('RejectLeagueJoinRequestUseCase', () => {
|
||||
|
||||
const result = await useCase.execute(
|
||||
{ leagueId: 'league-1', joinRequestId: 'jr-404' },
|
||||
output,
|
||||
);
|
||||
|
||||
expect(result.isErr()).toBe(true);
|
||||
|
||||
@@ -7,7 +7,13 @@
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import { SponsorshipRequestRepository } from '../../domain/repositories/SponsorshipRequestRepository';
|
||||
|
||||
export interface RejectSponsorshipRequestInput {
|
||||
requestId: string;
|
||||
respondedBy: string;
|
||||
reason?: string;
|
||||
}
|
||||
|
||||
export type RejectSponsorshipRequestResult = {
|
||||
requestId: string;
|
||||
|
||||
@@ -2,12 +2,12 @@ import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
|
||||
import {
|
||||
RejectTeamJoinRequestUseCase,
|
||||
type RejectTeamJoinRequestInput,
|
||||
type RejectTeamJoinRequestResult,
|
||||
type RejectTeamJoinRequestErrorCode,
|
||||
} from './RejectTeamJoinRequestUseCase';
|
||||
import type { TeamMembershipRepository } from '../../domain/repositories/TeamMembershipRepository';
|
||||
import type { TeamRepository } from '../../domain/repositories/TeamRepository';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
|
||||
interface TeamRepositoryMock {
|
||||
findById: Mock;
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import { TeamRepository } from '../../domain/repositories/TeamRepository';
|
||||
import { TeamMembershipRepository } from '../../domain/repositories/TeamMembershipRepository';
|
||||
import type { TeamJoinRequest } from '../../domain/types/TeamMembership';
|
||||
|
||||
export interface RejectTeamJoinRequestInput {
|
||||
teamId: string;
|
||||
managerId: string;
|
||||
requestId: string;
|
||||
reason?: string;
|
||||
}
|
||||
|
||||
export type RejectTeamJoinRequestResult = {
|
||||
teamId: string;
|
||||
@@ -57,7 +66,7 @@ export class RejectTeamJoinRequestUseCase {
|
||||
}
|
||||
|
||||
const joinRequests = await this.membershipRepository.getJoinRequests(teamId);
|
||||
const joinRequest = joinRequests.find(r => r.id === requestId);
|
||||
const joinRequest = joinRequests.find((r: TeamJoinRequest) => r.id === requestId);
|
||||
if (!joinRequest) {
|
||||
this.logger.warn('Join request not found when rejecting', { teamId, managerId, requestId });
|
||||
return Result.err({
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import type { Race } from '../../domain/entities/Race';
|
||||
import { RaceRepository } from '../../domain/repositories/RaceRepository';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
|
||||
export type ReopenRaceInput = {
|
||||
raceId: string;
|
||||
|
||||
@@ -6,6 +6,12 @@
|
||||
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import { ProtestRepository } from '../../domain/repositories/ProtestRepository';
|
||||
import { RaceRepository } from '../../domain/repositories/RaceRepository';
|
||||
import { LeagueMembershipRepository } from '../../domain/repositories/LeagueMembershipRepository';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
|
||||
import { LeagueMembership } from '../../domain/entities/LeagueMembership';
|
||||
|
||||
export type ReviewProtestErrorCode = 'PROTEST_NOT_FOUND' | 'RACE_NOT_FOUND' | 'NOT_LEAGUE_ADMIN' | 'REPOSITORY_ERROR';
|
||||
|
||||
@@ -53,7 +59,7 @@ export class ReviewProtestUseCase {
|
||||
// Validate steward has authority (owner or admin of the league)
|
||||
const memberships = await this.leagueMembershipRepository.getLeagueMembers(race.leagueId);
|
||||
const stewardMembership = memberships.find(
|
||||
m => m.driverId.toString() === input.stewardId && m.status.toString() === 'active'
|
||||
(m: LeagueMembership) => m.driverId.toString() === input.stewardId && m.status.toString() === 'active'
|
||||
);
|
||||
|
||||
if (!stewardMembership || (stewardMembership.role.toString() !== 'owner' && stewardMembership.role.toString() !== 'admin')) {
|
||||
|
||||
@@ -11,10 +11,6 @@ import {
|
||||
ManageSeasonLifecycleUseCase,
|
||||
type CreateSeasonForLeagueCommand,
|
||||
type ManageSeasonLifecycleCommand,
|
||||
type CreateSeasonForLeagueResult,
|
||||
type ListSeasonsForLeagueResult,
|
||||
type GetSeasonDetailsResult,
|
||||
type ManageSeasonLifecycleResult,
|
||||
type CreateSeasonForLeagueErrorCode,
|
||||
type ListSeasonsForLeagueErrorCode,
|
||||
type GetSeasonDetailsErrorCode,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Position } from '@/racing/domain/entities/result/Position';
|
||||
import { Position } from '../../domain/entities/result/Position';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
@@ -8,6 +8,10 @@ import type { RaceEvent } from '../../domain/entities/RaceEvent';
|
||||
import { IncidentCount } from '../../domain/entities/result/IncidentCount';
|
||||
import type { Result as RaceResult } from '../../domain/entities/result/Result';
|
||||
import { isLeagueStewardOrHigherRole } from '../../domain/types/LeagueRoles';
|
||||
import { RaceEventRepository } from '../../domain/repositories/RaceEventRepository';
|
||||
import { ResultRepository } from '../../domain/repositories/ResultRepository';
|
||||
import { LeagueRepository } from '../../domain/repositories/LeagueRepository';
|
||||
import { LeagueMembershipRepository } from '../../domain/repositories/LeagueMembershipRepository';
|
||||
|
||||
export type SendFinalResultsInput = {
|
||||
leagueId: string;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { isLeagueStewardOrHigherRole } from '@/racing/domain/types/LeagueRoles';
|
||||
import { isLeagueStewardOrHigherRole } from '../../domain/types/LeagueRoles';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
@@ -8,6 +8,11 @@ import type { RaceEvent } from '../../domain/entities/RaceEvent';
|
||||
import { IncidentCount } from '../../domain/entities/result/IncidentCount';
|
||||
import { Position } from '../../domain/entities/result/Position';
|
||||
import type { Result as RaceResult } from '../../domain/entities/result/Result';
|
||||
import { RaceEventRepository } from '../../domain/repositories/RaceEventRepository';
|
||||
import { ResultRepository } from '../../domain/repositories/ResultRepository';
|
||||
import { LeagueRepository } from '../../domain/repositories/LeagueRepository';
|
||||
import { LeagueMembershipRepository } from '../../domain/repositories/LeagueMembershipRepository';
|
||||
import { DriverRepository } from '../../domain/repositories/DriverRepository';
|
||||
|
||||
export type SendPerformanceSummaryInput = {
|
||||
leagueId: string;
|
||||
@@ -87,7 +92,7 @@ export class SendPerformanceSummaryUseCase {
|
||||
}
|
||||
|
||||
const results = await this.resultRepository.findByRaceId(mainRaceSession.id);
|
||||
const driverResult = results.find(r => r.driverId.toString() === input.driverId);
|
||||
const driverResult = results.find((r: RaceResult) => r.driverId.toString() === input.driverId);
|
||||
|
||||
if (!driverResult) {
|
||||
return Result.err({
|
||||
|
||||
@@ -407,7 +407,6 @@ describe('TeamRankingUseCase', () => {
|
||||
describe('error handling', () => {
|
||||
it('should handle repository errors gracefully', async () => {
|
||||
// Mock repository to throw error
|
||||
const originalFindAll = mockTeamRepo.findAll.bind(mockTeamRepo);
|
||||
mockTeamRepo.findAll = async () => {
|
||||
throw new Error('Repository connection failed');
|
||||
};
|
||||
|
||||
@@ -7,7 +7,7 @@ import { TeamRatingFactoryUseCase } from './TeamRatingFactoryUseCase';
|
||||
class MockTeamRaceResultsProvider implements TeamRaceResultsProvider {
|
||||
private results: TeamDrivingRaceFactsDto | null = null;
|
||||
|
||||
async getTeamRaceResults(raceId: string): Promise<TeamDrivingRaceFactsDto | null> {
|
||||
async getTeamRaceResults(_raceId: string): Promise<TeamDrivingRaceFactsDto | null> {
|
||||
return this.results;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,12 +6,13 @@
|
||||
* Mirrors the user rating factory pattern.
|
||||
*/
|
||||
|
||||
import { TeamDrivingRatingEventFactory } from '@/racing/domain/services/TeamDrivingRatingEventFactory';
|
||||
import { TeamDrivingRatingEventFactory } from '../../domain/services/TeamDrivingRatingEventFactory';
|
||||
import { TeamRatingEvent } from '@core/racing/domain/entities/TeamRatingEvent';
|
||||
import { TeamRatingDelta } from '@core/racing/domain/value-objects/TeamRatingDelta';
|
||||
import { TeamRatingDimensionKey } from '@core/racing/domain/value-objects/TeamRatingDimensionKey';
|
||||
import { TeamRatingEventId } from '@core/racing/domain/value-objects/TeamRatingEventId';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import { TeamRaceResultsProvider } from '../ports/TeamRaceResultsProvider';
|
||||
|
||||
export interface TeamRatingFactoryInput {
|
||||
raceId: string;
|
||||
|
||||
@@ -4,7 +4,13 @@ import type {
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import { LeagueRepository } from '../../domain/repositories/LeagueRepository';
|
||||
|
||||
export interface TransferLeagueOwnershipInput {
|
||||
leagueId: string;
|
||||
currentOwnerId: string;
|
||||
newOwnerId: string;
|
||||
}
|
||||
|
||||
export type TransferLeagueOwnershipResult = {
|
||||
leagueId: string;
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import { SeasonRepository } from '../../domain/repositories/SeasonRepository';
|
||||
|
||||
|
||||
export interface UnpublishLeagueSeasonScheduleInput {
|
||||
leagueId: string;
|
||||
seasonId: string;
|
||||
}
|
||||
|
||||
export type UnpublishLeagueSeasonScheduleResult = {
|
||||
success: true;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { UseCase } from '@core/shared/application/UseCase';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import type { Logger } from '@core/shared/application/Logger';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import type { DriverRepository } from '../../domain/repositories/DriverRepository';
|
||||
import type { Driver } from '../../domain/entities/Driver';
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { describe, it, expect, vi, type Mock } from 'vitest';
|
||||
import { describe, it, expect, vi } from 'vitest';
|
||||
import {
|
||||
UpdateLeagueMemberRoleUseCase,
|
||||
type UpdateLeagueMemberRoleInput,
|
||||
type UpdateLeagueMemberRoleResult,
|
||||
type UpdateLeagueMemberRoleErrorCode,
|
||||
} from './UpdateLeagueMemberRoleUseCase';
|
||||
import type { LeagueMembershipRepository } from '../../domain/repositories/LeagueMembershipRepository';
|
||||
@@ -22,9 +21,9 @@ describe('UpdateLeagueMemberRoleUseCase', () => {
|
||||
const mockLeagueMembershipRepository = {
|
||||
getLeagueMembers: vi.fn().mockResolvedValue([mockMembership]),
|
||||
saveMembership: vi.fn().mockResolvedValue(undefined),
|
||||
} as any;
|
||||
};
|
||||
|
||||
const useCase = new UpdateLeagueMemberRoleUseCase(mockLeagueMembershipRepository);
|
||||
const useCase = new UpdateLeagueMemberRoleUseCase(mockLeagueMembershipRepository as unknown as LeagueMembershipRepository);
|
||||
|
||||
const input: UpdateLeagueMemberRoleInput = {
|
||||
leagueId: 'league-1',
|
||||
|
||||
@@ -2,9 +2,11 @@ import type { Logger } from '@core/shared/domain/Logger';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
|
||||
import { SeasonScheduleGenerator } from '@/racing/domain/services/SeasonScheduleGenerator';
|
||||
import { SeasonScheduleGenerator } from '../../domain/services/SeasonScheduleGenerator';
|
||||
import { Race } from '../../domain/entities/Race';
|
||||
import type { Season } from '../../domain/entities/season/Season';
|
||||
import { SeasonRepository } from '../../domain/repositories/SeasonRepository';
|
||||
import { RaceRepository } from '../../domain/repositories/RaceRepository';
|
||||
|
||||
export type UpdateLeagueSeasonScheduleRaceInput = {
|
||||
leagueId: string;
|
||||
|
||||
@@ -26,11 +26,6 @@ describe('UpdateTeamUseCase', () => {
|
||||
getMembership: vi.fn().mockResolvedValue(mockMembership),
|
||||
} as unknown as TeamMembershipRepository;
|
||||
|
||||
const present = vi.fn<(data: UpdateTeamResult) => void>();
|
||||
const output: { present: typeof present } = {
|
||||
present,
|
||||
};
|
||||
|
||||
const useCase = new UpdateTeamUseCase(mockTeamRepository, mockMembershipRepository);
|
||||
|
||||
const command: UpdateTeamInput = {
|
||||
@@ -78,7 +73,6 @@ describe('UpdateTeamUseCase', () => {
|
||||
const error = result.unwrapErr() as ApplicationErrorCode<UpdateTeamErrorCode, { message: string }>;
|
||||
expect(error.code).toBe('PERMISSION_DENIED');
|
||||
expect(error.details?.message).toBe('User does not have permission to update this team');
|
||||
expect(present).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('returns error if team not found', async () => {
|
||||
@@ -94,11 +88,6 @@ describe('UpdateTeamUseCase', () => {
|
||||
getMembership: vi.fn().mockResolvedValue(mockMembership),
|
||||
} as unknown as TeamMembershipRepository;
|
||||
|
||||
const present = vi.fn<(data: UpdateTeamResult) => void>();
|
||||
const output: { present: typeof present } = {
|
||||
present,
|
||||
};
|
||||
|
||||
const useCase = new UpdateTeamUseCase(mockTeamRepository, mockMembershipRepository);
|
||||
|
||||
const command: UpdateTeamInput = {
|
||||
@@ -113,7 +102,6 @@ describe('UpdateTeamUseCase', () => {
|
||||
const error = result.unwrapErr() as ApplicationErrorCode<UpdateTeamErrorCode, { message: string }>;
|
||||
expect(error.code).toBe('TEAM_NOT_FOUND');
|
||||
expect(error.details?.message).toBe('Team not found');
|
||||
expect(present).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('returns repository error on unexpected failure', async () => {
|
||||
@@ -129,11 +117,6 @@ describe('UpdateTeamUseCase', () => {
|
||||
getMembership: vi.fn().mockResolvedValue(mockMembership),
|
||||
} as unknown as TeamMembershipRepository;
|
||||
|
||||
const present = vi.fn<(data: UpdateTeamResult) => void>();
|
||||
const output: { present: typeof present } = {
|
||||
present,
|
||||
};
|
||||
|
||||
const useCase = new UpdateTeamUseCase(mockTeamRepository, mockMembershipRepository);
|
||||
|
||||
const command: UpdateTeamInput = {
|
||||
@@ -148,6 +131,5 @@ describe('UpdateTeamUseCase', () => {
|
||||
const error = result.unwrapErr() as ApplicationErrorCode<UpdateTeamErrorCode, { message: string }>;
|
||||
expect(error.code).toBe('REPOSITORY_ERROR');
|
||||
expect(error.details?.message).toBe('db error');
|
||||
expect(present).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -10,11 +10,20 @@ import {
|
||||
type WithdrawFromLeagueWalletInput
|
||||
} from './WithdrawFromLeagueWalletUseCase';
|
||||
|
||||
import { LeagueRepository } from '../../domain/repositories/LeagueRepository';
|
||||
import { LeagueWalletRepository } from '../../domain/repositories/LeagueWalletRepository';
|
||||
import { TransactionRepository } from '../../domain/repositories/TransactionRepository';
|
||||
|
||||
describe('WithdrawFromLeagueWalletUseCase', () => {
|
||||
let leagueRepository: { findById: Mock };
|
||||
let walletRepository: { findByLeagueId: Mock; update: Mock };
|
||||
let transactionRepository: { create: Mock };
|
||||
let logger: Logger & { error: Mock };
|
||||
let logger: {
|
||||
debug: Mock;
|
||||
info: Mock;
|
||||
warn: Mock;
|
||||
error: Mock;
|
||||
};
|
||||
let useCase: WithdrawFromLeagueWalletUseCase;
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -27,12 +36,14 @@ describe('WithdrawFromLeagueWalletUseCase', () => {
|
||||
info: vi.fn(),
|
||||
warn: vi.fn(),
|
||||
error: vi.fn()
|
||||
} as any;
|
||||
};
|
||||
|
||||
useCase = new WithdrawFromLeagueWalletUseCase(leagueRepository as any,
|
||||
walletRepository as any,
|
||||
transactionRepository as any,
|
||||
logger);
|
||||
useCase = new WithdrawFromLeagueWalletUseCase(
|
||||
leagueRepository as unknown as LeagueRepository,
|
||||
walletRepository as unknown as LeagueWalletRepository,
|
||||
transactionRepository as unknown as TransactionRepository,
|
||||
logger as unknown as Logger
|
||||
);
|
||||
});
|
||||
|
||||
it('returns LEAGUE_NOT_FOUND when league is missing', async () => {
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { LeagueWalletId } from '@/racing/domain/entities/league-wallet/LeagueWalletId';
|
||||
import { LeagueWalletId } from '../../domain/entities/league-wallet/LeagueWalletId';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import { Transaction } from '../../domain/entities/league-wallet/Transaction';
|
||||
import { TransactionId } from '../../domain/entities/league-wallet/TransactionId';
|
||||
import { Money } from '../../domain/value-objects/Money';
|
||||
import { LeagueRepository } from '../../domain/repositories/LeagueRepository';
|
||||
import { LeagueWalletRepository } from '../../domain/repositories/LeagueWalletRepository';
|
||||
import { TransactionRepository } from '../../domain/repositories/TransactionRepository';
|
||||
|
||||
export type WithdrawFromLeagueWalletInput = {
|
||||
leagueId: string;
|
||||
|
||||
@@ -2,18 +2,22 @@ import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import {
|
||||
WithdrawFromRaceUseCase,
|
||||
type WithdrawFromRaceInput,
|
||||
type WithdrawFromRaceResult,
|
||||
type WithdrawFromRaceErrorCode,
|
||||
} from './WithdrawFromRaceUseCase';
|
||||
import type { RaceRepository } from '../../domain/repositories/RaceRepository';
|
||||
import type { RaceRegistrationRepository } from '../../domain/repositories/RaceRegistrationRepository';
|
||||
import type { Logger } from '@core/shared/application/Logger';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
|
||||
describe('WithdrawFromRaceUseCase', () => {
|
||||
let raceRepository: { findById: ReturnType<typeof vi.fn> };
|
||||
let registrationRepository: { isRegistered: ReturnType<typeof vi.fn>; withdraw: ReturnType<typeof vi.fn> };
|
||||
let logger: Logger;
|
||||
let logger: {
|
||||
debug: ReturnType<typeof vi.fn>;
|
||||
info: ReturnType<typeof vi.fn>;
|
||||
warn: ReturnType<typeof vi.fn>;
|
||||
error: ReturnType<typeof vi.fn>;
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
raceRepository = {
|
||||
@@ -30,13 +34,15 @@ describe('WithdrawFromRaceUseCase', () => {
|
||||
info: vi.fn(),
|
||||
warn: vi.fn(),
|
||||
error: vi.fn(),
|
||||
} as any;
|
||||
};
|
||||
});
|
||||
|
||||
const createUseCase = () =>
|
||||
new WithdrawFromRaceUseCase(raceRepository as any,
|
||||
registrationRepository as any,
|
||||
logger);
|
||||
new WithdrawFromRaceUseCase(
|
||||
raceRepository as unknown as RaceRepository,
|
||||
registrationRepository as unknown as RaceRegistrationRepository,
|
||||
logger as unknown as Logger
|
||||
);
|
||||
|
||||
it('withdraws from race successfully', async () => {
|
||||
const race = {
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Result } from '@core/shared/domain/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import type { RaceRegistrationRepository } from '@core/racing/domain/repositories/RaceRegistrationRepository';
|
||||
import type { RaceRepository } from '@core/racing/domain/repositories/RaceRepository';
|
||||
import type { Logger } from '@core/shared/application/Logger';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
|
||||
export type WithdrawFromRaceInput = {
|
||||
raceId: string;
|
||||
|
||||
Reference in New Issue
Block a user