use interfaces for requests
This commit is contained in:
		
							parent
							
								
									d6a12e4d0e
								
							
						
					
					
						commit
						8ab1ddbebc
					
				|  | @ -89,6 +89,7 @@ | |||
|       ".controller.ts", | ||||
|       ".module.ts", | ||||
|       ".request.ts", | ||||
|       ".presenter.ts", | ||||
|       "main.ts" | ||||
|     ], | ||||
|     "rootDir": "src", | ||||
|  |  | |||
|  | @ -9,7 +9,7 @@ import { ICollection } from 'src/modules/database/src/interfaces/collection.inte | |||
| import { Match } from '../../domain/entities/match'; | ||||
| import { MatchQuery } from '../../queries/match.query'; | ||||
| import { MatchPresenter } from '../secondaries/match.presenter'; | ||||
| import { ConfigService } from '@nestjs/config'; | ||||
| import { DefaultParamsProvider } from '../secondaries/default-params.provider'; | ||||
| 
 | ||||
| @UsePipes( | ||||
|   new RpcValidationPipe({ | ||||
|  | @ -21,7 +21,7 @@ import { ConfigService } from '@nestjs/config'; | |||
| export class MatcherController { | ||||
|   constructor( | ||||
|     private readonly _queryBus: QueryBus, | ||||
|     private readonly _configService: ConfigService, | ||||
|     private readonly _defaultParamsProvider: DefaultParamsProvider, | ||||
|     @InjectMapper() private readonly _mapper: Mapper, | ||||
|   ) {} | ||||
| 
 | ||||
|  | @ -29,7 +29,7 @@ export class MatcherController { | |||
|   async match(data: MatchRequest): Promise<ICollection<Match>> { | ||||
|     try { | ||||
|       const matchCollection = await this._queryBus.execute( | ||||
|         new MatchQuery(data, this._configService), | ||||
|         new MatchQuery(data, this._defaultParamsProvider.getParams()), | ||||
|       ); | ||||
|       return Promise.resolve({ | ||||
|         data: matchCollection.data.map((match: Match) => | ||||
|  |  | |||
|  | @ -0,0 +1,16 @@ | |||
| import { Injectable } from '@nestjs/common'; | ||||
| import { ConfigService } from '@nestjs/config'; | ||||
| import { IDefaultParams } from '../../domain/interfaces/default-params.interface'; | ||||
| 
 | ||||
| @Injectable() | ||||
| export class DefaultParamsProvider { | ||||
|   constructor(private readonly configService: ConfigService) {} | ||||
| 
 | ||||
|   getParams(): IDefaultParams { | ||||
|     return { | ||||
|       DEFAULT_IDENTIFIER: this.configService.get<number>('DEFAULT_IDENTIFIER'), | ||||
|       MARGIN_DURATION: this.configService.get<number>('MARGIN_DURATION'), | ||||
|       VALIDITY_DURATION: this.configService.get<number>('VALIDITY_DURATION'), | ||||
|     }; | ||||
|   } | ||||
| } | ||||
|  | @ -1,7 +1,7 @@ | |||
| import { Injectable } from '@nestjs/common'; | ||||
| 
 | ||||
| @Injectable() | ||||
| export abstract class IMessageBroker { | ||||
| export abstract class MessageBroker { | ||||
|   exchange: string; | ||||
| 
 | ||||
|   constructor(exchange: string) { | ||||
|  |  | |||
|  | @ -1,10 +1,10 @@ | |||
| import { AmqpConnection } from '@golevelup/nestjs-rabbitmq'; | ||||
| import { Injectable } from '@nestjs/common'; | ||||
| import { ConfigService } from '@nestjs/config'; | ||||
| import { IMessageBroker } from './message-broker'; | ||||
| import { MessageBroker } from './message-broker'; | ||||
| 
 | ||||
| @Injectable() | ||||
| export class Messager extends IMessageBroker { | ||||
| export class Messager extends MessageBroker { | ||||
|   constructor( | ||||
|     private readonly _amqpConnection: AmqpConnection, | ||||
|     configService: ConfigService, | ||||
|  |  | |||
|  | @ -14,8 +14,13 @@ import { Point } from '../entities/point.type'; | |||
| import { Schedule } from './schedule.type'; | ||||
| import { MarginDurations } from './margin-durations.type'; | ||||
| import { Algorithm } from './algorithm.enum'; | ||||
| import { IRequestTime } from '../interfaces/time-request.interface'; | ||||
| import { IRequestRole } from '../interfaces/role-request.interface'; | ||||
| import { IRequestPerson } from '../interfaces/person-request.interface'; | ||||
| 
 | ||||
| export class MatchRequest { | ||||
| export class MatchRequest | ||||
|   implements IRequestTime, IRequestRole, IRequestPerson | ||||
| { | ||||
|   @IsArray() | ||||
|   @AutoMap() | ||||
|   waypoints: Array<Point>; | ||||
|  | @ -23,12 +28,12 @@ export class MatchRequest { | |||
|   @IsOptional() | ||||
|   @IsString() | ||||
|   @AutoMap() | ||||
|   departure: number; | ||||
|   departure: string; | ||||
| 
 | ||||
|   @IsOptional() | ||||
|   @IsInt() | ||||
|   @IsString() | ||||
|   @AutoMap() | ||||
|   fromDate: number; | ||||
|   fromDate: string; | ||||
| 
 | ||||
|   @IsOptional() | ||||
|   @AutoMap() | ||||
|  |  | |||
|  | @ -1,25 +1,25 @@ | |||
| import { MatchRequest } from '../dtos/match.request'; | ||||
| import { IRequestPerson } from '../interfaces/person-request.interface'; | ||||
| 
 | ||||
| export class Person { | ||||
|   _matchRequest: MatchRequest; | ||||
|   _personRequest: IRequestPerson; | ||||
|   _defaultIdentifier: number; | ||||
|   _defaultMarginDuration: number; | ||||
|   identifier: number; | ||||
|   marginDurations: Array<number>; | ||||
| 
 | ||||
|   constructor( | ||||
|     matchRequest: MatchRequest, | ||||
|     personRequest: IRequestPerson, | ||||
|     defaultIdentifier: number, | ||||
|     defaultMarginDuration: number, | ||||
|   ) { | ||||
|     this._matchRequest = matchRequest; | ||||
|     this._personRequest = personRequest; | ||||
|     this._defaultIdentifier = defaultIdentifier; | ||||
|     this._defaultMarginDuration = defaultMarginDuration; | ||||
|   } | ||||
| 
 | ||||
|   init() { | ||||
|     this.setIdentifier( | ||||
|       this._matchRequest.identifier ?? this._defaultIdentifier, | ||||
|       this._personRequest.identifier ?? this._defaultIdentifier, | ||||
|     ); | ||||
|     this.setMarginDurations([ | ||||
|       this._defaultMarginDuration, | ||||
|  |  | |||
|  | @ -1,9 +1,9 @@ | |||
| import { MatcherException } from '../../exceptions/matcher.exception'; | ||||
| import { MatchRequest } from '../dtos/match.request'; | ||||
| import { IRequestTime } from '../interfaces/time-request.interface'; | ||||
| import { TimingFrequency } from './timing'; | ||||
| 
 | ||||
| export class Time { | ||||
|   _matchRequest: MatchRequest; | ||||
|   _timeRequest: IRequestTime; | ||||
|   _defaultMarginDuration: number; | ||||
|   _defaultValidityDuration: number; | ||||
|   frequency: TimingFrequency; | ||||
|  | @ -13,35 +13,44 @@ export class Time { | |||
|   marginDurations: Array<number>; | ||||
| 
 | ||||
|   constructor( | ||||
|     matchRequest: MatchRequest, | ||||
|     timeRequest: IRequestTime, | ||||
|     defaultMarginDuration: number, | ||||
|     defaultValidityDuration: number, | ||||
|   ) { | ||||
|     this._matchRequest = matchRequest; | ||||
|     this._timeRequest = timeRequest; | ||||
|     this._defaultMarginDuration = defaultMarginDuration; | ||||
|     this._defaultValidityDuration = defaultValidityDuration; | ||||
|   } | ||||
| 
 | ||||
|   init() { | ||||
|     this._validateBaseDate(); | ||||
|     this._validatePunctualDate(); | ||||
|     this._validateRecurrentDate(); | ||||
|     console.log(this.fromDate); | ||||
|   } | ||||
| 
 | ||||
|   _validateBaseDate() { | ||||
|     if (!this._timeRequest.departure && !this._timeRequest.fromDate) { | ||||
|       throw new MatcherException(3, 'departure or fromDate is required'); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   _validatePunctualDate() { | ||||
|     if (!this._matchRequest.departure && !this._matchRequest.fromDate) { | ||||
|       throw new MatcherException(3, 'departure or fromDate is Required'); | ||||
|     } | ||||
|     if (this._matchRequest.departure) { | ||||
|       this.fromDate = new Date(this._matchRequest.departure); | ||||
|     if (this._timeRequest.departure) { | ||||
|       this.fromDate = new Date(this._timeRequest.departure); | ||||
|       if (!this._isDate(this.fromDate)) { | ||||
|         throw new MatcherException(3, 'Wrong departure date'); | ||||
|       } | ||||
|       console.log(this.fromDate); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   _validateRecurrentDate() { | ||||
|     console.log('validate recurrent date'); | ||||
|     if (this._timeRequest.fromDate) { | ||||
|       this.fromDate = new Date(this._timeRequest.fromDate); | ||||
|       if (!this._isDate(this.fromDate)) { | ||||
|         throw new MatcherException(3, 'Wrong fromDate'); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   _isDate(date: Date) { | ||||
|  |  | |||
|  | @ -0,0 +1,5 @@ | |||
| export interface IDefaultParams { | ||||
|   DEFAULT_IDENTIFIER: number; | ||||
|   MARGIN_DURATION: number; | ||||
|   VALIDITY_DURATION: number; | ||||
| } | ||||
|  | @ -0,0 +1,3 @@ | |||
| export interface IRequestPerson { | ||||
|   identifier: number; | ||||
| } | ||||
|  | @ -0,0 +1,4 @@ | |||
| export interface IRequestRole { | ||||
|   driver: boolean; | ||||
|   passenger: boolean; | ||||
| } | ||||
|  | @ -0,0 +1,7 @@ | |||
| import { Schedule } from '../dtos/schedule.type'; | ||||
| 
 | ||||
| export interface IRequestTime { | ||||
|   departure: string; | ||||
|   fromDate: string; | ||||
|   schedule: Schedule; | ||||
| } | ||||
|  | @ -11,6 +11,7 @@ import { Messager } from './adapters/secondaries/messager'; | |||
| import { CacheModule } from '@nestjs/cache-manager'; | ||||
| import { RedisClientOptions } from '@liaoliaots/nestjs-redis'; | ||||
| import { redisStore } from 'cache-manager-ioredis-yet'; | ||||
| import { DefaultParamsProvider } from './adapters/secondaries/default-params.provider'; | ||||
| 
 | ||||
| @Module({ | ||||
|   imports: [ | ||||
|  | @ -44,7 +45,13 @@ import { redisStore } from 'cache-manager-ioredis-yet'; | |||
|     }), | ||||
|   ], | ||||
|   controllers: [MatcherController], | ||||
|   providers: [MatchProfile, AdRepository, Messager, MatchUseCase], | ||||
|   providers: [ | ||||
|     MatchProfile, | ||||
|     AdRepository, | ||||
|     Messager, | ||||
|     DefaultParamsProvider, | ||||
|     MatchUseCase, | ||||
|   ], | ||||
|   exports: [], | ||||
| }) | ||||
| export class MatcherModule {} | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| import { ConfigService } from '@nestjs/config'; | ||||
| import { MatchRequest } from '../domain/dtos/match.request'; | ||||
| import { Geography } from '../domain/entities/geography'; | ||||
| import { Person } from '../domain/entities/person'; | ||||
|  | @ -6,11 +5,11 @@ import { Requirement } from '../domain/entities/requirement'; | |||
| import { Role } from '../domain/entities/role.enum'; | ||||
| import { Settings } from '../domain/entities/settings'; | ||||
| import { Time } from '../domain/entities/time'; | ||||
| import { MatcherException } from '../exceptions/matcher.exception'; | ||||
| import { IDefaultParams } from '../domain/interfaces/default-params.interface'; | ||||
| 
 | ||||
| export class MatchQuery { | ||||
|   private readonly _matchRequest: MatchRequest; | ||||
|   private readonly _configService: ConfigService; | ||||
|   private readonly _defaultParams: IDefaultParams; | ||||
|   person: Person; | ||||
|   exclusions: Array<number>; | ||||
|   time: Time; | ||||
|  | @ -19,10 +18,9 @@ export class MatchQuery { | |||
|   requirement: Requirement; | ||||
|   settings: Settings; | ||||
| 
 | ||||
|   constructor(matchRequest: MatchRequest, configService: ConfigService) { | ||||
|   constructor(matchRequest: MatchRequest, defaultParams: IDefaultParams) { | ||||
|     this._matchRequest = matchRequest; | ||||
|     this._configService = configService; | ||||
|     this._validate(); | ||||
|     this._defaultParams = defaultParams; | ||||
|     this._initialize(); | ||||
|     this._setPerson(); | ||||
|     this._setExclusions(); | ||||
|  | @ -31,15 +29,6 @@ export class MatchQuery { | |||
|     // console.log(this);
 | ||||
|   } | ||||
| 
 | ||||
|   _validate() { | ||||
|     if (!this._matchRequest.departure) { | ||||
|       if (!this._matchRequest.fromDate) | ||||
|         throw new MatcherException(3, 'departure or fromDate is Required'); | ||||
|       if (!this._matchRequest.schedule) | ||||
|         throw new MatcherException(3, 'schedule is Required'); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   _initialize() { | ||||
|     if ( | ||||
|       this._matchRequest.driver === undefined && | ||||
|  | @ -54,8 +43,8 @@ export class MatchQuery { | |||
|   _setPerson() { | ||||
|     this.person = new Person( | ||||
|       this._matchRequest, | ||||
|       this._configService.get<number>('DEFAULT_IDENTIFIER'), | ||||
|       this._configService.get<number>('MARGIN_DURATION'), | ||||
|       this._defaultParams.DEFAULT_IDENTIFIER, | ||||
|       this._defaultParams.MARGIN_DURATION, | ||||
|     ); | ||||
|     this.person.init(); | ||||
|   } | ||||
|  | @ -77,8 +66,8 @@ export class MatchQuery { | |||
|   _setTime() { | ||||
|     this.time = new Time( | ||||
|       this._matchRequest, | ||||
|       this._configService.get<number>('MARGIN_DURATION'), | ||||
|       this._configService.get<number>('VALIDITY_DURATION'), | ||||
|       this._defaultParams.MARGIN_DURATION, | ||||
|       this._defaultParams.VALIDITY_DURATION, | ||||
|     ); | ||||
|     this.time.init(); | ||||
|   } | ||||
|  |  | |||
|  | @ -0,0 +1,38 @@ | |||
| import { ConfigService } from '@nestjs/config'; | ||||
| import { Test, TestingModule } from '@nestjs/testing'; | ||||
| import { DefaultParamsProvider } from '../../adapters/secondaries/default-params.provider'; | ||||
| import { IDefaultParams } from '../../domain/interfaces/default-params.interface'; | ||||
| 
 | ||||
| const mockConfigService = { | ||||
|   get: jest.fn().mockImplementationOnce(() => 99), | ||||
| }; | ||||
| 
 | ||||
| describe('DefaultParamsProvider', () => { | ||||
|   let defaultParamsProvider: DefaultParamsProvider; | ||||
| 
 | ||||
|   beforeAll(async () => { | ||||
|     const module: TestingModule = await Test.createTestingModule({ | ||||
|       imports: [], | ||||
|       providers: [ | ||||
|         DefaultParamsProvider, | ||||
|         { | ||||
|           provide: ConfigService, | ||||
|           useValue: mockConfigService, | ||||
|         }, | ||||
|       ], | ||||
|     }).compile(); | ||||
| 
 | ||||
|     defaultParamsProvider = module.get<DefaultParamsProvider>( | ||||
|       DefaultParamsProvider, | ||||
|     ); | ||||
|   }); | ||||
| 
 | ||||
|   it('should be defined', () => { | ||||
|     expect(defaultParamsProvider).toBeDefined(); | ||||
|   }); | ||||
| 
 | ||||
|   it('should provide default params', async () => { | ||||
|     const params: IDefaultParams = defaultParamsProvider.getParams(); | ||||
|     expect(params.DEFAULT_IDENTIFIER).toBe(99); | ||||
|   }); | ||||
| }); | ||||
|  | @ -6,6 +6,7 @@ import { MatchQuery } from '../../queries/match.query'; | |||
| import { AdRepository } from '../../adapters/secondaries/ad.repository'; | ||||
| import { AutomapperModule } from '@automapper/nestjs'; | ||||
| import { classes } from '@automapper/classes'; | ||||
| import { IDefaultParams } from '../../domain/interfaces/default-params.interface'; | ||||
| 
 | ||||
| const mockAdRepository = {}; | ||||
| 
 | ||||
|  | @ -13,6 +14,12 @@ const mockMessager = { | |||
|   publish: jest.fn().mockImplementation(), | ||||
| }; | ||||
| 
 | ||||
| const defaultParams: IDefaultParams = { | ||||
|   DEFAULT_IDENTIFIER: 0, | ||||
|   MARGIN_DURATION: 900, | ||||
|   VALIDITY_DURATION: 365, | ||||
| }; | ||||
| 
 | ||||
| describe('MatchUseCase', () => { | ||||
|   let matchUseCase: MatchUseCase; | ||||
| 
 | ||||
|  | @ -52,7 +59,10 @@ describe('MatchUseCase', () => { | |||
|           lon: 3.045432, | ||||
|         }, | ||||
|       ]; | ||||
|       const matches = await matchUseCase.execute(new MatchQuery(matchRequest)); | ||||
|       matchRequest.departure = '2023-04-01 12:23:00'; | ||||
|       const matches = await matchUseCase.execute( | ||||
|         new MatchQuery(matchRequest, defaultParams), | ||||
|       ); | ||||
|       expect(matches.total).toBe(1); | ||||
|     }); | ||||
|   }); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue