time request
This commit is contained in:
		
							parent
							
								
									2ffa40aa53
								
							
						
					
					
						commit
						56bdd11970
					
				| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
import { Injectable } from '@nestjs/common';
 | 
			
		||||
import { ConfigService } from '@nestjs/config';
 | 
			
		||||
import { IDefaultParams } from '../../domain/interfaces/default-params.interface';
 | 
			
		||||
import { IDefaultParams } from '../../domain/interfaces/default-params.type';
 | 
			
		||||
 | 
			
		||||
@Injectable()
 | 
			
		||||
export class DefaultParamsProvider {
 | 
			
		||||
| 
						 | 
				
			
			@ -8,9 +8,11 @@ export class DefaultParamsProvider {
 | 
			
		|||
 | 
			
		||||
  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'),
 | 
			
		||||
      DEFAULT_IDENTIFIER: parseInt(
 | 
			
		||||
        this.configService.get('DEFAULT_IDENTIFIER'),
 | 
			
		||||
      ),
 | 
			
		||||
      MARGIN_DURATION: parseInt(this.configService.get('MARGIN_DURATION')),
 | 
			
		||||
      VALIDITY_DURATION: parseInt(this.configService.get('VALIDITY_DURATION')),
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,9 +0,0 @@
 | 
			
		|||
export type MarginDurations = {
 | 
			
		||||
  mon: number;
 | 
			
		||||
  tue: number;
 | 
			
		||||
  wed: number;
 | 
			
		||||
  thu: number;
 | 
			
		||||
  fri: number;
 | 
			
		||||
  sat: number;
 | 
			
		||||
  sun: number;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -11,16 +11,13 @@ import {
 | 
			
		|||
} from 'class-validator';
 | 
			
		||||
import { AutoMap } from '@automapper/classes';
 | 
			
		||||
import { Point } from '../entities/point.type';
 | 
			
		||||
import { Schedule } from './schedule.type';
 | 
			
		||||
import { MarginDurations } from './margin-durations.type';
 | 
			
		||||
import { Schedule } from '../entities/schedule.type';
 | 
			
		||||
import { MarginDurations } from '../entities/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
 | 
			
		||||
  implements IRequestTime, IRequestRole, IRequestPerson
 | 
			
		||||
{
 | 
			
		||||
export class MatchRequest implements IRequestTime, IRequestPerson {
 | 
			
		||||
  @IsArray()
 | 
			
		||||
  @AutoMap()
 | 
			
		||||
  waypoints: Array<Point>;
 | 
			
		||||
| 
						 | 
				
			
			@ -50,9 +47,9 @@ export class MatchRequest
 | 
			
		|||
  passenger: boolean;
 | 
			
		||||
 | 
			
		||||
  @IsOptional()
 | 
			
		||||
  @IsInt()
 | 
			
		||||
  @IsString()
 | 
			
		||||
  @AutoMap()
 | 
			
		||||
  toDate: number;
 | 
			
		||||
  toDate: string;
 | 
			
		||||
 | 
			
		||||
  @IsOptional()
 | 
			
		||||
  @IsInt()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,9 +0,0 @@
 | 
			
		|||
export type Schedule = {
 | 
			
		||||
  mon: string;
 | 
			
		||||
  tue: string;
 | 
			
		||||
  wed: string;
 | 
			
		||||
  thu: string;
 | 
			
		||||
  fri: string;
 | 
			
		||||
  sat: string;
 | 
			
		||||
  sun: string;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,9 @@
 | 
			
		|||
export type MarginDurations = {
 | 
			
		||||
  mon?: number;
 | 
			
		||||
  tue?: number;
 | 
			
		||||
  wed?: number;
 | 
			
		||||
  thu?: number;
 | 
			
		||||
  fri?: number;
 | 
			
		||||
  sat?: number;
 | 
			
		||||
  sun?: number;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,9 @@
 | 
			
		|||
export type Schedule = {
 | 
			
		||||
  mon?: string;
 | 
			
		||||
  tue?: string;
 | 
			
		||||
  wed?: string;
 | 
			
		||||
  thu?: string;
 | 
			
		||||
  fri?: string;
 | 
			
		||||
  sat?: string;
 | 
			
		||||
  sun?: string;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,10 @@
 | 
			
		|||
import { MatcherException } from '../../exceptions/matcher.exception';
 | 
			
		||||
import { MarginDurations } from './margin-durations.type';
 | 
			
		||||
import { IRequestTime } from '../interfaces/time-request.interface';
 | 
			
		||||
import { TimingFrequency } from './timing';
 | 
			
		||||
import { TimingDays, TimingFrequency } from './timing';
 | 
			
		||||
import { Schedule } from './schedule.type';
 | 
			
		||||
 | 
			
		||||
const days = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'];
 | 
			
		||||
 | 
			
		||||
export class Time {
 | 
			
		||||
  _timeRequest: IRequestTime;
 | 
			
		||||
| 
						 | 
				
			
			@ -9,8 +13,8 @@ export class Time {
 | 
			
		|||
  frequency: TimingFrequency;
 | 
			
		||||
  fromDate: Date;
 | 
			
		||||
  toDate: Date;
 | 
			
		||||
  schedule: Array<Date>;
 | 
			
		||||
  marginDurations: Array<number>;
 | 
			
		||||
  schedule: Schedule;
 | 
			
		||||
  marginDurations: MarginDurations;
 | 
			
		||||
 | 
			
		||||
  constructor(
 | 
			
		||||
    timeRequest: IRequestTime,
 | 
			
		||||
| 
						 | 
				
			
			@ -20,12 +24,25 @@ export class Time {
 | 
			
		|||
    this._timeRequest = timeRequest;
 | 
			
		||||
    this._defaultMarginDuration = defaultMarginDuration;
 | 
			
		||||
    this._defaultValidityDuration = defaultValidityDuration;
 | 
			
		||||
    this.schedule = {};
 | 
			
		||||
    this.marginDurations = {
 | 
			
		||||
      mon: defaultMarginDuration,
 | 
			
		||||
      tue: defaultMarginDuration,
 | 
			
		||||
      wed: defaultMarginDuration,
 | 
			
		||||
      thu: defaultMarginDuration,
 | 
			
		||||
      fri: defaultMarginDuration,
 | 
			
		||||
      sat: defaultMarginDuration,
 | 
			
		||||
      sun: defaultMarginDuration,
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  init() {
 | 
			
		||||
    this._validateBaseDate();
 | 
			
		||||
    this._validatePunctualDate();
 | 
			
		||||
    this._validateRecurrentDate();
 | 
			
		||||
    this._validatePunctualRequest();
 | 
			
		||||
    this._validateRecurrentRequest();
 | 
			
		||||
    this._setPunctualRequest();
 | 
			
		||||
    this._setRecurrentRequest();
 | 
			
		||||
    this._setMargindurations();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _validateBaseDate() {
 | 
			
		||||
| 
						 | 
				
			
			@ -34,25 +51,118 @@ export class Time {
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _validatePunctualDate() {
 | 
			
		||||
  _validatePunctualRequest() {
 | 
			
		||||
    if (this._timeRequest.departure) {
 | 
			
		||||
      this.fromDate = new Date(this._timeRequest.departure);
 | 
			
		||||
      this.fromDate = this.toDate = new Date(this._timeRequest.departure);
 | 
			
		||||
      if (!this._isDate(this.fromDate)) {
 | 
			
		||||
        throw new MatcherException(3, 'Wrong departure date');
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _validateRecurrentDate() {
 | 
			
		||||
  _validateRecurrentRequest() {
 | 
			
		||||
    if (this._timeRequest.fromDate) {
 | 
			
		||||
      this.fromDate = new Date(this._timeRequest.fromDate);
 | 
			
		||||
      if (!this._isDate(this.fromDate)) {
 | 
			
		||||
        throw new MatcherException(3, 'Wrong fromDate');
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if (this._timeRequest.toDate) {
 | 
			
		||||
      this.toDate = new Date(this._timeRequest.toDate);
 | 
			
		||||
      if (!this._isDate(this.toDate)) {
 | 
			
		||||
        throw new MatcherException(3, 'Wrong toDate');
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if (this._timeRequest.fromDate) {
 | 
			
		||||
      this._validateSchedule();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _isDate(date: Date) {
 | 
			
		||||
    return date instanceof Date && isFinite(+date);
 | 
			
		||||
  _validateSchedule() {
 | 
			
		||||
    if (!this._timeRequest.schedule) {
 | 
			
		||||
      throw new MatcherException(3, 'Schedule is required');
 | 
			
		||||
    }
 | 
			
		||||
    if (
 | 
			
		||||
      !Object.keys(this._timeRequest.schedule).some((elem) =>
 | 
			
		||||
        days.includes(elem),
 | 
			
		||||
      )
 | 
			
		||||
    ) {
 | 
			
		||||
      throw new MatcherException(3, 'No valid day in the given schedule');
 | 
			
		||||
    }
 | 
			
		||||
    Object.keys(this._timeRequest.schedule).map((day) => {
 | 
			
		||||
      const time = new Date('1970-01-01 ' + this._timeRequest.schedule[day]);
 | 
			
		||||
      if (!this._isDate(time)) {
 | 
			
		||||
        throw new MatcherException(3, `Wrong time for ${day} in schedule`);
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _setPunctualRequest() {
 | 
			
		||||
    if (this._timeRequest.departure) {
 | 
			
		||||
      this.frequency = TimingFrequency.FREQUENCY_PUNCTUAL;
 | 
			
		||||
      this.schedule[TimingDays[this.fromDate.getDay()]] =
 | 
			
		||||
        this.fromDate.getHours() + ':' + this.fromDate.getMinutes();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _setRecurrentRequest() {
 | 
			
		||||
    if (this._timeRequest.fromDate) {
 | 
			
		||||
      this.frequency = TimingFrequency.FREQUENCY_RECURRENT;
 | 
			
		||||
      if (!this.toDate) {
 | 
			
		||||
        this.toDate = this._addDays(
 | 
			
		||||
          this.fromDate,
 | 
			
		||||
          this._defaultValidityDuration,
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
      this._setSchedule();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _setSchedule() {
 | 
			
		||||
    Object.keys(this._timeRequest.schedule).map((day) => {
 | 
			
		||||
      this.schedule[day] = this._timeRequest.schedule[day];
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _setMargindurations() {
 | 
			
		||||
    if (this._timeRequest.marginDuration) {
 | 
			
		||||
      const duration = Math.abs(this._timeRequest.marginDuration);
 | 
			
		||||
      this.marginDurations = {
 | 
			
		||||
        mon: duration,
 | 
			
		||||
        tue: duration,
 | 
			
		||||
        wed: duration,
 | 
			
		||||
        thu: duration,
 | 
			
		||||
        fri: duration,
 | 
			
		||||
        sat: duration,
 | 
			
		||||
        sun: duration,
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
    if (this._timeRequest.marginDurations) {
 | 
			
		||||
      if (
 | 
			
		||||
        !Object.keys(this._timeRequest.marginDurations).some((elem) =>
 | 
			
		||||
          days.includes(elem),
 | 
			
		||||
        )
 | 
			
		||||
      ) {
 | 
			
		||||
        throw new MatcherException(
 | 
			
		||||
          3,
 | 
			
		||||
          'No valid day in the given margin durations',
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
      Object.keys(this._timeRequest.marginDurations).map((day) => {
 | 
			
		||||
        this.marginDurations[day] = Math.abs(
 | 
			
		||||
          this._timeRequest.marginDurations[day],
 | 
			
		||||
        );
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _isDate = (date: Date): boolean => {
 | 
			
		||||
    return date instanceof Date && isFinite(+date);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  _addDays = (date: Date, days: number): Date => {
 | 
			
		||||
    const result = new Date(date);
 | 
			
		||||
    result.setDate(result.getDate() + days);
 | 
			
		||||
    return result;
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,11 +4,11 @@ export enum TimingFrequency {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
export enum TimingDays {
 | 
			
		||||
  'sun',
 | 
			
		||||
  'mon',
 | 
			
		||||
  'tue',
 | 
			
		||||
  'wed',
 | 
			
		||||
  'thu',
 | 
			
		||||
  'fri',
 | 
			
		||||
  'sat',
 | 
			
		||||
  'sun',
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
export interface IDefaultParams {
 | 
			
		||||
export type IDefaultParams = {
 | 
			
		||||
  DEFAULT_IDENTIFIER: number;
 | 
			
		||||
  MARGIN_DURATION: number;
 | 
			
		||||
  VALIDITY_DURATION: number;
 | 
			
		||||
}
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -1,3 +1,3 @@
 | 
			
		|||
export interface IRequestPerson {
 | 
			
		||||
  identifier: number;
 | 
			
		||||
  identifier?: number;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +0,0 @@
 | 
			
		|||
export interface IRequestRole {
 | 
			
		||||
  driver: boolean;
 | 
			
		||||
  passenger: boolean;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,7 +1,11 @@
 | 
			
		|||
import { Schedule } from '../dtos/schedule.type';
 | 
			
		||||
import { MarginDurations } from '../entities/margin-durations.type';
 | 
			
		||||
import { Schedule } from '../entities/schedule.type';
 | 
			
		||||
 | 
			
		||||
export interface IRequestTime {
 | 
			
		||||
  departure?: string;
 | 
			
		||||
  fromDate?: string;
 | 
			
		||||
  toDate?: string;
 | 
			
		||||
  schedule?: Schedule;
 | 
			
		||||
  marginDuration?: number;
 | 
			
		||||
  marginDurations?: MarginDurations;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,36 +5,30 @@ 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 { IDefaultParams } from '../domain/interfaces/default-params.interface';
 | 
			
		||||
import { IDefaultParams } from '../domain/interfaces/default-params.type';
 | 
			
		||||
 | 
			
		||||
export class MatchQuery {
 | 
			
		||||
  private readonly _matchRequest: MatchRequest;
 | 
			
		||||
  private readonly _defaultParams: IDefaultParams;
 | 
			
		||||
  person: Person;
 | 
			
		||||
  exclusions: Array<number>;
 | 
			
		||||
  time: Time;
 | 
			
		||||
  geography: Geography;
 | 
			
		||||
  roles: Array<Role>;
 | 
			
		||||
  time: Time;
 | 
			
		||||
  exclusions: Array<number>;
 | 
			
		||||
  geography: Geography;
 | 
			
		||||
  requirement: Requirement;
 | 
			
		||||
  settings: Settings;
 | 
			
		||||
 | 
			
		||||
  constructor(matchRequest: MatchRequest, defaultParams: IDefaultParams) {
 | 
			
		||||
    this._matchRequest = matchRequest;
 | 
			
		||||
    this._defaultParams = defaultParams;
 | 
			
		||||
    this._initialize();
 | 
			
		||||
    this._setPerson();
 | 
			
		||||
    this._setExclusions();
 | 
			
		||||
    this._setRoles();
 | 
			
		||||
    this._setTime();
 | 
			
		||||
    // console.log(this);
 | 
			
		||||
    this._initialize();
 | 
			
		||||
    this._setExclusions();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _initialize() {
 | 
			
		||||
    if (
 | 
			
		||||
      this._matchRequest.driver === undefined &&
 | 
			
		||||
      this._matchRequest.passenger === undefined
 | 
			
		||||
    )
 | 
			
		||||
      this._matchRequest.passenger = true;
 | 
			
		||||
    this.geography = new Geography();
 | 
			
		||||
    this.requirement = new Requirement();
 | 
			
		||||
    this.settings = new Settings();
 | 
			
		||||
| 
						 | 
				
			
			@ -49,18 +43,11 @@ export class MatchQuery {
 | 
			
		|||
    this.person.init();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _setExclusions() {
 | 
			
		||||
    this.exclusions = [];
 | 
			
		||||
    if (this._matchRequest.identifier)
 | 
			
		||||
      this.exclusions.push(this._matchRequest.identifier);
 | 
			
		||||
    if (this._matchRequest.exclusions)
 | 
			
		||||
      this.exclusions.push(...this._matchRequest.exclusions);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _setRoles() {
 | 
			
		||||
    this.roles = [];
 | 
			
		||||
    if (this._matchRequest.driver) this.roles.push(Role.DRIVER);
 | 
			
		||||
    if (this._matchRequest.passenger) this.roles.push(Role.PASSENGER);
 | 
			
		||||
    if (this.roles.length == 0) this.roles.push(Role.PASSENGER);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _setTime() {
 | 
			
		||||
| 
						 | 
				
			
			@ -71,4 +58,12 @@ export class MatchQuery {
 | 
			
		|||
    );
 | 
			
		||||
    this.time.init();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _setExclusions() {
 | 
			
		||||
    this.exclusions = [];
 | 
			
		||||
    if (this._matchRequest.identifier)
 | 
			
		||||
      this.exclusions.push(this._matchRequest.identifier);
 | 
			
		||||
    if (this._matchRequest.exclusions)
 | 
			
		||||
      this.exclusions.push(...this._matchRequest.exclusions);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
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';
 | 
			
		||||
import { IDefaultParams } from '../../domain/interfaces/default-params.type';
 | 
			
		||||
 | 
			
		||||
const mockConfigService = {
 | 
			
		||||
  get: jest.fn().mockImplementationOnce(() => 99),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +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';
 | 
			
		||||
import { IDefaultParams } from '../../domain/interfaces/default-params.type';
 | 
			
		||||
 | 
			
		||||
const mockAdRepository = {};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,40 @@
 | 
			
		|||
import { Person } from '../../domain/entities/person';
 | 
			
		||||
 | 
			
		||||
const DEFAULT_IDENTIFIER = 0;
 | 
			
		||||
const MARGIN_DURATION = 900;
 | 
			
		||||
 | 
			
		||||
describe('Person entity', () => {
 | 
			
		||||
  it('should be defined', () => {
 | 
			
		||||
    const person = new Person(
 | 
			
		||||
      {
 | 
			
		||||
        identifier: 1,
 | 
			
		||||
      },
 | 
			
		||||
      DEFAULT_IDENTIFIER,
 | 
			
		||||
      MARGIN_DURATION,
 | 
			
		||||
    );
 | 
			
		||||
    expect(person).toBeDefined();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('init', () => {
 | 
			
		||||
    it('should initialize a person with an identifier', () => {
 | 
			
		||||
      const person = new Person(
 | 
			
		||||
        {
 | 
			
		||||
          identifier: 1,
 | 
			
		||||
        },
 | 
			
		||||
        DEFAULT_IDENTIFIER,
 | 
			
		||||
        MARGIN_DURATION,
 | 
			
		||||
      );
 | 
			
		||||
      person.init();
 | 
			
		||||
      expect(person.identifier).toBe(1);
 | 
			
		||||
      expect(person.marginDurations[0]).toBe(900);
 | 
			
		||||
      expect(person.marginDurations[6]).toBe(900);
 | 
			
		||||
    });
 | 
			
		||||
    it('should initialize a person without an identifier', () => {
 | 
			
		||||
      const person = new Person({}, DEFAULT_IDENTIFIER, MARGIN_DURATION);
 | 
			
		||||
      person.init();
 | 
			
		||||
      expect(person.identifier).toBe(0);
 | 
			
		||||
      expect(person.marginDurations[0]).toBe(900);
 | 
			
		||||
      expect(person.marginDurations[6]).toBe(900);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			@ -1,31 +1,14 @@
 | 
			
		|||
import { Time } from '../../domain/entities/time';
 | 
			
		||||
import { IRequestTime } from '../../domain/interfaces/time-request.interface';
 | 
			
		||||
 | 
			
		||||
const MARGIN_DURATION = 900;
 | 
			
		||||
const VALIDITY_DURATION = 365;
 | 
			
		||||
 | 
			
		||||
const punctualTimeRequest: IRequestTime = {
 | 
			
		||||
  departure: '2023-04-01 12:24:00',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const invalidPunctualTimeRequest: IRequestTime = {
 | 
			
		||||
  departure: '2023-15-01 12:24:00',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const recurrentTimeRequest: IRequestTime = {
 | 
			
		||||
  fromDate: '2023-04-01',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const invalidRecurrentTimeRequest: IRequestTime = {
 | 
			
		||||
  fromDate: '2023-15-01',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const expectedPunctualFromDate = new Date(punctualTimeRequest.departure);
 | 
			
		||||
 | 
			
		||||
describe('Time entity', () => {
 | 
			
		||||
  it('should be defined', () => {
 | 
			
		||||
    const time = new Time(
 | 
			
		||||
      punctualTimeRequest,
 | 
			
		||||
      {
 | 
			
		||||
        departure: '2023-04-01 12:24:00',
 | 
			
		||||
      },
 | 
			
		||||
      MARGIN_DURATION,
 | 
			
		||||
      VALIDITY_DURATION,
 | 
			
		||||
    );
 | 
			
		||||
| 
						 | 
				
			
			@ -35,24 +18,74 @@ describe('Time entity', () => {
 | 
			
		|||
  describe('init', () => {
 | 
			
		||||
    it('should initialize a punctual time request', () => {
 | 
			
		||||
      const time = new Time(
 | 
			
		||||
        punctualTimeRequest,
 | 
			
		||||
        {
 | 
			
		||||
          departure: '2023-04-01 12:24:00',
 | 
			
		||||
        },
 | 
			
		||||
        MARGIN_DURATION,
 | 
			
		||||
        VALIDITY_DURATION,
 | 
			
		||||
      );
 | 
			
		||||
      time.init();
 | 
			
		||||
      expect(time.fromDate.getFullYear()).toBe(
 | 
			
		||||
        expectedPunctualFromDate.getFullYear(),
 | 
			
		||||
        new Date('2023-04-01 12:24:00').getFullYear(),
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('should initialize a punctual time request with specific single margin duration', () => {
 | 
			
		||||
      const time = new Time(
 | 
			
		||||
        {
 | 
			
		||||
          departure: '2023-04-01 12:24:00',
 | 
			
		||||
          marginDuration: 300,
 | 
			
		||||
        },
 | 
			
		||||
        MARGIN_DURATION,
 | 
			
		||||
        VALIDITY_DURATION,
 | 
			
		||||
      );
 | 
			
		||||
      time.init();
 | 
			
		||||
      expect(time.marginDurations['tue']).toBe(300);
 | 
			
		||||
    });
 | 
			
		||||
    it('should initialize a punctual time request with specific margin durations', () => {
 | 
			
		||||
      const time = new Time(
 | 
			
		||||
        {
 | 
			
		||||
          departure: '2023-04-01 12:24:00',
 | 
			
		||||
          marginDurations: {
 | 
			
		||||
            sat: 350,
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
        MARGIN_DURATION,
 | 
			
		||||
        VALIDITY_DURATION,
 | 
			
		||||
      );
 | 
			
		||||
      time.init();
 | 
			
		||||
      expect(time.marginDurations['tue']).toBe(900);
 | 
			
		||||
      expect(time.marginDurations['sat']).toBe(350);
 | 
			
		||||
    });
 | 
			
		||||
    it('should initialize a punctual time request with specific single margin duration and margin durations', () => {
 | 
			
		||||
      const time = new Time(
 | 
			
		||||
        {
 | 
			
		||||
          departure: '2023-04-01 12:24:00',
 | 
			
		||||
          marginDuration: 500,
 | 
			
		||||
          marginDurations: {
 | 
			
		||||
            sat: 350,
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
        MARGIN_DURATION,
 | 
			
		||||
        VALIDITY_DURATION,
 | 
			
		||||
      );
 | 
			
		||||
      time.init();
 | 
			
		||||
      expect(time.marginDurations['tue']).toBe(500);
 | 
			
		||||
      expect(time.marginDurations['sat']).toBe(350);
 | 
			
		||||
    });
 | 
			
		||||
    it('should initialize a recurrent time request', () => {
 | 
			
		||||
      const time = new Time(
 | 
			
		||||
        recurrentTimeRequest,
 | 
			
		||||
        {
 | 
			
		||||
          fromDate: '2023-04-01',
 | 
			
		||||
          schedule: {
 | 
			
		||||
            mon: '12:00',
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
        MARGIN_DURATION,
 | 
			
		||||
        VALIDITY_DURATION,
 | 
			
		||||
      );
 | 
			
		||||
      time.init();
 | 
			
		||||
      expect(time.fromDate.getFullYear()).toBe(
 | 
			
		||||
        expectedPunctualFromDate.getFullYear(),
 | 
			
		||||
        new Date('2023-04-01').getFullYear(),
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('should throw an exception if no date is provided', () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -61,19 +94,82 @@ describe('Time entity', () => {
 | 
			
		|||
    });
 | 
			
		||||
    it('should throw an exception if punctual date is invalid', () => {
 | 
			
		||||
      const time = new Time(
 | 
			
		||||
        invalidPunctualTimeRequest,
 | 
			
		||||
        {
 | 
			
		||||
          departure: '2023-15-01 12:24:00',
 | 
			
		||||
        },
 | 
			
		||||
        MARGIN_DURATION,
 | 
			
		||||
        VALIDITY_DURATION,
 | 
			
		||||
      );
 | 
			
		||||
      expect(() => time.init()).toThrow();
 | 
			
		||||
    });
 | 
			
		||||
    it('should throw an exception if recuurent date is invalid', () => {
 | 
			
		||||
    it('should throw an exception if recurrent fromDate is invalid', () => {
 | 
			
		||||
      const time = new Time(
 | 
			
		||||
        invalidRecurrentTimeRequest,
 | 
			
		||||
        {
 | 
			
		||||
          fromDate: '2023-15-01',
 | 
			
		||||
        },
 | 
			
		||||
        MARGIN_DURATION,
 | 
			
		||||
        VALIDITY_DURATION,
 | 
			
		||||
      );
 | 
			
		||||
      expect(() => time.init()).toThrow();
 | 
			
		||||
    });
 | 
			
		||||
    it('should throw an exception if recurrent toDate is invalid', () => {
 | 
			
		||||
      const time = new Time(
 | 
			
		||||
        {
 | 
			
		||||
          fromDate: '2023-04-01',
 | 
			
		||||
          toDate: '2023-13-01',
 | 
			
		||||
        },
 | 
			
		||||
        MARGIN_DURATION,
 | 
			
		||||
        VALIDITY_DURATION,
 | 
			
		||||
      );
 | 
			
		||||
      expect(() => time.init()).toThrow();
 | 
			
		||||
    });
 | 
			
		||||
    it('should throw an exception if schedule is missing', () => {
 | 
			
		||||
      const time = new Time(
 | 
			
		||||
        {
 | 
			
		||||
          fromDate: '2023-04-01',
 | 
			
		||||
          toDate: '2024-03-31',
 | 
			
		||||
        },
 | 
			
		||||
        MARGIN_DURATION,
 | 
			
		||||
        VALIDITY_DURATION,
 | 
			
		||||
      );
 | 
			
		||||
      expect(() => time.init()).toThrow();
 | 
			
		||||
    });
 | 
			
		||||
    it('should throw an exception if schedule is empty', () => {
 | 
			
		||||
      const time = new Time(
 | 
			
		||||
        {
 | 
			
		||||
          fromDate: '2023-04-01',
 | 
			
		||||
          toDate: '2024-03-31',
 | 
			
		||||
          schedule: {},
 | 
			
		||||
        },
 | 
			
		||||
        MARGIN_DURATION,
 | 
			
		||||
        VALIDITY_DURATION,
 | 
			
		||||
      );
 | 
			
		||||
      expect(() => time.init()).toThrow();
 | 
			
		||||
    });
 | 
			
		||||
    it('should throw an exception if schedule is invalid', () => {
 | 
			
		||||
      const time = new Time(
 | 
			
		||||
        {
 | 
			
		||||
          fromDate: '2023-04-01',
 | 
			
		||||
          toDate: '2024-03-31',
 | 
			
		||||
          schedule: {
 | 
			
		||||
            mon: '32:78',
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
        MARGIN_DURATION,
 | 
			
		||||
        VALIDITY_DURATION,
 | 
			
		||||
      );
 | 
			
		||||
      expect(() => time.init()).toThrow();
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
  it('should throw an exception if margin durations is provided but empty', () => {
 | 
			
		||||
    const time = new Time(
 | 
			
		||||
      {
 | 
			
		||||
        departure: '2023-04-01 12:24:00',
 | 
			
		||||
        marginDurations: {},
 | 
			
		||||
      },
 | 
			
		||||
      MARGIN_DURATION,
 | 
			
		||||
      VALIDITY_DURATION,
 | 
			
		||||
    );
 | 
			
		||||
    expect(() => time.init()).toThrow();
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue