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.
176 lines
6.1 KiB
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);
|
|
});
|
|
});
|
|
});
|
|
|