Skip to content

Commit

Permalink
:bugs: fix: Fix the bug in validation for type based slicing. Fixes: #43
Browse files Browse the repository at this point in the history
  • Loading branch information
Tuncay NAMLI committed Nov 2, 2022
1 parent 70e88a8 commit 1469f20
Showing 1 changed file with 22 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package io.onfhir.validation

import java.net.URI

import io.onfhir.api
import io.onfhir.api.{FHIR_DATA_TYPES, FHIR_ROOT_URL_FOR_DEFINITIONS, Resource}
import io.onfhir.api.model.FHIRResponse.{OUTCOME_CODES, SEVERITY_CODES}
Expand All @@ -11,7 +10,7 @@ import io.onfhir.api.validation._
import io.onfhir.config.FhirConfig
import io.onfhir.exception.InitializationException
import io.onfhir.path.{FhirPathComplex, FhirPathEvaluator}
import org.json4s.JInt
import org.json4s.{JInt, JNothing}
import org.json4s.JsonAST.{JArray, JBool, JDecimal, JDouble, JLong, JObject, JString, JValue}
import io.onfhir.util.JsonFormatter.formats
import org.slf4j.{Logger, LoggerFactory}
Expand Down Expand Up @@ -175,7 +174,7 @@ class FhirContentValidator(
validatedFields += fieldName
//Find all restrictions chain defined for the field (in priority order)
val elementRestrictions = findElementRestrictionsChain(fieldName, allRestrictions)
val cardinalityIssues = evaluateCardinalityConstraints(dataType, fieldValue, elementRestrictions.flatMap(_._1))
val cardinalityIssues = evaluateCardinalityAndTypeConstraints(dataType, fieldValue, elementRestrictions.flatMap(_._1))
if(cardinalityIssues.nonEmpty)
Future.apply(FhirContentValidator.convertToOutcomeIssue(FHIRUtil.mergeElementPath(parentPath, s"_$field"), cardinalityIssues))
else
Expand Down Expand Up @@ -231,7 +230,7 @@ class FhirContentValidator(
private def validateElement(path: String, fieldName: String, dataType: String, value: JValue, elementRestrictions: Seq[(Option[ElementRestrictions], Seq[(String, ElementRestrictions)])], possiblePrimitiveExtension:Option[JValue]): Future[Seq[OutcomeIssue]] = {
logger.debug(s"Validating element at path $path with field $fieldName and data type $dataType...")
//First perform cardinality validations
val cardinalityValidations = evaluateCardinalityConstraints(dataType, value, elementRestrictions.flatMap(_._1))
val cardinalityValidations = evaluateCardinalityAndTypeConstraints(dataType, value, elementRestrictions.flatMap(_._1))
//If there is an error in cardinality directly return it
if (cardinalityValidations.nonEmpty)
Future.apply(FhirContentValidator.convertToOutcomeIssue(path, cardinalityValidations))
Expand Down Expand Up @@ -362,9 +361,14 @@ class FhirContentValidator(
None
failures = failures ++ orderFailure.toSeq

val matchedValues = sliceValues match {
case Nil => JNothing
case oth => JArray(oth.map(_._1).toList)
}

//Cardinality checks on the slice values
failures = failures ++
evaluateCardinalityConstraints(dataType, JArray(sliceValues.map(_._1).toList), Seq(svm._4), testArray = false)
evaluateCardinalityConstraints(matchedValues, Seq(svm._4), testArray = false)
.map(cf => ConstraintFailure(s"Based on the slice definition '${svm._1}': ${cf.errorOrWarningMessage}"))

failures
Expand Down Expand Up @@ -1015,9 +1019,20 @@ class FhirContentValidator(
* @param elementRestrictions
* @return
*/
private def evaluateCardinalityConstraints(dataType: String, value: JValue, elementRestrictions: Seq[ElementRestrictions], testArray: Boolean = true): Seq[ConstraintFailure] = {
private def evaluateCardinalityAndTypeConstraints(dataType: String, value: JValue, elementRestrictions: Seq[ElementRestrictions], testArray: Boolean = true): Seq[ConstraintFailure] = {
evaluateDataTypeConstraint(dataType, value, elementRestrictions) ++
evaluateCardinalityConstraints(value, elementRestrictions, testArray)
}

/**
* Evaluate cardinality constraints on the element
* @param value Value provided for the element
* @param elementRestrictions Element restrictions given for the element
* @param testArray Whether to test being array or not
* @return
*/
private def evaluateCardinalityConstraints(value: JValue, elementRestrictions: Seq[ElementRestrictions], testArray: Boolean = true): Seq[ConstraintFailure] = {
Seq(
evaluateDataTypeConstraint(dataType, value, elementRestrictions),
//Evaluate Minimum cardinality restriction if exist
findFirstFhirRestriction(ConstraintKeys.MIN, elementRestrictions).map(_.evaluate(value, this)).getOrElse(Nil),
//Evaluate Maximum cardinality restriction if exist
Expand Down

0 comments on commit 1469f20

Please sign in to comment.