def test_nodes_can_be_fetched_directly():
    graph = create_graph({
        42: "Leave it to Psmith",
        43: "The Gentleman's Guide to Vice and Virtue",
        44: "Catch-22",
    })

    result = graph.resolve(
        Query(
            g.key(
                "books",
                Query.fields.books_connection(
                    Query.fields.books_connection.params.first(2),
                    g.key(
                        "nodes",
                        BooksConnection.fields.nodes(
                            g.key("title", Book.fields.title()), )),
                    g.key(
                        "page_info",
                        BooksConnection.fields.page_info(
                            g.key("has_next_page",
                                  PageInfo.fields.has_next_page()), )),
                )), ))

    assert_that(
        result.books,
        has_attrs(nodes=contains_exactly(
            has_attrs(title="Leave it to Psmith"),
            has_attrs(title="The Gentleman's Guide to Vice and Virtue"),
        ), ))
    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="*****@*****.**",
        ))
Esempio n. 3
0
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()),
            )),
        ),
    ))
Esempio n. 4
0
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()),
        ),
    ))
Esempio n. 5
0
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_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",
        ))
Esempio n. 7
0
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()),
            )),
        ),
    ))
Esempio n. 8
0
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()),
                            )), )), ), ))
Esempio n. 9
0
 def resolve_author(graph, query):
     assert_that(
         query,
         is_query(
             g.ListType(Author)(
                 g.key("name", Author.fields.name()),
                 g.key("books_written", Author.fields.books_written()),
             )))
     return [
         g.Object(dict(name="<author 1>", books_written=1)),
         g.Object(dict(name="<author 2>", books_written=2)),
     ]
Esempio n. 10
0
 def resolve_reader(graph, query):
     assert_that(
         query,
         is_query(
             g.ListType(Reader)(
                 g.key("name", Reader.fields.name()),
                 g.key("books_read", Reader.fields.books_read()),
             )))
     return [
         g.Object(dict(name="<reader 3>", books_read=3)),
         g.Object(dict(name="<reader 4>", books_read=4)),
     ]
Esempio n. 11
0
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"),
        ),
    ))
Esempio n. 12
0
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),
            )),
        ),
    ))
Esempio n. 13
0
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),
            )),
        ),
    ))
Esempio n. 14
0
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"),
            )),
        ),
    ))
Esempio n. 15
0
    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()),
            ),
        ))
Esempio n. 16
0
    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()),
            ),
        ))
Esempio n. 17
0
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),
            )),
        ),
    ))
Esempio n. 18
0
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()),
        ),
    ))
Esempio n. 19
0
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"),
            )),
        ),
    ))
Esempio n. 20
0
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_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_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", ))
Esempio n. 23
0
def test_when_merging_fragments_then_scalar_fields_can_overlap():
    Root = g.ObjectType(
        "Root",
        fields=lambda: (g.field("user", type=User), ),
    )

    User = g.ObjectType(
        "User",
        fields=(
            g.field("name", type=g.String),
            g.field("address", type=g.String),
            g.field("role", type=g.String),
        ),
    )

    graphql_query = """
        query {
            ... on Root {
                user {
                    name
                    address
                }
            }
            ... on Root {
                user {
                    name
                    role
                }
            }
        }
    """

    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()),
                        g.key("address", User.fields.address()),
                        g.key("role", User.fields.role()),
                    )), ), ))
def test_when_there_are_no_edges_then_connection_is_empty():
    graph = create_graph({})

    result = graph.resolve(
        Query(
            g.key(
                "books",
                Query.fields.books_connection(
                    Query.fields.books_connection.params.first(2),
                    g.key(
                        "edges",
                        BooksConnection.fields.edges(
                            g.key(
                                "node",
                                BookEdge.fields.node(
                                    g.key("title",
                                          Book.fields.title()), )), )),
                    g.key(
                        "page_info",
                        BooksConnection.fields.page_info(
                            g.key("end_cursor", PageInfo.fields.end_cursor()),
                            g.key("has_next_page",
                                  PageInfo.fields.has_next_page()),
                        )),
                )), ))

    assert_that(
        result.books,
        has_attrs(
            edges=contains_exactly(),
            page_info=has_attrs(end_cursor=None, has_next_page=False),
        ))
Esempio n. 25
0
def test_fragments_can_be_on_more_specific_type():
    Animal = g.InterfaceType(
        "Animal",
        fields=(
            g.field("name", type=g.String),
        ),
    )

    Cat = g.ObjectType(
        "Cat",
        fields=(
            g.field("name", type=g.String),
            g.field("whisker_count", type=g.Int),
        ),
        interfaces=(Animal, ),
    )

    Root = g.ObjectType(
        "Root",
        (
            g.field("animal", type=Animal),
        ),
    )

    graphql_query = """
        query {
            animal {
                name
                ... on Cat {
                    whiskerCount
                }
            }
        }
    """

    object_query = _document_text_to_graph_query(graphql_query, query_type=Root, types=(Cat, ))

    assert_that(object_query, is_query(
        Root(
            g.key("animal", Root.fields.animal(
                g.key("name", Animal.fields.name()),
                g.key("whiskerCount", Cat.fields.whisker_count()),
            )),
        ),
    ))
 def fetch(*, after):
     return graph.resolve(
         Query(
             g.key(
                 "books",
                 Query.fields.books_connection(
                     Query.fields.books_connection.params.first(2),
                     Query.fields.books_connection.params.after(after),
                     g.key(
                         "edges",
                         BooksConnection.fields.edges(
                             g.key(
                                 "node",
                                 BookEdge.fields.node(
                                     g.key("title",
                                           Book.fields.title()), )), )),
                     g.key(
                         "page_info",
                         BooksConnection.fields.page_info(
                             g.key("end_cursor",
                                   PageInfo.fields.end_cursor()),
                             g.key("has_next_page",
                                   PageInfo.fields.has_next_page()),
                         )),
                 )), ))
Esempio n. 27
0
def test_fields_can_be_nested():
    Root = g.ObjectType(
        "Root",
        fields=lambda: (
            g.field("one", type=One),
        ),
    )

    One = g.ObjectType(
        "One",
        fields=lambda: (
            g.field("two", type=Two),
        ),
    )

    Two = g.ObjectType(
        "Two",
        fields=lambda: (
            g.field("three", type=g.Int),
        ),
    )

    graphql_query = """
        query {
            one {
                two {
                    three
                }
            }
        }
    """

    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(
                    g.key("three", Two.fields.three()),
                )),
            )),
        ),
    ))
def test_when_first_is_negative_then_error_is_raised():
    graph = create_graph({})

    query = Query(
        g.key(
            "books",
            Query.fields.books_connection(
                Query.fields.books_connection.params.first(-1),
                g.key(
                    "page_info",
                    BooksConnection.fields.page_info(
                        g.key("has_next_page",
                              PageInfo.fields.has_next_page()), )),
            )), )

    error = pytest.raises(g.GraphError, lambda: graph.resolve(query))

    assert_that(str(error.value),
                equal_to("first must be non-negative integer, was -1"))
 def fetch(*, after):
     return graph.resolve(
         Query(
             g.key(
                 "books",
                 Query.fields.books_connection(
                     Query.fields.books_connection.params.first(2),
                     Query.fields.books_connection.params.after(after),
                     g.key(
                         "edges",
                         BooksConnection.fields.edges(
                             g.key("cursor", BookEdge.fields.cursor()),
                             g.key(
                                 "node",
                                 BookEdge.fields.node(
                                     g.key("title",
                                           Book.fields.title()), )),
                         )),
                 )), ))
    def test_when_type_is_interface_then_typename_field_is_unresolved(self):
        User = g.InterfaceType("User",
                               fields=(g.field("name", type=g.String), ))

        object_builder = g.create_object_builder(
            User(g.key("type", schema.typename_field()), ))

        error = pytest.raises(g.GraphError, lambda: object_builder({}))
        assert_that(str(error.value),
                    equal_to("Resolver missing for field type_name"))