Allow setting unmounted types with custom attributes that get carried over.

This commit is contained in:
Markus Padourek 2016-10-13 16:18:36 +01:00
parent 88ccaec8fa
commit 8fa8fba718
3 changed files with 70 additions and 5 deletions

View File

@ -44,15 +44,30 @@ def test_mutation_raises_exception_if_no_mutate():
def test_mutation_execution():
def with_metadata(gql_type, data):
setattr(gql_type, 'metadata', data)
return gql_type
class CreateUser(Mutation):
class Input:
name = String()
metadata = with_metadata(String(), 'service_key')
_Input = Input
name = String()
external = String()
def mutate(self, args, context, info):
@classmethod
def mutate(cls, root, args, context, info):
name = args.get('name')
return CreateUser(name=name)
external_data = {
'service_key': 'new_data'
}
metadata_type = dict(vars(cls._Input))['metadata']
data = external_data[getattr(metadata_type, 'metadata')]
return CreateUser(name=name, external=data)
class Query(ObjectType):
a = String()
@ -64,12 +79,14 @@ def test_mutation_execution():
result = schema.execute(''' mutation mymutation {
createUser(name:"Peter") {
name
external
}
}
''')
assert not result.errors
assert result.data == {
'createUser': {
'name': "Peter"
'name': 'Peter',
'external': 'new_data',
}
}

View File

@ -56,6 +56,36 @@ def test_query_wrong_default_value():
assert executed.data == {'hello': None}
def test_query_unmounted_type_with_custom_attributes():
def set_custom_metadata(gql_type):
setattr(gql_type, 'metadata', 'some_key')
return gql_type
class MyType(ObjectType):
field = set_custom_metadata(String())
@classmethod
def from_metadata(cls):
my_type = cls()
external_data = {
'some_key': 'my_data'
}
for field_name, field_value in cls._meta.fields.items():
data = external_data[getattr(field_value, 'metadata')]
setattr(my_type, field_name, data)
return my_type
class Query(ObjectType):
hello = Field(MyType, resolver=lambda *_: MyType.from_metadata())
hello_schema = Schema(Query)
executed = hello_schema.execute('{ hello { field } }')
assert not executed.errors
assert executed.data == {'hello': {'field': 'my_data'}}
def test_query_default_value_ignored_by_resolver():
class MyType(ObjectType):
field = String()

View File

@ -19,34 +19,52 @@ class UnmountedType(OrderedType):
super(UnmountedType, self).__init__()
self.args = args
self.kwargs = kwargs
self.custom_attributes = {}
def get_type(self):
raise NotImplementedError("get_type not implemented in {}".format(self))
def __setattr__(self, name, value):
if hasattr(self, 'custom_attributes'):
self.custom_attributes[name] = value
OrderedType.__setattr__(self, name, value)
def Field(self): # noqa: N802
'''
Mount the UnmountedType as Field
'''
from .field import Field
return Field(
f = Field(
self.get_type(),
*self.args,
_creation_counter=self.creation_counter,
**self.kwargs
)
if hasattr(self, 'custom_attributes'):
for name, value in self.custom_attributes.items():
setattr(f, name, value)
return f
def InputField(self): # noqa: N802
'''
Mount the UnmountedType as InputField
'''
from .inputfield import InputField
return InputField(
f = InputField(
self.get_type(),
*self.args,
_creation_counter=self.creation_counter,
**self.kwargs
)
if hasattr(self, 'custom_attributes'):
for name, value in self.custom_attributes.items():
setattr(f, name, value)
return f
def Argument(self): # noqa: N802
'''
Mount the UnmountedType as Argument