refactor core presenters
This commit is contained in:
@@ -17,6 +17,7 @@ import { GetTotalDriversUseCase } from '@core/racing/application/use-cases/GetTo
|
||||
import { CompleteDriverOnboardingUseCase } from '@core/racing/application/use-cases/CompleteDriverOnboardingUseCase';
|
||||
import { UpdateDriverProfileUseCase } from '@core/racing/application/use-cases/UpdateDriverProfileUseCase';
|
||||
import { IsDriverRegisteredForRaceUseCase } from '@core/racing/application/use-cases/IsDriverRegisteredForRaceUseCase';
|
||||
import { GetProfileOverviewUseCase } from '@core/racing/application/use-cases/GetProfileOverviewUseCase';
|
||||
|
||||
// Import concrete in-memory implementations
|
||||
import { InMemoryDriverRepository } from '@adapters/racing/persistence/inmemory/InMemoryDriverRepository';
|
||||
@@ -44,6 +45,7 @@ export const GET_TOTAL_DRIVERS_USE_CASE_TOKEN = 'GetTotalDriversUseCase';
|
||||
export const COMPLETE_DRIVER_ONBOARDING_USE_CASE_TOKEN = 'CompleteDriverOnboardingUseCase';
|
||||
export const IS_DRIVER_REGISTERED_FOR_RACE_USE_CASE_TOKEN = 'IsDriverRegisteredForRaceUseCase';
|
||||
export const UPDATE_DRIVER_PROFILE_USE_CASE_TOKEN = 'UpdateDriverProfileUseCase';
|
||||
export const GET_PROFILE_OVERVIEW_USE_CASE_TOKEN = 'GetProfileOverviewUseCase';
|
||||
|
||||
export const DriverProviders: Provider[] = [
|
||||
DriverService, // Provide the service itself
|
||||
@@ -113,4 +115,19 @@ export const DriverProviders: Provider[] = [
|
||||
useFactory: (driverRepo: IDriverRepository) => new UpdateDriverProfileUseCase(driverRepo),
|
||||
inject: [DRIVER_REPOSITORY_TOKEN],
|
||||
},
|
||||
{
|
||||
provide: GET_PROFILE_OVERVIEW_USE_CASE_TOKEN,
|
||||
useFactory: (driverRepo: IDriverRepository, imageService: IImageServicePort, logger: Logger) =>
|
||||
new GetProfileOverviewUseCase(
|
||||
driverRepo,
|
||||
// TODO: Add teamRepository, teamMembershipRepository, socialRepository, etc.
|
||||
null as any, // teamRepository
|
||||
null as any, // teamMembershipRepository
|
||||
null as any, // socialRepository
|
||||
imageService,
|
||||
() => null, // getDriverStats
|
||||
() => [], // getAllDriverRankings
|
||||
),
|
||||
inject: [DRIVER_REPOSITORY_TOKEN, IMAGE_SERVICE_PORT_TOKEN, LOGGER_TOKEN],
|
||||
},
|
||||
];
|
||||
|
||||
@@ -8,6 +8,9 @@ import { IsDriverRegisteredForRaceUseCase } from '@core/racing/application/use-c
|
||||
import { UpdateDriverProfileUseCase } from '@core/racing/application/use-cases/UpdateDriverProfileUseCase';
|
||||
import type { Logger } from '@core/shared/application';
|
||||
import type { IDriverRepository } from '@core/racing/domain/repositories/IDriverRepository';
|
||||
import { Result } from '@core/shared/application/Result';
|
||||
import type { CompleteDriverOnboardingOutputPort } from '@core/racing/application/ports/output/CompleteDriverOnboardingOutputPort';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
|
||||
describe('DriverService', () => {
|
||||
let service: DriverService;
|
||||
@@ -15,7 +18,9 @@ describe('DriverService', () => {
|
||||
let getTotalDriversUseCase: ReturnType<typeof vi.mocked<GetTotalDriversUseCase>>;
|
||||
let completeDriverOnboardingUseCase: ReturnType<typeof vi.mocked<CompleteDriverOnboardingUseCase>>;
|
||||
let isDriverRegisteredForRaceUseCase: ReturnType<typeof vi.mocked<IsDriverRegisteredForRaceUseCase>>;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
let updateDriverProfileUseCase: ReturnType<typeof vi.mocked<UpdateDriverProfileUseCase>>;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
let driverRepository: ReturnType<typeof vi.mocked<IDriverRepository>>;
|
||||
let logger: ReturnType<typeof vi.mocked<Logger>>;
|
||||
|
||||
@@ -102,17 +107,11 @@ describe('DriverService', () => {
|
||||
activeCount: 1,
|
||||
};
|
||||
|
||||
const mockPresenter = {
|
||||
viewModel: mockViewModel,
|
||||
};
|
||||
|
||||
getDriversLeaderboardUseCase.execute.mockImplementation(async (input, presenter) => {
|
||||
Object.assign(presenter, mockPresenter);
|
||||
});
|
||||
getDriversLeaderboardUseCase.execute.mockResolvedValue(Result.ok(mockViewModel));
|
||||
|
||||
const result = await service.getDriversLeaderboard();
|
||||
|
||||
expect(getDriversLeaderboardUseCase.execute).toHaveBeenCalledWith(undefined, expect.any(Object));
|
||||
expect(getDriversLeaderboardUseCase.execute).toHaveBeenCalledWith();
|
||||
expect(logger.debug).toHaveBeenCalledWith('[DriverService] Fetching drivers leaderboard.');
|
||||
expect(result).toEqual(mockViewModel);
|
||||
});
|
||||
@@ -120,26 +119,20 @@ describe('DriverService', () => {
|
||||
|
||||
describe('getTotalDrivers', () => {
|
||||
it('should call GetTotalDriversUseCase and return the view model', async () => {
|
||||
const mockViewModel = { totalDrivers: 5 };
|
||||
const mockOutput = { totalDrivers: 5 };
|
||||
|
||||
const mockPresenter = {
|
||||
viewModel: mockViewModel,
|
||||
};
|
||||
|
||||
getTotalDriversUseCase.execute.mockImplementation(async (input, presenter) => {
|
||||
Object.assign(presenter, mockPresenter);
|
||||
});
|
||||
getTotalDriversUseCase.execute.mockResolvedValue(Result.ok(mockOutput));
|
||||
|
||||
const result = await service.getTotalDrivers();
|
||||
|
||||
expect(getTotalDriversUseCase.execute).toHaveBeenCalledWith(undefined, expect.any(Object));
|
||||
expect(getTotalDriversUseCase.execute).toHaveBeenCalledWith();
|
||||
expect(logger.debug).toHaveBeenCalledWith('[DriverService] Fetching total drivers count.');
|
||||
expect(result).toEqual(mockViewModel);
|
||||
expect(result).toEqual(mockOutput);
|
||||
});
|
||||
});
|
||||
|
||||
describe('completeOnboarding', () => {
|
||||
it('should call CompleteDriverOnboardingUseCase and return the view model', async () => {
|
||||
it('should call CompleteDriverOnboardingUseCase and return success', async () => {
|
||||
const input = {
|
||||
firstName: 'John',
|
||||
lastName: 'Doe',
|
||||
@@ -149,30 +142,43 @@ describe('DriverService', () => {
|
||||
bio: 'Racing enthusiast',
|
||||
};
|
||||
|
||||
const mockViewModel = {
|
||||
success: true,
|
||||
driverId: 'user-123',
|
||||
};
|
||||
|
||||
const mockPresenter = {
|
||||
viewModel: mockViewModel,
|
||||
};
|
||||
|
||||
completeDriverOnboardingUseCase.execute.mockImplementation(async (input, presenter) => {
|
||||
Object.assign(presenter, mockPresenter);
|
||||
});
|
||||
completeDriverOnboardingUseCase.execute.mockResolvedValue(
|
||||
Result.ok<CompleteDriverOnboardingOutputPort, ApplicationErrorCode<string>>({ driverId: 'user-123' })
|
||||
);
|
||||
|
||||
const result = await service.completeOnboarding('user-123', input);
|
||||
|
||||
expect(completeDriverOnboardingUseCase.execute).toHaveBeenCalledWith(
|
||||
{
|
||||
userId: 'user-123',
|
||||
...input,
|
||||
},
|
||||
expect.any(Object)
|
||||
);
|
||||
expect(completeDriverOnboardingUseCase.execute).toHaveBeenCalledWith({
|
||||
userId: 'user-123',
|
||||
...input,
|
||||
});
|
||||
expect(logger.debug).toHaveBeenCalledWith('Completing onboarding for user:', 'user-123');
|
||||
expect(result).toEqual(mockViewModel);
|
||||
expect(result).toEqual({
|
||||
success: true,
|
||||
driverId: 'user-123',
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle error from use case', async () => {
|
||||
const input = {
|
||||
firstName: 'John',
|
||||
lastName: 'Doe',
|
||||
displayName: 'John Doe',
|
||||
country: 'US',
|
||||
timezone: 'America/New_York',
|
||||
bio: 'Racing enthusiast',
|
||||
};
|
||||
|
||||
completeDriverOnboardingUseCase.execute.mockResolvedValue(
|
||||
Result.err<CompleteDriverOnboardingOutputPort, ApplicationErrorCode<string>>({ code: 'DRIVER_ALREADY_EXISTS' })
|
||||
);
|
||||
|
||||
const result = await service.completeOnboarding('user-123', input);
|
||||
|
||||
expect(result).toEqual({
|
||||
success: false,
|
||||
errorMessage: 'DRIVER_ALREADY_EXISTS',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -183,25 +189,19 @@ describe('DriverService', () => {
|
||||
raceId: 'race-1',
|
||||
};
|
||||
|
||||
const mockViewModel = {
|
||||
const mockOutput = {
|
||||
isRegistered: true,
|
||||
raceId: 'race-1',
|
||||
driverId: 'driver-1',
|
||||
};
|
||||
|
||||
const mockPresenter = {
|
||||
viewModel: mockViewModel,
|
||||
};
|
||||
|
||||
isDriverRegisteredForRaceUseCase.execute.mockImplementation(async (params, presenter) => {
|
||||
Object.assign(presenter, mockPresenter);
|
||||
});
|
||||
isDriverRegisteredForRaceUseCase.execute.mockResolvedValue(Result.ok(mockOutput));
|
||||
|
||||
const result = await service.getDriverRegistrationStatus(query);
|
||||
|
||||
expect(isDriverRegisteredForRaceUseCase.execute).toHaveBeenCalledWith(query, expect.any(Object));
|
||||
expect(isDriverRegisteredForRaceUseCase.execute).toHaveBeenCalledWith(query);
|
||||
expect(logger.debug).toHaveBeenCalledWith('Checking driver registration status:', query);
|
||||
expect(result).toEqual(mockViewModel);
|
||||
expect(result).toEqual(mockOutput);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -13,15 +13,14 @@ import { GetDriversLeaderboardUseCase } from '@core/racing/application/use-cases
|
||||
import { GetTotalDriversUseCase } from '@core/racing/application/use-cases/GetTotalDriversUseCase';
|
||||
import { CompleteDriverOnboardingUseCase } from '@core/racing/application/use-cases/CompleteDriverOnboardingUseCase';
|
||||
import { IsDriverRegisteredForRaceUseCase } from '@core/racing/application/use-cases/IsDriverRegisteredForRaceUseCase';
|
||||
import { GetProfileOverviewUseCase } from '@core/racing/application/use-cases/GetProfileOverviewUseCase';
|
||||
|
||||
// Presenters
|
||||
import { DriversLeaderboardPresenter } from './presenters/DriversLeaderboardPresenter';
|
||||
import { DriverStatsPresenter } from './presenters/DriverStatsPresenter';
|
||||
import { CompleteOnboardingPresenter } from './presenters/CompleteOnboardingPresenter';
|
||||
import { DriverRegistrationStatusPresenter } from './presenters/DriverRegistrationStatusPresenter';
|
||||
|
||||
// Tokens
|
||||
import { GET_DRIVERS_LEADERBOARD_USE_CASE_TOKEN, GET_TOTAL_DRIVERS_USE_CASE_TOKEN, COMPLETE_DRIVER_ONBOARDING_USE_CASE_TOKEN, IS_DRIVER_REGISTERED_FOR_RACE_USE_CASE_TOKEN, UPDATE_DRIVER_PROFILE_USE_CASE_TOKEN, LOGGER_TOKEN, DRIVER_REPOSITORY_TOKEN } from './DriverProviders';
|
||||
import { GET_DRIVERS_LEADERBOARD_USE_CASE_TOKEN, GET_TOTAL_DRIVERS_USE_CASE_TOKEN, COMPLETE_DRIVER_ONBOARDING_USE_CASE_TOKEN, IS_DRIVER_REGISTERED_FOR_RACE_USE_CASE_TOKEN, UPDATE_DRIVER_PROFILE_USE_CASE_TOKEN, GET_PROFILE_OVERVIEW_USE_CASE_TOKEN, LOGGER_TOKEN, DRIVER_REPOSITORY_TOKEN } from './DriverProviders';
|
||||
import type { ProfileOverviewOutputPort } from '@core/racing/application/ports/output/ProfileOverviewOutputPort';
|
||||
import type { Logger } from '@core/shared/application';
|
||||
import { IDriverRepository } from '@core/racing/domain/repositories/IDriverRepository';
|
||||
import { UpdateDriverProfileUseCase } from '@core/racing/application/use-cases/UpdateDriverProfileUseCase';
|
||||
@@ -34,6 +33,7 @@ export class DriverService {
|
||||
@Inject(COMPLETE_DRIVER_ONBOARDING_USE_CASE_TOKEN) private readonly completeDriverOnboardingUseCase: CompleteDriverOnboardingUseCase,
|
||||
@Inject(IS_DRIVER_REGISTERED_FOR_RACE_USE_CASE_TOKEN) private readonly isDriverRegisteredForRaceUseCase: IsDriverRegisteredForRaceUseCase,
|
||||
@Inject(UPDATE_DRIVER_PROFILE_USE_CASE_TOKEN) private readonly updateDriverProfileUseCase: UpdateDriverProfileUseCase,
|
||||
@Inject(GET_PROFILE_OVERVIEW_USE_CASE_TOKEN) private readonly getProfileOverviewUseCase: GetProfileOverviewUseCase,
|
||||
@Inject(DRIVER_REPOSITORY_TOKEN) private readonly driverRepository: IDriverRepository,
|
||||
@Inject(LOGGER_TOKEN) private readonly logger: Logger,
|
||||
) {}
|
||||
@@ -41,24 +41,31 @@ export class DriverService {
|
||||
async getDriversLeaderboard(): Promise<DriversLeaderboardDTO> {
|
||||
this.logger.debug('[DriverService] Fetching drivers leaderboard.');
|
||||
|
||||
const presenter = new DriversLeaderboardPresenter();
|
||||
await this.getDriversLeaderboardUseCase.execute(undefined, presenter);
|
||||
return presenter.viewModel;
|
||||
const result = await this.getDriversLeaderboardUseCase.execute();
|
||||
if (result.isOk()) {
|
||||
return result.value as DriversLeaderboardDTO;
|
||||
} else {
|
||||
throw new Error(`Failed to fetch drivers leaderboard: ${result.error.details.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async getTotalDrivers(): Promise<DriverStatsDTO> {
|
||||
this.logger.debug('[DriverService] Fetching total drivers count.');
|
||||
|
||||
const result = await this.getTotalDriversUseCase.execute();
|
||||
if (result.isErr()) {
|
||||
throw new Error(result.unwrapErr().code);
|
||||
}
|
||||
|
||||
const presenter = new DriverStatsPresenter();
|
||||
await this.getTotalDriversUseCase.execute(undefined, presenter);
|
||||
presenter.present(result.unwrap());
|
||||
return presenter.viewModel;
|
||||
}
|
||||
|
||||
async completeOnboarding(userId: string, input: CompleteOnboardingInputDTO): Promise<CompleteOnboardingOutputDTO> {
|
||||
this.logger.debug('Completing onboarding for user:', userId);
|
||||
|
||||
const presenter = new CompleteOnboardingPresenter();
|
||||
await this.completeDriverOnboardingUseCase.execute({
|
||||
const result = await this.completeDriverOnboardingUseCase.execute({
|
||||
userId,
|
||||
firstName: input.firstName,
|
||||
lastName: input.lastName,
|
||||
@@ -66,16 +73,31 @@ export class DriverService {
|
||||
country: input.country,
|
||||
timezone: input.timezone,
|
||||
bio: input.bio,
|
||||
}, presenter);
|
||||
return presenter.viewModel;
|
||||
});
|
||||
|
||||
if (result.isOk()) {
|
||||
return {
|
||||
success: true,
|
||||
driverId: result.value.driverId,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
success: false,
|
||||
errorMessage: result.error.code,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
async getDriverRegistrationStatus(query: GetDriverRegistrationStatusQueryDTO): Promise<DriverRegistrationStatusDTO> {
|
||||
this.logger.debug('Checking driver registration status:', query);
|
||||
|
||||
const presenter = new DriverRegistrationStatusPresenter();
|
||||
await this.isDriverRegisteredForRaceUseCase.execute({ raceId: query.raceId, driverId: query.driverId }, presenter);
|
||||
return presenter.viewModel;
|
||||
const result = await this.isDriverRegisteredForRaceUseCase.execute({ raceId: query.raceId, driverId: query.driverId });
|
||||
if (result.isOk()) {
|
||||
return result.value;
|
||||
} else {
|
||||
// For now, throw error or handle appropriately. Since it's a query, perhaps return default or throw.
|
||||
throw new Error(`Failed to check registration status: ${result.error.code}`);
|
||||
}
|
||||
}
|
||||
|
||||
async getCurrentDriver(userId: string): Promise<GetDriverOutputDTO | null> {
|
||||
@@ -129,18 +151,42 @@ export class DriverService {
|
||||
async getDriverProfile(driverId: string): Promise<GetDriverProfileOutputDTO> {
|
||||
this.logger.debug(`[DriverService] Fetching driver profile for driverId: ${driverId}`);
|
||||
|
||||
// TODO: Implement proper driver profile fetching with all the detailed data
|
||||
// For now, return a placeholder structure
|
||||
const result = await this.getProfileOverviewUseCase.execute({ driverId });
|
||||
if (result.isErr()) {
|
||||
throw new Error(`Failed to fetch driver profile: ${result.error.code}`);
|
||||
}
|
||||
|
||||
const outputPort = result.value;
|
||||
return this.mapProfileOverviewToDTO(outputPort);
|
||||
}
|
||||
|
||||
private mapProfileOverviewToDTO(outputPort: ProfileOverviewOutputPort): GetDriverProfileOutputDTO {
|
||||
return {
|
||||
currentDriver: null,
|
||||
stats: null,
|
||||
finishDistribution: null,
|
||||
teamMemberships: [],
|
||||
socialSummary: {
|
||||
friendsCount: 0,
|
||||
friends: [],
|
||||
},
|
||||
extendedProfile: null,
|
||||
currentDriver: outputPort.driver ? {
|
||||
id: outputPort.driver.id,
|
||||
name: outputPort.driver.name,
|
||||
country: outputPort.driver.country,
|
||||
avatarUrl: outputPort.driver.avatarUrl,
|
||||
iracingId: outputPort.driver.iracingId,
|
||||
joinedAt: outputPort.driver.joinedAt.toISOString(),
|
||||
rating: outputPort.driver.rating,
|
||||
globalRank: outputPort.driver.globalRank,
|
||||
consistency: outputPort.driver.consistency,
|
||||
bio: outputPort.driver.bio,
|
||||
totalDrivers: outputPort.driver.totalDrivers,
|
||||
} : null,
|
||||
stats: outputPort.stats,
|
||||
finishDistribution: outputPort.finishDistribution,
|
||||
teamMemberships: outputPort.teamMemberships.map(membership => ({
|
||||
teamId: membership.teamId,
|
||||
teamName: membership.teamName,
|
||||
teamTag: membership.teamTag,
|
||||
role: membership.role,
|
||||
joinedAt: membership.joinedAt.toISOString(),
|
||||
isCurrent: membership.isCurrent,
|
||||
})),
|
||||
socialSummary: outputPort.socialSummary,
|
||||
extendedProfile: outputPort.extendedProfile,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import { CompleteOnboardingPresenter } from './CompleteOnboardingPresenter';
|
||||
import type { CompleteDriverOnboardingResultDTO } from '../../../../../core/racing/application/presenters/ICompleteDriverOnboardingPresenter';
|
||||
|
||||
describe('CompleteOnboardingPresenter', () => {
|
||||
let presenter: CompleteOnboardingPresenter;
|
||||
|
||||
beforeEach(() => {
|
||||
presenter = new CompleteOnboardingPresenter();
|
||||
});
|
||||
|
||||
describe('present', () => {
|
||||
it('should map successful core DTO to API view model', () => {
|
||||
const dto: CompleteDriverOnboardingResultDTO = {
|
||||
success: true,
|
||||
driverId: 'driver-123',
|
||||
};
|
||||
|
||||
presenter.present(dto);
|
||||
|
||||
const result = presenter.viewModel;
|
||||
|
||||
expect(result).toEqual({
|
||||
success: true,
|
||||
driverId: 'driver-123',
|
||||
errorMessage: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
it('should map failed core DTO to API view model', () => {
|
||||
const dto: CompleteDriverOnboardingResultDTO = {
|
||||
success: false,
|
||||
errorMessage: 'Driver already exists',
|
||||
};
|
||||
|
||||
presenter.present(dto);
|
||||
|
||||
const result = presenter.viewModel;
|
||||
|
||||
expect(result).toEqual({
|
||||
success: false,
|
||||
driverId: undefined,
|
||||
errorMessage: 'Driver already exists',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('reset', () => {
|
||||
it('should reset the result', () => {
|
||||
const dto: CompleteDriverOnboardingResultDTO = {
|
||||
success: true,
|
||||
driverId: 'driver-123',
|
||||
};
|
||||
|
||||
presenter.present(dto);
|
||||
expect(presenter.viewModel).toBeDefined();
|
||||
|
||||
presenter.reset();
|
||||
expect(() => presenter.viewModel).toThrow('Presenter not presented');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,23 +0,0 @@
|
||||
import { CompleteOnboardingOutputDTO } from '../dtos/CompleteOnboardingOutputDTO';
|
||||
import type { ICompleteDriverOnboardingPresenter, CompleteDriverOnboardingResultDTO } from '../../../../../core/racing/application/presenters/ICompleteDriverOnboardingPresenter';
|
||||
|
||||
export class CompleteOnboardingPresenter implements ICompleteDriverOnboardingPresenter {
|
||||
private result: CompleteOnboardingOutputDTO | null = null;
|
||||
|
||||
reset() {
|
||||
this.result = null;
|
||||
}
|
||||
|
||||
present(dto: CompleteDriverOnboardingResultDTO) {
|
||||
this.result = {
|
||||
success: dto.success,
|
||||
driverId: dto.driverId,
|
||||
errorMessage: dto.errorMessage,
|
||||
};
|
||||
}
|
||||
|
||||
get viewModel(): CompleteOnboardingOutputDTO {
|
||||
if (!this.result) throw new Error('Presenter not presented');
|
||||
return this.result;
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
import { DriverRegistrationStatusDTO } from '../dtos/DriverRegistrationStatusDTO';
|
||||
import type { IDriverRegistrationStatusPresenter } from '../../../../../core/racing/application/presenters/IDriverRegistrationStatusPresenter';
|
||||
|
||||
export class DriverRegistrationStatusPresenter implements IDriverRegistrationStatusPresenter {
|
||||
private result: DriverRegistrationStatusDTO | null = null;
|
||||
|
||||
present(isRegistered: boolean, raceId: string, driverId: string) {
|
||||
this.result = {
|
||||
isRegistered,
|
||||
raceId,
|
||||
driverId,
|
||||
};
|
||||
}
|
||||
|
||||
getViewModel(): DriverRegistrationStatusDTO {
|
||||
if (!this.result) throw new Error('Presenter not presented');
|
||||
return this.result;
|
||||
}
|
||||
|
||||
// For consistency with other presenters
|
||||
reset() {
|
||||
this.result = null;
|
||||
}
|
||||
|
||||
get viewModel(): DriverRegistrationStatusDTO {
|
||||
return this.getViewModel();
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,16 @@
|
||||
import { DriverStatsDTO } from '../dtos/DriverStatsDTO';
|
||||
import type { ITotalDriversPresenter, TotalDriversResultDTO } from '../../../../../core/racing/application/presenters/ITotalDriversPresenter';
|
||||
import type { TotalDriversOutputPort } from '../../../../../core/racing/application/ports/output/TotalDriversOutputPort';
|
||||
|
||||
export class DriverStatsPresenter implements ITotalDriversPresenter {
|
||||
export class DriverStatsPresenter {
|
||||
private result: DriverStatsDTO | null = null;
|
||||
|
||||
reset() {
|
||||
this.result = null;
|
||||
}
|
||||
|
||||
present(dto: TotalDriversResultDTO) {
|
||||
present(output: TotalDriversOutputPort) {
|
||||
this.result = {
|
||||
totalDrivers: dto.totalDrivers,
|
||||
totalDrivers: output.totalDrivers,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user