def test_enum_type_is_able_to_represent_enum_default_value_in_schema(): # regression test for: https://github.com/mirumee/ariadne/issues/293 type_defs = """ enum Role { ADMIN USER } type Query { hello(r: Role = USER): String } """ class Role(Enum): ADMIN = "admin" USER = "******" def resolve_test_enum(*_, r): return r == Role.USER RoleGraphQLType = EnumType("Role", Role) QueryGraphQLType = QueryType() QueryGraphQLType.set_field("hello", resolve_test_enum) schema = make_executable_schema( type_defs, QueryGraphQLType, RoleGraphQLType, ) query = "{__schema{types{name,fields{name,args{name,defaultValue}}}}}" _, result = ariadne_graphql_sync(schema, {"query": query}, debug=True) types_map = { result_type["name"]: result_type for result_type in result["data"]["__schema"]["types"] } assert schema.type_map["Query"].fields["hello"].args[ "r"].default_value == Role.USER result_hello_query = graphql_sync(schema, "{hello}") assert types_map["Query"]["fields"][0]["args"][0]["defaultValue"] == "USER" assert result_hello_query.data["hello"] assert result_hello_query.errors is None
def test_types_not_included_in_the_union_are_rejected(): @strawberry.type class Outside: c: int @strawberry.type class A: a: int @strawberry.type class B: b: int @strawberry.type class Mutation: @strawberry.mutation def hello(self, info) -> Union[A, B]: return Outside(c=5) # type:ignore schema = strawberry.Schema(query=A, mutation=Mutation) query = """ mutation { hello { __typename ... on A { a } ... on B { b } } } """ result = graphql_sync(schema, query) assert ( result.errors[0].message == "The type " "\"<class 'tests.test_union.test_types_not_included_in_the_union_are_rejected.<locals>.Outside'>\"" # noqa ' of the field "hello" ' "is not in the list of the types of the union: \"['A', 'B']\"" )
def test_federated_schema_execute_reference_resolver_that_returns_none(): type_defs = """ type Query { rootField: String } type Product @key(fields: "upc") { upc: Int name: String } """ product = FederatedObjectType("Product") @product.reference_resolver() def product_reference_resolver(_obj, _info, reference): assert reference["upc"] == 1 # return None schema = make_federated_schema(type_defs, product) result = graphql_sync( schema, """ query GetEntities($representations: [_Any!]!) { _entities(representations: $representations) { ... on Product { __typename name } } } """, variable_values={ "representations": [ { "__typename": "Product", "upc": 1, }, ], }, ) assert result.errors is None assert result.data["_entities"][0] is None
def test_enum_description(): @strawberry.enum(description="We love ice-creams") class IceCreamFlavour(Enum): VANILLA = "vanilla" STRAWBERRY = "strawberry" CHOCOLATE = "chocolate" @strawberry.enum class PizzaType(Enum): """We also love pizza""" MARGHERITA = "margherita" @strawberry.type class Query: favorite_ice_cream: IceCreamFlavour = IceCreamFlavour.STRAWBERRY pizza: PizzaType = PizzaType.MARGHERITA schema = strawberry.Schema(query=Query) query = """{ iceCreamFlavour: __type(name: "IceCreamFlavour") { description enumValues { name description } } pizzas: __type(name: "PizzaType") { description } }""" result = graphql_sync(schema, query) assert not result.errors assert result.data["iceCreamFlavour"]["description"] == "We love ice-creams" assert result.data["iceCreamFlavour"]["enumValues"] == [ {"name": "VANILLA", "description": None}, {"name": "STRAWBERRY", "description": None}, {"name": "CHOCOLATE", "description": None}, ] assert result.data["pizzas"]["description"] == "We also love pizza"
def test_query_object(query: str, variables: dict, expected_result_query: dict): """ Test how Query Object is generated """ # Prepare our schema schema = graphql.build_schema(schema_prepare()) # GraphQL resolver @resolves(schema, 'Query', 'object') @resolves(schema, 'Model', 'object') def resolve_object(obj, info: GraphQLResolveInfo, query: QueryObjectDict = None): query_object = query_object_for(info, runtime_type='Model') return { 'id': 1, 'query': query_object.dict(), } @resolves(schema, 'Query', 'objects') @resolves(schema, 'Model', 'objects') def resolve_objects(obj, info: GraphQLResolveInfo, query: QueryObjectDict = None): query_object = query_object_for(info, runtime_type='Model') return [ { 'id': 1, 'query': query_object.dict(), }, ] @resolves(schema, 'Query', 'getObject') def resolve_object(obj, info: GraphQLResolveInfo, id: int, query: QueryObjectDict = None) -> int: # just fail in case of bugs when getting the QueryObject query_object = query_object_for(info, runtime_type='Model') # Execute res = graphql_sync(schema, query, variable_values=variables) if res.errors: raise res.errors[0] assert res.data == expected_result_query
def test_field_description(): @strawberry.type class Query: a: str = strawberry.field(description="Example") @strawberry.field def b(self, info, id: int) -> str: return "I'm a resolver" @strawberry.field(description="Example C") def c(self, info, id: int) -> str: return "I'm a resolver" @strawberry.field def d(self, info, id: int) -> str: """Example D""" return "I'm a resolver" @strawberry.field(description="Inline description") def e(self, info, id: int) -> str: """Doc string description""" return "I'm a resolver" schema = strawberry.Schema(query=Query) query = """{ __type(name: "Query") { fields { name description } } }""" result = graphql_sync(schema, query) assert not result.errors assert result.data["__type"]["fields"] == [ {"name": "a", "description": "Example"}, {"name": "b", "description": None}, {"name": "c", "description": "Example C"}, {"name": "d", "description": "Example D"}, {"name": "e", "description": "Inline description"}, ]
def using_objects(): class Human: __typename = "Human" name = "Han Solo" totalCredits = 10 class Droid: __typename = "Droid" name = "R2-D2" primaryFunction = "Astromech" class RootValue: characters = [Human(), Droid()] assert ( graphql_sync(schema=schema, source=source, root_value=RootValue()) == expected )
async def throws_if_encountering_async_operation_without_check_sync(): doc = "query Example { syncField, asyncField }" result = graphql_sync(schema, doc, "rootValue") assert result == ( { "syncField": "rootValue", "asyncField": None }, [{ "message": "String cannot represent value:" " <coroutine _resolve_async>", "locations": [(1, 28)], "path": ["asyncField"], }], ) # garbage collect coroutine in order to not postpone the warning del result collect()
def resolve(self, server, request, query, operation, variables): """ Query resolver """ # get the response response = graphql_sync(schema, query, None, request, variables, operation) # the result data = {"data": response.data} # if something went wrong if response.errors: # inform the client data["errors"] = [{ "message": error.message } for error in response.errors] # send it over return server.documents.JSON(server=server, value=data)
def test_selection_in_resolver(query: str, runtime_type: Optional[str], expected_result: dict): """ Test selected_field_names() when used in a resolver function """ # GraphQL resolver def resolve_object(obj, info: graphql.GraphQLResolveInfo): names = selected(info, runtime_type=runtime_type) return {'id': 1, 'name': ' '.join(sorted(names))} # return as a name # Prepare our schema schema = graphql.build_schema(GQL_SCHEMA) # Bind resolver schema.type_map['Query'].fields['object'].resolve = resolve_object schema.type_map['Object'].fields['object'].resolve = resolve_object # Execute res = graphql.graphql_sync(schema, query) assert not res.errors assert res.data == expected_result
def test_int_enum_arg_default_python_value_is_set(): enum_param_default = """ type Query { testEnum(value: Episode! = EMPIRE): Boolean! } """ query = QueryType() def resolve_test_enum(*_, value): return value == PyIntEnum.EMPIRE query.set_field("testEnum", resolve_test_enum) schema = make_executable_schema([enum_definition, enum_param_default], [query, int_enum]) result = graphql_sync(schema, "{ testEnum }") assert result.data["testEnum"] assert result.errors is None
def gets_the_correct_typename_for_photos(): source = """ { node(id: "4") { id __typename } } """ assert graphql_sync(schema, source) == ( { "node": { "id": "4", "__typename": "Photo" } }, None, )
def can_build_a_schema_directly_from_the_source(): schema = build_schema(""" type Query { add(x: Int, y: Int): Int } """) # noinspection PyMethodMayBeStatic class Root: def add(self, _info, x, y): return x + y assert graphql_sync(schema, "{ add(x: 34, y: 55) }", Root()) == ( { "add": 89 }, None, )
def supports_the_type_root_field(): TestType = GraphQLObjectType( 'TestType', {'testField': GraphQLField(GraphQLString)}) schema = GraphQLSchema(TestType) request = """ { __type(name: "TestType") { name } } """ assert graphql_sync(schema, request) == ({ '__type': { 'name': 'TestType', } }, None)
def serialize_with_error(): source = """ { balance } """ result = graphql_sync(schema, source, root_value=21) assert result == ( { "balance": None }, [{ "message": "Cannot serialize money value: 21", "locations": [(3, 15)], "path": ["balance"], }], )
def test_support_nested_generics(): T = typing.TypeVar("T") @strawberry.type class User: name: str @strawberry.type class Edge(typing.Generic[T]): node: T @strawberry.type class Connection(typing.Generic[T]): edge: Edge[T] @strawberry.type class Query: @strawberry.field def users(self, info, **kwargs) -> Connection[User]: return Connection(edge=Edge(node=User("Patrick"))) schema = strawberry.Schema(query=Query) query = """{ users { __typename edge { __typename node { name } } } }""" result = graphql_sync(schema, query) assert not result.errors assert result.data == { "users": { "__typename": "UserConnection", "edge": {"__typename": "UserEdge", "node": {"name": "Patrick"}}, } }
def test_flattened_converted(): data2 = deserialize(Data2, {"attr": 0}) assert isinstance(data2.data_field2, Field2) and data2.data_field2.attr == 0 assert serialize(Data2, data2) == {"attr": 0} assert (deserialization_schema(Data) == serialization_schema(Data) == { "$schema": "http://json-schema.org/draft/2019-09/schema#", "type": "object", "allOf": [ { "type": "object", "additionalProperties": False }, { "type": "object", "properties": { "attr": { "type": "integer" } }, "required": ["attr"], "additionalProperties": False, }, ], "unevaluatedProperties": False, }) schema = graphql_schema(query=[get_data2]) assert graphql_sync(schema, "{getData2{attr}}").data == { "getData2": { "attr": 0 } } assert (print_schema(schema) == """\ type Query { getData2: Data2! } type Data2 { attr: Int! } """)
def test_custom_resolver_is_called_with_arguments_passed_with_query(): type_defs = """ type Query { test(returnValue: Int!): Int } """ query = QueryType() @query.field("test") def resolve_test(*_, returnValue): # pylint: disable=unused-variable assert returnValue == 4 return "42" schema = make_executable_schema(type_defs, query) result = graphql_sync(schema, "{ test(returnValue: 4) }") assert result.errors is None assert result.data == {"test": 42}
def test_default_resolver_resolves_value_from_dict_item(): type_defs = """ type Query { test: Custom } type Custom { node: String } """ query = QueryType() query.set_field("test", lambda *_: {"node": "custom"}) schema = make_executable_schema(type_defs, query) result = graphql_sync(schema, "{ test { node } }") assert result.errors is None assert result.data == {"test": {"node": "custom"}}
def run(): q = """\ { foo: person(name: "foo") { name, age, nickname } xxx: person(name: "xxx") { name, age, nickname } } """ data = { "people": [ {"name": "boo", "age": 20}, {"name": "foo", "age": 20, "nickname": "F"}, {"name": "bar", "age": 20}, ] } result = g.graphql_sync(schema, q, Root(data)) print(result.errors) loading.dumpfile(result.data)
def test_deserialization_with_parse_literal(typing, instance, serialized): @strawberry.type class Query: deserialized = None @strawberry.field def deserialize(self, info, arg: typing) -> bool: Query.deserialized = arg return True schema = strawberry.Schema(Query) query = f"""query Deserialize {{ deserialize(arg: "{serialized}") }}""" result = graphql_sync(schema, query) assert not result.errors assert Query.deserialized == instance
def using_dicts(): root_value = { "characters": [ { "name": "Han Solo", "totalCredits": 10, "__typename": "Human" }, { "name": "R2-D2", "primaryFunction": "Astromech", "__typename": "Droid", }, ] } assert (graphql_sync(schema=schema, source=source, root_value=root_value) == expected)
def test_executing_mutation_takes_scalar_args_and_returns_scalar_sum(): type_defs = """ type Query { _: String } type Mutation { sum(a: Int, b: Int): Int } """ mutation = MutationType() mutation.set_field("sum", lambda *_, a, b: a + b) schema = make_executable_schema(type_defs, mutation) result = graphql_sync(schema, "mutation { sum(a: 1, b: 2) }") assert result.errors is None assert result.data == {"sum": 3}
def test_raises_graphql_error_when_permission_is_denied(): class IsAuthenticated(BasePermission): message = "User is not authenticated" def has_permission(self, info): return False @strawberry.type class Query: @strawberry.field(permission_classes=[IsAuthenticated]) def user(self, info) -> str: return "patrick" schema = strawberry.Schema(query=Query) query = "{ user }" result = graphql_sync(schema, query) assert result.errors[0].message == "User is not authenticated"
def dispatch(self, request, *args, **kwargs): if request.method.lower() not in ("get", "post"): return HttpResponseNotAllowed( ["GET", "POST"], "GraphQL only supports GET and POST requests.") if "text/html" in request.META.get("HTTP_ACCEPT", ""): return render( request, "graphql/playground.html", {"REQUEST_PATH": request.get_full_path()}, ) data = json.loads(request.body) try: query = data["query"] variables = data.get("variables") operation_name = data.get("operationName") except KeyError: return HttpResponseBadRequest( "No GraphQL query found in the request") context = {"request": request} result = graphql_sync( self.schema, query, variable_values=variables, context_value=context, operation_name=operation_name, ) response_data = {"data": result.data} if result.errors: response_data["errors"] = [ format_graphql_error(err) for err in result.errors ] self._capture_sentry_exceptions(result.errors) return JsonResponse(response_data, status=200)
def test_mutation(): @strawberry.type class Query: hello: str = "Hello" @strawberry.type class Mutation: @strawberry.mutation def say(self, info) -> str: return "Hello!" schema = strawberry.Schema(query=Query, mutation=Mutation) query = "mutation { say }" result = graphql_sync(schema, query) assert not result.errors assert result.data["say"] == "Hello!"
async def handler(request): data = await request.json() source = data["query"] try: variables = data["variables"] except KeyError: variables = None result = graphql_sync( schema, source, variable_values=variables, root_value=root_value ) return web.json_response( { "data": result.data, "errors": [str(e) for e in result.errors] if result.errors else None, } )
def test_deserialization(typing, name, instance, serialized): @strawberry.type class Query: deserialized = None @strawberry.field def deserialize(self, info, arg: typing) -> bool: Query.deserialized = arg return True schema = strawberry.Schema(Query) query = f"""query Deserialize($value: {name}!) {{ deserialize(arg: $value) }}""" result = graphql_sync(schema, query, variable_values={"value": serialized}) assert not result.errors assert Query.deserialized == instance
def allows_querying_the_schema_for_documentation(): query = """ query IntrospectionDroidDescriptionQuery { __type(name: "Droid") { name description } } """ expected = { "__type": { "name": "Droid", "description": "A mechanical creature in the Star Wars universe.", } } result = graphql_sync(star_wars_schema, query) assert result == (expected, None)
def specifying_union_type_using_typename(): schema = build_schema( """ type Query { fruits: [Fruit] } union Fruit = Apple | Banana type Apple { color: String } type Banana { length: Int } """ ) query = """ { fruits { ... on Apple { color } ... on Banana { length } } } """ root = { "fruits": [ {"color": "green", "__typename": "Apple"}, {"length": 5, "__typename": "Banana"}, ] } assert graphql_sync(schema, query, root) == ( {"fruits": [{"color": "green"}, {"length": 5}]}, None, )