diff --git a/src/modules/ad/tests/unit/infrastructure/output-datetime-transformer.spec.ts b/src/modules/ad/tests/unit/infrastructure/output-datetime-transformer.spec.ts new file mode 100644 index 0000000..4c3dcf8 --- /dev/null +++ b/src/modules/ad/tests/unit/infrastructure/output-datetime-transformer.spec.ts @@ -0,0 +1,271 @@ +import { + PARAMS_PROVIDER, + TIMEZONE_FINDER, + TIME_CONVERTER, +} from '@modules/ad/ad.di-tokens'; +import { Frequency } from '@modules/ad/core/application/ports/datetime-transformer.port'; +import { DefaultParamsProviderPort } from '@modules/ad/core/application/ports/default-params-provider.port'; +import { TimeConverterPort } from '@modules/ad/core/application/ports/time-converter.port'; +import { TimezoneFinderPort } from '@modules/ad/core/application/ports/timezone-finder.port'; +import { OutputDateTimeTransformer } from '@modules/ad/infrastructure/output-datetime-transformer'; +import { Test, TestingModule } from '@nestjs/testing'; + +const mockDefaultParamsProvider: DefaultParamsProviderPort = { + getParams: () => { + return { + DEPARTURE_TIME_MARGIN: 900, + DRIVER: false, + SEATS_PROPOSED: 3, + PASSENGER: true, + SEATS_REQUESTED: 1, + STRICT: false, + DEFAULT_TIMEZONE: 'Europe/Paris', + }; + }, +}; + +const mockTimezoneFinder: TimezoneFinderPort = { + timezones: jest.fn().mockImplementation(() => ['Europe/Paris']), +}; + +const mockTimeConverter: TimeConverterPort = { + localStringTimeToUtcStringTime: jest.fn(), + utcStringTimeToLocalStringTime: jest + .fn() + .mockImplementationOnce(() => '00:15'), + localStringDateTimeToUtcDate: jest.fn(), + utcStringDateTimeToLocalIsoString: jest + .fn() + .mockImplementationOnce(() => '2023-07-30T08:15:00.000+02:00') + .mockImplementationOnce(() => '2023-07-20T10:15:00.000+02:00') + .mockImplementationOnce(() => '2023-07-19T23:15:00.000+02:00') + .mockImplementationOnce(() => '2023-07-20T00:15:00.000+02:00'), + utcUnixEpochDayFromTime: jest.fn(), + localUnixEpochDayFromTime: jest + .fn() + .mockImplementationOnce(() => 4) + .mockImplementationOnce(() => 5) + .mockImplementationOnce(() => 5) + .mockImplementationOnce(() => 3) + .mockImplementationOnce(() => 3), +}; + +describe('Output Datetime Transformer', () => { + let outputDatetimeTransformer: OutputDateTimeTransformer; + + beforeAll(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + { + provide: PARAMS_PROVIDER, + useValue: mockDefaultParamsProvider, + }, + { + provide: TIMEZONE_FINDER, + useValue: mockTimezoneFinder, + }, + { + provide: TIME_CONVERTER, + useValue: mockTimeConverter, + }, + OutputDateTimeTransformer, + ], + }).compile(); + + outputDatetimeTransformer = module.get( + OutputDateTimeTransformer, + ); + }); + + it('should be defined', () => { + expect(outputDatetimeTransformer).toBeDefined(); + }); + + describe('fromDate', () => { + it('should return fromDate as is if frequency is recurrent', () => { + const transformedFromDate: string = outputDatetimeTransformer.fromDate( + { + date: '2023-07-30', + time: '07:15', + coordinates: { + lon: 6.175, + lat: 48.685, + }, + }, + Frequency.RECURRENT, + ); + expect(transformedFromDate).toBe('2023-07-30'); + }); + it('should return transformed fromDate if frequency is punctual and coordinates are those of Nancy', () => { + const transformedFromDate: string = outputDatetimeTransformer.fromDate( + { + date: '2023-07-30', + time: '07:15', + coordinates: { + lon: 6.175, + lat: 48.685, + }, + }, + Frequency.PUNCTUAL, + ); + expect(transformedFromDate).toBe('2023-07-30'); + }); + }); + + describe('toDate', () => { + it('should return toDate as is if frequency is recurrent', () => { + const transformedToDate: string = outputDatetimeTransformer.toDate( + '2024-07-29', + { + date: '2023-07-20', + time: '10:15', + coordinates: { + lon: 6.175, + lat: 48.685, + }, + }, + Frequency.RECURRENT, + ); + expect(transformedToDate).toBe('2024-07-29'); + }); + it('should return transformed fromDate if frequency is punctual', () => { + const transformedToDate: string = outputDatetimeTransformer.toDate( + '2024-07-30', + { + date: '2023-07-20', + time: '08:15', + coordinates: { + lon: 6.175, + lat: 48.685, + }, + }, + Frequency.PUNCTUAL, + ); + expect(transformedToDate).toBe('2023-07-20'); + }); + }); + + describe('day', () => { + it('should not change day if frequency is recurrent and converted local time is on the same day', () => { + const day: number = outputDatetimeTransformer.day( + 1, + { + date: '2023-07-24', + time: '00:15', + coordinates: { + lon: 6.175, + lat: 48.685, + }, + }, + Frequency.RECURRENT, + ); + expect(day).toBe(1); + }); + it('should change day if frequency is recurrent and converted local time is on the next day', () => { + const day: number = outputDatetimeTransformer.day( + 0, + { + date: '2023-07-23', + time: '23:15', + coordinates: { + lon: 6.175, + lat: 48.685, + }, + }, + Frequency.RECURRENT, + ); + expect(day).toBe(1); + }); + it('should change day if frequency is recurrent and converted local time is on the next day and given day is saturday', () => { + const day: number = outputDatetimeTransformer.day( + 6, + { + date: '2023-07-23', + time: '23:15', + coordinates: { + lon: 6.175, + lat: 48.685, + }, + }, + Frequency.RECURRENT, + ); + expect(day).toBe(0); + }); + it('should change day if frequency is recurrent and converted local time is on the previous day', () => { + const day: number = outputDatetimeTransformer.day( + 1, + { + date: '2023-07-25', + time: '00:15', + coordinates: { + lon: 30.82, + lat: 49.37, + }, + }, + Frequency.RECURRENT, + ); + expect(day).toBe(0); + }); + it('should change day if frequency is recurrent and converted local time is on the previous day and given day is sunday(0)', () => { + const day: number = outputDatetimeTransformer.day( + 0, + { + date: '2023-07-30', + time: '00:15', + coordinates: { + lon: 30.82, + lat: 49.37, + }, + }, + Frequency.RECURRENT, + ); + expect(day).toBe(6); + }); + it('should return local fromDate day if frequency is punctual', () => { + const day: number = outputDatetimeTransformer.day( + 1, + { + date: '2023-07-20', + time: '00:15', + coordinates: { + lon: 6.175, + lat: 48.685, + }, + }, + Frequency.PUNCTUAL, + ); + expect(day).toBe(3); + }); + }); + + describe('time', () => { + it('should transform utc time to local time if frequency is recurrent', () => { + const time: string = outputDatetimeTransformer.time( + { + date: '2023-07-23', + time: '23:15', + coordinates: { + lon: 6.175, + lat: 48.685, + }, + }, + Frequency.RECURRENT, + ); + expect(time).toBe('00:15'); + }); + it('should return local time if frequency is punctual', () => { + const time: string = outputDatetimeTransformer.time( + { + date: '2023-07-19', + time: '23:15', + coordinates: { + lon: 6.175, + lat: 48.685, + }, + }, + Frequency.PUNCTUAL, + ); + expect(time).toBe('00:15'); + }); + }); +});