def validate_routing_rule(self, rule):
     rule = rule.get("goto")
     if rule and "when" in rule:
         when_validator = WhenRuleValidator(rule["when"],
                                            self.schema_element["id"],
                                            self.questionnaire_schema)
         self.errors += when_validator.validate()
    def validate_variants(self, block):
        question_variants = block.get("question_variants", [])
        content_variants = block.get("content_variants", [])

        all_variants = question_variants + content_variants

        for variant in question_variants:
            self.validate_question(variant)

        # This is validated in json schema, but the error message is not good at the moment.
        if len(question_variants) == 1 or len(content_variants) == 1:
            self.add_error(
                error_messages.VARIANTS_HAS_ONE_VARIANT, block_id=block["id"]
            )

        for variant in all_variants:
            when_clause = variant.get("when", [])

            if isinstance(when_clause, list):
                when_validator = WhenRuleValidator(
                    when_clause, block["id"], self.questionnaire_schema
                )
                self.errors += when_validator.validate()

            elif isinstance(when_clause, dict):
                when_validator = NewWhenRuleValidator(
                    when_clause, self.section["id"], self.questionnaire_schema
                )
                self.errors += when_validator.validate()

        self.validate_variant_fields(block, question_variants)
예제 #3
0
    def validate_skip_condition(self, skip_condition):
        """
        Validate skip condition is valid
        :return: list of dictionaries containing error messages, otherwise it returns an empty list
        """
        when = skip_condition.get("when")

        when_validator = WhenRuleValidator(
            when, self.schema_element["id"], self.questionnaire_schema
        )
        self.errors += when_validator.validate()
예제 #4
0
def test_validate_answer_value_in_when_rule_valid():
    when_rule = {"id": "answer-1", "condition": "equals", "value": "Yes"}
    option_value_to_answer_id_map = {
        "answer-1": {"Yes", "No"},
        "answer-2": {"Yes", "No"},
    }

    questionnaire_schema = QuestionnaireSchema({})
    validator = WhenRuleValidator(when_rule, {}, questionnaire_schema)
    validator.questionnaire_schema.answer_id_to_option_values_map = (
        option_value_to_answer_id_map)

    validator.validate_answer_value_in_when_rule(when_rule)

    assert not validator.errors
    def validate_section_enabled(self):
        section_enabled = self.section.get("enabled", None)

        if isinstance(section_enabled, list):
            for enabled in section_enabled:
                when = enabled["when"]
                when_validator = WhenRuleValidator(
                    when, self.section["id"], self.questionnaire_schema
                )
                self.errors += when_validator.validate()

        elif isinstance(section_enabled, dict):
            when = section_enabled["when"]
            when_validator = NewWhenRuleValidator(
                when, self.section["id"], self.questionnaire_schema
            )
            self.errors += when_validator.validate()
예제 #6
0
def test_validate_answer_value_in_when_rule_invalid():
    when_rule = {"id": "answer-1", "condition": "equals", "value": "Yes"}
    option_value_to_answer_id_map = {
        "answer-1": {"Maybe", "No"},
        "answer-2": {"Yes", "No"},
    }
    questionnaire_schema = QuestionnaireSchema({})
    validator = WhenRuleValidator(when_rule, {}, questionnaire_schema)
    validator.questionnaire_schema.answer_id_to_option_values_map = (
        option_value_to_answer_id_map)

    validator.validate_answer_value_in_when_rule(when_rule)

    assert validator.errors[0] == {
        "message": WhenRuleValidator.INVALID_WHEN_RULE_ANSWER_VALUE,
        "answer_id": "answer-1",
        "value": "Yes",
    }
예제 #7
0
def test_invalid_answer_value_in_when_rule():
    filename = "schemas/invalid/test_invalid_answer_value_in_when_rule.json"
    questionnaire_schema = QuestionnaireSchema(
        _open_and_load_schema_file(filename))
    validator = WhenRuleValidator({}, {}, questionnaire_schema)

    when = {
        "id": "country-checkbox-answer",
        "condition": "contains any",
        "values": ["France", 7, "Italian"],
    }
    expected_error_messages = [{
        "message": WhenRuleValidator.INVALID_WHEN_RULE_ANSWER_VALUE,
        "answer_id": "country-checkbox-answer",
        "value": value,
    } for value in ["France", 7, "Italian"]]

    validator.validate_answer_value_in_when_rule(when)

    assert validator.errors == expected_error_messages
예제 #8
0
def test_answer_comparisons_different_types_skip_group():
    """Ensures that when answer comparison is used, the type of the variables must be the same"""
    when_rule = {
        "id": "comparison-1-answer",
        "condition": "less than",
        "comparison": {
            "id": "comparison-2-answer",
            "source": "answers"
        },
    }
    questionnaire_schema = QuestionnaireSchema({})
    questionnaire_schema.answers_with_context = {
        "comparison-1-answer": {
            "answer": {
                "id": "comparison-1-answer",
                "type": "Number"
            },
            "block": "route-comparison-1",
        },
        "comparison-2-answer": {
            "answer": {
                "id": "comparison-2-answer",
                "type": "TextField"
            },
            "block": "comparison-2",
        },
    }
    validator = WhenRuleValidator(when_rule, {}, questionnaire_schema)
    validator.validate_comparison_in_when_rule(when_rule, "block-id")

    expected_errors = [{
        "message":
        WhenRuleValidator.NON_MATCHING_WHEN_ANSWER_AND_COMPARISON_TYPES,
        "comparison_id": "comparison-2-answer",
        "answer_id": "comparison-1-answer",
        "referenced_id": "block-id",
    }]

    assert expected_errors == validator.errors
예제 #9
0
def test_answer_comparisons_different_types():
    """Ensures that when answer comparison is used, the type of the variables must be the same"""
    when_rule = {
        "id": "comparison-1-answer",
        "condition": "equals any",
        "comparison": {
            "id": "comparison-2-answer",
            "source": "answers"
        },
    }
    questionnaire_schema = QuestionnaireSchema({})
    questionnaire_schema.answers_with_context = {
        "comparison-1-answer": {
            "answer": {
                "id": "comparison-1-answer",
                "type": "Number"
            },
            "block": "route-comparison-1",
        },
        "comparison-2-answer": {
            "answer": {
                "id": "comparison-2-answer",
                "type": "TextField"
            },
            "block": "comparison-2",
        },
    }
    validator = WhenRuleValidator(when_rule, {}, questionnaire_schema)
    validator.validate_comparison_in_when_rule(when_rule, "block-id")

    expected_errors = [{
        "message": WhenRuleValidator.NON_CHECKBOX_COMPARISON_ID,
        "comparison_id": "comparison-2-answer",
        "condition": "equals any",
    }]

    assert expected_errors == validator.errors
 def validate_skip_conditions(self, skip_conditions, origin_id):
     for skip_condition in skip_conditions:
         when_validator = WhenRuleValidator(
             skip_condition["when"], origin_id, self.questionnaire_schema
         )
         self.errors += when_validator.validate()