Skip to content

Commit

Permalink
fix: call validate_form
Browse files Browse the repository at this point in the history
Was dropped in 54b59bb.
  • Loading branch information
MHajoha committed Jan 7, 2025
1 parent 02b6bf1 commit 3486590
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 0 deletions.
6 changes: 6 additions & 0 deletions questionpy/_qtype.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from ._attempt import Attempt, AttemptProtocol, AttemptScoredProtocol, AttemptStartedProtocol
from ._util import get_mro_type_hint
from .form import FormModel, OptionsFormDefinition
from .form.validation import validate_form

_F = TypeVar("_F", bound=FormModel)
_S = TypeVar("_S", bound="BaseQuestionState")
Expand Down Expand Up @@ -169,6 +170,11 @@ def __init_subclass__(cls, *args: object, **kwargs: object) -> None:
cls.options_class, cls.question_state_class # type: ignore[name-defined]
]

# A form may have unresolved references when it is intended to be used as a repetition, group, section, etc.
# Only the complete form must pass validation, so the validation has to happen here instead of in FormModel or
# OptionsFormDefinition.
validate_form(cls.options_class.qpy_form)

@property # type: ignore[no-redef]
def options(self) -> FormModel:
return self.question_state_with_version.options
Expand Down
16 changes: 16 additions & 0 deletions tests/questionpy/wrappers/test_question.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@
from questionpy import (
InvalidResponseError,
NeedsManualScoringError,
Question,
QuestionTypeWrapper,
QuestionWrapper,
ResponseNotScorableError,
)
from questionpy.form import FormModel, is_not_checked, text_input
from questionpy.form.validation import FormError
from questionpy_common.api.attempt import AttemptModel, AttemptScoredModel, AttemptStartedModel, AttemptUi, ScoringCode
from questionpy_common.api.question import QuestionModel, ScoringMethod
from questionpy_common.environment import Package
Expand Down Expand Up @@ -103,3 +106,16 @@ def test_should_export_question_model(package: Package) -> None:
question_model = question.export()

assert question_model == QuestionModel(lang="en", scoring_method=ScoringMethod.AUTOMATICALLY_SCORABLE)


def test_should_raise_when_form_is_invalid() -> None:
class ModelWithUnresolvedReference(FormModel):
my_text: str | None = text_input("Label", hide_if=is_not_checked("nonexistent_checkbox"))

# There are more detailed validation tests in test_validation.py, here we just ensure that validate_form is called
# at the correct place.
with pytest.raises(FormError):

class MyQuestion(Question):
attempt_class = SomeAttempt
options: ModelWithUnresolvedReference

0 comments on commit 3486590

Please sign in to comment.