parent
4f2b7efb98
commit
aad2c81993
@ -1,15 +1,40 @@ |
|||||||
|
import { Test, TestingModuleBuilder } from '@nestjs/testing'; |
||||||
import { GeocodingProvider } from './clients/geocoding/types'; |
import { GeocodingProvider } from './clients/geocoding/types'; |
||||||
import { WeatherProvider } from './clients/weather/types'; |
import { WeatherProvider } from './clients/weather/types'; |
||||||
|
import { PackagesService } from './packages.service'; |
||||||
import { PackagesRepository } from './storage/types'; |
import { PackagesRepository } from './storage/types'; |
||||||
|
|
||||||
export const packagesRepositoryDependency = Symbol('packages repository'); |
export const packagesRepositoryDependency = Symbol('packages repository'); |
||||||
export const geocodingProviderDependency = Symbol('geocoding provider'); |
export const geocodingProviderDependency = Symbol('geocoding provider'); |
||||||
export const weatherProviderDependency = Symbol('weather provider'); |
export const weatherProviderDependency = Symbol('weather provider'); |
||||||
|
export const packagesServiceDependency = Symbol('packages service'); |
||||||
|
|
||||||
export type Dependencies = { |
export type Dependencies = { |
||||||
[packagesRepositoryDependency]: PackagesRepository; |
[packagesRepositoryDependency]: PackagesRepository; |
||||||
[geocodingProviderDependency]: GeocodingProvider; |
[geocodingProviderDependency]: GeocodingProvider; |
||||||
[weatherProviderDependency]: WeatherProvider; |
[weatherProviderDependency]: WeatherProvider; |
||||||
|
[packagesServiceDependency]: Pick<PackagesService, keyof PackagesService>; |
||||||
}; |
}; |
||||||
|
|
||||||
export type Dependency<T extends keyof Dependencies> = Dependencies[T]; |
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…
Reference in new issue