Skip to content

Commit

Permalink
fix(validation): fix evaluating requiredness from branch forms
Browse files Browse the repository at this point in the history
This commit fixes the form validation.

Given a structure like this:

f:topform
   q:formquestionbranch - hidden=false
     f:subformbranch
        q:depquestion2 - required = 'subquestion2'|answer=='bluh'
   q:formquestion - hidden=variable
     f:subform
        q:subquestion1 - hidden=false
        q:subquestion2 - hidden=false
   q:depquestion1 - required = 'subquestion1'|answer=='blah'

d:topdoc f=topform
   a:subanswer1 q=subquestion1, value='blah'
   a:subanswer2 q=subquestion2, value='bluh'

The requiredness of `depquestion2` was wrongly evaluated to `True`,
because it couldn't reach `formquestion` and everything below.

This commit fixes the validation, so it can reach all forms in the
document.
  • Loading branch information
open-dynaMIX committed Apr 7, 2020
1 parent d186c27 commit 062e350
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 16 deletions.
2 changes: 1 addition & 1 deletion caluma/caluma_form/jexl.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def _all_containers_hidden(self, question):
If all subforms are hidden where the question shows up,
the question shall be hidden as well.
"""
paths = self._structure.paths_to_question(question.slug)
paths = self._structure.root().paths_to_question(question.slug)

res = bool(paths) and all(
# the "inner" check here represents a single path. If any
Expand Down
60 changes: 45 additions & 15 deletions caluma/caluma_form/tests/test_jexl.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,42 +101,72 @@ def test_indirectly_hidden_dependency(
# but also if they're part of a subform, where the containing form question
# is hidden.
#
# Showcase form to demonstrate this (f: form, q:question, d:document, a:answer):
# Showcase form to demonstrate this (f:form, q:question, d:document, a:answer):
# f:topform
# q:formquestion - hidden=true
# q:formquestionbranch - hidden=false
# f:subformbranch
# q:depquestion2 - required = 'subquestion2'|answer=='bluh'
# q:formquestion - hidden=variable
# f:subform
# q:subquestion - hidden=false
# q:depquestion - required = subquestion|answer=='blah'
# q:subquestion1 - hidden=false
# q:subquestion2 - hidden=false
# q:depquestion1 - required = 'subquestion1'|answer=='blah'
#
# d:topdoc f=topform
# a:subanswer q=subquestion, value='blah'
# (depquestion has no answer, as it's indirectly not required)
# a:subanswer1 q=subquestion1, value='blah'
# a:subanswer2 q=subquestion2, value='bluh'
# (depquestion1 and depquestion2 have no answers, as they're indirectly not required)
#
# Note: The above structure shows the actual "feature" case.
# We also test with `subquestion` not hidden, to ensure both ways
# work correctly

# Build the form first...
topform = form_factory(slug="top")
subform = form_factory(slug="subform")
subformbranch = form_factory(slug="subform")
subform = form_factory(slug="subformbranch")

formquestion = question_factory(
type=Question.TYPE_FORM, is_hidden=fq_is_hidden, sub_form=subform
type=Question.TYPE_FORM,
is_hidden=fq_is_hidden,
sub_form=subform,
slug="topformquestion",
)
subquestion = question_factory(
type=Question.TYPE_INTEGER, is_hidden="false", slug="subquestion"
formquestionbranch = question_factory(
type=Question.TYPE_FORM,
is_hidden="false",
sub_form=subformbranch,
slug="topformquestionbranch",
)
depquestion = question_factory(
type=Question.TYPE_INTEGER, is_required="'subquestion'|answer=='blah'"
subquestion1 = question_factory(
type=Question.TYPE_INTEGER, is_hidden="false", slug="subquestion1"
)
subquestion2 = question_factory(
type=Question.TYPE_INTEGER, is_hidden="false", slug="subquestion2"
)
depquestion1 = question_factory(
type=Question.TYPE_INTEGER,
is_required="'subquestion1'|answer=='blah'",
slug="depquestion1",
)
depquestion2 = question_factory(
type=Question.TYPE_INTEGER,
is_required="'subquestion2'|answer=='bluh'",
slug="depquestion2",
)
form_question_factory(form=topform, question=formquestion)
form_question_factory(form=topform, question=depquestion)
form_question_factory(form=topform, question=formquestionbranch)
form_question_factory(form=topform, question=depquestion1)

form_question_factory(form=subformbranch, question=depquestion2)

form_question_factory(form=subform, question=subquestion)
form_question_factory(form=subform, question=subquestion1)
form_question_factory(form=subform, question=subquestion2)

# ... then build the document
topdoc = document_factory(form=topform)
answer_factory(document=topdoc, question=subquestion, value="blah")
answer_factory(document=topdoc, question=subquestion1, value="blah")
answer_factory(document=topdoc, question=subquestion2, value="bluh")

validator = validators.DocumentValidator()

Expand Down

0 comments on commit 062e350

Please sign in to comment.