TypeScript v4.4.4 is being used to transpile ES6+
codes, and Jasmine v4.4.4 with real-time console reported jasmine-spec-reporter to run tests.
Node v8+ is required.
Run npm install
from project root to install all necessary packages.
Run npm start
or npm run start
The project gets built and published on the BFRP Feed and can be imported in applications as
import ValidationEngine from 'bfrp-ar-validation'
The module can be instantiated with validation configuration as below
const valEngine = new ValidationEngine(config)
The validation engine works by running submission data through logic rules, returning either a pass or a fail. The validation config specifies what data needs to be sent to the logic rules.
The validation engine handles whether or not a validation should trigger. This is done by populating the validation config with form data before it is sent to the logic rule.
For example, a logic rule may look like:
"VAL0001S": {
"type": "SOFT",
"ruleId": "033_v2",
"cellSets": [
{ "setName": "mainCells", "cells": [ "DON010" ] },
{ "setName": "otherCells", "cells": [ "DON020" ] }
],
"message": "..."
}
This would get populated with field values and disabled statuses resulting in:
"VAL0001S": {
"type": "SOFT",
"ruleId": "033_v2",
"cellSets": [
{ "setName": "mainCells", "cells": [ "DON010" ], data: [ 100 ], "disabledStatus": [ false ] },
{ "setName": "otherCells", "cells": [ "DON020" ], data: [ 300 ], "disabledStatus": [ false ] }
],
"message": "..."
}
Above, you can see that DON010
has a value of 100
, while DON020
has a value of 300
.
If a field is yet to be given a value it will appear in data
as undefined
. When an undefined value is found within data
we know that the user has not completed all of the pages needed for this validation to trigger so we do not run the logic rule.
If a field does not have value (it is undefined
) but the field is disabled (perhaps on a page locked by the questionnaire responses) we replace undefined
with 0
so the logic rule will run.
Using the field requirements config file (generated from AR Web Forms and stored at /src/config/field-requirements.json
) we can use submission data to calculate whether or not a field is disabled. For example, if DON010
was only enabled if QUE010
is set to true
we can set its disabled status based on the data in QUE010.
Within a cell set there are additional configuration values that can give different behaviours to the triggering:
-
allAcademyData
when getting cell set data at academy level, data will be retrieved for all academies regardless of whether an instance was supplied when this is set totrue
-
noTrigger
data will be retrieved for this cell set however the validation will not trigger for these cells if this is set totrue
-
zeroIfFieldMissing
missing fields within this cell set will be given a value of0
regardless of field disabled status if this is set totrue
Before we send the populated validation config to the logic rule the validation engine adds methods to the cell sets to make it easy for the logic rules to make calculations. For example, from inside a logic rule we can call config.cellSets.sumOf('mainCells')
which would return a sum of all the field values within main cells. The available methods are:
-
cellsIn(cellSetName)
returns list of cells (field ids) in a specified cell set -
getPropertyValue
return a property value of a specified cell set -
hasValue
retruntrue
if cell set has that set name item -
sumOf(cellSetName)
returns a sum of the values held within a specified cell set -
valueOf(cellSetName, cellSetItemLocation)
returns the value held within a specified cell set and location (first location is default) -
valuesIn(cellSetName)
returns list of values held within a specified cell set
Each logic rule returns a LogicResult object. The values for this object are as follows:
result
- true/false value for overall pass/fail of the validation (required)
missingDataIdentified
- no longer needed as missing data will be caught by triggering, not the logic rule (optional)
failedCells
- a list of field ids to apply the error to. Used if not all cells fail and we only want to show errors on failed cells (optional)
academies
- used to return academy level result(s) (pass/fail) so academy validation errors can work independantly from each other (optional)
dynamicRows
- used to return result(s) (pass/fail) at dynamic row level so validation errors can target specific rows on dynamic lists (optional)