def test_get_arrangements(self, get_nodes_mock):
        get_nodes_mock.return_value = {
            'nodes': [{
                'id':
                1,
                'labels': ['Arrangement'],
                'properties': [{
                    'key': 'arrangement_type',
                    'value': 'test'
                }]
            }, {
                'id':
                2,
                'labels': ['Arrangement'],
                'properties': [{
                    'key': 'arrangement_type',
                    'value': 'test2'
                }]
            }],
            'errors':
            None
        }
        arrangement_one = BasicArrangementOut(arrangement_type="test", id=1)
        arrangement_two = BasicArrangementOut(arrangement_type="test2", id=2)
        arrangements = ArrangementsOut(
            arrangements=[arrangement_one, arrangement_two])
        arrangement_service = ArrangementService()

        result = arrangement_service.get_arrangements()

        self.assertEqual(result, arrangements)
        get_nodes_mock.assert_called_once_with("Arrangement")
    def test_get_arrangement_without_error(self, get_node_relationships_mock,
                                           get_node_mock):
        id_node = 1
        get_node_mock.return_value = {
            'id':
            id_node,
            'labels': ['Arrangement'],
            'properties': [{
                'key': 'arrangement_type',
                'value': 'test'
            }, {
                'key': 'arrangement_distance',
                'value': 'test'
            }, {
                'key': 'test',
                'value': 'test'
            }],
            "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
            }]
        }
        arrangement = ArrangementOut(
            arrangement_type="test",
            arrangement_distance="test",
            id=id_node,
            relations=[
                RelationInformation(second_node_id=19,
                                    name="testRelation",
                                    relation_id=0)
            ],
            reversed_relations=[
                RelationInformation(second_node_id=15,
                                    name="testReversedRelation",
                                    relation_id=0)
            ])
        arrangement_service = ArrangementService()

        result = arrangement_service.get_arrangement(id_node)

        self.assertEqual(result, arrangement)
        get_node_mock.assert_called_once_with(id_node)
        get_node_relationships_mock.assert_called_once_with(id_node)
    def test_get_arrangements_empty(self, get_nodes_mock):
        get_nodes_mock.return_value = {'nodes': [], 'errors': None}
        arrangements = ArrangementsOut(arrangements=[])
        arrangement_service = ArrangementService()

        result = arrangement_service.get_arrangements()

        self.assertEqual(result, arrangements)
        get_nodes_mock.assert_called_once_with("Arrangement")
    def test_save_arrangement_with_node_error(self, create_node_mock):
        id_node = 1
        create_node_mock.return_value = {'id': id_node, 'properties': None, "errors": ['error'], 'links': None}
        arrangement = ArrangementIn(arrangement_type='personal two persons', arrangement_distance='intimate zone')
        arrangement_service = ArrangementService()

        result = arrangement_service.save_arrangement(arrangement)

        self.assertEqual(result, ArrangementOut(arrangement_type='personal two persons', arrangement_distance='intimate zone', errors=['error']))
        create_node_mock.assert_called_once_with('Arrangement')
    def test_get_arrangement_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'])
        arrangement_service = ArrangementService()

        result = arrangement_service.get_arrangement(id_node)

        self.assertEqual(result, not_found)
        get_node_mock.assert_called_once_with(id_node)
    def test_get_arrangement_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.")
        arrangement_service = ArrangementService()

        result = arrangement_service.get_arrangement(id_node)

        self.assertEqual(result, not_found)
        get_node_mock.assert_called_once_with(id_node)
Exemple #7
0
 def set_arrangements(self):
     """
     Initialize values of arrangement distances
     """
     arrangement_service = ArrangementService()
     created_arrangements = \
         [arrangement.arrangement_distance
          for arrangement in
          arrangement_service.get_arrangements().arrangements]
     [
         arrangement_service.save_arrangement(
             ArrangementIn(arrangement_type=arrangement.value[0],
                           arrangement_distance=arrangement.value[1]))
         for arrangement in Arrangement
         if arrangement.value[1] not in created_arrangements
     ]
    def test_save_arrangement_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': 'arrangement_type',
                                                                              'value': 'personal two persons'},
                                                                             {'key': 'arrangement_distance',
                                                                              'value': 'intimate zone'}],
                                               "errors": None, 'links': None}
        arrangement = ArrangementIn(arrangement_type='personal two persons', arrangement_distance='intimate zone')
        arrangement_service = ArrangementService()

        result = arrangement_service.save_arrangement(arrangement)

        self.assertEqual(result, ArrangementOut(id=id_node, arrangement_type='personal two persons', arrangement_distance='intimate zone'))
        create_node_mock.assert_called_once_with('Arrangement')
        create_properties_mock.assert_called_once_with(id_node, arrangement)
class ArrangementRouter:
    """
    Class for routing arrangement based requests

    Attributes:
    arrangement_service (ArrangementService): Service instance for arrangement
    """
    arrangement_service = ArrangementService()

    @router.get("/arrangements/{arrangement_id}",
                tags=["arrangements"],
                response_model=Union[ArrangementOut, NotFoundByIdModel])
    async def get_arrangement(self, arrangement_id: int, response: Response):
        """
        Get arrangement from database
        """
        get_response = self.arrangement_service.get_arrangement(arrangement_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.get("/arrangements",
                tags=["arrangements"],
                response_model=ArrangementsOut)
    async def get_arrangements(self, response: Response):
        """
        Get arrangements from database
        """

        get_response = self.arrangement_service.get_arrangements()

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

        return get_response
class ActivityExecutionService:
    """
    Object to handle logic of activities requests

    Attributes:
    graph_api_service (GraphApiService): Service used to communicate with Graph API
    activity_service (ActivityService): Service used to communicate with Activity
    arrangement_service (ArrangementService): Service used to communicate with Arrangement
    """
    graph_api_service = GraphApiService()
    activity_service = ActivityService()
    arrangement_service = ArrangementService()

    def save_activity_execution(self, activity_execution: ActivityExecutionIn):
        """
        Send request to graph api to create new activity execution

        Args:
            activity_execution (ActivityExecutionIn): Activity execution to be added

        Returns:
            Result of request as activity execution object
        """
        node_response = self.graph_api_service.create_node("`Activity Execution`")

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

        activity_execution_id = node_response["id"]

        if activity_execution.activity_id is not None and \
                type(self.activity_service.get_activity(activity_execution.activity_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(start_node=activity_execution_id,
                                                        end_node=activity_execution.activity_id,
                                                        name="hasActivity")

        if activity_execution.arrangement_id is not None and \
                type(self.arrangement_service.get_arrangement(activity_execution.arrangement_id)) \
                is not NotFoundByIdModel:

            self.graph_api_service.create_relationships(start_node=activity_execution_id,
                                                        end_node=activity_execution.arrangement_id,
                                                        name="hasArrangement")

        activity_execution.activity_id = activity_execution.arrangement_id = None
        self.graph_api_service.create_properties(activity_execution_id, activity_execution)

        return self.get_activity_execution(activity_execution_id)

    def get_activity_executions(self):
        """
        Send request to graph api to get activity executions

        Returns:
            Result of request as list of activity executions objects
        """
        get_response = self.graph_api_service.get_nodes("`Activity Execution`")

        activity_executions = []
        for activity_execution_node in get_response["nodes"]:
            properties = {'id': activity_execution_node['id'], 'additional_properties': []}
            for property in activity_execution_node["properties"]:
                properties['additional_properties'].append({'key': property['key'], 'value': property['value']})
            activity_execution = BasicActivityExecutionOut(**properties)
            activity_executions.append(activity_execution)

        return ActivityExecutionsOut(activity_executions=activity_executions)

    def get_activity_execution(self, activity_execution_id: int):
        """
        Send request to graph api to get given activity execution

        Args:
            activity_execution_id (int): Id of activity execution

        Returns:
            Result of request as activity execution object
        """
        get_response = self.graph_api_service.get_node(activity_execution_id)

        if get_response["errors"] is not None:
            return NotFoundByIdModel(id=activity_execution_id, errors=get_response["errors"])
        if get_response["labels"][0] != "Activity Execution":
            return NotFoundByIdModel(id=activity_execution_id, errors="Node not found.")

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

        relations_response = self.graph_api_service.get_node_relationships(activity_execution_id)

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

        return ActivityExecutionOut(**activity_execution)

    def delete_activity_execution(self, activity_execution_id: int):
        """
        Send request to graph api to delete given activity execution
        Args:
            activity_execution_id (int): Id of activity execution
        Returns:
            Result of request as activity execution object
        """
        get_response = self.get_activity_execution(activity_execution_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        self.graph_api_service.delete_node(activity_execution_id)
        return get_response

    def update_activity_execution(self, activity_execution_id: int, activity_execution: ActivityExecutionPropertyIn):
        """
        Send request to graph api to update given participant state
        Args:
            activity_execution_id (int): Id of participant state
            activity_execution (ActivityExecutionPropertyIn): Properties to update
        Returns:
            Result of request as participant state object
        """
        get_response = self.get_activity_execution(activity_execution_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        self.graph_api_service.delete_node_properties(activity_execution_id)
        self.graph_api_service.create_properties(activity_execution_id, activity_execution)

        activity_execution_result = {"id": activity_execution_id, "relations": get_response.relations,
                                     "reversed_relations": get_response.reversed_relations}
        activity_execution_result.update(activity_execution.dict())

        return ActivityExecutionOut(**activity_execution_result)

    def update_activity_execution_relationships(self, activity_execution_id: int,
                                                activity_execution: ActivityExecutionRelationIn):
        """
        Send request to graph api to update given activity execution relationships
        Args:
            activity_execution_id (int): Id of activity execution
            activity_execution (ActivityExecutionIn): Relationships to update
        Returns:
            Result of request as activity execution object
        """
        get_response = self.get_activity_execution(activity_execution_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        if activity_execution.activity_id is not None and \
                type(self.activity_service.get_activity(activity_execution.activity_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(start_node=activity_execution_id,
                                                        end_node=activity_execution.activity_id,
                                                        name="hasActivity")
        if activity_execution.arrangement_id is not None and \
                type(self.arrangement_service.get_arrangement(activity_execution.arrangement_id)) \
                is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(start_node=activity_execution_id,
                                                        end_node=activity_execution.arrangement_id,
                                                        name="hasArrangement")

        return self.get_activity_execution(activity_execution_id)