예제 #1
0
    def test_save_participant_with_properties_error(self,
                                                    create_properties_mock,
                                                    create_node_mock):
        id_node = 1
        create_node_mock.return_value = {
            'id': id_node,
            'properties': None,
            "errors": None,
            'links': None
        }
        create_properties_mock.return_value = {
            'id': id_node,
            'errors': ['error'],
            'links': None
        }
        participant = ParticipantIn(name="Test Test", sex='male')
        participant_service = ParticipantService()

        result = participant_service.save_participant(participant)

        self.assertEqual(
            result,
            ParticipantOut(name="Test Test", sex='male', errors=['error']))
        create_node_mock.assert_called_once_with('Participant')
        create_properties_mock.assert_called_once_with(id_node, participant)
예제 #2
0
    def test_update_participant_without_error(self, get_node_relationships_mock, delete_node_properties_mock,
                                              get_node_mock, create_properties_mock):
        id_node = 1
        create_properties_mock.return_value = {}
        delete_node_properties_mock.return_value = {}
        get_node_mock.return_value = {'id': id_node, 'labels': ['Participant'],
                                      'properties': [{'key': 'name', 'value': 'test'},
                                                     {'key': 'sex', 'value': 'male'},
                                                     {'key': 'identifier', 'value': 5}],
                                      "errors": None, 'links': None}
        get_node_relationships_mock.return_value = {"relationships": [
                                                    {"start_node": id_node, "end_node": 19,
                                                     "name": "testRelation", "id": 0,
                                                     "properties": None},
                                                    {"start_node": 15, "end_node": id_node,
                                                     "name": "testReversedRelation", "id": 0,
                                                     "properties": None}]}
        additional_properties = [PropertyIn(key='identifier', value=5)]
        participant_in = ParticipantIn(name="test", sex='male', additional_properties=additional_properties)
        participant_out = ParticipantOut(name="test", sex='male', id=id_node,
                                         additional_properties=additional_properties, relations=
                                             [RelationInformation(second_node_id=19, name="testRelation", relation_id=0)],
                                             reversed_relations=
                                             [RelationInformation(second_node_id=15, name="testReversedRelation",
                                                                  relation_id=0)])
        participant_service = ParticipantService()

        result = participant_service.update_participant(id_node, participant_in)

        self.assertEqual(result, participant_out)
        get_node_mock.assert_called_once_with(id_node)
        create_properties_mock.assert_called_once_with(id_node, participant_in)
    def test_get_participants_empty(self, get_nodes_mock):
        get_nodes_mock.return_value = {'nodes': []}
        participants = ParticipantsOut(participant=[])
        participant_service = ParticipantService()

        result = participant_service.get_participants()

        self.assertEqual(result, participants)
        get_nodes_mock.assert_called_once_with("Participant")
예제 #4
0
    def test_delete_participant_with_error(self, get_node_mock):
        id_node = 1
        get_node_mock.return_value = {'id': id_node, 'errors': ['error'], 'links': None}
        not_found = NotFoundByIdModel(id=id_node, errors=['error'])
        participant_service = ParticipantService()

        result = participant_service.delete_participant(id_node)

        self.assertEqual(result, not_found)
        get_node_mock.assert_called_once_with(id_node)
예제 #5
0
    def test_delete_participant_without_participant_label(self, get_node_mock):
        id_node = 1
        get_node_mock.return_value = {'id': id_node, 'labels': ['Test'], 'properties': None,
                                      "errors": None, 'links': None}
        not_found = NotFoundByIdModel(id=id_node, errors="Node not found.")
        participant_service = ParticipantService()

        result = participant_service.delete_participant(id_node)

        self.assertEqual(result, not_found)
        get_node_mock.assert_called_once_with(id_node)
예제 #6
0
    def test_update_participant_with_error(self, get_node_mock):
        id_node = 1
        get_node_mock.return_value = {'id': id_node, 'errors': ['error'], 'links': None}
        not_found = NotFoundByIdModel(id=id_node, errors=['error'])
        additional_properties = [PropertyIn(key='identifier', value=5)]
        participant_in = ParticipantIn(name="test", sex='male', id=id_node,
                                       additional_properties=additional_properties)
        participant_service = ParticipantService()

        result = participant_service.update_participant(id_node, participant_in)

        self.assertEqual(result, not_found)
        get_node_mock.assert_called_once_with(id_node)
    def test_get_participants(self, get_nodes_mock):
        get_nodes_mock.return_value = {
            'nodes': [{
                'id':
                1,
                'labels': ['Participant'],
                'properties': [{
                    'key': 'name',
                    'value': 'test'
                }, {
                    'key': 'sex',
                    'value': 'male'
                }]
            }, {
                'id':
                2,
                'labels': ['Participant'],
                'properties': [{
                    'key': 'name',
                    'value': 'test2'
                }, {
                    'key': 'sex',
                    'value': 'female'
                }]
            }]
        }
        participant_one = BasicParticipantOut(id=1,
                                              name="test",
                                              sex="male",
                                              additional_properties=[])
        participant_two = BasicParticipantOut(id=2,
                                              name="test2",
                                              sex="female",
                                              additional_properties=[])
        participants = ParticipantsOut(
            participants=[participant_one, participant_two])
        participant_service = ParticipantService()

        result = participant_service.get_participants()

        self.assertEqual(result, participants)
        get_nodes_mock.assert_called_once_with("Participant")
예제 #8
0
    def test_save_participant_without_error(self, create_properties_mock,
                                            create_node_mock):
        id_node = 1
        create_node_mock.return_value = {
            'id': id_node,
            'properties': None,
            "errors": None,
            'links': None
        }
        create_properties_mock.return_value = {
            'id':
            id_node,
            'properties': [{
                'key': 'sex',
                'value': 'male'
            }, {
                'key': 'identifier',
                'value': 5
            }],
            "errors":
            None,
            'links':
            None
        }
        additional_properties = [PropertyIn(key='testkey', value='testvalue')]
        participant = ParticipantIn(
            name="Test Test",
            sex='male',
            additional_properties=additional_properties)
        participant_service = ParticipantService()

        result = participant_service.save_participant(participant)

        self.assertEqual(
            result,
            ParticipantOut(name="Test Test",
                           sex='male',
                           id=id_node,
                           additional_properties=additional_properties))
        create_node_mock.assert_called_once_with('Participant')
        create_properties_mock.assert_called_once_with(id_node, participant)
예제 #9
0
class ParticipantStateService:
    """
    Object to handle logic of participant state requests

    Attributes:
        graph_api_service (GraphApiService): Service used to communicate with Graph API
        participant_service (ParticipantService): Service to manage participant models
        appearance_service (AppearanceService): Service to manage appearance models
        personality_service (PersonalityService): Service to manage personality models
    """
    graph_api_service = GraphApiService()
    participant_service = ParticipantService()
    appearance_service = AppearanceService()
    personality_service = PersonalityService()

    def save_participant_state(self, participant_state: ParticipantStateIn):
        """
        Send request to graph api to create new participant state

        Args:
            participant_state (ParticipantStateIn): Participant state to be added

        Returns:
            Result of request as participant state object
        """
        node_response = self.graph_api_service.create_node(
            "`Participant State`")

        if node_response["errors"] is not None:
            return ParticipantStateOut(**participant_state.dict(),
                                       errors=node_response["errors"])

        participant_state_id = node_response["id"]

        if participant_state.participant_id is not None and \
                type(self.participant_service.get_participant(participant_state.participant_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                start_node=participant_state_id,
                end_node=participant_state.participant_id,
                name="hasParticipant")
        if participant_state.personality_id is not None and \
                type(self.personality_service.get_personality(participant_state.personality_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                start_node=participant_state_id,
                end_node=participant_state.personality_id,
                name="hasPersonality")
        if participant_state.appearance_id is not None and \
                type(self.appearance_service.get_appearance(participant_state.appearance_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                start_node=participant_state_id,
                end_node=participant_state.appearance_id,
                name="hasAppearance")

        participant_state.participant_id = participant_state.personality_id = participant_state.appearance_id = None
        self.graph_api_service.create_properties(participant_state_id,
                                                 participant_state)

        return self.get_participant_state(participant_state_id)

    def get_participant_states(self):
        """
        Send request to graph api to get participant states

        Returns:
            Result of request as list of participant states objects
        """
        get_response = self.graph_api_service.get_nodes("`Participant State`")

        participant_states = []

        for participant_state_node in get_response["nodes"]:
            properties = {
                'id': participant_state_node['id'],
                'additional_properties': []
            }
            for property in participant_state_node["properties"]:
                if property["key"] == "age":
                    properties[property["key"]] = property["value"]
                else:
                    properties['additional_properties'].append({
                        'key':
                        property['key'],
                        'value':
                        property['value']
                    })
            participant_state = BasicParticipantStateOut(**properties)
            participant_states.append(participant_state)

        return ParticipantStatesOut(participant_states=participant_states)

    def get_participant_state(self, participant_state_id: int):
        """
        Send request to graph api to get given participant state

        Args:
            participant_state_id (int): Id of participant state

        Returns:
            Result of request as participant state object
        """
        get_response = self.graph_api_service.get_node(participant_state_id)

        if get_response["errors"] is not None:
            return NotFoundByIdModel(id=participant_state_id,
                                     errors=get_response["errors"])
        if get_response["labels"][0] != "Participant State":
            return NotFoundByIdModel(id=participant_state_id,
                                     errors="Node not found.")

        participant_state = {
            'id': get_response['id'],
            'additional_properties': [],
            'relations': [],
            'reversed_relations': []
        }
        for property in get_response["properties"]:
            if property["key"] == "age":
                participant_state[property["key"]] = property["value"]
            else:
                participant_state['additional_properties'].append({
                    'key':
                    property['key'],
                    'value':
                    property['value']
                })

        relations_response = self.graph_api_service.get_node_relationships(
            participant_state_id)

        for relation in relations_response["relationships"]:
            if relation["start_node"] == participant_state_id:
                participant_state['relations'].append(
                    RelationInformation(second_node_id=relation["end_node"],
                                        name=relation["name"],
                                        relation_id=relation["id"]))
            else:
                participant_state['reversed_relations'].append(
                    RelationInformation(second_node_id=relation["start_node"],
                                        name=relation["name"],
                                        relation_id=relation["id"]))

        return ParticipantStateOut(**participant_state)

    def delete_participant_state(self, participant_state_id: int):
        """
        Send request to graph api to delete given participant state

        Args:
            participant_state_id (int): Id of participant state

        Returns:
            Result of request as participant state object
        """
        get_response = self.get_participant_state(participant_state_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        self.graph_api_service.delete_node(participant_state_id)
        return get_response

    def update_participant_state(
            self, participant_state_id: int,
            participant_state: ParticipantStatePropertyIn):
        """
        Send request to graph api to update given participant state

        Args:
            participant_state_id (int): Id of participant state
            participant_state (ParticipantStatePropertyIn): Properties to update

        Returns:
            Result of request as participant state object
        """
        get_response = self.get_participant_state(participant_state_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        self.graph_api_service.delete_node_properties(participant_state_id)
        self.graph_api_service.create_properties(participant_state_id,
                                                 participant_state)

        participant_state_result = {
            "id": participant_state_id,
            "relations": get_response.relations,
            "reversed_relations": get_response.reversed_relations
        }
        participant_state_result.update(participant_state.dict())

        return ParticipantStateOut(**participant_state_result)

    def update_participant_state_relationships(
            self, participant_state_id: int,
            participant_state: ParticipantStateRelationIn):
        """
        Send request to graph api to update given participant state

        Args:
            participant_state_id (int): Id of participant state
            participant_state (ParticipantStateRelationIn): Relationships to update

        Returns:
            Result of request as participant state object
        """
        get_response = self.get_participant_state(participant_state_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        if participant_state.participant_id is not None and \
                type(self.participant_service.get_participant(
                    participant_state.participant_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                start_node=participant_state_id,
                end_node=participant_state.participant_id,
                name="hasParticipant")
        if participant_state.personality_id is not None and \
                type(self.personality_service.get_personality(participant_state.personality_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                start_node=participant_state_id,
                end_node=participant_state.personality_id,
                name="hasPersonality")
        if participant_state.appearance_id is not None and \
                type(self.appearance_service.get_appearance(participant_state.appearance_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                start_node=participant_state_id,
                end_node=participant_state.appearance_id,
                name="hasAppearance")

        return self.get_participant_state(participant_state_id)
class ParticipantRouter:
    """
    Class for routing participant based requests

    Attributes:
        participant_service (ParticipantService): Service instance for participants
    """
    participant_service = ParticipantService()

    @router.post("/participants",
                 tags=["participants"],
                 response_model=ParticipantOut)
    async def create_participant(self, participant: ParticipantIn,
                                 response: Response):
        """
        Create participant in database
        """

        if participant.date_of_birth is not None:
            participant.date_of_birth = participant.date_of_birth.__str__()

        create_response = self.participant_service.save_participant(
            participant)
        if create_response.errors is not None:
            response.status_code = 422

        # add links from hateoas
        create_response.links = get_links(router)

        return create_response

    @router.get("/participants",
                tags=["participants"],
                response_model=ParticipantsOut)
    async def get_participants(self, response: Response):
        """
        Get participants from database
        """

        get_response = self.participant_service.get_participants()

        # add links from hateoas
        get_response.links = get_links(router)

        return get_response

    @router.get("/participants/{participant_id}",
                tags=["participants"],
                response_model=Union[ParticipantOut, NotFoundByIdModel])
    async def get_participant(self, participant_id: int, response: Response):
        """
        Get participant from database
        """

        get_response = self.participant_service.get_participant(participant_id)
        if get_response.errors is not None:
            response.status_code = 404

        # add links from hateoas
        get_response.links = get_links(router)

        return get_response

    @router.delete("/participants/{participant_id}",
                   tags=["participants"],
                   response_model=Union[ParticipantOut, NotFoundByIdModel])
    async def delete_participant(self, participant_id: int,
                                 response: Response):
        """
        Delete participant from database
        """
        get_response = self.participant_service.delete_participant(
            participant_id)
        if get_response.errors is not None:
            response.status_code = 404

        # add links from hateoas
        get_response.links = get_links(router)

        return get_response

    @router.put("/participants/{participant_id}",
                tags=["participants"],
                response_model=Union[ParticipantOut, NotFoundByIdModel])
    async def update_participant(self, participant_id: int,
                                 participant: ParticipantIn,
                                 response: Response):
        """
        Update participant model in database
        """
        update_response = self.participant_service.update_participant(
            participant_id, participant)
        if update_response.errors is not None:
            response.status_code = 404

        # add links from hateoas
        update_response.links = get_links(router)

        return update_response