import { Test, TestingModule } from '@nestjs/testing'; import { Repository } from 'typeorm'; import { ContainerEntity } from '@/entities/container.entity'; import { ShipmentsService } from '@/shipments/shipments.service'; import { NotificationsService } from '@/tracking/notifications.service'; import { getRepositoryToken } from '@nestjs/typeorm'; import { TrackingService } from '@/tracking/tracking.service'; import { mockContainerEntity, mockShipment, mockTrackingInfo, } from '@tests/data/tracking.mock'; describe('TrackingService', () => { const containerEntityToken = getRepositoryToken(ContainerEntity); let trackingService: TrackingService; let shipmentsService: ShipmentsService; let notificationsService: NotificationsService; let containerEntityRepository: Repository; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ providers: [TrackingService], }) .useMocker((token) => { switch (token) { case containerEntityToken: return { findOneOrFail: jest.fn().mockResolvedValue(mockContainerEntity), }; case ShipmentsService: return { update: jest.fn().mockResolvedValue(mockShipment), }; case NotificationsService: return { send: jest.fn().mockResolvedValue(true), }; } }) .compile(); trackingService = module.get(TrackingService); shipmentsService = module.get(ShipmentsService); notificationsService = module.get(NotificationsService); containerEntityRepository = module.get>(containerEntityToken); }); it('should be defined', () => { expect(trackingService).toBeDefined(); expect(trackingService.track).toBeDefined(); }); it('should have a track method that returns true', async () => { await expect(trackingService.track(mockTrackingInfo)).resolves.toBe(true); expect(containerEntityRepository.findOneOrFail).toHaveBeenCalledWith({ relations: ['shipment'], where: { containerNumber: mockTrackingInfo.containerNumber, }, }); expect(shipmentsService.update).toHaveBeenCalledWith({ ...mockShipment, arrivalDateEstimate: mockTrackingInfo.arrivalDateEstimate, departureDate: mockTrackingInfo.departureDate, }); expect(notificationsService.send).toHaveBeenCalledWith( mockShipment, mockTrackingInfo, ); }); it('should have a track method that validates the tracking information with the returned container information', async () => { const mockShipmentNotFound = { ...mockContainerEntity, shipment: undefined, }; const mockShipmentCarrierNameMismatch = { ...mockContainerEntity, shipment: { ...mockShipment, carrierName: 'incorrect' }, }; jest .spyOn(containerEntityRepository, 'findOneOrFail') .mockResolvedValueOnce(mockShipmentNotFound); await expect(trackingService.track(mockTrackingInfo)).rejects.toThrow( 'Shipment not found', ); expect(notificationsService.send).toHaveBeenCalledTimes(0); expect(shipmentsService.update).toHaveBeenCalledTimes(0); jest .spyOn(containerEntityRepository, 'findOneOrFail') .mockResolvedValueOnce(mockShipmentCarrierNameMismatch); await expect(trackingService.track(mockTrackingInfo)).rejects.toThrow( 'CarrierName does not match', ); expect(notificationsService.send).toHaveBeenCalledTimes(0); expect(shipmentsService.update).toHaveBeenCalledTimes(0); }); });