resolve todos in website and api

This commit is contained in:
2025-12-20 10:45:56 +01:00
parent 656ec62426
commit 7bbad511e2
62 changed files with 2036 additions and 611 deletions

View File

@@ -0,0 +1,75 @@
import { GetAllRacesPresenter } from './GetAllRacesPresenter';
import type { GetAllRacesOutputPort } from '@core/racing/application/ports/output/GetAllRacesOutputPort';
describe('GetAllRacesPresenter', () => {
it('should map races and distinct leagues into the DTO', async () => {
const presenter = new GetAllRacesPresenter();
const output: GetAllRacesOutputPort = {
races: [
{
id: 'race-1',
leagueId: 'league-1',
track: 'Track A',
car: 'Car A',
status: 'scheduled',
scheduledAt: '2025-01-01T10:00:00.000Z',
strengthOfField: 1500,
leagueName: 'League One',
},
{
id: 'race-2',
leagueId: 'league-1',
track: 'Track B',
car: 'Car B',
status: 'completed',
scheduledAt: '2025-01-02T10:00:00.000Z',
strengthOfField: null,
leagueName: 'League One',
},
{
id: 'race-3',
leagueId: 'league-2',
track: 'Track C',
car: 'Car C',
status: 'running',
scheduledAt: '2025-01-03T10:00:00.000Z',
strengthOfField: 1800,
leagueName: 'League Two',
},
],
totalCount: 3,
};
await presenter.present(output);
const viewModel = presenter.getViewModel();
expect(viewModel).not.toBeNull();
expect(viewModel!.races).toHaveLength(3);
// Leagues should be distinct and match league ids/names from races
expect(viewModel!.filters.leagues).toEqual(
expect.arrayContaining([
{ id: 'league-1', name: 'League One' },
{ id: 'league-2', name: 'League Two' },
]),
);
expect(viewModel!.filters.leagues).toHaveLength(2);
});
it('should handle empty races by returning empty leagues', async () => {
const presenter = new GetAllRacesPresenter();
const output: GetAllRacesOutputPort = {
races: [],
totalCount: 0,
};
await presenter.present(output);
const viewModel = presenter.getViewModel();
expect(viewModel).not.toBeNull();
expect(viewModel!.races).toHaveLength(0);
expect(viewModel!.filters.leagues).toHaveLength(0);
});
})

View File

@@ -9,6 +9,15 @@ export class GetAllRacesPresenter {
}
async present(output: GetAllRacesOutputPort) {
const uniqueLeagues = new Map<string, { id: string; name: string }>();
for (const race of output.races) {
uniqueLeagues.set(race.leagueId, {
id: race.leagueId,
name: race.leagueName,
});
}
this.result = {
races: output.races.map(race => ({
id: race.id,
@@ -28,7 +37,7 @@ export class GetAllRacesPresenter {
{ value: 'completed', label: 'Completed' },
{ value: 'cancelled', label: 'Cancelled' },
],
leagues: [], // TODO: populate if needed
leagues: Array.from(uniqueLeagues.values()),
},
};
}