website refactor

This commit is contained in:
2026-01-16 19:38:55 +01:00
parent 095885544b
commit 26fc726556
73 changed files with 232 additions and 213 deletions
@@ -1,7 +1,9 @@
import type { Logger } from '@core/shared/domain/Logger';
import { describe, expect, it, vi, type Mock } from 'vitest';
import { describe, expect, it, vi, type Mock, beforeEach } from 'vitest';
import type { EntityType } from '../../domain/types/PageView';
import { GetEntityAnalyticsQuery, type GetEntityAnalyticsInput } from './GetEntityAnalyticsQuery';
import type { PageViewRepository } from '../repositories/PageViewRepository';
import type { EngagementRepository } from '../../domain/repositories/EngagementRepository';
describe('GetEntityAnalyticsQuery', () => {
let pageViewRepository: {
@@ -1,8 +1,9 @@
import type { Logger } from '@core/shared/domain/Logger';
import { describe, expect, it, vi, type Mock } from 'vitest';
import { describe, expect, it, vi, type Mock, beforeEach } from 'vitest';
import { EngagementEvent } from '../../domain/entities/EngagementEvent';
import type { EngagementAction, EngagementEntityType } from '../../domain/types/EngagementEvent';
import { RecordEngagementUseCase, type RecordEngagementInput } from './RecordEngagementUseCase';
import type { EngagementRepository } from '../../domain/repositories/EngagementRepository';
describe('RecordEngagementUseCase', () => {
let engagementRepository: {
@@ -85,8 +85,8 @@ describe('GetUserRatingsSummaryQuery', () => {
expect(result.userId).toBe(userId);
expect(result.platform.driving.value).toBe(50); // Default
expect(result.platform.overallReputation).toBe(50);
expect(result.external.iracing.iRating).toBe(2200);
expect(result.external.iracing.safetyRating).toBe(4.5);
expect(result.external.iracing?.iRating).toBe(2200);
expect(result.external.iracing?.safetyRating).toBe(4.5);
expect(result.lastRatingEventAt).toBe('2024-01-01T00:00:00.000Z');
});
@@ -1,10 +1,13 @@
import type { Logger } from '@core/shared/domain/Logger';
import { Result } from '@core/shared/domain/Result';
import { describe, expect, it, vi, type Mock } from 'vitest';
import { describe, expect, it, vi, type Mock, beforeEach } from 'vitest';
import { User } from '../../domain/entities/User';
import { PasswordHash } from '../../domain/value-objects/PasswordHash';
import { UserId } from '../../domain/value-objects/UserId';
import { ForgotPasswordUseCase } from './ForgotPasswordUseCase';
import type { AuthRepository } from '../../domain/repositories/AuthRepository';
import type { MagicLinkRepository } from '../../domain/repositories/MagicLinkRepository';
import type { MagicLinkNotificationPort } from '../ports/MagicLinkNotificationPort';
describe('ForgotPasswordUseCase', () => {
let authRepo: {
@@ -1,7 +1,7 @@
import type { Logger } from '@core/shared/domain/Logger';
import { vi, type Mock } from 'vitest';
import { vi, type Mock, beforeEach, describe, it, expect } from 'vitest';
import { User } from '../../domain/entities/User';
import { StoredUser } from '../../domain/repositories/UserRepository';
import { StoredUser, type UserRepository } from '../../domain/repositories/UserRepository';
import { GetCurrentSessionUseCase } from './GetCurrentSessionUseCase';
describe('GetCurrentSessionUseCase', () => {
@@ -1,6 +1,7 @@
import type { Logger } from '@core/shared/domain/Logger';
import { describe, expect, it, vi, type Mock } from 'vitest';
import { describe, expect, it, vi, type Mock, beforeEach } from 'vitest';
import { GetUserUseCase } from './GetUserUseCase';
import type { UserRepository } from '../../domain/repositories/UserRepository';
describe('GetUserUseCase', () => {
let userRepo: {
@@ -1,9 +1,11 @@
import type { Logger } from '@core/shared/domain/Logger';
import { describe, expect, it, vi, type Mock } from 'vitest';
import { describe, expect, it, vi, type Mock, beforeEach } from 'vitest';
import { User } from '../../domain/entities/User';
import { PasswordHash } from '../../domain/value-objects/PasswordHash';
import { UserId } from '../../domain/value-objects/UserId';
import { LoginUseCase } from './LoginUseCase';
import type { AuthRepository } from '../../domain/repositories/AuthRepository';
import type { PasswordHashingService } from '../ports/PasswordHashingService';
describe('LoginUseCase', () => {
let authRepo: {
@@ -16,11 +16,11 @@ class MockRaceResultsProvider implements RaceResultsProvider {
this.results = results;
}
async getRaceResults(_raceId: string): Promise<RaceResultsData | null> {
async getRaceResults(): Promise<RaceResultsData | null> {
return this.results;
}
async hasRaceResults(_raceId: string): Promise<boolean> {
async hasRaceResults(): Promise<boolean> {
return this.results !== null;
}
}
@@ -1,6 +1,9 @@
import type { Logger } from '@core/shared/domain/Logger';
import { describe, expect, it, vi, type Mock } from 'vitest';
import { describe, expect, it, vi, type Mock, beforeEach } from 'vitest';
import { SignupSponsorUseCase } from './SignupSponsorUseCase';
import type { AuthRepository } from '../../domain/repositories/AuthRepository';
import type { CompanyRepository } from '../../domain/repositories/CompanyRepository';
import type { PasswordHashingService } from '../ports/PasswordHashingService';
describe('SignupSponsorUseCase', () => {
let authRepo: {
@@ -1,9 +1,11 @@
import type { Logger } from '@core/shared/domain/Logger';
import { describe, expect, it, vi, type Mock } from 'vitest';
import { describe, expect, it, vi, type Mock, beforeEach } from 'vitest';
import { User } from '../../domain/entities/User';
import { PasswordHash } from '../../domain/value-objects/PasswordHash';
import { UserId } from '../../domain/value-objects/UserId';
import { SignupUseCase } from './SignupUseCase';
import type { AuthRepository } from '../../domain/repositories/AuthRepository';
import type { PasswordHashingService } from '../ports/PasswordHashingService';
describe('SignupUseCase', () => {
let authRepo: {
@@ -1,7 +1,8 @@
import type { Logger } from '@core/shared/domain/Logger';
import { describe, expect, it, vi, type Mock } from 'vitest';
import { describe, expect, it, vi, type Mock, beforeEach } from 'vitest';
import type { IdentitySessionPort } from '../ports/IdentitySessionPort';
import { SignupWithEmailUseCase } from './SignupWithEmailUseCase';
import type { UserRepository } from '../../domain/repositories/UserRepository';
describe('SignupWithEmailUseCase', () => {
let userRepository: {
@@ -5,7 +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';
import { TeamRating } from '@core/racing/domain/value-objects/TeamRating';
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
// Mock repositories
@@ -1,7 +1,6 @@
import { describe, it, expect, beforeEach, vi, Mock } from 'vitest';
import {
ApproveLeagueJoinRequestUseCase,
type ApproveLeagueJoinRequestResult,
} from './ApproveLeagueJoinRequestUseCase';
import { League } from '../../domain/entities/League';
import type { LeagueMembershipRepository } from '../../domain/repositories/LeagueMembershipRepository';
@@ -1,5 +1,5 @@
import { describe, it, expect, beforeEach, vi, Mock } from 'vitest';
import { ApproveTeamJoinRequestUseCase, type ApproveTeamJoinRequestResult } from './ApproveTeamJoinRequestUseCase';
import { ApproveTeamJoinRequestUseCase } from './ApproveTeamJoinRequestUseCase';
import type { TeamMembershipRepository } from '../../domain/repositories/TeamMembershipRepository';
describe('ApproveTeamJoinRequestUseCase', () => {
@@ -2,7 +2,6 @@ import { describe, it, expect, beforeEach, afterEach, vi, Mock } from 'vitest';
import {
CompleteDriverOnboardingUseCase,
type CompleteDriverOnboardingInput,
type CompleteDriverOnboardingResult,
} from './CompleteDriverOnboardingUseCase';
import type { DriverRepository } from '../../domain/repositories/DriverRepository';
import { Driver } from '../../domain/entities/Driver';
@@ -2,7 +2,6 @@ import { describe, it, expect, beforeEach, vi, Mock } from 'vitest';
import {
CompleteRaceUseCaseWithRatings,
type CompleteRaceWithRatingsInput,
type CompleteRaceWithRatingsResult,
} from './CompleteRaceUseCaseWithRatings';
import type { RaceRepository } from '../../domain/repositories/RaceRepository';
import type { RaceRegistrationRepository } from '../../domain/repositories/RaceRegistrationRepository';
@@ -38,7 +37,6 @@ describe('CompleteRaceUseCaseWithRatings', () => {
getRaceResults: Mock;
hasRaceResults: Mock;
};
let output: { present: Mock };
beforeEach(() => {
raceRepository = {
@@ -3,6 +3,10 @@ import {
CreateLeagueWithSeasonAndScoringUseCase,
type CreateLeagueWithSeasonAndScoringCommand
} from './CreateLeagueWithSeasonAndScoringUseCase';
import type { LeagueRepository } from '../../domain/repositories/LeagueRepository';
import type { SeasonRepository } from '../../domain/repositories/SeasonRepository';
import type { LeagueScoringConfigRepository } from '../../domain/repositories/LeagueScoringConfigRepository';
import type { Logger } from '@core/shared/domain/Logger';
describe('CreateLeagueWithSeasonAndScoringUseCase', () => {
let useCase: CreateLeagueWithSeasonAndScoringUseCase;
@@ -40,11 +44,13 @@ describe('CreateLeagueWithSeasonAndScoringUseCase', () => {
warn: vi.fn(),
error: vi.fn(),
};
useCase = new CreateLeagueWithSeasonAndScoringUseCase(leagueRepository as any,
seasonRepository as any,
leagueScoringConfigRepository as any,
useCase = new CreateLeagueWithSeasonAndScoringUseCase(
leagueRepository as unknown as LeagueRepository,
seasonRepository as unknown as SeasonRepository,
leagueScoringConfigRepository as unknown as LeagueScoringConfigRepository,
getLeagueScoringPresetById,
logger as any);
logger as unknown as Logger
);
});
it('should create league, season, and scoring successfully', async () => {
@@ -7,7 +7,6 @@ import type { SeasonRepository } from '../../domain/repositories/SeasonRepositor
import {
GetAllLeaguesWithCapacityAndScoringUseCase,
type GetAllLeaguesWithCapacityAndScoringInput,
type GetAllLeaguesWithCapacityAndScoringResult,
} from './GetAllLeaguesWithCapacityAndScoringUseCase';
describe('GetAllLeaguesWithCapacityAndScoringUseCase', () => {
@@ -1,10 +1,12 @@
import type { Logger } from '@core/shared/domain/Logger';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { GetDriverTeamUseCase, type GetDriverTeamInput } from './GetDriverTeamUseCase';
import type { TeamRepository } from '../../domain/repositories/TeamRepository';
import type { TeamMembershipRepository } from '../../domain/repositories/TeamMembershipRepository';
describe('GetDriverTeamUseCase', () => {
let mockTeamRepo: any;
let mockMembershipRepo: any;
let mockTeamRepo: TeamRepository;
let mockMembershipRepo: TeamMembershipRepository;
let mockLogger: Logger;
beforeEach(() => {
@@ -16,7 +18,7 @@ describe('GetDriverTeamUseCase', () => {
update: vi.fn(),
delete: vi.fn(),
exists: vi.fn(),
};
} as unknown as TeamRepository;
mockMembershipRepo = {
getActiveMembershipForDriver: vi.fn(),
@@ -28,7 +30,7 @@ describe('GetDriverTeamUseCase', () => {
countByTeamId: vi.fn(),
saveJoinRequest: vi.fn(),
removeJoinRequest: vi.fn(),
};
} as unknown as TeamMembershipRepository;
mockLogger = {
debug: vi.fn(),
@@ -5,9 +5,10 @@ import {
GetEntitySponsorshipPricingUseCase,
type GetEntitySponsorshipPricingInput
} from './GetEntitySponsorshipPricingUseCase';
import type { SponsorshipPricingRepository } from '../../domain/repositories/SponsorshipPricingRepository';
describe('GetEntitySponsorshipPricingUseCase', () => {
let mockSponsorshipPricingRepo: any;
let mockSponsorshipPricingRepo: SponsorshipPricingRepository;
let mockLogger: Logger;
let mockFindByEntity: Mock;
@@ -22,7 +23,7 @@ describe('GetEntitySponsorshipPricingUseCase', () => {
save: vi.fn(),
exists: vi.fn(),
findAcceptingApplications: vi.fn(),
};
} as unknown as SponsorshipPricingRepository;
mockLogger = {
debug: vi.fn(),
info: vi.fn(),
@@ -32,7 +33,7 @@ describe('GetEntitySponsorshipPricingUseCase', () => {
});
it('should return PRICING_NOT_CONFIGURED when no pricing found', async () => {
const useCase = new GetEntitySponsorshipPricingUseCase(mockSponsorshipPricingRepo as any,
const useCase = new GetEntitySponsorshipPricingUseCase(mockSponsorshipPricingRepo,
mockLogger);
const dto: GetEntitySponsorshipPricingInput = {
@@ -54,7 +55,7 @@ describe('GetEntitySponsorshipPricingUseCase', () => {
});
it('should return pricing data when found', async () => {
const useCase = new GetEntitySponsorshipPricingUseCase(mockSponsorshipPricingRepo as any,
const useCase = new GetEntitySponsorshipPricingUseCase(mockSponsorshipPricingRepo,
mockLogger);
const dto: GetEntitySponsorshipPricingInput = {
@@ -106,7 +107,7 @@ describe('GetEntitySponsorshipPricingUseCase', () => {
});
it('should return error when repository throws', async () => {
const useCase = new GetEntitySponsorshipPricingUseCase(mockSponsorshipPricingRepo as any,
const useCase = new GetEntitySponsorshipPricingUseCase(mockSponsorshipPricingRepo,
mockLogger);
const dto: GetEntitySponsorshipPricingInput = {
@@ -6,10 +6,12 @@ import {
type GetLeagueAdminPermissionsErrorCode,
type GetLeagueAdminPermissionsInput
} from './GetLeagueAdminPermissionsUseCase';
import type { LeagueRepository } from '../../domain/repositories/LeagueRepository';
import type { LeagueMembershipRepository } from '../../domain/repositories/LeagueMembershipRepository';
describe('GetLeagueAdminPermissionsUseCase', () => {
let mockLeagueRepo: any;
let mockMembershipRepo: any;
let mockLeagueRepo: LeagueRepository;
let mockMembershipRepo: LeagueMembershipRepository;
let mockFindById: Mock;
let mockGetMembership: Mock;
const logger: Logger = {
@@ -31,7 +33,7 @@ describe('GetLeagueAdminPermissionsUseCase', () => {
exists: vi.fn(),
findByOwnerId: vi.fn(),
searchByName: vi.fn(),
};
} as unknown as LeagueRepository;
mockMembershipRepo = {
getMembership: mockGetMembership,
@@ -43,7 +45,7 @@ describe('GetLeagueAdminPermissionsUseCase', () => {
removeJoinRequest: vi.fn(),
countByLeagueId: vi.fn(),
getLeagueMembers: vi.fn(),
};
} as unknown as LeagueMembershipRepository;
});
const createUseCase = () => new GetLeagueAdminPermissionsUseCase(mockLeagueRepo,
@@ -107,7 +109,7 @@ describe('GetLeagueAdminPermissionsUseCase', () => {
});
it('returns admin permissions for admin role', async () => {
const league = { id: 'league1' } as any;
const league = { id: 'league1' } as unknown as League;
mockFindById.mockResolvedValue(league);
mockGetMembership.mockResolvedValue({ status: 'active', role: 'admin' });
@@ -127,7 +129,7 @@ describe('GetLeagueAdminPermissionsUseCase', () => {
});
it('returns admin permissions for owner role', async () => {
const league = { id: 'league1' } as any;
const league = { id: 'league1' } as unknown as League;
mockFindById.mockResolvedValue(league);
mockGetMembership.mockResolvedValue({ status: 'active', role: 'owner' });
@@ -2,7 +2,6 @@ import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
import {
GetLeagueJoinRequestsUseCase,
type GetLeagueJoinRequestsInput,
type GetLeagueJoinRequestsResult,
type GetLeagueJoinRequestsErrorCode,
} from './GetLeagueJoinRequestsUseCase';
import { LeagueMembershipRepository } from '../../domain/repositories/LeagueMembershipRepository';
@@ -1,7 +1,6 @@
import { describe, it, expect, beforeEach, vi, Mock } from 'vitest';
import {
GetLeagueProtestsUseCase,
GetLeagueProtestsResult,
GetLeagueProtestsInput,
GetLeagueProtestsErrorCode,
} from './GetLeagueProtestsUseCase';
@@ -2,7 +2,6 @@ import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
import {
GetLeagueRosterJoinRequestsUseCase,
type GetLeagueRosterJoinRequestsInput,
type GetLeagueRosterJoinRequestsResult,
type GetLeagueRosterJoinRequestsErrorCode,
} from './GetLeagueRosterJoinRequestsUseCase';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
@@ -2,7 +2,6 @@ import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
import {
GetLeagueRosterMembersUseCase,
type GetLeagueRosterMembersInput,
type GetLeagueRosterMembersResult,
type GetLeagueRosterMembersErrorCode,
} from './GetLeagueRosterMembersUseCase';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
@@ -1,4 +1,4 @@
import { describe, it, expect, beforeEach, vi } from 'vitest';
import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
import { GetLeagueScoringConfigUseCase } from './GetLeagueScoringConfigUseCase';
import type { LeagueRepository } from '../../domain/repositories/LeagueRepository';
import type { SeasonRepository } from '../../domain/repositories/SeasonRepository';
@@ -12,27 +12,11 @@ import type { LeagueScoringPreset } from '../../domain/types/LeagueScoringPreset
describe('GetLeagueScoringConfigUseCase', () => {
let useCase: GetLeagueScoringConfigUseCase;
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 };
let mockLeagueRepository: LeagueRepository;
let mockSeasonRepository: SeasonRepository;
let mockLeagueScoringConfigRepository: LeagueScoringConfigRepository;
let mockGameRepository: GameRepository;
let mockPresetProvider: { getPresetById: Mock };
beforeEach(() => {
mockLeagueRepository = {
@@ -40,35 +24,35 @@ describe('GetLeagueScoringConfigUseCase', () => {
exists: vi.fn(),
save: vi.fn(),
findAll: vi.fn(),
};
} as unknown as LeagueRepository;
mockSeasonRepository = {
findByLeagueId: vi.fn(),
save: vi.fn(),
findById: vi.fn(),
};
} as unknown as SeasonRepository;
mockLeagueScoringConfigRepository = {
findBySeasonId: vi.fn(),
save: vi.fn(),
};
} as unknown as LeagueScoringConfigRepository;
mockGameRepository = {
findById: vi.fn(),
save: vi.fn(),
findAll: vi.fn(),
};
} as unknown as GameRepository;
mockPresetProvider = {
getPresetById: vi.fn(),
};
useCase = new GetLeagueScoringConfigUseCase(
mockLeagueRepository as unknown as LeagueRepository,
mockSeasonRepository as unknown as SeasonRepository,
mockLeagueScoringConfigRepository as unknown as LeagueScoringConfigRepository,
mockGameRepository as unknown as GameRepository,
mockPresetProvider as any,
mockLeagueRepository,
mockSeasonRepository,
mockLeagueScoringConfigRepository,
mockGameRepository,
mockPresetProvider as unknown as { getPresetById: (id: string) => LeagueScoringPreset | undefined },
);
});
@@ -96,7 +80,7 @@ describe('GetLeagueScoringConfigUseCase', () => {
const result = await useCase.execute({ leagueId: 'league-1' });
expect(result.isOk()).toBe(true);
const value = result.unwrap() as any;
const value = result.unwrap();
expect(value.league).toBe(mockLeague);
expect(value.season).toBe(mockSeason);
expect(value.scoringConfig).toBe(mockScoringConfig);
@@ -221,7 +205,7 @@ describe('GetLeagueScoringConfigUseCase', () => {
const result = await useCase.execute({ leagueId: 'league-1' });
expect(result.isOk()).toBe(true);
const value = result.unwrap() as any;
const value = result.unwrap();
expect(value.preset).toBeUndefined();
});
@@ -2,14 +2,13 @@ import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
import {
GetLeagueSeasonsUseCase,
type GetLeagueSeasonsInput,
type GetLeagueSeasonsResult,
type GetLeagueSeasonsErrorCode,
} from './GetLeagueSeasonsUseCase';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import type { SeasonRepository } from '../../domain/repositories/SeasonRepository';
import type { LeagueRepository } from '../../domain/repositories/LeagueRepository';
import { Season } from '../../domain/entities/season/Season';
import { League } from '../../domain/entities/League';
import type { LeagueRepository } from '../../domain/repositories/LeagueRepository';
import type { SeasonRepository } from '../../domain/repositories/SeasonRepository';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
describe('GetLeagueSeasonsUseCase', () => {
let useCase: GetLeagueSeasonsUseCase;
@@ -31,8 +30,10 @@ describe('GetLeagueSeasonsUseCase', () => {
exists: vi.fn(),
};
useCase = new GetLeagueSeasonsUseCase(leagueRepository as any,
seasonRepository as any);
useCase = new GetLeagueSeasonsUseCase(
leagueRepository as unknown as LeagueRepository,
seasonRepository as unknown as SeasonRepository
);
});
it('should return seasons with correct isParallelActive flags on success', async () => {
@@ -3,11 +3,12 @@ import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorC
import {
GetLeagueStandingsUseCase,
type GetLeagueStandingsInput,
type GetLeagueStandingsResult,
type GetLeagueStandingsErrorCode,
} from './GetLeagueStandingsUseCase';
import { Standing } from '../../domain/entities/Standing';
import { Driver } from '../../domain/entities/Driver';
import type { StandingRepository } from '../../domain/repositories/StandingRepository';
import type { DriverRepository } from '../../domain/repositories/DriverRepository';
describe('GetLeagueStandingsUseCase', () => {
let useCase: GetLeagueStandingsUseCase;
@@ -26,8 +27,8 @@ describe('GetLeagueStandingsUseCase', () => {
findById: vi.fn(),
};
useCase = new GetLeagueStandingsUseCase(standingRepository as any,
driverRepository as any);
useCase = new GetLeagueStandingsUseCase(standingRepository as unknown as StandingRepository,
driverRepository as unknown as DriverRepository);
});
it('should return standings with drivers mapped', async () => {
@@ -2,7 +2,6 @@ import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
import {
GetLeagueStatsUseCase,
type GetLeagueStatsInput,
type GetLeagueStatsResult,
type GetLeagueStatsErrorCode,
} from './GetLeagueStatsUseCase';
import type { LeagueMembershipRepository } from '../../domain/repositories/LeagueMembershipRepository';
@@ -27,8 +26,8 @@ describe('GetLeagueStatsUseCase', () => {
findByLeagueId: vi.fn(),
};
getDriverRating = vi.fn();
useCase = new GetLeagueStatsUseCase(leagueMembershipRepository as any,
raceRepository as any,
useCase = new GetLeagueStatsUseCase(leagueMembershipRepository as unknown as LeagueMembershipRepository,
raceRepository as unknown as RaceRepository,
getDriverRating);
});
@@ -1,7 +1,6 @@
import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
import {
GetLeagueWalletUseCase,
type GetLeagueWalletResult,
type GetLeagueWalletInput,
type GetLeagueWalletErrorCode,
} from './GetLeagueWalletUseCase';
@@ -40,9 +39,9 @@ describe('GetLeagueWalletUseCase', () => {
findByWalletId: vi.fn(),
};
useCase = new GetLeagueWalletUseCase(leagueRepository as any,
leagueWalletRepository as any,
transactionRepository as any);
useCase = new GetLeagueWalletUseCase(leagueRepository as unknown as LeagueRepository,
leagueWalletRepository as unknown as LeagueWalletRepository,
transactionRepository as unknown as TransactionRepository);
});
it('returns mapped wallet data when wallet exists', async () => {
@@ -1,7 +1,6 @@
import { describe, it, expect, beforeEach, vi, Mock } from 'vitest';
import {
GetPendingSponsorshipRequestsUseCase,
type GetPendingSponsorshipRequestsResult,
type GetPendingSponsorshipRequestsInput,
type GetPendingSponsorshipRequestsErrorCode,
} from './GetPendingSponsorshipRequestsUseCase';
@@ -1,13 +1,16 @@
import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
import {
GetProfileOverviewUseCase,
type GetProfileOverviewResult,
} from './GetProfileOverviewUseCase';
import { DriverRepository } from '../../domain/repositories/DriverRepository';
import { TeamRepository } from '../../domain/repositories/TeamRepository';
import { TeamMembershipRepository } from '../../domain/repositories/TeamMembershipRepository';
import { SocialGraphRepository } from '@core/social/domain/repositories/SocialGraphRepository';
import { Driver } from '../../domain/entities/Driver';
import type { DriverStatsUseCase } from './DriverStatsUseCase';
import type { RankingUseCase } from './RankingUseCase';
import type { DriverExtendedProfileProvider } from '../ports/DriverExtendedProfileProvider';
describe('GetProfileOverviewUseCase', () => {
let useCase: GetProfileOverviewUseCase;
let driverRepository: {
@@ -64,9 +67,9 @@ describe('GetProfileOverviewUseCase', () => {
teamRepository as unknown as TeamRepository,
teamMembershipRepository as unknown as TeamMembershipRepository,
socialRepository as unknown as SocialGraphRepository,
driverExtendedProfileProvider,
driverStatsUseCase as unknown as any,
rankingUseCase as unknown as any);
driverExtendedProfileProvider as unknown as DriverExtendedProfileProvider,
driverStatsUseCase as unknown as DriverStatsUseCase,
rankingUseCase as unknown as RankingUseCase);
});
it('should return profile overview for existing driver', async () => {
@@ -2,7 +2,6 @@ import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
import {
GetRaceProtestsUseCase,
type GetRaceProtestsInput,
type GetRaceProtestsResult,
type GetRaceProtestsErrorCode,
} from './GetRaceProtestsUseCase';
import { Protest } from '../../domain/entities/Protest';
@@ -2,7 +2,6 @@ import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
import {
GetRaceResultsDetailUseCase,
type GetRaceResultsDetailInput,
type GetRaceResultsDetailResult,
type GetRaceResultsDetailErrorCode,
} from './GetRaceResultsDetailUseCase';
import type { RaceRepository } from '../../domain/repositories/RaceRepository';
@@ -39,7 +39,7 @@ describe('GetRaceWithSOFUseCase', () => {
raceRepository as unknown as RaceRepository,
registrationRepository as unknown as RaceRegistrationRepository,
resultRepository as unknown as ResultRepository,
getDriverRating as any
getDriverRating as unknown as (input: { driverId: string }) => Promise<{ rating: number | null; ratingChange: number | null }>
);
});
@@ -8,6 +8,8 @@ import {
type GetRacesPageDataInput,
type GetRacesPageDataResult,
} from './GetRacesPageDataUseCase';
import type { RaceRepository } from '../../domain/repositories/RaceRepository';
import type { LeagueRepository } from '../../domain/repositories/LeagueRepository';
describe('GetRacesPageDataUseCase', () => {
let useCase: GetRacesPageDataUseCase;
@@ -2,7 +2,6 @@ import { describe, it, expect, beforeEach, vi, Mock } from 'vitest';
import {
GetSponsorDashboardUseCase,
type GetSponsorDashboardInput,
type GetSponsorDashboardResult,
type GetSponsorDashboardErrorCode,
} from './GetSponsorDashboardUseCase';
import { SponsorRepository } from '../../domain/repositories/SponsorRepository';
@@ -2,7 +2,6 @@ import { describe, it, expect, beforeEach, vi, Mock } from 'vitest';
import {
GetSponsorSponsorshipsUseCase,
type GetSponsorSponsorshipsInput,
type GetSponsorSponsorshipsResult,
type GetSponsorSponsorshipsErrorCode,
} from './GetSponsorSponsorshipsUseCase';
import { SponsorRepository } from '../../domain/repositories/SponsorRepository';
@@ -2,7 +2,6 @@ import { beforeEach, describe, expect, it, vi, type Mock } from 'vitest';
import {
GetSponsorUseCase,
type GetSponsorInput,
type GetSponsorResult,
type GetSponsorErrorCode,
} from './GetSponsorUseCase';
import type { SponsorRepository } from '../../domain/repositories/SponsorRepository';
@@ -1,6 +1,7 @@
import { describe, it, expect, beforeEach, vi, Mock } from 'vitest';
import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
import { GetSponsorsUseCase } from './GetSponsorsUseCase';
import { Sponsor } from '../../domain/entities/sponsor/Sponsor';
import type { SponsorRepository } from '../../domain/repositories/SponsorRepository';
describe('GetSponsorsUseCase', () => {
let useCase: GetSponsorsUseCase;
@@ -12,7 +13,7 @@ describe('GetSponsorsUseCase', () => {
sponsorRepository = {
findAll: vi.fn(),
};
useCase = new GetSponsorsUseCase(sponsorRepository as any);
useCase = new GetSponsorsUseCase(sponsorRepository as unknown as SponsorRepository);
});
it('should return all sponsors', async () => {
@@ -2,7 +2,6 @@ import { describe, it, expect, beforeEach, vi, Mock } from 'vitest';
import {
GetTeamDetailsUseCase,
type GetTeamDetailsInput,
type GetTeamDetailsResult,
type GetTeamDetailsErrorCode,
} from './GetTeamDetailsUseCase';
import { Team } from '../../domain/entities/Team';
@@ -25,8 +24,8 @@ describe('GetTeamDetailsUseCase', () => {
membershipRepository = {
getMembership: vi.fn(),
};
useCase = new GetTeamDetailsUseCase(teamRepository as any,
membershipRepository as any);
useCase = new GetTeamDetailsUseCase(teamRepository as unknown as TeamRepository,
membershipRepository as unknown as TeamMembershipRepository);
});
it('should return team details with membership', async () => {
@@ -9,7 +9,6 @@ import {
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;
@@ -46,7 +45,7 @@ describe('GetTeamsLeaderboardUseCase', () => {
useCase = new GetTeamsLeaderboardUseCase(
teamRepository as unknown as TeamRepository,
teamMembershipRepository as unknown as TeamMembershipRepository,
getDriverStats as any,
getDriverStats as unknown as (driverId: string) => { rating: number | null; wins: number; totalRaces: number } | null,
logger as unknown as Logger
);
});
@@ -3,7 +3,6 @@ import {
GetTotalDriversUseCase,
GetTotalDriversInput,
GetTotalDriversErrorCode,
GetTotalDriversResult,
} from './GetTotalDriversUseCase';
import { DriverRepository } from '../../domain/repositories/DriverRepository';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
@@ -2,7 +2,6 @@ import { describe, it, expect, beforeEach, vi, Mock } from 'vitest';
import {
GetTotalLeaguesUseCase,
type GetTotalLeaguesInput,
type GetTotalLeaguesResult,
type GetTotalLeaguesErrorCode,
} from './GetTotalLeaguesUseCase';
import type { LeagueRepository } from '../../domain/repositories/LeagueRepository';
@@ -2,7 +2,6 @@ import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
import {
GetTotalRacesUseCase,
type GetTotalRacesInput,
type GetTotalRacesResult,
type GetTotalRacesErrorCode,
} from './GetTotalRacesUseCase';
import type { RaceRepository } from '../../domain/repositories/RaceRepository';
@@ -1,10 +1,13 @@
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import { beforeEach, describe, expect, it, Mock, vi } from 'vitest';
import { beforeEach, describe, expect, it, type Mock, vi } from 'vitest';
import {
IsDriverRegisteredForRaceUseCase,
type IsDriverRegisteredForRaceErrorCode,
type IsDriverRegisteredForRaceInput
} from './IsDriverRegisteredForRaceUseCase';
import type { RaceRegistrationRepository } from '../../domain/repositories/RaceRegistrationRepository';
import type { Logger } from '@core/shared/domain/Logger';
describe('IsDriverRegisteredForRaceUseCase', () => {
let useCase: IsDriverRegisteredForRaceUseCase;
let registrationRepository: {
@@ -26,8 +29,8 @@ describe('IsDriverRegisteredForRaceUseCase', () => {
warn: vi.fn(),
error: vi.fn(),
};
useCase = new IsDriverRegisteredForRaceUseCase(registrationRepository as any,
logger as any);
useCase = new IsDriverRegisteredForRaceUseCase(registrationRepository as unknown as RaceRegistrationRepository,
logger as unknown as Logger);
});
it('should return true when driver is registered', async () => {
@@ -1,5 +1,5 @@
import { describe, it, expect, beforeEach, vi, Mock } from 'vitest';
import { JoinLeagueUseCase, type JoinLeagueResult, type JoinLeagueInput, type JoinLeagueErrorCode } from './JoinLeagueUseCase';
import { JoinLeagueUseCase, type JoinLeagueInput, type JoinLeagueErrorCode } from './JoinLeagueUseCase';
import { LeagueMembershipRepository } from '../../domain/repositories/LeagueMembershipRepository';
import { LeagueMembership } from '../../domain/entities/LeagueMembership';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
@@ -2,7 +2,6 @@ import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
import {
LeaveTeamUseCase,
type LeaveTeamInput,
type LeaveTeamResult,
type LeaveTeamErrorCode,
} from './LeaveTeamUseCase';
import type { TeamMembershipRepository } from '../../domain/repositories/TeamMembershipRepository';
@@ -1,12 +1,11 @@
import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
import { describe, it, expect, beforeEach, vi } from 'vitest';
import {
ListLeagueScoringPresetsUseCase,
type ListLeagueScoringPresetsInput,
type ListLeagueScoringPresetsResult,
type ListLeagueScoringPresetsErrorCode,
} from './ListLeagueScoringPresetsUseCase';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import type { Result } from '@core/shared/domain/Result';
import type { LeagueScoringPreset } from '../../domain/types/LeagueScoringPreset';
describe('ListLeagueScoringPresetsUseCase', () => {
let useCase: ListLeagueScoringPresetsUseCase;
@@ -48,7 +47,7 @@ describe('ListLeagueScoringPresetsUseCase', () => {
},
];
useCase = new ListLeagueScoringPresetsUseCase(mockPresets as any);
useCase = new ListLeagueScoringPresetsUseCase(mockPresets as unknown as LeagueScoringPreset[]);
});
it('should list presets successfully', async () => {
@@ -102,7 +101,7 @@ describe('ListLeagueScoringPresetsUseCase', () => {
map: () => {
throw new Error('Repository failure');
},
} as any;
} as unknown as LeagueScoringPreset[];
useCase = new ListLeagueScoringPresetsUseCase(failingPresets);
@@ -2,7 +2,6 @@ import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
import {
ListSeasonsForLeagueUseCase,
type ListSeasonsForLeagueInput,
type ListSeasonsForLeagueResult,
type ListSeasonsForLeagueErrorCode,
} from './ListSeasonsForLeagueUseCase';
import type { SeasonRepository } from '../../domain/repositories/SeasonRepository';
@@ -1,8 +1,7 @@
import { describe, it, expect, beforeEach, vi, Mock } from 'vitest';
import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
import {
ManageSeasonLifecycleUseCase,
type ManageSeasonLifecycleInput,
type ManageSeasonLifecycleResult,
type ManageSeasonLifecycleErrorCode,
} from './ManageSeasonLifecycleUseCase';
import type { SeasonRepository } from '../../domain/repositories/SeasonRepository';
@@ -28,8 +27,8 @@ describe('ManageSeasonLifecycleUseCase', () => {
findById: vi.fn(),
update: vi.fn(),
};
useCase = new ManageSeasonLifecycleUseCase(leagueRepository as any,
seasonRepository as any);
useCase = new ManageSeasonLifecycleUseCase(leagueRepository as unknown as LeagueRepository,
seasonRepository as unknown as SeasonRepository);
});
it('applies activate → complete → archive transitions and persists state', async () => {
@@ -58,7 +58,7 @@ export class QuickPenaltyUseCase {
// Validate admin has authority
const memberships = await this.leagueMembershipRepository.getLeagueMembers(race.leagueId);
const adminMembership = memberships.find(
(m: any) => m.driverId.toString() === input.adminId && m.status.toString() === 'active'
(m) => m.driverId.toString() === input.adminId && m.status.toString() === 'active'
);
if (!adminMembership || (adminMembership.role.toString() !== 'owner' && adminMembership.role.toString() !== 'admin')) {
@@ -7,6 +7,15 @@ import {
type RecalculateChampionshipStandingsErrorCode,
type RecalculateChampionshipStandingsInput
} from './RecalculateChampionshipStandingsUseCase';
import type { LeagueRepository } from '../../domain/repositories/LeagueRepository';
import type { SeasonRepository } from '../../domain/repositories/SeasonRepository';
import type { LeagueScoringConfigRepository } from '../../domain/repositories/LeagueScoringConfigRepository';
import type { RaceRepository } from '../../domain/repositories/RaceRepository';
import type { ResultRepository } from '../../domain/repositories/ResultRepository';
import type { PenaltyRepository } from '../../domain/repositories/PenaltyRepository';
import type { ChampionshipStandingRepository } from '../../domain/repositories/ChampionshipStandingRepository';
import type { EventScoringService } from '../../domain/services/EventScoringService';
import type { ChampionshipAggregator } from '../../domain/services/ChampionshipAggregator';
describe('RecalculateChampionshipStandingsUseCase', () => {
let useCase: RecalculateChampionshipStandingsUseCase;
@@ -36,17 +45,17 @@ describe('RecalculateChampionshipStandingsUseCase', () => {
info: vi.fn(),
warn: vi.fn(),
error: vi.fn(),
} as any;
} as unknown as Logger;
useCase = new RecalculateChampionshipStandingsUseCase(leagueRepository as any,
seasonRepository as any,
leagueScoringConfigRepository as any,
raceRepository as any,
resultRepository as any,
penaltyRepository as any,
championshipStandingRepository as any,
eventScoringService as any,
championshipAggregator as any,
useCase = new RecalculateChampionshipStandingsUseCase(leagueRepository as unknown as LeagueRepository,
seasonRepository as unknown as SeasonRepository,
leagueScoringConfigRepository as unknown as LeagueScoringConfigRepository,
raceRepository as unknown as RaceRepository,
resultRepository as unknown as ResultRepository,
penaltyRepository as unknown as PenaltyRepository,
championshipStandingRepository as unknown as ChampionshipStandingRepository,
eventScoringService as unknown as EventScoringService,
championshipAggregator as unknown as ChampionshipAggregator,
logger);
});
@@ -5,7 +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';
import { TeamRating } from '../../domain/value-objects/TeamRating';
// Mock repositories
class MockTeamRatingEventRepository implements TeamRatingEventRepository {
@@ -28,7 +28,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,
@@ -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 { TeamRating } from '../../domain/entities/TeamRating';
import { TeamRating } from '../../domain/value-objects/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(): Promise<TeamDrivingRaceFactsDto | null> {
return this.results;
}
@@ -42,7 +42,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,
@@ -319,7 +319,6 @@ describe('RecordTeamRaceRatingEventsUseCase', () => {
mockResultsProvider.setResults(raceResults);
// Mock repository to throw error
const originalSave = mockEventRepo.save.bind(mockEventRepo);
mockEventRepo.save = async () => {
throw new Error('Repository error');
};
@@ -19,10 +19,6 @@ describe('RejectLeagueJoinRequestUseCase', () => {
});
it('reject removes request only', async () => {
const output: { present: Mock } = {
present: vi.fn(),
};
const useCase = new RejectLeagueJoinRequestUseCase(leagueMembershipRepository as unknown as LeagueMembershipRepository);
leagueMembershipRepository.getJoinRequests.mockResolvedValue([
@@ -38,10 +34,6 @@ describe('RejectLeagueJoinRequestUseCase', () => {
});
it('reject returns error when request missing', async () => {
const output: { present: Mock } = {
present: vi.fn(),
};
const useCase = new RejectLeagueJoinRequestUseCase(leagueMembershipRepository as unknown as LeagueMembershipRepository);
leagueMembershipRepository.getJoinRequests.mockResolvedValue([]);
@@ -2,7 +2,6 @@ import { describe, it, expect, beforeEach, vi, Mock } from 'vitest';
import {
RemoveLeagueMemberUseCase,
type RemoveLeagueMemberInput,
type RemoveLeagueMemberResult,
type RemoveLeagueMemberErrorCode,
} from './RemoveLeagueMemberUseCase';
import type { LeagueMembershipRepository } from '../../domain/repositories/LeagueMembershipRepository';
@@ -7,6 +7,8 @@ import {
type ReopenRaceErrorCode,
type ReopenRaceInput
} from './ReopenRaceUseCase';
import type { RaceRepository } from '../../domain/repositories/RaceRepository';
import type { Logger } from '@core/shared/domain/Logger';
describe('ReopenRaceUseCase', () => {
let raceRepository: {
@@ -34,8 +36,8 @@ describe('ReopenRaceUseCase', () => {
error: vi.fn(),
};
useCase = new ReopenRaceUseCase(raceRepository as any,
logger as any);
useCase = new ReopenRaceUseCase(raceRepository as unknown as RaceRepository,
logger as unknown as Logger);
});
it('returns RACE_NOT_FOUND when race does not exist', async () => {
@@ -2,7 +2,6 @@ import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
import {
RequestProtestDefenseUseCase,
type RequestProtestDefenseInput,
type RequestProtestDefenseResult,
type RequestProtestDefenseErrorCode,
} from './RequestProtestDefenseUseCase';
import type { ProtestRepository } from '../../domain/repositories/ProtestRepository';
@@ -1,5 +1,5 @@
import { describe, it, expect, beforeEach, vi, Mock } from 'vitest';
import { ReviewProtestUseCase, type ReviewProtestInput, type ReviewProtestResult, type ReviewProtestErrorCode } from './ReviewProtestUseCase';
import { ReviewProtestUseCase, type ReviewProtestInput, type ReviewProtestErrorCode } from './ReviewProtestUseCase';
import type { ProtestRepository } from '../../domain/repositories/ProtestRepository';
import type { RaceRepository } from '../../domain/repositories/RaceRepository';
import type { LeagueMembershipRepository } from '../../domain/repositories/LeagueMembershipRepository';
@@ -2,7 +2,6 @@ import { beforeEach, describe, expect, it, vi, type Mock } from 'vitest';
import {
SendFinalResultsUseCase,
type SendFinalResultsInput,
type SendFinalResultsResult,
type SendFinalResultsErrorCode,
} from './SendFinalResultsUseCase';
import type { NotificationService } from '../../../notifications/application/ports/NotificationService';
@@ -2,7 +2,6 @@ import { beforeEach, describe, expect, it, vi, type Mock } from 'vitest';
import {
SendPerformanceSummaryUseCase,
type SendPerformanceSummaryInput,
type SendPerformanceSummaryResult,
type SendPerformanceSummaryErrorCode,
} from './SendPerformanceSummaryUseCase';
import type { NotificationService } from '../../../notifications/application/ports/NotificationService';
@@ -8,6 +8,8 @@ import {
type SubmitProtestDefenseInput,
type SubmitProtestDefenseResult,
} from './SubmitProtestDefenseUseCase';
import type { LeagueRepository } from '../../domain/repositories/LeagueRepository';
import type { ProtestRepository } from '../../domain/repositories/ProtestRepository';
interface MockProtest {
id: string;
@@ -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(): Promise<TeamDrivingRaceFactsDto | null> {
return this.results;
}
@@ -5,14 +5,12 @@ import { TeamRatingRepository } from '@core/racing/domain/repositories/TeamRatin
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';
// Mock repositories
class MockTeamRaceResultsProvider implements TeamRaceResultsProvider {
private results: TeamDrivingRaceFactsDto | null = null;
async getTeamRaceResults(raceId: string): Promise<TeamDrivingRaceFactsDto | null> {
async getTeamRaceResults(): Promise<TeamDrivingRaceFactsDto | null> {
return this.results;
}
@@ -41,7 +39,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,
@@ -58,13 +56,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;
}
@@ -202,7 +200,6 @@ describe('TeamRatingIntegrationAdapter', () => {
mockResultsProvider.setResults(raceResults);
// Mock repository to throw error
const originalSave = mockEventRepo.save.bind(mockEventRepo);
mockEventRepo.save = async () => {
throw new Error('Repository error');
};
@@ -276,12 +273,11 @@ describe('TeamRatingIntegrationAdapter', () => {
mockResultsProvider.setResults(raceResults);
// Mock repository to fail for team-456
const originalSave = mockEventRepo.save.bind(mockEventRepo);
mockEventRepo.save = async (event) => {
if (event.teamId === 'team-456') {
throw new Error('Simulated failure');
}
return originalSave(event);
return event;
};
const result = await adapter.recordTeamRatingsWithDetails('race-123');
@@ -6,10 +6,20 @@ import {
type TransferLeagueOwnershipErrorCode,
type TransferLeagueOwnershipInput
} from './TransferLeagueOwnershipUseCase';
import type { LeagueRepository } from '../../domain/repositories/LeagueRepository';
import type { LeagueMembershipRepository } from '../../domain/repositories/LeagueMembershipRepository';
import type { League } from '../../domain/entities/League';
import type { LeagueMembership } from '../../domain/entities/LeagueMembership';
describe('TransferLeagueOwnershipUseCase', () => {
let leagueRepository: any;
let membershipRepository: any;
let leagueRepository: {
findById: Mock;
update: Mock;
};
let membershipRepository: {
getMembership: Mock;
saveMembership: Mock;
};
let logger: Logger & { error: Mock };
let useCase: TransferLeagueOwnershipUseCase;
@@ -29,11 +39,11 @@ describe('TransferLeagueOwnershipUseCase', () => {
info: vi.fn(),
warn: vi.fn(),
error: vi.fn(),
} as any;
} as unknown as Logger & { error: Mock };
useCase = new TransferLeagueOwnershipUseCase(
leagueRepository,
membershipRepository,
leagueRepository as unknown as LeagueRepository,
membershipRepository as unknown as LeagueMembershipRepository,
logger,
);
});
@@ -43,21 +53,21 @@ describe('TransferLeagueOwnershipUseCase', () => {
id: 'league-1',
ownerId: { toString: () => 'owner-1' },
update: vi.fn().mockReturnValue({}),
} as any;
} as unknown as League;
const mockNewOwnerMembership = {
leagueId: 'league-1',
driverId: 'owner-2',
status: { toString: () => 'active' },
role: 'member',
} as any;
} as unknown as LeagueMembership;
const mockCurrentOwnerMembership = {
leagueId: 'league-1',
driverId: 'owner-1',
status: { toString: () => 'active' },
role: 'owner',
} as any;
} as unknown as LeagueMembership;
leagueRepository.findById.mockResolvedValue(mockLeague);
@@ -124,7 +134,7 @@ describe('TransferLeagueOwnershipUseCase', () => {
id: 'league-1',
ownerId: { toString: () => 'other-owner' },
update: vi.fn(),
} as any;
} as unknown as League;
leagueRepository.findById.mockResolvedValue(mockLeague);
@@ -150,7 +160,7 @@ describe('TransferLeagueOwnershipUseCase', () => {
id: 'league-1',
ownerId: { toString: () => 'owner-1' },
update: vi.fn(),
} as any;
} as unknown as League;
leagueRepository.findById.mockResolvedValue(mockLeague);
@@ -178,7 +188,7 @@ describe('TransferLeagueOwnershipUseCase', () => {
id: 'league-1',
ownerId: { toString: () => 'owner-1' },
update: vi.fn().mockReturnValue({}),
} as any;
} as unknown as League;
leagueRepository.findById.mockResolvedValue(mockLeague);
@@ -187,7 +197,7 @@ describe('TransferLeagueOwnershipUseCase', () => {
driverId: 'owner-2',
status: { toString: () => 'active' },
role: 'member',
} as any;
} as unknown as LeagueMembership;
membershipRepository.getMembership
.mockResolvedValueOnce(mockNewOwnerMembership)
@@ -2,7 +2,6 @@ import { describe, it, expect, vi, beforeEach } from 'vitest';
import {
UpdateDriverProfileUseCase,
type UpdateDriverProfileInput,
type UpdateDriverProfileResult,
type UpdateDriverProfileErrorCode,
} from './UpdateDriverProfileUseCase';
import type { DriverRepository } from '../../domain/repositories/DriverRepository';
@@ -48,9 +48,10 @@ describe('UpdateLeagueMemberRoleUseCase', () => {
it('returns error if membership not found', async () => {
const mockLeagueMembershipRepository = {
getLeagueMembers: vi.fn().mockResolvedValue([]),
} as any;
saveMembership: vi.fn(),
};
const useCase = new UpdateLeagueMemberRoleUseCase(mockLeagueMembershipRepository);
const useCase = new UpdateLeagueMemberRoleUseCase(mockLeagueMembershipRepository as unknown as LeagueMembershipRepository);
const input: UpdateLeagueMemberRoleInput = {
leagueId: 'league-1',
@@ -75,9 +76,10 @@ describe('UpdateLeagueMemberRoleUseCase', () => {
getLeagueMembers: vi
.fn()
.mockRejectedValue(new Error('Database connection failed')),
} as any;
saveMembership: vi.fn(),
};
const useCase = new UpdateLeagueMemberRoleUseCase(mockLeagueMembershipRepository);
const useCase = new UpdateLeagueMemberRoleUseCase(mockLeagueMembershipRepository as unknown as LeagueMembershipRepository);
const input: UpdateLeagueMemberRoleInput = {
leagueId: 'league-1',
@@ -110,14 +112,14 @@ 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 result = await useCase.execute({
leagueId: 'league-1',
targetDriverId: 'driver-1',
newRole: 'manager' as any,
newRole: 'manager' as unknown as 'member',
});
expect(result.isErr()).toBe(true);
@@ -143,9 +145,9 @@ describe('UpdateLeagueMemberRoleUseCase', () => {
const mockLeagueMembershipRepository = {
getLeagueMembers: vi.fn().mockResolvedValue([mockOwnerMembership]),
saveMembership: vi.fn().mockResolvedValue(undefined),
} as any;
};
const useCase = new UpdateLeagueMemberRoleUseCase(mockLeagueMembershipRepository);
const useCase = new UpdateLeagueMemberRoleUseCase(mockLeagueMembershipRepository as unknown as LeagueMembershipRepository);
const result = await useCase.execute({
leagueId: 'league-1',
@@ -1,5 +1,5 @@
import { describe, it, expect, vi } from 'vitest';
import { UpdateTeamUseCase, type UpdateTeamInput, type UpdateTeamResult, type UpdateTeamErrorCode } from './UpdateTeamUseCase';
import { UpdateTeamUseCase, type UpdateTeamInput, type UpdateTeamErrorCode } from './UpdateTeamUseCase';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import type { TeamRepository } from '../../domain/repositories/TeamRepository';
import type { TeamMembershipRepository } from '../../domain/repositories/TeamMembershipRepository';
@@ -54,11 +54,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({} as unknown as TeamRepository, mockMembershipRepository);
const command: UpdateTeamInput = {
@@ -207,7 +207,7 @@ describe('WithdrawFromLeagueWalletUseCase', () => {
const presented = result.unwrap();
expect(transactionRepository.create).toHaveBeenCalledTimes(1);
const createdTx = (transactionRepository.create as Mock).mock.calls[0]![0] as any;
const createdTx = (transactionRepository.create as Mock).mock.calls[0]![0] as Transaction;
const expectedTransactionId = `txn-${new Date('2025-01-01T00:00:00.000Z').getTime()}`;
@@ -1,11 +1,12 @@
import { TeamRatingEvent } from './TeamRatingEvent';
import { describe, it, expect } from 'vitest';
import { TeamRatingEvent, type TeamRatingEventProps } from './TeamRatingEvent';
import { TeamRatingEventId } from '../value-objects/TeamRatingEventId';
import { TeamRatingDimensionKey } from '../value-objects/TeamRatingDimensionKey';
import { TeamRatingDelta } from '../value-objects/TeamRatingDelta';
import { RacingDomainValidationError, RacingDomainInvariantError } from '../errors/RacingDomainError';
describe('TeamRatingEvent', () => {
const validProps = {
const validProps: TeamRatingEventProps = {
id: TeamRatingEventId.create('123e4567-e89b-12d3-a456-426614174000'),
teamId: 'team-123',
dimension: TeamRatingDimensionKey.create('driving'),
@@ -47,28 +48,43 @@ describe('TeamRatingEvent', () => {
});
it('should throw for missing dimension', () => {
const { dimension: _, ...rest } = validProps;
expect(() => TeamRatingEvent.create(rest as typeof validProps)).toThrow(RacingDomainValidationError);
const props = { ...validProps };
// @ts-expect-error - testing validation
// eslint-disable-next-line @typescript-eslint/no-explicit-any
delete (props as any).dimension;
expect(() => TeamRatingEvent.create(props as unknown as TeamRatingEventProps)).toThrow(RacingDomainValidationError);
});
it('should throw for missing delta', () => {
const { delta: _, ...rest } = validProps;
expect(() => TeamRatingEvent.create(rest as typeof validProps)).toThrow(RacingDomainValidationError);
const props = { ...validProps };
// @ts-expect-error - testing validation
// eslint-disable-next-line @typescript-eslint/no-explicit-any
delete (props as any).delta;
expect(() => TeamRatingEvent.create(props as unknown as TeamRatingEventProps)).toThrow(RacingDomainValidationError);
});
it('should throw for missing source', () => {
const { source: _, ...rest } = validProps;
expect(() => TeamRatingEvent.create(rest as typeof validProps)).toThrow(RacingDomainValidationError);
const props = { ...validProps };
// @ts-expect-error - testing validation
// eslint-disable-next-line @typescript-eslint/no-explicit-any
delete (props as any).source;
expect(() => TeamRatingEvent.create(props as unknown as TeamRatingEventProps)).toThrow(RacingDomainValidationError);
});
it('should throw for missing reason', () => {
const { reason: _, ...rest } = validProps;
expect(() => TeamRatingEvent.create(rest as typeof validProps)).toThrow(RacingDomainValidationError);
const props = { ...validProps };
// @ts-expect-error - testing validation
// eslint-disable-next-line @typescript-eslint/no-explicit-any
delete (props as any).reason;
expect(() => TeamRatingEvent.create(props as unknown as TeamRatingEventProps)).toThrow(RacingDomainValidationError);
});
it('should throw for missing visibility', () => {
const { visibility: _, ...rest } = validProps;
expect(() => TeamRatingEvent.create(rest as typeof validProps)).toThrow(RacingDomainValidationError);
const props = { ...validProps };
// @ts-expect-error - testing validation
// eslint-disable-next-line @typescript-eslint/no-explicit-any
delete (props as any).visibility;
expect(() => TeamRatingEvent.create(props as unknown as TeamRatingEventProps)).toThrow(RacingDomainValidationError);
});
it('should throw for invalid weight', () => {
@@ -6,6 +6,7 @@ import {
type GetUserFeedApplicationError,
type GetUserFeedInput,
} from './GetUserFeedUseCase';
import type { FeedRepository } from '../../domain/repositories/FeedRepository';
describe('GetUserFeedUseCase', () => {
let feedRepository: FeedRepository & { getFeedForDriver: Mock };
+5
View File
@@ -0,0 +1,5 @@
{
"extends": "./tsconfig.json",
"include": ["**/*.ts"],
"exclude": ["node_modules", "dist"]
}