diff --git a/jest.config.ts b/jest.config.ts index fbd5d1bc..a4dfdb06 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -35,6 +35,7 @@ const config: JestConfigWithTsJest = { ...defaultSettings, }, ], + reporters: [['default', { summaryThreshold: 1 }]], }; export default config; diff --git a/src/modules/constants/constants.controller.test.ts b/src/modules/constants/constants.controller.test.ts deleted file mode 100644 index 643cf28a..00000000 --- a/src/modules/constants/constants.controller.test.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import Chance from 'chance'; - -import { ConstantsController } from './constants.controller'; -import { ConstantsService } from './constants.service'; -import { GetConstantsSpiQueryDto } from './dto/get-constants-spi-query.dto'; - -const chance = new Chance(); - -describe('ConstantsController', () => { - let constantsController: ConstantsController; - let constantsService: ConstantsService; - - beforeAll(async () => { - const app: TestingModule = await Test.createTestingModule({ - controllers: [ConstantsController], - providers: [ - ConstantsService, - { - provide: ConstantsService, - useValue: { - find: jest.fn().mockResolvedValue([ - { - id: chance.natural(), - category: chance.letter(), - subCategory: chance.word(), - oecdRiskCategory: '0', - value: chance.natural(), - constQualityGrade: chance.sentence({ words: 2 }), - constRepaymentFrequency: chance.integer(), - constInterestRate: chance.integer(), - }, - ]), - }, - }, - ], - }).compile(); - - constantsController = app.get(ConstantsController); - constantsService = app.get(ConstantsService); - }); - - it('should be defined', () => { - expect(constantsService).toBeDefined(); - }); - - describe('find()', () => { - it('should return all constants', async () => { - const query = new GetConstantsSpiQueryDto(); - await constantsController.find(query); - - expect(constantsService.find).toHaveBeenCalled(); - }); - }); -}); diff --git a/src/modules/constants/constants.controller.ts b/src/modules/constants/constants.controller.ts deleted file mode 100644 index c36c7d82..00000000 --- a/src/modules/constants/constants.controller.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Controller, Get, Query } from '@nestjs/common'; -import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; - -import { ConstantsService } from './constants.service'; -import { GetConstantsSpiQueryDto } from './dto/get-constants-spi-query.dto'; -import { ConstantSpiEntity } from './entities/constants-spi.entity'; - -@ApiTags('constants') -@Controller('constants') -export class ConstantsController { - constructor(private readonly constantsService: ConstantsService) {} - - @Get('spi') - @ApiOperation({ summary: 'Get constants required for SPI website to calculate indicative sovereign premium rate' }) - @ApiResponse({ - status: 200, - description: 'The found record', - type: [ConstantSpiEntity], - }) - find(@Query() query: GetConstantsSpiQueryDto): Promise { - return this.constantsService.find(query.oecdRiskCategory, query.category); - } -} diff --git a/src/modules/constants/constants.module.ts b/src/modules/constants/constants.module.ts deleted file mode 100644 index f46011c2..00000000 --- a/src/modules/constants/constants.module.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Module } from '@nestjs/common'; -import { TypeOrmModule } from '@nestjs/typeorm'; -import { DATABASE } from '@ukef/constants'; - -import { ConstantsController } from './constants.controller'; -import { ConstantsService } from './constants.service'; -import { ConstantSpiEntity } from './entities/constants-spi.entity'; - -@Module({ - imports: [TypeOrmModule.forFeature([ConstantSpiEntity], DATABASE.CIS)], - controllers: [ConstantsController], - providers: [ConstantsService], -}) -export class ConstantsModule {} diff --git a/src/modules/constants/constants.service.ts b/src/modules/constants/constants.service.ts deleted file mode 100644 index 1c81761a..00000000 --- a/src/modules/constants/constants.service.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Injectable, InternalServerErrorException, NotFoundException } from '@nestjs/common'; -import { InjectRepository } from '@nestjs/typeorm'; -import { DATABASE } from '@ukef/constants'; -import { DbResponseHelper } from '@ukef/helpers/db-response.helper'; -import { PinoLogger } from 'nestjs-pino'; -import { Repository } from 'typeorm'; - -import { ConstantSpiEntity } from './entities/constants-spi.entity'; - -@Injectable() -export class ConstantsService { - constructor( - @InjectRepository(ConstantSpiEntity, DATABASE.CIS) - private readonly constantsCisRepository: Repository, - private readonly logger: PinoLogger, - ) {} - - async find(oecdRiskCategory: number, category: string): Promise { - try { - const spResults = await this.constantsCisRepository.query('USP_MDM_READ_SPI_CONSTANTS @0, @1', [category, oecdRiskCategory]); - - if (spResults && !spResults[0]) { - throw new NotFoundException('No results for your search criteria'); - } - - const fieldMap = DbResponseHelper.getApiNameToDbNameMap(this.constantsCisRepository); - const renamedResults = DbResponseHelper.renameDbResultFields(this.constantsCisRepository, fieldMap, spResults); - - // Transform results to match logic in old implementation. - const transformedResults = renamedResults.map((result) => { - if (result.category === result.subCategory) result.subCategory = ''; - return result; - }); - - return transformedResults; - } catch (err) { - if (err instanceof NotFoundException) { - this.logger.warn(err); - throw err; - } - this.logger.error(err); - throw new InternalServerErrorException(); - } - } -} diff --git a/src/modules/constants/dto/get-constants-spi-query.dto.ts b/src/modules/constants/dto/get-constants-spi-query.dto.ts deleted file mode 100644 index c7c97d80..00000000 --- a/src/modules/constants/dto/get-constants-spi-query.dto.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { IsInt, IsOptional, IsString, Matches, Max, Min } from 'class-validator'; - -export class GetConstantsSpiQueryDto { - @IsInt() - @IsOptional() - @Min(0) - @Max(7) - @ApiProperty({ - required: false, - example: 1, - description: 'Country risk category. Values from 0 to 7', - }) - public oecdRiskCategory: number = null; - - @IsString() - @IsOptional() - @ApiProperty({ - required: false, - example: 'C', - description: 'Constant category/type/group. Values: A, B, C, Quality of Product, Percentage of Cover', - }) - @Matches(/^[a-zA-Z ]{1,20}$/) - public category: string = null; -} diff --git a/src/modules/constants/entities/constants-spi.entity.ts b/src/modules/constants/entities/constants-spi.entity.ts deleted file mode 100644 index 4779e512..00000000 --- a/src/modules/constants/entities/constants-spi.entity.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { Column, Entity, PrimaryColumn } from 'typeorm'; - -@Entity({ - name: 'SPI_COEFFICIENT', - schema: 'dbo', -}) -export class ConstantSpiEntity { - @PrimaryColumn({ name: 'DWD_COEFFICIENT_ID' }) - id: number; - - @Column({ - name: 'COEFFICIENT_CATEGORY', - transformer: { - to: (value: string) => value, - from: (value: string) => value.toString(), - }, - }) - @ApiProperty({ example: 'A', description: 'Acceptable values are `A`, `B`, `C`, `Quality of Product`, `Percentage of Cover`' }) - category: string; - - @Column({ name: 'COEFFICIENT_SUB_CATEGORY' }) - @ApiProperty({ example: 'SOV/CCO' }) - subCategory: string; - - @Column({ name: 'OECD_RISK_CATEGORY_CALC' }) - @ApiProperty({ example: '1', description: 'Values are 0 to 7' }) - oecdRiskCategory: string; - - @Column({ name: 'VALUE' }) - @ApiProperty({ example: 0.09 }) - value: number; - - @Column({ name: 'CONST_QUALITY_GRADE' }) - @ApiProperty({ example: 'Above Standard' }) - constQualityGrade: string; - - @Column({ name: 'CONST_REPAYMENT_FREQUENCY' }) - @ApiProperty({ example: 2, description: 'At the moment values is same for all records.' }) - constRepaymentFrequency: number; - - @Column({ name: 'CONST_INTEREST_RATE' }) - @ApiProperty({ example: 4, description: 'At the moment values is same for all records.' }) - constInterestRate: number; -} diff --git a/src/modules/mdm.module.ts b/src/modules/mdm.module.ts index b397823d..2c16ce9b 100644 --- a/src/modules/mdm.module.ts +++ b/src/modules/mdm.module.ts @@ -1,7 +1,6 @@ import { Module } from '@nestjs/common'; import { AuthModule } from '@ukef/auth/auth.module'; import { DatabaseModule } from '@ukef/database/database.module'; -import { ConstantsModule } from '@ukef/modules/constants/constants.module'; import { CurrenciesModule } from '@ukef/modules/currencies/currencies.module'; import { CustomersModule } from '@ukef/modules/customers/customers.module'; import { ExposurePeriodModule } from '@ukef/modules/exposure-period/exposure-period.module'; @@ -17,7 +16,6 @@ import { YieldRatesModule } from '@ukef/modules/yield-rates/yield-rates.module'; imports: [ AuthModule, DatabaseModule, - ConstantsModule, CurrenciesModule, CustomersModule, ExposurePeriodModule, @@ -32,7 +30,6 @@ import { YieldRatesModule } from '@ukef/modules/yield-rates/yield-rates.module'; exports: [ AuthModule, DatabaseModule, - ConstantsModule, CurrenciesModule, CustomersModule, ExposurePeriodModule, diff --git a/test/constants/constants.spi.api-test.ts b/test/constants/constants.spi.api-test.ts deleted file mode 100644 index 1b5e692f..00000000 --- a/test/constants/constants.spi.api-test.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { INestApplication } from '@nestjs/common'; - -import { Api } from '../api'; -import { CreateApp } from '../createApp'; - -describe('Constants SPI', () => { - let app: INestApplication; - let api: Api; - - const constantsSchema = { - category: expect.any(String), - subCategory: expect.any(String), - oecdRiskCategory: expect.any(String), - value: expect.any(Number), - constQualityGrade: expect.any(String), - constRepaymentFrequency: expect.any(Number), - constInterestRate: expect.any(Number), - }; - - beforeAll(async () => { - app = await new CreateApp().init(); - api = new Api(app.getHttpServer()); - }); - - it(`GET /constants/spi`, async () => { - const { status, body } = await api.get('/constants/spi'); - expect(status).toBe(200); - expect(body).toEqual(expect.arrayContaining([expect.objectContaining(constantsSchema)])); - }); - - it(`GET /constants/spi?oecdRiskCategory=3`, async () => { - const { status, body } = await api.get('/constants/spi?oecdRiskCategory=3'); - expect(status).toBe(200); - expect(body).toEqual(expect.arrayContaining([expect.objectContaining(constantsSchema)])); - // We have 8 country risk ratings (oecdRiskCategory), each rating gets 5 dynamic constants. - expect(body).toHaveLength(5); - }); - - it(`GET /constants/spi?category=B`, async () => { - const { status, body } = await api.get('/constants/spi?category=B'); - expect(status).toBe(200); - expect(body).toEqual(expect.arrayContaining([expect.objectContaining(constantsSchema)])); - // We have 8 country risk ratings (oecdRiskCategory), so we should get 8 results. - expect(body).toHaveLength(8); - }); - - it(`GET /constants/spi?category=Percentage of Cover`, async () => { - const { status, body } = await api.get('/constants/spi?category=Percentage of Cover'); - expect(status).toBe(200); - expect(body).toEqual(expect.arrayContaining([expect.objectContaining(constantsSchema)])); - // We have 8 country risk ratings (oecdRiskCategory), so we should get 8 results. - expect(body).toHaveLength(8); - }); - - it(`GET /constants/spi?oecdRiskCategory=3&category=B`, async () => { - const { status, body } = await api.get('/constants/spi?oecdRiskCategory=3&category=B'); - expect(status).toBe(200); - expect(body).toEqual(expect.arrayContaining([expect.objectContaining(constantsSchema)])); - expect(body).toHaveLength(1); - }); - - // Error checks bellow. - - it(`GET /constants/spi?category=Z`, async () => { - const { status, body } = await api.get('/constants/spi?category=Z'); - expect(status).toBe(404); - expect(body.message).toBe('No results for your search criteria'); - }); - - it(`GET /constants/spi?category=;DROP users;`, async () => { - const { status, body } = await api.get('/constants/spi?category=;DROP users;'); - expect(status).toBe(400); - expect(body.message).toContain('category must match /^[a-zA-Z ]{1,20}$/ regular expression'); - }); - - it(`GET /constants/spi?oecdRiskCategory=aaa&category=Some long not existing category;yes`, async () => { - const { status, body } = await api.get('/constants/spi?oecdRiskCategory=aaa&category=Some long not existing category;yes'); - expect(status).toBe(400); - expect(body.message).toContain('oecdRiskCategory must not be greater than 7'); - expect(body.message).toContain('oecdRiskCategory must be an integer number'); - expect(body.message).toContain('category must match /^[a-zA-Z ]{1,20}$/ regular expression'); - }); - - // category=null is accepted as correct text input. - it(`GET /constants/spi?oecdRiskCategory=null&category=null`, async () => { - const { status, body } = await api.get('/constants/spi?oecdRiskCategory=null&category=null'); - expect(status).toBe(400); - expect(body.message).toContain('oecdRiskCategory must not be greater than 7'); - expect(body.message).toContain('oecdRiskCategory must be an integer number'); - }); - - // category=undefined is accepted as correct text input. - it(`GET /constants/spi?oecdRiskCategory=undefined&category=undefined`, async () => { - const { status, body } = await api.get('/constants/spi?oecdRiskCategory=undefined&category=undefined'); - expect(status).toBe(400); - expect(body.message).toContain('oecdRiskCategory must not be greater than 7'); - expect(body.message).toContain('oecdRiskCategory must be an integer number'); - }); - - afterAll(async () => { - await app.close(); - }); -}); diff --git a/test/docs/__snapshots__/get-docs-yaml.api-test.ts.snap b/test/docs/__snapshots__/get-docs-yaml.api-test.ts.snap index 3307631b..13ac0e13 100644 --- a/test/docs/__snapshots__/get-docs-yaml.api-test.ts.snap +++ b/test/docs/__snapshots__/get-docs-yaml.api-test.ts.snap @@ -3,40 +3,6 @@ exports[`GET /openapi/yaml matches the snapshot 1`] = ` "openapi: 3.0.0 paths: - /api/v1/constants/spi: - get: - operationId: ConstantsController_find - summary: >- - Get constants required for SPI website to calculate indicative sovereign - premium rate - parameters: - - name: oecdRiskCategory - required: false - in: query - example: 1 - description: Country risk category. Values from 0 to 7 - schema: - type: number - - name: category - required: false - in: query - example: C - description: >- - Constant category/type/group. Values: A, B, C, Quality of Product, - Percentage of Cover - schema: - type: string - responses: - '200': - description: The found record - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/ConstantSpiEntity' - tags: - - constants /api/v1/currencies: get: operationId: CurrenciesController_findAll @@ -517,44 +483,6 @@ components: in: header name: x-api-key schemas: - ConstantSpiEntity: - type: object - properties: - category: - type: string - example: A - description: >- - Acceptable values are \`A\`, \`B\`, \`C\`, \`Quality of Product\`, - \`Percentage of Cover\` - subCategory: - type: string - example: SOV/CCO - oecdRiskCategory: - type: string - example: '1' - description: Values are 0 to 7 - value: - type: number - example: 0.09 - constQualityGrade: - type: string - example: Above Standard - constRepaymentFrequency: - type: number - example: 2 - description: At the moment values is same for all records. - constInterestRate: - type: number - example: 4 - description: At the moment values is same for all records. - required: - - category - - subCategory - - oecdRiskCategory - - value - - constQualityGrade - - constRepaymentFrequency - - constInterestRate CurrencyEntity: type: object properties: