mirror of
https://github.com/graphql-python/graphene.git
synced 2025-02-02 12:44:15 +03:00
Add experimental mutation decorator
This commit is contained in:
parent
0a5c8c1268
commit
48f249af3b
0
graphene/experimental/__init__.py
Normal file
0
graphene/experimental/__init__.py
Normal file
0
graphene/experimental/decorators/__init__.py
Normal file
0
graphene/experimental/decorators/__init__.py
Normal file
23
graphene/experimental/decorators/mutation.py
Normal file
23
graphene/experimental/decorators/mutation.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
from graphene.types.field import Field
|
||||
from graphene.utils.str_converters import to_camel_case
|
||||
|
||||
|
||||
def mutation(return_type, arguments=None, **kwargs):
|
||||
# TODO: validate input arguments
|
||||
if arguments is None:
|
||||
arguments = {}
|
||||
|
||||
def decorate(resolver_function):
|
||||
name = kwargs.pop("name", None) or resolver_function.__name__
|
||||
description = kwargs.pop("description", None) or resolver_function.__doc__
|
||||
|
||||
return Field(
|
||||
return_type,
|
||||
args=arguments,
|
||||
name=to_camel_case(name),
|
||||
resolver=resolver_function,
|
||||
description=description,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
return decorate
|
0
graphene/experimental/decorators/tests/__init__.py
Normal file
0
graphene/experimental/decorators/tests/__init__.py
Normal file
162
graphene/experimental/decorators/tests/test_mutation.py
Normal file
162
graphene/experimental/decorators/tests/test_mutation.py
Normal file
|
@ -0,0 +1,162 @@
|
|||
from textwrap import dedent
|
||||
|
||||
from graphene import String, ObjectType, Schema, Union, Field
|
||||
|
||||
from ..mutation import mutation
|
||||
|
||||
|
||||
def test_mutation_basic():
|
||||
@mutation(String, required=True)
|
||||
def my_mutation(root, info):
|
||||
return "hi"
|
||||
|
||||
class Query(ObjectType):
|
||||
a = String()
|
||||
|
||||
schema = Schema(query=Query, mutations=[my_mutation])
|
||||
result = schema.execute(
|
||||
"""
|
||||
mutation MyMutation {
|
||||
myMutation
|
||||
}
|
||||
"""
|
||||
)
|
||||
|
||||
assert not result.errors
|
||||
assert result.data == {"myMutation": "hi"}
|
||||
|
||||
|
||||
def test_mutation_arguments():
|
||||
@mutation(String, required=True, arguments={"name": String(required=True)})
|
||||
def my_mutation(root, info, name):
|
||||
return f"hi {name}"
|
||||
|
||||
class Query(ObjectType):
|
||||
a = String()
|
||||
|
||||
schema = Schema(query=Query, mutations=[my_mutation])
|
||||
result = schema.execute(
|
||||
"""
|
||||
mutation MyMutation {
|
||||
myMutation(name: "world")
|
||||
}
|
||||
"""
|
||||
)
|
||||
|
||||
assert not result.errors
|
||||
assert result.data == {"myMutation": "hi world"}
|
||||
|
||||
|
||||
def test_mutation_field_options():
|
||||
@mutation(
|
||||
String,
|
||||
required=True,
|
||||
arguments={"name": String(required=True)},
|
||||
name="other_mutation",
|
||||
deprecation_reason="Don't use this mutation",
|
||||
description="Some description",
|
||||
)
|
||||
def my_mutation(root, info, name):
|
||||
return f"hi {name}"
|
||||
|
||||
class Query(ObjectType):
|
||||
a = String()
|
||||
|
||||
schema = Schema(query=Query, mutations=[my_mutation])
|
||||
result = schema.execute(
|
||||
"""
|
||||
mutation MyMutation {
|
||||
otherMutation(name: "world")
|
||||
}
|
||||
"""
|
||||
)
|
||||
|
||||
assert not result.errors
|
||||
assert result.data == {"otherMutation": "hi world"}
|
||||
|
||||
assert str(schema) == dedent(
|
||||
"""\
|
||||
type Query {
|
||||
a: String
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
\"\"\"Some description\"\"\"
|
||||
otherMutation(name: String!): String! @deprecated(reason: \"Don't use this mutation\")
|
||||
}
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def test_mutation_complex_return():
|
||||
class User(ObjectType):
|
||||
name = String(required=True)
|
||||
|
||||
class CreateUserSuccess(ObjectType):
|
||||
user = Field(User, required=True)
|
||||
|
||||
class CreateUserError(ObjectType):
|
||||
error_message = String(required=True)
|
||||
|
||||
class CreateUserOutput(Union):
|
||||
class Meta:
|
||||
types = [
|
||||
CreateUserSuccess,
|
||||
CreateUserError,
|
||||
]
|
||||
|
||||
@mutation(
|
||||
CreateUserOutput, required=True, arguments={"name": String(required=True)}
|
||||
)
|
||||
def create_user(root, info, name):
|
||||
return CreateUserSuccess(user=User(name=name))
|
||||
|
||||
class Query(ObjectType):
|
||||
a = String()
|
||||
|
||||
schema = Schema(query=Query, mutations=[create_user])
|
||||
result = schema.execute(
|
||||
"""
|
||||
mutation CreateUserMutation {
|
||||
createUser(name: "Kate") {
|
||||
__typename
|
||||
... on CreateUserSuccess {
|
||||
user {
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
)
|
||||
|
||||
assert not result.errors
|
||||
assert result.data == {
|
||||
"createUser": {"__typename": "CreateUserSuccess", "user": {"name": "Kate"}}
|
||||
}
|
||||
|
||||
assert str(schema) == dedent(
|
||||
"""\
|
||||
type Query {
|
||||
a: String
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
createUser(name: String!): CreateUserOutput!
|
||||
}
|
||||
|
||||
union CreateUserOutput = CreateUserSuccess | CreateUserError
|
||||
|
||||
type CreateUserSuccess {
|
||||
user: User!
|
||||
}
|
||||
|
||||
type User {
|
||||
name: String!
|
||||
}
|
||||
|
||||
type CreateUserError {
|
||||
errorMessage: String!
|
||||
}
|
||||
"""
|
||||
)
|
Loading…
Reference in New Issue
Block a user