tests
This commit is contained in:
@@ -0,0 +1,487 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import { AllLeaguesWithCapacityAndScoringPresenter } from './AllLeaguesWithCapacityAndScoringPresenter';
|
||||
import { League } from '@core/racing/domain/entities/League';
|
||||
import { Season } from '@core/racing/domain/entities/season/Season';
|
||||
import { LeagueScoringConfig } from '@core/racing/domain/entities/LeagueScoringConfig';
|
||||
import { Game } from '@core/racing/domain/entities/Game';
|
||||
import { MediaReference } from '@core/domain/media/MediaReference';
|
||||
import type { LeagueScoringPreset } from '@core/racing/domain/types/LeagueScoringPreset';
|
||||
import { PointsTable } from '@core/racing/domain/value-objects/PointsTable';
|
||||
|
||||
describe('AllLeaguesWithCapacityAndScoringPresenter', () => {
|
||||
let presenter: AllLeaguesWithCapacityAndScoringPresenter;
|
||||
|
||||
beforeEach(() => {
|
||||
presenter = new AllLeaguesWithCapacityAndScoringPresenter();
|
||||
});
|
||||
|
||||
describe('present', () => {
|
||||
it('should map empty leagues array to DTO', async () => {
|
||||
await presenter.present({ leagues: [] });
|
||||
|
||||
const vm = presenter.getViewModel();
|
||||
|
||||
expect(vm).toEqual({
|
||||
leagues: [],
|
||||
totalCount: 0,
|
||||
});
|
||||
});
|
||||
|
||||
it('should map leagues with basic information', async () => {
|
||||
const league = League.create({
|
||||
id: 'league-1',
|
||||
name: 'Test League',
|
||||
description: 'A test league',
|
||||
ownerId: 'owner-1',
|
||||
settings: {
|
||||
pointsSystem: 'f1-2024',
|
||||
maxDrivers: 20,
|
||||
},
|
||||
createdAt: new Date('2024-01-01T00:00:00Z'),
|
||||
});
|
||||
|
||||
await presenter.present({
|
||||
leagues: [
|
||||
{
|
||||
league,
|
||||
currentDrivers: 5,
|
||||
maxDrivers: 20,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const vm = presenter.getViewModel();
|
||||
|
||||
expect(vm.leagues).toHaveLength(1);
|
||||
expect(vm.leagues[0]!.id).toBe('league-1');
|
||||
expect(vm.leagues[0]!.name).toBe('Test League');
|
||||
expect(vm.leagues[0]!.description).toBe('A test league');
|
||||
expect(vm.leagues[0]!.ownerId).toBe('owner-1');
|
||||
expect(vm.leagues[0]!.createdAt).toBe('2024-01-01T00:00:00.000Z');
|
||||
expect(vm.leagues[0]!.settings.maxDrivers).toBe(20);
|
||||
expect(vm.leagues[0]!.usedSlots).toBe(5);
|
||||
expect(vm.totalCount).toBe(1);
|
||||
});
|
||||
|
||||
it('should map leagues with social links', async () => {
|
||||
const league = League.create({
|
||||
id: 'league-1',
|
||||
name: 'Test League',
|
||||
description: 'A test league',
|
||||
ownerId: 'owner-1',
|
||||
settings: { pointsSystem: 'f1-2024' },
|
||||
socialLinks: {
|
||||
discordUrl: 'https://discord.gg/test',
|
||||
youtubeUrl: 'https://youtube.com/test',
|
||||
websiteUrl: 'https://test.com',
|
||||
},
|
||||
});
|
||||
|
||||
await presenter.present({
|
||||
leagues: [
|
||||
{
|
||||
league,
|
||||
currentDrivers: 3,
|
||||
maxDrivers: 32,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const vm = presenter.getViewModel();
|
||||
|
||||
expect(vm.leagues[0]!.socialLinks).toEqual({
|
||||
discordUrl: 'https://discord.gg/test',
|
||||
youtubeUrl: 'https://youtube.com/test',
|
||||
websiteUrl: 'https://test.com',
|
||||
});
|
||||
});
|
||||
|
||||
it('should map leagues with category', async () => {
|
||||
const league = League.create({
|
||||
id: 'league-1',
|
||||
name: 'Test League',
|
||||
description: 'A test league',
|
||||
ownerId: 'owner-1',
|
||||
settings: { pointsSystem: 'f1-2024' },
|
||||
category: 'Formula',
|
||||
});
|
||||
|
||||
await presenter.present({
|
||||
leagues: [
|
||||
{
|
||||
league,
|
||||
currentDrivers: 2,
|
||||
maxDrivers: 32,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const vm = presenter.getViewModel();
|
||||
|
||||
expect(vm.leagues[0]!.category).toBe('Formula');
|
||||
});
|
||||
|
||||
it('should map leagues with session duration and qualifying format', async () => {
|
||||
const league = League.create({
|
||||
id: 'league-1',
|
||||
name: 'Test League',
|
||||
description: 'A test league',
|
||||
ownerId: 'owner-1',
|
||||
settings: {
|
||||
pointsSystem: 'f1-2024',
|
||||
sessionDuration: 90,
|
||||
qualifyingFormat: 'single-lap',
|
||||
},
|
||||
});
|
||||
|
||||
await presenter.present({
|
||||
leagues: [
|
||||
{
|
||||
league,
|
||||
currentDrivers: 4,
|
||||
maxDrivers: 32,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const vm = presenter.getViewModel();
|
||||
|
||||
expect(vm.leagues[0]!.settings.sessionDuration).toBe(90);
|
||||
expect(vm.leagues[0]!.settings.qualifyingFormat).toBe('single-lap');
|
||||
});
|
||||
|
||||
it('should map leagues with timing summary for hours', async () => {
|
||||
const league = League.create({
|
||||
id: 'league-1',
|
||||
name: 'Test League',
|
||||
description: 'A test league',
|
||||
ownerId: 'owner-1',
|
||||
settings: { pointsSystem: 'f1-2024' },
|
||||
});
|
||||
|
||||
const season = Season.create({
|
||||
id: 'season-1',
|
||||
leagueId: 'league-1',
|
||||
gameId: 'iracing',
|
||||
name: 'Season 1',
|
||||
status: 'active',
|
||||
schedule: {
|
||||
startDate: new Date('2024-01-01'),
|
||||
timeOfDay: { hour: 20, minute: 0 },
|
||||
} as any,
|
||||
} as any);
|
||||
|
||||
const scoringConfig = LeagueScoringConfig.create({
|
||||
id: 'scoring-1',
|
||||
seasonId: 'season-1',
|
||||
scoringPresetId: 'preset-1',
|
||||
championships: [
|
||||
{
|
||||
id: 'champ-1',
|
||||
name: 'Drivers Championship',
|
||||
type: 'driver',
|
||||
sessionTypes: ['main'],
|
||||
pointsTableBySessionType: {
|
||||
practice: new PointsTable({}),
|
||||
qualifying: new PointsTable({}),
|
||||
q1: new PointsTable({}),
|
||||
q2: new PointsTable({}),
|
||||
q3: new PointsTable({}),
|
||||
sprint: new PointsTable({}),
|
||||
main: new PointsTable({ 1: 25, 2: 18, 3: 15, 4: 12, 5: 10, 6: 8, 7: 6, 8: 4, 9: 2, 10: 1 }),
|
||||
timeTrial: new PointsTable({}),
|
||||
},
|
||||
dropScorePolicy: { strategy: 'bestNResults', count: 3 },
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const game = Game.create({
|
||||
id: 'iracing',
|
||||
name: 'iRacing',
|
||||
});
|
||||
|
||||
const preset: LeagueScoringPreset = {
|
||||
id: 'preset-1',
|
||||
name: 'Test Preset',
|
||||
description: 'Test preset description',
|
||||
primaryChampionshipType: 'driver',
|
||||
dropPolicySummary: 'Best 8 of 12',
|
||||
sessionSummary: 'Qualifying + Race',
|
||||
bonusSummary: 'Bonus points for top 3',
|
||||
defaultTimings: {
|
||||
mainRaceMinutes: 120,
|
||||
practiceMinutes: 30,
|
||||
qualifyingMinutes: 20,
|
||||
sprintRaceMinutes: 0,
|
||||
sessionCount: 1
|
||||
},
|
||||
};
|
||||
|
||||
await presenter.present({
|
||||
leagues: [
|
||||
{
|
||||
league,
|
||||
currentDrivers: 5,
|
||||
maxDrivers: 32,
|
||||
season,
|
||||
scoringConfig,
|
||||
game,
|
||||
preset,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const vm = presenter.getViewModel();
|
||||
|
||||
expect(vm.leagues[0]!.timingSummary).toBe('2h Race');
|
||||
expect(vm.leagues[0]!.scoring).toEqual({
|
||||
gameId: 'iracing',
|
||||
gameName: 'iRacing',
|
||||
primaryChampionshipType: 'driver',
|
||||
scoringPresetId: 'preset-1',
|
||||
scoringPresetName: 'Test Preset',
|
||||
dropPolicySummary: 'Best 8 of 12',
|
||||
scoringPatternSummary: 'Qualifying + Race',
|
||||
});
|
||||
});
|
||||
|
||||
it('should map leagues with timing summary for minutes', async () => {
|
||||
const league = League.create({
|
||||
id: 'league-1',
|
||||
name: 'Test League',
|
||||
description: 'A test league',
|
||||
ownerId: 'owner-1',
|
||||
settings: { pointsSystem: 'f1-2024' },
|
||||
});
|
||||
|
||||
const season = Season.create({
|
||||
id: 'season-1',
|
||||
leagueId: 'league-1',
|
||||
gameId: 'iracing',
|
||||
name: 'Season 1',
|
||||
status: 'active',
|
||||
schedule: {
|
||||
startDate: new Date('2024-01-01'),
|
||||
timeOfDay: { hour: 20, minute: 0 },
|
||||
} as any,
|
||||
} as any);
|
||||
|
||||
const scoringConfig = LeagueScoringConfig.create({
|
||||
id: 'scoring-1',
|
||||
seasonId: 'season-1',
|
||||
scoringPresetId: 'preset-1',
|
||||
championships: [
|
||||
{
|
||||
id: 'champ-1',
|
||||
name: 'Drivers Championship',
|
||||
type: 'driver',
|
||||
sessionTypes: ['main'],
|
||||
pointsTableBySessionType: {
|
||||
practice: new PointsTable({}),
|
||||
qualifying: new PointsTable({}),
|
||||
q1: new PointsTable({}),
|
||||
q2: new PointsTable({}),
|
||||
q3: new PointsTable({}),
|
||||
sprint: new PointsTable({}),
|
||||
main: new PointsTable({ 1: 25, 2: 18, 3: 15, 4: 12, 5: 10, 6: 8, 7: 6, 8: 4, 9: 2, 10: 1 }),
|
||||
timeTrial: new PointsTable({}),
|
||||
},
|
||||
dropScorePolicy: { strategy: 'bestNResults', count: 3 },
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const game = Game.create({
|
||||
id: 'iracing',
|
||||
name: 'iRacing',
|
||||
});
|
||||
|
||||
const preset: LeagueScoringPreset = {
|
||||
id: 'preset-1',
|
||||
name: 'Test Preset',
|
||||
description: 'Test preset description',
|
||||
primaryChampionshipType: 'driver',
|
||||
dropPolicySummary: 'Best 8 of 12',
|
||||
sessionSummary: 'Qualifying + Race',
|
||||
bonusSummary: 'Bonus points for top 3',
|
||||
defaultTimings: {
|
||||
mainRaceMinutes: 45,
|
||||
practiceMinutes: 15,
|
||||
qualifyingMinutes: 10,
|
||||
sprintRaceMinutes: 0,
|
||||
sessionCount: 1
|
||||
},
|
||||
};
|
||||
|
||||
await presenter.present({
|
||||
leagues: [
|
||||
{
|
||||
league,
|
||||
currentDrivers: 5,
|
||||
maxDrivers: 32,
|
||||
season,
|
||||
scoringConfig,
|
||||
game,
|
||||
preset,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const vm = presenter.getViewModel();
|
||||
|
||||
expect(vm.leagues[0]!.timingSummary).toBe('45m Race');
|
||||
});
|
||||
|
||||
it('should handle leagues without scoring information', async () => {
|
||||
const league = League.create({
|
||||
id: 'league-1',
|
||||
name: 'Test League',
|
||||
description: 'A test league',
|
||||
ownerId: 'owner-1',
|
||||
settings: { pointsSystem: 'f1-2024' },
|
||||
});
|
||||
|
||||
await presenter.present({
|
||||
leagues: [
|
||||
{
|
||||
league,
|
||||
currentDrivers: 5,
|
||||
maxDrivers: 32,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const vm = presenter.getViewModel();
|
||||
|
||||
expect(vm.leagues[0]!.scoring).toBeUndefined();
|
||||
expect(vm.leagues[0]!.timingSummary).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should handle leagues with system default logoRef', async () => {
|
||||
const league = League.create({
|
||||
id: 'league-1',
|
||||
name: 'Test League',
|
||||
description: 'A test league',
|
||||
ownerId: 'owner-1',
|
||||
settings: { pointsSystem: 'f1-2024' },
|
||||
});
|
||||
|
||||
await presenter.present({
|
||||
leagues: [
|
||||
{
|
||||
league,
|
||||
currentDrivers: 5,
|
||||
maxDrivers: 32,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const vm = presenter.getViewModel();
|
||||
|
||||
// Should be null when it's system default (as per presenter logic)
|
||||
expect(vm.leagues[0]!.logoUrl).toBeNull();
|
||||
});
|
||||
|
||||
it('should handle multiple leagues with different configurations', async () => {
|
||||
const league1 = League.create({
|
||||
id: 'league-1',
|
||||
name: 'League One',
|
||||
description: 'First league',
|
||||
ownerId: 'owner-1',
|
||||
settings: { pointsSystem: 'f1-2024', maxDrivers: 20 },
|
||||
category: 'Formula',
|
||||
});
|
||||
|
||||
const league2 = League.create({
|
||||
id: 'league-2',
|
||||
name: 'League Two',
|
||||
description: 'Second league',
|
||||
ownerId: 'owner-2',
|
||||
settings: { pointsSystem: 'indycar', maxDrivers: 40 },
|
||||
socialLinks: { discordUrl: 'https://discord.gg/league2' },
|
||||
});
|
||||
|
||||
await presenter.present({
|
||||
leagues: [
|
||||
{
|
||||
league: league1,
|
||||
currentDrivers: 10,
|
||||
maxDrivers: 20,
|
||||
},
|
||||
{
|
||||
league: league2,
|
||||
currentDrivers: 25,
|
||||
maxDrivers: 40,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const vm = presenter.getViewModel();
|
||||
|
||||
expect(vm.leagues).toHaveLength(2);
|
||||
expect(vm.totalCount).toBe(2);
|
||||
expect(vm.leagues[0]!.id).toBe('league-1');
|
||||
expect(vm.leagues[0]!.category).toBe('Formula');
|
||||
expect(vm.leagues[0]!.settings.maxDrivers).toBe(20);
|
||||
expect(vm.leagues[1]!.id).toBe('league-2');
|
||||
expect(vm.leagues[1]!.socialLinks?.discordUrl).toBe('https://discord.gg/league2');
|
||||
expect(vm.leagues[1]!.settings.maxDrivers).toBe(40);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getViewModel', () => {
|
||||
it('should throw error when not presented', () => {
|
||||
expect(() => presenter.getViewModel()).toThrow('Presenter not presented');
|
||||
});
|
||||
|
||||
it('should return the model when presented', async () => {
|
||||
await presenter.present({ leagues: [] });
|
||||
|
||||
const vm = presenter.getViewModel();
|
||||
|
||||
expect(vm).toEqual({
|
||||
leagues: [],
|
||||
totalCount: 0,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('setMediaResolver', () => {
|
||||
it('should use media resolver to resolve logo URLs', async () => {
|
||||
const mockResolver = {
|
||||
resolve: async () => 'https://cdn.example.com/league-logo.png',
|
||||
};
|
||||
|
||||
presenter.setMediaResolver(mockResolver);
|
||||
|
||||
const league = League.create({
|
||||
id: 'league-1',
|
||||
name: 'Test League',
|
||||
description: 'A test league',
|
||||
ownerId: 'owner-1',
|
||||
settings: { pointsSystem: 'f1-2024' },
|
||||
});
|
||||
|
||||
// Override logoRef to uploaded type
|
||||
(league as any).logoRef = MediaReference.fromJSON({
|
||||
type: 'uploaded',
|
||||
mediaId: 'media-123',
|
||||
});
|
||||
|
||||
await presenter.present({
|
||||
leagues: [
|
||||
{
|
||||
league,
|
||||
currentDrivers: 5,
|
||||
maxDrivers: 32,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const vm = presenter.getViewModel();
|
||||
|
||||
expect(vm.leagues[0]!.logoUrl).toBe('https://cdn.example.com/league-logo.png');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,228 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import { AllLeaguesWithCapacityPresenter } from './AllLeaguesWithCapacityPresenter';
|
||||
import { League } from '@core/racing/domain/entities/League';
|
||||
|
||||
describe('AllLeaguesWithCapacityPresenter', () => {
|
||||
let presenter: AllLeaguesWithCapacityPresenter;
|
||||
|
||||
beforeEach(() => {
|
||||
presenter = new AllLeaguesWithCapacityPresenter();
|
||||
});
|
||||
|
||||
describe('present', () => {
|
||||
it('should map empty leagues array to DTO', () => {
|
||||
presenter.present({ leagues: [] });
|
||||
|
||||
const vm = presenter.getViewModel();
|
||||
|
||||
expect(vm).toEqual({
|
||||
leagues: [],
|
||||
totalCount: 0,
|
||||
});
|
||||
});
|
||||
|
||||
it('should map leagues with basic information', () => {
|
||||
const league = League.create({
|
||||
id: 'league-1',
|
||||
name: 'Test League',
|
||||
description: 'A test league',
|
||||
ownerId: 'owner-1',
|
||||
settings: {
|
||||
pointsSystem: 'f1-2024',
|
||||
maxDrivers: 20,
|
||||
},
|
||||
createdAt: new Date('2024-01-01T00:00:00Z'),
|
||||
});
|
||||
|
||||
presenter.present({
|
||||
leagues: [
|
||||
{
|
||||
league,
|
||||
currentDrivers: 5,
|
||||
maxDrivers: 20,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const vm = presenter.getViewModel();
|
||||
|
||||
expect(vm.leagues).toHaveLength(1);
|
||||
expect(vm.leagues[0]!.id).toBe('league-1');
|
||||
expect(vm.leagues[0]!.name).toBe('Test League');
|
||||
expect(vm.leagues[0]!.description).toBe('A test league');
|
||||
expect(vm.leagues[0]!.ownerId).toBe('owner-1');
|
||||
expect(vm.leagues[0]!.createdAt).toBe('2024-01-01T00:00:00.000Z');
|
||||
expect(vm.leagues[0]!.settings.maxDrivers).toBe(20);
|
||||
expect(vm.leagues[0]!.usedSlots).toBe(5);
|
||||
expect(vm.totalCount).toBe(1);
|
||||
});
|
||||
|
||||
it('should map leagues with social links', () => {
|
||||
const league = League.create({
|
||||
id: 'league-1',
|
||||
name: 'Test League',
|
||||
description: 'A test league',
|
||||
ownerId: 'owner-1',
|
||||
settings: { pointsSystem: 'f1-2024' },
|
||||
socialLinks: {
|
||||
discordUrl: 'https://discord.gg/test',
|
||||
youtubeUrl: 'https://youtube.com/test',
|
||||
websiteUrl: 'https://test.com',
|
||||
},
|
||||
});
|
||||
|
||||
presenter.present({
|
||||
leagues: [
|
||||
{
|
||||
league,
|
||||
currentDrivers: 3,
|
||||
maxDrivers: 32,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const vm = presenter.getViewModel();
|
||||
|
||||
expect(vm.leagues[0]!.socialLinks).toEqual({
|
||||
discordUrl: 'https://discord.gg/test',
|
||||
youtubeUrl: 'https://youtube.com/test',
|
||||
websiteUrl: 'https://test.com',
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle leagues without social links', () => {
|
||||
const league = League.create({
|
||||
id: 'league-1',
|
||||
name: 'Test League',
|
||||
description: 'A test league',
|
||||
ownerId: 'owner-1',
|
||||
settings: { pointsSystem: 'f1-2024' },
|
||||
});
|
||||
|
||||
presenter.present({
|
||||
leagues: [
|
||||
{
|
||||
league,
|
||||
currentDrivers: 2,
|
||||
maxDrivers: 32,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const vm = presenter.getViewModel();
|
||||
|
||||
expect(vm.leagues[0]!.socialLinks).toEqual({});
|
||||
});
|
||||
|
||||
it('should handle multiple leagues with different configurations', () => {
|
||||
const league1 = League.create({
|
||||
id: 'league-1',
|
||||
name: 'League One',
|
||||
description: 'First league',
|
||||
ownerId: 'owner-1',
|
||||
settings: { pointsSystem: 'f1-2024', maxDrivers: 20 },
|
||||
});
|
||||
|
||||
const league2 = League.create({
|
||||
id: 'league-2',
|
||||
name: 'League Two',
|
||||
description: 'Second league',
|
||||
ownerId: 'owner-2',
|
||||
settings: { pointsSystem: 'indycar', maxDrivers: 40 },
|
||||
socialLinks: { discordUrl: 'https://discord.gg/league2' },
|
||||
});
|
||||
|
||||
presenter.present({
|
||||
leagues: [
|
||||
{
|
||||
league: league1,
|
||||
currentDrivers: 10,
|
||||
maxDrivers: 20,
|
||||
},
|
||||
{
|
||||
league: league2,
|
||||
currentDrivers: 25,
|
||||
maxDrivers: 40,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const vm = presenter.getViewModel();
|
||||
|
||||
expect(vm.leagues).toHaveLength(2);
|
||||
expect(vm.totalCount).toBe(2);
|
||||
expect(vm.leagues[0]!.id).toBe('league-1');
|
||||
expect(vm.leagues[0]!.settings.maxDrivers).toBe(20);
|
||||
expect(vm.leagues[0]!.usedSlots).toBe(10);
|
||||
expect(vm.leagues[1]!.id).toBe('league-2');
|
||||
expect(vm.leagues[1]!.socialLinks?.discordUrl).toBe('https://discord.gg/league2');
|
||||
expect(vm.leagues[1]!.settings.maxDrivers).toBe(40);
|
||||
expect(vm.leagues[1]!.usedSlots).toBe(25);
|
||||
});
|
||||
|
||||
it('should handle leagues with zero drivers', () => {
|
||||
const league = League.create({
|
||||
id: 'league-1',
|
||||
name: 'Empty League',
|
||||
description: 'No drivers yet',
|
||||
ownerId: 'owner-1',
|
||||
settings: { pointsSystem: 'f1-2024', maxDrivers: 32 },
|
||||
});
|
||||
|
||||
presenter.present({
|
||||
leagues: [
|
||||
{
|
||||
league,
|
||||
currentDrivers: 0,
|
||||
maxDrivers: 32,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const vm = presenter.getViewModel();
|
||||
|
||||
expect(vm.leagues[0]!.usedSlots).toBe(0);
|
||||
});
|
||||
|
||||
it('should handle leagues with description containing special characters', () => {
|
||||
const league = League.create({
|
||||
id: 'league-1',
|
||||
name: 'Test League',
|
||||
description: 'A test league with "quotes" and <tags> & symbols!',
|
||||
ownerId: 'owner-1',
|
||||
settings: { pointsSystem: 'f1-2024' },
|
||||
});
|
||||
|
||||
presenter.present({
|
||||
leagues: [
|
||||
{
|
||||
league,
|
||||
currentDrivers: 5,
|
||||
maxDrivers: 32,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const vm = presenter.getViewModel();
|
||||
|
||||
expect(vm.leagues[0]!.description).toBe('A test league with "quotes" and <tags> & symbols!');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getViewModel', () => {
|
||||
it('should throw error when not presented', () => {
|
||||
expect(() => presenter.getViewModel()).toThrow('Presenter not presented');
|
||||
});
|
||||
|
||||
it('should return the model when presented', () => {
|
||||
presenter.present({ leagues: [] });
|
||||
|
||||
const vm = presenter.getViewModel();
|
||||
|
||||
expect(vm).toEqual({
|
||||
leagues: [],
|
||||
totalCount: 0,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,86 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import { ApproveLeagueJoinRequestPresenter } from './ApproveLeagueJoinRequestPresenter';
|
||||
|
||||
describe('ApproveLeagueJoinRequestPresenter', () => {
|
||||
let presenter: ApproveLeagueJoinRequestPresenter;
|
||||
|
||||
beforeEach(() => {
|
||||
presenter = new ApproveLeagueJoinRequestPresenter();
|
||||
});
|
||||
|
||||
describe('present', () => {
|
||||
it('should present successful approval result', () => {
|
||||
const result = {
|
||||
success: true,
|
||||
message: 'Join request approved successfully',
|
||||
};
|
||||
|
||||
presenter.present(result);
|
||||
|
||||
const vm = presenter.getViewModel();
|
||||
|
||||
expect(vm).toEqual({
|
||||
success: true,
|
||||
message: 'Join request approved successfully',
|
||||
});
|
||||
});
|
||||
|
||||
it('should present failed approval result', () => {
|
||||
const result = {
|
||||
success: false,
|
||||
message: 'Failed to approve join request',
|
||||
};
|
||||
|
||||
presenter.present(result);
|
||||
|
||||
const vm = presenter.getViewModel();
|
||||
|
||||
expect(vm).toEqual({
|
||||
success: false,
|
||||
message: 'Failed to approve join request',
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle empty message', () => {
|
||||
const result = {
|
||||
success: true,
|
||||
message: '',
|
||||
};
|
||||
|
||||
presenter.present(result);
|
||||
|
||||
const vm = presenter.getViewModel();
|
||||
|
||||
expect(vm).toEqual({
|
||||
success: true,
|
||||
message: '',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getViewModel', () => {
|
||||
it('should return null before presentation', () => {
|
||||
expect(presenter.getViewModel()).toBeNull();
|
||||
});
|
||||
|
||||
it('should return the model after presentation', () => {
|
||||
presenter.present({ success: true, message: 'Test' });
|
||||
|
||||
expect(presenter.getViewModel()).toEqual({
|
||||
success: true,
|
||||
message: 'Test',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('reset', () => {
|
||||
it('should reset the model to null', () => {
|
||||
presenter.present({ success: true, message: 'Test' });
|
||||
expect(presenter.getViewModel()).not.toBeNull();
|
||||
|
||||
presenter.reset();
|
||||
|
||||
expect(presenter.getViewModel()).toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,228 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import { CreateLeaguePresenter } from './CreateLeaguePresenter';
|
||||
import { League } from '@core/racing/domain/entities/League';
|
||||
import { Season } from '@core/racing/domain/entities/season/Season';
|
||||
import { LeagueScoringConfig } from '@core/racing/domain/entities/LeagueScoringConfig';
|
||||
import { PointsTable } from '@core/racing/domain/value-objects/PointsTable';
|
||||
|
||||
describe('CreateLeaguePresenter', () => {
|
||||
let presenter: CreateLeaguePresenter;
|
||||
|
||||
beforeEach(() => {
|
||||
presenter = new CreateLeaguePresenter();
|
||||
});
|
||||
|
||||
describe('present', () => {
|
||||
it('should present successful league creation', () => {
|
||||
const league = League.create({
|
||||
id: 'league-1',
|
||||
name: 'Test League',
|
||||
description: 'A test league',
|
||||
ownerId: 'owner-1',
|
||||
settings: { pointsSystem: 'f1-2024' },
|
||||
});
|
||||
|
||||
const season = Season.create({
|
||||
id: 'season-1',
|
||||
leagueId: 'league-1',
|
||||
gameId: 'iracing',
|
||||
name: 'Test League Season 1',
|
||||
status: 'active',
|
||||
} as any);
|
||||
|
||||
const scoringConfig = LeagueScoringConfig.create({
|
||||
id: 'scoring-1',
|
||||
seasonId: 'season-1',
|
||||
scoringPresetId: 'preset-1',
|
||||
championships: [
|
||||
{
|
||||
id: 'champ-1',
|
||||
name: 'Driver Championship',
|
||||
type: 'driver',
|
||||
sessionTypes: ['main'],
|
||||
pointsTableBySessionType: {
|
||||
practice: new PointsTable({}),
|
||||
qualifying: new PointsTable({}),
|
||||
q1: new PointsTable({}),
|
||||
q2: new PointsTable({}),
|
||||
q3: new PointsTable({}),
|
||||
sprint: new PointsTable({}),
|
||||
main: new PointsTable({ 1: 25, 2: 18, 3: 15 }),
|
||||
timeTrial: new PointsTable({}),
|
||||
},
|
||||
dropScorePolicy: { strategy: 'none' },
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
presenter.present({ league, season, scoringConfig });
|
||||
|
||||
const vm = presenter.getViewModel();
|
||||
|
||||
expect(vm).toEqual({
|
||||
leagueId: 'league-1',
|
||||
success: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('should present league with different ID', () => {
|
||||
const league = League.create({
|
||||
id: 'league-abc-123',
|
||||
name: 'Another League',
|
||||
description: 'Another test league',
|
||||
ownerId: 'owner-2',
|
||||
settings: { pointsSystem: 'indycar' },
|
||||
});
|
||||
|
||||
const season = Season.create({
|
||||
id: 'season-2',
|
||||
leagueId: 'league-abc-123',
|
||||
gameId: 'iracing',
|
||||
name: 'Another League Season 1',
|
||||
status: 'active',
|
||||
} as any);
|
||||
|
||||
const scoringConfig = LeagueScoringConfig.create({
|
||||
id: 'scoring-2',
|
||||
seasonId: 'season-2',
|
||||
scoringPresetId: 'preset-2',
|
||||
championships: [
|
||||
{
|
||||
id: 'champ-2',
|
||||
name: 'Driver Championship',
|
||||
type: 'driver',
|
||||
sessionTypes: ['main'],
|
||||
pointsTableBySessionType: {
|
||||
practice: new PointsTable({}),
|
||||
qualifying: new PointsTable({}),
|
||||
q1: new PointsTable({}),
|
||||
q2: new PointsTable({}),
|
||||
q3: new PointsTable({}),
|
||||
sprint: new PointsTable({}),
|
||||
main: new PointsTable({ 1: 25, 2: 18, 3: 15 }),
|
||||
timeTrial: new PointsTable({}),
|
||||
},
|
||||
dropScorePolicy: { strategy: 'none' },
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
presenter.present({ league, season, scoringConfig });
|
||||
|
||||
const vm = presenter.getViewModel();
|
||||
|
||||
expect(vm).toEqual({
|
||||
leagueId: 'league-abc-123',
|
||||
success: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getViewModel', () => {
|
||||
it('should throw error when not presented', () => {
|
||||
expect(() => presenter.getViewModel()).toThrow('Presenter not presented');
|
||||
});
|
||||
|
||||
it('should return the model when presented', () => {
|
||||
const league = League.create({
|
||||
id: 'league-1',
|
||||
name: 'Test League',
|
||||
description: 'A test league',
|
||||
ownerId: 'owner-1',
|
||||
settings: { pointsSystem: 'f1-2024' },
|
||||
});
|
||||
|
||||
const season = Season.create({
|
||||
id: 'season-1',
|
||||
leagueId: 'league-1',
|
||||
gameId: 'iracing',
|
||||
name: 'Test League Season 1',
|
||||
status: 'active',
|
||||
} as any);
|
||||
|
||||
const scoringConfig = LeagueScoringConfig.create({
|
||||
id: 'scoring-1',
|
||||
seasonId: 'season-1',
|
||||
scoringPresetId: 'preset-1',
|
||||
championships: [
|
||||
{
|
||||
id: 'champ-1',
|
||||
name: 'Driver Championship',
|
||||
type: 'driver',
|
||||
sessionTypes: ['main'],
|
||||
pointsTableBySessionType: {
|
||||
practice: new PointsTable({}),
|
||||
qualifying: new PointsTable({}),
|
||||
q1: new PointsTable({}),
|
||||
q2: new PointsTable({}),
|
||||
q3: new PointsTable({}),
|
||||
sprint: new PointsTable({}),
|
||||
main: new PointsTable({ 1: 25, 2: 18, 3: 15 }),
|
||||
timeTrial: new PointsTable({}),
|
||||
},
|
||||
dropScorePolicy: { strategy: 'none' },
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
presenter.present({ league, season, scoringConfig });
|
||||
|
||||
expect(presenter.getViewModel()).toEqual({
|
||||
leagueId: 'league-1',
|
||||
success: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('reset', () => {
|
||||
it('should reset the model and cause getViewModel to throw', () => {
|
||||
const league = League.create({
|
||||
id: 'league-1',
|
||||
name: 'Test League',
|
||||
description: 'A test league',
|
||||
ownerId: 'owner-1',
|
||||
settings: { pointsSystem: 'f1-2024' },
|
||||
});
|
||||
|
||||
const season = Season.create({
|
||||
id: 'season-1',
|
||||
leagueId: 'league-1',
|
||||
gameId: 'iracing',
|
||||
name: 'Test League Season 1',
|
||||
status: 'active',
|
||||
} as any);
|
||||
|
||||
const scoringConfig = LeagueScoringConfig.create({
|
||||
id: 'scoring-1',
|
||||
seasonId: 'season-1',
|
||||
scoringPresetId: 'preset-1',
|
||||
championships: [
|
||||
{
|
||||
id: 'champ-1',
|
||||
name: 'Driver Championship',
|
||||
type: 'driver',
|
||||
sessionTypes: ['main'],
|
||||
pointsTableBySessionType: {
|
||||
practice: new PointsTable({}),
|
||||
qualifying: new PointsTable({}),
|
||||
q1: new PointsTable({}),
|
||||
q2: new PointsTable({}),
|
||||
q3: new PointsTable({}),
|
||||
sprint: new PointsTable({}),
|
||||
main: new PointsTable({ 1: 25, 2: 18, 3: 15 }),
|
||||
timeTrial: new PointsTable({}),
|
||||
},
|
||||
dropScorePolicy: { strategy: 'none' },
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
presenter.present({ league, season, scoringConfig });
|
||||
expect(presenter.getViewModel()).not.toBeNull();
|
||||
|
||||
presenter.reset();
|
||||
|
||||
expect(() => presenter.getViewModel()).toThrow('Presenter not presented');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,70 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import { RejectLeagueJoinRequestPresenter } from './RejectLeagueJoinRequestPresenter';
|
||||
|
||||
describe('RejectLeagueJoinRequestPresenter', () => {
|
||||
let presenter: RejectLeagueJoinRequestPresenter;
|
||||
|
||||
beforeEach(() => {
|
||||
presenter = new RejectLeagueJoinRequestPresenter();
|
||||
});
|
||||
|
||||
describe('present', () => {
|
||||
it('should present successful rejection result', () => {
|
||||
const result = {
|
||||
success: true,
|
||||
message: 'Join request rejected successfully',
|
||||
};
|
||||
|
||||
presenter.present(result);
|
||||
|
||||
const vm = presenter.getViewModel();
|
||||
|
||||
expect(vm).toEqual({
|
||||
success: true,
|
||||
message: 'Join request rejected successfully',
|
||||
});
|
||||
});
|
||||
|
||||
it('should present failed rejection result', () => {
|
||||
const result = {
|
||||
success: false,
|
||||
message: 'Failed to reject join request',
|
||||
};
|
||||
|
||||
presenter.present(result);
|
||||
|
||||
const vm = presenter.getViewModel();
|
||||
|
||||
expect(vm).toEqual({
|
||||
success: false,
|
||||
message: 'Failed to reject join request',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getViewModel', () => {
|
||||
it('should return null before presentation', () => {
|
||||
expect(presenter.getViewModel()).toBeNull();
|
||||
});
|
||||
|
||||
it('should return the model after presentation', () => {
|
||||
presenter.present({ success: true, message: 'Test' });
|
||||
|
||||
expect(presenter.getViewModel()).toEqual({
|
||||
success: true,
|
||||
message: 'Test',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('reset', () => {
|
||||
it('should reset the model to null', () => {
|
||||
presenter.present({ success: true, message: 'Test' });
|
||||
expect(presenter.getViewModel()).not.toBeNull();
|
||||
|
||||
presenter.reset();
|
||||
|
||||
expect(presenter.getViewModel()).toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,67 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import { TotalLeaguesPresenter } from './TotalLeaguesPresenter';
|
||||
|
||||
describe('TotalLeaguesPresenter', () => {
|
||||
let presenter: TotalLeaguesPresenter;
|
||||
|
||||
beforeEach(() => {
|
||||
presenter = new TotalLeaguesPresenter();
|
||||
});
|
||||
|
||||
describe('present', () => {
|
||||
it('should present total leagues count', () => {
|
||||
presenter.present({ totalLeagues: 42 });
|
||||
|
||||
const vm = presenter.getResponseModel();
|
||||
|
||||
expect(vm).toEqual({
|
||||
totalLeagues: 42,
|
||||
});
|
||||
});
|
||||
|
||||
it('should present zero total leagues', () => {
|
||||
presenter.present({ totalLeagues: 0 });
|
||||
|
||||
const vm = presenter.getResponseModel();
|
||||
|
||||
expect(vm).toEqual({
|
||||
totalLeagues: 0,
|
||||
});
|
||||
});
|
||||
|
||||
it('should present large total leagues count', () => {
|
||||
presenter.present({ totalLeagues: 999999 });
|
||||
|
||||
const vm = presenter.getResponseModel();
|
||||
|
||||
expect(vm).toEqual({
|
||||
totalLeagues: 999999,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getResponseModel', () => {
|
||||
it('should return null before presentation', () => {
|
||||
expect(presenter.getResponseModel()).toBeNull();
|
||||
});
|
||||
|
||||
it('should return the model after presentation', () => {
|
||||
presenter.present({ totalLeagues: 10 });
|
||||
|
||||
expect(presenter.getResponseModel()).toEqual({
|
||||
totalLeagues: 10,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('reset', () => {
|
||||
it('should reset the model to null', () => {
|
||||
presenter.present({ totalLeagues: 25 });
|
||||
expect(presenter.getResponseModel()).not.toBeNull();
|
||||
|
||||
presenter.reset();
|
||||
|
||||
expect(presenter.getResponseModel()).toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user