def test_simple_mutation_is_converted_to_object_query(): QueryRoot = g.ObjectType( "Query", ( g.field("query_value", type=g.Int), ), ) MutationRoot = g.ObjectType( "Mutation", ( g.field("mutation_value", type=g.Int), ), ) graphql_query = """ mutation { mutationValue } """ object_query = _document_text_to_graph_query(graphql_query, query_type=QueryRoot, mutation_type=MutationRoot) assert_that(object_query, is_query( MutationRoot( g.key("mutationValue", MutationRoot.fields.mutation_value()), ), ))
def graphlayer_performance(): import graphlayer as g from graphlayer import graphql User = g.ObjectType("User", fields=( g.field("id", type=g.Int), g.field("name", type=g.String), )) Query = g.ObjectType("Query", fields=(g.field("users", type=g.ListType(User)), )) root_resolver = g.root_object_resolver(Query) @root_resolver.field(Query.fields.users) def root_resolve_users(graph, query, args): return graph.resolve(query) @g.resolver(g.ListType(User)) def resolve_users(graph, query): return [ query.element_query.create_object( dict((field_query.key, getattr(user, field_query.field.name)) for field_query in query.element_query.fields)) for user in users ] resolvers = (root_resolver, resolve_users) graph_definition = g.define_graph(resolvers=resolvers) graph = graph_definition.create_graph({}) return lambda document_text: graphql.execute( graph=graph, document_text=document_text, query_type=Query)
def test_object_builder_getters_access_value_directly(self): User = g.ObjectType("User", fields=( g.field("name", type=g.String), g.field("email_address", type=g.String), )) object_builder = g.create_object_builder( User( g.key("n", User.fields.name()), g.key("e", User.fields.email_address()), )) @object_builder.getter(User.fields.name) def resolve_name(user): return user["name"] @object_builder.getter(User.fields.email_address) def resolve_email_address(user): return user["emailAddress"] result = object_builder({ "name": "Bob", "emailAddress": "*****@*****.**" }) assert_that(result, has_attrs( n="Bob", e="*****@*****.**", ))
def test_can_get_scalar_from_root(): Root = g.ObjectType( "Root", fields=[ g.field("one", type=g.Int), g.field("two", type=g.Int), ], ) @g.resolver(Root) def resolve_root(graph, query): values = dict( one=1, two=2, ) return query.create_object( iterables.to_dict((field_query.key, values[field_query.field.name]) for field_query in query.fields)) resolvers = [resolve_root] query = Root(g.key("value", Root.fields.one()), ) result = g.create_graph(resolvers).resolve(query) assert_that(result, has_attrs(value=1))
def test_can_request_fields_of_list(): Root = g.ObjectType( "Root", fields=lambda: ( g.field("one", type=g.ListType(One)), ), ) One = g.ObjectType( "One", fields=lambda: ( g.field("two", type=g.Int), ), ) graphql_query = """ query { one { two } } """ object_query = _document_text_to_graph_query(graphql_query, query_type=Root) assert_that(object_query, is_query( Root( g.key("one", Root.fields.one( g.key("two", One.fields.two()), )), ), ))
def test_fragment_can_be_spread_into_nullable_type(): User = g.ObjectType("User", fields=lambda: ( g.field("name", type=g.String), )) Root = g.ObjectType( "Root", fields=lambda: ( g.field("user", type=g.NullableType(User)), ), ) graphql_query = """ query { user { ... on User { name } } } """ object_query = _document_text_to_graph_query(graphql_query, query_type=Root) assert_that(object_query, is_query( Root( g.key("user", Root.fields.user( g.key("name", User.fields.name()), )), ), ))
def test_when_merging_fragments_then_nested_object_fields_can_overlap(): Root = g.ObjectType( "Root", fields=lambda: (g.field("user", type=User), ), ) User = g.ObjectType( "User", fields=lambda: (g.field("address", type=Address), ), ) Address = g.ObjectType( "Address", fields=lambda: ( g.field("first_line", type=g.String), g.field("city", type=g.String), g.field("postcode", type=g.String), ), ) graphql_query = """ query { ... on Root { user { address { firstLine city } } } ... on Root { user { address { city postcode } } } } """ object_query = _document_text_to_graph_query(graphql_query, query_type=Root) assert_that( object_query, is_query( Root( g.key( "user", Root.fields.user( g.key( "address", User.fields.address( g.key("firstLine", Address.fields.first_line()), g.key("city", Address.fields.city()), g.key("postcode", Address.fields.postcode()), )), )), ), ))
def test_can_recursively_resolve(): Root = g.ObjectType( "Root", fields=lambda: [ g.field("books", type=g.ListType(Book)), ], ) Book = g.ObjectType( "Book", fields=lambda: [ g.field("title", type=g.String), ], ) @g.resolver(Root) def resolve_root(graph, query): return query.create_object(iterables.to_dict( (field_query.key, graph.resolve(field_query.type_query)) for field_query in query.field_queries )) @g.resolver(g.ListType(Book)) def resolve_book(graph, query): books = [ dict(title="Leave it to Psmith"), dict(title="Pericles, Prince of Tyre"), ] return [ query.element_query.create_object(iterables.to_dict( (field_query.key, book[field_query.field.name]) for field_query in query.element_query.field_queries )) for book in books ] resolvers = [resolve_root, resolve_book] query = Root( g.key("books", Root.fields.books( g.key("title", Book.fields.title()), )), ) result = g.create_graph(resolvers).resolve(query) assert_that(result, has_attrs( books=contains_exactly( has_attrs(title="Leave it to Psmith"), has_attrs(title="Pericles, Prince of Tyre"), ), ))
def test_graphql_arg_values_from_variables_are_converted(graph_type, graphql_type, variable_value, arg_value): if callable(arg_value): arg_value = arg_value(graph_type) Root = g.ObjectType( "Root", fields=( g.field("one", type=g.Int, params=[ g.param("arg", type=graph_type), ]), ), ) graphql_query = """ query ($var: %s) { one(arg: $var) } """ % (graphql_type, ) object_query = _document_text_to_graph_query(graphql_query, query_type=Root, variables={"var": variable_value}) assert_that(object_query, is_query( Root( g.key("one", Root.fields.one( Root.fields.one.params.arg(arg_value), )), ), ))
def test_literal_graphql_arg_values_are_converted(arg_type, arg_string, arg_value): if callable(arg_value): arg_value = arg_value(arg_type) Root = g.ObjectType( "Root", fields=( g.field("one", type=g.Int, params=[ g.param("arg", type=arg_type), ]), ), ) graphql_query = """ query { one(arg: %s) } """ % (arg_string, ) object_query = _document_text_to_graph_query(graphql_query, query_type=Root) assert_that(object_query, is_query( Root( g.key("one", Root.fields.one( Root.fields.one.params.arg(arg_value), )), ), ))
def test_graphql_field_args_are_converted_to_snake_case(): Root = g.ObjectType( "Root", fields=( g.field("one", type=g.Int, params=[ g.param("arg_zero", type=g.String), ]), ), ) graphql_query = """ query { one(argZero: "one") } """ object_query = _document_text_to_graph_query(graphql_query, query_type=Root) assert_that(object_query, is_query( Root( g.key("one", Root.fields.one( Root.fields.one.params.arg_zero("one"), )), ), ))
def test_typename(): Root = g.ObjectType("Root", fields=(g.field("value", g.String), )) root_resolver = g.root_object_resolver(Root) @root_resolver.field(Root.fields.value) def root_resolve_value(graph, query, args): return "resolved" graph_definition = g.define_graph(resolvers=(root_resolver, )) graph = graph_definition.create_graph({}) query = """ query { __typename value typename: __typename } """ result = graphql.execute(graph=graph, document_text=query, query_type=Root) assert_that( result, is_success(data=equal_to({ "__typename": "Root", "value": "resolved", "typename": "Root" })))
def test_when_field_value_in_input_object_in_list_is_not_set_then_default_is_used(): Input = schema.InputObjectType( "Input", fields=( schema.input_field("field0", type=schema.Int, default=42), ), ) Root = g.ObjectType( "Root", fields=( g.field("one", type=g.Int, params=[ g.param("arg", type=g.ListType(Input)), ]), ), ) graphql_query = """ query { one(arg: [{}]) } """ object_query = _document_text_to_graph_query(graphql_query, query_type=Root) assert_that(object_query.field_queries[0].args.arg, is_sequence( has_attrs( field0=42, ), ))
def test_named_fragments_are_expanded(): Root = g.ObjectType( "Root", ( g.field("value", type=g.Int), ), ) graphql_query = """ query { one: value ...Two three: value ...Four } fragment Two on Root { two: value } fragment Four on Root { four: value } """ object_query = _document_text_to_graph_query(graphql_query, query_type=Root) assert_that(object_query, is_query( Root( g.key("one", Root.fields.value()), g.key("two", Root.fields.value()), g.key("three", Root.fields.value()), g.key("four", Root.fields.value()), ), ))
def test_directives_can_use_variables(self): Root = g.ObjectType( "Root", ( g.field("one", type=g.Int), ), ) graphql_query = """ query ($t: Boolean!, $f: Boolean!) { includedField: one @include(if: $t) excludedField: one @include(if: $f) } """ object_query = _document_text_to_graph_query( graphql_query, query_type=Root, variables={"t": True, "f": False}, ) assert_that(object_query, is_query( Root( g.key("includedField", Root.fields.one()), ), ))
def test_directives_can_be_used_on_fragment_spreads(self): Root = g.ObjectType( "Root", ( g.field("one", type=g.Int), ), ) graphql_query = """ query { ... IncludedFragment @include(if: true) ... ExcludedFragment @include(if: false) } fragment IncludedFragment on Root { includedField: one } fragment ExcludedFragment on Root { excludedField: one } """ object_query = _document_text_to_graph_query(graphql_query, query_type=Root) assert_that(object_query, is_query( Root( g.key("includedField", Root.fields.one()), ), ))
def test_can_query_schema_with_other_data(): Root = g.ObjectType("Root", fields=(g.field("value", g.String), )) root_resolver = g.root_object_resolver(Root) @root_resolver.field(Root.fields.value) def root_resolve_value(graph, query, args): return "resolved" graph_definition = g.define_graph(resolvers=(root_resolver, )) graph = graph_definition.create_graph({}) query = """ query { value __schema { queryType { name } } } """ result = graphql.execute(graph=graph, document_text=query, query_type=Root) assert_that( result, is_success(data=equal_to({ "value": "resolved", "__schema": { "queryType": { "name": "Root", }, }, })))
def test_can_query_schema(): Root = g.ObjectType("Root", fields=(g.field("value", g.String), )) graph_definition = g.define_graph(resolvers=()) graph = graph_definition.create_graph({}) query = """ query { __schema { queryType { name } } } """ result = graphql.execute(graph=graph, document_text=query, query_type=Root) assert_that( result, is_success(data=equal_to({ "__schema": { "queryType": { "name": "Root", }, }, })))
def test_when_null_variable_is_missing_then_variable_is_null(): Root = g.ObjectType( "Root", fields=( g.field("one", type=g.Int, params=[ g.param("arg", type=g.NullableType(g.Int)), ]), ), ) graphql_query = """ query ($var: Int) { one(arg: $var) } """ object_query = _document_text_to_graph_query(graphql_query, query_type=Root, variables={}) assert_that(object_query, is_query( Root( g.key("one", Root.fields.one( Root.fields.one.params.arg(None), )), ), ))
def test_when_input_object_variable_is_missing_field_then_error_is_raised(): Input = g.InputObjectType( "Input", fields=lambda: ( g.input_field("field", type=g.Int), ), ) Root = g.ObjectType( "Root", fields=( g.field("one", type=g.Int, params=[ g.param("arg", type=Input), ]), ), ) graphql_query = """ query ($var: Input!) { one(arg: $var) } """ variables = {"var": {}} error = pytest.raises( GraphQLError, lambda: _document_text_to_graph_query(graphql_query, query_type=Root, variables=variables), ) assert_that(error.value.message, equal_to("Variable '$var' got invalid value {}; Field value.field of required type Int! was not provided."))
def test_object_builder_creates_object_using_field_resolvers(self): User = g.ObjectType("User", fields=(g.field("name", type=g.String, params=(g.param( "truncate", type=g.Int, default=None), )), )) object_builder = g.create_object_builder( User( g.key("name", User.fields.name()), g.key("initial", User.fields.name(User.fields.name.params.truncate(1))), )) @object_builder.field(User.fields.name) def resolve_name(field_query): if field_query.args.truncate is None: return lambda user: user["name"] else: return lambda user: user["name"][:field_query.args.truncate] result = object_builder({"name": "Bob"}) assert_that(result, has_attrs( name="Bob", initial="B", ))
def test_graphql_query_args_are_read(): Root = g.ObjectType( "Root", fields=(g.field("one", type=g.Int, params=[ g.param("arg", type=g.Int), ]), ), ) graphql_query = """ query ($value: Int!) { one(arg: $value) } """ object_query = _document_text_to_graph_query(graphql_query, query_type=Root, variables={"value": 42}) assert_that( object_query, is_query( Root( g.key("one", Root.fields.one(Root.fields.one.params.arg(42), )), ), ))
def test_variables_can_be_used_in_schema_query(): Root = g.ObjectType("Root", fields=(g.field("value", g.String), )) graph_definition = g.define_graph(resolvers=()) graph = graph_definition.create_graph({}) query = """ query ($f: Boolean!, $t: Boolean!) { included: __schema @include(if: $t) { queryType { name } } excluded: __schema @include(if: $f) { queryType { name } } } """ variables = {"t": True, "f": False} result = graphql.execute(graph=graph, document_text=query, query_type=Root, variables=variables) assert_that( result, is_success(data=equal_to({ "included": { "queryType": { "name": "Root", }, }, })))
def test_fragments_are_recursively_merged(): Root = g.ObjectType( "Root", fields=lambda: ( g.field("value", type=g.Int), ), ) graphql_query = """ query { ... on Root { ... on Root { one: value } } ... on Root { ... on Root { two: value } } } """ object_query = _document_text_to_graph_query(graphql_query, query_type=Root) assert_that(object_query, is_query( Root( g.key("one", Root.fields.value()), g.key("two", Root.fields.value()), ), ))
def test_when_field_value_in_input_object_in_input_object_is_not_set_then_default_is_used( ): Input = schema.InputObjectType( "Input", fields=(schema.input_field("field0", type=schema.Int, default=42), ), ) OuterInput = schema.InputObjectType( "OuterInput", fields=(schema.input_field("value", type=Input), ), ) Root = g.ObjectType( "Root", fields=(g.field("one", type=g.Int, params=[ g.param("arg", type=OuterInput), ]), ), ) graphql_query = """ query ($value: Int!) { one(arg: {value: {}}) } """ object_query = _document_text_to_graph_query(graphql_query, query_type=Root) assert_that(object_query.fields[0].args.arg, has_attrs(value=has_attrs(field0=42, ), ))
def test_graphql_field_args_are_read(): Root = g.ObjectType( "Root", fields=( g.field("one", type=g.Int, params=[ g.param("arg0", type=g.String), g.param("arg1", type=g.String), ]), ), ) graphql_query = """ query { one(arg0: "one", arg1: "two") } """ object_query = _document_text_to_graph_query(graphql_query, query_type=Root) assert_that(object_query, is_query( Root( g.key("one", Root.fields.one( Root.fields.one.params.arg0("one"), Root.fields.one.params.arg1("two"), )), ), ))
def test_when_resolution_raises_graph_error_then_result_is_invalid(): Root = g.ObjectType("Root", fields=( g.field("value", g.String), )) root_resolver = g.root_object_resolver(Root) @root_resolver.field(Root.fields.value) def root_resolve_value(graph, query, args): raise g.GraphError("BAD") graph_definition = g.define_graph(resolvers=(root_resolver, )) graph = graph_definition.create_graph({}) query = """ query { value } """ result = graphql.execute(graph=graph, document_text=query, query_type=Root) assert_that(result, is_invalid(errors=contains_exactly( all_of( is_instance(GraphQLError), has_str("BAD"), ), )))
def test_when_type_is_object_then_typename_field_is_resolved(self): User = g.ObjectType("User", fields=(g.field("name", type=g.String), )) object_builder = g.create_object_builder( User(g.key("type", schema.typename_field()), )) result = object_builder({}) assert_that(result, has_attrs(type="User", ))
def test_constant_object_resolver(): Root = g.ObjectType( "Root", fields=[ g.field("one", type=g.Int), g.field("two", type=g.Int), ], ) resolve_root = g.constant_object_resolver(Root, dict(one=1, two=2)) resolvers = [resolve_root] query = Root(g.key("value", Root.fields.one()), ) result = g.create_graph(resolvers).resolve(query) assert_that(result, has_attrs(value=1))
def to_graphql_input_type(graph_type): root_type = g.ObjectType("Root", fields=( g.field("value", type=g.String, params=( g.param("arg0", type=graph_type), )), )) graphql_schema = create_graphql_schema(query_type=root_type, mutation_type=None).graphql_schema return graphql_schema.query_type.fields["value"].args["arg0"].type