def test_list_serialisation():
    store = ListStore()

    first_id = store.add_list_item("people")
    second_id = store.add_list_item("people", primary_person=True)
    additional_list_id = store.add_list_item("pets")

    serialized = store.serialize()

    assert serialized == [
        {"name": "people", "primary_person": second_id, "items": [second_id, first_id]},
        {"name": "pets", "items": [additional_list_id]},
    ]
Exemple #2
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)