This commit is contained in:
2026-01-08 17:36:08 +01:00
parent 66ec6fe727
commit 05cf3bafd2
23 changed files with 3004 additions and 0 deletions

View File

@@ -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');
});
});
});

View File

@@ -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,
});
});
});
});

View File

@@ -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();
});
});
});

View File

@@ -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');
});
});
});

View File

@@ -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();
});
});
});

View File

@@ -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();
});
});
});