def test_clear():
    in_progress_sections = [
        {
            "section_id": "s1",
            "list_item_id": None,
            "status": CompletionStatus.COMPLETED,
            "block_ids": ["one", "two"],
        },
        {
            "section_id": "s2",
            "list_item_id": "abc123",
            "status": CompletionStatus.COMPLETED,
            "block_ids": ["three", "four"],
        },
    ]
    store = ProgressStore(in_progress_sections)

    store.clear()

    assert store.serialize() == []
    assert store.is_dirty
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"],
        }),
    ]
Exemplo n.º 3
0
class QuestionnaireStore:
    LATEST_VERSION = 1

    def __init__(self,
                 storage: EncryptedQuestionnaireStorage,
                 version: Optional[int] = None):
        self._storage = storage
        if version is None:
            version = self.get_latest_version_number()
        self.version = version
        self._metadata: dict[str, Any] = {}
        # self.metadata is a read-only view over self._metadata
        self.metadata: Mapping[str, Any] = MappingProxyType(self._metadata)
        self.response_metadata: Mapping[str, Any] = {}
        self.list_store = ListStore()
        self.answer_store = AnswerStore()
        self.progress_store = ProgressStore()
        self.submitted_at: Optional[datetime]
        self.collection_exercise_sid: Optional[str]

        (
            raw_data,
            self.collection_exercise_sid,
            version,
            self.submitted_at,
        ) = 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) -> int:
        return self.LATEST_VERSION

    def set_metadata(self, to_set: dict[str, Any]) -> QuestionnaireStore:
        """
        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: str) -> None:
        json_data = json_loads(data)
        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.response_metadata = json_data.get("RESPONSE_METADATA", {})

    def serialize(self) -> str:
        data = {
            "METADATA": self._metadata,
            "ANSWERS": list(self.answer_store),
            "LISTS": self.list_store.serialize(),
            "PROGRESS": self.progress_store.serialize(),
            "RESPONSE_METADATA": self.response_metadata,
        }
        return json_dumps(data)

    def delete(self) -> None:
        self._storage.delete()
        self._metadata.clear()
        self.response_metadata = {}
        self.answer_store.clear()
        self.progress_store.clear()

    def save(self) -> None:
        data = self.serialize()
        collection_exercise_sid = (self.collection_exercise_sid or
                                   self._metadata["collection_exercise_sid"])
        response_expires_at = self._metadata.get("response_expires_at")
        self._storage.save(
            data=data,
            collection_exercise_sid=collection_exercise_sid,
            submitted_at=self.submitted_at,
            expires_at=parse_iso_8601_datetime(response_expires_at)
            if response_expires_at else None,
        )
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.response_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)
        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.response_metadata = json_data.get("RESPONSE_METADATA", {})

    def serialize(self):
        data = {
            "METADATA": self._metadata,
            "ANSWERS": list(self.answer_store),
            "LISTS": self.list_store.serialize(),
            "PROGRESS": self.progress_store.serialize(),
            "RESPONSE_METADATA": self.response_metadata,
        }
        return json_dumps(data)

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

    def save(self):
        data = self.serialize()
        self._storage.save(data=data)