view data tests
This commit is contained in:
@@ -0,0 +1,600 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { LeaderboardsViewDataBuilder } from './LeaderboardsViewDataBuilder';
|
||||
|
||||
describe('LeaderboardsViewDataBuilder', () => {
|
||||
describe('happy paths', () => {
|
||||
it('should transform Leaderboards DTO to LeaderboardsViewData correctly', () => {
|
||||
const leaderboardsDTO = {
|
||||
drivers: {
|
||||
drivers: [
|
||||
{
|
||||
id: 'driver-1',
|
||||
name: 'John Doe',
|
||||
rating: 1234.56,
|
||||
skillLevel: 'pro',
|
||||
nationality: 'USA',
|
||||
racesCompleted: 150,
|
||||
wins: 25,
|
||||
podiums: 60,
|
||||
isActive: true,
|
||||
rank: 1,
|
||||
avatarUrl: 'https://example.com/avatar1.jpg',
|
||||
},
|
||||
{
|
||||
id: 'driver-2',
|
||||
name: 'Jane Smith',
|
||||
rating: 1100.0,
|
||||
skillLevel: 'advanced',
|
||||
nationality: 'Canada',
|
||||
racesCompleted: 100,
|
||||
wins: 15,
|
||||
podiums: 40,
|
||||
isActive: true,
|
||||
rank: 2,
|
||||
avatarUrl: 'https://example.com/avatar2.jpg',
|
||||
},
|
||||
],
|
||||
totalRaces: 250,
|
||||
totalWins: 40,
|
||||
activeCount: 2,
|
||||
},
|
||||
teams: {
|
||||
teams: [
|
||||
{
|
||||
id: 'team-1',
|
||||
name: 'Racing Team Alpha',
|
||||
tag: 'RTA',
|
||||
logoUrl: 'https://example.com/logo1.jpg',
|
||||
memberCount: 15,
|
||||
rating: 1500,
|
||||
totalWins: 50,
|
||||
totalRaces: 200,
|
||||
performanceLevel: 'elite',
|
||||
isRecruiting: false,
|
||||
createdAt: '2023-01-01',
|
||||
},
|
||||
{
|
||||
id: 'team-2',
|
||||
name: 'Speed Demons',
|
||||
tag: 'SD',
|
||||
logoUrl: 'https://example.com/logo2.jpg',
|
||||
memberCount: 8,
|
||||
rating: 1200,
|
||||
totalWins: 20,
|
||||
totalRaces: 150,
|
||||
performanceLevel: 'advanced',
|
||||
isRecruiting: true,
|
||||
createdAt: '2023-06-01',
|
||||
},
|
||||
],
|
||||
recruitingCount: 5,
|
||||
groupsBySkillLevel: 'pro,advanced,intermediate',
|
||||
topTeams: [
|
||||
{
|
||||
id: 'team-1',
|
||||
name: 'Racing Team Alpha',
|
||||
tag: 'RTA',
|
||||
logoUrl: 'https://example.com/logo1.jpg',
|
||||
memberCount: 15,
|
||||
rating: 1500,
|
||||
totalWins: 50,
|
||||
totalRaces: 200,
|
||||
performanceLevel: 'elite',
|
||||
isRecruiting: false,
|
||||
createdAt: '2023-01-01',
|
||||
},
|
||||
{
|
||||
id: 'team-2',
|
||||
name: 'Speed Demons',
|
||||
tag: 'SD',
|
||||
logoUrl: 'https://example.com/logo2.jpg',
|
||||
memberCount: 8,
|
||||
rating: 1200,
|
||||
totalWins: 20,
|
||||
totalRaces: 150,
|
||||
performanceLevel: 'advanced',
|
||||
isRecruiting: true,
|
||||
createdAt: '2023-06-01',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const result = LeaderboardsViewDataBuilder.build(leaderboardsDTO);
|
||||
|
||||
// Verify drivers
|
||||
expect(result.drivers).toHaveLength(2);
|
||||
expect(result.drivers[0].id).toBe('driver-1');
|
||||
expect(result.drivers[0].name).toBe('John Doe');
|
||||
expect(result.drivers[0].rating).toBe(1234.56);
|
||||
expect(result.drivers[0].skillLevel).toBe('pro');
|
||||
expect(result.drivers[0].nationality).toBe('USA');
|
||||
expect(result.drivers[0].wins).toBe(25);
|
||||
expect(result.drivers[0].podiums).toBe(60);
|
||||
expect(result.drivers[0].racesCompleted).toBe(150);
|
||||
expect(result.drivers[0].rank).toBe(1);
|
||||
expect(result.drivers[0].avatarUrl).toBe('https://example.com/avatar1.jpg');
|
||||
expect(result.drivers[0].position).toBe(1);
|
||||
|
||||
// Verify teams
|
||||
expect(result.teams).toHaveLength(2);
|
||||
expect(result.teams[0].id).toBe('team-1');
|
||||
expect(result.teams[0].name).toBe('Racing Team Alpha');
|
||||
expect(result.teams[0].tag).toBe('RTA');
|
||||
expect(result.teams[0].memberCount).toBe(15);
|
||||
expect(result.teams[0].totalWins).toBe(50);
|
||||
expect(result.teams[0].totalRaces).toBe(200);
|
||||
expect(result.teams[0].logoUrl).toBe('https://example.com/logo1.jpg');
|
||||
expect(result.teams[0].position).toBe(1);
|
||||
expect(result.teams[0].isRecruiting).toBe(false);
|
||||
expect(result.teams[0].performanceLevel).toBe('elite');
|
||||
expect(result.teams[0].rating).toBe(1500);
|
||||
expect(result.teams[0].category).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should handle empty driver and team arrays', () => {
|
||||
const leaderboardsDTO = {
|
||||
drivers: {
|
||||
drivers: [],
|
||||
totalRaces: 0,
|
||||
totalWins: 0,
|
||||
activeCount: 0,
|
||||
},
|
||||
teams: {
|
||||
teams: [],
|
||||
recruitingCount: 0,
|
||||
groupsBySkillLevel: '',
|
||||
topTeams: [],
|
||||
},
|
||||
};
|
||||
|
||||
const result = LeaderboardsViewDataBuilder.build(leaderboardsDTO);
|
||||
|
||||
expect(result.drivers).toEqual([]);
|
||||
expect(result.teams).toEqual([]);
|
||||
});
|
||||
|
||||
it('should handle missing avatar URLs with empty string fallback', () => {
|
||||
const leaderboardsDTO = {
|
||||
drivers: {
|
||||
drivers: [
|
||||
{
|
||||
id: 'driver-1',
|
||||
name: 'John Doe',
|
||||
rating: 1234.56,
|
||||
skillLevel: 'pro',
|
||||
nationality: 'USA',
|
||||
racesCompleted: 150,
|
||||
wins: 25,
|
||||
podiums: 60,
|
||||
isActive: true,
|
||||
rank: 1,
|
||||
},
|
||||
],
|
||||
totalRaces: 150,
|
||||
totalWins: 25,
|
||||
activeCount: 1,
|
||||
},
|
||||
teams: {
|
||||
teams: [],
|
||||
recruitingCount: 0,
|
||||
groupsBySkillLevel: '',
|
||||
topTeams: [
|
||||
{
|
||||
id: 'team-1',
|
||||
name: 'Racing Team Alpha',
|
||||
tag: 'RTA',
|
||||
memberCount: 15,
|
||||
totalWins: 50,
|
||||
totalRaces: 200,
|
||||
performanceLevel: 'elite',
|
||||
isRecruiting: false,
|
||||
createdAt: '2023-01-01',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const result = LeaderboardsViewDataBuilder.build(leaderboardsDTO);
|
||||
|
||||
expect(result.drivers[0].avatarUrl).toBe('');
|
||||
expect(result.teams[0].logoUrl).toBe('');
|
||||
});
|
||||
|
||||
it('should handle missing optional team fields with defaults', () => {
|
||||
const leaderboardsDTO = {
|
||||
drivers: {
|
||||
drivers: [],
|
||||
totalRaces: 0,
|
||||
totalWins: 0,
|
||||
activeCount: 0,
|
||||
},
|
||||
teams: {
|
||||
teams: [],
|
||||
recruitingCount: 0,
|
||||
groupsBySkillLevel: '',
|
||||
topTeams: [
|
||||
{
|
||||
id: 'team-1',
|
||||
name: 'Racing Team Alpha',
|
||||
tag: 'RTA',
|
||||
memberCount: 15,
|
||||
totalWins: 50,
|
||||
totalRaces: 200,
|
||||
performanceLevel: 'elite',
|
||||
isRecruiting: false,
|
||||
createdAt: '2023-01-01',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const result = LeaderboardsViewDataBuilder.build(leaderboardsDTO);
|
||||
|
||||
expect(result.teams[0].rating).toBe(0);
|
||||
expect(result.teams[0].logoUrl).toBe('');
|
||||
});
|
||||
|
||||
it('should calculate position based on index', () => {
|
||||
const leaderboardsDTO = {
|
||||
drivers: {
|
||||
drivers: [
|
||||
{ id: 'driver-1', name: 'Driver 1', rating: 1000, skillLevel: 'pro', nationality: 'USA', racesCompleted: 100, wins: 10, podiums: 30, isActive: true, rank: 1 },
|
||||
{ id: 'driver-2', name: 'Driver 2', rating: 900, skillLevel: 'advanced', nationality: 'Canada', racesCompleted: 80, wins: 8, podiums: 25, isActive: true, rank: 2 },
|
||||
{ id: 'driver-3', name: 'Driver 3', rating: 800, skillLevel: 'intermediate', nationality: 'UK', racesCompleted: 60, wins: 5, podiums: 15, isActive: true, rank: 3 },
|
||||
],
|
||||
totalRaces: 240,
|
||||
totalWins: 23,
|
||||
activeCount: 3,
|
||||
},
|
||||
teams: {
|
||||
teams: [],
|
||||
recruitingCount: 1,
|
||||
groupsBySkillLevel: 'elite,advanced,intermediate',
|
||||
topTeams: [
|
||||
{ id: 'team-1', name: 'Team 1', tag: 'T1', memberCount: 10, totalWins: 30, totalRaces: 150, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01' },
|
||||
{ id: 'team-2', name: 'Team 2', tag: 'T2', memberCount: 8, totalWins: 20, totalRaces: 120, performanceLevel: 'advanced', isRecruiting: true, createdAt: '2023-02-01' },
|
||||
{ id: 'team-3', name: 'Team 3', tag: 'T3', memberCount: 6, totalWins: 10, totalRaces: 80, performanceLevel: 'intermediate', isRecruiting: false, createdAt: '2023-03-01' },
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const result = LeaderboardsViewDataBuilder.build(leaderboardsDTO);
|
||||
|
||||
expect(result.drivers[0].position).toBe(1);
|
||||
expect(result.drivers[1].position).toBe(2);
|
||||
expect(result.drivers[2].position).toBe(3);
|
||||
|
||||
expect(result.teams[0].position).toBe(1);
|
||||
expect(result.teams[1].position).toBe(2);
|
||||
expect(result.teams[2].position).toBe(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe('data transformation', () => {
|
||||
it('should preserve all DTO fields in the output', () => {
|
||||
const leaderboardsDTO = {
|
||||
drivers: {
|
||||
drivers: [
|
||||
{
|
||||
id: 'driver-123',
|
||||
name: 'John Doe',
|
||||
rating: 1234.56,
|
||||
skillLevel: 'pro',
|
||||
nationality: 'USA',
|
||||
racesCompleted: 150,
|
||||
wins: 25,
|
||||
podiums: 60,
|
||||
isActive: true,
|
||||
rank: 1,
|
||||
avatarUrl: 'https://example.com/avatar.jpg',
|
||||
},
|
||||
],
|
||||
totalRaces: 150,
|
||||
totalWins: 25,
|
||||
activeCount: 1,
|
||||
},
|
||||
teams: {
|
||||
teams: [],
|
||||
recruitingCount: 5,
|
||||
groupsBySkillLevel: 'pro,advanced',
|
||||
topTeams: [
|
||||
{
|
||||
id: 'team-123',
|
||||
name: 'Racing Team Alpha',
|
||||
tag: 'RTA',
|
||||
logoUrl: 'https://example.com/logo.jpg',
|
||||
memberCount: 15,
|
||||
rating: 1500,
|
||||
totalWins: 50,
|
||||
totalRaces: 200,
|
||||
performanceLevel: 'elite',
|
||||
isRecruiting: false,
|
||||
createdAt: '2023-01-01',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const result = LeaderboardsViewDataBuilder.build(leaderboardsDTO);
|
||||
|
||||
expect(result.drivers[0].name).toBe(leaderboardsDTO.drivers.drivers[0].name);
|
||||
expect(result.drivers[0].nationality).toBe(leaderboardsDTO.drivers.drivers[0].nationality);
|
||||
expect(result.drivers[0].avatarUrl).toBe(leaderboardsDTO.drivers.drivers[0].avatarUrl);
|
||||
expect(result.teams[0].name).toBe(leaderboardsDTO.teams.topTeams[0].name);
|
||||
expect(result.teams[0].tag).toBe(leaderboardsDTO.teams.topTeams[0].tag);
|
||||
expect(result.teams[0].logoUrl).toBe(leaderboardsDTO.teams.topTeams[0].logoUrl);
|
||||
});
|
||||
|
||||
it('should not modify the input DTO', () => {
|
||||
const leaderboardsDTO = {
|
||||
drivers: {
|
||||
drivers: [
|
||||
{
|
||||
id: 'driver-123',
|
||||
name: 'John Doe',
|
||||
rating: 1234.56,
|
||||
skillLevel: 'pro',
|
||||
nationality: 'USA',
|
||||
racesCompleted: 150,
|
||||
wins: 25,
|
||||
podiums: 60,
|
||||
isActive: true,
|
||||
rank: 1,
|
||||
avatarUrl: 'https://example.com/avatar.jpg',
|
||||
},
|
||||
],
|
||||
totalRaces: 150,
|
||||
totalWins: 25,
|
||||
activeCount: 1,
|
||||
},
|
||||
teams: {
|
||||
teams: [],
|
||||
recruitingCount: 5,
|
||||
groupsBySkillLevel: 'pro,advanced',
|
||||
topTeams: [
|
||||
{
|
||||
id: 'team-123',
|
||||
name: 'Racing Team Alpha',
|
||||
tag: 'RTA',
|
||||
logoUrl: 'https://example.com/logo.jpg',
|
||||
memberCount: 15,
|
||||
rating: 1500,
|
||||
totalWins: 50,
|
||||
totalRaces: 200,
|
||||
performanceLevel: 'elite',
|
||||
isRecruiting: false,
|
||||
createdAt: '2023-01-01',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const originalDTO = JSON.parse(JSON.stringify(leaderboardsDTO));
|
||||
LeaderboardsViewDataBuilder.build(leaderboardsDTO);
|
||||
|
||||
expect(leaderboardsDTO).toEqual(originalDTO);
|
||||
});
|
||||
|
||||
it('should handle large numbers correctly', () => {
|
||||
const leaderboardsDTO = {
|
||||
drivers: {
|
||||
drivers: [
|
||||
{
|
||||
id: 'driver-1',
|
||||
name: 'John Doe',
|
||||
rating: 999999.99,
|
||||
skillLevel: 'pro',
|
||||
nationality: 'USA',
|
||||
racesCompleted: 10000,
|
||||
wins: 2500,
|
||||
podiums: 5000,
|
||||
isActive: true,
|
||||
rank: 1,
|
||||
avatarUrl: 'https://example.com/avatar.jpg',
|
||||
},
|
||||
],
|
||||
totalRaces: 10000,
|
||||
totalWins: 2500,
|
||||
activeCount: 1,
|
||||
},
|
||||
teams: {
|
||||
teams: [],
|
||||
recruitingCount: 0,
|
||||
groupsBySkillLevel: '',
|
||||
topTeams: [
|
||||
{
|
||||
id: 'team-1',
|
||||
name: 'Racing Team Alpha',
|
||||
tag: 'RTA',
|
||||
logoUrl: 'https://example.com/logo.jpg',
|
||||
memberCount: 100,
|
||||
rating: 999999,
|
||||
totalWins: 5000,
|
||||
totalRaces: 10000,
|
||||
performanceLevel: 'elite',
|
||||
isRecruiting: false,
|
||||
createdAt: '2023-01-01',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const result = LeaderboardsViewDataBuilder.build(leaderboardsDTO);
|
||||
|
||||
expect(result.drivers[0].rating).toBe(999999.99);
|
||||
expect(result.drivers[0].wins).toBe(2500);
|
||||
expect(result.drivers[0].podiums).toBe(5000);
|
||||
expect(result.drivers[0].racesCompleted).toBe(10000);
|
||||
expect(result.teams[0].rating).toBe(999999);
|
||||
expect(result.teams[0].totalWins).toBe(5000);
|
||||
expect(result.teams[0].totalRaces).toBe(10000);
|
||||
});
|
||||
});
|
||||
|
||||
describe('edge cases', () => {
|
||||
it('should handle null/undefined avatar URLs', () => {
|
||||
const leaderboardsDTO = {
|
||||
drivers: {
|
||||
drivers: [
|
||||
{
|
||||
id: 'driver-1',
|
||||
name: 'John Doe',
|
||||
rating: 1234.56,
|
||||
skillLevel: 'pro',
|
||||
nationality: 'USA',
|
||||
racesCompleted: 150,
|
||||
wins: 25,
|
||||
podiums: 60,
|
||||
isActive: true,
|
||||
rank: 1,
|
||||
avatarUrl: null as any,
|
||||
},
|
||||
],
|
||||
totalRaces: 150,
|
||||
totalWins: 25,
|
||||
activeCount: 1,
|
||||
},
|
||||
teams: {
|
||||
teams: [],
|
||||
recruitingCount: 0,
|
||||
groupsBySkillLevel: '',
|
||||
topTeams: [
|
||||
{
|
||||
id: 'team-1',
|
||||
name: 'Racing Team Alpha',
|
||||
tag: 'RTA',
|
||||
logoUrl: undefined as any,
|
||||
memberCount: 15,
|
||||
totalWins: 50,
|
||||
totalRaces: 200,
|
||||
performanceLevel: 'elite',
|
||||
isRecruiting: false,
|
||||
createdAt: '2023-01-01',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const result = LeaderboardsViewDataBuilder.build(leaderboardsDTO);
|
||||
|
||||
expect(result.drivers[0].avatarUrl).toBe('');
|
||||
expect(result.teams[0].logoUrl).toBe('');
|
||||
});
|
||||
|
||||
it('should handle null/undefined rating', () => {
|
||||
const leaderboardsDTO = {
|
||||
drivers: {
|
||||
drivers: [
|
||||
{
|
||||
id: 'driver-1',
|
||||
name: 'John Doe',
|
||||
rating: null as any,
|
||||
skillLevel: 'pro',
|
||||
nationality: 'USA',
|
||||
racesCompleted: 150,
|
||||
wins: 25,
|
||||
podiums: 60,
|
||||
isActive: true,
|
||||
rank: 1,
|
||||
},
|
||||
],
|
||||
totalRaces: 150,
|
||||
totalWins: 25,
|
||||
activeCount: 1,
|
||||
},
|
||||
teams: {
|
||||
teams: [],
|
||||
recruitingCount: 0,
|
||||
groupsBySkillLevel: '',
|
||||
topTeams: [
|
||||
{
|
||||
id: 'team-1',
|
||||
name: 'Racing Team Alpha',
|
||||
tag: 'RTA',
|
||||
memberCount: 15,
|
||||
rating: null as any,
|
||||
totalWins: 50,
|
||||
totalRaces: 200,
|
||||
performanceLevel: 'elite',
|
||||
isRecruiting: false,
|
||||
createdAt: '2023-01-01',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const result = LeaderboardsViewDataBuilder.build(leaderboardsDTO);
|
||||
|
||||
expect(result.drivers[0].rating).toBeNull();
|
||||
expect(result.teams[0].rating).toBe(0);
|
||||
});
|
||||
|
||||
it('should handle null/undefined totalWins and totalRaces', () => {
|
||||
const leaderboardsDTO = {
|
||||
drivers: {
|
||||
drivers: [],
|
||||
totalRaces: 0,
|
||||
totalWins: 0,
|
||||
activeCount: 0,
|
||||
},
|
||||
teams: {
|
||||
teams: [],
|
||||
recruitingCount: 0,
|
||||
groupsBySkillLevel: '',
|
||||
topTeams: [
|
||||
{
|
||||
id: 'team-1',
|
||||
name: 'Racing Team Alpha',
|
||||
tag: 'RTA',
|
||||
memberCount: 15,
|
||||
totalWins: null as any,
|
||||
totalRaces: null as any,
|
||||
performanceLevel: 'elite',
|
||||
isRecruiting: false,
|
||||
createdAt: '2023-01-01',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const result = LeaderboardsViewDataBuilder.build(leaderboardsDTO);
|
||||
|
||||
expect(result.teams[0].totalWins).toBe(0);
|
||||
expect(result.teams[0].totalRaces).toBe(0);
|
||||
});
|
||||
|
||||
it('should handle empty performance level', () => {
|
||||
const leaderboardsDTO = {
|
||||
drivers: {
|
||||
drivers: [],
|
||||
totalRaces: 0,
|
||||
totalWins: 0,
|
||||
activeCount: 0,
|
||||
},
|
||||
teams: {
|
||||
teams: [],
|
||||
recruitingCount: 0,
|
||||
groupsBySkillLevel: '',
|
||||
topTeams: [
|
||||
{
|
||||
id: 'team-1',
|
||||
name: 'Racing Team Alpha',
|
||||
tag: 'RTA',
|
||||
memberCount: 15,
|
||||
totalWins: 50,
|
||||
totalRaces: 200,
|
||||
performanceLevel: '',
|
||||
isRecruiting: false,
|
||||
createdAt: '2023-01-01',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const result = LeaderboardsViewDataBuilder.build(leaderboardsDTO);
|
||||
|
||||
expect(result.teams[0].performanceLevel).toBe('N/A');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user