module cleanup

This commit is contained in:
2025-12-19 01:22:45 +01:00
parent d617654928
commit d0fac9e6c1
135 changed files with 5104 additions and 1315 deletions

View File

@@ -0,0 +1,39 @@
import { Test, TestingModule } from '@nestjs/testing';
import { vi } from 'vitest';
import { ProtestsController } from './ProtestsController';
import { RaceService } from '../race/RaceService';
import { ReviewProtestCommandDTO } from '../race/dtos/ReviewProtestCommandDTO';
describe('ProtestsController', () => {
let controller: ProtestsController;
let raceService: ReturnType<typeof vi.mocked<RaceService>>;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [ProtestsController],
providers: [
{
provide: RaceService,
useValue: {
reviewProtest: vi.fn(),
},
},
],
}).compile();
controller = module.get<ProtestsController>(ProtestsController);
raceService = vi.mocked(module.get(RaceService));
});
describe('reviewProtest', () => {
it('should review protest', async () => {
const protestId = 'protest-123';
const body: Omit<ReviewProtestCommandDTO, 'protestId'> = { decision: 'upheld', reason: 'Reason' };
raceService.reviewProtest.mockResolvedValue(undefined);
await controller.reviewProtest(protestId, body);
expect(raceService.reviewProtest).toHaveBeenCalledWith({ protestId, ...body });
});
});
});

View File

@@ -0,0 +1,23 @@
import { Test, TestingModule } from '@nestjs/testing';
import { ProtestsModule } from './ProtestsModule';
import { ProtestsController } from './ProtestsController';
describe('ProtestsModule', () => {
let module: TestingModule;
beforeEach(async () => {
module = await Test.createTestingModule({
imports: [ProtestsModule],
}).compile();
});
it('should compile the module', () => {
expect(module).toBeDefined();
});
it('should provide ProtestsController', () => {
const controller = module.get<ProtestsController>(ProtestsController);
expect(controller).toBeDefined();
expect(controller).toBeInstanceOf(ProtestsController);
});
});

View File

@@ -1,9 +1,10 @@
import { Module } from '@nestjs/common';
import { ProtestsController } from './ProtestsController';
import { RaceModule } from '../race/RaceModule';
import { ProtestsService } from './ProtestsService';
import { ProtestsProviders } from './ProtestsProviders';
@Module({
imports: [RaceModule],
providers: [ProtestsService, ...ProtestsProviders],
controllers: [ProtestsController],
})
export class ProtestsModule {}

View File

@@ -0,0 +1,45 @@
import { Provider } from '@nestjs/common';
import { ProtestsService } from './ProtestsService';
// Import core interfaces
import type { Logger } from '@core/shared/application/Logger';
// Import concrete in-memory implementations
import { InMemoryProtestRepository } from '@adapters/racing/persistence/inmemory/InMemoryProtestRepository';
import { InMemoryRaceRepository } from '@adapters/racing/persistence/inmemory/InMemoryRaceRepository';
import { InMemoryLeagueMembershipRepository } from '@adapters/racing/persistence/inmemory/InMemoryLeagueMembershipRepository';
import { ConsoleLogger } from '@adapters/logging/ConsoleLogger';
// Import use cases
import { ReviewProtestUseCase } from '@core/racing/application/use-cases/ReviewProtestUseCase';
// Define injection tokens
export const PROTEST_REPOSITORY_TOKEN = 'IProtestRepository';
export const RACE_REPOSITORY_TOKEN = 'IRaceRepository';
export const LEAGUE_MEMBERSHIP_REPOSITORY_TOKEN = 'ILeagueMembershipRepository';
export const LOGGER_TOKEN = 'Logger';
export const ProtestsProviders: Provider[] = [
ProtestsService, // Provide the service itself
{
provide: PROTEST_REPOSITORY_TOKEN,
useFactory: (logger: Logger) => new InMemoryProtestRepository(logger),
inject: [LOGGER_TOKEN],
},
{
provide: RACE_REPOSITORY_TOKEN,
useFactory: (logger: Logger) => new InMemoryRaceRepository(logger),
inject: [LOGGER_TOKEN],
},
{
provide: LEAGUE_MEMBERSHIP_REPOSITORY_TOKEN,
useFactory: (logger: Logger) => new InMemoryLeagueMembershipRepository(logger),
inject: [LOGGER_TOKEN],
},
{
provide: LOGGER_TOKEN,
useClass: ConsoleLogger,
},
// Use cases
ReviewProtestUseCase,
];

View File

@@ -0,0 +1,31 @@
import { Injectable, Inject } from '@nestjs/common';
import type { Logger } from '@core/shared/application/Logger';
// Use cases
import { ReviewProtestUseCase } from '@core/racing/application/use-cases/ReviewProtestUseCase';
// Tokens
import { LOGGER_TOKEN } from './ProtestsProviders';
@Injectable()
export class ProtestsService {
constructor(
private readonly reviewProtestUseCase: ReviewProtestUseCase,
@Inject(LOGGER_TOKEN) private readonly logger: Logger,
) {}
async reviewProtest(command: {
protestId: string;
stewardId: string;
decision: 'uphold' | 'dismiss';
decisionNotes: string;
}): Promise<void> {
this.logger.debug('[ProtestsService] Reviewing protest:', command);
const result = await this.reviewProtestUseCase.execute(command);
if (result.isErr()) {
throw new Error(result.error.details.message || 'Failed to review protest');
}
}
}