implemented packages controller

main
Inga 🏳‍🌈 1 year ago
parent 4f2b7efb98
commit aad2c81993
  1. 25
      src/dependencies.ts
  2. 69
      src/packages.controller.spec.ts
  3. 33
      src/packages.controller.ts

@ -1,15 +1,40 @@
import { Test, TestingModuleBuilder } from '@nestjs/testing';
import { GeocodingProvider } from './clients/geocoding/types';
import { WeatherProvider } from './clients/weather/types';
import { PackagesService } from './packages.service';
import { PackagesRepository } from './storage/types';
export const packagesRepositoryDependency = Symbol('packages repository');
export const geocodingProviderDependency = Symbol('geocoding provider');
export const weatherProviderDependency = Symbol('weather provider');
export const packagesServiceDependency = Symbol('packages service');
export type Dependencies = {
[packagesRepositoryDependency]: PackagesRepository;
[geocodingProviderDependency]: GeocodingProvider;
[weatherProviderDependency]: WeatherProvider;
[packagesServiceDependency]: Pick<PackagesService, keyof PackagesService>;
};
export type Dependency<T extends keyof Dependencies> = Dependencies[T];
type ProviderDictionary = {
[TKey in keyof Dependencies]: {
provide: TKey;
useValue: Dependencies[TKey];
};
};
type Provider = ProviderDictionary[keyof ProviderDictionary];
type ModuleMetadata = {
// Quick workaround instead of extracting relevant types from @nestjs/types
// (which are not really very different from `any` anyway)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
controllers?: any[];
providers?: Provider[];
};
export const createTestingModule: (
metadata: ModuleMetadata,
) => TestingModuleBuilder = Test.createTestingModule.bind(Test);

@ -0,0 +1,69 @@
import { TestingModule } from '@nestjs/testing';
import request from 'supertest';
import { PackagesController } from './packages.controller';
import { createTestingModule, packagesServiceDependency } from './dependencies';
import { PackageInfo } from './storage/types';
describe('AppController', () => {
it('returns a result from packages service', async () => {
const testTrackingNumber = 'test-tracking-number';
const testPackageResponse = {
packageData: <PackageInfo>{
articleName: 'fake name',
articlePrice: 123,
articleQuantity: 456,
senderAddress: 'fake address',
SKU: 'fake sku',
status: 'delivery',
carrier: 'DHL',
trackingNumber: testTrackingNumber,
receiverAddress: 'fake recipient address',
},
receiverWeather: {
temperature: 'fake temperature',
apparentTemperature: 'fake apparent temperature',
relativeHumidity: 'fake relative humidity',
},
};
const moduleFixture: TestingModule = await createTestingModule({
controllers: [PackagesController],
providers: [
{
provide: packagesServiceDependency,
useValue: {
getPackageInfoWithWeather: (
carrier,
trackingNumber,
) => {
if (
carrier === 'DHL' &&
trackingNumber === testTrackingNumber
) {
return Promise.resolve(testPackageResponse);
}
return Promise.resolve(null);
},
},
},
],
}).compile();
const app = moduleFixture.createNestApplication();
await app.init();
try {
const appRequest = request(app.getHttpServer());
await appRequest
.get(`/packages/DHL/${testTrackingNumber}`)
.expect(200)
.expect(testPackageResponse);
await appRequest
.get(`/packages/UPS/${testTrackingNumber}`)
.expect(404);
await appRequest.get(`/packages/DHL/non-existent`).expect(404);
} finally {
await app.close();
}
});
});

@ -0,0 +1,33 @@
import {
Controller,
Get,
Inject,
NotFoundException,
Param,
} from '@nestjs/common';
import { Dependencies, packagesServiceDependency } from './dependencies';
import { CarrierType } from './types';
@Controller('packages')
export class PackagesController {
constructor(
@Inject(packagesServiceDependency)
private readonly packagesService: Dependencies[typeof packagesServiceDependency],
) {}
@Get(':carrier/:trackingNumber')
async getPackageInfoWithWeather(
@Param('carrier') carrier: string,
@Param('trackingNumber') trackingNumber: string,
) {
const result = await this.packagesService.getPackageInfoWithWeather(
carrier as CarrierType,
trackingNumber,
);
if (!result) {
throw new NotFoundException();
}
return result;
}
}
Loading…
Cancel
Save