Files
gridpilot.gg/apps/website/lib/display-objects/DashboardViewDataConsistency.test.ts
Marc Mintel 1f4f837282
Some checks failed
Contract Testing / contract-tests (pull_request) Failing after 5m58s
Contract Testing / contract-snapshot (pull_request) Has been skipped
view data tests
2026-01-22 18:06:46 +01:00

370 lines
13 KiB
TypeScript

import { describe, it, expect } from 'vitest';
import { DashboardViewDataBuilder } from '../builders/view-data/DashboardViewDataBuilder';
import { DashboardDateDisplay } from './DashboardDateDisplay';
import { DashboardCountDisplay } from './DashboardCountDisplay';
import { DashboardRankDisplay } from './DashboardRankDisplay';
import { DashboardConsistencyDisplay } from './DashboardConsistencyDisplay';
import { DashboardLeaguePositionDisplay } from './DashboardLeaguePositionDisplay';
import { RatingDisplay } from './RatingDisplay';
import type { DashboardOverviewDTO } from '@/lib/types/generated/DashboardOverviewDTO';
describe('Dashboard View Data - Cross-Component Consistency', () => {
describe('common patterns', () => {
it('should all use consistent formatting for numeric values', () => {
const dashboardDTO: DashboardOverviewDTO = {
currentDriver: {
id: 'driver-123',
name: 'John Doe',
country: 'USA',
rating: 1234.56,
globalRank: 42,
totalRaces: 150,
wins: 25,
podiums: 60,
consistency: 85,
},
myUpcomingRaces: [],
otherUpcomingRaces: [],
upcomingRaces: [],
activeLeaguesCount: 3,
nextRace: null,
recentResults: [],
leagueStandingsSummaries: [
{
leagueId: 'league-1',
leagueName: 'Test League',
position: 5,
totalDrivers: 50,
points: 1250,
},
],
feedSummary: {
notificationCount: 0,
items: [],
},
friends: [
{ id: 'friend-1', name: 'Alice', country: 'UK' },
{ id: 'friend-2', name: 'Bob', country: 'Germany' },
],
};
const result = DashboardViewDataBuilder.build(dashboardDTO);
// All numeric values should be formatted as strings
expect(typeof result.currentDriver.rating).toBe('string');
expect(typeof result.currentDriver.rank).toBe('string');
expect(typeof result.currentDriver.totalRaces).toBe('string');
expect(typeof result.currentDriver.wins).toBe('string');
expect(typeof result.currentDriver.podiums).toBe('string');
expect(typeof result.currentDriver.consistency).toBe('string');
expect(typeof result.activeLeaguesCount).toBe('string');
expect(typeof result.friendCount).toBe('string');
expect(typeof result.leagueStandings[0].position).toBe('string');
expect(typeof result.leagueStandings[0].points).toBe('string');
expect(typeof result.leagueStandings[0].totalDrivers).toBe('string');
});
it('should all handle missing data gracefully', () => {
const dashboardDTO: DashboardOverviewDTO = {
myUpcomingRaces: [],
otherUpcomingRaces: [],
upcomingRaces: [],
activeLeaguesCount: 0,
nextRace: null,
recentResults: [],
leagueStandingsSummaries: [],
feedSummary: {
notificationCount: 0,
items: [],
},
friends: [],
};
const result = DashboardViewDataBuilder.build(dashboardDTO);
// All fields should have safe defaults
expect(result.currentDriver.name).toBe('');
expect(result.currentDriver.avatarUrl).toBe('');
expect(result.currentDriver.country).toBe('');
expect(result.currentDriver.rating).toBe('0.0');
expect(result.currentDriver.rank).toBe('0');
expect(result.currentDriver.totalRaces).toBe('0');
expect(result.currentDriver.wins).toBe('0');
expect(result.currentDriver.podiums).toBe('0');
expect(result.currentDriver.consistency).toBe('0%');
expect(result.nextRace).toBeNull();
expect(result.upcomingRaces).toEqual([]);
expect(result.leagueStandings).toEqual([]);
expect(result.feedItems).toEqual([]);
expect(result.friends).toEqual([]);
expect(result.activeLeaguesCount).toBe('0');
expect(result.friendCount).toBe('0');
});
it('should all preserve ISO timestamps for serialization', () => {
const now = new Date();
const futureDate = new Date(now.getTime() + 24 * 60 * 60 * 1000);
const feedTimestamp = new Date(now.getTime() - 30 * 60 * 1000);
const dashboardDTO: DashboardOverviewDTO = {
myUpcomingRaces: [],
otherUpcomingRaces: [],
upcomingRaces: [],
activeLeaguesCount: 1,
nextRace: {
id: 'race-1',
track: 'Spa',
car: 'Porsche',
scheduledAt: futureDate.toISOString(),
status: 'scheduled',
isMyLeague: true,
},
recentResults: [],
leagueStandingsSummaries: [],
feedSummary: {
notificationCount: 1,
items: [
{
id: 'feed-1',
type: 'notification',
headline: 'Test',
timestamp: feedTimestamp.toISOString(),
},
],
},
friends: [],
};
const result = DashboardViewDataBuilder.build(dashboardDTO);
// All timestamps should be preserved as ISO strings
expect(result.nextRace?.scheduledAt).toBe(futureDate.toISOString());
expect(result.feedItems[0].timestamp).toBe(feedTimestamp.toISOString());
});
it('should all handle boolean flags correctly', () => {
const dashboardDTO: DashboardOverviewDTO = {
myUpcomingRaces: [],
otherUpcomingRaces: [],
upcomingRaces: [
{
id: 'race-1',
track: 'Spa',
car: 'Porsche',
scheduledAt: new Date().toISOString(),
status: 'scheduled',
isMyLeague: true,
},
{
id: 'race-2',
track: 'Monza',
car: 'Ferrari',
scheduledAt: new Date().toISOString(),
status: 'scheduled',
isMyLeague: false,
},
],
activeLeaguesCount: 1,
nextRace: null,
recentResults: [],
leagueStandingsSummaries: [],
feedSummary: {
notificationCount: 0,
items: [],
},
friends: [],
};
const result = DashboardViewDataBuilder.build(dashboardDTO);
expect(result.upcomingRaces[0].isMyLeague).toBe(true);
expect(result.upcomingRaces[1].isMyLeague).toBe(false);
});
});
describe('data integrity', () => {
it('should maintain data consistency across transformations', () => {
const dashboardDTO: DashboardOverviewDTO = {
currentDriver: {
id: 'driver-123',
name: 'John Doe',
country: 'USA',
rating: 1234.56,
globalRank: 42,
totalRaces: 150,
wins: 25,
podiums: 60,
consistency: 85,
},
myUpcomingRaces: [],
otherUpcomingRaces: [],
upcomingRaces: [],
activeLeaguesCount: 3,
nextRace: null,
recentResults: [],
leagueStandingsSummaries: [],
feedSummary: {
notificationCount: 5,
items: [],
},
friends: [
{ id: 'friend-1', name: 'Alice', country: 'UK' },
{ id: 'friend-2', name: 'Bob', country: 'Germany' },
],
};
const result = DashboardViewDataBuilder.build(dashboardDTO);
// Verify derived fields match their source data
expect(result.friendCount).toBe(dashboardDTO.friends.length.toString());
expect(result.activeLeaguesCount).toBe(dashboardDTO.activeLeaguesCount.toString());
expect(result.hasFriends).toBe(dashboardDTO.friends.length > 0);
expect(result.hasUpcomingRaces).toBe(dashboardDTO.upcomingRaces.length > 0);
expect(result.hasLeagueStandings).toBe(dashboardDTO.leagueStandingsSummaries.length > 0);
expect(result.hasFeedItems).toBe(dashboardDTO.feedSummary.items.length > 0);
});
it('should handle complex real-world scenarios', () => {
const now = new Date();
const race1Date = new Date(now.getTime() + 2 * 24 * 60 * 60 * 1000);
const race2Date = new Date(now.getTime() + 5 * 24 * 60 * 60 * 1000);
const feedTimestamp = new Date(now.getTime() - 60 * 60 * 1000);
const dashboardDTO: DashboardOverviewDTO = {
currentDriver: {
id: 'driver-123',
name: 'John Doe',
country: 'USA',
avatarUrl: 'https://example.com/avatar.jpg',
rating: 2456.78,
globalRank: 15,
totalRaces: 250,
wins: 45,
podiums: 120,
consistency: 92.5,
},
myUpcomingRaces: [],
otherUpcomingRaces: [],
upcomingRaces: [
{
id: 'race-1',
leagueId: 'league-1',
leagueName: 'Pro League',
track: 'Spa',
car: 'Porsche 911 GT3',
scheduledAt: race1Date.toISOString(),
status: 'scheduled',
isMyLeague: true,
},
{
id: 'race-2',
track: 'Monza',
car: 'Ferrari 488 GT3',
scheduledAt: race2Date.toISOString(),
status: 'scheduled',
isMyLeague: false,
},
],
activeLeaguesCount: 2,
nextRace: {
id: 'race-1',
leagueId: 'league-1',
leagueName: 'Pro League',
track: 'Spa',
car: 'Porsche 911 GT3',
scheduledAt: race1Date.toISOString(),
status: 'scheduled',
isMyLeague: true,
},
recentResults: [],
leagueStandingsSummaries: [
{
leagueId: 'league-1',
leagueName: 'Pro League',
position: 3,
totalDrivers: 100,
points: 2450,
},
{
leagueId: 'league-2',
leagueName: 'Rookie League',
position: 1,
totalDrivers: 50,
points: 1800,
},
],
feedSummary: {
notificationCount: 3,
items: [
{
id: 'feed-1',
type: 'race_result',
headline: 'Race completed',
body: 'You finished 3rd in the Pro League race',
timestamp: feedTimestamp.toISOString(),
ctaLabel: 'View Results',
ctaHref: '/races/123',
},
{
id: 'feed-2',
type: 'league_update',
headline: 'League standings updated',
body: 'You moved up 2 positions',
timestamp: feedTimestamp.toISOString(),
},
],
},
friends: [
{ id: 'friend-1', name: 'Alice', country: 'UK', avatarUrl: 'https://example.com/alice.jpg' },
{ id: 'friend-2', name: 'Bob', country: 'Germany' },
{ id: 'friend-3', name: 'Charlie', country: 'France', avatarUrl: 'https://example.com/charlie.jpg' },
],
};
const result = DashboardViewDataBuilder.build(dashboardDTO);
// Verify all transformations
expect(result.currentDriver.name).toBe('John Doe');
expect(result.currentDriver.rating).toBe('2,457');
expect(result.currentDriver.rank).toBe('15');
expect(result.currentDriver.totalRaces).toBe('250');
expect(result.currentDriver.wins).toBe('45');
expect(result.currentDriver.podiums).toBe('120');
expect(result.currentDriver.consistency).toBe('92.5%');
expect(result.nextRace).not.toBeNull();
expect(result.nextRace?.id).toBe('race-1');
expect(result.nextRace?.track).toBe('Spa');
expect(result.nextRace?.isMyLeague).toBe(true);
expect(result.upcomingRaces).toHaveLength(2);
expect(result.upcomingRaces[0].isMyLeague).toBe(true);
expect(result.upcomingRaces[1].isMyLeague).toBe(false);
expect(result.leagueStandings).toHaveLength(2);
expect(result.leagueStandings[0].position).toBe('#3');
expect(result.leagueStandings[0].points).toBe('2450');
expect(result.leagueStandings[1].position).toBe('#1');
expect(result.leagueStandings[1].points).toBe('1800');
expect(result.feedItems).toHaveLength(2);
expect(result.feedItems[0].type).toBe('race_result');
expect(result.feedItems[0].ctaLabel).toBe('View Results');
expect(result.feedItems[1].type).toBe('league_update');
expect(result.feedItems[1].ctaLabel).toBeUndefined();
expect(result.friends).toHaveLength(3);
expect(result.friends[0].avatarUrl).toBe('https://example.com/alice.jpg');
expect(result.friends[1].avatarUrl).toBe('');
expect(result.friends[2].avatarUrl).toBe('https://example.com/charlie.jpg');
expect(result.activeLeaguesCount).toBe('2');
expect(result.friendCount).toBe('3');
expect(result.hasUpcomingRaces).toBe(true);
expect(result.hasLeagueStandings).toBe(true);
expect(result.hasFeedItems).toBe(true);
expect(result.hasFriends).toBe(true);
});
});
});