refactor racing use cases

This commit is contained in:
2025-12-21 00:43:42 +01:00
parent e9d6f90bb2
commit c12656d671
308 changed files with 14401 additions and 7419 deletions

View File

@@ -1,5 +1,10 @@
import { describe, it, expect, beforeEach, vi, Mock } from 'vitest';
import { GetSponsorDashboardUseCase } from './GetSponsorDashboardUseCase';
import {
GetSponsorDashboardUseCase,
type GetSponsorDashboardInput,
type GetSponsorDashboardResult,
type GetSponsorDashboardErrorCode,
} from './GetSponsorDashboardUseCase';
import { ISponsorRepository } from '../../domain/repositories/ISponsorRepository';
import { ISeasonSponsorshipRepository } from '../../domain/repositories/ISeasonSponsorshipRepository';
import { ISeasonRepository } from '../../domain/repositories/ISeasonRepository';
@@ -11,6 +16,8 @@ import { SeasonSponsorship } from '../../domain/entities/SeasonSponsorship';
import { Season } from '../../domain/entities/Season';
import { League } from '../../domain/entities/League';
import { Money } from '../../domain/value-objects/Money';
import type { UseCaseOutputPort } from '@core/shared/application';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
describe('GetSponsorDashboardUseCase', () => {
let useCase: GetSponsorDashboardUseCase;
@@ -32,6 +39,7 @@ describe('GetSponsorDashboardUseCase', () => {
let raceRepository: {
findByLeagueId: Mock;
};
let output: UseCaseOutputPort<GetSponsorDashboardResult> & { present: Mock };
beforeEach(() => {
sponsorRepository = {
@@ -52,6 +60,10 @@ describe('GetSponsorDashboardUseCase', () => {
raceRepository = {
findByLeagueId: vi.fn(),
};
output = {
present: vi.fn(),
} as unknown as UseCaseOutputPort<GetSponsorDashboardResult> & { present: Mock };
useCase = new GetSponsorDashboardUseCase(
sponsorRepository as unknown as ISponsorRepository,
seasonSponsorshipRepository as unknown as ISeasonSponsorshipRepository,
@@ -59,10 +71,11 @@ describe('GetSponsorDashboardUseCase', () => {
leagueRepository as unknown as ILeagueRepository,
leagueMembershipRepository as unknown as ILeagueMembershipRepository,
raceRepository as unknown as IRaceRepository,
output,
);
});
it('should return sponsor dashboard for existing sponsor', async () => {
it('should present sponsor dashboard for existing sponsor', async () => {
const sponsorId = 'sponsor-1';
const sponsor = Sponsor.create({
id: sponsorId,
@@ -99,34 +112,56 @@ describe('GetSponsorDashboardUseCase', () => {
leagueMembershipRepository.getLeagueMembers.mockResolvedValue(memberships);
raceRepository.findByLeagueId.mockResolvedValue(races);
const result = await useCase.execute({ sponsorId });
const input: GetSponsorDashboardInput = { sponsorId };
const result = await useCase.execute(input);
expect(result.isOk()).toBe(true);
const dashboard = result.unwrap();
expect(dashboard?.sponsorId).toBe(sponsorId);
expect(dashboard?.metrics.impressions).toBe(100); // 1 completed race * 1 driver * 100
expect(result.unwrap()).toBeUndefined();
expect(output.present).toHaveBeenCalledTimes(1);
const dashboard = (output.present as Mock).mock.calls[0][0] as GetSponsorDashboardResult;
expect(dashboard.sponsorId).toBe(sponsorId);
expect(dashboard.metrics.impressions).toBe(100); // 1 completed race * 1 driver * 100
expect(dashboard.investment.totalInvestment.amount).toBe(10000);
expect(dashboard.investment.totalInvestment.currency).toBe('USD');
});
it('should return null for non-existing sponsor', async () => {
it('should return error when sponsor does not exist', async () => {
const sponsorId = 'sponsor-1';
sponsorRepository.findById.mockResolvedValue(null);
const result = await useCase.execute({ sponsorId });
const input: GetSponsorDashboardInput = { sponsorId };
const result = await useCase.execute(input);
expect(result.isOk()).toBe(true);
expect(result.unwrap()).toBe(null);
expect(result.isErr()).toBe(true);
const error = result.unwrapErr() as ApplicationErrorCode<
GetSponsorDashboardErrorCode,
{ message: string }
>;
expect(error.code).toBe('SPONSOR_NOT_FOUND');
expect(error.details.message).toBe('Sponsor not found');
expect(output.present).not.toHaveBeenCalled();
});
it('should return error on repository failure', async () => {
const sponsorId = 'sponsor-1';
sponsorRepository.findById.mockRejectedValue(new Error('DB error'));
const result = await useCase.execute({ sponsorId });
const input: GetSponsorDashboardInput = { sponsorId };
const result = await useCase.execute(input);
expect(result.isErr()).toBe(true);
expect(result.unwrapErr()).toEqual({
code: 'REPOSITORY_ERROR',
message: 'Failed to fetch sponsor dashboard',
});
const error = result.unwrapErr() as ApplicationErrorCode<
GetSponsorDashboardErrorCode,
{ message: string }
>;
expect(error.code).toBe('REPOSITORY_ERROR');
expect(error.details.message).toBe('DB error');
expect(output.present).not.toHaveBeenCalled();
});
});
});