website refactor

This commit is contained in:
2026-01-16 12:55:48 +01:00
parent 0208334c59
commit 20a42c52fd
83 changed files with 1610 additions and 1238 deletions

View File

@@ -168,8 +168,8 @@ describe('AllLeaguesWithCapacityAndScoringPresenter', () => {
schedule: {
startDate: new Date('2024-01-01'),
timeOfDay: { hour: 20, minute: 0 },
} as any,
} as any);
} as never,
} as never);
const scoringConfig = LeagueScoringConfig.create({
id: 'scoring-1',
@@ -264,8 +264,8 @@ describe('AllLeaguesWithCapacityAndScoringPresenter', () => {
schedule: {
startDate: new Date('2024-01-01'),
timeOfDay: { hour: 20, minute: 0 },
} as any,
} as any);
} as never,
} as never);
const scoringConfig = LeagueScoringConfig.create({
id: 'scoring-1',
@@ -464,7 +464,7 @@ describe('AllLeaguesWithCapacityAndScoringPresenter', () => {
});
// Override logoRef to uploaded type
(league as any).logoRef = MediaReference.fromJSON({
(league as unknown as { logoRef: unknown }).logoRef = MediaReference.fromJSON({
type: 'uploaded',
mediaId: 'media-123',
});

View File

@@ -28,7 +28,7 @@ describe('CreateLeaguePresenter', () => {
gameId: 'iracing',
name: 'Test League Season 1',
status: 'active',
} as any);
} as never);
const scoringConfig = LeagueScoringConfig.create({
id: 'scoring-1',
@@ -80,7 +80,7 @@ describe('CreateLeaguePresenter', () => {
gameId: 'iracing',
name: 'Another League Season 1',
status: 'active',
} as any);
} as never);
const scoringConfig = LeagueScoringConfig.create({
id: 'scoring-2',
@@ -138,7 +138,7 @@ describe('CreateLeaguePresenter', () => {
gameId: 'iracing',
name: 'Test League Season 1',
status: 'active',
} as any);
} as never);
const scoringConfig = LeagueScoringConfig.create({
id: 'scoring-1',
@@ -190,7 +190,7 @@ describe('CreateLeaguePresenter', () => {
gameId: 'iracing',
name: 'Test League Season 1',
status: 'active',
} as any);
} as never);
const scoringConfig = LeagueScoringConfig.create({
id: 'scoring-1',

View File

@@ -6,7 +6,7 @@ describe('GetLeagueMembershipsPresenter', () => {
const presenter = new GetLeagueMembershipsPresenter();
const output: GetLeagueMembershipsResult = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
league: {} as any,
league: {} as never,
memberships: [
{
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -15,7 +15,7 @@ describe('GetLeagueMembershipsPresenter', () => {
role: 'member',
joinedAt: { toDate: () => new Date('2024-01-01T00:00:00Z') },
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} as any,
} as never,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
driver: {
id: 'driver-1',
@@ -23,7 +23,7 @@ describe('GetLeagueMembershipsPresenter', () => {
name: 'John Doe',
country: 'US',
joinedAt: { toDate: () => new Date('2024-01-01T00:00:00Z') },
} as any,
} as never,
},
],
};

View File

@@ -2,8 +2,8 @@
import { LeagueConfigPresenter } from './LeagueConfigPresenter';
describe('LeagueConfigPresenter', () => {
const createFullConfig = (overrides: Partial<any> = {}): any => {
const base: any = {
const createFullConfig = (overrides: Partial<any> = {}): unknown => {
const base: unknown = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
league: {
id: 'league-1',
@@ -12,7 +12,7 @@ describe('LeagueConfigPresenter', () => {
ownerId: 'owner-1',
settings: { pointsSystem: 'custom' },
createdAt: new Date(),
} as any,
} as never,
activeSeason: {
id: 'season-1',
leagueId: 'league-1',
@@ -21,9 +21,9 @@ describe('LeagueConfigPresenter', () => {
status: 'planned',
schedule: {
startDate: new Date('2025-01-05T19:00:00Z'),
timeOfDay: { hour: 20, minute: 0 } as any,
} as any,
dropPolicy: { strategy: 'bestNResults', n: 3 } as any,
timeOfDay: { hour: 20, minute: 0 } as never,
} as never,
dropPolicy: { strategy: 'bestNResults', n: 3 } as never,
stewardingConfig: {
decisionMode: 'steward_vote',
requiredVotes: 3,
@@ -34,8 +34,8 @@ describe('LeagueConfigPresenter', () => {
stewardingClosesHours: 72,
notifyAccusedOnProtest: true,
notifyOnVoteRequired: true,
} as any,
} as any,
} as never,
} as never,
scoringConfig: {
id: 'scoring-1',
seasonId: 'season-1',
@@ -43,17 +43,17 @@ describe('LeagueConfigPresenter', () => {
{
id: 'champ-1',
name: 'Drivers',
type: 'driver' as any,
sessionTypes: ['race'] as any,
type: 'driver' as never,
sessionTypes: ['race'] as never,
pointsTableBySessionType: {
race: {
getPointsForPosition: (pos: number) => (pos === 1 ? 25 : 0),
} as any,
} as never,
},
dropScorePolicy: { strategy: 'bestNResults', count: 3 } as any,
dropScorePolicy: { strategy: 'bestNResults', count: 3 } as never,
},
],
} as any,
} as never,
game: undefined,
...overrides,
};
@@ -65,7 +65,7 @@ describe('LeagueConfigPresenter', () => {
const presenter = new LeagueConfigPresenter();
const fullConfig = createFullConfig();
presenter.present({ config: fullConfig });
presenter.present({ config: fullConfig } as never);
const vm = presenter.getViewModel()!;
expect(vm).not.toBeNull();

View File

@@ -10,8 +10,28 @@ export class LeagueConfigPresenter implements UseCaseOutputPort<GetLeagueFullCon
}
present(result: GetLeagueFullConfigResult): void {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const dto = result.config as any;
const dto = result.config as unknown as {
league: { id: string; name: string; description: string; settings: { pointsSystem: string } };
activeSeason?: {
stewardingConfig?: {
decisionMode: string;
requireDefense: boolean;
defenseTimeLimit: number;
voteTimeLimit: number;
protestDeadlineHours: number;
stewardingClosesHours: number;
notifyAccusedOnProtest: boolean;
notifyOnVoteRequired: boolean;
requiredVotes?: number;
};
dropPolicy?: { strategy: string; n?: number };
schedule?: {
startDate?: Date;
timeOfDay?: { hour: number; minute: number };
};
};
scoringConfig?: { championships: { sessionTypes: string[]; pointsTableBySessionType: Record<string, { getPointsForPosition: (pos: number) => number }> }[] };
};
const league = dto.league;
const settings = league.settings;
const stewarding = dto.activeSeason?.stewardingConfig;
@@ -53,7 +73,7 @@ export class LeagueConfigPresenter implements UseCaseOutputPort<GetLeagueFullCon
},
dropPolicy: {
strategy: dropPolicy?.strategy === 'none' ? 'none' : 'worst_n',
n: dropPolicy?.n,
...(dropPolicy?.n !== undefined ? { n: dropPolicy.n } : {}),
},
timings: {
raceDayOfWeek,
@@ -69,7 +89,7 @@ export class LeagueConfigPresenter implements UseCaseOutputPort<GetLeagueFullCon
stewardingClosesHours: stewarding?.stewardingClosesHours ?? 168,
notifyAccusedOnProtest: stewarding?.notifyAccusedOnProtest ?? true,
notifyOnVoteRequired: stewarding?.notifyOnVoteRequired ?? true,
requiredVotes: stewarding?.requiredVotes,
...(stewarding?.requiredVotes !== undefined ? { requiredVotes: stewarding.requiredVotes } : {}),
},
};
}

View File

@@ -13,7 +13,7 @@ describe('LeagueJoinRequestsPresenter', () => {
requestedAt: new Date('2023-01-01'),
message: 'Please accept me',
// eslint-disable-next-line @typescript-eslint/no-explicit-any
driver: { id: 'driver-1', name: 'John Doe' } as any,
driver: { id: 'driver-1', name: 'John Doe' } as never,
},
],
};

View File

@@ -6,7 +6,7 @@ describe('LeagueOwnerSummaryPresenter', () => {
const presenter = new LeagueOwnerSummaryPresenter();
const output: GetLeagueOwnerSummaryResult = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
league: {} as any,
league: {} as never,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
owner: {
id: 'driver-1',
@@ -14,9 +14,9 @@ describe('LeagueOwnerSummaryPresenter', () => {
name: 'John Doe',
country: 'US',
bio: 'Racing enthusiast',
joinedAt: { toDate: () => new Date('2024-01-01T00:00:00Z') } as any,
joinedAt: { toDate: () => new Date('2024-01-01T00:00:00Z') } as never,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} as any,
} as never,
totalMembers: 50,
activeMembers: 45,
rating: 1500,

View File

@@ -19,23 +19,23 @@ describe('LeagueSchedulePresenter', () => {
seasonId: 'season-1',
published: false,
races: [{ race }],
} as any);
} as never);
const vm = presenter.getViewModel() as any;
const vm = presenter.getViewModel() as unknown as { seasonId: string, published: boolean, races: { id: string, name: string, date: string }[] };
expect(vm).not.toBeNull();
expect(vm.seasonId).toBe('season-1');
expect(vm.published).toBe(false);
expect(Array.isArray(vm.races)).toBe(true);
expect(vm.races[0]).toMatchObject({
expect(vm.races[0]!).toMatchObject({
id: 'race-1',
name: 'Spa - GT3',
date: '2025-01-02T20:00:00.000Z',
});
// Guard: dates must be ISO strings (no Date objects)
expect(typeof vm.races[0].date).toBe('string');
expect(vm.races[0].date).toMatch(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/);
expect(typeof vm.races[0]!.date).toBe('string');
expect(vm.races[0]!.date).toMatch(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/);
});
});