Esempio n. 1
0
 def test_graph_entity_can_build_path_with_args(self):
     # create a graph entity to test
     entity = GraphEntity(service=Mock(), model_type='user', id=1)
     # build a path to test
     assert entity.foo(bar="baz").bar._api_path == [
         {"name": "user", "args": {"id": 1}},
         {"name": "foo", "args": {"bar": "baz"}},
         {"name": "bar", "args": {}}
     ], "Internal api with args path did not match expectation."
Esempio n. 2
0
 def test_graph_entity_can_build_path_with_args(self):
     # create a graph entity to test
     entity = GraphEntity(service=Mock(), model_type='user', id=1)
     # build a path to test
     assert entity.foo(bar="baz").bar._api_path == [{
         "name": "user",
         "args": {
             "id": 1
         }
     }, {
         "name": "foo",
         "args": {
             "bar": "baz"
         }
     }, {
         "name": "bar",
         "args": {}
     }], "Internal api with args path did not match expectation."
Esempio n. 3
0
 def test_graph_entity_needs_to_start_somewhere(self):
     # make sure an exception is raised
     try:
         # try to make an empty one
         GraphEntity(service=Mock())
         # if we got here then we failed
         raise AssertionError(
             "GraphEntity did not require a starting point.")
     # if an exception is raised
     except ValueError:
         # then we pass
         pass
Esempio n. 4
0
 def test_graph_entity_maintains_source(self):
     # create a graph entity to test
     entity = GraphEntity(service=Mock(), model_type='user', id=1)
     # check that the source values match up
     assert entity._api_path == [
         {
             "name": "user",
             "args": {
                 "id": 1
             }
         }
     ], ("The source node of the graph entity did not match constructor arguments."
         )
Esempio n. 5
0
    def test_graph_entity__find_id(self):
        # a graph entity to test with
        entity = GraphEntity(service=Mock(), model_type="user", id=1)
        # the result to test against
        result = {
            'user': {
                'foo': [
                    {'id': 1}
                ],
                'bar': {
                    'id': 7,
                    'baz': [
                        {'id': 5}
                    ]
                },
                'baz': {
                    'id': 8,
                    'bing': []
                }
            }
        }
        # make sure it can find the number 1 in the list
        assert entity._find_id(result, 1), (
            "Could not find id in GraphEntity result."
        )
        # make sure it can find the number 1 in the list
        assert entity._find_id(result, 5), (
            "Could not find id in GraphEntity result."
        )

        # make sure we don't have any false positives
        assert not entity._find_id(result, 7), (
            "Encountered false positive in GraphEntity._find_id."
        )

        # make sure we don't have any false positives
        assert not entity._find_id(result, 8), (
            "Encountered a complicated false positive in GraphEntity._find_id."
        )
Esempio n. 6
0
    def test_graph_entity__find_id(self):
        # a graph entity to test with
        entity = GraphEntity(service=Mock(), model_type="user", id=1)
        # the result to test against
        result = {
            'user': {
                'foo': [{
                    'id': 1
                }],
                'bar': {
                    'id': 7,
                    'baz': [{
                        'id': 5
                    }]
                },
                'baz': {
                    'id': 8,
                    'bing': []
                }
            }
        }
        # make sure it can find the number 1 in the list
        assert entity._find_id(result,
                               1), ("Could not find id in GraphEntity result.")
        # make sure it can find the number 1 in the list
        assert entity._find_id(result,
                               5), ("Could not find id in GraphEntity result.")

        # make sure we don't have any false positives
        assert not entity._find_id(
            result, 7), ("Encountered false positive in GraphEntity._find_id.")

        # make sure we don't have any false positives
        assert not entity._find_id(result, 8), (
            "Encountered a complicated false positive in GraphEntity._find_id."
        )
Esempio n. 7
0
    async def object_resolver(self,
                              object_name,
                              fields,
                              obey_auth=False,
                              current_user=None,
                              **filters):
        """
            This function resolves a given object in the remote backend services
        """

        try:
            # check if an object with that name has been registered
            registered = [model for model in self._external_service_data['models'] \
                                if model['name']==object_name][0]
        # if there is no connection data yet
        except AttributeError:
            raise ValueError("No objects are registered with this schema yet.")
        # if we dont recognize the model that was requested
        except IndexError:
            raise ValueError(
                "Cannot query for object {} on this service.".format(
                    object_name))

        # the valid fields for this object
        valid_fields = [field['name'] for field in registered['fields']]

        # figure out if any invalid fields were requested
        invalid_fields = [
            field for field in fields if field not in valid_fields
        ]
        try:
            # make sure we never treat pk as invalid
            invalid_fields.remove('pk')
        # if they weren't asking for pk as a field
        except ValueError:
            pass

        # if there were
        if invalid_fields:
            # yell loudly
            raise ValueError("Cannot query for fields {!r} on {}".format(
                invalid_fields, registered['name']))

        # make sure we include the id in the request
        fields.append('pk')

        # the query for model records
        query = query_for_model(fields, **filters)

        # the action type for the question
        action_type = get_crud_action('read', object_name)

        # query the appropriate stream for the information
        response = await self.event_broker.ask(action_type=action_type,
                                               payload=query)

        # treat the reply like a json object
        response_data = json.loads(response)

        # if something went wrong
        if 'errors' in response_data and response_data['errors']:
            # return an empty response
            raise ValueError(','.join(response_data['errors']))

        # grab the valid list of matches
        result = response_data['data'][root_query()]

        # grab the auth handler for the object
        auth_criteria = self.auth_criteria.get(object_name)

        # if we care about auth requirements and there is one for this object
        if obey_auth and auth_criteria:

            # build a second list of authorized entries
            authorized_results = []

            # for each query result
            for query_result in result:
                # create a graph entity for the model
                graph_entity = GraphEntity(self,
                                           model_type=object_name,
                                           id=query_result['pk'])
                # if the auth handler passes
                if await auth_criteria(model=graph_entity,
                                       user_id=current_user):
                    # add the result to the final list
                    authorized_results.append(query_result)

            # overwrite the query result
            result = authorized_results

        # apply the auth handler to the result
        return result
Esempio n. 8
0
    def test_graph_entity_query(self):
        # the graph entity to test against
        entity = GraphEntity(service=Mock(), model_type="user",
                             id=1).foo.bar(arg="2")
        # parse the associated query
        parsed = graphql.parse(entity._query)

        # the target query
        target = """
            query {
                user(id:1) {
                    foo {
                        bar(arg:2) {
                            id
                        }
                    }
                }
            }
        """

        # make sure there is a single root query definted
        assert len(
            parsed.definitions
        ) == 1 and parsed.definitions[0].operation == "query", (
            "Graph entity parsed query did not have a single definition.")

        top_selection = parsed.definitions[0].selection_set.selections
        # make sure there is a single selection with the right name
        assert len(
            top_selection) == 1 and top_selection[0].name.value == 'user', (
                "Top selection does not have the right name.")
        # pull out the first and only selection
        top_selection = top_selection[0]

        top_args = top_selection.arguments
        # verify the arguments of the top selection
        assert len(top_args) == 1 and top_args[
            0].name.value == 'id' and top_args[0].value.value == '1', (
                "Top selection did not have the right arguments.")

        # the first level deep selection
        second_selection_set = top_selection.selection_set.selections
        # make sure there is only one and it has no arguments
        assert len(second_selection_set) == 1 and second_selection_set[0].name.value == 'foo' \
                                                and len(second_selection_set[0].arguments) == 0, (
            "Second selection did not have the right characteristics."
        )
        second_selection = second_selection_set[0]

        # the third level of the selection
        third_selection_set = second_selection.selection_set.selections
        # make sure the third level has the correct name and arguments
        assert len(third_selection_set) == 1 and third_selection_set[0].name.value == 'bar' \
                                             and len(third_selection_set[0].arguments) == 1 \
                                             and third_selection_set[0].arguments[0].name.value == 'arg' \
                                             and third_selection_set[0].arguments[0].value.value == '2', (
            "Third selection did not have the right requirements."
        )
        third_selection = third_selection_set[0]

        fourth_selection_set = third_selection.selection_set.selections
        # make sure we are asking for the id of the final select
        assert len(fourth_selection_set
                   ) == 1 and fourth_selection_set[0].name.value == 'id', (
                       "Final selection was incorrect.")