def test_relationship_answers_not_on_path_in_payload(fake_questionnaire_store): routing_path = [ RoutingPath( ["list-collector", "relationships"], section_id="section", ) ] answer_objects = [ { "answer_id": "first-name", "value": "1", "list_item_id": "person1" }, { "answer_id": "last-name", "value": "1", "list_item_id": "person1" }, { "answer_id": "first-name", "value": "2", "list_item_id": "person2" }, { "answer_id": "last-name", "value": "2", "list_item_id": "person2" }, { "answer_id": "first-name", "value": "3", "list_item_id": "person3" }, { "answer_id": "last-name", "value": "3", "list_item_id": "person3" }, { "answer_id": "first-name", "value": "4", "list_item_id": "person4" }, { "answer_id": "last-name", "value": "4", "list_item_id": "person4" }, { "answer_id": "first-name", "value": "5", "list_item_id": "person5" }, { "answer_id": "last-name", "value": "5", "list_item_id": "person5" }, { "answer_id": "anyone-else", "value": "No" }, { "answer_id": "relationship-answer", "value": [ { "list_item_id": "person1", "to_list_item_id": "person2", "relationship": "Unrelated", }, { "list_item_id": "person1", "to_list_item_id": "person3", "relationship": "Unrelated", }, { "list_item_id": "person1", "to_list_item_id": "person4", "relationship": "Unrelated", }, { "list_item_id": "person1", "to_list_item_id": "person5", "relationship": "Unrelated", }, ], }, { "answer_id": "related-to-anyone-else-answer", "value": "No", "list_item_id": "person1", }, ] answers = AnswerStore(answer_objects) list_store = ListStore(existing_items=[{ "name": "people", "items": [ "person1", "person2", "person3", "person4", "person5", ], }]) fake_questionnaire_store.answer_store = answers fake_questionnaire_store.list_store = list_store schema = load_schema_from_name("test_relationships_unrelated") output = convert_answers(schema, fake_questionnaire_store, routing_path) data = json.loads(json.dumps(output["data"]["answers"], for_json=True)) answers = {(answer["answer_id"], answer.get("list_item_id")): answer for answer in data} expected_relationships_answer = [ { "list_item_id": "person1", "relationship": "Unrelated", "to_list_item_id": "person2", }, { "list_item_id": "person1", "relationship": "Unrelated", "to_list_item_id": "person3", }, { "list_item_id": "person1", "relationship": "Unrelated", "to_list_item_id": "person4", }, { "list_item_id": "person1", "relationship": "Unrelated", "to_list_item_id": "person5", }, ] assert ("related-to-anyone-else-answer", "person1") in answers relationships_answer = answers[("relationship-answer", None)] assert expected_relationships_answer == relationships_answer["value"]
def test_context_for_section_list_summary(people_answer_store): schema = load_schema_from_name("test_list_collector_section_summary") summary_context = SectionSummaryContext( language=DEFAULT_LANGUAGE_CODE, schema=schema, answer_store=people_answer_store, list_store=ListStore( [ {"items": ["PlwgoG", "UHPLbX"], "name": "people"}, {"items": ["gTrlio"], "name": "visitors"}, ] ), progress_store=ProgressStore(), metadata={"display_address": "70 Abingdon Road, Goathill"}, response_metadata={}, current_location=Location(section_id="section"), routing_path=RoutingPath( [ "primary-person-list-collector", "list-collector", "visitor-list-collector", ], section_id="section", ), ) context = summary_context() expected = { "summary": { "answers_are_editable": True, "collapsible": False, "custom_summary": [ { "add_link": "/questionnaire/people/add-person/?return_to=section-summary", "add_link_text": "Add someone to this household", "empty_list_text": "There are no householders", "list": { "editable": True, "list_items": [ { "edit_link": "/questionnaire/people/PlwgoG/edit-person/?return_to=section-summary", "item_title": "Toni Morrison", "primary_person": False, "remove_link": "/questionnaire/people/PlwgoG/remove-person/?return_to=section-summary", "list_item_id": "PlwgoG", }, { "edit_link": "/questionnaire/people/UHPLbX/edit-person/?return_to=section-summary", "item_title": "Barry Pheloung", "primary_person": False, "remove_link": "/questionnaire/people/UHPLbX/remove-person/?return_to=section-summary", "list_item_id": "UHPLbX", }, ], }, "list_name": "people", "title": "Household members staying overnight on 13 October 2019 at 70 Abingdon Road, Goathill", "type": "List", }, { "add_link": "/questionnaire/visitors/add-visitor/?return_to=section-summary", "add_link_text": "Add another visitor to this household", "empty_list_text": "There are no visitors", "list": { "editable": True, "list_items": [ { "edit_link": "/questionnaire/visitors/gTrlio/edit-visitor-person/?return_to=section-summary", "item_title": "", "primary_person": False, "remove_link": "/questionnaire/visitors/gTrlio/remove-visitor/?return_to=section-summary", "list_item_id": "gTrlio", } ], }, "list_name": "visitors", "title": "Visitors staying overnight on 13 October 2019 at 70 Abingdon Road, Goathill", "type": "List", }, ], "page_title": "People who live here and overnight visitors", "summary_type": "SectionSummary", "title": "People who live here and overnight visitors", } } assert context == expected
def test_context_for_driving_question_summary(): schema = load_schema_from_name("test_list_collector_driving_question") summary_context = SectionSummaryContext( DEFAULT_LANGUAGE_CODE, schema, AnswerStore( [ {"answer_id": "anyone-usually-live-at-answer", "value": "Yes"}, {"answer_id": "first-name", "value": "Toni", "list_item_id": "PlwgoG"}, { "answer_id": "last-name", "value": "Morrison", "list_item_id": "PlwgoG", }, ] ), ListStore([{"items": ["PlwgoG"], "name": "people"}]), ProgressStore(), {}, {}, current_location=Location(section_id="section"), routing_path=RoutingPath( ["anyone-usually-live-at", "anyone-else-live-at"], section_id="section" ), ) context = summary_context() expected = { "summary": { "answers_are_editable": True, "collapsible": False, "custom_summary": [ { "add_link": "/questionnaire/people/add-person/?return_to=section-summary", "add_link_text": "Add someone to this household", "empty_list_text": "There are no householders", "list": { "editable": True, "list_items": [ { "item_title": "Toni Morrison", "primary_person": False, "edit_link": "/questionnaire/people/PlwgoG/edit-person/?return_to=section-summary", "remove_link": "/questionnaire/people/PlwgoG/remove-person/?return_to=section-summary", "list_item_id": "PlwgoG", } ], }, "list_name": "people", "title": "Household members", "type": "List", } ], "page_title": "List Collector Driving Question Summary", "summary_type": "SectionSummary", "title": "List Collector Driving Question Summary", } } assert context == expected
def test_invalid_date_range_and_single_date_periods(self): with self.app_request_context(): store = AnswerStore() test_answer_id = Answer(answer_id="date", value="2017-03-20") store.add_or_update(test_answer_id) schema = load_schema_from_name("test_date_validation_range") question_schema = { "id": "date-range-question", "type": "DateRange", "answers": [ { "id": "date-range-from", "label": "Period from", "mandatory": True, "type": "Date", "minimum": { "value": "2018-01-10", "offset_by": { "days": -5 } }, }, { "id": "date-range-to", "label": "Period to", "mandatory": True, "type": "Date", "maximum": { "value": { "identifier": "date", "source": "answers" }, "offset_by": { "days": 5 }, }, }, ], } data = { "date-range-from-day": "6", "date-range-from-month": "1", "date-range-from-year": "2018", "date-range-to-day": "15", "date-range-to-month": "1", "date-range-to-year": "2018", } metadata = {"schema_name": "test_date_validation_range"} form = generate_form(schema, question_schema, store, metadata=metadata, formdata=data) with self.assertRaises(Exception) as ite: with patch( "app.questionnaire.questionnaire_schema.QuestionnaireSchema.get_all_questions_for_block", return_value=[question_schema], ): form.validate() self.assertEqual( "The schema has invalid date answer limits for date-range-question", str(ite.exception), )
def get_schema_json_from_name(schema_name): try: schema = load_schema_from_name(schema_name) return jsonify(schema.json) except FileNotFoundError: return "Schema Not Found", 404
def setUp(self): super().setUp() self.schema = load_schema_from_name("test_calculated_summary") answers = [ { "value": 1, "answer_id": "first-number-answer" }, { "value": 2, "answer_id": "second-number-answer" }, { "value": 3, "answer_id": "second-number-answer-unit-total" }, { "value": 4, "answer_id": "second-number-answer-also-in-total" }, { "value": 5, "answer_id": "third-number-answer" }, { "value": 6, "answer_id": "third-and-a-half-number-answer-unit-total" }, { "value": "No", "answer_id": "skip-fourth-block-answer" }, { "value": 7, "answer_id": "fourth-number-answer" }, { "value": 8, "answer_id": "fourth-and-a-half-number-answer-also-in-total" }, { "value": 9, "answer_id": "fifth-percent-answer" }, { "value": 10, "answer_id": "fifth-number-answer" }, { "value": 11, "answer_id": "sixth-percent-answer" }, { "value": 12, "answer_id": "sixth-number-answer" }, ] self.answer_store = AnswerStore(answers) self.list_store = ListStore() self.progress_store = ProgressStore() self.block_type = "CalculatedSummary"
def test_invalid_maximum_period_limit_and_single_date_periods(self): with self.app_request_context(): schema = load_schema_from_name("test_date_validation_range") question_schema = schema.get_block("date-range-block").get( "question") question_schema = { "id": "date-range-question", "type": "DateRange", "period_limits": { "maximum": { "days": 8 } }, "answers": [ { "id": "date-range-from", "label": "Period from", "mandatory": True, "type": "Date", "minimum": { "value": "2018-01-10", "offset_by": { "days": -5 } }, }, { "id": "date-range-to", "label": "Period to", "mandatory": True, "type": "Date", "maximum": { "value": "2018-01-10", "offset_by": { "days": 5 } }, }, ], } data = { "date-range-from-day": "6", "date-range-from-month": "1", "date-range-from-year": "2018", "date-range-to-day": "15", "date-range-to-month": "1", "date-range-to-year": "2018", } form = generate_form(schema, question_schema, AnswerStore(), metadata=None, formdata=data) with self.assertRaises(Exception) as ite: with patch( "app.questionnaire.questionnaire_schema.QuestionnaireSchema.get_all_questions_for_block", return_value=[question_schema], ): form.validate() self.assertEqual( "The schema has invalid period_limits for date-range-question", str(ite.exception), )
def test_load_schema_with_language_code(self): self.assertIsNotNone( load_schema_from_name("test_language", language_code="cy"))
def test_load_schema_from_name(self): self.assertIsNotNone(load_schema_from_name("test_checkbox"))
def test_load_schema_with_invalid_schema_name(self): with self.assertRaises(FileNotFoundError): load_schema_from_name("test_0309")
def test_load_schema_with_passing_default_language_code(self): self.assertIsNotNone( load_schema_from_name("test_language", language_code="en"))
def default_placeholder_value_schema(): return load_schema_from_name("test_placeholder_default_value", "en")
def option_label_from_value_schema(): return load_schema_from_name("test_placeholder_option_label_from_value", "en")
def test_is_not_complete(self): self.schema = load_schema_from_name("test_textfield") is_questionnaire_complete = self.router.is_questionnaire_complete self.assertFalse(is_questionnaire_complete)
def test_primary_person_not_in_payload_when_not_answered( fake_questionnaire_store): routing_path = [ RoutingPath( [ "list-collector", "next-interstitial", "another-list-collector-block" ], section_id="section-1", ) ] answer_objects = [ { "answer_id": "first-name", "value": "1", "list_item_id": "xJlKBy" }, { "answer_id": "last-name", "value": "1", "list_item_id": "xJlKBy" }, { "answer_id": "first-name", "value": "2", "list_item_id": "RfAGDc" }, { "answer_id": "last-name", "value": "2", "list_item_id": "RfAGDc" }, { "answer_id": "anyone-else", "value": "No" }, { "answer_id": "another-anyone-else", "value": "No" }, { "answer_id": "extraneous-answer", "value": "Bad", "list_item_id": "123" }, ] answers = AnswerStore(answer_objects) list_store = ListStore(existing_items=[{ "name": "people", "items": ["xJlKBy", "RfAGDc"] }]) fake_questionnaire_store.answer_store = answers fake_questionnaire_store.list_store = list_store schema = load_schema_from_name("test_list_collector") output = convert_answers(schema, fake_questionnaire_store, routing_path) data_dict = json.loads(json.dumps(output["data"]["lists"], for_json=True)) assert "primary_person" not in data_dict[0]
def test_load_schema_with_different_schema_name(self): self.assertIsNotNone(load_schema_from_name("test_dates"))
def test_relationships_in_payload(fake_questionnaire_store): routing_path = [ RoutingPath( ["list-collector", "relationships"], section_id="section", ) ] answer_objects = [ { "answer_id": "first-name", "value": "1", "list_item_id": "person1" }, { "answer_id": "last-name", "value": "1", "list_item_id": "person1" }, { "answer_id": "first-name", "value": "2", "list_item_id": "person2" }, { "answer_id": "last-name", "value": "2", "list_item_id": "person2" }, { "answer_id": "first-name", "value": "3", "list_item_id": "person3" }, { "answer_id": "last-name", "value": "3", "list_item_id": "person3" }, { "answer_id": "anyone-else", "value": "No" }, { "answer_id": "relationship-answer", "value": [ { "list_item_id": "person1", "to_list_item_id": "person2", "relationship": "Husband or Wife", }, { "list_item_id": "person1", "to_list_item_id": "person3", "relationship": "Son or daughter", }, ], }, ] answers = AnswerStore(answer_objects) list_store = ListStore( existing_items=[{ "name": "people", "items": [ "person1", "person2", "person3", ], }]) fake_questionnaire_store.answer_store = answers fake_questionnaire_store.list_store = list_store schema = load_schema_from_name("test_relationships") output = convert_answers(schema, fake_questionnaire_store, routing_path) data = json.loads(json.dumps(output["data"]["answers"], for_json=True)) answers = {answer["answer_id"]: answer for answer in data} expected_relationships_answer = [ { "list_item_id": "person1", "relationship": "Husband or Wife", "to_list_item_id": "person2", }, { "list_item_id": "person1", "relationship": "Son or daughter", "to_list_item_id": "person3", }, ] relationships_answer = answers["relationship-answer"] assert expected_relationships_answer == relationships_answer["value"]
def test_context_for_section_list_summary(people_answer_store): schema = load_schema_from_name("test_list_collector_section_summary") current_location = Location( block_id="people-list-section-summary", section_id="section" ) list_collector_summary_context = ListCollectorSummaryContext( language=DEFAULT_LANGUAGE_CODE, schema=schema, answer_store=people_answer_store, list_store=ListStore( [ {"items": ["PlwgoG", "UHPLbX"], "name": "people"}, {"items": ["gTrlio"], "name": "visitors"}, ] ), progress_store=ProgressStore(), metadata={"display_address": "70 Abingdon Road, Goathill"}, ) context = list_collector_summary_context.get_list_summaries(current_location) expected = [ { "add_link": "/questionnaire/people/add-person/?return_to=people-list-section-summary", "add_link_text": "Add someone to this household", "empty_list_text": "There are no householders", "list": { "list_items": [ { "edit_link": "/questionnaire/people/PlwgoG/edit-person/?return_to=people-list-section-summary", "item_title": "Toni Morrison", "primary_person": False, "remove_link": "/questionnaire/people/PlwgoG/remove-person/?return_to=people-list-section-summary", }, { "edit_link": "/questionnaire/people/UHPLbX/edit-person/?return_to=people-list-section-summary", "item_title": "Barry Pheloung", "primary_person": False, "remove_link": "/questionnaire/people/UHPLbX/remove-person/?return_to=people-list-section-summary", }, ], "editable": True, }, "title": "Household members staying overnight on 13 October 2019 at 70 Abingdon Road, Goathill", "list_name": "people", }, { "add_link": "/questionnaire/visitors/add-visitor/?return_to=people-list-section-summary", "add_link_text": "Add another visitor to this household", "empty_list_text": "There are no visitors", "list": { "list_items": [ { "edit_link": "/questionnaire/visitors/gTrlio/edit-visitor-person/?return_to=people-list-section-summary", "item_title": "", "primary_person": False, "remove_link": "/questionnaire/visitors/gTrlio/remove-visitor/?return_to=people-list-section-summary", } ], "editable": True, }, "title": "Visitors staying overnight on 13 October 2019 at 70 Abingdon Road, Goathill", "list_name": "visitors", }, ] assert context == expected