From 0986e58aa63787c9a2d37d482b6274012e5365ec Mon Sep 17 00:00:00 2001 From: Robert A Dingwell Date: Mon, 6 Nov 2023 17:00:41 -0500 Subject: [PATCH 1/4] Adding search parameters --- src/extractors/BaseFHIRExtractor.js | 6 ++-- src/extractors/FHIRAdverseEventExtractor.js | 4 +-- .../FHIRAllergyIntoleranceExtractor.js | 13 ++----- src/extractors/FHIRConditionExtractor.js | 15 ++------ .../FHIRDocumentReferenceExtractor.js | 4 +-- src/extractors/FHIREncounterExtractor.js | 4 +-- .../FHIRMedicationOrderExtractor.js | 4 +-- .../FHIRMedicationRequestExtractor.js | 17 ++------- .../FHIRMedicationStatementExtractor.js | 4 +-- src/extractors/FHIRObservationExtractor.js | 15 ++------ src/extractors/FHIRPatientExtractor.js | 4 +-- src/extractors/FHIRProcedureExtractor.js | 4 +-- src/helpers/patientUtils.js | 2 +- src/helpers/schemas/config.schema.json | 4 +++ test/extractors/BaseFHIRExtractor.test.js | 19 ++++++++-- .../FHIRAllergyIntoleranceExtractor.test.js | 30 ---------------- .../extractors/FHIRConditionExtractor.test.js | 23 +----------- .../FHIRMedicationRequestExtractor.test.js | 35 ------------------- .../FHIRObservationExtractor.test.js | 30 ++-------------- 19 files changed, 51 insertions(+), 186 deletions(-) diff --git a/src/extractors/BaseFHIRExtractor.js b/src/extractors/BaseFHIRExtractor.js index c34e594d..126af9ca 100644 --- a/src/extractors/BaseFHIRExtractor.js +++ b/src/extractors/BaseFHIRExtractor.js @@ -5,11 +5,12 @@ const { getPatientFromContext } = require('../helpers/contextUtils'); const logger = require('../helpers/logger'); class BaseFHIRExtractor extends Extractor { - constructor({ baseFhirUrl, requestHeaders, version, resourceType }) { + constructor({ baseFhirUrl, requestHeaders, version, resourceType, searchParameters={} }) { super(); this.resourceType = resourceType; this.version = version; this.baseFHIRModule = new BaseFHIRModule(baseFhirUrl, requestHeaders); + this.searchParameters = searchParameters; } updateRequestHeaders(newHeaders) { @@ -21,7 +22,8 @@ class BaseFHIRExtractor extends Extractor { // NOTE: Async because other extractors that extend this may need to make async lookups in the future async parametrizeArgsForFHIRModule({ context }) { const patient = getPatientFromContext(context); - return { patient: patient.id }; + + return { ...this.searchParameters, patient: patient.id }; } /* eslint-enable class-methods-use-this */ diff --git a/src/extractors/FHIRAdverseEventExtractor.js b/src/extractors/FHIRAdverseEventExtractor.js index 7cff373b..d214bc00 100644 --- a/src/extractors/FHIRAdverseEventExtractor.js +++ b/src/extractors/FHIRAdverseEventExtractor.js @@ -5,8 +5,8 @@ const logger = require('../helpers/logger'); const BASE_STUDY = ''; // No base study specified class FHIRAdverseEventExtractor extends BaseFHIRExtractor { - constructor({ baseFhirUrl, requestHeaders, version, study }) { - super({ baseFhirUrl, requestHeaders, version }); + constructor({ baseFhirUrl, requestHeaders, version, study, searchParameters }) { + super({ baseFhirUrl, requestHeaders, version,searchParameters }); this.resourceType = 'AdverseEvent'; this.study = study || BASE_STUDY; } diff --git a/src/extractors/FHIRAllergyIntoleranceExtractor.js b/src/extractors/FHIRAllergyIntoleranceExtractor.js index a74c5243..a37629f9 100644 --- a/src/extractors/FHIRAllergyIntoleranceExtractor.js +++ b/src/extractors/FHIRAllergyIntoleranceExtractor.js @@ -3,20 +3,11 @@ const { BaseFHIRExtractor } = require('./BaseFHIRExtractor'); const BASE_CLINICAL_STATUS = 'active'; class FHIRAllergyIntoleranceExtractor extends BaseFHIRExtractor { - constructor({ baseFhirUrl, requestHeaders, version, clinicalStatus }) { - super({ baseFhirUrl, requestHeaders, version }); + constructor({ baseFhirUrl, requestHeaders, version,searchParameters }) { + super({ baseFhirUrl, requestHeaders, version,searchParameters }); this.resourceType = 'AllergyIntolerance'; - this.clinicalStatus = clinicalStatus || BASE_CLINICAL_STATUS; } - // In addition to default parametrization, add clinical status - async parametrizeArgsForFHIRModule({ context }) { - const paramsWithID = await super.parametrizeArgsForFHIRModule({ context }); - return { - ...paramsWithID, - 'clinical-status': this.clinicalStatus, - }; - } } module.exports = { diff --git a/src/extractors/FHIRConditionExtractor.js b/src/extractors/FHIRConditionExtractor.js index fc66f372..57b029db 100644 --- a/src/extractors/FHIRConditionExtractor.js +++ b/src/extractors/FHIRConditionExtractor.js @@ -1,22 +1,11 @@ const { BaseFHIRExtractor } = require('./BaseFHIRExtractor'); -const BASE_CATEGORIES = 'problem-list-item'; - class FHIRConditionExtractor extends BaseFHIRExtractor { - constructor({ baseFhirUrl, requestHeaders, version, category }) { - super({ baseFhirUrl, requestHeaders, version }); + constructor({ baseFhirUrl, requestHeaders, version, searchParameters}) { + super({ baseFhirUrl, requestHeaders, version, searchParameters }); this.resourceType = 'Condition'; - this.category = category || BASE_CATEGORIES; } - // In addition to default parametrization, add category - async parametrizeArgsForFHIRModule({ context }) { - const paramsWithID = await super.parametrizeArgsForFHIRModule({ context }); - return { - ...paramsWithID, - category: this.category, - }; - } } module.exports = { diff --git a/src/extractors/FHIRDocumentReferenceExtractor.js b/src/extractors/FHIRDocumentReferenceExtractor.js index 4bba509e..6a6c94cb 100644 --- a/src/extractors/FHIRDocumentReferenceExtractor.js +++ b/src/extractors/FHIRDocumentReferenceExtractor.js @@ -1,8 +1,8 @@ const { BaseFHIRExtractor } = require('./BaseFHIRExtractor'); class FHIRDocumentReferenceExtractor extends BaseFHIRExtractor { - constructor({ baseFhirUrl, requestHeaders, version }) { - super({ baseFhirUrl, requestHeaders, version }); + constructor({ baseFhirUrl, requestHeaders, version, searchParameters }) { + super({ baseFhirUrl, requestHeaders, version,searchParameters }); this.resourceType = 'DocumentReference'; } } diff --git a/src/extractors/FHIREncounterExtractor.js b/src/extractors/FHIREncounterExtractor.js index ff30476e..c83c3c6a 100644 --- a/src/extractors/FHIREncounterExtractor.js +++ b/src/extractors/FHIREncounterExtractor.js @@ -1,8 +1,8 @@ const { BaseFHIRExtractor } = require('./BaseFHIRExtractor'); class FHIREncounterExtractor extends BaseFHIRExtractor { - constructor({ baseFhirUrl, requestHeaders, version }) { - super({ baseFhirUrl, requestHeaders, version }); + constructor({ baseFhirUrl, requestHeaders, version, searchParameters }) { + super({ baseFhirUrl, requestHeaders, version, searchParameters }); this.resourceType = 'Encounter'; } } diff --git a/src/extractors/FHIRMedicationOrderExtractor.js b/src/extractors/FHIRMedicationOrderExtractor.js index b06c5d51..1060391c 100644 --- a/src/extractors/FHIRMedicationOrderExtractor.js +++ b/src/extractors/FHIRMedicationOrderExtractor.js @@ -1,8 +1,8 @@ const { BaseFHIRExtractor } = require('./BaseFHIRExtractor'); class FHIRMedicationOrderExtractor extends BaseFHIRExtractor { - constructor({ baseFhirUrl, requestHeaders, version }) { - super({ baseFhirUrl, requestHeaders, version }); + constructor({ baseFhirUrl, requestHeaders, version, searchParameters }) { + super({ baseFhirUrl, requestHeaders, version, searchParameters }); this.resourceType = 'MedicationOrder'; } } diff --git a/src/extractors/FHIRMedicationRequestExtractor.js b/src/extractors/FHIRMedicationRequestExtractor.js index 59c38396..c52e760a 100644 --- a/src/extractors/FHIRMedicationRequestExtractor.js +++ b/src/extractors/FHIRMedicationRequestExtractor.js @@ -1,22 +1,9 @@ const { BaseFHIRExtractor } = require('./BaseFHIRExtractor'); -const BASE_STATUSES = ''; // No status specified, returns all statuses (on-hold, completed, stopped, active) - class FHIRMedicationRequestExtractor extends BaseFHIRExtractor { - constructor({ baseFhirUrl, requestHeaders, version, status }) { - super({ baseFhirUrl, requestHeaders, version }); + constructor({ baseFhirUrl, requestHeaders, version, status, searchParameters }) { + super({ baseFhirUrl, requestHeaders, version, searchParameters }); this.resourceType = 'MedicationRequest'; - this.status = status || BASE_STATUSES; - } - - // In addition to default parametrization, add status if specified - async parametrizeArgsForFHIRModule({ context }) { - const paramsWithID = await super.parametrizeArgsForFHIRModule({ context }); - // Only add status to parameters if it has been specified - return { - ...paramsWithID, - ...(this.status && { status: this.status }), - }; } } diff --git a/src/extractors/FHIRMedicationStatementExtractor.js b/src/extractors/FHIRMedicationStatementExtractor.js index 5af3f0bc..4e8ad130 100644 --- a/src/extractors/FHIRMedicationStatementExtractor.js +++ b/src/extractors/FHIRMedicationStatementExtractor.js @@ -1,8 +1,8 @@ const { BaseFHIRExtractor } = require('./BaseFHIRExtractor'); class FHIRMedicationStatementExtractor extends BaseFHIRExtractor { - constructor({ baseFhirUrl, requestHeaders, version }) { - super({ baseFhirUrl, requestHeaders, version }); + constructor({ baseFhirUrl, requestHeaders, version, searchParameters }) { + super({ baseFhirUrl, requestHeaders, version, searchParameters }); this.resourceType = 'MedicationStatement'; } } diff --git a/src/extractors/FHIRObservationExtractor.js b/src/extractors/FHIRObservationExtractor.js index 661338c4..c2986a7e 100644 --- a/src/extractors/FHIRObservationExtractor.js +++ b/src/extractors/FHIRObservationExtractor.js @@ -1,22 +1,11 @@ const { BaseFHIRExtractor } = require('./BaseFHIRExtractor'); -const BASE_CATEGORIES = 'laboratory,vital-signs,social-history,LDA,core-characteristics'; - class FHIRObservationExtractor extends BaseFHIRExtractor { - constructor({ baseFhirUrl, requestHeaders, version, category }) { - super({ baseFhirUrl, requestHeaders, version }); + constructor({ baseFhirUrl, requestHeaders, version, category, searchParameters }) { + super({ baseFhirUrl, requestHeaders, version, searchParameters }); this.resourceType = 'Observation'; - this.category = category || BASE_CATEGORIES; } - // In addition to default parametrization, add category - async parametrizeArgsForFHIRModule({ context }) { - const paramsWithID = await super.parametrizeArgsForFHIRModule({ context }); - return { - ...paramsWithID, - category: this.category, - }; - } } module.exports = { diff --git a/src/extractors/FHIRPatientExtractor.js b/src/extractors/FHIRPatientExtractor.js index f56a34e5..15fcb991 100644 --- a/src/extractors/FHIRPatientExtractor.js +++ b/src/extractors/FHIRPatientExtractor.js @@ -2,8 +2,8 @@ const { BaseFHIRExtractor } = require('./BaseFHIRExtractor'); const { maskPatientData } = require('../helpers/patientUtils.js'); class FHIRPatientExtractor extends BaseFHIRExtractor { - constructor({ baseFhirUrl, requestHeaders, version, mask = [] }) { - super({ baseFhirUrl, requestHeaders, version }); + constructor({ baseFhirUrl, requestHeaders, version, mask = [], searchParameters }) { + super({ baseFhirUrl, requestHeaders, version, searchParameters }); this.resourceType = 'Patient'; this.mask = mask; } diff --git a/src/extractors/FHIRProcedureExtractor.js b/src/extractors/FHIRProcedureExtractor.js index d899ea56..b03dc458 100644 --- a/src/extractors/FHIRProcedureExtractor.js +++ b/src/extractors/FHIRProcedureExtractor.js @@ -1,8 +1,8 @@ const { BaseFHIRExtractor } = require('./BaseFHIRExtractor'); class FHIRProcedureExtractor extends BaseFHIRExtractor { - constructor({ baseFhirUrl, requestHeaders, version }) { - super({ baseFhirUrl, requestHeaders, version }); + constructor({ baseFhirUrl, requestHeaders, version, searchParameters }) { + super({ baseFhirUrl, requestHeaders, version, searchParameters }); this.resourceType = 'Procedure'; } } diff --git a/src/helpers/patientUtils.js b/src/helpers/patientUtils.js index 0631347e..fc827b05 100644 --- a/src/helpers/patientUtils.js +++ b/src/helpers/patientUtils.js @@ -87,7 +87,7 @@ function maskPatientData(bundle, mask, maskAll = false) { // get Patient resource from bundle const patient = fhirpath.evaluate( bundle, - 'Bundle.entry.where(resource.resourceType=\'Patient\').resource,first()', + 'Bundle.entry.where(resource.resourceType=\'Patient\').resource.first()', )[0]; const validFields = [ diff --git a/src/helpers/schemas/config.schema.json b/src/helpers/schemas/config.schema.json index d31e41c3..42163fe1 100644 --- a/src/helpers/schemas/config.schema.json +++ b/src/helpers/schemas/config.schema.json @@ -41,6 +41,10 @@ "title": "Request Headers", "type": "object" }, + "queryParameters": { + "title": "Query Parameters", + "type": "object" + }, "csvParse" : { "title": "CSV Parse", "type": "object", diff --git a/test/extractors/BaseFHIRExtractor.test.js b/test/extractors/BaseFHIRExtractor.test.js index 68ddcd28..59b26cda 100644 --- a/test/extractors/BaseFHIRExtractor.test.js +++ b/test/extractors/BaseFHIRExtractor.test.js @@ -8,6 +8,9 @@ const MOCK_URL = 'http://localhost'; const MOCK_REQUEST_HEADERS = { Accept: 'application/json', }; +const MOCK_SEARCH_PARAMS = {"_include": "Condition::subject", + "category" : "problem-list-item", + "status" : "final"} const MOCK_RESOURCE_TYPE = 'Condition'; const MOCK_PATIENT_MRN = 'EXAMPLE-MRN'; const MOCK_CONTEXT = { @@ -21,7 +24,7 @@ const MOCK_CONTEXT = { }; // Create extractor and destructure to mock responses on modules -const baseFHIRExtractor = new BaseFHIRExtractor({ baseFhirUrl: MOCK_URL, requestHeaders: MOCK_REQUEST_HEADERS, resourceType: MOCK_RESOURCE_TYPE }); +const baseFHIRExtractor = new BaseFHIRExtractor({ baseFhirUrl: MOCK_URL, requestHeaders: MOCK_REQUEST_HEADERS, resourceType: MOCK_RESOURCE_TYPE , searchParameters: MOCK_SEARCH_PARAMS}); const { baseFHIRModule } = baseFHIRExtractor; // Spies for mocking @@ -29,8 +32,12 @@ const baseFHIRModuleSearchSpy = jest.spyOn(baseFHIRModule, 'search'); const moduleRequestHeadersSpy = jest.spyOn(baseFHIRModule, 'updateRequestHeaders'); // Ensure that data is returned for condition +debugger when(baseFHIRModuleSearchSpy) - .calledWith('Condition', { patient: examplePatientBundle.entry[0].resource.id }) + .calledWith('Condition', { patient: examplePatientBundle.entry[0].resource.id, + _include: MOCK_SEARCH_PARAMS._include, + category: MOCK_SEARCH_PARAMS.category, + status: MOCK_SEARCH_PARAMS.status }) .mockReturnValue(exampleConditionBundle); // Tests @@ -47,6 +54,13 @@ describe('BaseFhirExtractor', () => { expect(baseFHIRModuleSearchSpy).not.toHaveBeenCalled(); expect(paramsBasedOnContext).toHaveProperty('patient'); expect(paramsBasedOnContext.patient).toEqual(MOCK_CONTEXT.entry[0].resource.id); + expect(paramsBasedOnContext).toHaveProperty("_include"); + expect(paramsBasedOnContext._include).toEqual(MOCK_SEARCH_PARAMS._include); + expect(paramsBasedOnContext).toHaveProperty("category"); + expect(paramsBasedOnContext.category).toEqual(MOCK_SEARCH_PARAMS.category); + expect(paramsBasedOnContext).toHaveProperty("status"); + expect(paramsBasedOnContext.status).toEqual(MOCK_SEARCH_PARAMS.status); + }); test('parametrizeArgsForFHIRModule throws an error if context has no relevant ID', async () => { @@ -56,6 +70,7 @@ describe('BaseFhirExtractor', () => { }); test('get should return a condition resource', async () => { + debugger const data = await baseFHIRExtractor.get({ context: MOCK_CONTEXT }); expect(data.resourceType).toEqual('Bundle'); expect(data.entry).toBeDefined(); diff --git a/test/extractors/FHIRAllergyIntoleranceExtractor.test.js b/test/extractors/FHIRAllergyIntoleranceExtractor.test.js index 7856452b..4a484bd7 100644 --- a/test/extractors/FHIRAllergyIntoleranceExtractor.test.js +++ b/test/extractors/FHIRAllergyIntoleranceExtractor.test.js @@ -1,24 +1,8 @@ -const rewire = require('rewire'); const { FHIRAllergyIntoleranceExtractor } = require('../../src/extractors/FHIRAllergyIntoleranceExtractor.js'); - -const FHIRAllergyIntoleranceExtractorRewired = rewire('../../src/extractors/FHIRAllergyIntoleranceExtractor.js'); const MOCK_URL = 'http://example.com'; const MOCK_HEADERS = {}; -const MOCK_MRN = '123456789'; -const MOCK_CLINICAL_STATUS = 'status1,status2'; -const MOCK_CONTEXT = { - resourceType: 'Bundle', - entry: [ - { - fullUrl: 'context-url', - resource: { resourceType: 'Patient', id: MOCK_MRN }, - }, - ], -}; const extractor = new FHIRAllergyIntoleranceExtractor({ baseFhirUrl: MOCK_URL, requestHeaders: MOCK_HEADERS }); -const extractorWithClinicalStatus = new FHIRAllergyIntoleranceExtractor({ baseFhirUrl: MOCK_URL, requestHeaders: MOCK_HEADERS, clinicalStatus: MOCK_CLINICAL_STATUS }); -const baseClinicalStatus = FHIRAllergyIntoleranceExtractorRewired.__get__('BASE_CLINICAL_STATUS'); describe('FHIRAllergyIntoleranceExtractor', () => { describe('Constructor', () => { @@ -26,20 +10,6 @@ describe('FHIRAllergyIntoleranceExtractor', () => { expect(extractor.resourceType).toEqual('AllergyIntolerance'); }); - test('sets clinical status based on BASE_CLINICAL_STATUS', () => { - expect(extractor.clinicalStatus).toEqual(baseClinicalStatus); - }); - - test('sets clinical status if provided', () => { - expect(extractorWithClinicalStatus.clinicalStatus).toEqual(MOCK_CLINICAL_STATUS); - }); }); - describe('parametrizeArgsForFHIRModule', () => { - test('should add category to param values', async () => { - const params = await extractor.parametrizeArgsForFHIRModule({ context: MOCK_CONTEXT }); - expect(params).toHaveProperty('clinical-status'); - expect(params['clinical-status']).toEqual(baseClinicalStatus); - }); - }); }); diff --git a/test/extractors/FHIRConditionExtractor.test.js b/test/extractors/FHIRConditionExtractor.test.js index 9da357a7..21740268 100644 --- a/test/extractors/FHIRConditionExtractor.test.js +++ b/test/extractors/FHIRConditionExtractor.test.js @@ -1,37 +1,16 @@ -const rewire = require('rewire'); const { FHIRConditionExtractor } = require('../../src/extractors/FHIRConditionExtractor.js'); -const MOCK_CONTEXT = require('./fixtures/context-with-patient.json'); -const FHIRConditionExtractorRewired = rewire('../../src/extractors/FHIRConditionExtractor'); const MOCK_URL = 'http://example.com'; const MOCK_HEADERS = {}; -const MOCK_CATEGORIES = 'category1,category2'; + const extractor = new FHIRConditionExtractor({ baseFhirUrl: MOCK_URL, requestHeaders: MOCK_HEADERS }); -const extractorWithCategories = new FHIRConditionExtractor({ baseFhirUrl: MOCK_URL, requestHeaders: MOCK_HEADERS, category: MOCK_CATEGORIES }); -const baseCategories = FHIRConditionExtractorRewired.__get__('BASE_CATEGORIES'); describe('FHIRConditionExtractor', () => { describe('Constructor', () => { test('sets resourceType to Condition', () => { expect(extractor.resourceType).toEqual('Condition'); }); - - test('sets category based on BASE_CATEGORIES if not provided', () => { - expect(extractor.category).toEqual(baseCategories); - }); - - test('sets category if provided', () => { - expect(extractorWithCategories.category).toEqual(MOCK_CATEGORIES); - }); - }); - - describe('parametrizeArgsForFHIRModule', () => { - test('should add category to param values', async () => { - const params = await extractor.parametrizeArgsForFHIRModule({ context: MOCK_CONTEXT }); - expect(params).toHaveProperty('category'); - expect(params.category).toEqual(baseCategories); - }); }); }); diff --git a/test/extractors/FHIRMedicationRequestExtractor.test.js b/test/extractors/FHIRMedicationRequestExtractor.test.js index 28e320a9..fa0e6abc 100644 --- a/test/extractors/FHIRMedicationRequestExtractor.test.js +++ b/test/extractors/FHIRMedicationRequestExtractor.test.js @@ -1,49 +1,14 @@ -const rewire = require('rewire'); const { FHIRMedicationRequestExtractor } = require('../../src/extractors/FHIRMedicationRequestExtractor.js'); -const FHIRMedicationRequestExtractorRewired = rewire('../../src/extractors/FHIRMedicationRequestExtractor.js'); const MOCK_URL = 'http://example.com'; const MOCK_HEADERS = {}; -const MOCK_MRN = '123456789'; -const MOCK_STATUSES = 'status1,status2'; -const MOCK_CONTEXT = { - resourceType: 'Bundle', - entry: [ - { - fullUrl: 'context-url', - resource: { resourceType: 'Patient', id: MOCK_MRN }, - }, - ], -}; - // Construct extractor and create spies for mocking responses const extractor = new FHIRMedicationRequestExtractor({ baseFhirUrl: MOCK_URL, requestHeaders: MOCK_HEADERS }); -const extractorWithStatuses = new FHIRMedicationRequestExtractor({ baseFhirUrl: MOCK_URL, requestHeaders: MOCK_HEADERS, status: MOCK_STATUSES }); -const baseStatuses = FHIRMedicationRequestExtractorRewired.__get__('BASE_STATUSES'); describe('FHIRMedicationRequestExtractor', () => { describe('Constructor', () => { test('sets resourceType as MedicationRequest', () => { expect(extractor.resourceType).toEqual('MedicationRequest'); }); - test('sets status based on BASE_STATUS if not provided', () => { - expect(extractor.status).toEqual(baseStatuses); - }); - test('sets status if provided', () => { - expect(extractorWithStatuses.status).toEqual(MOCK_STATUSES); - }); - }); - - describe('parametrizeArgsForFHIRModule', () => { - test('should not add status when not set to param values', async () => { - const params = await extractor.parametrizeArgsForFHIRModule({ context: MOCK_CONTEXT }); - expect(params).not.toHaveProperty('status'); - }); - - test('should add status when set to param values', async () => { - const params = await extractorWithStatuses.parametrizeArgsForFHIRModule({ context: MOCK_CONTEXT }); - expect(params).toHaveProperty('status'); - expect(params.status).toEqual(extractorWithStatuses.status); - }); }); }); diff --git a/test/extractors/FHIRObservationExtractor.test.js b/test/extractors/FHIRObservationExtractor.test.js index 3bd60f13..7b4b8d08 100644 --- a/test/extractors/FHIRObservationExtractor.test.js +++ b/test/extractors/FHIRObservationExtractor.test.js @@ -1,44 +1,18 @@ -const rewire = require('rewire'); const { FHIRObservationExtractor } = require('../../src/extractors/FHIRObservationExtractor.js'); -const FHIRObservationExtractorRewired = rewire('../../src/extractors/FHIRObservationExtractor.js'); const MOCK_URL = 'http://example.com'; const MOCK_HEADERS = {}; -const MOCK_MRN = '123456789'; -const MOCK_CATEGORIES = 'category1,category2'; -const MOCK_CONTEXT = { - resourceType: 'Bundle', - entry: [ - { - fullUrl: 'context-url', - resource: { resourceType: 'Patient', id: MOCK_MRN }, - }, - ], -}; + + // Construct extractor and create spies for mocking responses const extractor = new FHIRObservationExtractor({ baseFhirUrl: MOCK_URL, requestHeaders: MOCK_HEADERS }); -const extractorWithCategories = new FHIRObservationExtractor({ baseFhirUrl: MOCK_URL, requestHeaders: MOCK_HEADERS, category: MOCK_CATEGORIES }); -const baseCategories = FHIRObservationExtractorRewired.__get__('BASE_CATEGORIES'); describe('FHIRObservationExtractor', () => { describe('Constructor', () => { test('sets resourceType as Observation', () => { expect(extractor.resourceType).toEqual('Observation'); }); - test('sets category based on BASE_CATEGORIES if not provided', () => { - expect(extractor.category).toEqual(baseCategories); - }); - test('sets category if provided', () => { - expect(extractorWithCategories.category).toEqual(MOCK_CATEGORIES); - }); }); - describe('parametrizeArgsForFHIRModule', () => { - test('should add category to param values', async () => { - const params = await extractor.parametrizeArgsForFHIRModule({ context: MOCK_CONTEXT }); - expect(params).toHaveProperty('category'); - expect(params.category).toEqual(baseCategories); - }); - }); }); From 0511aae5136bed3b9c43b7903b657b0ebb8e05ad Mon Sep 17 00:00:00 2001 From: Robert A Dingwell Date: Mon, 6 Nov 2023 17:04:18 -0500 Subject: [PATCH 2/4] updated lock file from install --- package-lock.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index fde4bb9b..668cfe0b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2412,7 +2412,8 @@ }, "ansi-regex": { "version": "5.0.0", - "resolved": "", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "ansi-styles": { From b4c6f48e698283861d9bf0d79d76e3ae44a090e7 Mon Sep 17 00:00:00 2001 From: Robert A Dingwell Date: Tue, 7 Nov 2023 07:12:26 -0500 Subject: [PATCH 3/4] Fixing linting issues --- .eslintrc.json | 2 +- src/extractors/BaseFHIRExtractor.js | 4 ++- src/extractors/FHIRAdverseEventExtractor.js | 6 +++-- .../FHIRAllergyIntoleranceExtractor.js | 6 ++--- src/extractors/FHIRConditionExtractor.js | 3 +-- .../FHIRDocumentReferenceExtractor.js | 2 +- .../FHIRMedicationRequestExtractor.js | 2 +- src/extractors/FHIRObservationExtractor.js | 3 +-- src/extractors/FHIRPatientExtractor.js | 4 ++- test/extractors/BaseFHIRExtractor.test.js | 25 ++++++++----------- .../FHIRAllergyIntoleranceExtractor.test.js | 3 +-- .../extractors/FHIRConditionExtractor.test.js | 1 - .../FHIRObservationExtractor.test.js | 2 -- 13 files changed, 29 insertions(+), 34 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 720ab5b0..6f4a8987 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -21,6 +21,6 @@ "object-curly-newline": ["error", { "ObjectPattern": { "minProperties": 5 } }], - "no-underscore-dangle": ["error", { "allow": ["__get__", "__set__"] }] + "no-underscore-dangle": ["error", { "allow": ["__get__", "__set__","_include"] }] } } diff --git a/src/extractors/BaseFHIRExtractor.js b/src/extractors/BaseFHIRExtractor.js index 126af9ca..15db4341 100644 --- a/src/extractors/BaseFHIRExtractor.js +++ b/src/extractors/BaseFHIRExtractor.js @@ -5,7 +5,9 @@ const { getPatientFromContext } = require('../helpers/contextUtils'); const logger = require('../helpers/logger'); class BaseFHIRExtractor extends Extractor { - constructor({ baseFhirUrl, requestHeaders, version, resourceType, searchParameters={} }) { + constructor({ + baseFhirUrl, requestHeaders, version, resourceType, searchParameters = {}, + }) { super(); this.resourceType = resourceType; this.version = version; diff --git a/src/extractors/FHIRAdverseEventExtractor.js b/src/extractors/FHIRAdverseEventExtractor.js index d214bc00..600e6456 100644 --- a/src/extractors/FHIRAdverseEventExtractor.js +++ b/src/extractors/FHIRAdverseEventExtractor.js @@ -5,8 +5,10 @@ const logger = require('../helpers/logger'); const BASE_STUDY = ''; // No base study specified class FHIRAdverseEventExtractor extends BaseFHIRExtractor { - constructor({ baseFhirUrl, requestHeaders, version, study, searchParameters }) { - super({ baseFhirUrl, requestHeaders, version,searchParameters }); + constructor({ + baseFhirUrl, requestHeaders, version, study, searchParameters, + }) { + super({ baseFhirUrl, requestHeaders, version, searchParameters }); this.resourceType = 'AdverseEvent'; this.study = study || BASE_STUDY; } diff --git a/src/extractors/FHIRAllergyIntoleranceExtractor.js b/src/extractors/FHIRAllergyIntoleranceExtractor.js index a37629f9..7c034855 100644 --- a/src/extractors/FHIRAllergyIntoleranceExtractor.js +++ b/src/extractors/FHIRAllergyIntoleranceExtractor.js @@ -1,13 +1,11 @@ const { BaseFHIRExtractor } = require('./BaseFHIRExtractor'); -const BASE_CLINICAL_STATUS = 'active'; class FHIRAllergyIntoleranceExtractor extends BaseFHIRExtractor { - constructor({ baseFhirUrl, requestHeaders, version,searchParameters }) { - super({ baseFhirUrl, requestHeaders, version,searchParameters }); + constructor({ baseFhirUrl, requestHeaders, version, searchParameters }) { + super({ baseFhirUrl, requestHeaders, version, searchParameters }); this.resourceType = 'AllergyIntolerance'; } - } module.exports = { diff --git a/src/extractors/FHIRConditionExtractor.js b/src/extractors/FHIRConditionExtractor.js index 57b029db..f4a1d1f9 100644 --- a/src/extractors/FHIRConditionExtractor.js +++ b/src/extractors/FHIRConditionExtractor.js @@ -1,11 +1,10 @@ const { BaseFHIRExtractor } = require('./BaseFHIRExtractor'); class FHIRConditionExtractor extends BaseFHIRExtractor { - constructor({ baseFhirUrl, requestHeaders, version, searchParameters}) { + constructor({ baseFhirUrl, requestHeaders, version, searchParameters }) { super({ baseFhirUrl, requestHeaders, version, searchParameters }); this.resourceType = 'Condition'; } - } module.exports = { diff --git a/src/extractors/FHIRDocumentReferenceExtractor.js b/src/extractors/FHIRDocumentReferenceExtractor.js index 6a6c94cb..18086e47 100644 --- a/src/extractors/FHIRDocumentReferenceExtractor.js +++ b/src/extractors/FHIRDocumentReferenceExtractor.js @@ -2,7 +2,7 @@ const { BaseFHIRExtractor } = require('./BaseFHIRExtractor'); class FHIRDocumentReferenceExtractor extends BaseFHIRExtractor { constructor({ baseFhirUrl, requestHeaders, version, searchParameters }) { - super({ baseFhirUrl, requestHeaders, version,searchParameters }); + super({ baseFhirUrl, requestHeaders, version, searchParameters }); this.resourceType = 'DocumentReference'; } } diff --git a/src/extractors/FHIRMedicationRequestExtractor.js b/src/extractors/FHIRMedicationRequestExtractor.js index c52e760a..be068ff2 100644 --- a/src/extractors/FHIRMedicationRequestExtractor.js +++ b/src/extractors/FHIRMedicationRequestExtractor.js @@ -1,7 +1,7 @@ const { BaseFHIRExtractor } = require('./BaseFHIRExtractor'); class FHIRMedicationRequestExtractor extends BaseFHIRExtractor { - constructor({ baseFhirUrl, requestHeaders, version, status, searchParameters }) { + constructor({ baseFhirUrl, requestHeaders, version, searchParameters }) { super({ baseFhirUrl, requestHeaders, version, searchParameters }); this.resourceType = 'MedicationRequest'; } diff --git a/src/extractors/FHIRObservationExtractor.js b/src/extractors/FHIRObservationExtractor.js index c2986a7e..bc9b6d63 100644 --- a/src/extractors/FHIRObservationExtractor.js +++ b/src/extractors/FHIRObservationExtractor.js @@ -1,11 +1,10 @@ const { BaseFHIRExtractor } = require('./BaseFHIRExtractor'); class FHIRObservationExtractor extends BaseFHIRExtractor { - constructor({ baseFhirUrl, requestHeaders, version, category, searchParameters }) { + constructor({ baseFhirUrl, requestHeaders, version, searchParameters }) { super({ baseFhirUrl, requestHeaders, version, searchParameters }); this.resourceType = 'Observation'; } - } module.exports = { diff --git a/src/extractors/FHIRPatientExtractor.js b/src/extractors/FHIRPatientExtractor.js index 15fcb991..be139e37 100644 --- a/src/extractors/FHIRPatientExtractor.js +++ b/src/extractors/FHIRPatientExtractor.js @@ -2,7 +2,9 @@ const { BaseFHIRExtractor } = require('./BaseFHIRExtractor'); const { maskPatientData } = require('../helpers/patientUtils.js'); class FHIRPatientExtractor extends BaseFHIRExtractor { - constructor({ baseFhirUrl, requestHeaders, version, mask = [], searchParameters }) { + constructor({ + baseFhirUrl, requestHeaders, version, mask = [], searchParameters, + }) { super({ baseFhirUrl, requestHeaders, version, searchParameters }); this.resourceType = 'Patient'; this.mask = mask; diff --git a/test/extractors/BaseFHIRExtractor.test.js b/test/extractors/BaseFHIRExtractor.test.js index 59b26cda..4236019c 100644 --- a/test/extractors/BaseFHIRExtractor.test.js +++ b/test/extractors/BaseFHIRExtractor.test.js @@ -8,9 +8,9 @@ const MOCK_URL = 'http://localhost'; const MOCK_REQUEST_HEADERS = { Accept: 'application/json', }; -const MOCK_SEARCH_PARAMS = {"_include": "Condition::subject", - "category" : "problem-list-item", - "status" : "final"} +const MOCK_SEARCH_PARAMS = { _include: 'Condition::subject', + category: 'problem-list-item', + status: 'final' }; const MOCK_RESOURCE_TYPE = 'Condition'; const MOCK_PATIENT_MRN = 'EXAMPLE-MRN'; const MOCK_CONTEXT = { @@ -24,7 +24,7 @@ const MOCK_CONTEXT = { }; // Create extractor and destructure to mock responses on modules -const baseFHIRExtractor = new BaseFHIRExtractor({ baseFhirUrl: MOCK_URL, requestHeaders: MOCK_REQUEST_HEADERS, resourceType: MOCK_RESOURCE_TYPE , searchParameters: MOCK_SEARCH_PARAMS}); +const baseFHIRExtractor = new BaseFHIRExtractor({ baseFhirUrl: MOCK_URL, requestHeaders: MOCK_REQUEST_HEADERS, resourceType: MOCK_RESOURCE_TYPE, searchParameters: MOCK_SEARCH_PARAMS }); const { baseFHIRModule } = baseFHIRExtractor; // Spies for mocking @@ -32,12 +32,11 @@ const baseFHIRModuleSearchSpy = jest.spyOn(baseFHIRModule, 'search'); const moduleRequestHeadersSpy = jest.spyOn(baseFHIRModule, 'updateRequestHeaders'); // Ensure that data is returned for condition -debugger when(baseFHIRModuleSearchSpy) - .calledWith('Condition', { patient: examplePatientBundle.entry[0].resource.id, - _include: MOCK_SEARCH_PARAMS._include, - category: MOCK_SEARCH_PARAMS.category, - status: MOCK_SEARCH_PARAMS.status }) + .calledWith('Condition', { patient: examplePatientBundle.entry[0].resource.id, + _include: MOCK_SEARCH_PARAMS._include, + category: MOCK_SEARCH_PARAMS.category, + status: MOCK_SEARCH_PARAMS.status }) .mockReturnValue(exampleConditionBundle); // Tests @@ -54,13 +53,12 @@ describe('BaseFhirExtractor', () => { expect(baseFHIRModuleSearchSpy).not.toHaveBeenCalled(); expect(paramsBasedOnContext).toHaveProperty('patient'); expect(paramsBasedOnContext.patient).toEqual(MOCK_CONTEXT.entry[0].resource.id); - expect(paramsBasedOnContext).toHaveProperty("_include"); + expect(paramsBasedOnContext).toHaveProperty('_include'); expect(paramsBasedOnContext._include).toEqual(MOCK_SEARCH_PARAMS._include); - expect(paramsBasedOnContext).toHaveProperty("category"); + expect(paramsBasedOnContext).toHaveProperty('category'); expect(paramsBasedOnContext.category).toEqual(MOCK_SEARCH_PARAMS.category); - expect(paramsBasedOnContext).toHaveProperty("status"); + expect(paramsBasedOnContext).toHaveProperty('status'); expect(paramsBasedOnContext.status).toEqual(MOCK_SEARCH_PARAMS.status); - }); test('parametrizeArgsForFHIRModule throws an error if context has no relevant ID', async () => { @@ -70,7 +68,6 @@ describe('BaseFhirExtractor', () => { }); test('get should return a condition resource', async () => { - debugger const data = await baseFHIRExtractor.get({ context: MOCK_CONTEXT }); expect(data.resourceType).toEqual('Bundle'); expect(data.entry).toBeDefined(); diff --git a/test/extractors/FHIRAllergyIntoleranceExtractor.test.js b/test/extractors/FHIRAllergyIntoleranceExtractor.test.js index 4a484bd7..cec9d630 100644 --- a/test/extractors/FHIRAllergyIntoleranceExtractor.test.js +++ b/test/extractors/FHIRAllergyIntoleranceExtractor.test.js @@ -1,4 +1,5 @@ const { FHIRAllergyIntoleranceExtractor } = require('../../src/extractors/FHIRAllergyIntoleranceExtractor.js'); + const MOCK_URL = 'http://example.com'; const MOCK_HEADERS = {}; @@ -9,7 +10,5 @@ describe('FHIRAllergyIntoleranceExtractor', () => { test('sets resourceType as AllergyIntolerance', () => { expect(extractor.resourceType).toEqual('AllergyIntolerance'); }); - }); - }); diff --git a/test/extractors/FHIRConditionExtractor.test.js b/test/extractors/FHIRConditionExtractor.test.js index 21740268..12ea84fb 100644 --- a/test/extractors/FHIRConditionExtractor.test.js +++ b/test/extractors/FHIRConditionExtractor.test.js @@ -4,7 +4,6 @@ const MOCK_URL = 'http://example.com'; const MOCK_HEADERS = {}; - const extractor = new FHIRConditionExtractor({ baseFhirUrl: MOCK_URL, requestHeaders: MOCK_HEADERS }); describe('FHIRConditionExtractor', () => { diff --git a/test/extractors/FHIRObservationExtractor.test.js b/test/extractors/FHIRObservationExtractor.test.js index 7b4b8d08..33e924b4 100644 --- a/test/extractors/FHIRObservationExtractor.test.js +++ b/test/extractors/FHIRObservationExtractor.test.js @@ -4,7 +4,6 @@ const MOCK_URL = 'http://example.com'; const MOCK_HEADERS = {}; - // Construct extractor and create spies for mocking responses const extractor = new FHIRObservationExtractor({ baseFhirUrl: MOCK_URL, requestHeaders: MOCK_HEADERS }); @@ -14,5 +13,4 @@ describe('FHIRObservationExtractor', () => { expect(extractor.resourceType).toEqual('Observation'); }); }); - }); From 0c09fd788f16691f75c368b228fa25e5a6f309da Mon Sep 17 00:00:00 2001 From: Robert A Dingwell Date: Mon, 27 Nov 2023 13:55:43 -0500 Subject: [PATCH 4/4] changing property name and moving to constructor args location. --- src/helpers/schemas/config.schema.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/helpers/schemas/config.schema.json b/src/helpers/schemas/config.schema.json index 42163fe1..f766ade0 100644 --- a/src/helpers/schemas/config.schema.json +++ b/src/helpers/schemas/config.schema.json @@ -41,10 +41,6 @@ "title": "Request Headers", "type": "object" }, - "queryParameters": { - "title": "Query Parameters", - "type": "object" - }, "csvParse" : { "title": "CSV Parse", "type": "object", @@ -160,6 +156,10 @@ "title": "Type", "type": "string" }, + "searchParameters": { + "title": "Search Parameters", + "type": "object" + }, "mask": { "title": "Masked Fields", "oneOf": [