From f3d6abf6fd229574ab6b406e5159d3e0d530392d Mon Sep 17 00:00:00 2001 From: nvim Date: Thu, 22 Aug 2024 09:54:10 +0200 Subject: [PATCH] Update add tests for the SQL combo parameters --- Makefile | 2 +- compose.yml | 26 +------ src/main.ts | 2 +- src/modules/requests/request.dto.ts | 3 + src/modules/requests/request.entity.ts | 3 + src/utils/clientTestingHelpers.spec.ts | 104 ++++++++++++++++--------- src/utils/clientTestingHelpers.ts | 20 +++++ src/utils/data.ts | 1 + 8 files changed, 101 insertions(+), 60 deletions(-) diff --git a/Makefile b/Makefile index a9eec61..9bc6a13 100644 --- a/Makefile +++ b/Makefile @@ -31,4 +31,4 @@ tests_run: $(compose) $(tests_env) $(tests_profile) up --abort-on-container-exit tests_down: - $(compose) $(tests_env) $(tests_profile) down + $(compose) $(tests_env) $(tests_profile) down -v diff --git a/compose.yml b/compose.yml index 1af7c8a..cb878eb 100644 --- a/compose.yml +++ b/compose.yml @@ -13,10 +13,8 @@ services: profiles: - development - production - environment: - POSTGRES_USER: ${POSTGRES_USER} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - POSTGRES_DB: ${POSTGRES_DB} + env_file: + - ./envs/.env.development test: build: context: ./ @@ -26,10 +24,8 @@ services: - postgres profiles: - tests - environment: - POSTGRES_USER: ${POSTGRES_USER} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - POSTGRES_DB: ${POSTGRES_DB} + env_file: + - ./envs/.env.test postgres: image: postgres:15 ports: @@ -44,20 +40,6 @@ services: - development - tests - production - pgweb: - container_name: pgweb - restart: always - image: sosedoff/pgweb - ports: - - "8081:8081" - links: - - postgres:postgres - environment: - - DATABASE_URL=postgres://myuser:mypassword@postgres:5432/mydatabase?sslmode=disable - depends_on: - - postgres - profiles: - - development validator-api: image: pavelrozhkov/wrapper:6.3.11 ports: diff --git a/src/main.ts b/src/main.ts index 98b5edb..ca4683a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -16,6 +16,6 @@ async function bootstrap() { SwaggerModule.setup('api', app, document); await app.listen(8080); - await initialValidateResource(); + initialValidateResource(); } bootstrap(); diff --git a/src/modules/requests/request.dto.ts b/src/modules/requests/request.dto.ts index fe35e53..4468b9d 100644 --- a/src/modules/requests/request.dto.ts +++ b/src/modules/requests/request.dto.ts @@ -61,6 +61,9 @@ export class CreateRequestDto { @ApiProperty({ description: 'Filters applied to the request' }) filters: jsonbType; + @ApiProperty({ description: 'Filters codes applied to the request' }) + filtersCodes: string[]; + @ApiProperty({ description: 'HTTP status code of the response' }) status: Response['statusCode']; diff --git a/src/modules/requests/request.entity.ts b/src/modules/requests/request.entity.ts index 9c90b74..e6c4303 100644 --- a/src/modules/requests/request.entity.ts +++ b/src/modules/requests/request.entity.ts @@ -65,6 +65,9 @@ export class Request { @Column({ name: 'filters', type: 'jsonb', nullable: true }) filters: jsonbType; + @Column({ name: 'filters_codes', type: 'text', array: true, nullable: true }) + filtersCodes: string[]; + @Column({ name: 'status', type: 'smallint' }) status: Response['statusCode']; diff --git a/src/utils/clientTestingHelpers.spec.ts b/src/utils/clientTestingHelpers.spec.ts index 9b7d631..6b3862d 100644 --- a/src/utils/clientTestingHelpers.spec.ts +++ b/src/utils/clientTestingHelpers.spec.ts @@ -2,7 +2,11 @@ import { DataSource } from 'typeorm'; import { Request } from '../modules/requests/request.entity'; import { Session } from '../modules/sessions/session.entity'; import { TestRun } from '../modules/test_runs/testRun.entity'; -import { getRequestsWithUnavailableSearchParams } from './clientTestingHelpers'; +import { + getRequestsWithUnavailableComboSearchParams, + getRequestsWithUnavailableSearchParams, +} from './clientTestingHelpers'; +import { v4 as uuidv4 } from 'uuid'; const TestDataSource = new DataSource({ type: 'postgres', @@ -17,8 +21,61 @@ const TestDataSource = new DataSource({ logging: false, }); +const sessionUUID = uuidv4(); + beforeAll(async () => { await TestDataSource.initialize(); + const sessionRepository = TestDataSource.getRepository(Session); + const requestsRepository = TestDataSource.getRepository(Request); + const sessionEntity = await sessionRepository.save({ + id: sessionUUID, + target: 'http://test.com', + }); + + for (const requestData of [ + { resourceType: 'Patient', fhirAction: 'SEARCH', filters: [{ code: '_id', value: '123' }] }, + { resourceType: 'Patient', fhirAction: 'SEARCH', filters: [{ code: 'family', value: '123' }] }, + { + resourceType: 'Patient', + fhirAction: 'SEARCH', + filters: [ + { code: 'family', value: '123' }, + { code: 'gender', value: 'unknown' }, + ], + }, + { + resourceType: 'Patient', + fhirAction: 'SEARCH', + filters: [ + { code: 'family', value: '123' }, + { code: 'name', value: 'unknown' }, + ], + }, + { + resourceType: 'Patient', + fhirAction: 'SEARCH', + filters: [ + { code: 'test', value: '123' }, + { code: 'name', value: 'unknown' }, + ], + }, + { resourceType: 'Patent', fhirAction: 'CREATE' }, + { resourceType: 'Observation', fhirAction: 'SEARCH' }, + ]) { + await requestsRepository.save({ + session: sessionEntity, + resourceType: requestData.resourceType, + fhirAction: requestData.fhirAction, + requestMethod: 'GET', + requestUri: '/Patient', + remoteAddr: 'undefined', + status: 200, + userAgent: 'Mozilla/5.0', + headers: {}, + filters: requestData.filters, + filtersCodes: requestData.filters?.map((filter) => filter.code).sort() ?? [], + }); + } }); afterAll(async () => { @@ -26,44 +83,19 @@ afterAll(async () => { }); describe('Client testing helpers', () => { + const requestsRepository = TestDataSource.getRepository(Request); it('Should return correct request entities via getRequestsWithUnavailableSearchParams', async () => { - const sessionRepository = TestDataSource.getRepository(Session); - const requestsRepository = TestDataSource.getRepository(Request); - - const sessionEntity = await sessionRepository.save({ - target: 'http://test.com', - }); + const requests = await getRequestsWithUnavailableSearchParams(requestsRepository, sessionUUID, 'Patient', [ + '_id', + ]); - for (const requestData of [ - { resourceType: 'Patient', fhirAction: 'SEARCH', filters: [{ code: '_id', value: '123' }] }, - { resourceType: 'Patient', fhirAction: 'SEARCH', filters: [{ code: 'family', value: '123' }] }, - { - resourceType: 'Patient', - fhirAction: 'SEARCH', - filters: [ - { code: '_id', value: '123' }, - { code: 'family', value: '123' }, - ], - }, - { resourceType: 'Patent', fhirAction: 'CREATE' }, - { resourceType: 'Observation', fhirAction: 'SEARCH' }, - ]) { - await requestsRepository.save({ - session: sessionEntity, - resourceType: requestData.resourceType, - fhirAction: requestData.fhirAction, - requestMethod: 'GET', - requestUri: '/Patient', - remoteAddr: 'undefined', - status: 200, - userAgent: 'Mozilla/5.0', - headers: {}, - filters: requestData.filters, - }); - } + expect(requests).toHaveLength(1); + }); - const requests = await getRequestsWithUnavailableSearchParams(requestsRepository, sessionEntity.id, 'Patient', [ - '_id', + it('Should return correct request entities via getRequestsWithUnavailableComboSearchParams', async () => { + const requests = await getRequestsWithUnavailableComboSearchParams(requestsRepository, sessionUUID, 'Patient', [ + ['family', 'name'], + ['family', 'gender'], ]); expect(requests).toHaveLength(1); diff --git a/src/utils/clientTestingHelpers.ts b/src/utils/clientTestingHelpers.ts index 06debc2..6d6b2a0 100644 --- a/src/utils/clientTestingHelpers.ts +++ b/src/utils/clientTestingHelpers.ts @@ -34,3 +34,23 @@ export async function getRequestsWithUnavailableSearchParams( .andWhere("request.filters->0->>'code' NOT IN (:...availableSearchParams)", { availableSearchParams }) .getMany(); } + +export async function getRequestsWithUnavailableComboSearchParams( + repository: Repository, + sessionId: string, + resourceType: string, + availableSearchParams: string[][], +): Promise { + const result = await repository + .createQueryBuilder('request') + .where('request.sessionId = :sessionId', { sessionId }) + .andWhere('request.resourceType = :resourceType', { resourceType }) + .andWhere('request.fhirAction = :action', { action: 'SEARCH' }) + .andWhere('jsonb_array_length(request.filters) > 1') + .andWhere('NOT request.filters_codes <@ :codes', { + codes: availableSearchParams, + }) + .getMany(); + + return result; +} diff --git a/src/utils/data.ts b/src/utils/data.ts index 9c4d229..a2e0706 100644 --- a/src/utils/data.ts +++ b/src/utils/data.ts @@ -34,6 +34,7 @@ export function createRequestObject( revInclude: JSON.stringify(searchReqObj.revInclude), sortRules: JSON.stringify(searchReqObj.sortRules), filters: searchReqObj.filters, + filtersCodes: searchReqObj.filters?.map((filter) => filter.code).sort() ?? [], status: res.statusCode, responseBody: JSON.parse(responseBody), requestBody: req.body,