refactor health module, improve code coverage
This commit is contained in:
		
							parent
							
								
									b232247c93
								
							
						
					
					
						commit
						1989ff6e67
					
				| 
						 | 
					@ -14,6 +14,7 @@ import {
 | 
				
			||||||
} from '@mobicoop/configuration-module';
 | 
					} from '@mobicoop/configuration-module';
 | 
				
			||||||
import { EventEmitterModule } from '@nestjs/event-emitter';
 | 
					import { EventEmitterModule } from '@nestjs/event-emitter';
 | 
				
			||||||
import { RequestContextModule } from 'nestjs-request-context';
 | 
					import { RequestContextModule } from 'nestjs-request-context';
 | 
				
			||||||
 | 
					import { HealthModule } from '@modules/health/health.module';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Module({
 | 
					@Module({
 | 
				
			||||||
  imports: [
 | 
					  imports: [
 | 
				
			||||||
| 
						 | 
					@ -53,7 +54,7 @@ import { RequestContextModule } from 'nestjs-request-context';
 | 
				
			||||||
        propagateConfigurationQueue: 'ad-configuration-propagate',
 | 
					        propagateConfigurationQueue: 'ad-configuration-propagate',
 | 
				
			||||||
      }),
 | 
					      }),
 | 
				
			||||||
    }),
 | 
					    }),
 | 
				
			||||||
    // HealthModule,
 | 
					    HealthModule,
 | 
				
			||||||
    AdModule,
 | 
					    AdModule,
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
  controllers: [],
 | 
					  controllers: [],
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,10 @@ import { AggregateRoot, Mapper, RepositoryPort } from '../ddd';
 | 
				
			||||||
import { ObjectLiteral } from '../types';
 | 
					import { ObjectLiteral } from '../types';
 | 
				
			||||||
import { LoggerPort } from '../ports/logger.port';
 | 
					import { LoggerPort } from '../ports/logger.port';
 | 
				
			||||||
import { None, Option, Some } from 'oxide.ts';
 | 
					import { None, Option, Some } from 'oxide.ts';
 | 
				
			||||||
import { PrismaRepositoryPort } from '../ports/prisma-repository.port';
 | 
					import {
 | 
				
			||||||
 | 
					  PrismaRawRepositoryPort,
 | 
				
			||||||
 | 
					  PrismaRepositoryPort,
 | 
				
			||||||
 | 
					} from '../ports/prisma-repository.port';
 | 
				
			||||||
import { Prisma } from '@prisma/client';
 | 
					import { Prisma } from '@prisma/client';
 | 
				
			||||||
import { ConflictException, DatabaseErrorException } from '@libs/exceptions';
 | 
					import { ConflictException, DatabaseErrorException } from '@libs/exceptions';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,6 +17,7 @@ export abstract class PrismaRepositoryBase<
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  protected constructor(
 | 
					  protected constructor(
 | 
				
			||||||
    protected readonly prisma: PrismaRepositoryPort<Aggregate> | any,
 | 
					    protected readonly prisma: PrismaRepositoryPort<Aggregate> | any,
 | 
				
			||||||
 | 
					    protected readonly prismaRaw: PrismaRawRepositoryPort,
 | 
				
			||||||
    protected readonly mapper: Mapper<Aggregate, DbModel>,
 | 
					    protected readonly mapper: Mapper<Aggregate, DbModel>,
 | 
				
			||||||
    protected readonly eventEmitter: EventEmitter2,
 | 
					    protected readonly eventEmitter: EventEmitter2,
 | 
				
			||||||
    protected readonly logger: LoggerPort,
 | 
					    protected readonly logger: LoggerPort,
 | 
				
			||||||
| 
						 | 
					@ -43,9 +47,10 @@ export abstract class PrismaRepositoryBase<
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async healthCheck(): Promise<boolean> {
 | 
					  async healthCheck(): Promise<boolean> {
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      await this.prisma.$queryRaw`SELECT 1`;
 | 
					      await this.prismaRaw.$queryRaw`SELECT 1`;
 | 
				
			||||||
      return true;
 | 
					      return true;
 | 
				
			||||||
    } catch (e) {
 | 
					    } catch (e) {
 | 
				
			||||||
 | 
					      console.log(e);
 | 
				
			||||||
      if (e instanceof Prisma.PrismaClientKnownRequestError) {
 | 
					      if (e instanceof Prisma.PrismaClientKnownRequestError) {
 | 
				
			||||||
        throw new DatabaseErrorException(e.message);
 | 
					        throw new DatabaseErrorException(e.message);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,3 +2,10 @@ export interface PrismaRepositoryPort<Entity> {
 | 
				
			||||||
  findUnique(options: any): Promise<Entity>;
 | 
					  findUnique(options: any): Promise<Entity>;
 | 
				
			||||||
  create(entity: any): Promise<Entity>;
 | 
					  create(entity: any): Promise<Entity>;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface PrismaRawRepositoryPort {
 | 
				
			||||||
 | 
					  $queryRaw<T = unknown>(
 | 
				
			||||||
 | 
					    query: TemplateStringsArray,
 | 
				
			||||||
 | 
					    ...values: any[]
 | 
				
			||||||
 | 
					  ): Promise<T>;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,5 +47,12 @@ import { PrismaService } from '@libs/db/prisma.service';
 | 
				
			||||||
      useClass: TimezoneFinder,
 | 
					      useClass: TimezoneFinder,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
 | 
					  exports: [
 | 
				
			||||||
 | 
					    PrismaService,
 | 
				
			||||||
 | 
					    AdMapper,
 | 
				
			||||||
 | 
					    AD_REPOSITORY,
 | 
				
			||||||
 | 
					    PARAMS_PROVIDER,
 | 
				
			||||||
 | 
					    TIMEZONE_FINDER,
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
export class AdModule {}
 | 
					export class AdModule {}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -66,6 +66,12 @@ export class AdRepository
 | 
				
			||||||
    mapper: AdMapper,
 | 
					    mapper: AdMapper,
 | 
				
			||||||
    eventEmitter: EventEmitter2,
 | 
					    eventEmitter: EventEmitter2,
 | 
				
			||||||
  ) {
 | 
					  ) {
 | 
				
			||||||
    super(prisma.ad, mapper, eventEmitter, new Logger(AdRepository.name));
 | 
					    super(
 | 
				
			||||||
 | 
					      prisma.ad,
 | 
				
			||||||
 | 
					      prisma,
 | 
				
			||||||
 | 
					      mapper,
 | 
				
			||||||
 | 
					      eventEmitter,
 | 
				
			||||||
 | 
					      new Logger(AdRepository.name),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,140 +0,0 @@
 | 
				
			||||||
import { Day } from '../../../core/_old/types/day.enum';
 | 
					 | 
				
			||||||
import { CreateAdRequestDTO } from '../../../interface/commands/create-ad.request.dto';
 | 
					 | 
				
			||||||
import { ScheduleDTO } from '../../../core/dtos/schedule.dto';
 | 
					 | 
				
			||||||
import { FrequencyNormalizer } from '../../../core/entities/frequency.normalizer';
 | 
					 | 
				
			||||||
import { Frequency } from '../../../interface/commands/frequency.enum';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
describe('recurrent normalizer transformer for punctual ad ', () => {
 | 
					 | 
				
			||||||
  const frequencyNormalizer = new FrequencyNormalizer();
 | 
					 | 
				
			||||||
  it('should transform punctual ad into recurrent ad', () => {
 | 
					 | 
				
			||||||
    const punctualAd: CreateAdRequestDTO = {
 | 
					 | 
				
			||||||
      userUuid: 'cb7ad514-ad0d-463f-9041-b79f9afe33aa',
 | 
					 | 
				
			||||||
      frequency: Frequency.PUNCTUAL,
 | 
					 | 
				
			||||||
      departureDate: new Date('2023-03-05T12:39:39+02:00'),
 | 
					 | 
				
			||||||
      waypoints: [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          position: 0,
 | 
					 | 
				
			||||||
          lon: 48.68944505415954,
 | 
					 | 
				
			||||||
          lat: 6.176510296462267,
 | 
					 | 
				
			||||||
          houseNumber: '5',
 | 
					 | 
				
			||||||
          street: 'Avenue Foch',
 | 
					 | 
				
			||||||
          locality: 'Nancy',
 | 
					 | 
				
			||||||
          postalCode: '54000',
 | 
					 | 
				
			||||||
          country: 'France',
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          position: 1,
 | 
					 | 
				
			||||||
          lon: 48.8566,
 | 
					 | 
				
			||||||
          lat: 2.3522,
 | 
					 | 
				
			||||||
          locality: 'Paris',
 | 
					 | 
				
			||||||
          postalCode: '75000',
 | 
					 | 
				
			||||||
          country: 'France',
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    // expect(frequencyNormalizer.fromDateResolver(punctualAd)).toStrictEqual(
 | 
					 | 
				
			||||||
    //   new Date('2023-03-05T12:39:39Z'),
 | 
					 | 
				
			||||||
    // );
 | 
					 | 
				
			||||||
    // expect(frequencyNormalizer.toDateResolver(punctualAd)).toStrictEqual(
 | 
					 | 
				
			||||||
    //   new Date('2023-03-05T12:39:39Z'),
 | 
					 | 
				
			||||||
    // );
 | 
					 | 
				
			||||||
    // expect(
 | 
					 | 
				
			||||||
    //   frequencyNormalizer.scheduleResolver(punctualAd, Day.mon),
 | 
					 | 
				
			||||||
    // ).toBeUndefined();
 | 
					 | 
				
			||||||
    // expect(
 | 
					 | 
				
			||||||
    //   frequencyNormalizer.scheduleResolver(punctualAd, Day.tue),
 | 
					 | 
				
			||||||
    // ).toBeUndefined();
 | 
					 | 
				
			||||||
    // expect(
 | 
					 | 
				
			||||||
    //   frequencyNormalizer.scheduleResolver(punctualAd, Day.wed),
 | 
					 | 
				
			||||||
    // ).toBeUndefined();
 | 
					 | 
				
			||||||
    // expect(
 | 
					 | 
				
			||||||
    //   frequencyNormalizer.scheduleResolver(punctualAd, Day.thu),
 | 
					 | 
				
			||||||
    // ).toBeUndefined();
 | 
					 | 
				
			||||||
    // expect(
 | 
					 | 
				
			||||||
    //   frequencyNormalizer.scheduleResolver(punctualAd, Day.fri),
 | 
					 | 
				
			||||||
    // ).toBeUndefined();
 | 
					 | 
				
			||||||
    // expect(
 | 
					 | 
				
			||||||
    //   frequencyNormalizer.scheduleResolver(punctualAd, Day.sat),
 | 
					 | 
				
			||||||
    // ).toBeUndefined();
 | 
					 | 
				
			||||||
    expect(frequencyNormalizer.scheduleResolver(punctualAd, Day.sun)).toBe(
 | 
					 | 
				
			||||||
      '12:39',
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
  // it('should leave recurrent ad as is', () => {
 | 
					 | 
				
			||||||
  //   const recurrentAd: CreateAdRequest = {
 | 
					 | 
				
			||||||
  //     userUuid: '',
 | 
					 | 
				
			||||||
  //     frequency: Frequency.RECURRENT,
 | 
					 | 
				
			||||||
  //     schedule: {
 | 
					 | 
				
			||||||
  //       mon: '08:30',
 | 
					 | 
				
			||||||
  //       tue: '08:30',
 | 
					 | 
				
			||||||
  //       wed: '09:00',
 | 
					 | 
				
			||||||
  //       fri: '09:00',
 | 
					 | 
				
			||||||
  //     },
 | 
					 | 
				
			||||||
  //     waypoints: [],
 | 
					 | 
				
			||||||
  //   };
 | 
					 | 
				
			||||||
  //   expect(frequencyNormalizer.fromDateResolver(recurrentAd)).toBe(
 | 
					 | 
				
			||||||
  //     recurrentAd.departure,
 | 
					 | 
				
			||||||
  //   );
 | 
					 | 
				
			||||||
  //   expect(frequencyNormalizer.toDateResolver(recurrentAd)).toBe(
 | 
					 | 
				
			||||||
  //     recurrentAd.departure,
 | 
					 | 
				
			||||||
  //   );
 | 
					 | 
				
			||||||
  //   expect(frequencyNormalizer.scheduleResolver(recurrentAd, Day.mon)).toBe(
 | 
					 | 
				
			||||||
  //     recurrentAd.schedule.mon,
 | 
					 | 
				
			||||||
  //   );
 | 
					 | 
				
			||||||
  //   expect(frequencyNormalizer.scheduleResolver(recurrentAd, Day.tue)).toBe(
 | 
					 | 
				
			||||||
  //     recurrentAd.schedule.tue,
 | 
					 | 
				
			||||||
  //   );
 | 
					 | 
				
			||||||
  //   expect(frequencyNormalizer.scheduleResolver(recurrentAd, Day.wed)).toBe(
 | 
					 | 
				
			||||||
  //     recurrentAd.schedule.wed,
 | 
					 | 
				
			||||||
  //   );
 | 
					 | 
				
			||||||
  //   expect(frequencyNormalizer.scheduleResolver(recurrentAd, Day.thu)).toBe(
 | 
					 | 
				
			||||||
  //     recurrentAd.schedule.thu,
 | 
					 | 
				
			||||||
  //   );
 | 
					 | 
				
			||||||
  //   expect(frequencyNormalizer.scheduleResolver(recurrentAd, Day.fri)).toBe(
 | 
					 | 
				
			||||||
  //     recurrentAd.schedule.fri,
 | 
					 | 
				
			||||||
  //   );
 | 
					 | 
				
			||||||
  //   expect(frequencyNormalizer.scheduleResolver(recurrentAd, Day.sat)).toBe(
 | 
					 | 
				
			||||||
  //     recurrentAd.schedule.sat,
 | 
					 | 
				
			||||||
  //   );
 | 
					 | 
				
			||||||
  //   expect(frequencyNormalizer.scheduleResolver(recurrentAd, Day.sun)).toBe(
 | 
					 | 
				
			||||||
  //     recurrentAd.schedule.sun,
 | 
					 | 
				
			||||||
  //   );
 | 
					 | 
				
			||||||
  // });
 | 
					 | 
				
			||||||
  // it('should pass for each day of the week of a deprarture ', () => {
 | 
					 | 
				
			||||||
  //   const punctualAd: CreateAdRequest = {
 | 
					 | 
				
			||||||
  //     userUuid: '',
 | 
					 | 
				
			||||||
  //     frequency: Frequency.PUNCTUAL,
 | 
					 | 
				
			||||||
  //     departure: undefined,
 | 
					 | 
				
			||||||
  //     schedule: {} as ScheduleDTO,
 | 
					 | 
				
			||||||
  //     waypoints: [],
 | 
					 | 
				
			||||||
  //   };
 | 
					 | 
				
			||||||
  //   punctualAd.departure = new Date('05-01-2023 ');
 | 
					 | 
				
			||||||
  //   expect(frequencyNormalizer.scheduleResolver(punctualAd, Day.mon)).toBe(
 | 
					 | 
				
			||||||
  //     '00:00',
 | 
					 | 
				
			||||||
  //   );
 | 
					 | 
				
			||||||
  //   punctualAd.departure = new Date('05-02-2023 06:32:45');
 | 
					 | 
				
			||||||
  //   expect(frequencyNormalizer.scheduleResolver(punctualAd, Day.tue)).toBe(
 | 
					 | 
				
			||||||
  //     '06:32',
 | 
					 | 
				
			||||||
  //   );
 | 
					 | 
				
			||||||
  //   punctualAd.departure = new Date('05-03-2023 10:21');
 | 
					 | 
				
			||||||
  //   expect(frequencyNormalizer.scheduleResolver(punctualAd, Day.wed)).toBe(
 | 
					 | 
				
			||||||
  //     '10:21',
 | 
					 | 
				
			||||||
  //   );
 | 
					 | 
				
			||||||
  //   punctualAd.departure = new Date('05-04-2023 11:06:00');
 | 
					 | 
				
			||||||
  //   expect(frequencyNormalizer.scheduleResolver(punctualAd, Day.thu)).toBe(
 | 
					 | 
				
			||||||
  //     '11:06',
 | 
					 | 
				
			||||||
  //   );
 | 
					 | 
				
			||||||
  //   punctualAd.departure = new Date('05-05-2023 05:20');
 | 
					 | 
				
			||||||
  //   expect(frequencyNormalizer.scheduleResolver(punctualAd, Day.fri)).toBe(
 | 
					 | 
				
			||||||
  //     '05:20',
 | 
					 | 
				
			||||||
  //   );
 | 
					 | 
				
			||||||
  //   punctualAd.departure = new Date('05-06-2023');
 | 
					 | 
				
			||||||
  //   expect(frequencyNormalizer.scheduleResolver(punctualAd, Day.sat)).toBe(
 | 
					 | 
				
			||||||
  //     '00:00',
 | 
					 | 
				
			||||||
  //   );
 | 
					 | 
				
			||||||
  //   punctualAd.departure = new Date('05-07-2023');
 | 
					 | 
				
			||||||
  //   expect(frequencyNormalizer.scheduleResolver(punctualAd, Day.sun)).toBe(
 | 
					 | 
				
			||||||
  //     '00:00',
 | 
					 | 
				
			||||||
  //   );
 | 
					 | 
				
			||||||
  // });
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,15 +0,0 @@
 | 
				
			||||||
import { intToFrequency } from '../../../core/dtos/validators/frequency.mapping';
 | 
					 | 
				
			||||||
import { Frequency } from '../../../interface/commands/frequency.enum';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
describe('frequency mapping function ', () => {
 | 
					 | 
				
			||||||
  it('should return punctual', () => {
 | 
					 | 
				
			||||||
    expect(intToFrequency(1)).toBe(Frequency.PUNCTUAL);
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
  it('should return recurrent', () => {
 | 
					 | 
				
			||||||
    expect(intToFrequency(2)).toBe(Frequency.RECURRENT);
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
  it('should throw an error if frequency is unknown', () => {
 | 
					 | 
				
			||||||
    expect(() => intToFrequency(0)).toThrow();
 | 
					 | 
				
			||||||
    expect(() => intToFrequency(3)).toThrow();
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,93 +0,0 @@
 | 
				
			||||||
import { isPunctualOrRecurrent } from '../../../core/dtos/validators/is-punctual-or-recurrent';
 | 
					 | 
				
			||||||
import { Frequency } from '../../../interface/commands/frequency.enum';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
describe('punctual or recurrent validators', () => {
 | 
					 | 
				
			||||||
  describe('punctual case ', () => {
 | 
					 | 
				
			||||||
    describe('valid cases', () => {
 | 
					 | 
				
			||||||
      it('should validate with valid departure', () => {
 | 
					 | 
				
			||||||
        expect(
 | 
					 | 
				
			||||||
          isPunctualOrRecurrent({
 | 
					 | 
				
			||||||
            value: undefined,
 | 
					 | 
				
			||||||
            constraints: [],
 | 
					 | 
				
			||||||
            targetName: '',
 | 
					 | 
				
			||||||
            object: {
 | 
					 | 
				
			||||||
              frequency: Frequency.PUNCTUAL,
 | 
					 | 
				
			||||||
              departure: new Date('2023-02-01T18:00:00+02:00'),
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            property: '',
 | 
					 | 
				
			||||||
          }),
 | 
					 | 
				
			||||||
        ).toBeTruthy();
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    describe('invalid cases ', () => {
 | 
					 | 
				
			||||||
      it('should not validate without departure', () => {
 | 
					 | 
				
			||||||
        expect(
 | 
					 | 
				
			||||||
          isPunctualOrRecurrent({
 | 
					 | 
				
			||||||
            value: undefined,
 | 
					 | 
				
			||||||
            constraints: [],
 | 
					 | 
				
			||||||
            targetName: '',
 | 
					 | 
				
			||||||
            object: {
 | 
					 | 
				
			||||||
              frequency: Frequency.PUNCTUAL,
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            property: '',
 | 
					 | 
				
			||||||
          }),
 | 
					 | 
				
			||||||
        ).toBeFalsy();
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
  describe('recurrent case ', () => {
 | 
					 | 
				
			||||||
    describe('valid cases', () => {
 | 
					 | 
				
			||||||
      it('should validate with valid from date, to date and non empty schedule', () => {
 | 
					 | 
				
			||||||
        expect(
 | 
					 | 
				
			||||||
          isPunctualOrRecurrent({
 | 
					 | 
				
			||||||
            value: undefined,
 | 
					 | 
				
			||||||
            constraints: [],
 | 
					 | 
				
			||||||
            targetName: '',
 | 
					 | 
				
			||||||
            object: {
 | 
					 | 
				
			||||||
              frequency: Frequency.RECURRENT,
 | 
					 | 
				
			||||||
              fromDate: new Date('2023-01-15'),
 | 
					 | 
				
			||||||
              toDate: new Date('2023-06-30'),
 | 
					 | 
				
			||||||
              schedule: {
 | 
					 | 
				
			||||||
                mon: '08:30',
 | 
					 | 
				
			||||||
              },
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            property: '',
 | 
					 | 
				
			||||||
          }),
 | 
					 | 
				
			||||||
        ).toBeTruthy();
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    describe('invalid cases ', () => {
 | 
					 | 
				
			||||||
      it('should not validate with empty schedule', () => {
 | 
					 | 
				
			||||||
        expect(
 | 
					 | 
				
			||||||
          isPunctualOrRecurrent({
 | 
					 | 
				
			||||||
            value: undefined,
 | 
					 | 
				
			||||||
            constraints: [],
 | 
					 | 
				
			||||||
            targetName: '',
 | 
					 | 
				
			||||||
            object: {
 | 
					 | 
				
			||||||
              frequency: Frequency.RECURRENT,
 | 
					 | 
				
			||||||
              fromDate: new Date('2023-01-15'),
 | 
					 | 
				
			||||||
              toDate: new Date('2023-06-30'),
 | 
					 | 
				
			||||||
              schedule: {},
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            property: '',
 | 
					 | 
				
			||||||
          }),
 | 
					 | 
				
			||||||
        ).toBeFalsy();
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
      it('should not validate with invalid from date to date and empty schedule and margin', () => {
 | 
					 | 
				
			||||||
        expect(
 | 
					 | 
				
			||||||
          isPunctualOrRecurrent({
 | 
					 | 
				
			||||||
            value: undefined,
 | 
					 | 
				
			||||||
            constraints: [],
 | 
					 | 
				
			||||||
            targetName: '',
 | 
					 | 
				
			||||||
            object: {
 | 
					 | 
				
			||||||
              frequency: Frequency.RECURRENT,
 | 
					 | 
				
			||||||
              departure: new Date('2023-10-20'),
 | 
					 | 
				
			||||||
              toDate: new Date('2023-10-30'),
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            property: '',
 | 
					 | 
				
			||||||
          }),
 | 
					 | 
				
			||||||
        ).toBeFalsy();
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,15 @@
 | 
				
			||||||
 | 
					import { Frequency } from '@modules/ad/core/ad.types';
 | 
				
			||||||
 | 
					import { intToFrequency } from '@modules/ad/interface/grpc-controllers/dtos/validators/frequency.mapping';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe('frequency mapping', () => {
 | 
				
			||||||
 | 
					  it('should return punctual if frequency is 1', () => {
 | 
				
			||||||
 | 
					    expect(intToFrequency(1)).toBe(Frequency.PUNCTUAL);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  it('should return recurrent if frequency is 2', () => {
 | 
				
			||||||
 | 
					    expect(intToFrequency(2)).toBe(Frequency.RECURRENT);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  it('should throw an error if frequency is unknown', () => {
 | 
				
			||||||
 | 
					    expect(() => intToFrequency(0)).toThrow();
 | 
				
			||||||
 | 
					    expect(() => intToFrequency(3)).toThrow();
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,8 @@
 | 
				
			||||||
import { Waypoint } from '../../../interface/commands/waypoint';
 | 
					import { hasValidPositionIndexes } from '@modules/ad/interface/grpc-controllers/dtos/validators/waypoint-position';
 | 
				
			||||||
import { hasValidPositionIndexes } from '../../../core/dtos/validators/waypoint-position';
 | 
					import { WaypointDTO } from '@modules/ad/interface/grpc-controllers/dtos/waypoint.dto';
 | 
				
			||||||
describe('addresses position validators', () => {
 | 
					
 | 
				
			||||||
  const mockAddress1: Waypoint = {
 | 
					describe('addresses position validator', () => {
 | 
				
			||||||
 | 
					  const mockAddress1: WaypointDTO = {
 | 
				
			||||||
    lon: 48.68944505415954,
 | 
					    lon: 48.68944505415954,
 | 
				
			||||||
    lat: 6.176510296462267,
 | 
					    lat: 6.176510296462267,
 | 
				
			||||||
    houseNumber: '5',
 | 
					    houseNumber: '5',
 | 
				
			||||||
| 
						 | 
					@ -10,33 +11,33 @@ describe('addresses position validators', () => {
 | 
				
			||||||
    postalCode: '54000',
 | 
					    postalCode: '54000',
 | 
				
			||||||
    country: 'France',
 | 
					    country: 'France',
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  const mockAddress2: Waypoint = {
 | 
					  const mockAddress2: WaypointDTO = {
 | 
				
			||||||
    lon: 48.8566,
 | 
					    lon: 48.8566,
 | 
				
			||||||
    lat: 2.3522,
 | 
					    lat: 2.3522,
 | 
				
			||||||
    locality: 'Paris',
 | 
					    locality: 'Paris',
 | 
				
			||||||
    postalCode: '75000',
 | 
					    postalCode: '75000',
 | 
				
			||||||
    country: 'France',
 | 
					    country: 'France',
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					  const mockAddress3: WaypointDTO = {
 | 
				
			||||||
  const mockAddress3: Waypoint = {
 | 
					 | 
				
			||||||
    lon: 49.2628,
 | 
					    lon: 49.2628,
 | 
				
			||||||
    lat: 4.0347,
 | 
					    lat: 4.0347,
 | 
				
			||||||
    locality: 'Reims',
 | 
					    locality: 'Reims',
 | 
				
			||||||
    postalCode: '51454',
 | 
					    postalCode: '51454',
 | 
				
			||||||
    country: 'France',
 | 
					    country: 'France',
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  it('should validate if none of position is definded ', () => {
 | 
					
 | 
				
			||||||
 | 
					  it('should validate if no position is defined', () => {
 | 
				
			||||||
    expect(
 | 
					    expect(
 | 
				
			||||||
      hasValidPositionIndexes([mockAddress1, mockAddress2, mockAddress3]),
 | 
					      hasValidPositionIndexes([mockAddress1, mockAddress2, mockAddress3]),
 | 
				
			||||||
    ).toBeTruthy();
 | 
					    ).toBeTruthy();
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
  it('should throw an error if position are partialy defined ', () => {
 | 
					  it('should not validate if only one position is defined', () => {
 | 
				
			||||||
    mockAddress1.position = 0;
 | 
					    mockAddress1.position = 0;
 | 
				
			||||||
    expect(
 | 
					    expect(
 | 
				
			||||||
      hasValidPositionIndexes([mockAddress1, mockAddress2, mockAddress3]),
 | 
					      hasValidPositionIndexes([mockAddress1, mockAddress2, mockAddress3]),
 | 
				
			||||||
    ).toBeFalsy();
 | 
					    ).toBeFalsy();
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
  it('should throw an error if position are partialy defined ', () => {
 | 
					  it('should not validate if positions are partially defined', () => {
 | 
				
			||||||
    mockAddress1.position = 0;
 | 
					    mockAddress1.position = 0;
 | 
				
			||||||
    mockAddress2.position = null;
 | 
					    mockAddress2.position = null;
 | 
				
			||||||
    mockAddress3.position = undefined;
 | 
					    mockAddress3.position = undefined;
 | 
				
			||||||
| 
						 | 
					@ -45,7 +46,7 @@ describe('addresses position validators', () => {
 | 
				
			||||||
    ).toBeFalsy();
 | 
					    ).toBeFalsy();
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it('should throw an error if positions are not incremented  ', () => {
 | 
					  it('should not validate if multiple positions have same value', () => {
 | 
				
			||||||
    mockAddress1.position = 0;
 | 
					    mockAddress1.position = 0;
 | 
				
			||||||
    mockAddress2.position = 1;
 | 
					    mockAddress2.position = 1;
 | 
				
			||||||
    mockAddress3.position = 1;
 | 
					    mockAddress3.position = 1;
 | 
				
			||||||
| 
						 | 
					@ -53,7 +54,7 @@ describe('addresses position validators', () => {
 | 
				
			||||||
      hasValidPositionIndexes([mockAddress1, mockAddress2, mockAddress3]),
 | 
					      hasValidPositionIndexes([mockAddress1, mockAddress2, mockAddress3]),
 | 
				
			||||||
    ).toBeFalsy();
 | 
					    ).toBeFalsy();
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
  it('should validate if all positions are defined and incremented', () => {
 | 
					  it('should validate if all positions are ordered', () => {
 | 
				
			||||||
    mockAddress1.position = 0;
 | 
					    mockAddress1.position = 0;
 | 
				
			||||||
    mockAddress2.position = 1;
 | 
					    mockAddress2.position = 1;
 | 
				
			||||||
    mockAddress3.position = 2;
 | 
					    mockAddress3.position = 2;
 | 
				
			||||||
| 
						 | 
					@ -8,9 +8,10 @@ import { RepositoriesHealthIndicatorUseCase } from './core/usecases/repositories
 | 
				
			||||||
import { AdRepository } from '../ad/infrastructure/ad.repository';
 | 
					import { AdRepository } from '../ad/infrastructure/ad.repository';
 | 
				
			||||||
import { AD_REPOSITORY } from './health.di-tokens';
 | 
					import { AD_REPOSITORY } from './health.di-tokens';
 | 
				
			||||||
import { HealthGrpcController } from './interface/grpc-controllers/health.grpc.controller';
 | 
					import { HealthGrpcController } from './interface/grpc-controllers/health.grpc.controller';
 | 
				
			||||||
 | 
					import { AdModule } from '@modules/ad/ad.module';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Module({
 | 
					@Module({
 | 
				
			||||||
  imports: [TerminusModule],
 | 
					  imports: [TerminusModule, AdModule],
 | 
				
			||||||
  controllers: [HealthGrpcController, HealthHttpController],
 | 
					  controllers: [HealthGrpcController, HealthHttpController],
 | 
				
			||||||
  providers: [
 | 
					  providers: [
 | 
				
			||||||
    RepositoriesHealthIndicatorUseCase,
 | 
					    RepositoriesHealthIndicatorUseCase,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,7 +12,7 @@ const mockAdRepository = {
 | 
				
			||||||
      return Promise.resolve(true);
 | 
					      return Promise.resolve(true);
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
    .mockImplementation(() => {
 | 
					    .mockImplementation(() => {
 | 
				
			||||||
      throw new DatabaseErrorException('an error occured in the database');
 | 
					      throw new DatabaseErrorException('An error occured in the database');
 | 
				
			||||||
    }),
 | 
					    }),
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -56,9 +56,11 @@ describe('RepositoriesHealthIndicatorUseCase', () => {
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it('should throw an error if database is unavailable', async () => {
 | 
					    it('should throw an error if database is unavailable', async () => {
 | 
				
			||||||
 | 
					      jest.spyOn(mockMessagePublisher, 'publish');
 | 
				
			||||||
      await expect(
 | 
					      await expect(
 | 
				
			||||||
        repositoriesHealthIndicatorUseCase.isHealthy('repositories'),
 | 
					        repositoriesHealthIndicatorUseCase.isHealthy('repositories'),
 | 
				
			||||||
      ).rejects.toBeInstanceOf(HealthCheckError);
 | 
					      ).rejects.toBeInstanceOf(HealthCheckError);
 | 
				
			||||||
 | 
					      expect(mockMessagePublisher.publish).toHaveBeenCalledTimes(1);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue