diff --git a/references/list.json b/references/list.json
index c2ac6300..33b37e5a 100644
--- a/references/list.json
+++ b/references/list.json
@@ -1,6 +1,8 @@
{
- "yes_no": ["Yes", "No", "Unknown"],
- "yes_no_na": ["Yes", "No", "Not applicable", "Unknown"],
+ "yes_no": ["Yes", "No"],
+ "yes_no_unk": ["Yes", "No", "Unknown"],
+ "yes_no_na": ["Yes", "No", "Not applicable"],
+ "yes_no_na_unk": ["Yes", "No", "Not applicable", "Unknown"],
"exposure_usage": ["Never","Not applicable", "Unknown","Yes, currently","Yes, only in the past"],
"exposure_frequency": [
"Never",
@@ -29,14 +31,14 @@
"FIGO staging system",
"Lugano staging system",
"Rai staging system",
- "Revised International staging system (RISS)",
+ "Revised International staging system (R-ISS)",
"St Jude staging system"
],
- "drug_dosage_units": ["mg/m2", "IU/m2", "ug/m2", "g/m2", "mg/kg"],
+ "drug_dose_units": ["mg/m2", "IU/m2", "ug/m2", "g/m2", "mg/kg"],
"stage_groups": ["Occult Carcinoma", "Stage 0", "Stage 0a", "Stage 0is", "Stage 1", "Stage 1A", "Stage 1B", "Stage A", "Stage B", "Stage C", "Stage I", "Stage IA", "Stage IA1", "Stage IA2", "Stage IA3", "Stage IAB", "Stage IAE", "Stage IAES", "Stage IAS", "Stage IB", "Stage IB1", "Stage IB2", "Stage IBE", "Stage IBES", "Stage IBS", "Stage IC", "Stage IE", "Stage IEA", "Stage IEB", "Stage IES", "Stage II", "Stage II bulky", "Stage IIA", "Stage IIA1", "Stage IIA2", "Stage IIAE", "Stage IIAES", "Stage IIAS", "Stage IIB", "Stage IIBE", "Stage IIBES", "Stage IIBS", "Stage IIC", "Stage IIE", "Stage IIEA", "Stage IIEB", "Stage IIES", "Stage III", "Stage IIIA", "Stage IIIA1", "Stage IIIA2", "Stage IIIAE", "Stage IIIAES", "Stage IIIAS", "Stage IIIB", "Stage IIIBE", "Stage IIIBES", "Stage IIIBS", "Stage IIIC", "Stage IIIC1", "Stage IIIC2", "Stage IIID", "Stage IIIE", "Stage IIIES", "Stage IIIS", "Stage IIS", "Stage IS", "Stage IV", "Stage IVA", "Stage IVA1", "Stage IVA2", "Stage IVAE", "Stage IVAES", "Stage IVAS", "Stage IVB", "Stage IVBE", "Stage IVBES", "Stage IVBS", "Stage IVC", "Stage IVE", "Stage IVES", "Stage IVS", "Cannot be assessed"],
"t_categories": ["T0","T1","T1a","T1a1","T1a2","T1a(s)","T1a(m)","T1b","T1b1","T1b2","T1b(s)","T1b(m)","T1c","T1d","T1mi","T2","T2(s)","T2(m)","T2a","T2a1","T2a2","T2b","T2c","T2d","T3","T3(s)","T3(m)","T3a","T3b","T3c","T3d","T3e","T4","T4a","T4a(s)","T4a(m)","T4b","T4b(s)","T4b(m)","T4c","T4d","T4e","Ta","Tis","Tis(DCIS)","Tis(LAMN)","Tis(LCIS)","Tis(Paget)","Tis(Paget’s)","Tis pd","Tis pu","TX"],
"n_categories": ["N0","N0a","N0a (biopsy)","N0b","N0b (no biopsy)","N0(i+)","N0(i-)","N0(mol+)","N0(mol-)","N1","N1a","N1a(sn)","N1b","N1c","N1mi","N2","N2a","N2b","N2c","N2mi","N3","N3a","N3b","N3c","N4","NX"],
- "m_categories": ["M0","M0(i+)","M1","M1a","M1a(0)","M1a(1)","M1b","M1b(0)","M1b(1)","M1c","M1c(0)","M1c(1)","M1d","M1d(0)","M1d(1)","M1e","MX"],
+ "m_categories": ["M0","M0(i+)","M1","M1a","M1a(0)","M1a(1)","M1b","M1b(0)","M1b(1)","M1c","M1c(0)","M1c(1)","M1d","M1d(0)","M1d(1)","M1e","MX", "Not applicable"],
"adverse_events": [
"Abdominal distension",
"Abdominal infection",
@@ -1026,5 +1028,77 @@
"Triple bypass of pancreas",
"Wedge/localised gastric resection",
"Wide Local Excision"
- ]
+ ],
+ "primary_site": [
+ "Accessory sinuses",
+ "Adrenal gland",
+ "Anus and anal canal",
+ "Base of tongue",
+ "Bladder",
+ "Bones, joints and articular cartilage of limbs",
+ "Bones, joints and articular cartilage of other and unspecified sites",
+ "Brain",
+ "Breast",
+ "Bronchus and lung",
+ "Cervix uteri",
+ "Colon",
+ "Connective, subcutaneous and other soft tissues",
+ "Corpus uteri",
+ "Esophagus",
+ "Eye and adnexa",
+ "Floor of mouth",
+ "Gallbladder",
+ "Gum",
+ "Heart, mediastinum, and pleura",
+ "Hematopoietic and reticuloendothelial systems",
+ "Hypopharynx",
+ "Kidney",
+ "Larynx",
+ "Lip",
+ "Liver and intrahepatic bile ducts",
+ "Lymph nodes",
+ "Meninges",
+ "Nasal cavity and middle ear",
+ "Nasopharynx",
+ "Oropharynx",
+ "Other and ill-defined digestive organs",
+ "Other and ill-defined sites",
+ "Other and ill-defined sites in lip, oral cavity and pharynx",
+ "Other and ill-defined sites within respiratory system and intrathoracic organs",
+ "Other and unspecified female genital organs",
+ "Other and unspecified major salivary glands",
+ "Other and unspecified male genital organs",
+ "Other and unspecified parts of biliary tract",
+ "Other and unspecified parts of mouth",
+ "Other and unspecified parts of tongue",
+ "Other and unspecified urinary organs",
+ "Other endocrine glands and related structures",
+ "Ovary",
+ "Palate",
+ "Pancreas",
+ "Parotid gland",
+ "Penis",
+ "Peripheral nerves and autonomic nervous system",
+ "Placenta",
+ "Prostate gland",
+ "Pyriform sinus",
+ "Rectosigmoid junction",
+ "Rectum",
+ "Renal pelvis",
+ "Retroperitoneum and peritoneum",
+ "Skin",
+ "Small intestine",
+ "Spinal cord, cranial nerves, and other parts of central nervous system",
+ "Stomach",
+ "Testis",
+ "Thymus",
+ "Thyroid gland",
+ "Tonsil",
+ "Trachea",
+ "Unknown primary site",
+ "Ureter",
+ "Uterus, NOS",
+ "Vagina",
+ "Vulva"
+ ]
}
diff --git a/references/validationFunctions/chemotherapy/drugDose.js b/references/validationFunctions/chemotherapy/drugDose.js
new file mode 100644
index 00000000..28ab2344
--- /dev/null
+++ b/references/validationFunctions/chemotherapy/drugDose.js
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved
+ *
+ * This program and the accompanying materials are made available under the terms of the GNU Affero General Public License v3.0.
+ * You should have received a copy of the GNU Affero General Public License along with
+ * this program. If not, see .
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ */
+
+/**
+ * Requirement to submit either prescribed or actual drug dose.
+ */
+
+const validation = () =>
+ (function validate(inputs) {
+ const {$row, $name, $field} = inputs;
+ let result = {valid: true, message: "Ok"};
+ let checkField = "";
+
+ if ($name === 'actual_cumulative_drug_dose') { checkField = 'prescribed_cumulative_drug_dose'; }
+ else if ($name === 'prescribed_cumulative_drug_dose') { checkField = 'actual_cumulative_drug_dose'; }
+
+ // checks for a string just consisting of whitespace
+ const checkforEmpty = (entry) => {return /^\s+$/g.test(decodeURI(entry).replace(/^"(.*)"$/, '$1'))};
+
+ if ( (!$field || $field === null || checkforEmpty($field)) && (!($row[checkField]) || $row[checkField] === null || checkforEmpty(!($row[checkField])))) {
+ result = {
+ valid: false,
+ message: `Either the 'actual_cumulative_drug_dose' or the 'prescribed_cumulative_drug_dose' fields must be submitted.`
+ };
+ }
+ return result;
+ });
+
+module.exports = validation;
diff --git a/references/validationFunctions/common/mxCategoryValidation.js b/references/validationFunctions/common/mxCategoryValidation.js
index 5b87f87c..d86d3515 100644
--- a/references/validationFunctions/common/mxCategoryValidation.js
+++ b/references/validationFunctions/common/mxCategoryValidation.js
@@ -49,6 +49,16 @@ const validation = () =>
}
}
}
+ if ($row[tumourStagingSystem] && $row[tumourStagingSystem] != null && !(checkforEmpty($row[tumourStagingSystem]))) {
+ if ($row[tumourStagingSystem].trim().toLowerCase() == "ajcc 6th edition") {
+ if ($field && $field != null && !(checkforEmpty($field)) && $field.trim().toLowerCase() === 'not applicable') {
+ result = {
+ valid: false,
+ message: `The designation of '${$field}' in the '${$name}' field is not a valid M category in the ${tumourStagingSystem} '${$row[tumourStagingSystem]}'.`
+ };
+ }
+ }
+ }
return result;
});
module.exports = validation;
diff --git a/references/validationFunctions/follow_up/baseScripts/requiredWhenProgressOrRelapseRecur.js b/references/validationFunctions/follow_up/baseScripts/requiredWhenProgressOrRelapseRecur.js
index 2ed209db..ec34452e 100644
--- a/references/validationFunctions/follow_up/baseScripts/requiredWhenProgressOrRelapseRecur.js
+++ b/references/validationFunctions/follow_up/baseScripts/requiredWhenProgressOrRelapseRecur.js
@@ -38,12 +38,19 @@ const validation = () =>
/* checks for a string just consisting of whitespace */
const checkforEmpty = (entry) => {return /^\s+$/g.test(decodeURI(entry).replace(/^"(.*)"$/, '$1'))};
-
- if ((!$field || checkforEmpty($field)) && (stateOfProgression(diseaseStatus) || relapseOrRecurrence)) {
- result = {valid: false, message: `'${$name}' is a required field if 'disease_status_at_followup' is set a state of progression, relapse, or recurrence.` }
+
+ if ($name === 'recurrence_tumour_staging_system') {
+ if (!(!$field || checkforEmpty($field)) && !stateOfProgression(diseaseStatus) && !relapseOrRecurrence) {
+ result = {valid: false, message: `'${$name}' should not be submitted if 'disease_status_at_followup' is not a state of progression, relapse, or recurrence.` }
+ }
}
- else if (!(!$field || checkforEmpty($field)) && !stateOfProgression(diseaseStatus) && !relapseOrRecurrence) {
- result = {valid: false, message: `'${$name}' cannot be provided if 'disease_status_at_followup' is not a state of progression, relapse, or recurrence.` }
+ else {
+ if ((!$field || checkforEmpty($field)) && (stateOfProgression(diseaseStatus) || relapseOrRecurrence)) {
+ result = {valid: false, message: `'${$name}' is a required field if 'disease_status_at_followup' is set a state of progression, relapse, or recurrence.` }
+ }
+ else if (!(!$field || checkforEmpty($field)) && !stateOfProgression(diseaseStatus) && !relapseOrRecurrence) {
+ result = {valid: false, message: `'${$name}' should not be submitted if 'disease_status_at_followup' is not a state of progression, relapse, or recurrence.` }
+ }
}
}
return result;
diff --git a/references/validationFunctions/hormone_therapy/drugDose.js b/references/validationFunctions/hormone_therapy/drugDose.js
new file mode 100644
index 00000000..28ab2344
--- /dev/null
+++ b/references/validationFunctions/hormone_therapy/drugDose.js
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved
+ *
+ * This program and the accompanying materials are made available under the terms of the GNU Affero General Public License v3.0.
+ * You should have received a copy of the GNU Affero General Public License along with
+ * this program. If not, see .
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ */
+
+/**
+ * Requirement to submit either prescribed or actual drug dose.
+ */
+
+const validation = () =>
+ (function validate(inputs) {
+ const {$row, $name, $field} = inputs;
+ let result = {valid: true, message: "Ok"};
+ let checkField = "";
+
+ if ($name === 'actual_cumulative_drug_dose') { checkField = 'prescribed_cumulative_drug_dose'; }
+ else if ($name === 'prescribed_cumulative_drug_dose') { checkField = 'actual_cumulative_drug_dose'; }
+
+ // checks for a string just consisting of whitespace
+ const checkforEmpty = (entry) => {return /^\s+$/g.test(decodeURI(entry).replace(/^"(.*)"$/, '$1'))};
+
+ if ( (!$field || $field === null || checkforEmpty($field)) && (!($row[checkField]) || $row[checkField] === null || checkforEmpty(!($row[checkField])))) {
+ result = {
+ valid: false,
+ message: `Either the 'actual_cumulative_drug_dose' or the 'prescribed_cumulative_drug_dose' fields must be submitted.`
+ };
+ }
+ return result;
+ });
+
+module.exports = validation;
diff --git a/references/validationFunctions/immunotherapy/drugDose.js b/references/validationFunctions/immunotherapy/drugDose.js
new file mode 100644
index 00000000..28ab2344
--- /dev/null
+++ b/references/validationFunctions/immunotherapy/drugDose.js
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved
+ *
+ * This program and the accompanying materials are made available under the terms of the GNU Affero General Public License v3.0.
+ * You should have received a copy of the GNU Affero General Public License along with
+ * this program. If not, see .
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ */
+
+/**
+ * Requirement to submit either prescribed or actual drug dose.
+ */
+
+const validation = () =>
+ (function validate(inputs) {
+ const {$row, $name, $field} = inputs;
+ let result = {valid: true, message: "Ok"};
+ let checkField = "";
+
+ if ($name === 'actual_cumulative_drug_dose') { checkField = 'prescribed_cumulative_drug_dose'; }
+ else if ($name === 'prescribed_cumulative_drug_dose') { checkField = 'actual_cumulative_drug_dose'; }
+
+ // checks for a string just consisting of whitespace
+ const checkforEmpty = (entry) => {return /^\s+$/g.test(decodeURI(entry).replace(/^"(.*)"$/, '$1'))};
+
+ if ( (!$field || $field === null || checkforEmpty($field)) && (!($row[checkField]) || $row[checkField] === null || checkforEmpty(!($row[checkField])))) {
+ result = {
+ valid: false,
+ message: `Either the 'actual_cumulative_drug_dose' or the 'prescribed_cumulative_drug_dose' fields must be submitted.`
+ };
+ }
+ return result;
+ });
+
+module.exports = validation;
diff --git a/references/validationFunctions/primary_diagnosis/lymphNodesExaminedMethod.js b/references/validationFunctions/primary_diagnosis/lymphNodesExaminedMethod.js
new file mode 100644
index 00000000..986defc6
--- /dev/null
+++ b/references/validationFunctions/primary_diagnosis/lymphNodesExaminedMethod.js
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved
+ *
+ * This program and the accompanying materials are made available under the terms of the GNU Affero General Public License v3.0.
+ * You should have received a copy of the GNU Affero General Public License along with
+ * this program. If not, see .
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ */
+
+/**
+ * Enforces requirement on lymph_nodes_examined_method if lymph_nodes_examined_status is 'Yes'. If 'lymph_nodes_examined_status' is any other value, then 'lymph_nodes_examined_method' should not be submitted.
+ * @param {object} $row
+ * @param {string} $field
+ * @param {string} $name
+ */
+const validation = () =>
+ (function validate(inputs) {
+ const {$row, $name, $field} = inputs;
+ let result = {valid: true, message: "Ok"};
+
+ const notExamined = ['cannot be determined', 'no', 'no lymph nodes found in resected specimen', 'not applicable'];
+ const lymphNodesExaminedStatus = $row.lymph_nodes_examined_status.trim().toLowerCase();
+
+ /* checks for a string just consisting of whitespace */
+ const checkforEmpty = (entry) => {return /^\s+$/g.test(decodeURI(entry).replace(/^"(.*)"$/, '$1'))};
+
+
+ if (!$field || $field === null || checkforEmpty($field)) {
+ if (lymphNodesExaminedStatus === 'yes') {
+ result = { valid: false, message: `The '${$name}' field must be submitted if the 'lymph_nodes_examined_status' field is 'Yes'`};
+ }
+ }
+ else {
+ if (notExamined.includes(lymphNodesExaminedStatus)) {
+ result = { valid: false, message: `The '${$name}' field should not be submitted if the 'lymph_nodes_examined_status' field is '${lymphNodesExaminedStatus}'`};
+ }
+ }
+ return result;
+});
+
+module.exports = validation;
diff --git a/references/validationFunctions/treatment/checkWhenNoTreatment.js b/references/validationFunctions/treatment/checkWhenNoTreatment.js
index 02e9e837..249d4689 100644
--- a/references/validationFunctions/treatment/checkWhenNoTreatment.js
+++ b/references/validationFunctions/treatment/checkWhenNoTreatment.js
@@ -19,37 +19,26 @@
*/
/**
- * If treatment_type is 'No treatment', the other core treatment fields should not be submitted.
- * Ensure interval/duration fields are greater than 0 days
+ * If treatment_type is 'No treatment', core treatment fields should not be submitted.
*/
const validation = () =>
(function validate(inputs) {
const {$row, $name, $field} = inputs;
let result = {valid: true, message: "Ok"};
- const coreFields = ['is_primary_treatment', 'treatment_start_interval', 'treatment_duration', 'treatment_intent', 'treatment_setting', 'response_to_treatment'];
+ const coreFields = ['treatment_start_interval', 'treatment_duration', 'is_primary_treatment', 'treatment_intent', 'treatment_setting', 'response_to_treatment_criteria_method', 'response_to_treatment'];
// checks for a string just consisting of whitespace
const checkforEmpty = (entry) => {return /^\s+$/g.test(decodeURI(entry).replace(/^"(.*)"$/, '$1'))};
-
- if ($row.treatment_type != null) {
- const treatmentType = $row.treatment_type;
- if (!(treatmentType.includes("No treatment"))) {
- if (coreFields.includes($name)) {
- if (!$field || checkforEmpty($field)) {
- result = {
- valid: false,
- message: `The '${$name}' field must be submitted when 'treatment_type' is '${treatmentType}'`,
- };
- }
- }
- }
- else if (treatmentType.includes("No treatment") && ($field)) {
- result = {
- valid: false,
- message: `The '${$name}' field should not be submitted if 'treatment_type' is set to '${treatmentType}'`,
- };
- }
+ const treatmentType = ($row.treatment_type).map(value => value.toLowerCase());
+
+ if (!treatmentType.includes("no treatment") && coreFields.includes($name) && (!$field || $field === null || checkforEmpty($field))) {
+ result = { valid: false, message: `The '${$name}' field must be submitted when the 'treatment_type' field is '${treatmentType}'`};
+ }
+ else if (treatmentType.includes("no treatment") && ($field && $field != null && !(checkforEmpty($field)))) {
+ if (coreFields.includes($name) || (typeof($field) === 'string' && $field.trim().toLowerCase() != 'not applicable') || typeof($field) === 'number') {
+ result = { valid: false, message: `The '${$name}' field cannot be submitted if the 'treatment_type' field is '${treatmentType}'`};
+ }
}
return result;
});
diff --git a/references/validationFunctions/treatment/lineOfTreatment.js b/references/validationFunctions/treatment/lineOfTreatment.js
index c0548ede..cae23cd6 100644
--- a/references/validationFunctions/treatment/lineOfTreatment.js
+++ b/references/validationFunctions/treatment/lineOfTreatment.js
@@ -43,8 +43,8 @@ const validation = () =>
result = { valid: false, message: `The '${$name}' field must be a value greater than 1`};
}
/* if it is unknown whether treatment was primary treatment, then line_of_treatment should not be submitted. If it is, then primary_treatment should be 'no' */
- else if (isPrimaryTreatment === 'unknown') {
- result = { valid: false, message: `The '${$name}' field should not be submitted if 'is_primary_treatment' is 'unknown'.`};
+ else if (isPrimaryTreatment === 'not applicable') {
+ result = { valid: false, message: `The '${$name}' field should not be submitted if 'is_primary_treatment' is 'Not applicable'.`};
}
}
return result;
diff --git a/references/validationFunctions/treatment/responseToTreatment.js b/references/validationFunctions/treatment/responseToTreatment.js
new file mode 100644
index 00000000..9abc07d0
--- /dev/null
+++ b/references/validationFunctions/treatment/responseToTreatment.js
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved
+ *
+ * This program and the accompanying materials are made available under the terms of the GNU Affero General Public License v3.0.
+ * You should have received a copy of the GNU Affero General Public License along with
+ * this program. If not, see .
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ */
+
+/**
+ * Validates to ensure that response_to_treatment is a permissable value based on response_to_treatment_criteria_method
+ *
+ * @param {Object} $row The object representing the row for a donor. Object keys represent the fields.
+ * @param {String} $field The value for the field.
+ */
+const validation = () =>
+ (function validate(inputs) {
+ const {$row, $name, $field} = inputs;
+ let result = { valid: true, message: 'Ok' };
+
+ /* checks for a string just consisting of whitespace */
+ const checkforEmpty = (entry) => {return /^\s+$/g.test(decodeURI(entry).replace(/^"(.*)"$/, '$1'))};
+ let codeList = [];
+
+ switch ($row.response_to_treatment_criteria_method && $row.response_to_treatment_criteria_method.trim().toLowerCase()) {
+ case 'eln dohner aml 2017 oncology response criteria':
+ codeList = [
+ 'complete remission',
+ 'complete remission with incomplete hematologic recovery (cri)',
+ 'complete remission without minimal residual disease (crmrd-)',
+ 'hematologic relapse (after crmrd-, cr, cri)',
+ 'molecular relapse (after crmrd-)',
+ 'partial remission',
+ 'progressive disease',
+ 'stable disease'
+ ];
+ break;
+ case 'iwg cheson aml 2003 oncology response criteria':
+ codeList = [
+ 'cytogenetic complete remission (crc)',
+ 'molecular complete remission (crm)',
+ 'morphologic complete remission',
+ 'morphologic complete remission with incomplete blood count recovery (cri)',
+ 'morphologic leukemia-free state',
+ 'partial remission'
+ ];
+ break;
+ case 'irecist':
+ codeList = [
+ 'immune complete response (icr)',
+ 'immune confirmed progressive disease (icpd)',
+ 'immune partial response (ipr)',
+ 'immune stable disease (isd)',
+ 'immune unconfirmed progressive disease (iupd)'
+ ];
+ break;
+ case 'recist':
+ codeList = [
+ 'complete response',
+ 'no evidence of disease (ned)',
+ 'partial response',
+ 'progressive disease',
+ 'stable disease'
+ ];
+ break;
+ case 'response assessment in neuro-oncology (rano)':
+ codeList = [
+ 'complete response',
+ 'minor response',
+ 'partial response',
+ 'progressive disease',
+ 'stable disease'
+ ];
+ break;
+ case 'physician assessed response criteria':
+ codeList = [
+ 'physician assessed complete response',
+ 'physician assessed partial response',
+ 'physician assessed stable disease'
+ ];
+ break;
+ default:
+ codelist = [];
+ }
+
+ if ($field && $field != null && !(checkforEmpty($field))) {
+ if (!codeList.includes($field.trim().toLowerCase()) && codeList.length) {
+ const msg = `'${$field}' is not a permissible value. When 'response_to_treatment_criteria_method' is set to '${
+ $row.response_to_treatment_criteria_method}', the '${$name}' field must be one of the following: \n${codeList
+ .map(code => `- "${code}"`)
+ .join('\n')}`;
+
+ result.valid = false;
+ result.message = msg;
+ }
+ }
+ else {
+ if ($row.response_to_treatment_criteria_method && $row.response_to_treatment_criteria_method != null && !(checkforEmpty($row.response_to_treatment_criteria_method))) {
+ result = { valid: false, message: `The '${$name}' field must be submitted when 'response_to_treatment_criteria_method' is set to '${$row.response_to_treatment_criteria_method}'. The '${$name}' field must be one of the following: \n${codeList
+ .map(code => `- "${code}"`)
+ .join('\n')}`};
+ }
+ }
+ return result;
+ });
+
+module.exports = validation;
diff --git a/references/validationFunctions/treatment/responseToTreatmentCheck.js b/references/validationFunctions/treatment/responseToTreatmentCheck.js
new file mode 100644
index 00000000..8d0595f0
--- /dev/null
+++ b/references/validationFunctions/treatment/responseToTreatmentCheck.js
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2020 The Ontario Institute for Cancer Research. All rights reserved
+ *
+ * This program and the accompanying materials are made available under the terms of the GNU Affero General Public License v3.0.
+ * You should have received a copy of the GNU Affero General Public License along with
+ * this program. If not, see .
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ */
+
+const checkWhenNoTreatment = require('./checkWhenNoTreatment');
+const responseToTreatment = require('./responseToTreatment');
+
+
+module.exports = [
+ checkWhenNoTreatment,
+ responseToTreatment
+];
diff --git a/schemas/biomarker.json b/schemas/biomarker.json
index eb8b50dc..2cd0cc0c 100644
--- a/schemas/biomarker.json
+++ b/schemas/biomarker.json
@@ -55,7 +55,9 @@
"valueType": "string",
"description": "If the biomarker test was done at the time of primary diagnosis, then indicate the associated submitter_primary_diagnosis_id here.",
"meta": {
+ "validationDependency": true,
"displayName": "Submitter Primary Diagnosis ID",
+ "foreignKey": "primary_diagnosis.submitter_primary_diagnosis_id",
"primaryId": true,
"notes": "Only one of ['submitter_specimen_id', 'submitter_primary_diagnosis_id', 'submitter_treatment_id', 'submitter_follow_up_id'] is required. If the biomarker test is not associated with a specimen or primary diagnosis, treatment or follow up event, then the 'test_interval' field will be required."
},
@@ -69,7 +71,9 @@
"valueType": "string",
"description": "If the biomarker test was done at the initiation of a specific treatment regimen, indicate the associated submitter_treatment_id here.",
"meta": {
+ "validationDependency": true,
"primaryId": true,
+ "foreignKey": "treatment.submitter_treatment_id",
"displayName": "Submitter Treatment ID",
"notes": "Only one of ['submitter_specimen_id', 'submitter_primary_diagnosis_id', 'submitter_treatment_id', 'submitter_follow_up_id'] is required. If the biomarker test is not associated with a specimen or primary diagnosis, treatment or follow up event, then the 'test_interval' field will be required."
},
@@ -85,6 +89,7 @@
"meta": {
"validationDependency": true,
"primaryId": true,
+ "foreignKey": "follow_up.submitter_follow_up_id",
"displayName": "Submitter Follow-Up ID",
"notes": "Only one of ['submitter_specimen_id', 'submitter_primary_diagnosis_id', 'submitter_treatment_id', 'submitter_follow_up_id'] is required. If the biomarker test is not associated with a specimen or primary diagnosis, treatment or follow up event, then the 'test_interval' field will be required."
},
diff --git a/schemas/chemotherapy.json b/schemas/chemotherapy.json
index 84012900..8325865d 100644
--- a/schemas/chemotherapy.json
+++ b/schemas/chemotherapy.json
@@ -78,31 +78,50 @@
}
},
{
- "name": "chemotherapy_dosage_units",
- "description": "Indicate units used to record chemotherapy drug dosage.",
+ "name": "chemotherapy_drug_dose_units",
+ "description": "Indicate units used to record chemotherapy drug dose.",
"valueType": "string",
"restrictions": {
"required": true,
- "codeList": "#/list/drug_dosage_units"
+ "codeList": "#/list/drug_dose_units"
},
"meta": {
"core": true,
- "displayName": "Chemotherapy Dosage Units"
+ "displayName": "Chemotherapy Drug Dose Units"
}
},
{
- "name": "cumulative_drug_dosage",
- "description": "Indicate the total actual drug dose in the same units specified in chemotherapy_dosage_units.",
+ "name": "prescribed_cumulative_drug_dose",
+ "description": "Indicate the total prescribed cumulative drug dose in the same units specified in chemotherapy_drug_dose_units.",
"valueType": "number",
"restrictions": {
- "required": true,
+ "script": "#/script/chemotherapy/drugDose",
+ "range": {
+ "exclusiveMin": 0
+ }
+ },
+ "meta": {
+ "core": true,
+ "displayName": "Prescribed Cumulative Drug Dose",
+ "dependsOn": "chemotherapy.actual_cumulative_drug_dose",
+ "notes": "Either the 'actual_cumulative_drug_dose' or the 'prescribed_cumulative_drug_dose' field must be submitted."
+ }
+ },
+ {
+ "name": "actual_cumulative_drug_dose",
+ "description": "Indicate the total actual cumulative drug dose in the same units specified in chemotherapy_drug_dose_units.",
+ "valueType": "number",
+ "restrictions": {
+ "script": "#/script/chemotherapy/drugDose",
"range": {
"exclusiveMin": 0
}
},
"meta": {
"core": true,
- "displayName": "Cumulative Drug Dosage"
+ "displayName": "Actual Cumulative Drug Dose",
+ "dependsOn": "chemotherapy.prescribed_cumulative_drug_dose",
+ "notes": "Either the 'actual_cumulative_drug_dose' or the 'prescribed_cumulative_drug_dose' field must be submitted."
}
},
{
@@ -110,7 +129,7 @@
"description": "Indicate if there was a significant reduction in dose intensity.",
"valueType": "string",
"restrictions": {
- "codeList": "#/list/yes_no"
+ "codeList": "#/list/yes_no_unk"
},
"meta": {
"displayName": "Dose Intensity Reduction"
diff --git a/schemas/comorbidity.json b/schemas/comorbidity.json
index 4e2f75d2..b04d6035 100644
--- a/schemas/comorbidity.json
+++ b/schemas/comorbidity.json
@@ -38,7 +38,7 @@
"name": "prior_malignancy",
"description": "Prior malignancy affecting donor.",
"restrictions": {
- "codeList": "#/list/yes_no"
+ "codeList": "#/list/yes_no_unk"
},
"valueType": "string",
"meta": {
@@ -96,7 +96,7 @@
"valueType": "string",
"description": "Indicate if the patient is being treated for the comorbidity (this includes prior malignancies).",
"restrictions": {
- "codeList": "#/list/yes_no",
+ "codeList": "#/list/yes_no_unk",
"script": "#/script/comorbidity/comorbidityOptionalFieldsCheck"
},
"meta": {
diff --git a/schemas/donor.json b/schemas/donor.json
index 566a5845..0c10c288 100644
--- a/schemas/donor.json
+++ b/schemas/donor.json
@@ -95,77 +95,7 @@
},
"restrictions": {
"required": true,
- "codeList": [
- "Accessory sinuses",
- "Adrenal gland",
- "Anus and anal canal",
- "Base of tongue",
- "Bladder",
- "Bones, joints and articular cartilage of limbs",
- "Bones, joints and articular cartilage of other and unspecified sites",
- "Brain",
- "Breast",
- "Bronchus and lung",
- "Cervix uteri",
- "Colon",
- "Connective, subcutaneous and other soft tissues",
- "Corpus uteri",
- "Esophagus",
- "Eye and adnexa",
- "Floor of mouth",
- "Gallbladder",
- "Gum",
- "Heart, mediastinum, and pleura",
- "Hematopoietic and reticuloendothelial systems",
- "Hypopharynx",
- "Kidney",
- "Larynx",
- "Lip",
- "Liver and intrahepatic bile ducts",
- "Lymph nodes",
- "Meninges",
- "Nasal cavity and middle ear",
- "Nasopharynx",
- "Oropharynx",
- "Other and ill-defined digestive organs",
- "Other and ill-defined sites",
- "Other and ill-defined sites in lip, oral cavity and pharynx",
- "Other and ill-defined sites within respiratory system and intrathoracic organs",
- "Other and unspecified female genital organs",
- "Other and unspecified major salivary glands",
- "Other and unspecified male genital organs",
- "Other and unspecified parts of biliary tract",
- "Other and unspecified parts of mouth",
- "Other and unspecified parts of tongue",
- "Other and unspecified urinary organs",
- "Other endocrine glands and related structures",
- "Ovary",
- "Palate",
- "Pancreas",
- "Parotid gland",
- "Penis",
- "Peripheral nerves and autonomic nervous system",
- "Placenta",
- "Prostate gland",
- "Pyriform sinus",
- "Rectosigmoid junction",
- "Rectum",
- "Renal pelvis",
- "Retroperitoneum and peritoneum",
- "Skin",
- "Small intestine",
- "Spinal cord, cranial nerves, and other parts of central nervous system",
- "Stomach",
- "Testis",
- "Thymus",
- "Thyroid gland",
- "Tonsil",
- "Trachea",
- "Ureter",
- "Uterus, NOS",
- "Vagina",
- "Vulva"
- ]
+ "codeList": "#/list/primary_site"
}
},
{
diff --git a/schemas/exposure.json b/schemas/exposure.json
index 367dc120..0c67d121 100644
--- a/schemas/exposure.json
+++ b/schemas/exposure.json
@@ -103,7 +103,7 @@
"displayName": "Alcohol History"
},
"restrictions": {
- "codeList": "#/list/yes_no_na",
+ "codeList": "#/list/yes_no_na_unk",
"script": "#/script/exposure/checkAlcoholHistory"
}
},
diff --git a/schemas/family_history.json b/schemas/family_history.json
index acaad954..2fe485d3 100644
--- a/schemas/family_history.json
+++ b/schemas/family_history.json
@@ -52,7 +52,7 @@
"description": "Indicate if donor has any genetic relatives with a history of cancer. (Reference: NCIt C159104, caDSR CDE ID 6161023)",
"name": "relative_with_cancer_history",
"restrictions": {
- "codeList": "#/list/yes_no"
+ "codeList": "#/list/yes_no_unk"
},
"valueType": "string",
"meta": {
diff --git a/schemas/follow_up.json b/schemas/follow_up.json
index 8219c350..8bc89caa 100644
--- a/schemas/follow_up.json
+++ b/schemas/follow_up.json
@@ -92,6 +92,8 @@
"valueType": "string",
"description": "Indicate if the follow-up is related to a specific primary diagnosis event in the clinical timeline.",
"meta": {
+ "validationDependency": true,
+ "foreignKey": "primary_diagnosis.submitter_primary_diagnosis_id",
"displayName": "Submitter Primary Diagnosis ID",
"primaryId": true
},
@@ -104,7 +106,9 @@
"valueType": "string",
"description": "Indicate if the follow-up is related to a specific treatment event in the clinical timeline.",
"meta": {
+ "validationDependency": true,
"primaryId": true,
+ "foreignKey": "treatment.submitter_treatment_id",
"displayName": "Submitter Treatment ID"
},
"restrictions": {
@@ -228,7 +232,6 @@
"script": "#/script/follow_up/recurrence_tumour_staging_system"
},
"meta": {
- "core": true,
"dependsOn": "follow_up.disease_status_at_followup",
"notes": "#/notes/disease_status_requirement",
"displayName": "Recurrance Tumour Staging System"
@@ -239,7 +242,6 @@
"description": "The code to represent the extent of the primary tumour (T) based on evidence obtained from clinical assessment parameters determined at the time of retreatment for a recurrence or disease progression, according to criteria based on multiple editions of the AJCC's Cancer Staging Manual.",
"valueType": "string",
"meta": {
- "core": true,
"dependsOn": "follow_up.recurrence_tumour_staging_system",
"notes": "This field is required only if the selected recurrence_tumour_staging_system is any edition of the AJCC cancer staging system.",
"displayName": "Recurrence T Category"
@@ -253,7 +255,6 @@
"description": "The code to represent the stage of cancer defined by the extent of the regional lymph node (N) involvement for the cancer based on evidence obtained from clinical assessment parameters determined at the time of retreatment for a recurrence or disease progression, according to criteria based on multiple editions of the AJCC's Cancer Staging Manual.",
"valueType": "string",
"meta": {
- "core": true,
"dependsOn": "follow_up.recurrence_tumour_staging_system",
"notes": "This field is required only if the selected recurrence_tumour_staging_system is any edition of the AJCC cancer staging system.",
"displayName": "Recurrence N Category"
@@ -267,7 +268,6 @@
"description": "The code to represent the stage of cancer defined by the extent of the distant metastasis (M) for the cancer based on evidence obtained from clinical assessment parameters determined at the time of retreatment for a recurrence or disease progression, according to criteria based on multiple editions of the AJCC's Cancer Staging Manual.",
"valueType": "string",
"meta": {
- "core": true,
"dependsOn": "follow_up.recurrence_tumour_staging_system",
"notes": "This field is required only if the selected recurrence_tumour_staging_system is any edition of the AJCC cancer staging system.",
"displayName": "Recurrence M Category"
@@ -282,7 +282,6 @@
"description": "The code to represent the stage group of the tumour, as assigned by the reporting recurrence_tumour_staging_system, that indicates the overall prognostic tumour stage (ie. Stage I, Stage II, Stage III etc.) at the time of retreatment for a recurrence or disease progression.",
"valueType": "string",
"meta": {
- "core": true,
"dependsOn": "follow_up.recurrence_tumour_staging_system",
"notes": "This field is dependent on the selected recurrence_tumour_staging_system.\nPlease refer to the documentation for Tumour Staging Classifications: http://docs.icgc-argo.org/docs/submission/dictionary-overview#tumour-staging-classifications",
"displayName": "Recurrence Stage Group"
diff --git a/schemas/hormone_therapy.json b/schemas/hormone_therapy.json
index 8015b1a4..948529de 100644
--- a/schemas/hormone_therapy.json
+++ b/schemas/hormone_therapy.json
@@ -76,31 +76,50 @@
}
},
{
- "name": "hormone_drug_dosage_units",
- "description": "Indicate the units used to record hormone drug dosage.",
+ "name": "hormone_drug_dose_units",
+ "description": "Indicate the units used to record hormone drug dose.",
"valueType": "string",
"restrictions": {
"required": true,
- "codeList": "#/list/drug_dosage_units"
+ "codeList": "#/list/drug_dose_units"
},
"meta": {
"core": true,
- "displayName": "Hormone Therapy Dosage Units"
+ "displayName": "Hormone Drug Dose Units"
}
},
{
- "name": "cumulative_drug_dosage",
- "description": "Indicate total drug dose in units specified in hormone_drug_dosage_units.",
+ "name": "prescribed_cumulative_drug_dose",
+ "description": "Indicate the total prescribed cumulative drug dose in the same units specified in hormone_drug_dose_units.",
"valueType": "number",
"restrictions": {
- "required": true,
+ "script": "#/script/hormone_therapy/drugDose",
+ "range": {
+ "exclusiveMin": 0
+ }
+ },
+ "meta": {
+ "core": true,
+ "displayName": "Prescribed Cumulative Drug Dose",
+ "dependsOn": "hormone_therapy.actual_cumulative_drug_dose",
+ "notes": "Either the 'actual_cumulative_drug_dose' or the 'prescribed_cumulative_drug_dose' field must be submitted."
+ }
+ },
+ {
+ "name": "actual_cumulative_drug_dose",
+ "description": "Indicate the total actual cumulative drug dose in the same units specified in hormone_drug_dose_units.",
+ "valueType": "number",
+ "restrictions": {
+ "script": "#/script/hormone_therapy/drugDose",
"range": {
"exclusiveMin": 0
}
},
"meta": {
"core": true,
- "displayName": "Cumulative Drug Dosage"
+ "displayName": "Actual Cumulative Drug Dose",
+ "dependsOn": "hormone_therapy.prescribed_cumulative_drug_dose",
+ "notes": "Either the 'actual_cumulative_drug_dose' or the 'prescribed_cumulative_drug_dose' field must be submitted."
}
}
]
diff --git a/schemas/immunotherapy.json b/schemas/immunotherapy.json
index 6fcf5352..9fe1b3a4 100644
--- a/schemas/immunotherapy.json
+++ b/schemas/immunotherapy.json
@@ -94,6 +94,53 @@
"restrictions": {
"required": true
}
+ },
+ {
+ "name": "immunotherapy_drug_dose_units",
+ "description": "Indicate units used to record immunotherapy drug dose.",
+ "valueType": "string",
+ "restrictions": {
+ "required": true,
+ "codeList": "#/list/drug_dose_units"
+ },
+ "meta": {
+ "core": true,
+ "displayName": "Immunotherapy Drug Dose Units"
+ }
+ },
+ {
+ "name": "prescribed_cumulative_drug_dose",
+ "description": "Indicate the total prescribed cumulative drug dose in the same units specified in immunotherapy_drug_dose_units.",
+ "valueType": "number",
+ "restrictions": {
+ "script": "#/script/immunotherapy/drugDose",
+ "range": {
+ "exclusiveMin": 0
+ }
+ },
+ "meta": {
+ "core": true,
+ "displayName": "Prescribed Cumulative Drug Dose",
+ "dependsOn": "immunotherapy.actual_cumulative_drug_dose",
+ "notes": "Either the 'actual_cumulative_drug_dose' or the 'prescribed_cumulative_drug_dose' field must be submitted."
+ }
+ },
+ {
+ "name": "actual_cumulative_drug_dose",
+ "description": "Indicate the total actual cumulative drug dose in the same units specified in immunotherapy_drug_dose_units.",
+ "valueType": "number",
+ "restrictions": {
+ "script": "#/script/immunotherapy/drugDose",
+ "range": {
+ "exclusiveMin": 0
+ }
+ },
+ "meta": {
+ "core": true,
+ "displayName": "Actual Cumulative Drug Dose",
+ "dependsOn": "immunotherapy.prescribed_cumulative_drug_dose",
+ "notes": "Either the 'actual_cumulative_drug_dose' or the 'prescribed_cumulative_drug_dose' field must be submitted."
+ }
}
]
}
diff --git a/schemas/primary_diagnosis.json b/schemas/primary_diagnosis.json
index 04c6706d..1b99aa6e 100644
--- a/schemas/primary_diagnosis.json
+++ b/schemas/primary_diagnosis.json
@@ -145,6 +145,24 @@
"displayName": "Lymph Nodes Examined Status"
}
},
+ {
+ "name": "lymph_nodes_examined_method",
+ "description": "Indicate the method used to examine lymph nodes.",
+ "valueType": "string",
+ "restrictions": {
+ "script": "#/script/primary_diagnosis/lymphNodesExaminedMethod",
+ "codeList": [
+ "Imaging",
+ "Lymph node dissection/pathological exam",
+ "Physical palpation of patient"
+ ]
+ },
+ "meta": {
+ "core": true,
+ "dependsOn": "primary_diagnosis.lymph_nodes_examined_status",
+ "displayName": "Method Used to Examine Lymph Nodes"
+ }
+ },
{
"name": "number_lymph_nodes_examined",
"description": "The total number of lymph nodes tested for the presence of cancer. (Reference: caDSR CDE ID 3)",
diff --git a/schemas/sample_registration.json b/schemas/sample_registration.json
index 292f9cba..cc9b498c 100644
--- a/schemas/sample_registration.json
+++ b/schemas/sample_registration.json
@@ -136,7 +136,6 @@
"Primary tumour - adjacent to normal",
"Primary tumour",
"Recurrent tumour",
- "Tumour - unknown if derived from primary or metastatic",
"Xenograft - derived from primary tumour",
"Xenograft - derived from tumour cell line"
],
diff --git a/schemas/specimen.json b/schemas/specimen.json
index 25524ad3..1b11d985 100644
--- a/schemas/specimen.json
+++ b/schemas/specimen.json
@@ -54,7 +54,9 @@
"valueType": "string",
"description": "Indicate the primary diagnosis event in the clinical timeline that this specimen acquisition was related to.",
"meta": {
+ "validationDependency": true,
"primaryId": true,
+ "foreignKey": "primary_diagnosis.submitter_primary_diagnosis_id",
"displayName": "Submitter Primary Diagnosis ID"
},
"restrictions": {
@@ -254,7 +256,7 @@
"displayName": "Reference Pathology Confirmed"
},
"restrictions": {
- "codeList": "#/list/yes_no"
+ "codeList": "#/list/yes_no_unk"
}
},
{
diff --git a/schemas/treatment.json b/schemas/treatment.json
index f62919fe..820d95b6 100644
--- a/schemas/treatment.json
+++ b/schemas/treatment.json
@@ -53,7 +53,9 @@
"valueType": "string",
"description": "Indicate the primary diagnosis event in the clinical timeline that this treatment was related to.",
"meta": {
+ "validationDependency": true,
"primaryId": true,
+ "foreignKey": "primary_diagnosis.submitter_primary_diagnosis_id",
"displayName": "Submitter Primary Diagnosis ID"
},
"restrictions": {
@@ -125,7 +127,7 @@
"restrictions": {
"script": "#/script/treatment/checkWhenNoTreatment",
"range": {
- "exclusiveMin": 0
+ "exclusiveMin": 0
}
},
"meta": {
@@ -143,7 +145,7 @@
"restrictions": {
"script": "#/script/treatment/checkWhenNoTreatment",
"range": {
- "exclusiveMin": 0
+ "exclusiveMin": 0
}
},
"meta": {
@@ -160,10 +162,10 @@
"restrictions": {
"script": "#/script/treatment/checkWhenNoTreatment",
"range": {
- "exclusiveMin": 0
+ "exclusiveMin": 0
}
},
- "meta": {
+ "meta": {
"displayName": "Days Per Cycle",
"dependsOn": "treatment.treatment_type"
}
@@ -175,24 +177,29 @@
"restrictions": {
"script": "#/script/treatment/checkWhenNoTreatment",
"range": {
- "exclusiveMin": 0
+ "exclusiveMin": 0
}
},
- "meta": {
+ "meta": {
"displayName": "Number Of Cycles",
"dependsOn": "treatment.treatment_type"
}
},
{
"name": "treatment_intent",
- "description": "Indicate the intended disease outcome for which the treatment is given. (Reference: NCIt C124307)",
+ "description": "Indicate the purpose of the treatment, or the desired effect or outcome resulting from the treatment. (Reference: mCODE/FHIR)",
"valueType": "string",
"restrictions": {
"script": "#/script/treatment/checkWhenNoTreatment",
"codeList": [
"Curative",
+ "Diagnostic",
+ "Forensic",
+ "Guidance",
"Palliative",
- "Unknown"
+ "Preventative",
+ "Screening",
+ "Supportive"
]
},
"meta": {
@@ -210,8 +217,14 @@
"codeList": [
"Adjuvant",
"Advanced/Metastatic",
+ "Conditioning",
+ "Induction",
+ "Maintenance",
+ "Mobilization",
"Neoadjuvant",
- "Not applicable"
+ "Preventative",
+ "Radiosensitization",
+ "Salvage"
]
},
"meta": {
@@ -221,25 +234,68 @@
}
},
{
- "name": "response_to_treatment",
- "description": "The donor's response to the applied treatment regimen. (Source: RECIST)",
+ "name": "response_to_treatment_criteria_method",
+ "description": "Indicate the criteria used to assess the donor's response to the applied treatment regimen.",
"valueType": "string",
"restrictions": {
"script": "#/script/treatment/checkWhenNoTreatment",
"codeList": [
- "Complete response",
- "Disease progression",
- "NED",
- "Partial response",
- "Stable disease"
+ "ELN Dohner AML 2017 Oncology Response Criteria",
+ "IWG Cheson AML 2003 Oncology Response Criteria",
+ "iRECIST",
+ "RECIST",
+ "Response Assessment in Neuro-Oncology (RANO)",
+ "Physician Assessed Response Criteria"
]
},
"meta": {
"core": true,
- "displayName": "Response To Treatment",
+ "displayName": "Response To Treatment Criteria Method",
+ "validationDependency": true,
"dependsOn": "treatment.treatment_type"
}
},
+ {
+ "name": "response_to_treatment",
+ "description": "The donor's response to the applied treatment regimen.",
+ "valueType": "string",
+ "restrictions": {
+ "script": "#/script/treatment/responseToTreatmentCheck",
+ "codeList": [
+ "Complete remission",
+ "Complete remission with incomplete hematologic recovery (CRi)",
+ "Complete remission without minimal residual disease (CRMRD-)",
+ "Complete response",
+ "Cytogenetic complete remission (CRc)",
+ "Hematologic relapse (after CRMRD-, CR, CRi)",
+ "Immune complete response (iCR)",
+ "Immune confirmed progressive disease (iCPD)",
+ "Immune partial response (iPR)",
+ "Immune stable disease (iSD)",
+ "Immune unconfirmed progressive disease (iUPD)",
+ "Minor response",
+ "Molecular complete remission (CRm)",
+ "Molecular relapse (after CRMRD-)",
+ "Morphologic complete remission",
+ "Morphologic complete remission with incomplete blood count recovery (CRi)",
+ "Morphologic leukemia-free state",
+ "No evidence of disease (NED)",
+ "Partial remission",
+ "Partial response",
+ "Physician assessed complete response",
+ "Physician assessed partial response",
+ "Physician assessed stable disease",
+ "Progressive disease",
+ "Stable disease"
+ ]
+ },
+ "meta": {
+ "core": true,
+ "displayName": "Response To Treatment",
+ "dependsOn": "treatment.response_to_treatment_criteria_method",
+ "notes": "This field depends on the selected response_to_treatment_criteria_method. Please refer to the documentation for Response to Treatment Criteria: http://docs.icgc-argo.org/docs/submission/dictionary-overview#response-to-treatment-criteria"
+ }
+ },
{
"name": "outcome_of_treatment",
"description": "Indicate the donor's outcome of the prescribed treatment.",
@@ -337,12 +393,17 @@
"name": "clinical_trials_database",
"description": "If the donor is a participant in a clinical trial, indicate the clinical trial database where the clinical trial is registered.",
"valueType": "string",
- "meta": {
+ "meta": {
"display name": "Clinical Trials Database",
"notes": "If the clinical trials database you use is not included in the controlled terminology, please contact us at https://platform.icgc-argo.org/contact to request it be added."
- },
+ },
"restrictions": {
- "codeList": ["NCI Clinical Trials", "EU Clinical Trials Register", "Not applicable", "Unknown"]
+ "codeList": [
+ "NCI Clinical Trials",
+ "EU Clinical Trials Register",
+ "Not applicable",
+ "Unknown"
+ ]
}
},
{
diff --git a/tests/chemotherapy/drugDose.test.js b/tests/chemotherapy/drugDose.test.js
new file mode 100644
index 00000000..32326c3b
--- /dev/null
+++ b/tests/chemotherapy/drugDose.test.js
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2020 The Ontario Institute for Cancer Research. All rights reserved
+ *
+ * This program and the accompanying materials are made available under the terms of the GNU Affero General Public License v3.0.
+ * You should have received a copy of the GNU Affero General Public License along with
+ * this program. If not, see .
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ */
+
+const validation = require('../../references/validationFunctions/chemotherapy/drugDose.js');
+
+const universalTest = require('../universal');
+const loadObjects = require('../loadObjects');
+
+// load in all fields with entries prepopulated to null
+const chemotherapy = require('../constructDummyData').getSchemaDummy('chemotherapy');
+
+
+// key -> name of field, value -> unit tests
+const myUnitTests = {
+ 'actual_cumulative_drug_dose': [
+ [
+ 'actual_cumulative_drug_dose is submitted when prescribed_cumulative_drug_dose is missing',
+ true,
+ loadObjects(chemotherapy,
+ {
+ "actual_cumulative_drug_dose": 100
+ }
+ )
+ ],
+ [
+ 'prescribed_drug_dose is submitted when actual_cumulative_drug_dose is missing',
+ true,
+ loadObjects(chemotherapy,
+ {
+ "prescribed_cumulative_drug_dose": 150
+ }
+ )
+ ],
+ [
+ 'Both actual_cumulative_drug_dose and prescribed_cumulative_drug_dose are submitted',
+ true,
+ loadObjects(chemotherapy,
+ {
+ "actual_cumulative_drug_dose": 300,
+ "prescribed_cumulative_drug_dose": 350
+ }
+ )
+ ]
+ ],
+ 'prescribed_cumulative_drug_dose': [
+ [
+ 'prescibed_cumulative_drug_dose is submitted when actual_cumulative_drug_dose is missing',
+ true,
+ loadObjects(chemotherapy,
+ {
+ "prescribed_cumulative_drug_dose": 100
+ }
+ )
+ ],
+ [
+ 'actual_cumlative__drug_dose is submitted when prescribed_cumlative_drug_dose is missing',
+ true,
+ loadObjects(chemotherapy,
+ {
+ "actual_cumulative_drug_dose": 150
+ }
+ )
+ ],
+ [
+ 'Both actual_cumulative_drug_dose and prescribed_cumulative_drug_dose are submitted',
+ true,
+ loadObjects(chemotherapy,
+ {
+ "actual_cumulative_drug_dose": 300,
+ "prescribed_cumulative_drug_dose": 350
+ }
+ )
+ ],
+ [
+ 'Both cumulative_drug_dose and prescribed_cumulative_drug_dose are missing',
+ false,
+ loadObjects(chemotherapy,
+ {
+ }
+ )
+ ]
+ ]
+}
+
+
+describe("Common Tests",()=>{
+ Object.entries(myUnitTests).forEach(field =>{
+ const name = field[0];
+ const unitTests = field[1];
+ unitTests.forEach(test=>{
+ const testIndex = 2;
+ const testInputs = test[testIndex];
+ universalTest(validation()({ $row: testInputs, $name: name, $field: testInputs[name]}));
+ })
+ })
+
+})
+
+describe("Unit Tests for chemotherapy fields",()=>{
+ Object.entries(myUnitTests).forEach(field => {
+ const name = field[0];
+ const unitTests = field[1];
+ describe(`Tests for the ${name} field.`,()=>{
+ test.each(unitTests)('\n Test %# : %s \nExpecting result.valid to be: %s',(description,target,inputs) =>{
+ const scriptOutput = validation()({ $row: inputs, $field: inputs[name], $name: name});
+ expect(scriptOutput.valid).toBe(target);
+ })
+ })
+
+ })
+
+})
diff --git a/tests/common/mxCategoryValidation.test.js b/tests/common/mxCategoryValidation.test.js
index f3037ed7..34698227 100644
--- a/tests/common/mxCategoryValidation.test.js
+++ b/tests/common/mxCategoryValidation.test.js
@@ -31,6 +31,28 @@ const primary_diagnosis = require('../constructDummyData').getSchemaDummy('prima
const unitTests = {
'Specimen': [
+ [
+ 'Pathological staging system set to "AJCC 6th edition" and "not applicable" is submitted in pathological_m_category',
+ false,
+ {
+ row: loadObjects(specimen, {
+ pathological_tumour_staging_system: 'ajcc 6th edition',
+ pathological_m_category: 'Not applicable'
+ }),
+ name: 'pathological_m_category',
+ },
+ ],
+ [
+ 'Pathological staging system set to "AJCC 7th edition" and "not applicable" submitted in pathological_m_category',
+ true,
+ {
+ row: loadObjects(specimen, {
+ pathological_tumour_staging_system: 'ajcc 7th edition',
+ pathological_m_category: 'not Applicable'
+ }),
+ name: 'pathological_m_category',
+ },
+ ],
[
'Pathological staging system set to "AJCC 6th edition" and "MX" submitted in pathological_m_category',
true,
diff --git a/tests/follow_up/requiredWhenProgressOrRelapseRecur.test.js b/tests/follow_up/requiredWhenProgressOrRelapseRecur.test.js
index 624da917..80f20dee 100644
--- a/tests/follow_up/requiredWhenProgressOrRelapseRecur.test.js
+++ b/tests/follow_up/requiredWhenProgressOrRelapseRecur.test.js
@@ -162,7 +162,7 @@ const myUnitTests = {
],
[
'Disease status is relapse, without provided RTSS',
- false,
+ true,
loadObjects(followUp,
{
"disease_status_at_followup": "relapse or recurrence"
@@ -171,7 +171,7 @@ const myUnitTests = {
],
[
'Disease status is distant progression, without provided RTSS',
- false,
+ true,
loadObjects(followUp,
{
"disease_status_at_followup": "distant progression"
@@ -179,7 +179,7 @@ const myUnitTests = {
)
],
[
- 'Disease status is loco-regional progression, without provided RTSS',
+ 'Disease status is loco-regional progression, with provided RTSS',
true,
loadObjects(followUp,
{
@@ -199,7 +199,7 @@ const myUnitTests = {
)
],
[
- 'Disease status is no evidence of disease, without provided RTSS',
+ 'Disease status is no evidence of disease, with provided RTSS',
false,
loadObjects(followUp,
{
diff --git a/tests/hormone_therapy/drugDose.test.js b/tests/hormone_therapy/drugDose.test.js
new file mode 100644
index 00000000..10f65454
--- /dev/null
+++ b/tests/hormone_therapy/drugDose.test.js
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2020 The Ontario Institute for Cancer Research. All rights reserved
+ *
+ * This program and the accompanying materials are made available under the terms of the GNU Affero General Public License v3.0.
+ * You should have received a copy of the GNU Affero General Public License along with
+ * this program. If not, see .
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ */
+
+const validation = require('../../references/validationFunctions/hormone_therapy/drugDose.js');
+
+const universalTest = require('../universal');
+const loadObjects = require('../loadObjects');
+
+// load in all fields with entries prepopulated to null
+const hormone_therapy = require('../constructDummyData').getSchemaDummy('hormone_therapy');
+
+
+// key -> name of field, value -> unit tests
+const myUnitTests = {
+ 'actual_cumulative_drug_dose': [
+ [
+ 'actual_cumulative_drug_dose is submitted when prescribed_cumulative_drug_dose is missing',
+ true,
+ loadObjects(hormone_therapy,
+ {
+ "actual_cumulative_drug_dose": 100
+ }
+ )
+ ],
+ [
+ 'prescribed_drug_dose is submitted when actual_cumulative_drug_dose is missing',
+ true,
+ loadObjects(hormone_therapy,
+ {
+ "prescribed_cumulative_drug_dose": 150
+ }
+ )
+ ],
+ [
+ 'Both actual_cumulative_drug_dose and prescribed_cumulative_drug_dose are submitted',
+ true,
+ loadObjects(hormone_therapy,
+ {
+ "actual_cumulative_drug_dose": 300,
+ "prescribed_cumulative_drug_dose": 350
+ }
+ )
+ ]
+ ],
+ 'prescribed_cumulative_drug_dose': [
+ [
+ 'prescribed_cumulative_drug_dose is submitted when actual_cumulative_drug_dose is missing',
+ true,
+ loadObjects(hormone_therapy,
+ {
+ "prescribed_cumulative_drug_dose": 100
+ }
+ )
+ ],
+ [
+ 'actual_cumlative_drug_dose is submitted when prescribed_cumlative_drug_dose is missing',
+ true,
+ loadObjects(hormone_therapy,
+ {
+ "actual_cumulative_drug_dose": 150
+ }
+ )
+ ],
+ [
+ 'Both actual_cumulative_drug_dose and prescribed_cumulative_drug_dose are submitted',
+ true,
+ loadObjects(hormone_therapy,
+ {
+ "actual_cumulative_drug_dose": 300,
+ "prescribed_cumulative_drug_dose": 350
+ }
+ )
+ ],
+ [
+ 'Both actual_cumulative_drug_dose and prescribed_cumulative_drug_dose are missing',
+ false,
+ loadObjects(hormone_therapy,
+ {
+ }
+ )
+ ]
+ ]
+}
+
+
+describe("Common Tests",()=>{
+ Object.entries(myUnitTests).forEach(field =>{
+ const name = field[0];
+ const unitTests = field[1];
+ unitTests.forEach(test=>{
+ const testIndex = 2;
+ const testInputs = test[testIndex];
+ universalTest(validation()({ $row: testInputs, $name: name, $field: testInputs[name]}));
+ })
+ })
+
+})
+
+describe("Unit Tests for hormone_therapy fields",()=>{
+ Object.entries(myUnitTests).forEach(field => {
+ const name = field[0];
+ const unitTests = field[1];
+ describe(`Tests for the ${name} field.`,()=>{
+ test.each(unitTests)('\n Test %# : %s \nExpecting result.valid to be: %s',(description,target,inputs) =>{
+ const scriptOutput = validation()({ $row: inputs, $field: inputs[name], $name: name});
+ expect(scriptOutput.valid).toBe(target);
+ })
+ })
+
+ })
+
+})
diff --git a/tests/immunotherapy/drugDose.test.js b/tests/immunotherapy/drugDose.test.js
new file mode 100644
index 00000000..c10ec069
--- /dev/null
+++ b/tests/immunotherapy/drugDose.test.js
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2020 The Ontario Institute for Cancer Research. All rights reserved
+ *
+ * This program and the accompanying materials are made available under the terms of the GNU Affero General Public License v3.0.
+ * You should have received a copy of the GNU Affero General Public License along with
+ * this program. If not, see .
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ */
+
+const validation = require('../../references/validationFunctions/immunotherapy/drugDose.js');
+
+const universalTest = require('../universal');
+const loadObjects = require('../loadObjects');
+
+// load in all fields with entries prepopulated to null
+const immunotherapy = require('../constructDummyData').getSchemaDummy('immunotherapy');
+
+
+// key -> name of field, value -> unit tests
+const myUnitTests = {
+ 'actual_cumulative_drug_dose': [
+ [
+ 'actual_cumulative_drug_dose is submitted when prescribed_cumulative_drug_dose is missing',
+ true,
+ loadObjects(immunotherapy,
+ {
+ "actual_cumulative_drug_dose": 100
+ }
+ )
+ ],
+ [
+ 'prescribed_drug_dose is submitted when actual_cumulative_drug_dose is missing',
+ true,
+ loadObjects(immunotherapy,
+ {
+ "prescribed_cumulative_drug_dose": 150
+ }
+ )
+ ],
+ [
+ 'Both actual_cumulative_drug_dose and prescribed_cumulative_drug_dose are submitted',
+ true,
+ loadObjects(immunotherapy,
+ {
+ "actual_cumulative_drug_dose": 300,
+ "prescribed_cumulative_drug_dose": 350
+ }
+ )
+ ]
+ ],
+ 'prescribed_cumulative_drug_dose': [
+ [
+ 'prescribed_cumulative_drug_dose is submitted when actual_cumulative_drug_dose is missing',
+ true,
+ loadObjects(immunotherapy,
+ {
+ "prescribed_cumulative_drug_dose": 100
+ }
+ )
+ ],
+ [
+ 'actual_cumlative__drug_dose is submitted when prescribed_cumlative_drug_dose is missing',
+ true,
+ loadObjects(immunotherapy,
+ {
+ "actual_cumulative_drug_dose": 150
+ }
+ )
+ ],
+ [
+ 'Both actual_cumulative_drug_dose and prescribed_cumulative_drug_dose are submitted',
+ true,
+ loadObjects(immunotherapy,
+ {
+ "actual_cumulative_drug_dose": 300,
+ "prescribed_cumulative_drug_dose": 350
+ }
+ )
+ ],
+ [
+ 'Both actual_cumulative_drug_dose and prescribed_cumulative_drug_dose are missing',
+ false,
+ loadObjects(immunotherapy,
+ {
+ }
+ )
+ ]
+ ]
+}
+
+
+describe("Common Tests",()=>{
+ Object.entries(myUnitTests).forEach(field =>{
+ const name = field[0];
+ const unitTests = field[1];
+ unitTests.forEach(test=>{
+ const testIndex = 2;
+ const testInputs = test[testIndex];
+ universalTest(validation()({ $row: testInputs, $name: name, $field: testInputs[name]}));
+ })
+ })
+
+})
+
+describe("Unit Tests for immunotherapy fields",()=>{
+ Object.entries(myUnitTests).forEach(field => {
+ const name = field[0];
+ const unitTests = field[1];
+ describe(`Tests for the ${name} field.`,()=>{
+ test.each(unitTests)('\n Test %# : %s \nExpecting result.valid to be: %s',(description,target,inputs) =>{
+ const scriptOutput = validation()({ $row: inputs, $field: inputs[name], $name: name});
+ expect(scriptOutput.valid).toBe(target);
+ })
+ })
+
+ })
+
+})
diff --git a/tests/primary_diagnosis/lymphNodesExaminedMethod.test.js b/tests/primary_diagnosis/lymphNodesExaminedMethod.test.js
new file mode 100644
index 00000000..a1117d84
--- /dev/null
+++ b/tests/primary_diagnosis/lymphNodesExaminedMethod.test.js
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2020 The Ontario Institute for Cancer Research. All rights reserved
+ *
+ * This program and the accompanying materials are made available under the terms of the GNU Affero General Public License v3.0.
+ * You should have received a copy of the GNU Affero General Public License along with
+ * this program. If not, see .
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ */
+
+const validation = require('../../references/validationFunctions/primary_diagnosis/lymphNodesExaminedMethod');
+
+const universalTest = require('../universal');
+const loadObjects = require('../loadObjects');
+
+// load in all fields with entries prepopulated to null
+const primary_diagnosis = require('../constructDummyData').getSchemaDummy('primary_diagnosis');
+
+
+// key -> name of field, value -> unit tests
+const myUnitTests = {
+ 'lymph_nodes_examined_method': [
+ [
+ 'lymph nodes were examined and lymph_nodes_examined_method is submitted',
+ true,
+ loadObjects(primary_diagnosis,
+ {
+ "lymph_nodes_examined_status": "Yes",
+ "lymph_nodes_examined_method": "imaging"
+ }
+ )
+ ],
+ [
+ 'lymph nodes were not examined and lymph_nodes_examined_method is submitted',
+ false,
+ loadObjects(primary_diagnosis,
+ {
+ "lymph_nodes_examined_status": "no",
+ "lymph_nodes_examined_method": "physical palpation of patient"
+ }
+ )
+ ],
+ [
+ 'lymph nodes were examined and lymph_nodes_examined_method is left blank',
+ false,
+ loadObjects(primary_diagnosis,
+ {
+ "lymph_nodes_examined_status": "Yes",
+ "lymph_nodes_examined_method": ""
+ }
+ )
+ ],
+ [
+ 'lymph nodes were examined and lymph_nodes_examined_method not submitted',
+ false,
+ loadObjects(primary_diagnosis,
+ {
+ "lymph_nodes_examined_status": "Yes",
+ }
+ )
+ ],
+ [
+ 'lymph nodes were not examined and lymph_nodes_examined_method not submitted',
+ true,
+ loadObjects(primary_diagnosis,
+ {
+ "lymph_nodes_examined_status": "Not applicable"
+ }
+ )
+ ]
+ ]
+}
+
+
+describe("Common Tests",()=>{
+ Object.entries(myUnitTests).forEach(field =>{
+ const name = field[0];
+ const unitTests = field[1];
+ unitTests.forEach(test=>{
+ const testIndex = 2;
+ const testInputs = test[testIndex];
+ universalTest(validation()({ $row: testInputs, $name: name, $field: testInputs[name]}));
+ })
+ })
+
+})
+
+describe("Unit Tests for Lymph Node Fields in Primary Diagnosis",()=>{
+ Object.entries(myUnitTests).forEach(field => {
+ const name = field[0];
+ const unitTests = field[1];
+ describe(`Tests for the ${name} field.`,()=>{
+ test.each(unitTests)('\n Test %# : %s \nExpecting result.valid to be: %s',(description,target,inputs) =>{
+ const scriptOutput = validation()({ $row: inputs, $field: inputs[name], $name: name});
+ expect(scriptOutput.valid).toBe(target);
+ })
+ })
+
+ })
+
+})
diff --git a/tests/treatment/checkWhenNoTreatment.test.js b/tests/treatment/checkWhenNoTreatment.test.js
index 9334408c..b85b5994 100644
--- a/tests/treatment/checkWhenNoTreatment.test.js
+++ b/tests/treatment/checkWhenNoTreatment.test.js
@@ -36,7 +36,7 @@ const myUnitTests = {
loadObjects(treatment,
{
"treatment_start_interval": 30,
- "treatment_type": "No treatment"
+ "treatment_type": ["No treatment"]
}
)
],
@@ -46,7 +46,7 @@ const myUnitTests = {
loadObjects(treatment,
{
"treatment_start_interval": 409,
- "treatment_type": "Chemotherapy"
+ "treatment_type": ["Chemotherapy"]
}
)
],
@@ -55,19 +55,10 @@ const myUnitTests = {
true,
loadObjects(treatment,
{
- "treatment_type": "No treatment"
+ "treatment_type": ["No treatment"]
}
)
- ],
- [
- 'treatment_start_interval is submitted but treatment_type is not submitted',
- true,
- loadObjects(treatment,
- {
- "treatment_start_interval": 30,
- }
- )
- ],
+ ]
],
'treatment_duration': [
[
@@ -76,7 +67,7 @@ const myUnitTests = {
loadObjects(treatment,
{
"treatment_duration": 30,
- "treatment_type": "No treatment"
+ "treatment_type": ["No treatment"]
}
)
],
@@ -86,7 +77,7 @@ const myUnitTests = {
loadObjects(treatment,
{
"treatment_duration": 40,
- "treatment_type": "Chemotherapy"
+ "treatment_type": ["Chemotherapy"]
}
)
],
@@ -95,7 +86,7 @@ const myUnitTests = {
false,
loadObjects(treatment,
{
- "treatment_type": "Surgery"
+ "treatment_type": ["Surgery"]
}
)
]
@@ -106,8 +97,7 @@ const myUnitTests = {
false,
loadObjects(treatment,
{
- "is_primary_treatment": "",
- "treatment_type": "Chemotherapy"
+ "treatment_type": ["Chemotherapy"]
}
)
],
@@ -117,7 +107,7 @@ const myUnitTests = {
loadObjects(treatment,
{
"is_primary_treatment": "Yes",
- "treatment_type": "No treatment"
+ "treatment_type": ["No treatment"]
}
)
],
@@ -127,7 +117,7 @@ const myUnitTests = {
loadObjects(treatment,
{
"is_primary_treatment": "No",
- "treatment_type": "Chemotherapy"
+ "treatment_type": ["Chemotherapy"]
}
)
],
@@ -137,7 +127,16 @@ const myUnitTests = {
loadObjects(treatment,
{
"is_primary_treatment": "",
- "treatment_type": "No treatment"
+ "treatment_type": ["No treatment"]
+ }
+ )
+ ],
+ [
+ 'is_primary_treatment is not submitted when no treatment is given',
+ true,
+ loadObjects(treatment,
+ {
+ "treatment_type": ["No treatment"]
}
)
]
@@ -149,7 +148,7 @@ const myUnitTests = {
loadObjects(treatment,
{
"treatment_setting": "neoadjuvant",
- "treatment_type": "No treatment"
+ "treatment_type": ["No treatment"]
}
)
],
@@ -159,10 +158,20 @@ const myUnitTests = {
loadObjects(treatment,
{
"treatment_setting": "adjuvant",
- "treatment_type": "Chemotherapy"
+ "treatment_type": ["Chemotherapy"]
+ }
+ )
+ ],
+ [
+ 'treatment_setting is not submitted when no treatment is given',
+ true,
+ loadObjects(treatment,
+ {
+ "treatment_type": ["no treatment"]
}
)
]
+
],
'treatment_intent': [
[
@@ -171,7 +180,7 @@ const myUnitTests = {
loadObjects(treatment,
{
"treatment_intent": "curative",
- "treatment_type": "No treatment"
+ "treatment_type": ["No treatment"]
}
)
],
@@ -181,54 +190,97 @@ const myUnitTests = {
loadObjects(treatment,
{
"treatment_intent": "palliative",
- "treatment_type": "Chemotherapy"
+ "treatment_type": ["Chemotherapy"]
+ }
+ )
+ ],
+ [
+ 'treatment_intent is not submitted when no treatment is given',
+ true,
+ loadObjects(treatment,
+ {
+ "treatment_type": ["no treatment"]
}
)
]
+
],
- 'line_of_treatment': [
+ 'days_per_cycle': [
[
- 'line of treatment submitted even though no treatment was given',
+ 'days per cycle is submitted when Chemotherapy was given',
+ true,
+ loadObjects(treatment,
+ {
+ "days_per_cycle": 12,
+ "treatment_type": ["Chemotherapy"]
+ }
+ )
+ ],
+ [
+ 'days per cycle is submitted when no treatment was given',
false,
loadObjects(treatment,
{
- "line_of_treatment": 1,
- "treatment_type": "No treatment"
+ "days_per_cycle": 10,
+ "treatment_type": ["no treatment"]
+ }
+ )
+ ]
+ ],
+ 'outcome_of_treatment': [
+ [
+ 'outcome_of_treatment is submitted when no treatment was given',
+ false,
+ loadObjects(treatment,
+ {
+ "outcome_of_treatment": "treatment completed as prescribed",
+ "treatment_type": ["no treatment"]
}
)
],
[
- 'line of treatment not submitted when no treatment was given',
+ 'outcome_of_treatment is not applicable when no treatment was given',
true,
loadObjects(treatment,
{
- "treatment_type": "No treatment"
+ "outcome_of_treatment": "Not Applicable",
+ "treatment_type": ["no treatment"]
}
)
],
[
- 'line of treatment not submitted when Hormonal therapy given. Should not fail since this field is optional',
+ 'outcome_of_treatment is empty when no treatment was given',
true,
loadObjects(treatment,
{
- "line_of_treatment": "",
- "treatment_type": "Hormonal therapy"
+ "outcome_of_treatment": "",
+ "treatment_type": ["no treatment"]
}
)
- ],
+ ]
],
- 'days_per_cycle': [
+ 'response_to_treatment_criteria_method': [
[
- 'days per cycle is submitted when Chemotherapy was given',
- true,
+ 'response_to_treatment_criteria_method is submitted when no treatment was given',
+ false,
loadObjects(treatment,
{
- "days_per_cycle": 12,
- "treatment_type": "Chemotherapy"
+ "response_to_treatment_criteria_method": "RECIST",
+ "treatment_type": ["no treatment"]
+ }
+ )
+ ],
+ [
+ 'response_to_treatment_criteria_method is missing when radiation treatment was given',
+ false,
+ loadObjects(treatment,
+ {
+ "treatment_type": ["radiation therapy"]
}
)
]
]
+
}
describe("Common Tests",()=>{
diff --git a/tests/treatment/lineofTreatment.test.js b/tests/treatment/lineofTreatment.test.js
index 54f5c611..0500386d 100644
--- a/tests/treatment/lineofTreatment.test.js
+++ b/tests/treatment/lineofTreatment.test.js
@@ -51,25 +51,15 @@ const myUnitTests = {
)
],
[
- 'is_primary_treatment is unknown, and line_of_treatment is submitted as 1',
+ 'is_primary_treatment is not applicable, and line_of_treatment is submitted as 1',
false,
loadObjects(treatment,
{
- "is_primary_treatment": "unknown",
+ "is_primary_treatment": "not applicable",
"line_of_treatment": 1
}
)
],
- [
- 'is_primary_treatment is unknown, and line_of_treatment is submitted as 3',
- false,
- loadObjects(treatment,
- {
- "is_primary_treatment": "unknown",
- "line_of_treatment": 3
- }
- )
- ],
[
'is_primary_treatment is yes, and line_of_treatment is submitted as 2',
false,
diff --git a/tests/treatment/responseToTreatment.test.js b/tests/treatment/responseToTreatment.test.js
new file mode 100644
index 00000000..9808e963
--- /dev/null
+++ b/tests/treatment/responseToTreatment.test.js
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved
+ *
+ * This program and the accompanying materials are made available under the terms of the GNU Affero General Public License v3.0.
+ * You should have received a copy of the GNU Affero General Public License along with
+ * this program. If not, see .
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ */
+
+const validation = require('./../../references/validationFunctions/treatment/responseToTreatment.js');
+const universalTest = require('../universal');
+const loadObjects = require('../loadObjects');
+
+// load in all fields with entries prepopulated to null
+const dummy = require('../constructDummyData');
+const treatment = require('../constructDummyData').getSchemaDummy('treatment');
+
+// the name of the field being validateds
+
+const myUnitTests = {
+ 'response_to_treatment': [
+ [
+ 'response_to_treatment_criteria_method is IWG Cheson AML 2003 Oncology Response Criteria, response_to_treatment is "Stable disease" which does not exist',
+ false,
+ loadObjects(treatment,
+ {
+ "response_to_treatment_criteria_method": "IWG Cheson AML 2003 Oncology Response Criteria",
+ "response_to_treatment": "stable Disease",
+ }
+ )
+ ],
+ [
+ 'response_to_treatment_criteria_method is "Response Assessment in Neuro-Oncology (RANO)" when response_to_treatment is "minor response"',
+ true,
+ loadObjects(treatment,
+ {
+ "response_to_treatment_criteria_method": "Response Assessment in Neuro-Oncology (RANO)",
+ "response_to_treatment": "minor response",
+ }
+ )
+ ],
+ [
+ 'response_to_treatment_criteria_method is "recist" when response_to_treatment is "minor response"',
+ false,
+ loadObjects(treatment,
+ {
+ "response_to_treatment_criteria_method": "recist",
+ "response_to_treatment": "minor response",
+ }
+ )
+ ],
+ [
+ 'response_to_treatment_criteria_method is recist and response_to_treatment is missing',
+ false,
+ loadObjects(treatment,
+ {
+ "response_to_treatment_criteria_method": "recist",
+ }
+ )
+ ]
+ ]
+};
+
+describe("Common Tests",()=>{
+ Object.entries(myUnitTests).forEach(field =>{
+ const name = field[0];
+ const unitTests = field[1];
+ unitTests.forEach(test=>{
+ const testIndex = 2;
+ const testInputs = test[testIndex];
+ universalTest(validation()({ $row: testInputs, $name: name, $field: testInputs[name]}));
+ })
+ })
+
+})
+
+describe("Unit Tests for response_to_treatment field",()=>{
+ Object.entries(myUnitTests).forEach(field => {
+ const name = field[0];
+ const unitTests = field[1];
+ describe(`Tests for the ${name} field.`,()=>{
+ test.each(unitTests)('\n Test %# : %s \nExpecting result.valid to be: %s',(description,target,inputs) =>{
+ const scriptOutput = validation()({ $row: inputs, $field: inputs[name], $name: name});
+ expect(scriptOutput.valid).toBe(target);
+ })
+ })
+
+ })
+
+})
+