Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions src/application/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const { sendEmailNotification, zipErrors } = require('./tools/emailNotifications
const { extractDataForPatients } = require('./tools/mcodeExtraction');
const { maskMRN } = require('../helpers/patientUtils');
const { parsePatientIds } = require('../helpers/appUtils');
const { validateConfig } = require('../helpers/configValidator');

function getConfig(pathToConfig) {
// Checks pathToConfig points to valid JSON file
Expand All @@ -20,7 +21,7 @@ function getConfig(pathToConfig) {

function checkInputAndConfig(config, fromDate, toDate) {
// Check input args and needed config variables based on client being used
const { patientIdCsvPath } = config;
validateConfig(config);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it might be useful to have some (likely debug level?) log statements here to indicate that this is happening/has succeeded after the function call


// Check if `fromDate` is a valid date
if (fromDate && !moment(fromDate).isValid()) {
Expand All @@ -31,11 +32,6 @@ function checkInputAndConfig(config, fromDate, toDate) {
if (toDate && !moment(toDate).isValid()) {
throw new Error('-t/--to-date is not a valid date.');
}

// Check if there is a path to the MRN CSV within our config JSON
if (!patientIdCsvPath) {
throw new Error('patientIdCsvPath is required in config file');
}
}

async function mcodeApp(Client, fromDate, toDate, pathToConfig, pathToRunLogs, debug, allEntries) {
Expand Down
20 changes: 20 additions & 0 deletions src/helpers/configValidator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const Ajv = require('ajv');
const metaSchema = require('ajv/lib/refs/json-schema-draft-06.json');
const logger = require('./logger');
const configSchema = require('./schemas/config.schema.json');

const ajv = new Ajv({ logger: false, allErrors: true });
ajv.addMetaSchema(metaSchema);
const validator = ajv.addSchema(configSchema, 'config');

function validateConfig(config) {
logger.debug('Validating config file');
const valid = validator.validate('config', config);
const errors = ajv.errorsText(validator.errors, { dataVar: 'config' });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not realize there was a way to access errors from the base Ajv object, good find!

if (!valid) throw new Error(`Error(s) found in config file: ${errors}`);
logger.debug('Config file validated successfully');
}

module.exports = {
validateConfig,
};
2 changes: 1 addition & 1 deletion src/helpers/schemas/config.schema.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$id": "csv-config",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "http://json-schema.org/draft-06/schema#",
"description": "Schema for mcode-extraction-framework config files",
"type": "object",
"properties": {
Expand Down
12 changes: 7 additions & 5 deletions test/application/app.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,19 @@ describe('App Tests', () => {
});

describe('checkInputAndConfig', () => {
const config = { patientIdCsvPath: '', extractors: [] };
it('should throw error when fromDate is invalid.', () => {
expect(() => checkInputAndConfig(testConfig, '2020-06-31')).toThrowError('-f/--from-date is not a valid date.');
expect(() => checkInputAndConfig(config, '2020-06-31')).toThrowError('-f/--from-date is not a valid date.');
});
it('should throw error when toDate is invalid date.', () => {
expect(() => checkInputAndConfig(testConfig, '2020-06-30', '2020-06-31')).toThrowError('-t/--to-date is not a valid date.');
expect(() => checkInputAndConfig(config, '2020-06-30', '2020-06-31')).toThrowError('-t/--to-date is not a valid date.');
});
it('should throw error when patientIdCsvPath not provided in config', () => {
expect(() => checkInputAndConfig({})).toThrowError('patientIdCsvPath is required in config file');
it('should throw error when config is not valid', () => {
expect(() => checkInputAndConfig({}))
.toThrowError('Error(s) found in config file: config should have required property \'patientIdCsvPath\', config should have required property \'extractors\'');
});
it('should not throw error when all args are valid', () => {
expect(() => checkInputAndConfig(testConfig, '2020-06-01', '2020-06-30')).not.toThrowError();
expect(() => checkInputAndConfig(config, '2020-06-01', '2020-06-30')).not.toThrowError();
});
});
});
24 changes: 24 additions & 0 deletions test/helpers/configValidator.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const { validateConfig } = require('../../src/helpers/configValidator.js');

describe('validateConfig', () => {
const missingPropertyConfig = { patientIdCsvPath: '' };
const wrongTypeConfig = { patientIdCsvPath: '', extractors: 12 };
const wrongFormatConfig = { patientIdCsvPath: '', extractors: [], commonExtractorArgs: { baseFhirUrl: 'wrong' } };
const validConfig = { patientIdCsvPath: '', extractors: [] };

test('Should throw error when config file is missing required property', () => {
expect(() => validateConfig(missingPropertyConfig)).toThrowError('Error(s) found in config file: config should have required property \'extractors\'');
});

test('Should throw error when property is of incorrect type', () => {
expect(() => validateConfig(wrongTypeConfig)).toThrowError('Error(s) found in config file: config.extractors should be array');
});

test('Should throw error when property has incorrect format', () => {
expect(() => validateConfig(wrongFormatConfig)).toThrowError('Error(s) found in config file: config.commonExtractorArgs.baseFhirUrl should match format "uri"');
});

test('Should not throw error when config file is valid', () => {
expect(() => validateConfig(validConfig)).not.toThrow();
});
});