mirror of
https://github.com/graphql-python/graphene.git
synced 2024-11-22 17:46:57 +03:00
Fixed Union and Interface resolve_type when the field is a List/NonNull
This commit is contained in:
parent
3c99302ed6
commit
6817761a08
|
@ -4,12 +4,14 @@ from functools import partial
|
|||
from graphql import Source, execute, parse, GraphQLError
|
||||
|
||||
from ..field import Field
|
||||
from ..interface import Interface
|
||||
from ..inputfield import InputField
|
||||
from ..inputobjecttype import InputObjectType
|
||||
from ..objecttype import ObjectType
|
||||
from ..scalars import Int, String
|
||||
from ..schema import Schema
|
||||
from ..structures import List
|
||||
from ..union import Union
|
||||
from ..dynamic import Dynamic
|
||||
|
||||
|
||||
|
@ -24,6 +26,99 @@ def test_query():
|
|||
assert executed.data == {'hello': 'World'}
|
||||
|
||||
|
||||
def test_query_union():
|
||||
class one_object(object):
|
||||
pass
|
||||
|
||||
class two_object(object):
|
||||
pass
|
||||
|
||||
class One(ObjectType):
|
||||
one = String()
|
||||
|
||||
@classmethod
|
||||
def is_type_of(cls, root, context, info):
|
||||
return isinstance(root, one_object)
|
||||
|
||||
class Two(ObjectType):
|
||||
two = String()
|
||||
|
||||
@classmethod
|
||||
def is_type_of(cls, root, context, info):
|
||||
return isinstance(root, two_object)
|
||||
|
||||
class MyUnion(Union):
|
||||
class Meta:
|
||||
types = (One, Two)
|
||||
|
||||
class Query(ObjectType):
|
||||
unions = List(MyUnion)
|
||||
|
||||
def resolve_unions(self, args, context, info):
|
||||
return [one_object(), two_object()]
|
||||
|
||||
hello_schema = Schema(Query)
|
||||
|
||||
executed = hello_schema.execute('{ unions { __typename } }')
|
||||
assert not executed.errors
|
||||
assert executed.data == {
|
||||
'unions': [{
|
||||
'__typename': 'One'
|
||||
}, {
|
||||
'__typename': 'Two'
|
||||
}]
|
||||
}
|
||||
|
||||
|
||||
def test_query_interface():
|
||||
class one_object(object):
|
||||
pass
|
||||
|
||||
class two_object(object):
|
||||
pass
|
||||
|
||||
class MyInterface(Interface):
|
||||
base = String()
|
||||
|
||||
class One(ObjectType):
|
||||
class Meta:
|
||||
interfaces = (MyInterface, )
|
||||
|
||||
one = String()
|
||||
|
||||
@classmethod
|
||||
def is_type_of(cls, root, context, info):
|
||||
return isinstance(root, one_object)
|
||||
|
||||
class Two(ObjectType):
|
||||
class Meta:
|
||||
interfaces = (MyInterface, )
|
||||
|
||||
two = String()
|
||||
|
||||
@classmethod
|
||||
def is_type_of(cls, root, context, info):
|
||||
return isinstance(root, two_object)
|
||||
|
||||
class Query(ObjectType):
|
||||
interfaces = List(MyInterface)
|
||||
|
||||
def resolve_interfaces(self, args, context, info):
|
||||
return [one_object(), two_object()]
|
||||
|
||||
hello_schema = Schema(Query, types=[One, Two])
|
||||
|
||||
executed = hello_schema.execute('{ interfaces { __typename } }')
|
||||
assert not executed.errors
|
||||
assert executed.data == {
|
||||
'interfaces': [{
|
||||
'__typename': 'One'
|
||||
}, {
|
||||
'__typename': 'Two'
|
||||
}]
|
||||
}
|
||||
|
||||
|
||||
def test_query_dynamic():
|
||||
class Query(ObjectType):
|
||||
hello = Dynamic(lambda: String(resolver=lambda *_: 'World'))
|
||||
|
|
|
@ -30,18 +30,18 @@ def is_graphene_type(_type):
|
|||
return True
|
||||
|
||||
|
||||
def resolve_type(resolve_type_func, map, root, context, info):
|
||||
def resolve_type(resolve_type_func, map, type_name, root, context, info):
|
||||
_type = resolve_type_func(root, context, info)
|
||||
# assert inspect.isclass(_type) and issubclass(_type, ObjectType), (
|
||||
# 'Received incompatible type "{}".'.format(_type)
|
||||
# )
|
||||
|
||||
if not _type:
|
||||
return get_default_resolve_type_fn(root, context, info, info.return_type)
|
||||
return_type = map[type_name]
|
||||
return get_default_resolve_type_fn(root, context, info, return_type)
|
||||
|
||||
if inspect.isclass(_type) and issubclass(_type, ObjectType):
|
||||
graphql_type = map.get(_type._meta.name)
|
||||
assert graphql_type and graphql_type.graphene_type == _type
|
||||
return graphql_type
|
||||
|
||||
return _type
|
||||
|
||||
|
||||
|
@ -151,7 +151,7 @@ class TypeMap(GraphQLTypeMap):
|
|||
from .definitions import GrapheneInterfaceType
|
||||
_resolve_type = None
|
||||
if type.resolve_type:
|
||||
_resolve_type = partial(resolve_type, type.resolve_type, map)
|
||||
_resolve_type = partial(resolve_type, type.resolve_type, map, type._meta.name)
|
||||
map[type._meta.name] = GrapheneInterfaceType(
|
||||
graphene_type=type,
|
||||
name=type._meta.name,
|
||||
|
@ -178,7 +178,7 @@ class TypeMap(GraphQLTypeMap):
|
|||
from .definitions import GrapheneUnionType
|
||||
_resolve_type = None
|
||||
if type.resolve_type:
|
||||
_resolve_type = partial(resolve_type, type.resolve_type, map)
|
||||
_resolve_type = partial(resolve_type, type.resolve_type, map, type._meta.name)
|
||||
types = []
|
||||
for i in type._meta.types:
|
||||
map = self.construct_objecttype(map, i)
|
||||
|
|
Loading…
Reference in New Issue
Block a user