refactor use cases
This commit is contained in:
@@ -28,7 +28,7 @@ import { SponsorRaceDTO } from './dtos/RaceDTO';
|
||||
import { SponsorProfileDTO } from './dtos/SponsorProfileDTO';
|
||||
import { NotificationSettingsDTO } from './dtos/NotificationSettingsDTO';
|
||||
import { PrivacySettingsDTO } from './dtos/PrivacySettingsDTO';
|
||||
import type { AcceptSponsorshipRequestResultViewModel } from './presenters/AcceptSponsorshipRequestPresenter';
|
||||
import { AcceptSponsorshipRequestResultViewModel } from './presenters/AcceptSponsorshipRequestPresenter';
|
||||
import type { RejectSponsorshipRequestResult } from '@core/racing/application/use-cases/RejectSponsorshipRequestUseCase';
|
||||
|
||||
@ApiTags('sponsors')
|
||||
@@ -166,7 +166,7 @@ export class SponsorController {
|
||||
async acceptSponsorshipRequest(
|
||||
@Param('requestId') requestId: string,
|
||||
@Body() input: AcceptSponsorshipRequestInputDTO,
|
||||
): Promise<AcceptSponsorshipRequestResultViewModel | null> {
|
||||
): Promise<AcceptSponsorshipRequestResultViewModel> {
|
||||
return await this.sponsorService.acceptSponsorshipRequest(
|
||||
requestId,
|
||||
input.respondedBy,
|
||||
@@ -185,7 +185,7 @@ export class SponsorController {
|
||||
async rejectSponsorshipRequest(
|
||||
@Param('requestId') requestId: string,
|
||||
@Body() input: RejectSponsorshipRequestInputDTO,
|
||||
): Promise<RejectSponsorshipRequestResult | null> {
|
||||
): Promise<RejectSponsorshipRequestResult> {
|
||||
return await this.sponsorService.rejectSponsorshipRequest(
|
||||
requestId,
|
||||
input.respondedBy,
|
||||
@@ -219,9 +219,13 @@ export class SponsorController {
|
||||
description: 'Available leagues',
|
||||
type: [AvailableLeagueDTO],
|
||||
})
|
||||
async getAvailableLeagues(): Promise<AvailableLeagueDTO[] | null> {
|
||||
async getAvailableLeagues(): Promise<AvailableLeagueDTO[]> {
|
||||
const presenter = await this.sponsorService.getAvailableLeagues();
|
||||
return presenter.viewModel;
|
||||
const viewModel = presenter.viewModel;
|
||||
if (!viewModel) {
|
||||
throw new Error('Available leagues not found');
|
||||
}
|
||||
return viewModel;
|
||||
}
|
||||
|
||||
@Get('leagues/:leagueId/detail')
|
||||
@@ -236,9 +240,13 @@ export class SponsorController {
|
||||
league: LeagueDetailDTO;
|
||||
drivers: SponsorDriverDTO[];
|
||||
races: SponsorRaceDTO[];
|
||||
} | null> {
|
||||
}> {
|
||||
const presenter = await this.sponsorService.getLeagueDetail(leagueId);
|
||||
return presenter.viewModel;
|
||||
const viewModel = presenter.viewModel;
|
||||
if (!viewModel) {
|
||||
throw new Error('League detail not found');
|
||||
}
|
||||
return viewModel;
|
||||
}
|
||||
|
||||
@Get('settings/:sponsorId')
|
||||
@@ -253,9 +261,13 @@ export class SponsorController {
|
||||
profile: SponsorProfileDTO;
|
||||
notifications: NotificationSettingsDTO;
|
||||
privacy: PrivacySettingsDTO;
|
||||
} | null> {
|
||||
}> {
|
||||
const presenter = await this.sponsorService.getSponsorSettings(sponsorId);
|
||||
return presenter.viewModel;
|
||||
const viewModel = presenter.viewModel;
|
||||
if (!viewModel) {
|
||||
throw new Error('Sponsor settings not found');
|
||||
}
|
||||
return viewModel;
|
||||
}
|
||||
|
||||
@Put('settings/:sponsorId')
|
||||
@@ -273,8 +285,12 @@ export class SponsorController {
|
||||
notifications?: Partial<NotificationSettingsDTO>;
|
||||
privacy?: Partial<PrivacySettingsDTO>;
|
||||
},
|
||||
): Promise<{ success: boolean; errorCode?: string; message?: string } | null> {
|
||||
): Promise<{ success: boolean; errorCode?: string; message?: string }> {
|
||||
const presenter = await this.sponsorService.updateSponsorSettings(sponsorId, input);
|
||||
return presenter.viewModel;
|
||||
const viewModel = presenter.viewModel;
|
||||
if (!viewModel) {
|
||||
throw new Error('Update failed');
|
||||
}
|
||||
return viewModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,6 @@ import { SponsorService } from './SponsorService';
|
||||
import type { NotificationService } from '@core/notifications/application/ports/NotificationService';
|
||||
import type { IPaymentRepository } from '@core/payments/domain/repositories/IPaymentRepository';
|
||||
import type { IWalletRepository } from '@core/payments/domain/repositories/IWalletRepository';
|
||||
// Remove the missing import
|
||||
// import { IPaymentGateway } from '@core/payments/domain/ports/IPaymentGateway';
|
||||
import { ILeagueMembershipRepository } from '@core/racing/domain/repositories/ILeagueMembershipRepository';
|
||||
import { ILeagueRepository } from '@core/racing/domain/repositories/ILeagueRepository';
|
||||
import { ILeagueWalletRepository } from '@core/racing/domain/repositories/ILeagueWalletRepository';
|
||||
@@ -16,7 +14,7 @@ import { ISeasonSponsorshipRepository } from '@core/racing/domain/repositories/I
|
||||
import { ISponsorRepository } from '@core/racing/domain/repositories/ISponsorRepository';
|
||||
import { ISponsorshipPricingRepository } from '@core/racing/domain/repositories/ISponsorshipPricingRepository';
|
||||
import { ISponsorshipRequestRepository } from '@core/racing/domain/repositories/ISponsorshipRequestRepository';
|
||||
import type { Logger, UseCaseOutputPort } from '@core/shared/application';
|
||||
import type { Logger } from '@core/shared/application';
|
||||
|
||||
import { GetSponsorBillingUseCase } from '@core/payments/application/use-cases/GetSponsorBillingUseCase';
|
||||
import { AcceptSponsorshipRequestUseCase } from '@core/racing/application/use-cases/AcceptSponsorshipRequestUseCase';
|
||||
@@ -24,7 +22,6 @@ import { CreateSponsorUseCase } from '@core/racing/application/use-cases/CreateS
|
||||
import { GetEntitySponsorshipPricingUseCase } from '@core/racing/application/use-cases/GetEntitySponsorshipPricingUseCase';
|
||||
import { GetPendingSponsorshipRequestsUseCase } from '@core/racing/application/use-cases/GetPendingSponsorshipRequestsUseCase';
|
||||
import { GetSponsorDashboardUseCase } from '@core/racing/application/use-cases/GetSponsorDashboardUseCase';
|
||||
import { GetSponsorshipPricingUseCase } from '@core/racing/application/use-cases/GetSponsorshipPricingUseCase';
|
||||
import { GetSponsorSponsorshipsUseCase } from '@core/racing/application/use-cases/GetSponsorSponsorshipsUseCase';
|
||||
import { GetSponsorsUseCase } from '@core/racing/application/use-cases/GetSponsorsUseCase';
|
||||
import { GetSponsorUseCase } from '@core/racing/application/use-cases/GetSponsorUseCase';
|
||||
@@ -35,18 +32,6 @@ import { ConsoleLogger } from '@adapters/logging/ConsoleLogger';
|
||||
import { InMemoryPaymentRepository } from '@adapters/payments/persistence/inmemory/InMemoryPaymentRepository';
|
||||
import { InMemoryWalletRepository } from '@adapters/payments/persistence/inmemory/InMemoryWalletRepository';
|
||||
|
||||
// Import presenters
|
||||
import { GetEntitySponsorshipPricingPresenter } from './presenters/GetEntitySponsorshipPricingPresenter';
|
||||
import { GetSponsorsPresenter } from './presenters/GetSponsorsPresenter';
|
||||
import { CreateSponsorPresenter } from './presenters/CreateSponsorPresenter';
|
||||
import { GetSponsorDashboardPresenter } from './presenters/GetSponsorDashboardPresenter';
|
||||
import { GetSponsorSponsorshipsPresenter } from './presenters/GetSponsorSponsorshipsPresenter';
|
||||
import { GetSponsorPresenter } from './presenters/GetSponsorPresenter';
|
||||
import { GetPendingSponsorshipRequestsPresenter } from './presenters/GetPendingSponsorshipRequestsPresenter';
|
||||
import { AcceptSponsorshipRequestPresenter } from './presenters/AcceptSponsorshipRequestPresenter';
|
||||
import { RejectSponsorshipRequestPresenter } from './presenters/RejectSponsorshipRequestPresenter';
|
||||
import { SponsorBillingPresenter } from './presenters/SponsorBillingPresenter';
|
||||
|
||||
// Define injection tokens
|
||||
export const SPONSOR_REPOSITORY_TOKEN = 'ISponsorRepository';
|
||||
export const SEASON_SPONSORSHIP_REPOSITORY_TOKEN = 'ISeasonSponsorshipRepository';
|
||||
@@ -62,20 +47,7 @@ export const LEAGUE_WALLET_REPOSITORY_TOKEN = 'ILeagueWalletRepository';
|
||||
export const NOTIFICATION_SERVICE_TOKEN = 'INotificationService';
|
||||
export const LOGGER_TOKEN = 'Logger';
|
||||
|
||||
// Presenter tokens
|
||||
export const GET_ENTITY_SPONSORSHIP_PRICING_PRESENTER_TOKEN = 'GetEntitySponsorshipPricingPresenter';
|
||||
export const GET_SPONSORS_PRESENTER_TOKEN = 'GetSponsorsPresenter';
|
||||
export const CREATE_SPONSOR_PRESENTER_TOKEN = 'CreateSponsorPresenter';
|
||||
export const GET_SPONSOR_DASHBOARD_PRESENTER_TOKEN = 'GetSponsorDashboardPresenter';
|
||||
export const GET_SPONSOR_SPONSORSHIPS_PRESENTER_TOKEN = 'GetSponsorSponsorshipsPresenter';
|
||||
export const GET_SPONSOR_PRESENTER_TOKEN = 'GetSponsorPresenter';
|
||||
export const GET_PENDING_SPONSORSHIP_REQUESTS_PRESENTER_TOKEN = 'GetPendingSponsorshipRequestsPresenter';
|
||||
export const ACCEPT_SPONSORSHIP_REQUEST_PRESENTER_TOKEN = 'AcceptSponsorshipRequestPresenter';
|
||||
export const REJECT_SPONSORSHIP_REQUEST_PRESENTER_TOKEN = 'RejectSponsorshipRequestPresenter';
|
||||
export const GET_SPONSOR_BILLING_PRESENTER_TOKEN = 'SponsorBillingPresenter';
|
||||
|
||||
// Use case / application service tokens
|
||||
export const GET_SPONSORSHIP_PRICING_USE_CASE_TOKEN = 'GetSponsorshipPricingUseCase';
|
||||
export const GET_SPONSORS_USE_CASE_TOKEN = 'GetSponsorsUseCase';
|
||||
export const CREATE_SPONSOR_USE_CASE_TOKEN = 'CreateSponsorUseCase';
|
||||
export const GET_SPONSOR_DASHBOARD_USE_CASE_TOKEN = 'GetSponsorDashboardUseCase';
|
||||
@@ -87,19 +59,6 @@ export const ACCEPT_SPONSORSHIP_REQUEST_USE_CASE_TOKEN = 'AcceptSponsorshipReque
|
||||
export const REJECT_SPONSORSHIP_REQUEST_USE_CASE_TOKEN = 'RejectSponsorshipRequestUseCase';
|
||||
export const GET_SPONSOR_BILLING_USE_CASE_TOKEN = 'GetSponsorBillingUseCase';
|
||||
|
||||
// Output port tokens
|
||||
export const GET_SPONSORSHIP_PRICING_OUTPUT_PORT_TOKEN = 'GetSponsorshipPricingOutputPort_TOKEN';
|
||||
export const GET_SPONSORS_OUTPUT_PORT_TOKEN = 'GetSponsorsOutputPort_TOKEN';
|
||||
export const CREATE_SPONSOR_OUTPUT_PORT_TOKEN = 'CreateSponsorOutputPort_TOKEN';
|
||||
export const GET_SPONSOR_DASHBOARD_OUTPUT_PORT_TOKEN = 'GetSponsorDashboardOutputPort_TOKEN';
|
||||
export const GET_SPONSOR_SPONSORSHIPS_OUTPUT_PORT_TOKEN = 'GetSponsorSponsorshipsOutputPort_TOKEN';
|
||||
export const GET_ENTITY_SPONSORSHIP_PRICING_OUTPUT_PORT_TOKEN = 'GetEntitySponsorshipPricingOutputPort_TOKEN';
|
||||
export const GET_SPONSOR_OUTPUT_PORT_TOKEN = 'GetSponsorOutputPort_TOKEN';
|
||||
export const GET_PENDING_SPONSORSHIP_REQUESTS_OUTPUT_PORT_TOKEN = 'GetPendingSponsorshipRequestsOutputPort_TOKEN';
|
||||
export const ACCEPT_SPONSORSHIP_REQUEST_OUTPUT_PORT_TOKEN = 'AcceptSponsorshipRequestOutputPort_TOKEN';
|
||||
export const REJECT_SPONSORSHIP_REQUEST_OUTPUT_PORT_TOKEN = 'RejectSponsorshipRequestOutputPort_TOKEN';
|
||||
export const GET_SPONSOR_BILLING_OUTPUT_PORT_TOKEN = 'GetSponsorBillingOutputPort_TOKEN';
|
||||
|
||||
export const SponsorProviders: Provider[] = [
|
||||
SponsorService,
|
||||
// Repositories (payments repos are local to this module; racing repos come from InMemoryRacingPersistenceModule)
|
||||
@@ -126,77 +85,16 @@ export const SponsorProviders: Provider[] = [
|
||||
provide: LOGGER_TOKEN,
|
||||
useClass: ConsoleLogger,
|
||||
},
|
||||
// Presenters
|
||||
GetEntitySponsorshipPricingPresenter,
|
||||
GetSponsorsPresenter,
|
||||
CreateSponsorPresenter,
|
||||
GetSponsorDashboardPresenter,
|
||||
GetSponsorSponsorshipsPresenter,
|
||||
GetSponsorPresenter,
|
||||
GetPendingSponsorshipRequestsPresenter,
|
||||
AcceptSponsorshipRequestPresenter,
|
||||
RejectSponsorshipRequestPresenter,
|
||||
SponsorBillingPresenter,
|
||||
// Output ports
|
||||
{
|
||||
provide: GET_SPONSORSHIP_PRICING_OUTPUT_PORT_TOKEN,
|
||||
useExisting: GetEntitySponsorshipPricingPresenter,
|
||||
},
|
||||
{
|
||||
provide: GET_ENTITY_SPONSORSHIP_PRICING_OUTPUT_PORT_TOKEN,
|
||||
useExisting: GetEntitySponsorshipPricingPresenter,
|
||||
},
|
||||
{
|
||||
provide: GET_SPONSORS_OUTPUT_PORT_TOKEN,
|
||||
useExisting: GetSponsorsPresenter,
|
||||
},
|
||||
{
|
||||
provide: CREATE_SPONSOR_OUTPUT_PORT_TOKEN,
|
||||
useExisting: CreateSponsorPresenter,
|
||||
},
|
||||
{
|
||||
provide: GET_SPONSOR_DASHBOARD_OUTPUT_PORT_TOKEN,
|
||||
useExisting: GetSponsorDashboardPresenter,
|
||||
},
|
||||
{
|
||||
provide: GET_SPONSOR_SPONSORSHIPS_OUTPUT_PORT_TOKEN,
|
||||
useExisting: GetSponsorSponsorshipsPresenter,
|
||||
},
|
||||
{
|
||||
provide: GET_SPONSOR_OUTPUT_PORT_TOKEN,
|
||||
useExisting: GetSponsorPresenter,
|
||||
},
|
||||
{
|
||||
provide: GET_PENDING_SPONSORSHIP_REQUESTS_OUTPUT_PORT_TOKEN,
|
||||
useExisting: GetPendingSponsorshipRequestsPresenter,
|
||||
},
|
||||
{
|
||||
provide: ACCEPT_SPONSORSHIP_REQUEST_OUTPUT_PORT_TOKEN,
|
||||
useExisting: AcceptSponsorshipRequestPresenter,
|
||||
},
|
||||
{
|
||||
provide: REJECT_SPONSORSHIP_REQUEST_OUTPUT_PORT_TOKEN,
|
||||
useExisting: RejectSponsorshipRequestPresenter,
|
||||
},
|
||||
{
|
||||
provide: GET_SPONSOR_BILLING_OUTPUT_PORT_TOKEN,
|
||||
useExisting: SponsorBillingPresenter,
|
||||
},
|
||||
// Use cases
|
||||
{
|
||||
provide: GET_SPONSORSHIP_PRICING_USE_CASE_TOKEN,
|
||||
useFactory: (output: UseCaseOutputPort<unknown>) => new GetSponsorshipPricingUseCase(output),
|
||||
inject: [GET_SPONSORSHIP_PRICING_OUTPUT_PORT_TOKEN],
|
||||
},
|
||||
{
|
||||
provide: GET_SPONSORS_USE_CASE_TOKEN,
|
||||
useFactory: (sponsorRepo: ISponsorRepository, output: UseCaseOutputPort<unknown>) => new GetSponsorsUseCase(sponsorRepo, output),
|
||||
inject: [SPONSOR_REPOSITORY_TOKEN, GET_SPONSORS_OUTPUT_PORT_TOKEN],
|
||||
useFactory: (sponsorRepo: ISponsorRepository) => new GetSponsorsUseCase(sponsorRepo),
|
||||
inject: [SPONSOR_REPOSITORY_TOKEN],
|
||||
},
|
||||
{
|
||||
provide: CREATE_SPONSOR_USE_CASE_TOKEN,
|
||||
useFactory: (sponsorRepo: ISponsorRepository, logger: Logger, output: UseCaseOutputPort<unknown>) => new CreateSponsorUseCase(sponsorRepo, logger, output),
|
||||
inject: [SPONSOR_REPOSITORY_TOKEN, LOGGER_TOKEN, CREATE_SPONSOR_OUTPUT_PORT_TOKEN],
|
||||
useFactory: (sponsorRepo: ISponsorRepository, logger: Logger) => new CreateSponsorUseCase(sponsorRepo, logger),
|
||||
inject: [SPONSOR_REPOSITORY_TOKEN, LOGGER_TOKEN],
|
||||
},
|
||||
{
|
||||
provide: GET_SPONSOR_DASHBOARD_USE_CASE_TOKEN,
|
||||
@@ -207,8 +105,7 @@ export const SponsorProviders: Provider[] = [
|
||||
leagueRepo: ILeagueRepository,
|
||||
leagueMembershipRepo: ILeagueMembershipRepository,
|
||||
raceRepo: IRaceRepository,
|
||||
output: UseCaseOutputPort<unknown>,
|
||||
) => new GetSponsorDashboardUseCase(sponsorRepo, seasonSponsorshipRepo, seasonRepo, leagueRepo, leagueMembershipRepo, raceRepo, output),
|
||||
) => new GetSponsorDashboardUseCase(sponsorRepo, seasonSponsorshipRepo, seasonRepo, leagueRepo, leagueMembershipRepo, raceRepo),
|
||||
inject: [
|
||||
SPONSOR_REPOSITORY_TOKEN,
|
||||
SEASON_SPONSORSHIP_REPOSITORY_TOKEN,
|
||||
@@ -216,7 +113,6 @@ export const SponsorProviders: Provider[] = [
|
||||
LEAGUE_REPOSITORY_TOKEN,
|
||||
LEAGUE_MEMBERSHIP_REPOSITORY_TOKEN,
|
||||
RACE_REPOSITORY_TOKEN,
|
||||
GET_SPONSOR_DASHBOARD_OUTPUT_PORT_TOKEN,
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -228,8 +124,7 @@ export const SponsorProviders: Provider[] = [
|
||||
leagueRepo: ILeagueRepository,
|
||||
leagueMembershipRepo: ILeagueMembershipRepository,
|
||||
raceRepo: IRaceRepository,
|
||||
output: UseCaseOutputPort<unknown>,
|
||||
) => new GetSponsorSponsorshipsUseCase(sponsorRepo, seasonSponsorshipRepo, seasonRepo, leagueRepo, leagueMembershipRepo, raceRepo, output),
|
||||
) => new GetSponsorSponsorshipsUseCase(sponsorRepo, seasonSponsorshipRepo, seasonRepo, leagueRepo, leagueMembershipRepo, raceRepo),
|
||||
inject: [
|
||||
SPONSOR_REPOSITORY_TOKEN,
|
||||
SEASON_SPONSORSHIP_REPOSITORY_TOKEN,
|
||||
@@ -237,7 +132,6 @@ export const SponsorProviders: Provider[] = [
|
||||
LEAGUE_REPOSITORY_TOKEN,
|
||||
LEAGUE_MEMBERSHIP_REPOSITORY_TOKEN,
|
||||
RACE_REPOSITORY_TOKEN,
|
||||
GET_SPONSOR_SPONSORSHIPS_OUTPUT_PORT_TOKEN,
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -255,27 +149,24 @@ export const SponsorProviders: Provider[] = [
|
||||
useFactory: (
|
||||
sponsorshipPricingRepo: ISponsorshipPricingRepository,
|
||||
logger: Logger,
|
||||
output: UseCaseOutputPort<unknown>,
|
||||
) => new GetEntitySponsorshipPricingUseCase(sponsorshipPricingRepo, logger, output),
|
||||
) => new GetEntitySponsorshipPricingUseCase(sponsorshipPricingRepo, logger),
|
||||
inject: [
|
||||
SPONSORSHIP_PRICING_REPOSITORY_TOKEN,
|
||||
LOGGER_TOKEN,
|
||||
GET_ENTITY_SPONSORSHIP_PRICING_OUTPUT_PORT_TOKEN,
|
||||
],
|
||||
},
|
||||
{
|
||||
provide: GET_SPONSOR_USE_CASE_TOKEN,
|
||||
useFactory: (sponsorRepo: ISponsorRepository, output: UseCaseOutputPort<unknown>) => new GetSponsorUseCase(sponsorRepo, output),
|
||||
inject: [SPONSOR_REPOSITORY_TOKEN, GET_SPONSOR_OUTPUT_PORT_TOKEN],
|
||||
useFactory: (sponsorRepo: ISponsorRepository) => new GetSponsorUseCase(sponsorRepo),
|
||||
inject: [SPONSOR_REPOSITORY_TOKEN],
|
||||
},
|
||||
{
|
||||
provide: GET_PENDING_SPONSORSHIP_REQUESTS_USE_CASE_TOKEN,
|
||||
useFactory: (
|
||||
sponsorshipRequestRepo: ISponsorshipRequestRepository,
|
||||
sponsorRepo: ISponsorRepository,
|
||||
output: UseCaseOutputPort<unknown>,
|
||||
) => new GetPendingSponsorshipRequestsUseCase(sponsorshipRequestRepo, sponsorRepo, output),
|
||||
inject: [SPONSORSHIP_REQUEST_REPOSITORY_TOKEN, SPONSOR_REPOSITORY_TOKEN, GET_PENDING_SPONSORSHIP_REQUESTS_OUTPUT_PORT_TOKEN],
|
||||
) => new GetPendingSponsorshipRequestsUseCase(sponsorshipRequestRepo, sponsorRepo),
|
||||
inject: [SPONSORSHIP_REQUEST_REPOSITORY_TOKEN, SPONSOR_REPOSITORY_TOKEN],
|
||||
},
|
||||
{
|
||||
provide: ACCEPT_SPONSORSHIP_REQUEST_USE_CASE_TOKEN,
|
||||
@@ -287,7 +178,6 @@ export const SponsorProviders: Provider[] = [
|
||||
walletRepository: IWalletRepository,
|
||||
leagueWalletRepository: ILeagueWalletRepository,
|
||||
logger: Logger,
|
||||
output: UseCaseOutputPort<unknown>,
|
||||
) => {
|
||||
// Create a mock payment processor function
|
||||
const paymentProcessor = async (input: unknown) => {
|
||||
@@ -303,8 +193,7 @@ export const SponsorProviders: Provider[] = [
|
||||
paymentProcessor,
|
||||
walletRepository,
|
||||
leagueWalletRepository,
|
||||
logger,
|
||||
output
|
||||
logger
|
||||
);
|
||||
},
|
||||
inject: [
|
||||
@@ -315,7 +204,6 @@ export const SponsorProviders: Provider[] = [
|
||||
WALLET_REPOSITORY_TOKEN,
|
||||
LEAGUE_WALLET_REPOSITORY_TOKEN,
|
||||
LOGGER_TOKEN,
|
||||
ACCEPT_SPONSORSHIP_REQUEST_OUTPUT_PORT_TOKEN,
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -323,8 +211,7 @@ export const SponsorProviders: Provider[] = [
|
||||
useFactory: (
|
||||
sponsorshipRequestRepo: ISponsorshipRequestRepository,
|
||||
logger: Logger,
|
||||
output: UseCaseOutputPort<unknown>,
|
||||
) => new RejectSponsorshipRequestUseCase(sponsorshipRequestRepo, logger, output),
|
||||
inject: [SPONSORSHIP_REQUEST_REPOSITORY_TOKEN, LOGGER_TOKEN, REJECT_SPONSORSHIP_REQUEST_OUTPUT_PORT_TOKEN],
|
||||
) => new RejectSponsorshipRequestUseCase(sponsorshipRequestRepo, logger),
|
||||
inject: [SPONSORSHIP_REQUEST_REPOSITORY_TOKEN, LOGGER_TOKEN],
|
||||
},
|
||||
];
|
||||
@@ -3,7 +3,7 @@ import type { AcceptSponsorshipRequestUseCase } from '@core/racing/application/u
|
||||
import type { CreateSponsorUseCase } from '@core/racing/application/use-cases/CreateSponsorUseCase';
|
||||
import type { GetPendingSponsorshipRequestsUseCase } from '@core/racing/application/use-cases/GetPendingSponsorshipRequestsUseCase';
|
||||
import type { GetSponsorDashboardInput, GetSponsorDashboardUseCase } from '@core/racing/application/use-cases/GetSponsorDashboardUseCase';
|
||||
import type { GetSponsorshipPricingUseCase } from '@core/racing/application/use-cases/GetSponsorshipPricingUseCase';
|
||||
import type { GetEntitySponsorshipPricingUseCase } from '@core/racing/application/use-cases/GetEntitySponsorshipPricingUseCase';
|
||||
import type { GetSponsorSponsorshipsInput, GetSponsorSponsorshipsUseCase } from '@core/racing/application/use-cases/GetSponsorSponsorshipsUseCase';
|
||||
import type { GetSponsorsUseCase } from '@core/racing/application/use-cases/GetSponsorsUseCase';
|
||||
import type { GetSponsorUseCase } from '@core/racing/application/use-cases/GetSponsorUseCase';
|
||||
@@ -14,21 +14,11 @@ import { beforeEach, describe, expect, it, Mock, vi } from 'vitest';
|
||||
import type { CreateSponsorInputDTO } from './dtos/CreateSponsorInputDTO';
|
||||
import { Sponsor } from '@core/racing/domain/entities/sponsor/Sponsor';
|
||||
import { Money } from '@core/racing/domain/value-objects/Money';
|
||||
import { AcceptSponsorshipRequestPresenter } from './presenters/AcceptSponsorshipRequestPresenter';
|
||||
import { CreateSponsorPresenter } from './presenters/CreateSponsorPresenter';
|
||||
import { GetEntitySponsorshipPricingPresenter } from './presenters/GetEntitySponsorshipPricingPresenter';
|
||||
import { GetPendingSponsorshipRequestsPresenter } from './presenters/GetPendingSponsorshipRequestsPresenter';
|
||||
import { GetSponsorDashboardPresenter } from './presenters/GetSponsorDashboardPresenter';
|
||||
import { GetSponsorPresenter } from './presenters/GetSponsorPresenter';
|
||||
import { GetSponsorSponsorshipsPresenter } from './presenters/GetSponsorSponsorshipsPresenter';
|
||||
import { GetSponsorsPresenter } from './presenters/GetSponsorsPresenter';
|
||||
import { RejectSponsorshipRequestPresenter } from './presenters/RejectSponsorshipRequestPresenter';
|
||||
import { SponsorBillingPresenter } from './presenters/SponsorBillingPresenter';
|
||||
import { SponsorService } from './SponsorService';
|
||||
|
||||
describe('SponsorService', () => {
|
||||
let service: SponsorService;
|
||||
let getSponsorshipPricingUseCase: { execute: Mock };
|
||||
let getEntitySponsorshipPricingUseCase: { execute: Mock };
|
||||
let getSponsorsUseCase: { execute: Mock };
|
||||
let createSponsorUseCase: { execute: Mock };
|
||||
let getSponsorDashboardUseCase: { execute: Mock };
|
||||
@@ -40,20 +30,8 @@ describe('SponsorService', () => {
|
||||
let getSponsorBillingUseCase: { execute: Mock };
|
||||
let logger: Logger;
|
||||
|
||||
// Presenters
|
||||
let getEntitySponsorshipPricingPresenter: GetEntitySponsorshipPricingPresenter;
|
||||
let getSponsorsPresenter: GetSponsorsPresenter;
|
||||
let createSponsorPresenter: CreateSponsorPresenter;
|
||||
let getSponsorDashboardPresenter: GetSponsorDashboardPresenter;
|
||||
let getSponsorSponsorshipsPresenter: GetSponsorSponsorshipsPresenter;
|
||||
let getSponsorPresenter: GetSponsorPresenter;
|
||||
let getPendingSponsorshipRequestsPresenter: GetPendingSponsorshipRequestsPresenter;
|
||||
let acceptSponsorshipRequestPresenter: AcceptSponsorshipRequestPresenter;
|
||||
let rejectSponsorshipRequestPresenter: RejectSponsorshipRequestPresenter;
|
||||
let sponsorBillingPresenter: SponsorBillingPresenter;
|
||||
|
||||
beforeEach(() => {
|
||||
getSponsorshipPricingUseCase = { execute: vi.fn() };
|
||||
getEntitySponsorshipPricingUseCase = { execute: vi.fn() };
|
||||
getSponsorsUseCase = { execute: vi.fn() };
|
||||
createSponsorUseCase = { execute: vi.fn() };
|
||||
getSponsorDashboardUseCase = { execute: vi.fn() };
|
||||
@@ -70,20 +48,8 @@ describe('SponsorService', () => {
|
||||
error: vi.fn(),
|
||||
} as unknown as Logger;
|
||||
|
||||
// Initialize presenters
|
||||
getEntitySponsorshipPricingPresenter = new GetEntitySponsorshipPricingPresenter();
|
||||
getSponsorsPresenter = new GetSponsorsPresenter();
|
||||
createSponsorPresenter = new CreateSponsorPresenter();
|
||||
getSponsorDashboardPresenter = new GetSponsorDashboardPresenter();
|
||||
getSponsorSponsorshipsPresenter = new GetSponsorSponsorshipsPresenter();
|
||||
getSponsorPresenter = new GetSponsorPresenter();
|
||||
getPendingSponsorshipRequestsPresenter = new GetPendingSponsorshipRequestsPresenter();
|
||||
acceptSponsorshipRequestPresenter = new AcceptSponsorshipRequestPresenter();
|
||||
rejectSponsorshipRequestPresenter = new RejectSponsorshipRequestPresenter();
|
||||
sponsorBillingPresenter = new SponsorBillingPresenter();
|
||||
|
||||
service = new SponsorService(
|
||||
getSponsorshipPricingUseCase as unknown as GetSponsorshipPricingUseCase,
|
||||
getEntitySponsorshipPricingUseCase as unknown as GetEntitySponsorshipPricingUseCase,
|
||||
getSponsorsUseCase as unknown as GetSponsorsUseCase,
|
||||
createSponsorUseCase as unknown as CreateSponsorUseCase,
|
||||
getSponsorDashboardUseCase as unknown as GetSponsorDashboardUseCase,
|
||||
@@ -94,31 +60,19 @@ describe('SponsorService', () => {
|
||||
rejectSponsorshipRequestUseCase as unknown as RejectSponsorshipRequestUseCase,
|
||||
getSponsorBillingUseCase as unknown as GetSponsorBillingUseCase,
|
||||
logger,
|
||||
getEntitySponsorshipPricingPresenter,
|
||||
getSponsorsPresenter,
|
||||
createSponsorPresenter,
|
||||
getSponsorDashboardPresenter,
|
||||
getSponsorSponsorshipsPresenter,
|
||||
getSponsorPresenter,
|
||||
getPendingSponsorshipRequestsPresenter,
|
||||
acceptSponsorshipRequestPresenter,
|
||||
rejectSponsorshipRequestPresenter,
|
||||
sponsorBillingPresenter,
|
||||
);
|
||||
});
|
||||
|
||||
describe('getEntitySponsorshipPricing', () => {
|
||||
it('returns pricing data on success', async () => {
|
||||
const outputPort = {
|
||||
const output = {
|
||||
entityType: 'season',
|
||||
entityId: 'season-1',
|
||||
acceptingApplications: true,
|
||||
tiers: [{ name: 'Gold', price: { amount: 500, currency: 'USD' }, benefits: ['Main slot'] }],
|
||||
};
|
||||
|
||||
getSponsorshipPricingUseCase.execute.mockImplementation(async () => {
|
||||
getEntitySponsorshipPricingPresenter.present(outputPort as any);
|
||||
return Result.ok(undefined);
|
||||
});
|
||||
getEntitySponsorshipPricingUseCase.execute.mockResolvedValue(Result.ok(output));
|
||||
|
||||
const result = await service.getEntitySponsorshipPricing();
|
||||
|
||||
@@ -130,7 +84,7 @@ describe('SponsorService', () => {
|
||||
});
|
||||
|
||||
it('returns empty pricing on error', async () => {
|
||||
getSponsorshipPricingUseCase.execute.mockResolvedValue(Result.err({ code: 'REPOSITORY_ERROR' }));
|
||||
getEntitySponsorshipPricingUseCase.execute.mockResolvedValue(Result.err({ code: 'REPOSITORY_ERROR' }));
|
||||
|
||||
const result = await service.getEntitySponsorshipPricing();
|
||||
|
||||
@@ -153,10 +107,7 @@ describe('SponsorService', () => {
|
||||
}),
|
||||
];
|
||||
|
||||
getSponsorsUseCase.execute.mockImplementation(async () => {
|
||||
getSponsorsPresenter.present(sponsors);
|
||||
return Result.ok(undefined);
|
||||
});
|
||||
getSponsorsUseCase.execute.mockResolvedValue(Result.ok({ sponsors }));
|
||||
|
||||
const result = await service.getSponsors();
|
||||
|
||||
@@ -191,10 +142,7 @@ describe('SponsorService', () => {
|
||||
createdAt: new Date('2024-01-01T00:00:00Z'),
|
||||
});
|
||||
|
||||
createSponsorUseCase.execute.mockImplementation(async () => {
|
||||
createSponsorPresenter.present(sponsor);
|
||||
return Result.ok(undefined);
|
||||
});
|
||||
createSponsorUseCase.execute.mockResolvedValue(Result.ok({ sponsor }));
|
||||
|
||||
const result = await service.createSponsor(input);
|
||||
|
||||
@@ -235,7 +183,7 @@ describe('SponsorService', () => {
|
||||
describe('getSponsorDashboard', () => {
|
||||
it('returns dashboard on success', async () => {
|
||||
const params: GetSponsorDashboardInput = { sponsorId: 's1' };
|
||||
const outputPort = {
|
||||
const output = {
|
||||
sponsorId: 's1',
|
||||
sponsorName: 'S1',
|
||||
metrics: {
|
||||
@@ -254,19 +202,25 @@ describe('SponsorService', () => {
|
||||
totalInvestment: Money.create(0, 'USD'),
|
||||
costPerThousandViews: 0,
|
||||
},
|
||||
sponsorships: {
|
||||
leagues: [],
|
||||
teams: [],
|
||||
drivers: [],
|
||||
races: [],
|
||||
platform: [],
|
||||
},
|
||||
recentActivity: [],
|
||||
upcomingRenewals: [],
|
||||
};
|
||||
|
||||
getSponsorDashboardUseCase.execute.mockImplementation(async () => {
|
||||
getSponsorDashboardPresenter.present(outputPort as any);
|
||||
return Result.ok(undefined);
|
||||
});
|
||||
getSponsorDashboardUseCase.execute.mockResolvedValue(Result.ok(output));
|
||||
|
||||
const result = await service.getSponsorDashboard(params);
|
||||
|
||||
expect(result).toEqual({
|
||||
sponsorId: 's1',
|
||||
sponsorName: 'S1',
|
||||
metrics: outputPort.metrics,
|
||||
metrics: output.metrics,
|
||||
sponsoredLeagues: [],
|
||||
investment: {
|
||||
activeSponsorships: 0,
|
||||
@@ -296,7 +250,7 @@ describe('SponsorService', () => {
|
||||
describe('getSponsorSponsorships', () => {
|
||||
it('returns sponsorships on success', async () => {
|
||||
const params: GetSponsorSponsorshipsInput = { sponsorId: 's1' };
|
||||
const outputPort = {
|
||||
const output = {
|
||||
sponsor: Sponsor.create({
|
||||
id: 's1',
|
||||
name: 'S1',
|
||||
@@ -311,10 +265,7 @@ describe('SponsorService', () => {
|
||||
},
|
||||
};
|
||||
|
||||
getSponsorSponsorshipsUseCase.execute.mockImplementation(async () => {
|
||||
getSponsorSponsorshipsPresenter.present(outputPort as any);
|
||||
return Result.ok(undefined);
|
||||
});
|
||||
getSponsorSponsorshipsUseCase.execute.mockResolvedValue(Result.ok(output));
|
||||
|
||||
const result = await service.getSponsorSponsorships(params);
|
||||
|
||||
@@ -345,16 +296,25 @@ describe('SponsorService', () => {
|
||||
describe('getSponsor', () => {
|
||||
it('returns sponsor when found', async () => {
|
||||
const sponsorId = 's1';
|
||||
const output = { sponsor: { id: sponsorId, name: 'S1' } };
|
||||
|
||||
getSponsorUseCase.execute.mockImplementation(async () => {
|
||||
getSponsorPresenter.present(output);
|
||||
return Result.ok(undefined);
|
||||
const sponsor = Sponsor.create({
|
||||
id: sponsorId,
|
||||
name: 'S1',
|
||||
contactEmail: 's1@example.com',
|
||||
createdAt: new Date('2024-01-01T00:00:00Z'),
|
||||
});
|
||||
|
||||
getSponsorUseCase.execute.mockResolvedValue(Result.ok({ sponsor }));
|
||||
|
||||
const result = await service.getSponsor(sponsorId);
|
||||
|
||||
expect(result).toEqual(output);
|
||||
expect(result).toEqual({
|
||||
sponsor: {
|
||||
id: sponsorId,
|
||||
name: 'S1',
|
||||
logoUrl: undefined,
|
||||
websiteUrl: undefined,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('throws when not found', async () => {
|
||||
@@ -375,21 +335,18 @@ describe('SponsorService', () => {
|
||||
describe('getPendingSponsorshipRequests', () => {
|
||||
it('returns requests on success', async () => {
|
||||
const params = { entityType: 'season' as const, entityId: 'season-1' };
|
||||
const outputPort = {
|
||||
const output = {
|
||||
entityType: 'season',
|
||||
entityId: 'season-1',
|
||||
requests: [],
|
||||
totalCount: 0,
|
||||
};
|
||||
|
||||
getPendingSponsorshipRequestsUseCase.execute.mockImplementation(async () => {
|
||||
getPendingSponsorshipRequestsPresenter.present(outputPort as any);
|
||||
return Result.ok(undefined);
|
||||
});
|
||||
getPendingSponsorshipRequestsUseCase.execute.mockResolvedValue(Result.ok(output));
|
||||
|
||||
const result = await service.getPendingSponsorshipRequests(params);
|
||||
|
||||
expect(result).toEqual(outputPort);
|
||||
expect(result).toEqual(output);
|
||||
});
|
||||
|
||||
it('returns empty result on error', async () => {
|
||||
@@ -405,20 +362,13 @@ describe('SponsorService', () => {
|
||||
totalCount: 0,
|
||||
});
|
||||
});
|
||||
|
||||
it('throws when presenter viewModel is missing on success', async () => {
|
||||
const params = { entityType: 'season' as const, entityId: 'season-1' };
|
||||
getPendingSponsorshipRequestsUseCase.execute.mockResolvedValue(Result.ok(undefined));
|
||||
|
||||
await expect(service.getPendingSponsorshipRequests(params)).rejects.toThrow('Pending sponsorship requests not found');
|
||||
});
|
||||
});
|
||||
|
||||
describe('SponsorshipRequest', () => {
|
||||
it('returns accept result on success', async () => {
|
||||
const requestId = 'r1';
|
||||
const respondedBy = 'u1';
|
||||
const outputPort = {
|
||||
const output = {
|
||||
requestId,
|
||||
sponsorshipId: 'sp1',
|
||||
status: 'accepted' as const,
|
||||
@@ -427,14 +377,11 @@ describe('SponsorService', () => {
|
||||
netAmount: 90,
|
||||
};
|
||||
|
||||
acceptSponsorshipRequestUseCase.execute.mockImplementation(async () => {
|
||||
acceptSponsorshipRequestPresenter.present(outputPort as any);
|
||||
return Result.ok(undefined);
|
||||
});
|
||||
acceptSponsorshipRequestUseCase.execute.mockResolvedValue(Result.ok(output));
|
||||
|
||||
const result = await service.acceptSponsorshipRequest(requestId, respondedBy);
|
||||
|
||||
expect(result).toEqual(outputPort);
|
||||
expect(result).toEqual(output);
|
||||
});
|
||||
|
||||
it('throws on error', async () => {
|
||||
@@ -448,16 +395,6 @@ describe('SponsorService', () => {
|
||||
'Accept sponsorship request failed',
|
||||
);
|
||||
});
|
||||
|
||||
it('throws when presenter viewModel is missing on success', async () => {
|
||||
const requestId = 'r1';
|
||||
const respondedBy = 'u1';
|
||||
acceptSponsorshipRequestUseCase.execute.mockResolvedValue(Result.ok(undefined));
|
||||
|
||||
await expect(service.acceptSponsorshipRequest(requestId, respondedBy)).rejects.toThrow(
|
||||
'Accept sponsorship request failed',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('rejectSponsorshipRequest', () => {
|
||||
@@ -472,10 +409,7 @@ describe('SponsorService', () => {
|
||||
rejectionReason: reason,
|
||||
};
|
||||
|
||||
rejectSponsorshipRequestUseCase.execute.mockImplementation(async () => {
|
||||
rejectSponsorshipRequestPresenter.present(output as any);
|
||||
return Result.ok(undefined);
|
||||
});
|
||||
rejectSponsorshipRequestUseCase.execute.mockResolvedValue(Result.ok(output));
|
||||
|
||||
const result = await service.rejectSponsorshipRequest(requestId, respondedBy, reason);
|
||||
|
||||
@@ -485,19 +419,18 @@ describe('SponsorService', () => {
|
||||
it('passes no reason when reason is undefined', async () => {
|
||||
const requestId = 'r1';
|
||||
const respondedBy = 'u1';
|
||||
const output = {
|
||||
requestId,
|
||||
status: 'rejected' as const,
|
||||
respondedAt: new Date(),
|
||||
rejectionReason: '',
|
||||
};
|
||||
|
||||
rejectSponsorshipRequestUseCase.execute.mockImplementation(async (input: any) => {
|
||||
expect(input).toEqual({ requestId, respondedBy });
|
||||
rejectSponsorshipRequestPresenter.present({
|
||||
requestId,
|
||||
status: 'rejected' as const,
|
||||
respondedAt: new Date(),
|
||||
rejectionReason: '',
|
||||
} as any);
|
||||
return Result.ok(undefined);
|
||||
});
|
||||
rejectSponsorshipRequestUseCase.execute.mockResolvedValue(Result.ok(output));
|
||||
|
||||
await expect(service.rejectSponsorshipRequest(requestId, respondedBy)).resolves.toMatchObject({
|
||||
const result = await service.rejectSponsorshipRequest(requestId, respondedBy);
|
||||
|
||||
expect(result).toMatchObject({
|
||||
requestId,
|
||||
status: 'rejected',
|
||||
});
|
||||
@@ -514,16 +447,6 @@ describe('SponsorService', () => {
|
||||
'Reject sponsorship request failed',
|
||||
);
|
||||
});
|
||||
|
||||
it('throws when presenter viewModel is missing on success', async () => {
|
||||
const requestId = 'r1';
|
||||
const respondedBy = 'u1';
|
||||
rejectSponsorshipRequestUseCase.execute.mockResolvedValue(Result.ok(undefined));
|
||||
|
||||
await expect(service.rejectSponsorshipRequest(requestId, respondedBy)).rejects.toThrow(
|
||||
'Reject sponsorship request failed',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSponsorBilling', () => {
|
||||
|
||||
@@ -21,7 +21,7 @@ import { InvoiceDTO } from './dtos/InvoiceDTO';
|
||||
import { BillingStatsDTO } from './dtos/BillingStatsDTO';
|
||||
|
||||
// Use cases
|
||||
import { GetSponsorshipPricingUseCase } from '@core/racing/application/use-cases/GetSponsorshipPricingUseCase';
|
||||
import { GetEntitySponsorshipPricingUseCase } from '@core/racing/application/use-cases/GetEntitySponsorshipPricingUseCase';
|
||||
import { GetSponsorsUseCase } from '@core/racing/application/use-cases/GetSponsorsUseCase';
|
||||
import { CreateSponsorUseCase } from '@core/racing/application/use-cases/CreateSponsorUseCase';
|
||||
import { GetSponsorDashboardUseCase } from '@core/racing/application/use-cases/GetSponsorDashboardUseCase';
|
||||
@@ -37,26 +37,8 @@ import { GetSponsorBillingUseCase } from '@core/payments/application/use-cases/G
|
||||
import type { SponsorableEntityType } from '@core/racing/domain/entities/SponsorshipRequest';
|
||||
import type { Logger } from '@core/shared/application';
|
||||
|
||||
// Presenters
|
||||
import { GetEntitySponsorshipPricingPresenter } from './presenters/GetEntitySponsorshipPricingPresenter';
|
||||
import { GetSponsorsPresenter } from './presenters/GetSponsorsPresenter';
|
||||
import { CreateSponsorPresenter } from './presenters/CreateSponsorPresenter';
|
||||
import { GetSponsorDashboardPresenter } from './presenters/GetSponsorDashboardPresenter';
|
||||
import { GetSponsorSponsorshipsPresenter } from './presenters/GetSponsorSponsorshipsPresenter';
|
||||
import { GetSponsorPresenter } from './presenters/GetSponsorPresenter';
|
||||
import { GetPendingSponsorshipRequestsPresenter } from './presenters/GetPendingSponsorshipRequestsPresenter';
|
||||
import { AcceptSponsorshipRequestPresenter, AcceptSponsorshipRequestResultViewModel } from './presenters/AcceptSponsorshipRequestPresenter';
|
||||
import { RejectSponsorshipRequestPresenter } from './presenters/RejectSponsorshipRequestPresenter';
|
||||
import { SponsorBillingPresenter } from './presenters/SponsorBillingPresenter';
|
||||
import { AvailableLeaguesPresenter } from './presenters/AvailableLeaguesPresenter';
|
||||
import { LeagueDetailPresenter } from './presenters/LeagueDetailPresenter';
|
||||
import { SponsorSettingsPresenter } from './presenters/SponsorSettingsPresenter';
|
||||
import { SponsorSettingsUpdatePresenter } from './presenters/SponsorSettingsUpdatePresenter';
|
||||
import type { RejectSponsorshipRequestResult } from '@core/racing/application/use-cases/RejectSponsorshipRequestUseCase';
|
||||
|
||||
// Tokens
|
||||
import {
|
||||
GET_SPONSORSHIP_PRICING_USE_CASE_TOKEN,
|
||||
GET_SPONSORS_USE_CASE_TOKEN,
|
||||
CREATE_SPONSOR_USE_CASE_TOKEN,
|
||||
GET_SPONSOR_DASHBOARD_USE_CASE_TOKEN,
|
||||
@@ -66,14 +48,33 @@ import {
|
||||
ACCEPT_SPONSORSHIP_REQUEST_USE_CASE_TOKEN,
|
||||
REJECT_SPONSORSHIP_REQUEST_USE_CASE_TOKEN,
|
||||
GET_SPONSOR_BILLING_USE_CASE_TOKEN,
|
||||
GET_ENTITY_SPONSORSHIP_PRICING_USE_CASE_TOKEN,
|
||||
LOGGER_TOKEN,
|
||||
} from './SponsorTokens';
|
||||
|
||||
// Presenters (for view model transformation only)
|
||||
import { GetEntitySponsorshipPricingPresenter } from './presenters/GetEntitySponsorshipPricingPresenter';
|
||||
import { GetSponsorsPresenter } from './presenters/GetSponsorsPresenter';
|
||||
import { CreateSponsorPresenter } from './presenters/CreateSponsorPresenter';
|
||||
import { GetSponsorDashboardPresenter } from './presenters/GetSponsorDashboardPresenter';
|
||||
import { GetSponsorSponsorshipsPresenter } from './presenters/GetSponsorSponsorshipsPresenter';
|
||||
import { GetSponsorPresenter } from './presenters/GetSponsorPresenter';
|
||||
import { GetPendingSponsorshipRequestsPresenter } from './presenters/GetPendingSponsorshipRequestsPresenter';
|
||||
import { AcceptSponsorshipRequestPresenter } from './presenters/AcceptSponsorshipRequestPresenter';
|
||||
import { RejectSponsorshipRequestPresenter } from './presenters/RejectSponsorshipRequestPresenter';
|
||||
import { SponsorBillingPresenter } from './presenters/SponsorBillingPresenter';
|
||||
import { AvailableLeaguesPresenter } from './presenters/AvailableLeaguesPresenter';
|
||||
import { LeagueDetailPresenter } from './presenters/LeagueDetailPresenter';
|
||||
import { SponsorSettingsPresenter } from './presenters/SponsorSettingsPresenter';
|
||||
import { SponsorSettingsUpdatePresenter } from './presenters/SponsorSettingsUpdatePresenter';
|
||||
import type { RejectSponsorshipRequestResult } from '@core/racing/application/use-cases/RejectSponsorshipRequestUseCase';
|
||||
import type { AcceptSponsorshipRequestResultViewModel } from './presenters/AcceptSponsorshipRequestPresenter';
|
||||
|
||||
@Injectable()
|
||||
export class SponsorService {
|
||||
constructor(
|
||||
@Inject(GET_SPONSORSHIP_PRICING_USE_CASE_TOKEN)
|
||||
private readonly getSponsorshipPricingUseCase: GetSponsorshipPricingUseCase,
|
||||
@Inject(GET_ENTITY_SPONSORSHIP_PRICING_USE_CASE_TOKEN)
|
||||
private readonly getEntitySponsorshipPricingUseCase: GetEntitySponsorshipPricingUseCase,
|
||||
@Inject(GET_SPONSORS_USE_CASE_TOKEN)
|
||||
private readonly getSponsorsUseCase: GetSponsorsUseCase,
|
||||
@Inject(CREATE_SPONSOR_USE_CASE_TOKEN)
|
||||
@@ -94,22 +95,14 @@ export class SponsorService {
|
||||
private readonly getSponsorBillingUseCase: GetSponsorBillingUseCase,
|
||||
@Inject(LOGGER_TOKEN)
|
||||
private readonly logger: Logger,
|
||||
// Injected presenters
|
||||
private readonly getEntitySponsorshipPricingPresenter: GetEntitySponsorshipPricingPresenter,
|
||||
private readonly getSponsorsPresenter: GetSponsorsPresenter,
|
||||
private readonly createSponsorPresenter: CreateSponsorPresenter,
|
||||
private readonly getSponsorDashboardPresenter: GetSponsorDashboardPresenter,
|
||||
private readonly getSponsorSponsorshipsPresenter: GetSponsorSponsorshipsPresenter,
|
||||
private readonly getSponsorPresenter: GetSponsorPresenter,
|
||||
private readonly getPendingSponsorshipRequestsPresenter: GetPendingSponsorshipRequestsPresenter,
|
||||
private readonly acceptSponsorshipRequestPresenter: AcceptSponsorshipRequestPresenter,
|
||||
private readonly rejectSponsorshipRequestPresenter: RejectSponsorshipRequestPresenter,
|
||||
private readonly sponsorBillingPresenter: SponsorBillingPresenter,
|
||||
) {}
|
||||
|
||||
async getEntitySponsorshipPricing(): Promise<GetEntitySponsorshipPricingResultDTO> {
|
||||
this.logger.debug('[SponsorService] Fetching sponsorship pricing.');
|
||||
const result = await this.getSponsorshipPricingUseCase.execute({});
|
||||
const result = await this.getEntitySponsorshipPricingUseCase.execute({
|
||||
entityType: 'season',
|
||||
entityId: 'default',
|
||||
});
|
||||
|
||||
if (result.isErr()) {
|
||||
return {
|
||||
@@ -119,18 +112,22 @@ export class SponsorService {
|
||||
};
|
||||
}
|
||||
|
||||
return this.getEntitySponsorshipPricingPresenter.viewModel;
|
||||
const presenter = new GetEntitySponsorshipPricingPresenter();
|
||||
presenter.present(result.value);
|
||||
return presenter.viewModel;
|
||||
}
|
||||
|
||||
async getSponsors(): Promise<GetSponsorsOutputDTO> {
|
||||
this.logger.debug('[SponsorService] Fetching sponsors.');
|
||||
const result = await this.getSponsorsUseCase.execute();
|
||||
const result = await this.getSponsorsUseCase.execute({});
|
||||
|
||||
if (result.isErr()) {
|
||||
return { sponsors: [] };
|
||||
}
|
||||
|
||||
return this.getSponsorsPresenter.responseModel;
|
||||
const presenter = new GetSponsorsPresenter();
|
||||
presenter.present(result.unwrap().sponsors);
|
||||
return presenter.responseModel;
|
||||
}
|
||||
|
||||
async createSponsor(input: CreateSponsorInputDTO): Promise<CreateSponsorOutputDTO> {
|
||||
@@ -142,7 +139,14 @@ export class SponsorService {
|
||||
throw new Error(error.details?.message ?? error.message ?? 'Failed to create sponsor');
|
||||
}
|
||||
|
||||
return this.createSponsorPresenter.viewModel;
|
||||
const resultValue = result.value;
|
||||
if (!resultValue) {
|
||||
throw new Error('Create sponsor failed');
|
||||
}
|
||||
|
||||
const presenter = new CreateSponsorPresenter();
|
||||
presenter.present(resultValue.sponsor);
|
||||
return presenter.viewModel;
|
||||
}
|
||||
|
||||
async getSponsorDashboard(
|
||||
@@ -155,7 +159,14 @@ export class SponsorService {
|
||||
throw new Error('Sponsor dashboard not found');
|
||||
}
|
||||
|
||||
return this.getSponsorDashboardPresenter.viewModel;
|
||||
const resultValue = result.value;
|
||||
if (!resultValue) {
|
||||
throw new Error('Sponsor dashboard not found');
|
||||
}
|
||||
|
||||
const presenter = new GetSponsorDashboardPresenter();
|
||||
presenter.present(resultValue);
|
||||
return presenter.viewModel;
|
||||
}
|
||||
|
||||
async getSponsorSponsorships(
|
||||
@@ -168,7 +179,14 @@ export class SponsorService {
|
||||
throw new Error('Sponsor sponsorships not found');
|
||||
}
|
||||
|
||||
return this.getSponsorSponsorshipsPresenter.viewModel;
|
||||
const resultValue = result.value;
|
||||
if (!resultValue) {
|
||||
throw new Error('Sponsor sponsorships not found');
|
||||
}
|
||||
|
||||
const presenter = new GetSponsorSponsorshipsPresenter();
|
||||
presenter.present(resultValue);
|
||||
return presenter.viewModel;
|
||||
}
|
||||
|
||||
async getSponsor(sponsorId: string): Promise<GetSponsorOutputDTO> {
|
||||
@@ -179,7 +197,14 @@ export class SponsorService {
|
||||
throw new Error('Sponsor not found');
|
||||
}
|
||||
|
||||
const viewModel = this.getSponsorPresenter.viewModel;
|
||||
const resultValue = result.value;
|
||||
if (!resultValue) {
|
||||
throw new Error('Sponsor not found');
|
||||
}
|
||||
|
||||
const presenter = new GetSponsorPresenter();
|
||||
presenter.present(resultValue.sponsor);
|
||||
const viewModel = presenter.viewModel;
|
||||
if (!viewModel) {
|
||||
throw new Error('Sponsor not found');
|
||||
}
|
||||
@@ -205,7 +230,14 @@ export class SponsorService {
|
||||
};
|
||||
}
|
||||
|
||||
const viewModel = this.getPendingSponsorshipRequestsPresenter.viewModel;
|
||||
const resultValue = result.value;
|
||||
if (!resultValue) {
|
||||
throw new Error('Pending sponsorship requests not found');
|
||||
}
|
||||
|
||||
const presenter = new GetPendingSponsorshipRequestsPresenter();
|
||||
presenter.present(resultValue);
|
||||
const viewModel = presenter.viewModel;
|
||||
if (!viewModel) {
|
||||
throw new Error('Pending sponsorship requests not found');
|
||||
}
|
||||
@@ -231,7 +263,14 @@ export class SponsorService {
|
||||
throw new Error('Accept sponsorship request failed');
|
||||
}
|
||||
|
||||
const viewModel = this.acceptSponsorshipRequestPresenter.viewModel;
|
||||
const resultValue = result.value;
|
||||
if (!resultValue) {
|
||||
throw new Error('Accept sponsorship request failed');
|
||||
}
|
||||
|
||||
const presenter = new AcceptSponsorshipRequestPresenter();
|
||||
presenter.present(resultValue);
|
||||
const viewModel = presenter.viewModel;
|
||||
if (!viewModel) {
|
||||
throw new Error('Accept sponsorship request failed');
|
||||
}
|
||||
@@ -263,7 +302,14 @@ export class SponsorService {
|
||||
throw new Error('Reject sponsorship request failed');
|
||||
}
|
||||
|
||||
const viewModel = this.rejectSponsorshipRequestPresenter.viewModel;
|
||||
const resultValue = result.value;
|
||||
if (!resultValue) {
|
||||
throw new Error('Reject sponsorship request failed');
|
||||
}
|
||||
|
||||
const presenter = new RejectSponsorshipRequestPresenter();
|
||||
presenter.present(resultValue);
|
||||
const viewModel = presenter.viewModel;
|
||||
if (!viewModel) {
|
||||
throw new Error('Reject sponsorship request failed');
|
||||
}
|
||||
@@ -284,7 +330,8 @@ export class SponsorService {
|
||||
}
|
||||
|
||||
const billingData = result.unwrap();
|
||||
this.sponsorBillingPresenter.present({
|
||||
const presenter = new SponsorBillingPresenter();
|
||||
presenter.present({
|
||||
paymentMethods: billingData.paymentMethods,
|
||||
invoices: billingData.invoices,
|
||||
stats: {
|
||||
@@ -294,7 +341,7 @@ export class SponsorService {
|
||||
},
|
||||
});
|
||||
|
||||
return this.sponsorBillingPresenter.viewModel;
|
||||
return presenter.viewModel;
|
||||
}
|
||||
|
||||
async getAvailableLeagues(): Promise<AvailableLeaguesPresenter> {
|
||||
@@ -498,4 +545,4 @@ export class SponsorService {
|
||||
presenter.present({ success: true });
|
||||
return presenter;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,18 +9,6 @@ export const SPONSORSHIP_REQUEST_REPOSITORY_TOKEN = 'ISponsorshipRequestReposito
|
||||
export const LOGGER_TOKEN = 'Logger';
|
||||
export const MEDIA_RESOLVER_TOKEN = 'MediaResolverPort';
|
||||
|
||||
// Presenter tokens
|
||||
export const GET_ENTITY_SPONSORSHIP_PRICING_PRESENTER_TOKEN = 'GetEntitySponsorshipPricingPresenter';
|
||||
export const GET_SPONSORS_PRESENTER_TOKEN = 'GetSponsorsPresenter';
|
||||
export const CREATE_SPONSOR_PRESENTER_TOKEN = 'CreateSponsorPresenter';
|
||||
export const GET_SPONSOR_DASHBOARD_PRESENTER_TOKEN = 'GetSponsorDashboardPresenter';
|
||||
export const GET_SPONSOR_SPONSORSHIPS_PRESENTER_TOKEN = 'GetSponsorSponsorshipsPresenter';
|
||||
export const GET_SPONSOR_PRESENTER_TOKEN = 'GetSponsorPresenter';
|
||||
export const GET_PENDING_SPONSORSHIP_REQUESTS_PRESENTER_TOKEN = 'GetPendingSponsorshipRequestsPresenter';
|
||||
export const ACCEPT_SPONSORSHIP_REQUEST_PRESENTER_TOKEN = 'AcceptSponsorshipRequestPresenter';
|
||||
export const REJECT_SPONSORSHIP_REQUEST_PRESENTER_TOKEN = 'RejectSponsorshipRequestPresenter';
|
||||
export const GET_SPONSOR_BILLING_PRESENTER_TOKEN = 'SponsorBillingPresenter';
|
||||
|
||||
// Use case / application service tokens
|
||||
export const GET_SPONSORSHIP_PRICING_USE_CASE_TOKEN = 'GetSponsorshipPricingUseCase';
|
||||
export const GET_SPONSORS_USE_CASE_TOKEN = 'GetSponsorsUseCase';
|
||||
@@ -32,17 +20,4 @@ export const GET_SPONSOR_USE_CASE_TOKEN = 'GetSponsorUseCase';
|
||||
export const GET_PENDING_SPONSORSHIP_REQUESTS_USE_CASE_TOKEN = 'GetPendingSponsorshipRequestsUseCase';
|
||||
export const ACCEPT_SPONSORSHIP_REQUEST_USE_CASE_TOKEN = 'AcceptSponsorshipRequestUseCase';
|
||||
export const REJECT_SPONSORSHIP_REQUEST_USE_CASE_TOKEN = 'RejectSponsorshipRequestUseCase';
|
||||
export const GET_SPONSOR_BILLING_USE_CASE_TOKEN = 'GetSponsorBillingUseCase';
|
||||
|
||||
// Output port tokens
|
||||
export const GET_SPONSORSHIP_PRICING_OUTPUT_PORT_TOKEN = 'GetSponsorshipPricingOutputPort_TOKEN';
|
||||
export const GET_SPONSORS_OUTPUT_PORT_TOKEN = 'GetSponsorsOutputPort_TOKEN';
|
||||
export const CREATE_SPONSOR_OUTPUT_PORT_TOKEN = 'CreateSponsorOutputPort_TOKEN';
|
||||
export const GET_SPONSOR_DASHBOARD_OUTPUT_PORT_TOKEN = 'GetSponsorDashboardOutputPort_TOKEN';
|
||||
export const GET_SPONSOR_SPONSORSHIPS_OUTPUT_PORT_TOKEN = 'GetSponsorSponsorshipsOutputPort_TOKEN';
|
||||
export const GET_ENTITY_SPONSORSHIP_PRICING_OUTPUT_PORT_TOKEN = 'GetEntitySponsorshipPricingOutputPort_TOKEN';
|
||||
export const GET_SPONSOR_OUTPUT_PORT_TOKEN = 'GetSponsorOutputPort_TOKEN';
|
||||
export const GET_PENDING_SPONSORSHIP_REQUESTS_OUTPUT_PORT_TOKEN = 'GetPendingSponsorshipRequestsOutputPort_TOKEN';
|
||||
export const ACCEPT_SPONSORSHIP_REQUEST_OUTPUT_PORT_TOKEN = 'AcceptSponsorshipRequestOutputPort_TOKEN';
|
||||
export const REJECT_SPONSORSHIP_REQUEST_OUTPUT_PORT_TOKEN = 'RejectSponsorshipRequestOutputPort_TOKEN';
|
||||
export const GET_SPONSOR_BILLING_OUTPUT_PORT_TOKEN = 'GetSponsorBillingOutputPort_TOKEN';
|
||||
export const GET_SPONSOR_BILLING_USE_CASE_TOKEN = 'GetSponsorBillingUseCase';
|
||||
@@ -8,7 +8,7 @@ export class GetEntitySponsorshipPricingPresenter {
|
||||
this.result = null;
|
||||
}
|
||||
|
||||
present(output: GetEntitySponsorshipPricingResult | null) {
|
||||
present(output: GetEntitySponsorshipPricingResult | null | undefined) {
|
||||
if (!output) {
|
||||
this.result = {
|
||||
entityType: 'season',
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
import { GetSponsorOutputDTO } from '../dtos/GetSponsorOutputDTO';
|
||||
|
||||
interface GetSponsorOutputPort {
|
||||
sponsor: {
|
||||
id: string;
|
||||
name: string;
|
||||
logoUrl?: string;
|
||||
websiteUrl?: string;
|
||||
};
|
||||
}
|
||||
import type { Sponsor } from '@core/racing/domain/entities/sponsor/Sponsor';
|
||||
|
||||
export class GetSponsorPresenter {
|
||||
private result: GetSponsorOutputDTO | null = null;
|
||||
@@ -16,18 +8,18 @@ export class GetSponsorPresenter {
|
||||
this.result = null;
|
||||
}
|
||||
|
||||
present(output: GetSponsorOutputPort | null) {
|
||||
if (!output) {
|
||||
present(sponsor: Sponsor) {
|
||||
if (!sponsor) {
|
||||
this.result = null;
|
||||
return;
|
||||
}
|
||||
|
||||
this.result = {
|
||||
sponsor: {
|
||||
id: output.sponsor.id,
|
||||
name: output.sponsor.name,
|
||||
...(output.sponsor.logoUrl !== undefined ? { logoUrl: output.sponsor.logoUrl } : {}),
|
||||
...(output.sponsor.websiteUrl !== undefined ? { websiteUrl: output.sponsor.websiteUrl } : {}),
|
||||
id: sponsor.id.toString(),
|
||||
name: sponsor.name.toString(),
|
||||
...(sponsor.logoUrl !== undefined ? { logoUrl: sponsor.logoUrl.toString() } : {}),
|
||||
...(sponsor.websiteUrl !== undefined ? { websiteUrl: sponsor.websiteUrl.toString() } : {}),
|
||||
},
|
||||
} as GetSponsorOutputDTO;
|
||||
}
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import { GetSponsorshipPricingPresenter } from './GetSponsorshipPricingPresenter';
|
||||
import type { GetSponsorshipPricingResult } from '@core/racing/application/use-cases/GetSponsorshipPricingUseCase';
|
||||
|
||||
describe('GetSponsorshipPricingPresenter', () => {
|
||||
let presenter: GetSponsorshipPricingPresenter;
|
||||
|
||||
beforeEach(() => {
|
||||
presenter = new GetSponsorshipPricingPresenter();
|
||||
});
|
||||
|
||||
describe('reset', () => {
|
||||
it('should reset the result to null', () => {
|
||||
const mockResult: GetSponsorshipPricingResult = {
|
||||
entityType: 'season',
|
||||
entityId: 'season-1',
|
||||
pricing: []
|
||||
};
|
||||
presenter.present(mockResult);
|
||||
|
||||
const expectedViewModel = {
|
||||
entityType: 'season',
|
||||
entityId: 'season-1',
|
||||
pricing: []
|
||||
};
|
||||
expect(presenter.viewModel).toEqual(expectedViewModel);
|
||||
|
||||
presenter.reset();
|
||||
expect(() => presenter.viewModel).toThrow('Presenter not presented');
|
||||
});
|
||||
});
|
||||
|
||||
describe('present', () => {
|
||||
it('should store the result', () => {
|
||||
const mockResult: GetSponsorshipPricingResult = {
|
||||
entityType: 'season',
|
||||
entityId: 'season-1',
|
||||
pricing: []
|
||||
};
|
||||
|
||||
presenter.present(mockResult);
|
||||
|
||||
const expectedViewModel = {
|
||||
entityType: 'season',
|
||||
entityId: 'season-1',
|
||||
pricing: []
|
||||
};
|
||||
expect(presenter.viewModel).toEqual(expectedViewModel);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getViewModel', () => {
|
||||
it('should return null when not presented', () => {
|
||||
expect(presenter.getViewModel()).toBeNull();
|
||||
});
|
||||
|
||||
it('should return the result when presented', () => {
|
||||
const mockResult: GetSponsorshipPricingResult = {
|
||||
entityType: 'season',
|
||||
entityId: 'season-1',
|
||||
pricing: []
|
||||
};
|
||||
presenter.present(mockResult);
|
||||
|
||||
const expectedViewModel = {
|
||||
entityType: 'season',
|
||||
entityId: 'season-1',
|
||||
pricing: []
|
||||
};
|
||||
expect(presenter.getViewModel()).toEqual(expectedViewModel);
|
||||
});
|
||||
});
|
||||
|
||||
describe('viewModel', () => {
|
||||
it('should throw error when not presented', () => {
|
||||
expect(() => presenter.viewModel).toThrow('Presenter not presented');
|
||||
});
|
||||
|
||||
it('should return the result when presented', () => {
|
||||
const mockResult: GetSponsorshipPricingResult = {
|
||||
entityType: 'season',
|
||||
entityId: 'season-1',
|
||||
pricing: []
|
||||
};
|
||||
presenter.present(mockResult);
|
||||
|
||||
const expectedViewModel = {
|
||||
entityType: 'season',
|
||||
entityId: 'season-1',
|
||||
pricing: []
|
||||
};
|
||||
expect(presenter.viewModel).toEqual(expectedViewModel);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,32 +0,0 @@
|
||||
import type { GetSponsorshipPricingResult } from '@core/racing/application/use-cases/GetSponsorshipPricingUseCase';
|
||||
import { GetEntitySponsorshipPricingResultDTO } from '../dtos/GetEntitySponsorshipPricingResultDTO';
|
||||
|
||||
export class GetSponsorshipPricingPresenter {
|
||||
private result: GetEntitySponsorshipPricingResultDTO | null = null;
|
||||
|
||||
reset() {
|
||||
this.result = null;
|
||||
}
|
||||
|
||||
present(outputPort: GetSponsorshipPricingResult): void {
|
||||
this.result = {
|
||||
entityType: outputPort.entityType,
|
||||
entityId: outputPort.entityId,
|
||||
pricing: outputPort.pricing.map(item => ({
|
||||
id: item.id,
|
||||
level: item.level,
|
||||
price: item.price,
|
||||
currency: item.currency,
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
getViewModel(): GetEntitySponsorshipPricingResultDTO | null {
|
||||
return this.result;
|
||||
}
|
||||
|
||||
get viewModel(): GetEntitySponsorshipPricingResultDTO {
|
||||
if (!this.result) throw new Error('Presenter not presented');
|
||||
return this.result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user