diff --git a/src/extractors/CSVAdverseEventExtractor.js b/src/extractors/CSVAdverseEventExtractor.js index 2f48fb61..bdbdecbe 100644 --- a/src/extractors/CSVAdverseEventExtractor.js +++ b/src/extractors/CSVAdverseEventExtractor.js @@ -10,8 +10,23 @@ function formatData(adverseEventData, patientId) { logger.debug('Reformatting adverse event data from CSV into template format'); return adverseEventData.map((data) => { const { - adverseEventId, adverseEventCode, adverseEventCodeSystem, adverseEventDisplayText, suspectedCauseId, suspectedCauseType, seriousness, seriousnessCodeSystem, seriousnessDisplayText, - category, categoryCodeSystem, categoryDisplayText, severity, actuality, studyId, effectiveDate, recordedDate, + adverseeventid: adverseEventId, + adverseeventcode: adverseEventCode, + adverseeventcodesystem: adverseEventCodeSystem, + adverseeventdisplaytext: adverseEventDisplayText, + suspectedcauseid: suspectedCauseId, + suspectedcausetype: suspectedCauseType, + seriousness, + seriousnesscodesystem: seriousnessCodeSystem, + seriousnessdisplaytext: seriousnessDisplayText, + category, + categorycodesystem: categoryCodeSystem, + categorydisplaytext: categoryDisplayText, + severity, + actuality, + studyid: studyId, + effectivedate: effectiveDate, + recordeddate: recordedDate, } = data; if (!(adverseEventCode && effectiveDate)) { diff --git a/src/extractors/CSVCancerDiseaseStatusExtractor.js b/src/extractors/CSVCancerDiseaseStatusExtractor.js index 166232ea..69e0dc39 100644 --- a/src/extractors/CSVCancerDiseaseStatusExtractor.js +++ b/src/extractors/CSVCancerDiseaseStatusExtractor.js @@ -16,31 +16,40 @@ class CSVCancerDiseaseStatusExtractor extends BaseCSVExtractor { joinAndReformatData(arrOfDiseaseStatusData, patientId) { logger.debug('Reformatting disease status data from CSV into template format'); // Check the shape of the data - arrOfDiseaseStatusData.forEach((record) => { - if (!record.conditionId || !record.diseaseStatusCode || !record.dateOfObservation) { + return arrOfDiseaseStatusData.map((record) => { + const { + conditionid: conditionId, + diseasestatuscode: diseaseStatusCode, + diseasestatustext: diseaseStatusText, + dateofobservation: dateOfObservation, + observationstatus: observationStatus, + evidence, + } = record; + + if (!conditionId || !diseaseStatusCode || !dateOfObservation) { throw new Error('DiseaseStatusData missing an expected property: conditionId, diseaseStatusCode, and dateOfObservation are required.'); } + + return { + status: observationStatus || 'final', + value: { + code: diseaseStatusCode, + system: 'http://snomed.info/sct', + display: diseaseStatusText || getDiseaseStatusDisplay(diseaseStatusCode, this.implementation), + }, + subject: { + id: patientId, + }, + condition: { + id: conditionId, + }, + effectiveDateTime: formatDateTime(dateOfObservation), + evidence: !evidence ? null : evidence.split('|').map((evidenceCode) => ({ + code: evidenceCode, + display: getDiseaseStatusEvidenceDisplay(evidenceCode), + })), + }; }); - const evidenceDelimiter = '|'; - return arrOfDiseaseStatusData.map((record) => ({ - status: record.observationStatus || 'final', - value: { - code: record.diseaseStatusCode, - system: 'http://snomed.info/sct', - display: record.diseaseStatusText ? record.diseaseStatusText : getDiseaseStatusDisplay(record.diseaseStatusCode, this.implementation), - }, - subject: { - id: patientId, - }, - condition: { - id: record.conditionId, - }, - effectiveDateTime: formatDateTime(record.dateOfObservation), - evidence: !record.evidence ? null : record.evidence.split(evidenceDelimiter).map((evidenceCode) => ({ - code: evidenceCode, - display: getDiseaseStatusEvidenceDisplay(evidenceCode), - })), - })); } async getDiseaseStatusData(mrn, fromDate, toDate) { diff --git a/src/extractors/CSVCancerRelatedMedicationExtractor.js b/src/extractors/CSVCancerRelatedMedicationExtractor.js index 336d9a24..15765695 100644 --- a/src/extractors/CSVCancerRelatedMedicationExtractor.js +++ b/src/extractors/CSVCancerRelatedMedicationExtractor.js @@ -11,7 +11,17 @@ function formatData(medicationData, patientId) { return medicationData.map((medication) => { const { - medicationId, code, codeSystem, displayText, startDate, endDate, treatmentReasonCode, treatmentReasonCodeSystem, treatmentReasonDisplayText, treatmentIntent, status, + medicationid: medicationId, + code, + codesystem: codeSystem, + displaytext: displayText, + startdate: startDate, + enddate: endDate, + treatmentreasoncode: treatmentReasonCode, + treatmentreasoncodesystem: treatmentReasonCodeSystem, + treatmentreasondisplaytext: treatmentReasonDisplayText, + treatmentintent: treatmentIntent, + status, } = medication; if (!(code && codeSystem && status)) { diff --git a/src/extractors/CSVClinicalTrialInformationExtractor.js b/src/extractors/CSVClinicalTrialInformationExtractor.js index 71e0ebda..f215eb98 100644 --- a/src/extractors/CSVClinicalTrialInformationExtractor.js +++ b/src/extractors/CSVClinicalTrialInformationExtractor.js @@ -18,7 +18,11 @@ class CSVClinicalTrialInformationExtractor extends BaseCSVExtractor { joinClinicalTrialData(clinicalTrialData, patientId) { logger.debug('Reformatting clinical trial data from CSV into template format'); const { - trialSubjectID, enrollmentStatus, trialResearchID, trialStatus, trialResearchSystem, + trialsubjectid: trialSubjectID, + enrollmentstatus: enrollmentStatus, + trialresearchid: trialResearchID, + trialstatus: trialStatus, + trialresearchsystem: trialResearchSystem, } = clinicalTrialData; const { clinicalSiteID, clinicalSiteSystem } = this; diff --git a/src/extractors/CSVConditionExtractor.js b/src/extractors/CSVConditionExtractor.js index 694059ca..56a2775a 100644 --- a/src/extractors/CSVConditionExtractor.js +++ b/src/extractors/CSVConditionExtractor.js @@ -11,7 +11,17 @@ function formatData(conditionData, patientId) { logger.debug('Reformatting condition data from CSV into template format'); return conditionData.map((data) => { const { - conditionId, codeSystem, code, displayName, category, dateOfDiagnosis, clinicalStatus, verificationStatus, bodySite, laterality, histology, + conditionid: conditionId, + codesystem: codeSystem, + code, + displayname: displayName, + category, + dateofdiagnosis: dateOfDiagnosis, + clinicalstatus: clinicalStatus, + verificationstatus: verificationStatus, + bodysite: bodySite, + laterality, + histology, } = data; if (!(conditionId && codeSystem && code && category)) { diff --git a/src/extractors/CSVObservationExtractor.js b/src/extractors/CSVObservationExtractor.js index 8b13ff74..8a2c8cfe 100644 --- a/src/extractors/CSVObservationExtractor.js +++ b/src/extractors/CSVObservationExtractor.js @@ -9,7 +9,16 @@ function formatData(observationData, patientId) { logger.debug('Reformatting observation data from CSV into template format'); return observationData.map((data) => { const { - observationId, status, code, codeSystem, displayName, value, valueCodeSystem, effectiveDate, bodySite, laterality, + observationid: observationId, + status, + code, + codesystem: codeSystem, + displayname: displayName, + value, + valuecodesystem: valueCodeSystem, + effectivedate: effectiveDate, + bodysite: bodySite, + laterality, } = data; if (!observationId || !status || !code || !codeSystem || !value || !effectiveDate) { diff --git a/src/extractors/CSVPatientExtractor.js b/src/extractors/CSVPatientExtractor.js index 018b0a27..342a2348 100644 --- a/src/extractors/CSVPatientExtractor.js +++ b/src/extractors/CSVPatientExtractor.js @@ -13,7 +13,19 @@ function joinAndReformatData(patientData) { logger.debug('Reformatting patient data from CSV into template format'); // No join needed, just a reformatting const { - mrn, familyName, givenName, gender, birthsex, dateOfBirth, race, ethnicity, language, addressLine, city, state, zip, + mrn, + familyname: familyName, + givenname: givenName, + gender, + birthsex, + dateofbirth: dateOfBirth, + race, + ethnicity, + language, + addressline: addressLine, + city, + state, + zip, } = patientData; if (!mrn) { diff --git a/src/extractors/CSVProcedureExtractor.js b/src/extractors/CSVProcedureExtractor.js index ab6909d4..590bf7fc 100644 --- a/src/extractors/CSVProcedureExtractor.js +++ b/src/extractors/CSVProcedureExtractor.js @@ -10,7 +10,19 @@ function formatData(procedureData, patientId) { logger.debug('Reformatting procedure data from CSV into template format'); return procedureData.map((data) => { const { - procedureId, conditionId, status, code, codeSystem, displayName, reasonCode, reasonCodeSystem, reasonDisplayName, bodySite, laterality, effectiveDate, treatmentIntent, + procedureid: procedureId, + conditionid: conditionId, + status, + code, + codesystem: codeSystem, + displayname: displayName, + reasoncode: reasonCode, + reasoncodesystem: reasonCodeSystem, + reasondisplayname: reasonDisplayName, + bodysite: bodySite, + laterality, + effectivedate: effectiveDate, + treatmentintent: treatmentIntent, } = data; if (!(procedureId && status && code && codeSystem && effectiveDate)) { diff --git a/src/extractors/CSVStagingExtractor.js b/src/extractors/CSVStagingExtractor.js index f10cffe7..3cd73bd2 100644 --- a/src/extractors/CSVStagingExtractor.js +++ b/src/extractors/CSVStagingExtractor.js @@ -9,7 +9,14 @@ function formatTNMCategoryData(stagingData, patientId) { logger.debug('Reformatting TNM Category data into template format'); const formattedData = []; const { - conditionId, t, n, m, type, stagingSystem, stagingCodeSystem, effectiveDate, + conditionid: conditionId, + t, + n, + m, + type, + stagingsystem: stagingSystem, + stagingcodesystem: stagingCodeSystem, + effectivedate: effectiveDate, } = stagingData; if (!conditionId || !effectiveDate) { @@ -35,7 +42,12 @@ function formatTNMCategoryData(stagingData, patientId) { function formatStagingData(stagingData, categoryIds, patientId) { const { - conditionId, type, stageGroup, stagingSystem, stagingCodeSystem, effectiveDate, + conditionid: conditionId, + type, + stagegroup: stageGroup, + stagingsystem: stagingSystem, + stagingcodesystem: stagingCodeSystem, + effectivedate: effectiveDate, } = stagingData; return { diff --git a/src/extractors/CSVTreatmentPlanChangeExtractor.js b/src/extractors/CSVTreatmentPlanChangeExtractor.js index e7a291a5..b24d580b 100644 --- a/src/extractors/CSVTreatmentPlanChangeExtractor.js +++ b/src/extractors/CSVTreatmentPlanChangeExtractor.js @@ -21,7 +21,10 @@ function formatData(tpcData, patientId) { // If there are multiple entries, combine them into one object with multiple reviews const combinedData = _.reduce(tpcData, (res, currentDataEntry) => { - const { dateOfCarePlan, changed, reasonCode, reasonDisplayText } = currentDataEntry; + const { dateofcareplan: dateOfCarePlan, + changed, + reasoncode: reasonCode, + reasondisplaytext: reasonDisplayText } = currentDataEntry; if (!dateOfCarePlan || !changed) { throw new Error('Treatment Plan Change Data missing an expected property: dateOfCarePlan, changed are required'); diff --git a/src/helpers/csvValidator.js b/src/helpers/csvValidator.js index 960cb330..eba51eae 100644 --- a/src/helpers/csvValidator.js +++ b/src/helpers/csvValidator.js @@ -5,9 +5,9 @@ function validateCSV(pathToCSVFile, csvSchema, csvData) { let isValid = true; // Check headers - const headers = Object.keys(csvData[0]); - const schemaDiff = _.difference(csvSchema.headers.map((h) => h.name), headers); - const fileDiff = _.difference(headers, csvSchema.headers.map((h) => h.name)); + const headers = Object.keys(csvData[0]).map((h) => h.toLowerCase()); + const schemaDiff = _.difference(csvSchema.headers.map((h) => h.name.toLowerCase()), headers); + const fileDiff = _.difference(headers, csvSchema.headers.map((h) => h.name.toLowerCase())); if (fileDiff.length > 0) { logger.warn(`Found extra column(s) in CSV ${pathToCSVFile}: "${fileDiff.join(',')}"`); @@ -15,7 +15,7 @@ function validateCSV(pathToCSVFile, csvSchema, csvData) { if (schemaDiff.length > 0) { schemaDiff.forEach((sd) => { - const headerSchema = csvSchema.headers.find((h) => h.name === sd); + const headerSchema = csvSchema.headers.find((h) => h.name.toLowerCase() === sd); if (headerSchema.required) { logger.error(`Column ${sd} is marked as required but is missing in CSV ${pathToCSVFile}`); isValid = false; diff --git a/src/modules/CSVModule.js b/src/modules/CSVModule.js index 1d03701f..5fc27f0a 100644 --- a/src/modules/CSVModule.js +++ b/src/modules/CSVModule.js @@ -5,22 +5,22 @@ const logger = require('../helpers/logger'); class CSVModule { constructor(csvFilePath) { - this.data = parse(fs.readFileSync(csvFilePath), { columns: true, bom: true }); + this.data = parse(fs.readFileSync(csvFilePath), { columns: (header) => header.map((column) => column.toLowerCase()), bom: true }); } async get(key, value, fromDate, toDate) { logger.debug(`Get csvModule info by key '${key}'`); // return all rows if key and value aren't provided if (!key && !value) return this.data; - let result = this.data.filter((d) => d[key] === value); + let result = this.data.filter((d) => d[key.toLowerCase()] === value); if (result.length === 0) { logger.warn(`CSV Record with provided key '${key}' and value was not found`); return result; } // If fromDate and toDate is provided, filter out all results that fall outside that timespan - if (fromDate && moment(fromDate).isValid()) result = result.filter((r) => !(r.dateRecorded && moment(fromDate).isAfter(r.dateRecorded))); - if (toDate && moment(toDate).isValid()) result = result.filter((r) => !(r.dateRecorded && moment(toDate).isBefore(r.dateRecorded))); + if (fromDate && moment(fromDate).isValid()) result = result.filter((r) => !(r.daterecorded && moment(fromDate).isAfter(r.daterecorded))); + if (toDate && moment(toDate).isValid()) result = result.filter((r) => !(r.daterecorded && moment(toDate).isBefore(r.daterecorded))); if (result.length === 0) logger.warn('No data for patient within specified time range'); return result; } diff --git a/test/extractors/CSVAdverseEventExtractor.test.js b/test/extractors/CSVAdverseEventExtractor.test.js index a6161e85..37c30823 100644 --- a/test/extractors/CSVAdverseEventExtractor.test.js +++ b/test/extractors/CSVAdverseEventExtractor.test.js @@ -51,17 +51,17 @@ describe('CSVAdverseEventExtractor', () => { expect(() => formatData(localData, patientId)).toThrow(new Error(expectedCategoryErrorString)); // Test that adding another category but adding a corresponding categoryCodeSystem and categoryDisplayText works fine - localData[0].categoryCodeSystem = 'http://terminology.hl7.org/CodeSystem/adverse-event-category|http://snomed.info/sct'; - localData[0].categoryDisplayText = 'Product Use Error|Product Problem'; + localData[0].categorycodesystem = 'http://terminology.hl7.org/CodeSystem/adverse-event-category|http://snomed.info/sct'; + localData[0].categorydisplaytext = 'Product Use Error|Product Problem'; expect(formatData(localData, patientId)).toEqual(expect.anything()); // Test that adding another category but including syntax for default categoryCodeSystem and categoryDisplayText values works fine - localData[0].categoryCodeSystem = 'http://terminology.hl7.org/CodeSystem/adverse-event-category|'; - localData[0].categoryDisplayText = 'Product Use Error|'; + localData[0].categorycodesystem = 'http://terminology.hl7.org/CodeSystem/adverse-event-category|'; + localData[0].categorydisplaytext = 'Product Use Error|'; expect(formatData(localData, patientId)).toEqual(expect.anything()); // Test that deleting a mandatory value throws an error - delete localData[0].adverseEventCode; + delete localData[0].adverseeventcode; expect(() => formatData(localData, patientId)).toThrow(new Error(expectedErrorString)); }); }); diff --git a/test/extractors/CSVCancerDiseaseStatusExtractor.test.js b/test/extractors/CSVCancerDiseaseStatusExtractor.test.js index 54d3d5f7..afc76f1b 100644 --- a/test/extractors/CSVCancerDiseaseStatusExtractor.test.js +++ b/test/extractors/CSVCancerDiseaseStatusExtractor.test.js @@ -35,12 +35,12 @@ describe('CSVCancerDiseaseStatusExtractor', () => { expect(csvCancerDiseaseStatusExtractor.joinAndReformatData(exampleCSVDiseaseStatusModuleResponse, patientId)).toEqual(expect.anything()); localData[0].evidence = ''; // Evidence is not required and will not throw an error - localData[0].observationStatus = ''; // Observation Status is not required and will not throw an error + localData[0].observationstatus = ''; // Observation Status is not required and will not throw an error // Only including required properties is valid expect(csvCancerDiseaseStatusExtractor.joinAndReformatData(localData, patientId)).toEqual(expect.anything()); - const requiredProperties = ['conditionId', 'diseaseStatusCode', 'dateOfObservation']; + const requiredProperties = ['conditionid', 'diseasestatuscode', 'dateofobservation']; // Removing each required property should throw an error requiredProperties.forEach((key) => { diff --git a/test/extractors/CSVClinicalTrialInformationExtractor.test.js b/test/extractors/CSVClinicalTrialInformationExtractor.test.js index 073252d2..d8fee6b5 100644 --- a/test/extractors/CSVClinicalTrialInformationExtractor.test.js +++ b/test/extractors/CSVClinicalTrialInformationExtractor.test.js @@ -39,7 +39,7 @@ describe('CSVClinicalTrialInformationExtractor', () => { const clonedData = _.cloneDeep(firstClinicalTrialInfoResponse); expect(csvClinicalTrialInformationExtractor.joinClinicalTrialData(clonedData, patientId)).toEqual(expect.anything()); if (key === 'patientId') return; // MRN is optional - if (key === 'trialResearchSystem') return; // trialResearchSystem is optional + if (key === 'trialresearchsystem') return; // trialResearchSystem is optional delete clonedData[key]; expect(() => csvClinicalTrialInformationExtractor.joinClinicalTrialData(clonedData, patientId)).toThrow(new Error(expectedErrorString)); }); @@ -47,18 +47,18 @@ describe('CSVClinicalTrialInformationExtractor', () => { // joinClinicalTrialData should return correct format expect(csvClinicalTrialInformationExtractor.joinClinicalTrialData(firstClinicalTrialInfoResponse, patientId)).toEqual({ formattedDataSubject: { - enrollmentStatus: firstClinicalTrialInfoResponse.enrollmentStatus, - trialSubjectID: firstClinicalTrialInfoResponse.trialSubjectID, - trialResearchID: firstClinicalTrialInfoResponse.trialResearchID, + enrollmentStatus: firstClinicalTrialInfoResponse.enrollmentstatus, + trialSubjectID: firstClinicalTrialInfoResponse.trialsubjectid, + trialResearchID: firstClinicalTrialInfoResponse.trialresearchid, patientId, - trialResearchSystem: firstClinicalTrialInfoResponse.trialResearchSystem, + trialResearchSystem: firstClinicalTrialInfoResponse.trialresearchsystem, }, formattedDataStudy: { - trialStatus: firstClinicalTrialInfoResponse.trialStatus, - trialResearchID: firstClinicalTrialInfoResponse.trialResearchID, + trialStatus: firstClinicalTrialInfoResponse.trialstatus, + trialResearchID: firstClinicalTrialInfoResponse.trialresearchid, clinicalSiteID: MOCK_CLINICAL_SITE_ID, clinicalSiteSystem: MOCK_CLINICAL_SITE_SYSTEM, - trialResearchSystem: firstClinicalTrialInfoResponse.trialResearchSystem, + trialResearchSystem: firstClinicalTrialInfoResponse.trialresearchsystem, }, }); }); diff --git a/test/extractors/CSVObservationExtractor.test.js b/test/extractors/CSVObservationExtractor.test.js index 9922d400..d7e60938 100644 --- a/test/extractors/CSVObservationExtractor.test.js +++ b/test/extractors/CSVObservationExtractor.test.js @@ -38,7 +38,7 @@ describe('CSVObservationExtractor', () => { expect(formatData(exampleCSVObservationModuleResponse, patientId)).toEqual(expect.anything()); // Test that deleting an optional value works fine - delete localData[0].bodySite; + delete localData[0].bodysite; expect(formatData(exampleCSVObservationModuleResponse, patientId)).toEqual(expect.anything()); // Test that deleting a mandatory value throws an error diff --git a/test/extractors/CSVProcedureExtractor.test.js b/test/extractors/CSVProcedureExtractor.test.js index 65592c39..18368f86 100644 --- a/test/extractors/CSVProcedureExtractor.test.js +++ b/test/extractors/CSVProcedureExtractor.test.js @@ -37,11 +37,11 @@ describe('CSVProcedureExtractor', () => { expect(formatData(localData, patientId)).toEqual(expect.anything()); // Test that removing an optional value works - delete localData[0].bodySite; + delete localData[0].bodysite; expect(formatData(localData, patientId)).toEqual(expect.anything()); // Test that removing a required value throws - delete localData[0].procedureId; + delete localData[0].procedureid; expect(() => formatData(localData, patientId)).toThrow(new Error(expectedErrorString)); }); }); diff --git a/test/extractors/CSVStagingExtractor.test.js b/test/extractors/CSVStagingExtractor.test.js index c9eae1e4..44ce15a7 100644 --- a/test/extractors/CSVStagingExtractor.test.js +++ b/test/extractors/CSVStagingExtractor.test.js @@ -36,15 +36,15 @@ describe('CSVStagingExtractor', () => { localData.m = ''; localData.n = ''; localData.type = ''; - localData.stagingSystem = ''; - localData.stagingCodeSystem = ''; - localData.stageGroup = ''; + localData.stagingsystem = ''; + localData.stagingcodesystem = ''; + localData.stagegroup = ''; // Only including required properties is valid expect(formatTNMCategoryData(localData)).toEqual(expect.anything()); // Removing each required property should throw an error - const requiredKeys = ['conditionId', 'effectiveDate']; + const requiredKeys = ['conditionid', 'effectivedate']; requiredKeys.forEach((key) => { const clonedData = _.cloneDeep(localData); clonedData[key] = ''; diff --git a/test/extractors/CSVTreatmentPlanChangeExtractor.test.js b/test/extractors/CSVTreatmentPlanChangeExtractor.test.js index 9849d208..1009ef6c 100644 --- a/test/extractors/CSVTreatmentPlanChangeExtractor.test.js +++ b/test/extractors/CSVTreatmentPlanChangeExtractor.test.js @@ -27,14 +27,14 @@ describe('CSVTreatmentPlanChangeExtractor', () => { describe('formatData', () => { const exampleData = [ { - dateOfCarePlan: '2020-04-15', + dateofcareplan: '2020-04-15', changed: 'false', mrn: 'id', }, { - dateOfCarePlan: '2020-04-30', + dateofcareplan: '2020-04-30', changed: 'true', - reasonCode: 'example code', + reasoncode: 'example code', mrn: 'id', }, ]; @@ -47,7 +47,7 @@ describe('CSVTreatmentPlanChangeExtractor', () => { expect(() => formatData(exampleData, patientId)).not.toThrowError(); // Test required properties throw error - const requiredKeys = ['dateOfCarePlan', 'changed']; + const requiredKeys = ['dateofcareplan', 'changed']; requiredKeys.forEach((key) => { const clonedData = _.cloneDeep(exampleData); @@ -64,7 +64,7 @@ describe('CSVTreatmentPlanChangeExtractor', () => { expect(() => formatData(exampleData, patientId)).toThrow(new Error(expectedErrorString)); // No error should be throw when reasonCode is provided - exampleData[0].reasonCode = 'example code'; + exampleData[0].reasoncode = 'example code'; expect(() => formatData(exampleData, patientId)).not.toThrowError(); }); diff --git a/test/extractors/fixtures/csv-adverse-event-module-response.json b/test/extractors/fixtures/csv-adverse-event-module-response.json index c51e0490..d3543916 100644 --- a/test/extractors/fixtures/csv-adverse-event-module-response.json +++ b/test/extractors/fixtures/csv-adverse-event-module-response.json @@ -1,22 +1,22 @@ [ { "mrn": "mrn-1", - "adverseEventId": "adverseEventId-1", - "adverseEventCode": "109006", - "adverseEventCodeSystem": "code-system", - "adverseEventDisplayText": "Anxiety disorder of childhood OR adolescence", - "suspectedCauseId": "procedure-id", - "suspectedCauseType": "Procedure", + "adverseeventid": "adverseEventId-1", + "adverseeventcode": "109006", + "adverseeventcodesystem": "code-system", + "adverseeventdisplaytext": "Anxiety disorder of childhood OR adolescence", + "suspectedcauseid": "procedure-id", + "suspectedcausetype": "Procedure", "seriousness": "serious", - "seriousnessCodeSystem": "http://terminology.hl7.org/CodeSystem/adverse-event-seriousness", - "seriousnessDisplayText": "Serious", + "seriousnesscodesystem": "http://terminology.hl7.org/CodeSystem/adverse-event-seriousness", + "seriousnessdisplaytext": "Serious", "category": "product-use-error", - "categoryCodeSystem": "http://terminology.hl7.org/CodeSystem/adverse-event-category", - "categoryDisplayText": "Product Use Error", + "categorycodesystem": "http://terminology.hl7.org/CodeSystem/adverse-event-category", + "categorydisplaytext": "Product Use Error", "severity": "severe", "actuality": "actual", - "studyId": "researchId-1", - "effectiveDate": "12-09-1994", - "recordedDate": "12-09-1994" + "studyid": "researchId-1", + "effectivedate": "12-09-1994", + "recordeddate": "12-09-1994" } ] \ No newline at end of file diff --git a/test/extractors/fixtures/csv-cancer-disease-status-module-response.json b/test/extractors/fixtures/csv-cancer-disease-status-module-response.json index bc5a09ad..497744d0 100644 --- a/test/extractors/fixtures/csv-cancer-disease-status-module-response.json +++ b/test/extractors/fixtures/csv-cancer-disease-status-module-response.json @@ -1,10 +1,10 @@ [ { "mrn": "mrn-1", - "conditionId": "cond-1", - "diseaseStatusCode": "268910001", - "dateOfObservation": "2019-12-02", + "conditionid": "cond-1", + "diseasestatuscode": "268910001", + "dateofobservation": "2019-12-02", "evidence": "363679005|252416005", - "observationStatus": "amended" + "observationstatus": "amended" } ] diff --git a/test/extractors/fixtures/csv-clinical-trial-information-module-response.json b/test/extractors/fixtures/csv-clinical-trial-information-module-response.json index 92558480..f7317f26 100644 --- a/test/extractors/fixtures/csv-clinical-trial-information-module-response.json +++ b/test/extractors/fixtures/csv-clinical-trial-information-module-response.json @@ -1,10 +1,10 @@ [ { "patientId": "mrn-1", - "trialSubjectID": "example-subjectId", - "enrollmentStatus": "example-enrollment-status", - "trialResearchID": "example-researchId", - "trialStatus": "example-trialStatus", - "trialResearchSystem": "example-system" + "trialsubjectid": "example-subjectId", + "enrollmentstatus": "example-enrollment-status", + "trialresearchid": "example-researchId", + "trialstatus": "example-trialStatus", + "trialresearchsystem":"example-system" } ] diff --git a/test/extractors/fixtures/csv-condition-module-response.json b/test/extractors/fixtures/csv-condition-module-response.json index dc6e3101..8932841c 100644 --- a/test/extractors/fixtures/csv-condition-module-response.json +++ b/test/extractors/fixtures/csv-condition-module-response.json @@ -1,15 +1,15 @@ [ { "mrn": "mrn-1", - "conditionId": "conditionId-1", - "codeSystem": "http://hl7.org/fhir/sid/icd-10-cm", + "conditionid": "conditionId-1", + "codesystem": "http://hl7.org/fhir/sid/icd-10-cm", "code": "C02.0", - "displayName": "Some Cancer Condition", + "displayname": "Some Cancer Condition", "category": "example-category", - "dateOfDiagnosis": "YYYY-MM-DD", - "clinicalStatus": "example-status", - "verificationStatus": "example-status", - "bodySite": "example-site", + "dateofdiagnosis": "YYYY-MM-DD", + "clinicalstatus": "example-status", + "verificationstatus": "example-status", + "bodysite": "example-site", "laterality": "example-laterality", "histology": "example-histology" } diff --git a/test/extractors/fixtures/csv-medication-module-response.json b/test/extractors/fixtures/csv-medication-module-response.json index e549d875..64c2a7c5 100644 --- a/test/extractors/fixtures/csv-medication-module-response.json +++ b/test/extractors/fixtures/csv-medication-module-response.json @@ -1,16 +1,16 @@ [ { "mrn": "mrn-1", - "medicationId": "medicationId-1", + "medicationid": "medicationId-1", "code": "example-code", - "codeSystem": "example-code-system", - "displayText": "Example Text", - "startDate": "YYYY-MM-DD", - "endDate": "YYYY-MM-DD", - "treatmentReasonCode": "example-reason", - "treatmentReasonCodeSystem": "example-code-system", - "treatmentReasonDisplayText": "Example Text", - "treatmentIntent": "example-code", + "codesystem": "example-code-system", + "displaytext": "Example Text", + "startdate": "YYYY-MM-DD", + "enddate": "YYYY-MM-DD", + "treatmentreasoncode": "example-reason", + "treatmentreasoncodesystem": "example-code-system", + "treatmentreasondisplaytext": "Example Text", + "treatmentintent": "example-code", "status": "example-status" } ] diff --git a/test/extractors/fixtures/csv-observation-module-response.json b/test/extractors/fixtures/csv-observation-module-response.json index d05e251b..cdde520e 100644 --- a/test/extractors/fixtures/csv-observation-module-response.json +++ b/test/extractors/fixtures/csv-observation-module-response.json @@ -1,15 +1,15 @@ [ { "mrn": "mrn-1", - "observationId": "observation-id", + "observationid": "observation-id", "status": "final", "code": "1695-6", - "codeSystem": "http://loinc.org", - "displayName": "", + "codesystem": "http://loinc.org", + "displayname": "", "value": "10828004", - "valueCodeSystem": "http://snomed.info/sct", - "effectiveDate": "2020-01-02", - "bodySite": "12345", + "valuecodesystem": "http://snomed.info/sct", + "effectivedate": "2020-01-02", + "bodysite": "12345", "laterality": "678910" } ] diff --git a/test/extractors/fixtures/csv-patient-module-response.json b/test/extractors/fixtures/csv-patient-module-response.json index bfe23726..e475a4c9 100644 --- a/test/extractors/fixtures/csv-patient-module-response.json +++ b/test/extractors/fixtures/csv-patient-module-response.json @@ -1,13 +1,13 @@ [ { "mrn": "119147111821125", - "familyName": "Marshall", - "givenName": "Archy", + "familyname": "Marshall", + "givenname": "Archy", "gender": "male", "birthsex": "male", - "dateOfBirth":"1994-08-24", + "dateofbirth":"1994-08-24", "language": "en", - "addressLine": "57 Adams St", + "addressline": "57 Adams St", "city": "New Rochelle", "state": "NY", "zip": "10801", diff --git a/test/extractors/fixtures/csv-procedure-module-response.json b/test/extractors/fixtures/csv-procedure-module-response.json index c7dc1341..15c3fe86 100644 --- a/test/extractors/fixtures/csv-procedure-module-response.json +++ b/test/extractors/fixtures/csv-procedure-module-response.json @@ -1,18 +1,18 @@ [ { "mrn": "mrn-1", - "procedureId": "procedure-1", - "conditionId": "condition-id", + "procedureid": "procedure-1", + "conditionid": "condition-id", "status": "completed", - "codeSystem": "http://snomed.info/sct", + "codesystem": "http://snomed.info/sct", "code": "152198000", - "displayName": "Brachytherapy (procedure)", - "reasonCode": "example-code", - "reasonCodeSystem": "example-system", - "reasonDisplayName": "example-name", - "bodySite": "example-site", + "displayname": "Brachytherapy (procedure)", + "reasoncode": "example-code", + "reasoncodesystem": "example-system", + "reasondisplayname": "example-name", + "bodysite": "example-site", "laterality": "example-laterality", - "treatmentIntent": "example-treatment-intent", - "effectiveDate": "2020-01-01" + "treatmentintent": "example-treatment-intent", + "effectivedate": "2020-01-01" } ] \ No newline at end of file diff --git a/test/extractors/fixtures/csv-staging-module-response.json b/test/extractors/fixtures/csv-staging-module-response.json index e84c26a5..f287630c 100644 --- a/test/extractors/fixtures/csv-staging-module-response.json +++ b/test/extractors/fixtures/csv-staging-module-response.json @@ -1,14 +1,14 @@ [ { "mrn": "mrn-1", - "conditionId": "cond-1", - "stageGroup": "3C", + "conditionid": "cond-1", + "stagegroup": "3C", "t": "cT3", "n": "cN3", "m": "cM0", "type": "Clinical", - "stagingSystem": "444256004", - "stagingCodeSystem": "http://snomed.info/sct", - "effectiveDate": "2020-01-01" + "stagingsystem": "444256004", + "stagingcodesystem": "http://snomed.info/sct", + "effectivedate": "2020-01-01" } ] diff --git a/test/extractors/fixtures/csv-treatment-plan-change-module-response.json b/test/extractors/fixtures/csv-treatment-plan-change-module-response.json index c049a026..ffef92d4 100644 --- a/test/extractors/fixtures/csv-treatment-plan-change-module-response.json +++ b/test/extractors/fixtures/csv-treatment-plan-change-module-response.json @@ -1,15 +1,15 @@ [ { "subjectId": "mrn-1", - "dateOfCarePlan": "2020-04-15", - "reasonCode": "281647001", - "reasonDisplayText": "Adverse reaction (disorder)", + "dateofcareplan": "2020-04-15", + "reasoncode": "281647001", + "reasondisplaytext": "Adverse reaction (disorder)", "changed": "true" }, { "subjectId": "mrn-1", - "dateOfCarePlan": "2020-04-30", - "reasonCode": "405613005", + "dateofcareplan": "2020-04-30", + "reasoncode": "405613005", "changed": "true" } ] diff --git a/test/helpers/csvValidator.test.js b/test/helpers/csvValidator.test.js index 1b554fa7..a575fab9 100644 --- a/test/helpers/csvValidator.test.js +++ b/test/helpers/csvValidator.test.js @@ -65,6 +65,14 @@ const SIMPLE_DATA_MISSING_OPTIONAL_COLUMN = [ }, ]; +const SIMPLE_DATA_DIFFERENT_CASING = [ + { + Header1: '1', + hEaDeR2: '2', + header3: '3', + }, +]; + const schema = { headers: [ { name: 'header1', required: true }, @@ -93,4 +101,8 @@ describe('csvValidator', () => { test('data missing an optional column should still validate', () => { expect(validateCSV('', schema, SIMPLE_DATA_MISSING_OPTIONAL_COLUMN)).toBe(true); }); + + test('data with different casing in the column header should still validate', () => { + expect(validateCSV('', schema, SIMPLE_DATA_DIFFERENT_CASING)).toBe(true); + }); }); diff --git a/test/modules/CSVModule.test.js b/test/modules/CSVModule.test.js index 2ea6d72e..8fd7e7aa 100644 --- a/test/modules/CSVModule.test.js +++ b/test/modules/CSVModule.test.js @@ -41,3 +41,8 @@ test('Should return an empty array when key-value pair does not exist', async () const data = await csvModule.get('mrn', INVALID_MRN); expect(data).toEqual([]); }); + +test('Should return proper value regardless of key casing', async () => { + const data = await csvModule.get('mRN', 'example-mrn-1'); + expect(data).toEqual(exampleResponse); +}); diff --git a/test/modules/fixtures/csv-response.json b/test/modules/fixtures/csv-response.json index e9950bc8..41143988 100644 --- a/test/modules/fixtures/csv-response.json +++ b/test/modules/fixtures/csv-response.json @@ -1,10 +1,10 @@ [ { "mrn": "example-mrn-1", - "trialSubjectID": "subjectId-1", - "enrollmentStatus": "status-1", - "trialResearchID": "researchId-1", - "trialStatus": "trialStatus-1", - "dateRecorded": "2020-01-10" + "trialsubjectid": "subjectId-1", + "enrollmentstatus": "status-1", + "trialresearchid": "researchId-1", + "trialstatus": "trialStatus-1", + "daterecorded": "2020-01-10" } ]