core tests
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { CreateLeagueUseCase } from './CreateLeagueUseCase';
|
||||
import { LeagueCreateCommand } from '../ports/LeagueCreateCommand';
|
||||
|
||||
describe('CreateLeagueUseCase', () => {
|
||||
let mockLeagueRepository: any;
|
||||
let mockEventPublisher: any;
|
||||
let useCase: CreateLeagueUseCase;
|
||||
|
||||
beforeEach(() => {
|
||||
mockLeagueRepository = {
|
||||
create: vi.fn().mockImplementation((data) => Promise.resolve(data)),
|
||||
updateStats: vi.fn().mockResolvedValue(undefined),
|
||||
updateFinancials: vi.fn().mockResolvedValue(undefined),
|
||||
updateStewardingMetrics: vi.fn().mockResolvedValue(undefined),
|
||||
updatePerformanceMetrics: vi.fn().mockResolvedValue(undefined),
|
||||
updateRatingMetrics: vi.fn().mockResolvedValue(undefined),
|
||||
updateTrendMetrics: vi.fn().mockResolvedValue(undefined),
|
||||
updateSuccessRateMetrics: vi.fn().mockResolvedValue(undefined),
|
||||
updateResolutionTimeMetrics: vi.fn().mockResolvedValue(undefined),
|
||||
updateComplexSuccessRateMetrics: vi.fn().mockResolvedValue(undefined),
|
||||
updateComplexResolutionTimeMetrics: vi.fn().mockResolvedValue(undefined),
|
||||
};
|
||||
mockEventPublisher = {
|
||||
emitLeagueCreated: vi.fn().mockResolvedValue(undefined),
|
||||
};
|
||||
useCase = new CreateLeagueUseCase(mockLeagueRepository, mockEventPublisher);
|
||||
});
|
||||
|
||||
it('should create a league and initialize all metrics', async () => {
|
||||
const command: LeagueCreateCommand = {
|
||||
name: 'New League',
|
||||
ownerId: 'owner-1',
|
||||
visibility: 'public',
|
||||
approvalRequired: false,
|
||||
lateJoinAllowed: true,
|
||||
bonusPointsEnabled: true,
|
||||
penaltiesEnabled: true,
|
||||
protestsEnabled: true,
|
||||
appealsEnabled: true,
|
||||
};
|
||||
|
||||
const result = await useCase.execute(command);
|
||||
|
||||
expect(result.name).toBe('New League');
|
||||
expect(result.ownerId).toBe('owner-1');
|
||||
expect(mockLeagueRepository.create).toHaveBeenCalled();
|
||||
expect(mockLeagueRepository.updateStats).toHaveBeenCalled();
|
||||
expect(mockLeagueRepository.updateFinancials).toHaveBeenCalled();
|
||||
expect(mockEventPublisher.emitLeagueCreated).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should throw error if name is missing', async () => {
|
||||
const command: any = { ownerId: 'owner-1' };
|
||||
await expect(useCase.execute(command)).rejects.toThrow('League name is required');
|
||||
});
|
||||
|
||||
it('should throw error if ownerId is missing', async () => {
|
||||
const command: any = { name: 'League' };
|
||||
await expect(useCase.execute(command)).rejects.toThrow('Owner ID is required');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,30 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { DemoteAdminUseCase } from './DemoteAdminUseCase';
|
||||
|
||||
describe('DemoteAdminUseCase', () => {
|
||||
let mockLeagueRepository: any;
|
||||
let mockDriverRepository: any;
|
||||
let mockEventPublisher: any;
|
||||
let useCase: DemoteAdminUseCase;
|
||||
|
||||
beforeEach(() => {
|
||||
mockLeagueRepository = {
|
||||
updateLeagueMember: vi.fn().mockResolvedValue(undefined),
|
||||
};
|
||||
mockDriverRepository = {};
|
||||
mockEventPublisher = {};
|
||||
useCase = new DemoteAdminUseCase(mockLeagueRepository, mockDriverRepository, mockEventPublisher as any);
|
||||
});
|
||||
|
||||
it('should update member role to member', async () => {
|
||||
const command = {
|
||||
leagueId: 'l1',
|
||||
targetDriverId: 'd1',
|
||||
actorId: 'owner-1',
|
||||
};
|
||||
|
||||
await useCase.execute(command);
|
||||
|
||||
expect(mockLeagueRepository.updateLeagueMember).toHaveBeenCalledWith('l1', 'd1', { role: 'member' });
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,45 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { GetLeagueRosterUseCase } from './GetLeagueRosterUseCase';
|
||||
|
||||
describe('GetLeagueRosterUseCase', () => {
|
||||
let mockLeagueRepository: any;
|
||||
let mockEventPublisher: any;
|
||||
let useCase: GetLeagueRosterUseCase;
|
||||
|
||||
const mockLeague = { id: 'league-1' };
|
||||
const mockMembers = [
|
||||
{ driverId: 'd1', name: 'Owner', role: 'owner', joinDate: new Date() },
|
||||
{ driverId: 'd2', name: 'Admin', role: 'admin', joinDate: new Date() },
|
||||
{ driverId: 'd3', name: 'Member', role: 'member', joinDate: new Date() },
|
||||
];
|
||||
const mockRequests = [
|
||||
{ id: 'r1', driverId: 'd4', name: 'Requester', requestDate: new Date() },
|
||||
];
|
||||
|
||||
beforeEach(() => {
|
||||
mockLeagueRepository = {
|
||||
findById: vi.fn().mockResolvedValue(mockLeague),
|
||||
getLeagueMembers: vi.fn().mockResolvedValue(mockMembers),
|
||||
getPendingRequests: vi.fn().mockResolvedValue(mockRequests),
|
||||
};
|
||||
mockEventPublisher = {
|
||||
emitLeagueRosterAccessed: vi.fn().mockResolvedValue(undefined),
|
||||
};
|
||||
useCase = new GetLeagueRosterUseCase(mockLeagueRepository, mockEventPublisher);
|
||||
});
|
||||
|
||||
it('should return roster with members, requests and stats', async () => {
|
||||
const result = await useCase.execute({ leagueId: 'league-1' });
|
||||
|
||||
expect(result.members).toHaveLength(3);
|
||||
expect(result.pendingRequests).toHaveLength(1);
|
||||
expect(result.stats.adminCount).toBe(2); // owner + admin
|
||||
expect(result.stats.driverCount).toBe(1);
|
||||
expect(mockEventPublisher.emitLeagueRosterAccessed).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should throw error if league not found', async () => {
|
||||
mockLeagueRepository.findById.mockResolvedValue(null);
|
||||
await expect(useCase.execute({ leagueId: 'invalid' })).rejects.toThrow('League with id invalid not found');
|
||||
});
|
||||
});
|
||||
52
core/leagues/application/use-cases/GetLeagueUseCase.test.ts
Normal file
52
core/leagues/application/use-cases/GetLeagueUseCase.test.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { GetLeagueUseCase, GetLeagueQuery } from './GetLeagueUseCase';
|
||||
|
||||
describe('GetLeagueUseCase', () => {
|
||||
let mockLeagueRepository: any;
|
||||
let mockEventPublisher: any;
|
||||
let useCase: GetLeagueUseCase;
|
||||
|
||||
const mockLeague = {
|
||||
id: 'league-1',
|
||||
name: 'Test League',
|
||||
ownerId: 'owner-1',
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
mockLeagueRepository = {
|
||||
findById: vi.fn().mockResolvedValue(mockLeague),
|
||||
};
|
||||
mockEventPublisher = {
|
||||
emitLeagueAccessed: vi.fn().mockResolvedValue(undefined),
|
||||
};
|
||||
useCase = new GetLeagueUseCase(mockLeagueRepository, mockEventPublisher);
|
||||
});
|
||||
|
||||
it('should return league data', async () => {
|
||||
const query: GetLeagueQuery = { leagueId: 'league-1' };
|
||||
const result = await useCase.execute(query);
|
||||
|
||||
expect(result).toEqual(mockLeague);
|
||||
expect(mockLeagueRepository.findById).toHaveBeenCalledWith('league-1');
|
||||
expect(mockEventPublisher.emitLeagueAccessed).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should emit event if driverId is provided', async () => {
|
||||
const query: GetLeagueQuery = { leagueId: 'league-1', driverId: 'driver-1' };
|
||||
await useCase.execute(query);
|
||||
|
||||
expect(mockEventPublisher.emitLeagueAccessed).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should throw error if league not found', async () => {
|
||||
mockLeagueRepository.findById.mockResolvedValue(null);
|
||||
const query: GetLeagueQuery = { leagueId: 'non-existent' };
|
||||
|
||||
await expect(useCase.execute(query)).rejects.toThrow('League with id non-existent not found');
|
||||
});
|
||||
|
||||
it('should throw error if leagueId is missing', async () => {
|
||||
const query: any = {};
|
||||
await expect(useCase.execute(query)).rejects.toThrow('League ID is required');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,41 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { SearchLeaguesUseCase, SearchLeaguesQuery } from './SearchLeaguesUseCase';
|
||||
|
||||
describe('SearchLeaguesUseCase', () => {
|
||||
let mockLeagueRepository: any;
|
||||
let useCase: SearchLeaguesUseCase;
|
||||
|
||||
const mockLeagues = [
|
||||
{ id: '1', name: 'League 1' },
|
||||
{ id: '2', name: 'League 2' },
|
||||
{ id: '3', name: 'League 3' },
|
||||
];
|
||||
|
||||
beforeEach(() => {
|
||||
mockLeagueRepository = {
|
||||
search: vi.fn().mockResolvedValue([...mockLeagues]),
|
||||
};
|
||||
useCase = new SearchLeaguesUseCase(mockLeagueRepository);
|
||||
});
|
||||
|
||||
it('should return search results with default limit', async () => {
|
||||
const query: SearchLeaguesQuery = { query: 'test' };
|
||||
const result = await useCase.execute(query);
|
||||
|
||||
expect(result).toHaveLength(3);
|
||||
expect(mockLeagueRepository.search).toHaveBeenCalledWith('test');
|
||||
});
|
||||
|
||||
it('should respect limit and offset', async () => {
|
||||
const query: SearchLeaguesQuery = { query: 'test', limit: 1, offset: 1 };
|
||||
const result = await useCase.execute(query);
|
||||
|
||||
expect(result).toHaveLength(1);
|
||||
expect(result[0].id).toBe('2');
|
||||
});
|
||||
|
||||
it('should throw error if query is missing', async () => {
|
||||
const query: any = { query: '' };
|
||||
await expect(useCase.execute(query)).rejects.toThrow('Search query is required');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user