Skip to content

Commit

Permalink
For #6252: add test and clarify xs:string UI handling
Browse files Browse the repository at this point in the history
  • Loading branch information
ebruchez committed Apr 6, 2024
1 parent 618f997 commit 463f41c
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 3 deletions.
Expand Up @@ -392,6 +392,12 @@ trait AlertsAndConstraintsOps extends ControlOps {

object DatatypeValidation {

// `xs:string` is special since the empty string is still a valid `xs:string`, so `xs:string` is the same as
// `xf:string`. We shouldn't ever have to write `xf:string`. (XForms 2.0 even removes those `xf:*` types as
// they are not needed anymore, since `required` has precedence.) Here, we decide to return `xs:string` as the
// default datatype (`DefaultDataTypeValidation`), but we always mark it as not implying requiredness. The UI
// will show it as required only if the `required` validation implies it. However, for other `xs:*` types, we
// imply requiredness unless there is a `required` validation that implies otherwise.
private val DefaultDataTypeValidation =
DatatypeValidation(None, Left(XMLConstants.XS_STRING_QNAME -> false), None)

Expand All @@ -405,7 +411,7 @@ trait AlertsAndConstraintsOps extends ControlOps {
val isBuiltinType = Set(XF, XS)(qName.namespace.uri)

if (isBuiltinType)
Left(qName -> (qName.namespace.uri == XS))
Left(qName -> (qName != XMLConstants.XS_STRING_QNAME && qName.namespace.uri == XS)) // see `DefaultDataTypeValidation`
else
Right(qName)
}
Expand All @@ -416,7 +422,7 @@ trait AlertsAndConstraintsOps extends ControlOps {
// https://github.com/orbeon/orbeon-forms/issues/6252
DatatypeValidation(
idOpt,
value.trimAllToOpt.map(builtinOrSchemaType).getOrElse(DefaultDataTypeValidation.datatype),
value.trimAllToOpt.map(builtinOrSchemaType).getOrElse(DefaultDataTypeValidation.datatype), // see `DefaultDataTypeValidation`
alertOpt
)
} getOrElse
Expand Down
Expand Up @@ -17,6 +17,7 @@ import org.orbeon.dom.Document
import org.orbeon.oxf.fb.FormBuilder._
import org.orbeon.oxf.fr.FormRunner._
import org.orbeon.oxf.fr.SchemaOps.findSchemaPrefix
import org.orbeon.oxf.fr.XMLNames.XF
import org.orbeon.oxf.test.{DocumentTestBase, ResourceManagerSupport}
import org.orbeon.oxf.xml.dom.Converter._
import org.orbeon.oxf.xml.{TransformerUtils, XMLConstants}
Expand Down Expand Up @@ -558,7 +559,48 @@ class AlertsAndConstraintsTest
}
}

private def globalAlert (implicit ctx: FormBuilderDocContext) = AlertDetails(None, Nil, global = true)
describe("Writing `*:string` type with custom alert") {

for (required <- List(true, false))
it(s"must not write the `*:string` type for required = $required") {
withActionAndFBDoc(AlertsDoc) { implicit ctx =>

val newValidations = List(
<validation type="required" level="error" default-alert="true">
<required>{required}()</required>
<alert global="false"/>
</validation>,
<validation type="datatype" id="" level="error" default-alert="false">
<builtin-type>string</builtin-type>
<builtin-type-required>{required}</builtin-type-required>
<schema-type/>
<alert global="false">
<message lang="en" value="Incorrect datatype"/>
</alert>
</validation>
)

writeAlertsAndValidationsAsXML(Control1, "", globalAlertAsXML, newValidations map elemToNodeInfo)

val xfTypeElem =
ctx.topLevelBindElem.get.descendant(XF -> "type").head

assert(xfTypeElem.id == "validation-2-validation")
assert(xfTypeElem.stringValue.isEmpty)

val expected =
DatatypeValidation(
Some("validation-2-validation"),
Left((XMLConstants.XS_STRING_QNAME, false)), // always `false` even for `xs:string`
Some(AlertDetails(Some("validation-2-validation"), List(("en", "Incorrect datatype"), ("fr", "")), global = false))
)

assert(expected == DatatypeValidation.fromForm(Control1))
}
}
}

private def globalAlert = AlertDetails(None, Nil, global = true)
private def globalAlertAsXML(implicit ctx: FormBuilderDocContext) = globalAlert.toXML

private def readConstraintValidationsAsXML(controlName: String)(implicit ctx: FormBuilderDocContext) =
Expand Down

0 comments on commit 463f41c

Please sign in to comment.