import { CreateAdRequest } from '../../../domain/dtos/create-ad.request'; import { CreateAdUseCase } from '../../../domain/usecases/create-ad.usecase'; import { Test, TestingModule } from '@nestjs/testing'; import { AutomapperModule } from '@automapper/nestjs'; import { classes } from '@automapper/classes'; import { AdRepository } from '../../../adapters/secondaries/ad.repository'; import { CreateAdCommand } from '../../../commands/create-ad.command'; import { Ad } from '../../../domain/entities/ad'; import { AdProfile } from '../../../mappers/ad.profile'; import { Frequency } from '../../../domain/types/frequency.enum'; import { RouteKey } from '../../../domain/entities/geography'; import { DatabaseException } from '../../../../database/exceptions/database.exception'; import { Route } from '../../../../geography/domain/entities/route'; const mockAdRepository = { createAd: jest.fn().mockImplementation((ad) => { if (ad.uuid == '00000000-0000-0000-0000-000000000000') throw new DatabaseException(); return new Ad(); }), }; const mockGeorouterCreator = { create: jest.fn().mockImplementation(() => ({ route: jest.fn().mockImplementation(() => [ { key: RouteKey.DRIVER, route: { points: [], fwdAzimuth: 0, backAzimuth: 180, distance: 20000, duration: 1800, }, }, { key: RouteKey.PASSENGER, route: { points: [], fwdAzimuth: 0, backAzimuth: 180, distance: 20000, duration: 1800, }, }, { key: RouteKey.COMMON, route: { points: [], fwdAzimuth: 0, backAzimuth: 180, distance: 20000, duration: 1800, }, }, ]), })), }; const mockParamsProvider = { getParams: jest.fn().mockImplementation(() => ({ DEFAULT_TIMEZONE: 'Europe/Paris', GEOROUTER_TYPE: 'graphhopper', GEOROUTER_URL: 'localhost', })), }; const mockTimezoneFinder = { timezones: jest.fn().mockImplementation(() => ['Europe/Paris']), }; const mockDirectionEncoder = { encode: jest.fn(), }; const createAdRequest: CreateAdRequest = { uuid: '77c55dfc-c28b-4026-942e-f94e95401fb1', userUuid: 'dfd993f6-7889-4876-9570-5e1d7b6e3f42', driver: true, passenger: false, frequency: Frequency.RECURRENT, fromDate: new Date('2023-04-26'), toDate: new Date('2024-04-25'), monTime: '07:00', tueTime: '07:00', wedTime: '07:00', thuTime: '07:00', friTime: '07:00', satTime: null, sunTime: null, monMargin: 900, tueMargin: 900, wedMargin: 900, thuMargin: 900, friMargin: 900, satMargin: 900, sunMargin: 900, seatsDriver: 3, seatsPassenger: 1, strict: false, waypoints: [ { lon: 6, lat: 45 }, { lon: 6.5, lat: 45.5 }, ], }; const setUuid = async (uuid: string): Promise => { createAdRequest.uuid = uuid; }; const setIsDriver = async (isDriver: boolean): Promise => { createAdRequest.driver = isDriver; }; const setIsPassenger = async (isPassenger: boolean): Promise => { createAdRequest.passenger = isPassenger; }; describe('CreateAdUseCase', () => { let createAdUseCase: CreateAdUseCase; beforeAll(async () => { const module: TestingModule = await Test.createTestingModule({ imports: [AutomapperModule.forRoot({ strategyInitializer: classes() })], providers: [ { provide: AdRepository, useValue: mockAdRepository, }, { provide: 'GeorouterCreator', useValue: mockGeorouterCreator, }, { provide: 'ParamsProvider', useValue: mockParamsProvider, }, { provide: 'TimezoneFinder', useValue: mockTimezoneFinder, }, { provide: 'DirectionEncoder', useValue: mockDirectionEncoder, }, AdProfile, CreateAdUseCase, ], }).compile(); createAdUseCase = module.get(CreateAdUseCase); }); it('should be defined', () => { expect(createAdUseCase).toBeDefined(); }); describe('execute', () => { it('should create an ad as driver', async () => { const ad = await createAdUseCase.execute( new CreateAdCommand(createAdRequest), ); expect(ad).toBeInstanceOf(Ad); }); it('should create an ad as passenger', async () => { await setIsDriver(false); await setIsPassenger(true); const ad = await createAdUseCase.execute( new CreateAdCommand(createAdRequest), ); expect(ad).toBeInstanceOf(Ad); }); it('should throw an exception if repository fails', async () => { await setUuid('00000000-0000-0000-0000-000000000000'); await expect( createAdUseCase.execute(new CreateAdCommand(createAdRequest)), ).rejects.toBeInstanceOf(DatabaseException); }); }); });