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