Small Nest.js-based project
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
test-assignment-parcellab/src/packages.service.spec.ts

176 lines
6.1 KiB

import { GeocodingProvider } from './integration/geocoding/types';
import { WeatherProvider } from './integration/weather/types';
import { PackagesService } from './packages.service';
import { PackageInfo, PackagesRepository } from './storage/types';
describe('PackagesService', () => {
describe('with mock providers', () => {
const defaultPackage = {
articleName: 'fake name',
articlePrice: 123,
articleQuantity: 456,
senderAddress: 'fake address',
SKU: 'fake sku',
status: 'delivery',
} satisfies Partial<PackageInfo>;
const packageCold: PackageInfo = {
...defaultPackage,
carrier: 'DHL',
trackingNumber: 'package-cold',
receiverAddress: 'Olympic stadium, Esperanza City',
};
const packageWarm: PackageInfo = {
...defaultPackage,
carrier: 'DHL',
trackingNumber: 'package-warm',
receiverAddress: 'Mitsubishi headquarters, Tōgenkyō',
};
const packageNoGeolocation: PackageInfo = {
...defaultPackage,
carrier: 'GLS',
trackingNumber: 'package-no-geolocation',
receiverAddress: 'Perhaps the stars',
};
const packageNoWeather: PackageInfo = {
...defaultPackage,
carrier: 'GLS',
trackingNumber: 'package-no-weather',
receiverAddress:
'Headquarters of the United Nations, Lagos, Nigeria',
};
const packages = [
packageCold,
packageWarm,
packageNoGeolocation,
packageNoWeather,
];
const packagesRepository: PackagesRepository = {
getPackage: (requestedCarrier, requestedTrackingNumber) => {
const foundPackage = packages.find(
({ carrier, trackingNumber }) =>
carrier === requestedCarrier &&
trackingNumber === requestedTrackingNumber,
);
if (!foundPackage) {
return Promise.resolve({ found: false });
}
return Promise.resolve({
found: true,
value: foundPackage,
});
},
};
const geocodingProvider: GeocodingProvider = {
geocode: (query) => {
switch (query) {
case packageCold.receiverAddress:
return Promise.resolve({
latitude: -63.4,
longitude: -57,
});
case packageWarm.receiverAddress:
return Promise.resolve({ latitude: 0, longitude: 107 });
case packageNoWeather.receiverAddress:
return Promise.resolve({
latitude: 6.5,
longitude: 3.4,
});
default:
throw new Error('unknown address');
}
},
};
const weatherCold = {
apparentTemperature: '0°C',
temperature: '-52°C',
relativeHumidity: '30%',
};
const weatherWarm = {
apparentTemperature: '35°C',
temperature: '30°C',
relativeHumidity: '80%',
};
const weatherProvider: WeatherProvider = {
getCurrentWeather: ({ longitude, latitude }) => {
if (latitude < -60) {
return Promise.resolve(weatherCold);
}
if (latitude === 0 && longitude > 100) {
return Promise.resolve(weatherWarm);
}
throw new Error('No weather data');
},
};
const packagesService = new PackagesService(
packagesRepository,
geocodingProvider,
weatherProvider,
);
it('returns weather for packages with available weather', async () => {
expect(
await packagesService.getPackageInfoWithWeather(
packageCold.carrier,
packageCold.trackingNumber,
),
).toEqual({
packageData: packageCold,
receiverWeather: weatherCold,
});
expect(
await packagesService.getPackageInfoWithWeather(
packageWarm.carrier,
packageWarm.trackingNumber,
),
).toEqual({
packageData: packageWarm,
receiverWeather: weatherWarm,
});
});
it('does not return weather for packages with unavailable weather', async () => {
expect(
await packagesService.getPackageInfoWithWeather(
packageNoWeather.carrier,
packageNoWeather.trackingNumber,
),
).toEqual({
packageData: packageNoWeather,
});
});
it('does not return weather for packages with unresolvable address', async () => {
expect(
await packagesService.getPackageInfoWithWeather(
packageNoGeolocation.carrier,
packageNoGeolocation.trackingNumber,
),
).toEqual({
packageData: packageNoGeolocation,
});
});
it('returns null for non-existent packages', async () => {
expect(
await packagesService.getPackageInfoWithWeather(
'DHL',
'non-existent',
),
).toBe(null);
});
it('returns null for packages with wrong carrier name', async () => {
expect(
await packagesService.getPackageInfoWithWeather(
'UPS',
packageCold.trackingNumber,
),
).toBe(null);
});
});
});