def _test_schema(server_schema): initial_introspection = graphql(server_schema, introspection_query) client_schema = build_client_schema(initial_introspection.data) second_introspection = graphql(client_schema, introspection_query) assert contain_subset(initial_introspection.data, second_introspection.data) return client_schema
def test_uses_provided_resolve_function(): def resolver(source, args, *_): return json.dumps([source, args], separators=(',', ':')) schema = _test_schema(GraphQLField( GraphQLString, args=OrderedDict([ ('aStr', GraphQLArgument(GraphQLString)), ('aInt', GraphQLArgument(GraphQLInt)), ]), resolver=resolver )) result = graphql(schema, '{ test }', None) assert not result.errors assert result.data == {'test': '[null,{}]'} result = graphql(schema, '{ test(aStr: "String!") }', 'Source!') assert not result.errors assert result.data == {'test': '["Source!",{"aStr":"String!"}]'} result = graphql(schema, '{ test(aInt: -123, aStr: "String!",) }', 'Source!') assert not result.errors assert result.data in [ {'test': '["Source!",{"aStr":"String!","aInt":-123}]'}, {'test': '["Source!",{"aInt":-123,"aStr":"String!"}]'} ]
def test_maps_argument_out_names_well_with_input(): def resolver(source, info, **args): return json.dumps([source, args], separators=(',', ':')) TestInputObject = GraphQLInputObjectType('TestInputObject', lambda: OrderedDict([ ('inputOne', GraphQLInputObjectField(GraphQLString, out_name="input_one")), ('inputRecursive', GraphQLInputObjectField(TestInputObject, out_name="input_recursive")), ])) schema = _test_schema(GraphQLField( GraphQLString, args=OrderedDict([ ('aInput', GraphQLArgument(TestInputObject, out_name="a_input")) ]), resolver=resolver )) result = graphql(schema, '{ test }', None) assert not result.errors assert result.data == {'test': '[null,{}]'} result = graphql(schema, '{ test(aInput: {inputOne: "String!"} ) }', 'Source!') assert not result.errors assert result.data == {'test': '["Source!",{"a_input":{"input_one":"String!"}}]'} result = graphql(schema, '{ test(aInput: {inputRecursive:{inputOne: "SourceRecursive!"}} ) }', 'Source!') assert not result.errors assert result.data == { 'test': '["Source!",{"a_input":{"input_recursive":{"input_one":"SourceRecursive!"}}}]' }
def test_maps_argument_out_names_well(): def resolver(source, info, **args): return json.dumps([source, args], separators=(',', ':')) schema = _test_schema(GraphQLField( GraphQLString, args=OrderedDict([ ('aStr', GraphQLArgument(GraphQLString, out_name="a_str")), ('aInt', GraphQLArgument(GraphQLInt, out_name="a_int")), ]), resolver=resolver )) result = graphql(schema, '{ test }', None) assert not result.errors assert result.data == {'test': '[null,{}]'} result = graphql(schema, '{ test(aStr: "String!") }', 'Source!') assert not result.errors assert result.data == {'test': '["Source!",{"a_str":"String!"}]'} result = graphql(schema, '{ test(aInt: -123, aStr: "String!",) }', 'Source!') assert not result.errors assert result.data in [ {'test': '["Source!",{"a_str":"String!","a_int":-123}]'}, {'test': '["Source!",{"a_int":-123,"a_str":"String!"}]'} ]
def test_custom_scalar_type(): R = TypeRegistry() def serialize_date_time(dt): assert isinstance(dt, datetime.datetime) return dt.isoformat() def parse_literal(node): if isinstance(node, ast.StringValue): return datetime.datetime.strptime(node.value, "%Y-%m-%dT%H:%M:%S.%f") def parse_value(value): return datetime.datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%f") DateTimeType = GraphQLScalarType(name='DateTime', serialize=serialize_date_time, parse_literal=parse_literal, parse_value=parse_value) R(DateTimeType) class Query(R.ObjectType): datetime = R.DateTime(args={ 'in': R.DateTime }) def resolve_datetime(self, obj, args, info): return args.get('in') now = datetime.datetime.now() isoformat = now.isoformat() Schema = R.Schema(R.Query) response = graphql(Schema, ''' { datetime(in: "%s") } ''' % isoformat) assert not response.errors assert response.data == { 'datetime': isoformat } response = graphql(Schema, ''' query Test($date: DateTime) { datetime(in: $date) } ''', args={ 'date': isoformat }) assert not response.errors assert response.data == { 'datetime': isoformat }
def test_allows_fetching(): query = ''' { usernames(usernames:["dschafer", "leebyron", "schrockn"]) { username url } } ''' expected = { 'usernames': [ { 'username': '******', 'url': 'www.facebook.com/dschafer?lang=en' }, { 'username': '******', 'url': 'www.facebook.com/leebyron?lang=en' }, { 'username': '******', 'url': 'www.facebook.com/schrockn?lang=en' }, ] } result = graphql(schema, query, root=RootValue()) assert not result.errors assert result.data == expected
def test_query_custom_type_custom_resolver(): type_defs = """ schema { query: Query } type Query { test: Custom } type Custom { node: String } """ resolvers = { "Query": { "test": lambda *_: { "node": "custom" } }, "Custom": { "node": lambda *_: "deep" }, } schema = make_executable_schema(type_defs, resolvers) result = graphql(schema, "{ test { node } }") assert result.errors is None assert result.data == {"test": {"node": "deep"}}
def test_query_custom_scalar(): type_defs = """ schema { query: Query } scalar Date type Query { test: Date } """ resolvers = { "Query": { "test": lambda *_: date.today() }, "Date": lambda date: date.strftime("%Y-%m-%d"), } schema = make_executable_schema(type_defs, resolvers) result = graphql(schema, "{ test }") assert result.errors is None assert result.data == {"test": date.today().strftime("%Y-%m-%d")}
def test_input_type(): R = TypeRegistry() class SimpleInput(R.InputType): a = R.Int b = R.Int class Query(R.ObjectType): f = R.String(args={ 'input': R.SimpleInput }) def resolve_f(self, obj, args, info): input = SimpleInput(args['input']) return "I was given {i.a} and {i.b}".format(i=input) Schema = R.Schema(R.Query) query = ''' { f(input: {a: 1, b: 2}) } ''' result = graphql(Schema, query) assert not result.errors assert result.data == { 'f': "I was given 1 and 2" }
def test_duplicate_fields(schema): query = """ query DuplicateFields { luke: human(id: "1000") { name homePlanet } leia: human(id: "1003") { name homePlanet } } """ expected = { "luke": { "name": "Luke Skywalker", "homePlanet": "Tatooine" }, "leia": { "name": "Leia Organa", "homePlanet": "Alderaan" }, } result = graphql(schema, query) assert not result.errors assert result.data == expected
def test_enum_may_be_both_input_and_output_type(): result = graphql(Schema, '{ colorEnum(fromEnum: GREEN) }') assert not result.errors assert result.data == { 'colorEnum': 'GREEN' }
def test_use_fragment(): query = ''' query UseFragment { luke: human(id: "1000") { ...HumanFragment } leia: human(id: "1003") { ...HumanFragment } } fragment HumanFragment on Human { name homePlanet } ''' expected = { 'luke': { 'name': 'Luke Skywalker', 'homePlanet': 'Tatooine', }, 'leia': { 'name': 'Leia Organa', 'homePlanet': 'Alderaan', } } result = graphql(StarWarsSchema, query) assert not result.errors assert result.data == expected
def test_duplicate_fields(): query = ''' query DuplicateFields { luke: human(id: "1000") { name homePlanet } leia: human(id: "1003") { name homePlanet } } ''' expected = { 'luke': { 'name': 'Luke Skywalker', 'homePlanet': 'Tatooine', }, 'leia': { 'name': 'Leia Organa', 'homePlanet': 'Alderaan', } } result = graphql(StarWarsSchema, query) assert not result.errors assert result.data == expected
def test_hero_name_and_friends_query(): query = ''' query HeroNameAndFriendsQuery { hero { id name friends { name } } } ''' expected = { 'hero': { 'id': '2001', 'name': 'R2-D2', 'friends': [ { 'name': 'Luke Skywalker' }, { 'name': 'Han Solo' }, { 'name': 'Leia Organa' }, ] } } result = graphql(StarWarsSchema, query) assert not result.errors assert result.data == expected
def test_works_with_backward_connection_args(): query = ''' query FriendsQuery { user { friendsBackward: friends(last: 2) { edges { node { name } } } } } ''' expected = { 'user': { 'friendsBackward': { 'edges': [ { 'node': { 'name': 'Joe' } }, { 'node': { 'name': 'Tim' } }, ] } } } result = graphql(schema, query) assert not result.errors assert result.data == expected
def test_hero_name_and_friends_query(schema): query = """ query HeroNameAndFriendsQuery { hero { id name friends { name } } } """ expected = { "hero": { "id": "2001", "name": "R2-D2", "friends": [ { "name": "Luke Skywalker" }, { "name": "Han Solo" }, { "name": "Leia Organa" }, ], } } result = graphql(schema, query) assert not result.errors assert result.data == expected
def test_accepts_json_string_as_enum_variable(): result = graphql( Schema, 'query test($color: Color!) { colorEnum(fromEnum: $color) }', variable_values={'color': 'BLUE'}) assert not result.errors assert result.data == {'colorEnum': 'BLUE'}
def test_use_fragment(schema): query = """ query UseFragment { luke: human(id: "1000") { ...HumanFragment } leia: human(id: "1003") { ...HumanFragment } } fragment HumanFragment on Human { name homePlanet } """ expected = { "luke": { "name": "Luke Skywalker", "homePlanet": "Tatooine" }, "leia": { "name": "Leia Organa", "homePlanet": "Alderaan" }, } result = graphql(schema, query) assert not result.errors assert result.data == expected
def test_accepts_enum_literals_as_input_arguments_to_mutations(): result = graphql( Schema, 'mutation x($color: Color!) { favoriteEnum(color: $color) }', variable_values={'color': 'GREEN'}) assert not result.errors assert result.data == {'favoriteEnum': 'GREEN'}
def test_does_not_accept_string_literals(): result = graphql(Schema, '{ colorEnum(fromEnum: "GREEN") }') assert not result.data assert ( result.errors[0].message == 'Argument "fromEnum" has invalid value "GREEN".\n' 'Expected type "Color", found "GREEN".' )
def graphql_view(request): data = get_query_data(request) query = data.get('query') operation_name = data.get('operationName') result = graphql(schema, query, backend=backend, operation_name=operation_name, validate=False) return json_response(request, result.to_dict())
def test_identifies_deprecated_enum_values(): TestEnum = GraphQLEnumType('TestEnum', OrderedDict([ ('NONDEPRECATED', GraphQLEnumValue(0)), ('DEPRECATED', GraphQLEnumValue(1, deprecation_reason='Removed in 1.0')), ('ALSONONDEPRECATED', GraphQLEnumValue(2)) ])) TestType = GraphQLObjectType('TestType', { 'testEnum': GraphQLField(TestEnum) }) schema = GraphQLSchema(TestType) request = '''{__type(name: "TestEnum") { name enumValues(includeDeprecated: true) { name isDeprecated deprecationReason } } }''' result = graphql(schema, request) assert not result.errors assert result.data == {'__type': { 'name': 'TestEnum', 'enumValues': [ {'name': 'NONDEPRECATED', 'isDeprecated': False, 'deprecationReason': None}, {'name': 'DEPRECATED', 'isDeprecated': True, 'deprecationReason': 'Removed in 1.0'}, {'name': 'ALSONONDEPRECATED', 'isDeprecated': False, 'deprecationReason': None}, ]}}
def test_allows_querying_the_schema_for_object_fields(): query = """ query IntrospectionDroidFieldsQuery { __type(name: "Droid") { name fields { name type { name kind } } } } """ expected = { "__type": { "name": "Droid", "fields": [ {"name": "id", "type": {"name": None, "kind": "NON_NULL"}}, {"name": "name", "type": {"name": "String", "kind": "SCALAR"}}, {"name": "friends", "type": {"name": None, "kind": "LIST"}}, {"name": "appearsIn", "type": {"name": None, "kind": "LIST"}}, {"name": "primaryFunction", "type": {"name": "String", "kind": "SCALAR"}}, ], } } result = graphql(StarWarsSchema, query) assert not result.errors assert contain_subset(result.data, expected)
def test_mutation_input(): type_defs = """ type Query { _: String } input StaffInput { name: String } type Staff { name: String } type Mutation { addStaff(data: StaffInput): Staff } """ def resolve_add_staff(*_, data): assert data == {"name": "Bob"} return data resolvers = {"Mutation": {"addStaff": resolve_add_staff}} schema = make_executable_schema(type_defs, resolvers) result = graphql(schema, 'mutation { addStaff(data: { name: "Bob" }) { name } }') assert result.errors is None assert result.data == {"addStaff": {"name": "Bob"}}
def test_requires_an_argument(): query = ''' mutation M { simpleMutation { result } } ''' expected = { 'allObjects': [ { 'id': 'VXNlcjox' }, { 'id': 'VXNlcjoy' }, { 'id': 'UGhvdG86MQ==' }, { 'id': 'UGhvdG86Mg==' }, ] } result = graphql(schema, query) assert len(result.errors) == 1
def test_relay_node_definition_using_custom_type(): R = TypeRegistry() Relay = R.Mixin(RelayMixin, InMemoryDataSource()) class Pet(R.Implements[R.Node]): name = R.String class Query(R.ObjectType): pets = R.Pet.List node = Relay.NodeField schema = R.Schema(R.Query) @R.Pet.CanBe class MyPet(object): def __init__(self, id, name): self.id = id self.name = name pets = { 5: MyPet(id=5, name='Garfield'), 6: MyPet(id=6, name='Odis') } data = Query(pets=[pets[5], pets[6]]) result = graphql(schema, '{ pets { id, name } }', data) assert result.data == {'pets': [{'id': 'UGV0OjU=', 'name': 'Garfield'}, {'id': 'UGV0OjY=', 'name': 'Odis'}]} assert not result.errors
def gives_different_ids(schema): query = """ { allObjects { id } } """ assert graphql(schema, query) == ( { "allObjects": [ { "id": "VXNlcjox" }, { "id": "VXNlcjoy" }, { "id": "UGhvdG86MQ==" }, { "id": "UGhvdG86Mg==" }, { "id": "UG9zdDox" }, { "id": "UG9zdDoy" }, ] }, None, )
def test_correct_fetch_first_ship_rebels(): query = ''' query RebelsShipsQuery { rebels { name, ships(first: 1) { edges { node { name } } } } } ''' expected = { 'rebels': { 'name': 'Alliance to Restore the Republic', 'ships': { 'edges': [ { 'node': { 'name': 'X-Wing' } } ] } } } result = graphql(StarWarsSchema, query) assert not result.errors assert result.data == expected
def test_input_type(): @dataclass class SubInput: aList: List[int] @dataclass class MyInput: anInt: int aStr: str aSubInput: SubInput class Query(Object): def serialize(self, i: MyInput) -> str: return json.dumps(asdict(i), sort_keys=True, indent=2) schema = make_schema(Query) result = graphql( schema, ''' query { serialize(i: { anInt: 1, aStr: "asdf", aSubInput: { aList: [1, 2, 3] } }) }''') assert not result.errors assert result.data['serialize'] == ''' { "aStr": "asdf", "aSubInput": { "aList": [ 1, 2, 3 ] }, "anInt": 1 } '''.strip()
def test_query_custom_type_merged_custom_default_resolvers(): type_defs = """ type Query { test: Custom } type Custom { node: String default: String } """ resolvers = { "Query": { "test": lambda *_: { "node": "custom", "default": "ok" } }, "Custom": { "node": lambda *_: "deep" }, } schema = make_executable_schema(type_defs, resolvers) result = graphql(schema, "{ test { node default } }") assert result.errors is None assert result.data == {"test": {"node": "deep", "default": "ok"}}
def test_correct_fetch_first_ship_rebels(): query = ''' query RebelsShipsQuery { rebels { name, ships(first: 1) { edges { node { name } } } } } ''' expected = { 'rebels': { 'name': 'Alliance to Restore the Republic', 'ships': { 'edges': [{ 'node': { 'name': 'X-Wing' } }] } } } result = graphql(StarWarsSchema, query) assert not result.errors assert result.data == expected
def test_mapping_resolver_to_object_attribute(): type_defs = """ type Query { user: User } type User { firstName: String } """ resolvers = { "Query": { "user": lambda *_: Mock(first_name="Joe") }, "User": { "firstName": resolve_to("first_name") }, } schema = make_executable_schema(type_defs, resolvers) result = graphql(schema, "{ user { firstName } }") assert result.errors is None assert result.data == {"user": {"firstName": "Joe"}}
def test_allows_querying_the_schema_for_types(): query = """ query IntrospectionTypeQuery { __schema { types { name } } } """ expected = { "__schema": { "types": [ {"name": "Query"}, {"name": "Episode"}, {"name": "Character"}, {"name": "String"}, {"name": "Human"}, {"name": "Droid"}, {"name": "__Schema"}, {"name": "__Type"}, {"name": "__TypeKind"}, {"name": "Boolean"}, {"name": "__Field"}, {"name": "__InputValue"}, {"name": "__EnumValue"}, {"name": "__Directive"}, {"name": "__DirectiveLocation"}, ] } } result = graphql(StarWarsSchema, query) assert not result.errors assert contain_subset(result.data, expected)
def test_fails_on_a_very_deep_non_null(): schema = GraphQLSchema(query=GraphQLObjectType( name="Query", fields={ "foo": GraphQLField( GraphQLList( GraphQLList( GraphQLList( GraphQLList( GraphQLList( GraphQLList( GraphQLList( GraphQLList( GraphQLNonNull( GraphQLString)))))))))) }, )) introspection = graphql(schema, introspection_query) with raises(Exception) as excinfo: build_client_schema(introspection.data) assert str( excinfo.value) == "Decorated type deeper than introspection query."
def execute(self, *args, sync=True, **kwargs): """Execute a GraphQL operation on this schema Args: sync: If True (the default), run the query syncronously and return the result. Return a coroutine otherwise. variables: (deprecated) variables to be passed to the query variable_values: Variables to be passed to the query (replaces "variables") *args: Extra arguments passed to graphql.graphql() **kwawrgs: Extra arguments passed to graphql.graphql() """ if "variables" in kwargs: # TODO: issue a deprecation warning? kwargs["variable_values"] = kwargs.pop("variables") compiled = self.compile() coro = graphql.graphql(compiled, *args, **kwargs) if sync: # In Python 3.7+ we could do: # return asyncio.run(coro) loop = asyncio.get_event_loop() return loop.run_until_complete(coro) return coro
def test_mutation_return_type(): type_defs = """ type Query { _: String } type Staff { name: String } type Mutation { addStaff(name: String): Staff } """ def resolve_add_staff(*_, name): assert name == "Bob" return {"name": name} resolvers = {"Mutation": {"addStaff": resolve_add_staff}} schema = make_executable_schema(type_defs, resolvers) result = graphql(schema, 'mutation { addStaff(name: "Bob") { name } }') assert result.errors is None assert result.data == {"addStaff": {"name": "Bob"}}
def test_respects_the_includedeprecated_parameter_for_enum_values(): TestEnum = GraphQLEnumType('TestEnum', OrderedDict([ ('NONDEPRECATED', GraphQLEnumValue(0)), ('DEPRECATED', GraphQLEnumValue(1, deprecation_reason='Removed in 1.0')), ('ALSONONDEPRECATED', GraphQLEnumValue(2)) ])) TestType = GraphQLObjectType('TestType', { 'testEnum': GraphQLField(TestEnum) }) schema = GraphQLSchema(TestType) request = '''{__type(name: "TestEnum") { name trueValues: enumValues(includeDeprecated: true) { name } falseValues: enumValues(includeDeprecated: false) { name } omittedValues: enumValues { name } } }''' result = graphql(schema, request) assert not result.errors assert result.data == {'__type': { 'name': 'TestEnum', 'trueValues': [{'name': 'NONDEPRECATED'}, {'name': 'DEPRECATED'}, {'name': 'ALSONONDEPRECATED'}], 'falseValues': [{'name': 'NONDEPRECATED'}, {'name': 'ALSONONDEPRECATED'}], 'omittedValues': [{'name': 'NONDEPRECATED'}, {'name': 'ALSONONDEPRECATED'}], }}
def test_object_type_can_override_interface_resolver(): R = TypeRegistry() class Pet(R.Interface): make_noise = R.String def resolve_make_noise(self, *args): return 'I am a pet, hear me roar!' class Dog(R.Implements.Pet): make_noise = R.String def resolve_make_noise(self, *args): return 'Woof woof! Bark bark!' class Query(R.ObjectType): dog = R.Dog def resolve_dog(self, *args): return Dog() schema = R.Schema(R.Query) result = graphql(schema, '{ dog { makeNoise } }') assert not result.errors assert result.data == {'dog': {'makeNoise': 'Woof woof! Bark bark!'}}
def test_hero_name_and_friends_query(): query = ''' query HeroNameAndFriendsQuery { hero { id name friends { name } } } ''' expected = { 'hero': { 'id': '2001', 'name': 'R2-D2', 'friends': [ {'name': 'Luke Skywalker'}, {'name': 'Han Solo'}, {'name': 'Leia Organa'}, ] } } result = graphql(StarWarsSchema, query) assert not result.errors assert result.data == expected
def test_gives_different_ids(): query = ''' { allObjects { id } } ''' expected = { 'allObjects': [ { 'id': 'VXNlcjox' }, { 'id': 'VXNlcjoy' }, { 'id': 'UGhvdG86MQ==' }, { 'id': 'UGhvdG86Mg==' }, ] } result = graphql(schema, query) assert not result.errors assert result.data == expected
def test_will_choose_first_resolver_of_first_defined_interface(): R = TypeRegistry() class Pet(R.Interface): make_noise = R.String def resolve_make_noise(self, *args): return 'I am a pet, hear me roar!' class Barker(R.Interface): make_noise = R.String def resolve_make_noise(self, *args): return 'Woof, woof!!' class Dog(R.Implements[Barker, Pet]): make_noise = R.String class Query(R.ObjectType): dog = R.Dog def resolve_dog(self, *args): return Dog() schema = R.Schema(R.Query) result = graphql(schema, '{ dog { makeNoise } }') assert not result.errors assert result.data == {'dog': {'makeNoise': 'Woof, woof!!'}}
def test_respects_the_includedeprecated_parameter_for_fields(): TestType = GraphQLObjectType( "TestType", OrderedDict( [ ("nonDeprecated", GraphQLField(GraphQLString)), ( "deprecated", GraphQLField(GraphQLString, deprecation_reason="Removed in 1.0"), ), ] ), ) schema = GraphQLSchema(TestType) request = """{__type(name: "TestType") { name trueFields: fields(includeDeprecated: true) { name } falseFields: fields(includeDeprecated: false) { name } omittedFields: fields { name } } }""" result = graphql(schema, request) assert not result.errors assert result.data == { "__type": { "name": "TestType", "trueFields": [{"name": "nonDeprecated"}, {"name": "deprecated"}], "falseFields": [{"name": "nonDeprecated"}], "omittedFields": [{"name": "nonDeprecated"}], } }
def test_refetches_the_ids(): query = ''' { user: node(id: "VXNlcjox") { id ... on User { name } }, photo: node(id: "UGhvdG86MQ==") { id ... on Photo { width } } } ''' expected = { 'user': { 'id': 'VXNlcjox', 'name': 'John Doe' }, 'photo': { 'id': 'UGhvdG86MQ==', 'width': 300 } } result = graphql(schema, query) assert not result.errors assert result.data == expected
def test_exposes_descriptions_on_enums(): QueryRoot = GraphQLObjectType("QueryRoot", {"f": GraphQLField(GraphQLString)}) schema = GraphQLSchema(QueryRoot) request = """{ typeKindType: __type(name: "__TypeKind") { name, description, enumValues { name, description } } } """ result = graphql(schema, request) assert not result.errors assert result.data == { "typeKindType": { "name": "__TypeKind", "description": "An enum describing what kind of type a given `__Type` is", "enumValues": [ {"description": "Indicates this type is a scalar.", "name": "SCALAR"}, { "description": "Indicates this type is an object. " + "`fields` and `interfaces` are valid fields.", "name": "OBJECT", }, { "description": "Indicates this type is an interface. " + "`fields` and `possibleTypes` are valid fields.", "name": "INTERFACE", }, { "description": "Indicates this type is a union. " + "`possibleTypes` is a valid field.", "name": "UNION", }, { "description": "Indicates this type is an enum. " + "`enumValues` is a valid field.", "name": "ENUM", }, { "description": "Indicates this type is an input object. " + "`inputFields` is a valid field.", "name": "INPUT_OBJECT", }, { "description": "Indicates this type is a list. " + "`ofType` is a valid field.", "name": "LIST", }, { "description": "Indicates this type is a non-null. " + "`ofType` is a valid field.", "name": "NON_NULL", }, ], } }
def test_respects_the_includedeprecated_parameter_for_fields(): TestType = GraphQLObjectType( 'TestType', OrderedDict([('nonDeprecated', GraphQLField(GraphQLString)), ('deprecated', GraphQLField(GraphQLString, deprecation_reason='Removed in 1.0'))])) schema = GraphQLSchema(TestType) request = '''{__type(name: "TestType") { name trueFields: fields(includeDeprecated: true) { name } falseFields: fields(includeDeprecated: false) { name } omittedFields: fields { name } } }''' result = graphql(schema, request) assert not result.errors assert result.data == { '__type': { 'name': 'TestType', 'trueFields': [{ 'name': 'nonDeprecated' }, { 'name': 'deprecated' }], 'falseFields': [{ 'name': 'nonDeprecated' }], 'omittedFields': [{ 'name': 'nonDeprecated' }], } }
def test_relay_node_field_resolver(): data_source = InMemoryDataSource() R = TypeRegistry() Relay = R.Mixin(RelayMixin, data_source) class Pet(R.Implements[R.Node]): name = R.String class Query(R.ObjectType): pets = R.Pet.List node = Relay.NodeField schema = R.Schema(R.Query) data_source.add(Pet(id=5, name='Garfield')) data_source.add(Pet(id=6, name='Odis')) result = graphql(schema, ''' { node(id: "UGV0OjU=") { id, ... on Pet { name } } } ''') assert not result.errors assert result.data == {'node': {'id': 'UGV0OjU=', 'name': 'Garfield'}}
def test_is_type_of_used_to_resolve_runtime_type_for_interface(): PetType = GraphQLInterfaceType( name='Pet', fields={ 'name': GraphQLField(GraphQLString) } ) DogType = GraphQLObjectType( name='Dog', interfaces=[PetType], is_type_of=is_type_of(Dog), fields={ 'name': GraphQLField(GraphQLString), 'woofs': GraphQLField(GraphQLBoolean) } ) CatType = GraphQLObjectType( name='Cat', interfaces=[PetType], is_type_of=is_type_of(Cat), fields={ 'name': GraphQLField(GraphQLString), 'meows': GraphQLField(GraphQLBoolean) } ) schema = GraphQLSchema( query=GraphQLObjectType( name='Query', fields={ 'pets': GraphQLField( GraphQLList(PetType), resolver=lambda *_: [Dog('Odie', True), Cat('Garfield', False)] ) } ), types=[CatType, DogType] ) query = ''' { pets { name ... on Dog { woofs } ... on Cat { meows } } } ''' result = graphql(schema, query) assert not result.errors assert result.data == {'pets': [{'woofs': True, 'name': 'Odie'}, {'name': 'Garfield', 'meows': False}]}
def test_simple_mutation(): R = TypeRegistry() class SimpleAddition(R.Mutation): class Input: a = R.Int b = R.Int class Output: sum = R.Int def execute(self, obj, input, info): return self.Output(sum=input.a + input.b) class SimpleMultiplication(R.Mutation): class Input: a = R.Int.List class Output: product = R.Int input = R.Int.List def execute(self, obj, input, info): return self.Output( input=input.a, product=reduce(operator.mul, input.a[1:], input.a[0]) ) # Dummy query -- does nothing. class Query(R.ObjectType): foo = R.String Schema = R.Schema(R.Query, R.Mutations) mutation_query = ''' mutation testSimpleAdd { simpleAddition(input: {a: 5, b: 10}) { sum } simpleMultiplication(input: {a: [1, 2, 3, 4, 5]}) { product input } } ''' result = graphql(Schema, mutation_query) assert not result.errors assert result.data == { 'simpleAddition': { 'sum': 15 }, 'simpleMultiplication': { 'product': 120, 'input': [1, 2, 3, 4, 5] } }
def test_default_function_accesses_properties(): schema = _test_schema(GraphQLField(GraphQLString)) class source: test = 'testValue' result = graphql(schema, '{ test }', source) assert not result.errors assert result.data == {'test': 'testValue'}
def test_object_type_as_data(): jake = Human(name='Jake', favorite_color='Red') assert jake.name == 'Jake' assert jake.favorite_color == 'Red' assert repr(jake) == '<Human name={!r} favorite_color={!r}>'.format(jake.name, jake.favorite_color) result = graphql(Schema, '{ name favoriteColor }', jake) assert not result.errors assert result.data == {'name': 'Jake', 'favoriteColor': 'Red'}
def test_object_type_as_data_with_partial_fields_provided(): jake = Human(name='Jake') assert jake.name == 'Jake' assert jake.favorite_color is None assert repr(jake) == '<Human name={!r} favorite_color={!r}>'.format(jake.name, jake.favorite_color) result = graphql(Schema, '{ name favoriteColor }', jake) assert not result.errors assert result.data == {'name': 'Jake', 'favoriteColor': None}
def test_has_correct_node_root_field(): query = ''' { __schema { queryType { fields { name type { name kind } args { name type { kind ofType { name kind } } } } } } } ''' expected = { '__schema': { 'queryType': { 'fields': [ { 'name': 'node', 'type': { 'name': 'Node', 'kind': 'INTERFACE' }, 'args': [ { 'name': 'id', 'type': { 'kind': 'NON_NULL', 'ofType': { 'name': 'ID', 'kind': 'SCALAR' } } } ] } ] } } } result = graphql(schema, query) assert not result.errors assert result.data == expected