website refactor
This commit is contained in:
@@ -37,7 +37,7 @@ describe('LeagueController', () => {
|
||||
|
||||
it('getTotalLeagues should return total leagues', async () => {
|
||||
const mockResult = { totalLeagues: 1 };
|
||||
leagueService.getTotalLeagues.mockResolvedValue(mockResult as any);
|
||||
leagueService.getTotalLeagues.mockResolvedValue(mockResult as never);
|
||||
|
||||
const result = await controller.getTotalLeagues();
|
||||
|
||||
@@ -47,7 +47,7 @@ describe('LeagueController', () => {
|
||||
|
||||
it('getAllLeaguesWithCapacity should return leagues and totalCount', async () => {
|
||||
const mockResult = { leagues: [], totalCount: 0 };
|
||||
leagueService.getAllLeaguesWithCapacity.mockResolvedValue(mockResult as any);
|
||||
leagueService.getAllLeaguesWithCapacity.mockResolvedValue(mockResult as never);
|
||||
|
||||
const result = await controller.getAllLeaguesWithCapacity();
|
||||
|
||||
@@ -57,7 +57,7 @@ describe('LeagueController', () => {
|
||||
|
||||
it('getLeagueStandings should return standings', async () => {
|
||||
const mockResult = { standings: [] };
|
||||
leagueService.getLeagueStandings.mockResolvedValue(mockResult as any);
|
||||
leagueService.getLeagueStandings.mockResolvedValue(mockResult as never);
|
||||
|
||||
const result = await controller.getLeagueStandings('league-1');
|
||||
|
||||
@@ -66,7 +66,7 @@ describe('LeagueController', () => {
|
||||
});
|
||||
|
||||
describe('auth guards (HTTP)', () => {
|
||||
let app: any;
|
||||
let app: import("@nestjs/common").INestApplication;
|
||||
|
||||
const sessionPort: { getCurrentSession: () => Promise<null | { token: string; user: { id: string } }> } = {
|
||||
getCurrentSession: vi.fn(async () => null),
|
||||
@@ -105,9 +105,9 @@ describe('LeagueController', () => {
|
||||
|
||||
const reflector = new Reflector();
|
||||
app.useGlobalGuards(
|
||||
new AuthenticationGuard(sessionPort as any),
|
||||
new AuthorizationGuard(reflector, authorizationService as any),
|
||||
new FeatureAvailabilityGuard(reflector, policyService as any),
|
||||
new AuthenticationGuard(sessionPort as never),
|
||||
new AuthorizationGuard(reflector, authorizationService as never),
|
||||
new FeatureAvailabilityGuard(reflector, policyService as never),
|
||||
);
|
||||
|
||||
await app.init();
|
||||
|
||||
@@ -15,7 +15,7 @@ import { FeatureAvailabilityGuard } from '../policy/FeatureAvailabilityGuard';
|
||||
describe('League roster admin read (HTTP, league-scoped)', () => {
|
||||
const originalEnv = { ...process.env };
|
||||
|
||||
let app: any;
|
||||
let app: import("@nestjs/common").INestApplication;
|
||||
|
||||
beforeAll(async () => {
|
||||
vi.resetModules();
|
||||
@@ -62,9 +62,9 @@ describe('League roster admin read (HTTP, league-scoped)', () => {
|
||||
};
|
||||
|
||||
app.useGlobalGuards(
|
||||
new AuthenticationGuard(sessionPort as any),
|
||||
new AuthorizationGuard(reflector, authorizationService as any),
|
||||
new FeatureAvailabilityGuard(reflector, policyService as any),
|
||||
new AuthenticationGuard(sessionPort as never),
|
||||
new AuthorizationGuard(reflector, authorizationService as never),
|
||||
new FeatureAvailabilityGuard(reflector, policyService as never),
|
||||
);
|
||||
|
||||
await app.init();
|
||||
@@ -105,7 +105,7 @@ describe('League roster admin read (HTTP, league-scoped)', () => {
|
||||
expect(res.body).toEqual(expect.any(Array));
|
||||
expect(res.body.length).toBeGreaterThan(0);
|
||||
|
||||
const first = res.body[0] as any;
|
||||
const first = res.body[0] as unknown as { driver: { id: string, name: string, country: string }, role: string };
|
||||
expect(first).toMatchObject({
|
||||
driverId: expect.any(String),
|
||||
role: expect.any(String),
|
||||
@@ -133,8 +133,8 @@ describe('League roster admin read (HTTP, league-scoped)', () => {
|
||||
|
||||
// Seed data may or may not include join requests for a given league.
|
||||
// Validate shape on first item if present.
|
||||
if ((res.body as any[]).length > 0) {
|
||||
const first = (res.body as any[])[0];
|
||||
if ((res.body as never[]).length > 0) {
|
||||
const first = (res.body as unknown as { message?: string }[])[0];
|
||||
expect(first).toMatchObject({
|
||||
id: expect.any(String),
|
||||
leagueId: expect.any(String),
|
||||
@@ -146,8 +146,10 @@ describe('League roster admin read (HTTP, league-scoped)', () => {
|
||||
},
|
||||
});
|
||||
|
||||
if (first.message !== undefined) {
|
||||
expect(first.message).toEqual(expect.any(String));
|
||||
if (first) {
|
||||
if (first.message !== undefined) {
|
||||
expect(first.message).toEqual(expect.any(String));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -25,7 +25,7 @@ import { JoinRequest } from '@core/racing/domain/entities/JoinRequest';
|
||||
import { LeagueMembership } from '@core/racing/domain/entities/LeagueMembership';
|
||||
|
||||
describe('League roster join request mutations (HTTP)', () => {
|
||||
let app: any;
|
||||
let app: import("@nestjs/common").INestApplication;
|
||||
|
||||
const sessionPort: { getCurrentSession: () => Promise<null | { token: string; user: { id: string } }> } = {
|
||||
getCurrentSession: vi.fn(async () => null),
|
||||
@@ -123,15 +123,16 @@ describe('League roster join request mutations (HTTP)', () => {
|
||||
app = module.createNestApplication();
|
||||
|
||||
// Required for getActorFromRequestContext() used by requireLeagueAdminOrOwner().
|
||||
app.use(requestContextMiddleware as any);
|
||||
app.use(requestContextMiddleware as never);
|
||||
|
||||
// Test-only auth injection: emulate an authenticated session by setting request.user.
|
||||
app.use((req: any, _res: any, next: any) => {
|
||||
const userId = req.headers['x-test-user-id'];
|
||||
app.use((req: unknown, _res: unknown, next: unknown) => {
|
||||
const r = req as { headers: Record<string, string>, user?: { userId: string } };
|
||||
const userId = r.headers['x-test-user-id'];
|
||||
if (typeof userId === 'string' && userId.length > 0) {
|
||||
req.user = { userId };
|
||||
r.user = { userId };
|
||||
}
|
||||
next();
|
||||
(next as () => void)();
|
||||
});
|
||||
|
||||
app.useGlobalPipes(
|
||||
@@ -144,8 +145,8 @@ describe('League roster join request mutations (HTTP)', () => {
|
||||
|
||||
const reflector = new Reflector();
|
||||
app.useGlobalGuards(
|
||||
new AuthenticationGuard(sessionPort as any),
|
||||
new AuthorizationGuard(reflector, authorizationService as any),
|
||||
new AuthenticationGuard(sessionPort as never),
|
||||
new AuthorizationGuard(reflector, authorizationService as never),
|
||||
);
|
||||
|
||||
await app.init();
|
||||
@@ -202,7 +203,7 @@ describe('League roster join request mutations (HTTP)', () => {
|
||||
.expect(200);
|
||||
|
||||
expect(Array.isArray(joinRequests.body)).toBe(true);
|
||||
expect(joinRequests.body.find((r: any) => r.id === 'jr-1')).toBeUndefined();
|
||||
expect(joinRequests.body.find((r: unknown) => (r as { id: string }).id === 'jr-1')).toBeUndefined();
|
||||
|
||||
const members = await request(app.getHttpServer())
|
||||
.get('/leagues/league-1/admin/roster/members')
|
||||
@@ -210,7 +211,7 @@ describe('League roster join request mutations (HTTP)', () => {
|
||||
.expect(200);
|
||||
|
||||
expect(Array.isArray(members.body)).toBe(true);
|
||||
expect(members.body.some((m: any) => m.driverId === 'driver-2')).toBe(true);
|
||||
expect(members.body.some((m: unknown) => (m as { driverId: string }).driverId === 'driver-2')).toBe(true);
|
||||
});
|
||||
|
||||
it('reject removes request only; roster reads reflect changes', async () => {
|
||||
@@ -232,7 +233,7 @@ describe('League roster join request mutations (HTTP)', () => {
|
||||
.expect(200);
|
||||
|
||||
expect(Array.isArray(joinRequests.body)).toBe(true);
|
||||
expect(joinRequests.body.find((r: any) => r.id === 'jr-1')).toBeUndefined();
|
||||
expect(joinRequests.body.find((r: unknown) => (r as { id: string }).id === 'jr-1')).toBeUndefined();
|
||||
|
||||
const members = await request(app.getHttpServer())
|
||||
.get('/leagues/league-1/admin/roster/members')
|
||||
@@ -240,7 +241,7 @@ describe('League roster join request mutations (HTTP)', () => {
|
||||
.expect(200);
|
||||
|
||||
expect(Array.isArray(members.body)).toBe(true);
|
||||
expect(members.body.some((m: any) => m.driverId === 'driver-2')).toBe(false);
|
||||
expect(members.body.some((m: unknown) => (m as { driverId: string }).driverId === 'driver-2')).toBe(false);
|
||||
});
|
||||
|
||||
it('approve returns error when league is full and keeps request pending', async () => {
|
||||
@@ -264,6 +265,6 @@ describe('League roster join request mutations (HTTP)', () => {
|
||||
.expect(200);
|
||||
|
||||
expect(Array.isArray(joinRequests.body)).toBe(true);
|
||||
expect(joinRequests.body.find((r: any) => r.id === 'jr-1')).toBeDefined();
|
||||
expect(joinRequests.body.find((r: unknown) => (r as { id: string }).id === 'jr-1')).toBeDefined();
|
||||
});
|
||||
});
|
||||
@@ -24,7 +24,7 @@ import { Driver } from '@core/racing/domain/entities/Driver';
|
||||
import { LeagueMembership } from '@core/racing/domain/entities/LeagueMembership';
|
||||
|
||||
describe('League roster member mutations (HTTP)', () => {
|
||||
let app: any;
|
||||
let app: import("@nestjs/common").INestApplication;
|
||||
|
||||
const sessionPort: { getCurrentSession: () => Promise<null | { token: string; user: { id: string } }> } = {
|
||||
getCurrentSession: vi.fn(async () => null),
|
||||
@@ -98,15 +98,16 @@ describe('League roster member mutations (HTTP)', () => {
|
||||
app = module.createNestApplication();
|
||||
|
||||
// Required for getActorFromRequestContext() used by requireLeagueAdminOrOwner().
|
||||
app.use(requestContextMiddleware as any);
|
||||
app.use(requestContextMiddleware as never);
|
||||
|
||||
// Test-only auth injection: emulate an authenticated session by setting request.user.
|
||||
app.use((req: any, _res: any, next: any) => {
|
||||
const userId = req.headers['x-test-user-id'];
|
||||
app.use((req: unknown, _res: unknown, next: unknown) => {
|
||||
const r = req as { headers: Record<string, string>, user?: { userId: string } };
|
||||
const userId = r.headers['x-test-user-id'];
|
||||
if (typeof userId === 'string' && userId.length > 0) {
|
||||
req.user = { userId };
|
||||
r.user = { userId };
|
||||
}
|
||||
next();
|
||||
(next as () => void)();
|
||||
});
|
||||
|
||||
app.useGlobalPipes(
|
||||
@@ -119,8 +120,8 @@ describe('League roster member mutations (HTTP)', () => {
|
||||
|
||||
const reflector = new Reflector();
|
||||
app.useGlobalGuards(
|
||||
new AuthenticationGuard(sessionPort as any),
|
||||
new AuthorizationGuard(reflector, authorizationService as any),
|
||||
new AuthenticationGuard(sessionPort as never),
|
||||
new AuthorizationGuard(reflector, authorizationService as never),
|
||||
);
|
||||
|
||||
await app.init();
|
||||
@@ -173,9 +174,9 @@ describe('League roster member mutations (HTTP)', () => {
|
||||
|
||||
expect(Array.isArray(members.body)).toBe(true);
|
||||
|
||||
const updated = (members.body as any[]).find(m => m.driverId === 'driver-2');
|
||||
const updated = (members.body as { driverId: string, role: string }[]).find((m: unknown) => (m as { driverId: string }).driverId === 'driver-2');
|
||||
expect(updated).toBeDefined();
|
||||
expect(updated.role).toBe('steward');
|
||||
expect(updated?.role).toBe('steward');
|
||||
});
|
||||
|
||||
it('member removal is reflected in roster members read', async () => {
|
||||
@@ -192,6 +193,6 @@ describe('League roster member mutations (HTTP)', () => {
|
||||
.expect(200);
|
||||
|
||||
expect(Array.isArray(members.body)).toBe(true);
|
||||
expect((members.body as any[]).some(m => m.driverId === 'driver-2')).toBe(false);
|
||||
expect((members.body as never[]).some((m: unknown) => (m as { driverId: string }).driverId === 'driver-2')).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -15,7 +15,7 @@ import { FeatureAvailabilityGuard } from '../policy/FeatureAvailabilityGuard';
|
||||
describe('League schedule admin CRUD (HTTP, season-scoped)', () => {
|
||||
const originalEnv = { ...process.env };
|
||||
|
||||
let app: any;
|
||||
let app: import("@nestjs/common").INestApplication;
|
||||
|
||||
beforeAll(async () => {
|
||||
vi.resetModules();
|
||||
@@ -62,9 +62,9 @@ describe('League schedule admin CRUD (HTTP, season-scoped)', () => {
|
||||
};
|
||||
|
||||
app.useGlobalGuards(
|
||||
new AuthenticationGuard(sessionPort as any),
|
||||
new AuthorizationGuard(reflector, authorizationService as any),
|
||||
new FeatureAvailabilityGuard(reflector, policyService as any),
|
||||
new AuthenticationGuard(sessionPort as never),
|
||||
new AuthorizationGuard(reflector, authorizationService as never),
|
||||
new FeatureAvailabilityGuard(reflector, policyService as never),
|
||||
);
|
||||
|
||||
await app.init();
|
||||
@@ -152,7 +152,7 @@ describe('League schedule admin CRUD (HTTP, season-scoped)', () => {
|
||||
const raceId: string = createRes.body.raceId;
|
||||
|
||||
const afterCreateRes = await agent.get('/leagues/league-5/schedule?seasonId=league-5-season-1').expect(200);
|
||||
const createdRace = (afterCreateRes.body.races as any[]).find((r) => r.id === raceId);
|
||||
const createdRace = (afterCreateRes.body.races as { id: string }[]).find((r) => r.id === raceId);
|
||||
expect(createdRace).toMatchObject({
|
||||
id: raceId,
|
||||
name: 'Test Track - Test Car',
|
||||
@@ -174,7 +174,7 @@ describe('League schedule admin CRUD (HTTP, season-scoped)', () => {
|
||||
});
|
||||
|
||||
const afterUpdateRes = await agent.get('/leagues/league-5/schedule?seasonId=league-5-season-1').expect(200);
|
||||
const updatedRace = (afterUpdateRes.body.races as any[]).find((r) => r.id === raceId);
|
||||
const updatedRace = (afterUpdateRes.body.races as { id: string }[]).find((r) => r.id === raceId);
|
||||
expect(updatedRace).toMatchObject({
|
||||
id: raceId,
|
||||
name: 'Updated Track - Updated Car',
|
||||
@@ -186,7 +186,7 @@ describe('League schedule admin CRUD (HTTP, season-scoped)', () => {
|
||||
});
|
||||
|
||||
const afterDeleteRes = await agent.get('/leagues/league-5/schedule?seasonId=league-5-season-1').expect(200);
|
||||
const deletedRace = (afterDeleteRes.body.races as any[]).find((r) => r.id === raceId);
|
||||
const deletedRace = (afterDeleteRes.body.races as { id: string }[]).find((r) => r.id === raceId);
|
||||
expect(deletedRace).toBeUndefined();
|
||||
});
|
||||
});
|
||||
@@ -15,7 +15,7 @@ import { FeatureAvailabilityGuard } from '../policy/FeatureAvailabilityGuard';
|
||||
describe('League season schedule publish/unpublish (HTTP, season-scoped)', () => {
|
||||
const originalEnv = { ...process.env };
|
||||
|
||||
let app: any;
|
||||
let app: import("@nestjs/common").INestApplication;
|
||||
|
||||
beforeAll(async () => {
|
||||
vi.resetModules();
|
||||
@@ -62,9 +62,9 @@ describe('League season schedule publish/unpublish (HTTP, season-scoped)', () =>
|
||||
};
|
||||
|
||||
app.useGlobalGuards(
|
||||
new AuthenticationGuard(sessionPort as any),
|
||||
new AuthorizationGuard(reflector, authorizationService as any),
|
||||
new FeatureAvailabilityGuard(reflector, policyService as any),
|
||||
new AuthenticationGuard(sessionPort as never),
|
||||
new AuthorizationGuard(reflector, authorizationService as never),
|
||||
new FeatureAvailabilityGuard(reflector, policyService as never),
|
||||
);
|
||||
|
||||
await app.init();
|
||||
|
||||
@@ -8,7 +8,7 @@ async function withUserId<T>(userId: string, fn: () => Promise<T>): Promise<T> {
|
||||
const res = {};
|
||||
|
||||
return await new Promise<T>((resolve, reject) => {
|
||||
requestContextMiddleware(req as any, res as any, () => {
|
||||
requestContextMiddleware(req as never, res as never, () => {
|
||||
fn().then(resolve, reject);
|
||||
});
|
||||
});
|
||||
@@ -19,13 +19,13 @@ describe('LeagueService', () => {
|
||||
const logger = { debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() };
|
||||
|
||||
const ok = async () => Result.ok(undefined);
|
||||
const err = async () => Result.err({ code: 'REPOSITORY_ERROR', details: { message: 'boom' } });
|
||||
const err = async () => Result.err({ code: 'REPOSITORY_ERROR', details: { message: 'boom' } } as never);
|
||||
|
||||
const getAllLeaguesWithCapacityUseCase: any = { execute: vi.fn(async () => Result.ok({ leagues: [] })) };
|
||||
const getAllLeaguesWithCapacityAndScoringUseCase: any = { execute: vi.fn(ok) };
|
||||
const getAllLeaguesWithCapacityUseCase = { execute: vi.fn(async () => Result.ok({ leagues: [] })) };
|
||||
const getAllLeaguesWithCapacityAndScoringUseCase = { execute: vi.fn(ok) };
|
||||
const getLeagueStandingsUseCase = { execute: vi.fn(ok) };
|
||||
const getLeagueStatsUseCase = { execute: vi.fn(ok) };
|
||||
const getLeagueFullConfigUseCase: any = { execute: vi.fn(ok) };
|
||||
const getLeagueFullConfigUseCase = { execute: vi.fn(ok) };
|
||||
const getLeagueScoringConfigUseCase = { execute: vi.fn(ok) };
|
||||
const listLeagueScoringPresetsUseCase = { execute: vi.fn(ok) };
|
||||
const joinLeagueUseCase = { execute: vi.fn(ok) };
|
||||
@@ -120,74 +120,74 @@ describe('LeagueService', () => {
|
||||
const publishLeagueSeasonSchedulePresenter = { present: vi.fn(), getResponseModel: vi.fn(() => ({ success: true, published: true })) };
|
||||
const unpublishLeagueSeasonSchedulePresenter = { present: vi.fn(), getResponseModel: vi.fn(() => ({ success: true, published: false })) };
|
||||
|
||||
const service = new (LeagueService as any)(
|
||||
getAllLeaguesWithCapacityUseCase as any,
|
||||
getAllLeaguesWithCapacityAndScoringUseCase as any,
|
||||
getLeagueStandingsUseCase as any,
|
||||
getLeagueStatsUseCase as any,
|
||||
getLeagueFullConfigUseCase as any,
|
||||
getLeagueScoringConfigUseCase as any,
|
||||
listLeagueScoringPresetsUseCase as any,
|
||||
joinLeagueUseCase as any,
|
||||
transferLeagueOwnershipUseCase as any,
|
||||
createLeagueWithSeasonAndScoringUseCase as any,
|
||||
getTotalLeaguesUseCase as any,
|
||||
getLeagueJoinRequestsUseCase as any,
|
||||
approveLeagueJoinRequestUseCase as any,
|
||||
rejectLeagueJoinRequestUseCase as any,
|
||||
removeLeagueMemberUseCase as any,
|
||||
updateLeagueMemberRoleUseCase as any,
|
||||
getLeagueOwnerSummaryUseCase as any,
|
||||
getLeagueProtestsUseCase as any,
|
||||
getLeagueSeasonsUseCase as any,
|
||||
getLeagueMembershipsUseCase as any,
|
||||
getLeagueScheduleUseCase as any,
|
||||
getLeagueAdminPermissionsUseCase as any,
|
||||
getLeagueWalletUseCase as any,
|
||||
withdrawFromLeagueWalletUseCase as any,
|
||||
getSeasonSponsorshipsUseCase as any,
|
||||
createLeagueSeasonScheduleRaceUseCase as any,
|
||||
updateLeagueSeasonScheduleRaceUseCase as any,
|
||||
deleteLeagueSeasonScheduleRaceUseCase as any,
|
||||
publishLeagueSeasonScheduleUseCase as any,
|
||||
unpublishLeagueSeasonScheduleUseCase as any,
|
||||
logger as any,
|
||||
allLeaguesWithCapacityPresenter as any,
|
||||
allLeaguesWithCapacityAndScoringPresenter as any,
|
||||
leagueStandingsPresenter as any,
|
||||
leagueProtestsPresenter as any,
|
||||
seasonSponsorshipsPresenter as any,
|
||||
leagueScoringPresetsPresenter as any,
|
||||
approveLeagueJoinRequestPresenter as any,
|
||||
createLeaguePresenter as any,
|
||||
getLeagueAdminPermissionsPresenter as any,
|
||||
getLeagueMembershipsPresenter as any,
|
||||
getLeagueOwnerSummaryPresenter as any,
|
||||
getLeagueSeasonsPresenter as any,
|
||||
joinLeaguePresenter as any,
|
||||
leagueSchedulePresenter as any,
|
||||
leagueStatsPresenter as any,
|
||||
rejectLeagueJoinRequestPresenter as any,
|
||||
removeLeagueMemberPresenter as any,
|
||||
totalLeaguesPresenter as any,
|
||||
transferLeagueOwnershipPresenter as any,
|
||||
updateLeagueMemberRolePresenter as any,
|
||||
leagueConfigPresenter as any,
|
||||
leagueScoringConfigPresenter as any,
|
||||
getLeagueWalletPresenter as any,
|
||||
withdrawFromLeagueWalletPresenter as any,
|
||||
leagueJoinRequestsPresenter as any,
|
||||
createLeagueSeasonScheduleRacePresenter as any,
|
||||
updateLeagueSeasonScheduleRacePresenter as any,
|
||||
deleteLeagueSeasonScheduleRacePresenter as any,
|
||||
publishLeagueSeasonSchedulePresenter as any,
|
||||
unpublishLeagueSeasonSchedulePresenter as any,
|
||||
const service = new (LeagueService as unknown as { new (...args: never[]): LeagueService })(
|
||||
getAllLeaguesWithCapacityUseCase as never,
|
||||
getAllLeaguesWithCapacityAndScoringUseCase as never,
|
||||
getLeagueStandingsUseCase as never,
|
||||
getLeagueStatsUseCase as never,
|
||||
getLeagueFullConfigUseCase as never,
|
||||
getLeagueScoringConfigUseCase as never,
|
||||
listLeagueScoringPresetsUseCase as never,
|
||||
joinLeagueUseCase as never,
|
||||
transferLeagueOwnershipUseCase as never,
|
||||
createLeagueWithSeasonAndScoringUseCase as never,
|
||||
getTotalLeaguesUseCase as never,
|
||||
getLeagueJoinRequestsUseCase as never,
|
||||
approveLeagueJoinRequestUseCase as never,
|
||||
rejectLeagueJoinRequestUseCase as never,
|
||||
removeLeagueMemberUseCase as never,
|
||||
updateLeagueMemberRoleUseCase as never,
|
||||
getLeagueOwnerSummaryUseCase as never,
|
||||
getLeagueProtestsUseCase as never,
|
||||
getLeagueSeasonsUseCase as never,
|
||||
getLeagueMembershipsUseCase as never,
|
||||
getLeagueScheduleUseCase as never,
|
||||
getLeagueAdminPermissionsUseCase as never,
|
||||
getLeagueWalletUseCase as never,
|
||||
withdrawFromLeagueWalletUseCase as never,
|
||||
getSeasonSponsorshipsUseCase as never,
|
||||
createLeagueSeasonScheduleRaceUseCase as never,
|
||||
updateLeagueSeasonScheduleRaceUseCase as never,
|
||||
deleteLeagueSeasonScheduleRaceUseCase as never,
|
||||
publishLeagueSeasonScheduleUseCase as never,
|
||||
unpublishLeagueSeasonScheduleUseCase as never,
|
||||
logger as never,
|
||||
allLeaguesWithCapacityPresenter as never,
|
||||
allLeaguesWithCapacityAndScoringPresenter as never,
|
||||
leagueStandingsPresenter as never,
|
||||
leagueProtestsPresenter as never,
|
||||
seasonSponsorshipsPresenter as never,
|
||||
leagueScoringPresetsPresenter as never,
|
||||
approveLeagueJoinRequestPresenter as never,
|
||||
createLeaguePresenter as never,
|
||||
getLeagueAdminPermissionsPresenter as never,
|
||||
getLeagueMembershipsPresenter as never,
|
||||
getLeagueOwnerSummaryPresenter as never,
|
||||
getLeagueSeasonsPresenter as never,
|
||||
joinLeaguePresenter as never,
|
||||
leagueSchedulePresenter as never,
|
||||
leagueStatsPresenter as never,
|
||||
rejectLeagueJoinRequestPresenter as never,
|
||||
removeLeagueMemberPresenter as never,
|
||||
totalLeaguesPresenter as never,
|
||||
transferLeagueOwnershipPresenter as never,
|
||||
updateLeagueMemberRolePresenter as never,
|
||||
leagueConfigPresenter as never,
|
||||
leagueScoringConfigPresenter as never,
|
||||
getLeagueWalletPresenter as never,
|
||||
withdrawFromLeagueWalletPresenter as never,
|
||||
leagueJoinRequestsPresenter as never,
|
||||
createLeagueSeasonScheduleRacePresenter as never,
|
||||
updateLeagueSeasonScheduleRacePresenter as never,
|
||||
deleteLeagueSeasonScheduleRacePresenter as never,
|
||||
publishLeagueSeasonSchedulePresenter as never,
|
||||
unpublishLeagueSeasonSchedulePresenter as never,
|
||||
|
||||
// Roster admin read delegation (added for strict TDD)
|
||||
getLeagueRosterMembersUseCase as any,
|
||||
getLeagueRosterJoinRequestsUseCase as any,
|
||||
getLeagueRosterMembersPresenter as any,
|
||||
getLeagueRosterJoinRequestsPresenter as any,
|
||||
getLeagueRosterMembersUseCase as never,
|
||||
getLeagueRosterJoinRequestsUseCase as never,
|
||||
getLeagueRosterMembersPresenter as never,
|
||||
getLeagueRosterJoinRequestsPresenter as never,
|
||||
);
|
||||
|
||||
await expect(service.getTotalLeagues()).resolves.toEqual({ total: 1 });
|
||||
@@ -196,13 +196,13 @@ describe('LeagueService', () => {
|
||||
});
|
||||
|
||||
await withUserId('user-1', async () => {
|
||||
await expect(service.approveLeagueJoinRequest({ leagueId: 'l1', requestId: 'r1' } as any)).resolves.toEqual({
|
||||
await expect(service.approveLeagueJoinRequest({ leagueId: 'l1', requestId: 'r1' } as never)).resolves.toEqual({
|
||||
success: true,
|
||||
});
|
||||
});
|
||||
|
||||
await withUserId('user-1', async () => {
|
||||
await expect(service.rejectLeagueJoinRequest({ leagueId: 'l1', requestId: 'r1' } as any)).resolves.toEqual({
|
||||
await expect(service.rejectLeagueJoinRequest({ leagueId: 'l1', requestId: 'r1' } as never)).resolves.toEqual({
|
||||
success: true,
|
||||
});
|
||||
});
|
||||
@@ -212,11 +212,11 @@ describe('LeagueService', () => {
|
||||
);
|
||||
|
||||
await withUserId('user-1', async () => {
|
||||
await expect(service.getLeagueAdminPermissions({ leagueId: 'l1' } as any)).resolves.toEqual({ canManage: true });
|
||||
await expect(service.getLeagueAdminPermissions({ leagueId: 'l1' } as never)).resolves.toEqual({ canManage: true });
|
||||
});
|
||||
|
||||
await withUserId('user-1', async () => {
|
||||
await expect(service.removeLeagueMember({ leagueId: 'l1', targetDriverId: 'd1' } as any)).resolves.toEqual({
|
||||
await expect(service.removeLeagueMember({ leagueId: 'l1', targetDriverId: 'd1' } as never)).resolves.toEqual({
|
||||
success: true,
|
||||
});
|
||||
});
|
||||
@@ -232,7 +232,7 @@ describe('LeagueService', () => {
|
||||
});
|
||||
|
||||
await withUserId('user-1', async () => {
|
||||
await expect(service.updateLeagueMemberRole('l1', 'd1', { newRole: 'member' } as any)).resolves.toEqual({
|
||||
await expect(service.updateLeagueMemberRole('l1', 'd1', { newRole: 'member' } as never)).resolves.toEqual({
|
||||
success: true,
|
||||
});
|
||||
});
|
||||
@@ -248,11 +248,11 @@ describe('LeagueService', () => {
|
||||
newRole: 'member',
|
||||
});
|
||||
|
||||
await expect(service.getLeagueOwnerSummary({ leagueId: 'l1' } as any)).resolves.toEqual({ ownerId: 'o1' });
|
||||
await expect(service.getLeagueProtests({ leagueId: 'l1' } as any)).resolves.toEqual({ protests: [] });
|
||||
await expect(service.getLeagueSeasons({ leagueId: 'l1' } as any)).resolves.toEqual([]);
|
||||
await expect(service.getLeagueOwnerSummary({ leagueId: 'l1' } as never)).resolves.toEqual({ ownerId: 'o1' });
|
||||
await expect(service.getLeagueProtests({ leagueId: 'l1' } as never)).resolves.toEqual({ protests: [] });
|
||||
await expect(service.getLeagueSeasons({ leagueId: 'l1' } as never)).resolves.toEqual([]);
|
||||
|
||||
await expect(service.getLeagueFullConfig({ leagueId: 'l1' } as any)).resolves.toEqual({ form: {} });
|
||||
await expect(service.getLeagueFullConfig({ leagueId: 'l1' } as never)).resolves.toEqual({ form: {} });
|
||||
await expect(service.getLeagueScoringConfig('l1')).resolves.toEqual({ config: {} });
|
||||
|
||||
await expect(service.getLeagueMemberships('l1')).resolves.toEqual({ memberships: [] });
|
||||
@@ -272,7 +272,7 @@ describe('LeagueService', () => {
|
||||
|
||||
// Roster admin read endpoints must be admin-gated (auth boundary) and must not execute core use cases on 403.
|
||||
getLeagueAdminPermissionsUseCase.execute.mockResolvedValueOnce(
|
||||
Result.err({ code: 'FORBIDDEN', details: { message: 'nope' } }) as any,
|
||||
Result.err({ code: 'FORBIDDEN', details: { message: 'nope' } }) as never,
|
||||
);
|
||||
getLeagueRosterMembersUseCase.execute.mockClear();
|
||||
await withUserId('user-2', async () => {
|
||||
@@ -285,7 +285,7 @@ describe('LeagueService', () => {
|
||||
expect(getLeagueScheduleUseCase.execute).toHaveBeenCalledWith({ leagueId: 'l1' });
|
||||
|
||||
getLeagueScheduleUseCase.execute.mockClear();
|
||||
await expect(service.getLeagueSchedule('l1', { seasonId: 'season-x' } as any)).resolves.toEqual({
|
||||
await expect(service.getLeagueSchedule('l1', { seasonId: 'season-x' } as never)).resolves.toEqual({
|
||||
seasonId: 'season-1',
|
||||
published: false,
|
||||
races: [],
|
||||
@@ -293,7 +293,7 @@ describe('LeagueService', () => {
|
||||
expect(getLeagueScheduleUseCase.execute).toHaveBeenCalledWith({ leagueId: 'l1', seasonId: 'season-x' });
|
||||
await expect(service.getLeagueStats('l1')).resolves.toEqual({ stats: {} });
|
||||
|
||||
await expect(service.createLeague({ name: 'n', description: 'd', ownerId: 'o' } as any)).resolves.toEqual({ id: 'l1' });
|
||||
await expect(service.createLeague({ name: 'n', description: 'd', ownerId: 'o' } as never)).resolves.toEqual({ id: 'l1' });
|
||||
await expect(service.listLeagueScoringPresets()).resolves.toEqual({ presets: [] });
|
||||
|
||||
await withUserId('user-1', async () => {
|
||||
@@ -301,7 +301,7 @@ describe('LeagueService', () => {
|
||||
});
|
||||
|
||||
await withUserId('user-1', async () => {
|
||||
await expect(service.transferLeagueOwnership('l1', { newOwnerId: 'o2' } as any)).resolves.toEqual({ success: true });
|
||||
await expect(service.transferLeagueOwnership('l1', { newOwnerId: 'o2' } as never)).resolves.toEqual({ success: true });
|
||||
});
|
||||
|
||||
// Transfer ownership must be admin-gated and actor-derived (no payload owner/admin IDs)
|
||||
@@ -310,7 +310,7 @@ describe('LeagueService', () => {
|
||||
|
||||
await withUserId('user-1', async () => {
|
||||
await expect(
|
||||
service.transferLeagueOwnership('l1', { newOwnerId: 'o2', currentOwnerId: 'spoof' } as any),
|
||||
service.transferLeagueOwnership('l1', { newOwnerId: 'o2', currentOwnerId: 'spoof' } as never),
|
||||
).resolves.toEqual({ success: true });
|
||||
});
|
||||
|
||||
@@ -327,11 +327,11 @@ describe('LeagueService', () => {
|
||||
|
||||
// Unauthorized (non-admin/owner) actors are rejected
|
||||
getLeagueAdminPermissionsUseCase.execute.mockResolvedValueOnce(
|
||||
Result.err({ code: 'FORBIDDEN', details: { message: 'nope' } }) as any,
|
||||
Result.err({ code: 'FORBIDDEN', details: { message: 'nope' } }) as never,
|
||||
);
|
||||
transferLeagueOwnershipUseCase.execute.mockClear();
|
||||
await withUserId('user-2', async () => {
|
||||
await expect(service.transferLeagueOwnership('l1', { newOwnerId: 'o2' } as any)).rejects.toThrow('Forbidden');
|
||||
await expect(service.transferLeagueOwnership('l1', { newOwnerId: 'o2' } as never)).rejects.toThrow('Forbidden');
|
||||
});
|
||||
expect(transferLeagueOwnershipUseCase.execute).not.toHaveBeenCalled();
|
||||
|
||||
@@ -349,11 +349,11 @@ describe('LeagueService', () => {
|
||||
|
||||
await withUserId('user-1', async () => {
|
||||
await expect(
|
||||
service.publishLeagueSeasonSchedule('l1', 'season-1', {} as any),
|
||||
service.publishLeagueSeasonSchedule('l1', 'season-1', {} as never),
|
||||
).resolves.toEqual({ success: true, published: true });
|
||||
|
||||
await expect(
|
||||
service.unpublishLeagueSeasonSchedule('l1', 'season-1', {} as any),
|
||||
service.unpublishLeagueSeasonSchedule('l1', 'season-1', {} as never),
|
||||
).resolves.toEqual({ success: true, published: false });
|
||||
|
||||
await expect(
|
||||
@@ -361,14 +361,14 @@ describe('LeagueService', () => {
|
||||
track: 'Spa',
|
||||
car: 'GT3',
|
||||
scheduledAtIso: new Date('2025-01-10T20:00:00Z').toISOString(),
|
||||
} as any),
|
||||
} as never),
|
||||
).resolves.toEqual({ raceId: 'race-1' });
|
||||
|
||||
await expect(
|
||||
service.updateLeagueSeasonScheduleRace('l1', 'season-1', 'race-1', {
|
||||
track: 'Monza',
|
||||
car: 'LMP2',
|
||||
} as any),
|
||||
} as never),
|
||||
).resolves.toEqual({ success: true });
|
||||
|
||||
await expect(
|
||||
@@ -403,7 +403,7 @@ describe('LeagueService', () => {
|
||||
|
||||
await withUserId('user-1', async () => {
|
||||
await expect(
|
||||
service.withdrawFromLeagueWallet('l1', { amount: 1, currency: 'USD', destinationAccount: 'x' } as any),
|
||||
service.withdrawFromLeagueWallet('l1', { amount: 1, currency: 'USD', destinationAccount: 'x' } as never),
|
||||
).resolves.toEqual({
|
||||
success: true,
|
||||
});
|
||||
@@ -421,14 +421,14 @@ describe('LeagueService', () => {
|
||||
await expect(service.getAllLeaguesWithCapacityAndScoring()).resolves.toEqual({ leagues: [], totalCount: 0 });
|
||||
|
||||
// Error branch: getAllLeaguesWithCapacity throws on result.isErr()
|
||||
getAllLeaguesWithCapacityUseCase.execute.mockResolvedValueOnce(Result.err({ code: 'REPOSITORY_ERROR', details: { message: 'boom' } }));
|
||||
getAllLeaguesWithCapacityUseCase.execute.mockResolvedValueOnce(Result.err({ code: 'REPOSITORY_ERROR', details: { message: 'boom' } } as never));
|
||||
await expect(service.getAllLeaguesWithCapacity()).rejects.toThrow('REPOSITORY_ERROR');
|
||||
|
||||
// Error branches: try/catch returning null
|
||||
getLeagueFullConfigUseCase.execute.mockImplementationOnce(async () => {
|
||||
throw new Error('boom');
|
||||
});
|
||||
await expect(service.getLeagueFullConfig({ leagueId: 'l1' } as any)).resolves.toBeNull();
|
||||
await expect(service.getLeagueFullConfig({ leagueId: 'l1' } as never)).resolves.toBeNull();
|
||||
|
||||
getLeagueScoringConfigUseCase.execute.mockImplementationOnce(async () => {
|
||||
throw new Error('boom');
|
||||
@@ -439,7 +439,7 @@ describe('LeagueService', () => {
|
||||
getLeagueFullConfigUseCase.execute.mockImplementationOnce(async () => {
|
||||
throw 'boom';
|
||||
});
|
||||
await expect(service.getLeagueFullConfig({ leagueId: 'l1' } as any)).resolves.toBeNull();
|
||||
await expect(service.getLeagueFullConfig({ leagueId: 'l1' } as never)).resolves.toBeNull();
|
||||
|
||||
getLeagueScoringConfigUseCase.execute.mockImplementationOnce(async () => {
|
||||
throw 'boom';
|
||||
@@ -447,7 +447,7 @@ describe('LeagueService', () => {
|
||||
await expect(service.getLeagueScoringConfig('l1')).resolves.toBeNull();
|
||||
|
||||
// getLeagueAdmin error branch: fullConfigResult is Err
|
||||
getLeagueFullConfigUseCase.execute.mockResolvedValueOnce(Result.err({ code: 'REPOSITORY_ERROR', details: { message: 'boom' } }));
|
||||
getLeagueFullConfigUseCase.execute.mockResolvedValueOnce(Result.err({ code: 'REPOSITORY_ERROR', details: { message: 'boom' } } as never));
|
||||
await withUserId('user-1', async () => {
|
||||
await expect(service.getLeagueAdmin('l1')).rejects.toThrow('REPOSITORY_ERROR');
|
||||
});
|
||||
@@ -467,4 +467,4 @@ describe('LeagueService', () => {
|
||||
// keep lint happy (ensures err() used)
|
||||
await err();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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',
|
||||
});
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 } : {}),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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$/);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user