fix issues in core

This commit is contained in:
2025-12-23 15:38:50 +01:00
parent df5c20c5cc
commit 120d3bb1a1
125 changed files with 1005 additions and 793 deletions

View File

@@ -1,6 +1,7 @@
import { describe, it, expect, vi } from 'vitest';
import { Season } from '@core/racing/domain/entities/season/Season';
import { League } from '@core/racing/domain/entities/League';
import type { ISeasonRepository } from '@core/racing/domain/repositories/ISeasonRepository';
import type { ILeagueRepository } from '@core/racing/domain/repositories/ILeagueRepository';
import {
@@ -23,13 +24,49 @@ import type { LeagueConfigFormModel } from '@core/racing/application/dto/LeagueC
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
function createFakeLeagueRepository(seed: Array<{ id: string }>): ILeagueRepository {
type MockOutputPort<T> = UseCaseOutputPort<T> & { present: ReturnType<typeof vi.fn> };
function createOutputPort<T>(): MockOutputPort<T> {
return {
findById: async (id: string) => seed.find((l) => l.id === id) ?? null,
findAll: async () => seed,
create: async (league: any) => league,
update: async (league: any) => league,
} as unknown as ILeagueRepository;
present: vi.fn<(data: T) => void>(),
};
}
function getUnknownString(value: unknown): string | null {
if (typeof value === 'string') return value;
if (
value &&
typeof value === 'object' &&
'toString' in value &&
typeof (value as { toString: unknown }).toString === 'function'
) {
return (value as { toString: () => string }).toString();
}
return null;
}
function createFakeLeagueRepository(seed: Array<{ id: string }>): ILeagueRepository {
const leagues: League[] = seed.map(({ id }) =>
League.create({
id,
name: `League ${id}`,
description: 'Test league',
ownerId: 'owner-1',
}),
);
return {
findById: async (id: string) =>
leagues.find((league) => league.id.toString() === id) ?? null,
findAll: async () => leagues,
findByOwnerId: async (ownerId: string) =>
leagues.filter((league) => getUnknownString((league as unknown as { ownerId: unknown }).ownerId) === ownerId),
create: async (league: League) => league,
update: async (league: League) => league,
delete: async () => undefined,
exists: async (id: string) => leagues.some((league) => league.id.toString() === id),
searchByName: async () => [],
};
}
function createLeagueConfigFormModel(overrides?: Partial<LeagueConfigFormModel>): LeagueConfigFormModel {
@@ -100,9 +137,7 @@ describe('CreateSeasonForLeagueUseCase', () => {
listActiveByLeague: vi.fn(),
} as unknown as ISeasonRepository;
const output: UseCaseOutputPort<CreateSeasonForLeagueResult> & { present: ReturnType<typeof vi.fn> } = {
present: vi.fn(),
} as any;
const output = createOutputPort<CreateSeasonForLeagueResult>();
const useCase = new CreateSeasonForLeagueUseCase(leagueRepo, seasonRepo, output);
@@ -150,7 +185,9 @@ describe('CreateSeasonForLeagueUseCase', () => {
expect(result.unwrap()).toBeUndefined();
expect(output.present).toHaveBeenCalledTimes(1);
const payload = (output.present as ReturnType<typeof vi.fn>).mock.calls[0][0] as CreateSeasonForLeagueResult;
const payloadRaw = (output.present as ReturnType<typeof vi.fn>).mock.calls[0]?.[0];
expect(payloadRaw).toBeDefined();
const payload = payloadRaw as CreateSeasonForLeagueResult;
const season = payload.season;
expect(season.leagueId).toBe('league-1');
@@ -199,7 +236,9 @@ describe('CreateSeasonForLeagueUseCase', () => {
expect(result.unwrap()).toBeUndefined();
expect(output.present).toHaveBeenCalledTimes(1);
const payload = (output.present as ReturnType<typeof vi.fn>).mock.calls[0][0] as CreateSeasonForLeagueResult;
const payloadRaw = (output.present as ReturnType<typeof vi.fn>).mock.calls[0]?.[0];
expect(payloadRaw).toBeDefined();
const payload = payloadRaw as CreateSeasonForLeagueResult;
const season = payload.season;
expect(season.id).not.toBe(sourceSeason.id);
@@ -223,9 +262,7 @@ describe('CreateSeasonForLeagueUseCase', () => {
listActiveByLeague: vi.fn(),
} as unknown as ISeasonRepository;
const output: UseCaseOutputPort<CreateSeasonForLeagueResult> & { present: ReturnType<typeof vi.fn> } = {
present: vi.fn(),
} as any;
const output = createOutputPort<CreateSeasonForLeagueResult>();
const useCase = new CreateSeasonForLeagueUseCase(leagueRepo, seasonRepo, output);
@@ -257,9 +294,7 @@ describe('ListSeasonsForLeagueUseCase', () => {
listActiveByLeague: vi.fn(),
} as unknown as ISeasonRepository;
const output: UseCaseOutputPort<ListSeasonsForLeagueResult> & { present: ReturnType<typeof vi.fn> } = {
present: vi.fn(),
} as any;
const output = createOutputPort<ListSeasonsForLeagueResult>();
const useCase = new ListSeasonsForLeagueUseCase(leagueRepo, seasonRepo, output);
@@ -303,7 +338,9 @@ describe('ListSeasonsForLeagueUseCase', () => {
expect(result.unwrap()).toBeUndefined();
expect(output.present).toHaveBeenCalledTimes(1);
const payload = (output.present as ReturnType<typeof vi.fn>).mock.calls[0][0] as ListSeasonsForLeagueResult;
const payloadRaw = (output.present as ReturnType<typeof vi.fn>).mock.calls[0]?.[0];
expect(payloadRaw).toBeDefined();
const payload = payloadRaw as ListSeasonsForLeagueResult;
const league1Seasons = payload.seasons.filter((s) => s.leagueId === 'league-1');
expect(league1Seasons.map((s) => s.id).sort()).toEqual(['season-1', 'season-2']);
@@ -319,9 +356,7 @@ describe('ListSeasonsForLeagueUseCase', () => {
listActiveByLeague: vi.fn(),
} as unknown as ISeasonRepository;
const output: UseCaseOutputPort<ListSeasonsForLeagueResult> & { present: ReturnType<typeof vi.fn> } = {
present: vi.fn(),
} as any;
const output = createOutputPort<ListSeasonsForLeagueResult>();
const useCase = new ListSeasonsForLeagueUseCase(leagueRepo, seasonRepo, output);
@@ -347,9 +382,7 @@ describe('GetSeasonDetailsUseCase', () => {
listActiveByLeague: vi.fn(),
} as unknown as ISeasonRepository;
const output: UseCaseOutputPort<GetSeasonDetailsResult> & { present: ReturnType<typeof vi.fn> } = {
present: vi.fn(),
} as any;
const output = createOutputPort<GetSeasonDetailsResult>();
const useCase = new GetSeasonDetailsUseCase(leagueRepo, seasonRepo, output);
@@ -378,7 +411,9 @@ describe('GetSeasonDetailsUseCase', () => {
expect(result.unwrap()).toBeUndefined();
expect(output.present).toHaveBeenCalledTimes(1);
const payload = (output.present as ReturnType<typeof vi.fn>).mock.calls[0][0] as GetSeasonDetailsResult;
const payloadRaw = (output.present as ReturnType<typeof vi.fn>).mock.calls[0]?.[0];
expect(payloadRaw).toBeDefined();
const payload = payloadRaw as GetSeasonDetailsResult;
expect(payload.season.id).toBe('season-1');
expect(payload.season.leagueId).toBe('league-1');
@@ -441,9 +476,7 @@ describe('ManageSeasonLifecycleUseCase', () => {
listActiveByLeague: vi.fn(),
} as unknown as ISeasonRepository;
const output: UseCaseOutputPort<ManageSeasonLifecycleResult> & { present: ReturnType<typeof vi.fn> } = {
present: vi.fn(),
} as any;
const output = createOutputPort<ManageSeasonLifecycleResult>();
const useCase = new ManageSeasonLifecycleUseCase(leagueRepo, seasonRepo, output);
@@ -476,7 +509,9 @@ describe('ManageSeasonLifecycleUseCase', () => {
const activated = await useCase.execute(activateCommand);
expect(activated.isOk()).toBe(true);
const activatePayload = (output.present as ReturnType<typeof vi.fn>).mock.calls[0][0] as ManageSeasonLifecycleResult;
const activatePayloadRaw = (output.present as ReturnType<typeof vi.fn>).mock.calls[0]?.[0];
expect(activatePayloadRaw).toBeDefined();
const activatePayload = activatePayloadRaw as ManageSeasonLifecycleResult;
expect(activatePayload.season.status).toBe('active');
const completeCommand: ManageSeasonLifecycleCommand = {
@@ -488,7 +523,9 @@ describe('ManageSeasonLifecycleUseCase', () => {
const completed = await useCase.execute(completeCommand);
expect(completed.isOk()).toBe(true);
const completePayload = (output.present as ReturnType<typeof vi.fn>).mock.calls[1][0] as ManageSeasonLifecycleResult;
const completePayloadRaw = (output.present as ReturnType<typeof vi.fn>).mock.calls[1]?.[0];
expect(completePayloadRaw).toBeDefined();
const completePayload = completePayloadRaw as ManageSeasonLifecycleResult;
expect(completePayload.season.status).toBe('completed');
const archiveCommand: ManageSeasonLifecycleCommand = {
@@ -500,7 +537,9 @@ describe('ManageSeasonLifecycleUseCase', () => {
const archived = await useCase.execute(archiveCommand);
expect(archived.isOk()).toBe(true);
const archivePayload = (output.present as ReturnType<typeof vi.fn>).mock.calls[2][0] as ManageSeasonLifecycleResult;
const archivePayloadRaw = (output.present as ReturnType<typeof vi.fn>).mock.calls[2]?.[0];
expect(archivePayloadRaw).toBeDefined();
const archivePayload = archivePayloadRaw as ManageSeasonLifecycleResult;
expect(archivePayload.season.status).toBe('archived');
expect(currentSeason.status).toBe('archived');
@@ -544,9 +583,7 @@ describe('ManageSeasonLifecycleUseCase', () => {
listActiveByLeague: vi.fn(),
} as unknown as ISeasonRepository;
const output: UseCaseOutputPort<ManageSeasonLifecycleResult> & { present: ReturnType<typeof vi.fn> } = {
present: vi.fn(),
} as any;
const output = createOutputPort<ManageSeasonLifecycleResult>();
const useCase = new ManageSeasonLifecycleUseCase(leagueRepo, seasonRepo, output);
@@ -575,9 +612,7 @@ describe('ManageSeasonLifecycleUseCase', () => {
listActiveByLeague: vi.fn(),
} as unknown as ISeasonRepository;
const output: UseCaseOutputPort<ManageSeasonLifecycleResult> & { present: ReturnType<typeof vi.fn> } = {
present: vi.fn(),
} as any;
const output = createOutputPort<ManageSeasonLifecycleResult>();
const useCase = new ManageSeasonLifecycleUseCase(leagueRepo, seasonRepo, output);