From 5ebcbfc51745157e43eedaa34f7c337f1e2fd063 Mon Sep 17 00:00:00 2001 From: arodidev <51090527+arodidev@users.noreply.github.com> Date: Wed, 15 Nov 2023 07:43:54 +0300 Subject: [PATCH 1/2] Functions refactored for defensive coding --- .../src/form-validator.test.ts | 0 .../esm-form-render-app/src/form-validator.ts | 60 ++++++++++++------- 2 files changed, 37 insertions(+), 23 deletions(-) create mode 100644 packages/esm-form-render-app/src/form-validator.test.ts diff --git a/packages/esm-form-render-app/src/form-validator.test.ts b/packages/esm-form-render-app/src/form-validator.test.ts new file mode 100644 index 000000000..e69de29bb diff --git a/packages/esm-form-render-app/src/form-validator.ts b/packages/esm-form-render-app/src/form-validator.ts index f9f4b4e89..c504b8b51 100644 --- a/packages/esm-form-render-app/src/form-validator.ts +++ b/packages/esm-form-render-app/src/form-validator.ts @@ -5,35 +5,49 @@ export const handleFormValidation = async (schema, configObject) => { const errors = []; const warnings = []; - if (schema) { - const parsedForm = typeof schema == 'string' ? JSON.parse(schema) : schema; - - const asyncTasks = []; + if (!schema) { + throw new Error('Invalid argument: "schema" cannot be null or undefined. Please provide a valid object.'); + } - parsedForm.pages?.forEach((page) => - page.sections?.forEach((section) => - section.questions?.forEach((question) => { - asyncTasks.push( - handleQuestionValidation(question, errors, configObject, warnings), - handleAnswerValidation(question, errors, warnings), + const parsedForm = typeof schema == 'string' ? JSON.parse(schema) : schema; + + const asyncTasks = []; + + parsedForm.pages?.forEach((page) => + page.sections?.forEach((section) => + section.questions?.forEach((question) => { + asyncTasks.push( + handleQuestionValidation(question, errors, configObject, warnings), + handleAnswerValidation(question, errors, warnings), + ); + question.type === 'obsGroup' && + question.questions?.forEach((obsGrpQuestion) => + asyncTasks.push( + handleQuestionValidation(obsGrpQuestion, errors, configObject, warnings), + handleAnswerValidation(question, errors, warnings), + ), ); - question.type === 'obsGroup' && - question.questions?.forEach((obsGrpQuestion) => - asyncTasks.push( - handleQuestionValidation(obsGrpQuestion, errors, configObject, warnings), - handleAnswerValidation(question, errors, warnings), - ), - ); - }), - ), - ); - await Promise.all(asyncTasks); + }), + ), + ); + await Promise.all(asyncTasks); - return [errors, warnings]; - } + return [errors, warnings]; }; const handleQuestionValidation = async (conceptObject, errorsArray, configObject, warningsArray) => { + if (!configObject || !Object.keys(configObject)?.length) { + throw new Error( + 'Invalid argument: "configObject" cannot be null, undefined or an empty object. Please provide a valid object.', + ); + } + + if (!conceptObject || !Object.keys(conceptObject)?.length) { + throw new Error( + 'Invalid argument: "conceptObject" cannot be null, undefined or an empty object. Please provide a valid object.', + ); + } + const conceptRepresentation = 'custom:(uuid,display,datatype,answers,conceptMappings:(conceptReferenceTerm:(conceptSource:(name),code)))'; From e2995645ba5b27523c4a9e9537ec54033522c464 Mon Sep 17 00:00:00 2001 From: arodidev <51090527+arodidev@users.noreply.github.com> Date: Thu, 16 Nov 2023 09:26:05 +0300 Subject: [PATCH 2/2] Added test plus jest env configuration --- jest.config.js | 1 + .../esm-form-render-app/src/form-validator.test.ts | 11 +++++++++++ packages/esm-form-render-app/src/form-validator.ts | 13 +++++++++++-- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/jest.config.js b/jest.config.js index a544b1cc4..afd1588c5 100644 --- a/jest.config.js +++ b/jest.config.js @@ -24,6 +24,7 @@ const config = { 'react-markdown': '/__mocks__/react-markdown.tsx', '^dexie$': require.resolve('dexie'), }, + testEnvironment: 'jsdom', }; module.exports = config; diff --git a/packages/esm-form-render-app/src/form-validator.test.ts b/packages/esm-form-render-app/src/form-validator.test.ts index e69de29bb..f93059ba2 100644 --- a/packages/esm-form-render-app/src/form-validator.test.ts +++ b/packages/esm-form-render-app/src/form-validator.test.ts @@ -0,0 +1,11 @@ +/** @jest-environment jsdom */ + +import { handleFormValidation } from './form-validator'; + +describe('handleFormValidation', () => { + it('should fail when no schema is passed to the function', async () => { + await expect(() => handleFormValidation(null, null)).rejects.toThrow( + 'Invalid argument: "schema" cannot be null, undefined or an empty object. Please provide a valid object.', + ); + }); +}); diff --git a/packages/esm-form-render-app/src/form-validator.ts b/packages/esm-form-render-app/src/form-validator.ts index c504b8b51..4728bb573 100644 --- a/packages/esm-form-render-app/src/form-validator.ts +++ b/packages/esm-form-render-app/src/form-validator.ts @@ -1,12 +1,21 @@ import { openmrsFetch } from '@openmrs/esm-framework'; +import { OHRIFormSchema } from '@openmrs/openmrs-form-engine-lib'; import { async } from 'rxjs'; export const handleFormValidation = async (schema, configObject) => { const errors = []; const warnings = []; - if (!schema) { - throw new Error('Invalid argument: "schema" cannot be null or undefined. Please provide a valid object.'); + if (!schema || !Object.keys(schema)?.length) { + throw new Error( + 'Invalid argument: "schema" cannot be null, undefined or an empty object. Please provide a valid object.', + ); + } + + if (!configObject || !Object.keys(configObject)?.length) { + throw new Error( + 'Invalid argument: "configObject" cannot be null, undefined or an empty object. Please provide a valid object.', + ); } const parsedForm = typeof schema == 'string' ? JSON.parse(schema) : schema;