def chained_resolver(self, resolver, is_partial, root, info, **args): only_fields = list() for field in self.only_fields: if field in self.model._fields_ordered: only_fields.append(field) for field in get_query_fields(info): if to_snake_case(field) in self.model._fields_ordered: only_fields.append(to_snake_case(field)) if not bool(args) or not is_partial: if isinstance(self.model, mongoengine.Document) or isinstance( self.model, mongoengine.base.metaclasses.TopLevelDocumentMetaclass): args_copy = args.copy() for arg_name, arg in args.copy().items(): if arg_name not in self.model._fields_ordered: args_copy.pop(arg_name) if isinstance(info, ResolveInfo): if not info.context: info.context = Context() info.context.queryset = self.get_queryset( self.model, info, only_fields, **args_copy) # XXX: Filter nested args resolved = resolver(root, info, **args) if resolved is not None: if isinstance(resolved, list): if resolved == list(): return resolved elif not isinstance(resolved[0], DBRef): return resolved else: return resolved return self.default_resolver(root, info, only_fields, **args)
def test_dataset_list(schema): client = Client(schema) data = client.execute( '''{ datasets { id title clusters { name } } }''', context=Context(datastore=Datastore('tests/mock-data/*'))) print(data) # Check if all datasets are there assert 'data' in data assert 'datasets' in data['data'] assert len(data['data']['datasets']) == 2 # Check the individual properties assert data['data']['datasets'][0]['id'] == 'dataset-1' assert data['data']['datasets'][1]['id'] == 'dataset-2' assert data['data']['datasets'][0]['title'] == 'My First Dataset' assert data['data']['datasets'][1]['title'] == 'My Second Dataset' assert data['data']['datasets'][0]['clusters'][0]['name'] == 'cluster1' assert data['data']['datasets'][0]['clusters'][1]['name'] == 'cluster2'
def test_create_personal_info_with_photo_succeeds( create_personal_info_query, graphql_client, user_and_resume_fixture, data_url_encoded_file, settings, ): # noqa user, resume = user_and_resume_fixture resume_id = str(resume.id) create_params = { "firstName": "kanmii", "resumeId": resume_id, "photo": data_url_encoded_file, } # noqa result = graphql_client.execute( create_personal_info_query, variables={"input": create_params}, context=Context(current_user=user), ) personal_info = result["data"]["createPersonalInfo"]["personalInfo"] photo = personal_info["photo"] assert photo.startswith(settings.MEDIA_URL) assert photo.endswith(".jpeg")
def test_create_personal_info_fails_cos_resume_not_found( create_personal_info_query, graphql_client, bogus_uuid): # noqa create_params = {"firstName": "kanmii", "resumeId": bogus_uuid} result = graphql_client.execute( create_personal_info_query, variables={"input": create_params}, context=Context(current_user=BogusUser(id=bogus_uuid)), ) assert type( result["data"]["createPersonalInfo"]["errors"]["resume"]) == str
def test_create_skill_fails_cos_resume_not_found(graphql_client, create_skill_query, bogus_uuid): params = {"resumeId": bogus_uuid, "index": 1, "description": "d 1"} result = graphql_client.execute( create_skill_query, variables={"input": params}, context=Context(current_user=BogusUser(id=bogus_uuid)), ) errors = result["data"]["createSkill"]["errors"] assert type(errors["resume"]) == str
def test_create_resume_succeeds(graphql_client, create_resume_query, registered_user): # noqa title = "t 12" attrs = {"title": title} result = graphql_client.execute( create_resume_query, variables={"input": attrs}, context=Context(current_user=registered_user, app_data_loader=AppDataLoader()), # noqa ) # noqa resume = result["data"]["createResume"]["resume"] assert resume["title"] == title assert resume["userId"] == str(registered_user.id)
def test_create_skill_succeeds(graphql_client, create_skill_query, user_and_resume_fixture): user, resume = user_and_resume_fixture resume_id = str(resume.id) params = {"resumeId": resume_id, "index": 1, "description": "d 1"} result = graphql_client.execute( create_skill_query, variables={"input": params}, context=Context(current_user=user), ) skill = result["data"]["createSkill"]["skill"] assert skill["resumeId"] == resume_id assert skill["index"] == 1
def test_create_education_succeeds(graphql_client, create_education_query, user_and_resume_fixture): user, resume = user_and_resume_fixture resume_id = str(resume.id) params = {"resumeId": resume_id, "index": 1, "school": "school 1"} result = graphql_client.execute( create_education_query, variables={"input": params}, context=Context(current_user=user), ) education = result["data"]["createEducation"]["education"] assert education["resumeId"] == resume_id assert education["index"] == 1
def test_create_experience_succeeds(graphql_client, create_experience_query, user_and_resume_fixture): user, resume = user_and_resume_fixture resume_id = str(resume.id) params = {"resumeId": resume_id, "index": 1, "position": "pos 1"} result = graphql_client.execute( create_experience_query, variables={"input": params}, context=Context(current_user=user), ) experience = result["data"]["createExperience"]["experience"] assert experience["resumeId"] == resume_id assert experience["index"] == 1
def test_query_vote(self): context = Context(user=self.user) executed = client.execute(''' query { vote(articleId:2) { user { username } article { id } } } ''', context=context) self.assertDictEqual(self.expected, executed)
def test_create_personal_info_no_photo_succeeds( create_personal_info_query, graphql_client, user_and_resume_fixture): # noqa user, resume = user_and_resume_fixture resume_id = str(resume.id) create_params = {"firstName": "kanmii", "resumeId": resume_id} result = graphql_client.execute( create_personal_info_query, variables={"input": create_params}, context=Context(current_user=user), ) personal_info = result["data"]["createPersonalInfo"]["personalInfo"] assert personal_info["firstName"] == "kanmii" assert personal_info["resumeId"] == resume_id
def test_create_supplementary_skill_fails_cos_resume_not_found( graphql_client, create_ratable_query, bogus_uuid): params = { "ownerId": bogus_uuid, "description": "d 1", "tag": RatableEnumType.supplementary_skill.name, } result = graphql_client.execute( create_ratable_query, variables={"input": params}, context=Context(current_user=BogusUser(id=bogus_uuid)), ) errors = result["data"]["createRatable"]["errors"] assert type(errors["owner"]) == str assert errors["tag"] == RatableEnumType.supplementary_skill.name
def default_resolver(self, _root, info, only_fields=list(), **args): args = args or {} if _root is not None: field_name = to_snake_case(info.field_name) if getattr(_root, field_name, []) is not None: args["pk__in"] = [r.id for r in getattr(_root, field_name, [])] connection_args = { "first": args.pop("first", None), "last": args.pop("last", None), "before": args.pop("before", None), "after": args.pop("after", None), } _id = args.pop('id', None) if _id is not None: args['pk'] = from_global_id(_id)[-1] if callable(getattr(self.model, "objects", None)): iterables = self.get_queryset(self.model, info, only_fields, **args) if isinstance(info, ResolveInfo): if not info.context: info.context = Context() info.context.queryset = iterables list_length = iterables.count() else: iterables = [] list_length = 0 connection = connection_from_list_slice( list_slice=iterables, args=connection_args, list_length=list_length, list_slice_length=list_length, connection_type=self.type, edge_type=self.type.Edge, pageinfo_type=graphene.PageInfo, ) connection.iterable = iterables connection.list_length = list_length return connection
def test_create_resume_child_text_only_child_succeeds( user_and_resume_fixture, create_text_only_query, graphql_client, make_education_fixture, make_experience_fixture, make_skill_fixture, ): user, resume = user_and_resume_fixture resume_id = str(resume.id) for fixture_fn, tag_name in ( ( make_education_fixture, TextOnlyEnumType.education_achievement.name, ), ( make_skill_fixture, TextOnlyEnumType.skill_achievement.name, ), ( make_experience_fixture, TextOnlyEnumType.experience_achievement.name, ), # noqa E501 ): owner = fixture_fn(resume_id) owner_id_str = str(owner.id) result = graphql_client.execute( create_text_only_query, variables={ "ownerId": owner_id_str, "text": "aa" }, context=Context(current_user=user, app_data_loader=AppDataLoader()), ) text_only_obj = result["data"]["createTextOnly"]["textOnly"] assert text_only_obj["ownerId"] == owner_id_str assert text_only_obj["tag"] == tag_name
def test_create_spoken_languages_succeeds(graphql_client, create_ratable_query, user_and_resume_fixture): user, resume = user_and_resume_fixture resume_id = str(resume.id) params = { "ownerId": resume_id, "description": "d 1", "tag": RatableEnumType.spoken_language.name, } result = graphql_client.execute( create_ratable_query, variables={"input": params}, context=Context(current_user=user), ) spoken_language = result["data"]["createRatable"]["ratable"] assert spoken_language["ownerId"] == resume_id assert spoken_language["tag"] == RatableEnumType.spoken_language.name
def test_create_resume_hobby_succeeds(user_and_resume_fixture, create_text_only_query, graphql_client): user, resume = user_and_resume_fixture resume_id = str(resume.id) params = { "ownerId": resume_id, "text": "aa", "tag": TextOnlyEnumType.resume_hobby.name, } result = graphql_client.execute( create_text_only_query, variables={"input": params}, context=Context(current_user=user, app_data_loader=AppDataLoader()), ) hobby = result["data"]["createTextOnly"]["textOnly"] assert hobby["ownerId"] == resume_id assert hobby["tag"] == TextOnlyEnumType.resume_hobby.name
def test_get_all_resume_fields_succeeds( graphql_client, user_and_resume_fixture, get_resume_query, make_skill_fixture, make_education_fixture, ): user, resume = user_and_resume_fixture resume_id = str(resume.id) hobby = cast( TextOnlyLike, ResumesLogic.create_text_only( CreateTextOnlyAttr( tag=TextOnlyEnumType.resume_hobby, owner_id=resume_id, text="rh", # noqa E501 )), ) personal_info = cast( PersonalInfoLike, ResumesLogic.create_personal_info( CreatePersonalInfoAttrs(resume_id=resume_id, first_name="kanmii")), ) education = make_education_fixture(resume_id) education_achievement = cast( TextOnlyLike, ResumesLogic.create_text_only( CreateTextOnlyAttr( tag=TextOnlyEnumType.education_achievement, owner_id=education.id, text="ea", # noqa E501 )), ) skill = make_skill_fixture(resume_id) skill_achievement = cast( TextOnlyLike, ResumesLogic.create_text_only( CreateTextOnlyAttr( tag=TextOnlyEnumType.skill_achievement, owner_id=skill.id, text="sa", # noqa E501 )), ) experience = cast( ExperienceLike, ResumesLogic.create_experience( CreateExperienceAttrs(resume_id=resume_id, index=0)), ) experience_achievement = cast( TextOnlyLike, ResumesLogic.create_text_only( CreateTextOnlyAttr( tag=TextOnlyEnumType.experience_achievement, owner_id=experience.id, text="exa", # noqa E501 )), ) language = cast( Ratable, ResumesLogic.create_ratable( CreateRatableAttrs( owner_id=resume_id, tag=RatableEnumType.spoken_language, description="aa", )), ) supplementary_skill = cast( Ratable, ResumesLogic.create_ratable( CreateRatableAttrs( owner_id=resume_id, tag=RatableEnumType.supplementary_skill, description="bb", )), ) result = graphql_client.execute( get_resume_query, variables={"input": { "title": resume.title }}, context=Context(current_user=user, app_data_loader=AppDataLoader()), ) resume_map = result["data"]["getResume"] assert resume_map["id"] == resume_id assert resume_map["personalInfo"]["id"] == str(personal_info.id) education_obj = resume_map["educations"][0] assert education_obj["id"] == str(education.id) education_achievement_obj = education_obj["achievements"][0] assert education_achievement_obj["id"] == str(education_achievement.id) skill_obj = resume_map["skills"][0] assert skill_obj["id"] == str(skill.id) skill_achievement_obj = skill_obj["achievements"][0] assert skill_achievement_obj["id"] == str(skill_achievement.id) hobby_obj = resume_map["hobbies"][0] assert hobby_obj["id"] == str(hobby.id) experience_obj = resume_map["experiences"][0] assert experience_obj["id"] == str(experience.id) experience_achievement_obj = experience_obj["achievements"][0] assert experience_achievement_obj["id"] == str(experience_achievement.id) language_obj = resume_map["languages"][0] assert language_obj["id"] == str(language.id) supplementary_skill_obj = resume_map["supplementarySkills"][0] assert supplementary_skill_obj["id"] == str(supplementary_skill.id)
app = Flask(__name__) @app.route('/') def index(): return redirect(url_for('graphql')) app.add_url_rule( '/graphql', view_func=GraphQLView.as_view( 'graphql', schema=get_schema(), graphiql=True, get_context=lambda: Context(datastore=Datastore('tests/mock-data/*')))) # Optional, for adding batch query support (used in Apollo-Client) app.add_url_rule( '/graphql', view_func=GraphQLView.as_view( 'graphql-batch', schema=get_schema(), graphiql=True, get_context=lambda: Context(datastore=Datastore('tests/mock-data/*')), batch=True)) CONFIGTEMPLATE = { 'app': { 'host': 'str', 'port': 5000,
def chained_resolver(self, resolver, is_partial, root, info, **args): required_fields = list() for field in self.required_fields: if field in self.model._fields_ordered: required_fields.append(field) for field in get_query_fields(info): if to_snake_case(field) in self.model._fields_ordered: required_fields.append(to_snake_case(field)) args_copy = args.copy() if not bool(args) or not is_partial: if isinstance(self.model, mongoengine.Document) or isinstance( self.model, mongoengine.base.metaclasses.TopLevelDocumentMetaclass): for arg_name, arg in args.copy().items(): if arg_name not in self.model._fields_ordered + tuple( self.filter_args.keys()): args_copy.pop(arg_name) if isinstance(info, ResolveInfo): if not info.context: info.context = Context() info.context.queryset = self.get_queryset( self.model, info, required_fields, **args_copy) # XXX: Filter nested args resolved = resolver(root, info, **args) if resolved is not None: if isinstance(resolved, list): if resolved == list(): return resolved elif not isinstance(resolved[0], DBRef): return resolved else: return self.default_resolver(root, info, required_fields, **args_copy) elif isinstance(resolved, QuerySet): args.update(resolved._query) args_copy = args.copy() for arg_name, arg in args.copy().items(): if arg_name not in self.model._fields_ordered + ( 'first', 'last', 'before', 'after') + tuple( self.filter_args.keys()): args_copy.pop(arg_name) if arg_name == '_id' and isinstance(arg, dict): operation = list(arg.keys())[0] args_copy['pk' + operation.replace( '$', '__')] = arg[operation] if '.' in arg_name: operation = list(arg.keys())[0] args_copy[arg_name.replace('.', '__') + operation.replace( '$', '__')] = arg[operation] else: operations = ["$lte", "$gte", "$ne", "$in"] if isinstance(arg, dict) and any( op in arg for op in operations): operation = list(arg.keys())[0] args_copy[arg_name + operation.replace( '$', '__')] = arg[operation] del args_copy[arg_name] return self.default_resolver(root, info, required_fields, **args_copy) else: return resolved return self.default_resolver(root, info, required_fields, **args)
def default_resolver(self, _root, info, required_fields=list(), **args): args = args or {} if _root is not None: field_name = to_snake_case(info.field_name) if field_name in _root._fields_ordered: if getattr(_root, field_name, []) is not None: args["pk__in"] = [ r.id for r in getattr(_root, field_name, []) ] _id = args.pop('id', None) if _id is not None: args['pk'] = from_global_id(_id)[-1] iterables = [] list_length = 0 skip = 0 count = 0 limit = None reverse = False if callable(getattr(self.model, "objects", None)): first = args.pop("first", None) after = cursor_to_offset(args.pop("after", None)) last = args.pop("last", None) before = cursor_to_offset(args.pop("before", None)) if "pk__in" in args and args["pk__in"]: count = len(args["pk__in"]) skip, limit, reverse = find_skip_and_limit(first=first, last=last, after=after, before=before, count=count) if limit: if reverse: args["pk__in"] = args["pk__in"][::-1][skip:skip + limit] else: args["pk__in"] = args["pk__in"][skip:skip + limit] elif skip: args["pk__in"] = args["pk__in"][skip:] iterables = self.get_queryset(self.model, info, required_fields, **args) list_length = len(iterables) if isinstance(info, ResolveInfo): if not info.context: info.context = Context() info.context.queryset = self.get_queryset( self.model, info, required_fields, **args) elif _root is None: count = self.get_queryset(self.model, info, required_fields, **args).count() if count != 0: skip, limit, reverse = find_skip_and_limit(first=first, after=after, last=last, before=before, count=count) iterables = self.get_queryset(self.model, info, required_fields, skip, limit, reverse, **args) list_length = len(iterables) if isinstance(info, ResolveInfo): if not info.context: info.context = Context() info.context.queryset = self.get_queryset( self.model, info, required_fields, **args) has_next_page = True if (0 if limit is None else limit) + ( 0 if skip is None else skip) < count else False has_previous_page = True if skip else False if reverse: iterables = list(iterables) iterables.reverse() skip = limit connection = connection_from_iterables( edges=iterables, start_offset=skip, has_previous_page=has_previous_page, has_next_page=has_next_page, connection_type=self.type, edge_type=self.type.Edge, pageinfo_type=graphene.PageInfo) connection.iterable = iterables connection.list_length = list_length return connection