def test_answer_comparisons_different_types(): """ Ensures that when answer comparison is used, the type of the variables must be the same """ filename = "schemas/invalid/test_invalid_answer_comparison_types.json" questionnaire_schema = QuestionnaireSchema( _open_and_load_schema_file(filename)) group = questionnaire_schema.get_group("route-group") block = questionnaire_schema.get_block("route-comparison-2") validator = RoutingValidator(block, group, questionnaire_schema) validator.validate() expected_errors = [ { "message": WhenRuleValidator.NON_MATCHING_WHEN_ANSWER_AND_COMPARISON_TYPES, "comparison_id": "route-comparison-1-answer", "answer_id": "route-comparison-2-answer", "referenced_id": "route-comparison-2", }, { "message": WhenRuleValidator.NON_CHECKBOX_COMPARISON_ID, "comparison_id": "route-comparison-2-answer", "condition": "equals any", }, ] assert expected_errors == validator.errors
def test_get_sub_block_context(): filename = "schemas/valid/test_list_collector_driving_question.json" questionnaire_schema = QuestionnaireSchema(_open_and_load_schema_file(filename)) assert [ (question["id"], context) for question, context in questionnaire_schema.questions_with_context ] == [ ( "anyone-usually-live-at-question", { "group_id": "group", "section": "section", "block": "anyone-usually-live-at", }, ), ( "confirmation-question", {"group_id": "group", "section": "section", "block": "anyone-else-live-at"}, ), ( "add-question", {"group_id": "group", "section": "section", "block": "add-person"}, ), ( "edit-question", {"group_id": "group", "section": "section", "block": "edit-person"}, ), ( "remove-question", {"group_id": "group", "section": "section", "block": "remove-person"}, ), ]
def test_get_context_from_match(): filename = "schemas/valid/test_question_variants.json" questionnaire_schema = QuestionnaireSchema(_open_and_load_schema_file(filename)) matches = parse("$..blocks[*]").find(questionnaire_schema.schema) context = get_context_from_match(matches[0]) assert context == {"section": "section", "group_id": "group", "block": "block-1"}
def test_returns_pointer(): file = "schemas/invalid/test_invalid_survey_id_whitespace.json" json_to_validate = _open_and_load_schema_file(file) validator = SchemaValidator(json_to_validate) validator.validate() assert validator.errors[0]["pointer"] == "/survey_id"
def test_single_variant_invalid(): file_name = "schemas/invalid/test_invalid_single_variant.json" validator = SchemaValidator(_open_and_load_schema_file(file_name)) validator.validate() assert validator.errors[0]["message"] == "'when' is a required property" assert len(validator.errors) == 1
def test_invalid_survey_id_whitespace(): file = "schemas/invalid/test_invalid_survey_id_whitespace.json" json_to_validate = _open_and_load_schema_file(file) validator = SchemaValidator(json_to_validate) validator.validate() assert validator.errors[0][ "message"] == "'lms ' does not match '^[0-9a-z]+$'"
def test_questions_with_context(): filename = "schemas/valid/test_question_variants.json" questionnaire_schema = QuestionnaireSchema(_open_and_load_schema_file(filename)) assert list(questionnaire_schema.questions_with_context) == [ ( { "id": "question-1", "type": "General", "title": "What is your age?", "answers": [ { "id": "answer-1", "label": "Your age?", "mandatory": False, "type": "Number", } ], }, {"group_id": "group", "section": "section", "block": "block-1"}, ), ( { "id": "question-2", "type": "General", "title": "What is your age?", "answers": [ { "id": "answer-2", "label": "Your age?", "mandatory": False, "type": "Number", } ], }, {"group_id": "group", "section": "section", "block": "block-2"}, ), ( { "id": "question-2", "type": "General", "title": "What is your age?", "answers": [ { "id": "answer-2", "label": "Your age?", "mandatory": False, "type": "Number", } ], }, {"group_id": "group", "section": "section", "block": "block-2"}, ), ]
def test_get_other_blocks(): filename = "schemas/valid/test_list_collector.json" questionnaire_schema = QuestionnaireSchema(_open_and_load_schema_file(filename)) other_list_collectors = questionnaire_schema.get_other_blocks( block_id_to_filter="list-collector", type="ListCollector", for_list="people" ) assert len(other_list_collectors) == 1 assert other_list_collectors[0]["id"] == "another-list-collector"
def test_invalid_calculated_summary(): """Asserts invalid `when` types, currencies or units are not of the same type for CalculatedSummary""" filename = "schemas/invalid/test_invalid_calculated_summary.json" json_to_validate = _open_and_load_schema_file(filename) expected_error_messages = [ { "message": CalculatedSummaryBlockValidator.ANSWERS_MUST_HAVE_SAME_TYPE, "block_id": "total-playback-type-error", }, { "message": CalculatedSummaryBlockValidator.ANSWERS_MUST_HAVE_SAME_CURRENCY, "block_id": "total-playback-currency-error", }, { "message": CalculatedSummaryBlockValidator.ANSWERS_MUST_HAVE_SAME_UNIT, "block_id": "total-playback-unit-error", }, { "message": CalculatedSummaryBlockValidator.ANSWERS_HAS_INVALID_ID, "answer_id": "seventh-number-answer", "block_id": "total-playback-answer-error", }, { "message": CalculatedSummaryBlockValidator.ANSWERS_HAS_DUPLICATES, "block_id": "total-playback-duplicate-error", "duplicate_answers": ["fourth-number-answer", "sixth-number-answer"], }, { "message": CalculatedSummaryBlockValidator.ANSWERS_MUST_HAVE_SAME_TYPE, "block_id": "total-playback-duplicate-error", }, ] questionnaire_schema = QuestionnaireSchema(json_to_validate) errors = [] for block_id in [ "total-playback-type-error", "total-playback-currency-error", "total-playback-unit-error", "total-playback-answer-error", "total-playback-duplicate-error", ]: block = questionnaire_schema.get_block(block_id) validator = CalculatedSummaryBlockValidator(block, questionnaire_schema) errors += validator.validate() assert errors == expected_error_messages
def test_get_blocks(): filename = "schemas/valid/test_list_collector_driving_question.json" questionnaire_schema = QuestionnaireSchema( _open_and_load_schema_file(filename)) driving_question_blocks = questionnaire_schema.get_blocks( type="ListCollectorDrivingQuestion", for_list="people") assert len(driving_question_blocks) == 1 assert driving_question_blocks[0]["id"] == "anyone-usually-live-at"
def test_invalid_list_collector_non_radio(): filename = "schemas/invalid/test_invalid_list_collector_non_radio.json" questionnaire_schema = QuestionnaireSchema( _open_and_load_schema_file(filename)) validator = ListCollectorValidator( questionnaire_schema.get_block("list-collector"), questionnaire_schema) validator.validate() expected_error_messages = [{ "message": validator.NO_RADIO_FOR_LIST_COLLECTOR, "block_id": "list-collector" }] assert expected_error_messages == validator.errors
def test_invalid_hub_and_spoke_and_summary_confirmation_non_existent(): filename = "schemas/invalid/test_invalid_hub_and_spoke_and_summary_confirmation_non_existent.json" questionnaire_schema = QuestionnaireSchema( _open_and_load_schema_file(filename)) section = questionnaire_schema.get_section("accommodation-section") validator = SectionValidator(section, questionnaire_schema) expected_errors = [{ "section_id": "accommodation-section", "message": SectionValidator.UNDEFINED_SUBMISSION_PAGE, }] validator.validate() assert validator.errors == expected_errors
def test_invalid_list_collector_with_different_add_block_answer_ids(): filename = "schemas/invalid/test_invalid_list_collector_with_different_add_block_answer_ids.json" questionnaire_schema = QuestionnaireSchema( _open_and_load_schema_file(filename)) block = questionnaire_schema.get_block("list-collector") validator = ListCollectorValidator(block, questionnaire_schema) validator.validate() expected_errors = [{ "message": validator.NON_UNIQUE_ANSWER_ID_FOR_LIST_COLLECTOR_ADD, "list_name": "people", "block_id": "list-collector", }] assert expected_errors == validator.errors
def test_invalid_relationship_multiple_answers(): filename = "schemas/invalid/test_invalid_relationship_multiple_answers.json" questionnaire_schema = QuestionnaireSchema( _open_and_load_schema_file(filename)) block = questionnaire_schema.get_block("relationships") validator = RelationshipCollectorValidator(block, questionnaire_schema) expected_errors = [{ "message": validator.RELATIONSHIP_COLLECTOR_HAS_MULTIPLE_ANSWERS, "block_id": "relationships", }] validator.validate() assert validator.errors == expected_errors
def test_invalid_driving_question_multiple_driving_questions(): filename = "schemas/invalid/test_invalid_list_collector_driving_question_multiple_driving_questions.json" questionnaire_schema = QuestionnaireSchema( _open_and_load_schema_file(filename)) block = questionnaire_schema.get_block("anyone-usually-live-at") validator = ListCollectorDrivingQuestionValidator(block, questionnaire_schema) expected_error_messages = [{ "message": validator.MULTIPLE_DRIVING_QUESTIONS_FOR_LIST, "block_id": "anyone-usually-live-at", "for_list": "people", }] assert expected_error_messages == validator.validate()
def test_invalid_list_collector_with_different_answer_ids_in_add_and_edit(): filename = "schemas/invalid/test_invalid_list_collector_with_different_answer_ids_in_add_and_edit.json" questionnaire_schema = QuestionnaireSchema( _open_and_load_schema_file(filename)) block = questionnaire_schema.get_block("list-collector") validator = ListCollectorValidator(block, questionnaire_schema) expected_errors = [{ "message": validator.LIST_COLLECTOR_ADD_EDIT_IDS_DONT_MATCH, "block_id": "list-collector", }] validator.validate() assert validator.errors == expected_errors
def test_invalid_list_collector_same_name_answer_id_reference(): filename = "schemas/invalid/test_invalid_list_collector_same_name_answer_ids.json" questionnaire_schema = QuestionnaireSchema( _open_and_load_schema_file(filename)) validator = ListCollectorValidator( questionnaire_schema.get_block("list-collector"), questionnaire_schema) validator.validate() expected_errors = [{ "message": validator.MISSING_SAME_NAME_ANSWER_ID, "block_id": "list-collector", "answer_id": "surname", }] assert expected_errors == validator.errors
def test_invalid_primary_person_list_collector_with_no_add_or_edit_answer_action( ): filename = "schemas/invalid/test_invalid_primary_person_list_collector_no_add_edit_action.json" questionnaire_schema = QuestionnaireSchema( _open_and_load_schema_file(filename)) block = questionnaire_schema.get_block("primary-person-list-collector") validator = PrimaryPersonListCollectorValidator(block, questionnaire_schema) expected_errors = [{ "message": validator.NO_REDIRECT_TO_LIST_ADD_BLOCK, "block_id": "primary-person-list-collector", }] assert validator.validate() == expected_errors
def test_invalid_list_reference_in_custom_summary(): filename = "schemas/invalid/test_invalid_custom_list_summary.json" questionnaire_schema = QuestionnaireSchema( _open_and_load_schema_file(filename)) section = questionnaire_schema.get_section("section") validator = SectionValidator(section, questionnaire_schema) expected_errors = [{ "message": error_messages.FOR_LIST_NEVER_POPULATED, "list_name": "household", "section_id": "section", }] validator.validate() assert validator.errors == expected_errors
def test_invalid_actions(): filename = "schemas/invalid/test_invalid_relationships_unrelated.json" questionnaire_schema = QuestionnaireSchema( _open_and_load_schema_file(filename)) block = questionnaire_schema.get_block("relationships").get( "unrelated_block") validator = UnrelatedBlockValidator(block, questionnaire_schema) expected_errors = [{ "message": validator.ACTION_PARAMS_MISSING, "block_id": "related-to-anyone-else", }] validator.validate() assert validator.errors == expected_errors
def test_invalid_list_collector_with_no_remove_answer_action(): filename = ( "schemas/invalid/test_invalid_list_collector_with_no_remove_answer_action.json" ) questionnaire_schema = QuestionnaireSchema( _open_and_load_schema_file(filename)) validator = ListCollectorValidator( questionnaire_schema.get_block("list-collector"), questionnaire_schema) validator.validate() expected_errors = [{ "message": validator.NO_REMOVE_LIST_ITEM_AND_ANSWERS_ACTION, "block_id": "list-collector", }] assert expected_errors == validator.errors
def test_invalid_answer_action_redirect_to_list_add_block_unexpected_params(): filename = "schemas/invalid/test_invalid_answer_action_redirect_to_list_add_block_unexpected_params.json" questionnaire_schema = QuestionnaireSchema(_open_and_load_schema_file(filename)) validator = BlockValidator( questionnaire_schema.get_block("list-collector"), questionnaire_schema ) expected_error_messages = [ { "message": validator.ACTION_PARAMS_SHOULDNT_EXIST, "block_id": "list-collector", } ] validator.validate() assert expected_error_messages == validator.errors
def test_primary_person_invalid_list_collector_non_radio(): filename = ( "schemas/invalid/test_invalid_primary_person_list_collector_no_radio.json" ) questionnaire_schema = QuestionnaireSchema( _open_and_load_schema_file(filename)) validator = PrimaryPersonListCollectorValidator( questionnaire_schema.get_block("primary-person-list-collector"), questionnaire_schema, ) expected_errors = [{ "message": validator.NO_RADIO_FOR_PRIMARY_PERSON_LIST_COLLECTOR, "block_id": "primary-person-list-collector", }] assert expected_errors == validator.validate()
def test_invalid_use_of_id_relationships_with_type(): filename = "schemas/invalid/test_invalid_use_of_block_id_relationships.json" questionnaire_schema = QuestionnaireSchema(_open_and_load_schema_file(filename)) validator = BlockValidator( questionnaire_schema.get_block("relationships"), questionnaire_schema ) expected_error_messages = [ { "message": validator.ID_RELATIONSHIPS_NOT_USED_WITH_RELATIONSHIP_COLLECTOR, "block_id": "relationships", } ] validator.validate() assert expected_error_messages == validator.errors
def test_invalid_hub_and_spoke_with_summary_confirmation(): filename = ( "schemas/invalid/test_invalid_hub_and_spoke_with_summary_confirmation.json" ) questionnaire_schema = QuestionnaireSchema( _open_and_load_schema_file(filename)) section = questionnaire_schema.get_section("accommodation-section") validator = SectionValidator(section, questionnaire_schema) expected_errors = [{ "message": SectionValidator.MULTIPLE_SUBMISSION_PAGES, "section_id": "accommodation-section", }] validator.validate() assert validator.errors == expected_errors
def test_invalid_answer_action_redirect_to_list_add_block_no_params(): filename = "schemas/invalid/test_invalid_answer_action_redirect_to_list_add_block_no_params.json" questionnaire_schema = QuestionnaireSchema(_open_and_load_schema_file(filename)) validator = BlockValidator( questionnaire_schema.get_block("anyone-else-live-here-block"), questionnaire_schema, ) expected_error_messages = [ { "message": validator.ACTION_PARAMS_MISSING, "block_id": "anyone-else-live-here-block", } ] validator.validate() assert expected_error_messages == validator.errors
def test_invalid_placeholder_list_reference(): filename = "schemas/invalid/test_invalid_placeholder_plurals.json" questionnaire_schema = QuestionnaireSchema(_open_and_load_schema_file(filename)) validator = BlockValidator( questionnaire_schema.get_block("block1"), questionnaire_schema ) validator.validate_list_source_reference(["people"]) expected_errors = [ { "message": BlockValidator.LIST_REFERENCE_INVALID, "block_id": "block1", "id": "people", } ] assert expected_errors == validator.errors
def test_invalid_primary_person_list_collector_with_different_add_block_answer_ids( ): filename = "schemas/invalid/test_invalid_primary_person_list_collector_different_answer_ids_multi_collectors.json" questionnaire_schema = QuestionnaireSchema( _open_and_load_schema_file(filename)) block = questionnaire_schema.get_block("primary-person-list-collector") validator = PrimaryPersonListCollectorValidator(block, questionnaire_schema) expected_errors = [{ "message": validator.NON_UNIQUE_ANSWER_ID_FOR_PRIMARY_LIST_COLLECTOR_ADD_OR_EDIT, "list_name": "people", "block_id": "primary-person-list-collector", }] assert expected_errors == validator.validate()
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
def test_questions_with_context(): filename = "schemas/valid/test_question_variants.json" questionnaire_schema = QuestionnaireSchema( _open_and_load_schema_file(filename)) assert list(questionnaire_schema.questions_with_context) == [ ( { "id": "question-1", "type": "General", "title": "Are you answering for yourself", "answers": [{ "type": "Radio", "id": "answer-1", "mandatory": True, "options": [ { "label": "Yes", "value": "Yes" }, { "label": "No", "value": "No" }, ], }], }, { "section": "section", "block": "block-1", "group_id": "group" }, ), ( { "id": "question-2", "type": "General", "title": "Are you in full time education?", "answers": [{ "type": "Radio", "id": "answer-2", "mandatory": False, "options": [ { "label": "Yes", "value": "Yes" }, { "label": "No", "value": "No" }, ], }], }, { "section": "section", "block": "block-2", "group_id": "group" }, ), ( { "id": "question-2", "type": "General", "title": "Is the person your are answering for in full time education?", "answers": [{ "type": "Radio", "id": "answer-2", "mandatory": False, "options": [ { "label": "Yes", "value": "Yes" }, { "label": "No", "value": "No" }, ], }], }, { "section": "section", "block": "block-2", "group_id": "group" }, ), ]