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."
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."
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
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." )
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." )
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." )
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
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.")