myfreight-assessment/tests/tracking/tracking.service.spec.ts

104 lines
3.6 KiB
TypeScript

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<ContainerEntity>;
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>(TrackingService);
shipmentsService = module.get<ShipmentsService>(ShipmentsService);
notificationsService =
module.get<NotificationsService>(NotificationsService);
containerEntityRepository =
module.get<Repository<ContainerEntity>>(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);
});
});