Files
gridpilot.gg/core/leaderboards/application/use-cases/GetTeamRankingsUseCase.test.ts
2026-01-24 12:18:31 +01:00

83 lines
3.1 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from 'vitest';
import { GetTeamRankingsUseCase, GetTeamRankingsUseCasePorts } from './GetTeamRankingsUseCase';
import { ValidationError } from '../../../shared/errors/ValidationError';
describe('GetTeamRankingsUseCase', () => {
let mockLeaderboardsRepository: any;
let mockEventPublisher: any;
let ports: GetTeamRankingsUseCasePorts;
let useCase: GetTeamRankingsUseCase;
const mockTeams = [
{ id: 't1', name: 'Team A', rating: 2500, memberCount: 0, raceCount: 20 },
{ id: 't2', name: 'Team B', rating: 2200, memberCount: 0, raceCount: 15 },
];
const mockDrivers = [
{ id: 'd1', name: 'Alice', rating: 2000, raceCount: 10, teamId: 't1', teamName: 'Team A' },
{ id: 'd2', name: 'Bob', rating: 1500, raceCount: 5, teamId: 't1', teamName: 'Team A' },
{ id: 'd3', name: 'Charlie', rating: 1800, raceCount: 8, teamId: 't2', teamName: 'Team B' },
{ id: 'd4', name: 'David', rating: 1600, raceCount: 2, teamId: 't3', teamName: 'Discovered Team' },
];
beforeEach(() => {
mockLeaderboardsRepository = {
findAllTeams: vi.fn().mockResolvedValue([...mockTeams]),
findAllDrivers: vi.fn().mockResolvedValue([...mockDrivers]),
};
mockEventPublisher = {
publishTeamRankingsAccessed: vi.fn().mockResolvedValue(undefined),
publishLeaderboardsError: vi.fn().mockResolvedValue(undefined),
};
ports = {
leaderboardsRepository: mockLeaderboardsRepository,
eventPublisher: mockEventPublisher,
};
useCase = new GetTeamRankingsUseCase(ports);
});
it('should return teams with aggregated member counts', async () => {
const result = await useCase.execute();
expect(result.teams).toHaveLength(3); // Team A, Team B, and discovered Team t3
const teamA = result.teams.find(t => t.id === 't1');
expect(teamA?.memberCount).toBe(2);
const teamB = result.teams.find(t => t.id === 't2');
expect(teamB?.memberCount).toBe(1);
const teamDiscovered = result.teams.find(t => t.id === 't3');
expect(teamDiscovered?.memberCount).toBe(1);
expect(teamDiscovered?.name).toBe('Discovered Team');
expect(mockEventPublisher.publishTeamRankingsAccessed).toHaveBeenCalled();
});
it('should filter teams by search term', async () => {
const result = await useCase.execute({ search: 'team a' });
expect(result.teams).toHaveLength(1);
expect(result.teams[0].name).toBe('Team A');
});
it('should filter teams by minMemberCount', async () => {
const result = await useCase.execute({ minMemberCount: 2 });
expect(result.teams).toHaveLength(1);
expect(result.teams[0].id).toBe('t1');
});
it('should sort teams by rating DESC by default', async () => {
const result = await useCase.execute();
expect(result.teams[0].id).toBe('t1'); // 2500
expect(result.teams[1].id).toBe('t2'); // 2200
expect(result.teams[2].id).toBe('t3'); // 0
});
it('should throw ValidationError for invalid minMemberCount', async () => {
await expect(useCase.execute({ minMemberCount: -1 })).rejects.toThrow(ValidationError);
});
});