Example #1
0
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
Example #2
0
    def test_update_same_name_items(self):
        answer_store = AnswerStore(existing_answers=[
            {
                "answer_id": "first-name",
                "value": "Joe",
                "list_item_id": "abcdef"
            },
            {
                "answer_id": "middle-name",
                "value": "Brian",
                "list_item_id": "abcdef",
            },
            {
                "answer_id": "last-name",
                "value": "Bloggs",
                "list_item_id": "abcdef"
            },
            {
                "answer_id": "first-name",
                "value": "Joe",
                "list_item_id": "ghijkl"
            },
            {
                "answer_id": "middle-name",
                "value": "Roger",
                "list_item_id": "ghijkl",
            },
            {
                "answer_id": "last-name",
                "value": "Bloggs",
                "list_item_id": "ghijkl"
            },
            {
                "answer_id": "first-name",
                "value": "Martha",
                "list_item_id": "xyzabc",
            },
            {
                "answer_id": "last-name",
                "value": "Bloggs",
                "list_item_id": "xyzabc"
            },
        ])
        list_store = fake_list_store()

        questionnaire_store = MagicMock(
            spec=QuestionnaireStore,
            completed_blocks=[],
            answer_store=answer_store,
            list_store=list_store,
            progress_store=ProgressStore(),
        )

        questionnaire_store_updater = QuestionnaireStoreUpdater(
            self.location, self.schema, questionnaire_store,
            self.current_question)

        questionnaire_store_updater.update_same_name_items(
            "people", ["first-name", "last-name"])

        assert "abcdef" in list_store["people"].same_name_items
        assert "ghijkl" in list_store["people"].same_name_items
Example #3
0
class QuestionnaireStore:
    LATEST_VERSION = 1

    def __init__(self, storage, version=None):
        self._storage = storage
        if version is None:
            version = self.get_latest_version_number()
        self.version = version
        self._metadata = {}
        # self.metadata is a read-only view over self._metadata
        self.metadata = MappingProxyType(self._metadata)
        self.collection_metadata = {}
        self.list_store = ListStore()
        self.answer_store = AnswerStore()
        self.progress_store = ProgressStore()

        raw_data, version = self._storage.get_user_data()
        if raw_data:
            self._deserialize(raw_data)
        if version is not None:
            self.version = version

    def get_latest_version_number(self):
        return self.LATEST_VERSION

    def set_metadata(self, to_set):
        """
        Set metadata. This should only be used where absolutely necessary.
        Metadata should normally be read only.
        """
        self._metadata = to_set
        self.metadata = MappingProxyType(self._metadata)

        return self

    def _deserialize(self, data):
        json_data = json.loads(data, use_decimal=True)
        self.progress_store = ProgressStore(json_data.get("PROGRESS"))
        self.set_metadata(json_data.get("METADATA", {}))
        self.answer_store = AnswerStore(json_data.get("ANSWERS"))
        self.list_store = ListStore.deserialize(json_data.get("LISTS"))
        self.collection_metadata = json_data.get("COLLECTION_METADATA", {})

    def serialize(self):
        data = {
            "METADATA": self._metadata,
            "ANSWERS": list(self.answer_store),
            "LISTS": self.list_store.serialize(),
            "PROGRESS": self.progress_store.serialize(),
            "COLLECTION_METADATA": self.collection_metadata,
        }
        return json.dumps(data, for_json=True)

    def delete(self):
        self._storage.delete()
        self._metadata.clear()
        self.collection_metadata = {}
        self.answer_store.clear()
        self.progress_store.clear()

    def save(self):
        data = self.serialize()
        self._storage.save(data=data)
def test_serialisation():
    store = ProgressStore()

    store.add_completed_location(Location(section_id="s1", block_id="one"))
    store.add_completed_location(Location(section_id="s1", block_id="two"))
    store.update_section_status(section_status=CompletionStatus.COMPLETED,
                                section_id="s1")

    store.add_completed_location(
        Location(
            section_id="s2",
            block_id="another-one",
            list_name="people",
            list_item_id="abc123",
        ))
    store.update_section_status(
        section_status=CompletionStatus.IN_PROGRESS,
        section_id="s2",
        list_item_id="abc123",
    )

    serialized = store.serialize()

    assert serialized == [
        Progress.from_dict({
            "section_id": "s1",
            "list_item_id": None,
            "status": CompletionStatus.COMPLETED,
            "block_ids": ["one", "two"],
        }),
        Progress.from_dict({
            "section_id": "s2",
            "list_item_id": "abc123",
            "status": CompletionStatus.IN_PROGRESS,
            "block_ids": ["another-one"],
        }),
    ]
class TestRouterLastLocationLinearFlow(RouterTestCase):
    def test_block_on_path(self):
        self.schema = load_schema_from_name("test_checkbox")
        self.progress_store = ProgressStore([{
            "section_id":
            "default-section",
            "block_ids": [
                "mandatory-checkbox",
                "non-mandatory-checkbox",
                "single-checkbox",
            ],
            "status":
            CompletionStatus.COMPLETED,
        }])
        last_location_url = self.router.get_last_location_in_questionnaire_url(
        )
        expected_location_url = Location(section_id="default-section",
                                         block_id="single-checkbox",
                                         list_item_id=None).url()

        self.assertEqual(expected_location_url, last_location_url)

    def test_last_block_not_on_path(self):
        self.schema = load_schema_from_name(
            "test_new_routing_to_questionnaire_end_multiple_sections")
        self.answer_store = AnswerStore([
            {
                "answer_id": "test-answer",
                "value": "No"
            },
            {
                "answer_id": "test-optional-answer",
                "value": "I am a completionist",
            },
        ])
        section_id = "test-section"
        last_block_on_path = "test-forced"
        completed_block_not_on_path = "test-optional"
        self.progress_store = ProgressStore([{
            "section_id":
            section_id,
            "block_ids": [last_block_on_path, completed_block_not_on_path],
            "status":
            CompletionStatus.COMPLETED,
        }])

        expected_location_url = Location(
            section_id=section_id,
            block_id=last_block_on_path,
            list_item_id=None,
        ).url()

        last_completed_block_in_progress_store = (
            self.progress_store.get_completed_block_ids(section_id=section_id,
                                                        list_item_id=None)[-1])

        last_location_url = self.router.get_last_location_in_questionnaire_url(
        )

        self.assertEqual(completed_block_not_on_path,
                         last_completed_block_in_progress_store)
        self.assertEqual(expected_location_url, last_location_url)
Example #6
0
def progress_store():
    return ProgressStore()
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
Example #8
0
 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"