Beispiel #1
0
async def test_issue154_input_type(sdl, should_exp):
    if should_exp:
        with pytest.raises(GraphQLSchemaError):
            Engine(sdl=sdl, schema_name=f"issue154_{sdl}")
    else:
        e = Engine(sdl=sdl, schema_name=f"issue154_{sdl}")
        assert e._schema is not None
Beispiel #2
0
async def test_engine_subscribe_with_default_resolver_alias(clean_registry):
    from tartiflette import Engine, Subscription, Resolver

    @Subscription("Subscription.counter", schema_name="subscribe_counter")
    async def _subscription_counter_subscription(parent_result, args, *_args,
                                                 **_kwargs):
        start_at = args["startAt"]
        while start_at > 0:
            await asyncio.sleep(0.01)
            start_at -= 1
            yield start_at

    e = Engine(
        """
        type Query {
          a: String
        }

        type Subscription {
          counter(startAt: Int!): Int!
        }
        """,
        schema_name="subscribe_counter",
    )

    expected_values = list(range(4))

    async for result in e.subscribe(
            "subscription { aliasCounter: counter(startAt: 4) }"):
        assert result == {"data": {"aliasCounter": expected_values.pop()}}
Beispiel #3
0
async def test_issue154(sdl, should_exp, adddir):
    class aDirective(CommonDirective):
        pass

    if adddir:
        Directive("adirective", schema_name=f"issue154_{sdl}")(aDirective)

    if should_exp:
        with pytest.raises(GraphQLSchemaError):
            Engine(sdl=sdl, schema_name=f"issue154_{sdl}")
    else:
        e = Engine(sdl=sdl, schema_name=f"issue154_{sdl}")
        assert e._schema is not None
Beispiel #4
0
async def test_engine_execute_custom_error_coercer(clean_registry):
    from tartiflette.engine import Engine

    def custom_error_coercer(exception):
        error = default_error_coercer(exception)
        error["message"] = error["message"] + "Custom"
        return error

    e = Engine("type Query { a: String }", error_coercer=custom_error_coercer)

    assert await e.execute("query { unknownNode1 unknownNode2 }") == {
        "data":
        None,
        "errors": [
            {
                "message":
                "field `Query.unknownNode1` was not found in GraphQL schema.Custom",
                "path": ["unknownNode1"],
                "locations": [{
                    "column": 9,
                    "line": 1
                }],
            },
            {
                "message":
                "field `Query.unknownNode2` was not found in GraphQL schema.Custom",
                "path": ["unknownNode2"],
                "locations": [{
                    "column": 22,
                    "line": 1
                }],
            },
        ],
    }
Beispiel #5
0
async def test_issue21_okayquery(
    query, expected, typee, varis, clean_registry
):
    from tartiflette.engine import Engine

    @Resolver("Query.a")
    async def a_resolver(_, arguments, __, info: Info):
        return {"iam": info.query_field.name, "args": arguments}

    ttftt = Engine(
        """
    type Args{
        xid: %s
    }

    type Obj {
        iam: String
        args: Args
    }

    type Query {
        a(xid: %s): Obj
    }
    """
        % (typee, typee)
    )

    results = await ttftt.execute(
        query, context={}, variables=varis, operation_name="LOL"
    )

    assert results == expected
Beispiel #6
0
async def test_tartiflette_execute_enum_type_output(clean_registry):
    schema_sdl = """
    enum Test {
        Value1
        Value2
        Value3
    }

    type Query {
        enumTest: Test
    }
    """

    @Resolver("Query.enumTest")
    async def func_field_resolver(*args, **kwargs):
        return "Value1"

    ttftt = Engine(schema_sdl)

    result = await ttftt.execute(
        """
    query Test{
        enumTest
    }
    """,
        operation_name="Test",
    )

    assert {"data": {"enumTest": "Value1"}} == result
Beispiel #7
0
async def test_tartiflette_execute_object_type_output(clean_registry):
    schema_sdl = """
    type Test {
        field1: String
    }

    type Query {
        objectTest: Test
    }
    """

    @Resolver("Query.objectTest")
    async def func_field_resolver(*args, **kwargs):
        return {"field1": "Test"}

    ttftt = Engine(schema_sdl)

    result = await ttftt.execute(
        """
    query Test{
        objectTest {
            field1
        }
    }
    """,
        operation_name="Test",
    )

    assert {"data": {"objectTest": {"field1": "Test"}}} == result
Beispiel #8
0
async def test_tartiflette_execute_hello_world(clean_registry):
    schema_sdl = """
    type Query {
        hello: String!
    }
    """

    @Resolver("Query.hello")
    async def func_field_resolver(parent, arguments, request_ctx, info):
        return "world"

    ttftt = Engine(schema_sdl)

    result = await ttftt.execute(
        """
    query Test{
        hello
    }
    """,
        operation_name="Test",
    )

    assert {"data": {"hello": "world"}} == result

    # Try twice to be sure everything works mutliple times
    result = await ttftt.execute(
        """
        query Test{
            hello
        }
        """,
        operation_name="Test",
    )

    assert {"data": {"hello": "world"}} == result
Beispiel #9
0
async def test_engine_execute_parse_error(clean_registry):
    from tartiflette.engine import Engine

    e = Engine("type Query { a: String }")

    assert await e.execute("query { unknownNode1 unknownNode2 }") == {
        "data":
        None,
        "errors": [
            {
                "message":
                "field `Query.unknownNode1` was not found in GraphQL schema.",
                "path": ["unknownNode1"],
                "locations": [{
                    "column": 9,
                    "line": 1
                }],
            },
            {
                "message":
                "field `Query.unknownNode2` was not found in GraphQL schema.",
                "path": ["unknownNode2"],
                "locations": [{
                    "column": 22,
                    "line": 1
                }],
            },
        ],
    }
Beispiel #10
0
async def test_tartiflette_execute_scalar_type_output(clean_registry):
    schema_sdl = """
    type Query {
        lastUpdate: DateTime
    }
    """

    @Resolver("Query.lastUpdate")
    async def func_field_resolver(*args, **kwargs):
        return datetime(year=2018,
                        month=4,
                        day=19,
                        hour=14,
                        minute=57,
                        second=38)

    ttftt = Engine(schema_sdl)

    result = await ttftt.execute(
        """
    query Test{
        lastUpdate
    }
    """,
        operation_name="Test",
    )

    assert {"data": {"lastUpdate": "2018-04-19T14:57:38"}} == result
Beispiel #11
0
async def test_issue21_exceptquery(query, expected, varis, clean_registry):
    from tartiflette.engine import Engine

    @Resolver("Query.a")
    async def a_resolver(_, arguments, __, info: Info):
        return {"iam": info.query_field.name, "args": arguments}

    ttftt = Engine(
        """
    type Args{
        xid: Int
    }

    type Obj {
        iam: String
        args: Args
    }

    type Query {
        a(xid: Int): Obj
    }
    """
    )

    assert await ttftt.execute(query, context={}, variables=varis) == expected
Beispiel #12
0
async def test_tartiflette_execute_enum_type_advanced(input_sdl,
                                                      resolver_response,
                                                      expected,
                                                      clean_registry):
    schema_sdl = """
    enum Test {{
        Value1
        Value2
        Value3
    }}

    type Query {{
        testField: {}
    }}
    """.format(input_sdl)

    @Resolver("Query.testField")
    async def func_field_resolver(*args, **kwargs):
        return resolver_response

    ttftt = Engine(schema_sdl)

    result = await ttftt.execute(
        """
    query Test{
        testField
    }
    """,
        operation_name="Test",
    )

    assert expected == result
Beispiel #13
0
async def test_engine_execute(clean_registry):
    from tartiflette.engine import Engine

    e = Engine("type Query { a:String }")

    result = await e.execute("query aquery { a }", operation_name="aquery")

    assert result == {"data": {"a": None}}
Beispiel #14
0
async def create_engine(
    sdl: Union[str, List[str]],
    schema_name: str = "default",
    error_coercer: Callable[[Exception, Dict[str, Any]], Dict[str,
                                                              Any]] = None,
    custom_default_resolver: Optional[Callable] = None,
    custom_default_type_resolver: Optional[Callable] = None,
    modules: Optional[Union[str, List[str], List[Dict[str, Any]]]] = None,
) -> "Engine":
    """
    Create an engine by analyzing the SDL and connecting it with the imported
    Resolver, Mutation, Subscription, Directive and Scalar linking them through
    the `schema_name`.
    :param sdl: the SDL to work with
    :param schema_name: the name of the SDL
    :param error_coercer: callable in charge of transforming a couple
    Exception/error into an error dictionary
    :param custom_default_resolver: callable that will replace the tartiflette
    `default_resolver` (Will be called like a resolver for each UNDECORATED
    field)
    :param custom_default_type_resolver: callable that will replace the
    tartiflette `default_type_resolver` (will be called on abstract types to
    deduct the type of a result)
    :param modules: list of string containing the name of the modules you want
    the engine to import, usually this modules contains your Resolvers,
    Directives, Scalar or Subscription code
    :type sdl: Union[str, List[str]]
    :type schema_name: str
    :type error_coercer: Callable[[Exception, Dict[str, Any]], Dict[str, Any]]
    :type custom_default_resolver: Optional[Callable]
    :type custom_default_type_resolver: Optional[Callable]
    :type modules: Optional[Union[str, List[str], List[Dict[str, Any]]]]
    :return: a Cooked Engine instance
    :rtype: Engine

    :Example:

    >>> from tartiflette import create_engine
    >>>
    >>>
    >>> engine = await create_engine('''type Query {
    >>>   hello(name: String!): String!
    >>> }''')
    """
    e = Engine()

    await e.cook(
        sdl=sdl,
        error_coercer=error_coercer,
        custom_default_resolver=custom_default_resolver,
        custom_default_type_resolver=custom_default_type_resolver,
        modules=modules,
        schema_name=schema_name,
    )

    return e
Beispiel #15
0
def test_engine(clean_registry):
    from tartiflette.engine import Engine
    from tartiflette.schema.registry import SchemaRegistry

    e = Engine("type Query { a:String }")
    s = SchemaRegistry.find_schema()

    assert e._parser is not None
    assert s is not None
    assert s.name == "default"

    ee = Engine("type Query { a:String }", "Bob")
    ss = SchemaRegistry.find_schema("Bob")

    assert ee._parser is not None
    assert ss is not None
    assert ss.name == "Bob"

    assert ss != s
Beispiel #16
0
async def test_tartiflette_execute_union_type_output(query, expected,
                                                     clean_registry):
    schema_sdl = """
    type One {
        aField: String
        bField: Int
    }

    type Two {
        cField: Int
        dField: String
    }

    type Three {
        eField: Float
        fField: String
    }

    union Mixed = One | Two | Three

    type Query {
        test(choose: Int!): Mixed
    }
    """

    @Resolver("Query.test")
    async def func_field_resolver(parent, arguments, request_ctx, info: Info):
        chosen = arguments.get("choose", 0)
        if chosen == 1:
            return {"aField": "aValue", "bField": 1, "_typename": "One"}
        elif chosen == 2:

            class Lol:
                def __init__(self, *args, **kwargs):
                    self._typename = "Two"
                    self.cField = 2
                    self.dField = "dValue"

            return Lol()
        elif chosen == 3:

            class Three:
                def __init__(self, *args, **kwargs):
                    self.eField = 3.6
                    self.fField = "fValue"

            return Three()

        return None

    ttftt = Engine(schema_sdl)

    result = await ttftt.execute(query, operation_name="aquery")

    assert expected == result
Beispiel #17
0
async def test_tartiflette_engine_initialization_with_single_sdl_file(
    clean_registry
):
    engine = Engine(_curr_path + "/data/simple_full_sdl/simple_full.sdl")

    assert clean_registry.find_schema().find_type("Author") is not None
    assert clean_registry.find_schema().find_type("Blog") is not None
    assert clean_registry.find_schema().find_type("Post") is not None
    assert (
        clean_registry.find_schema().find_type("Query").find_field("blogs")
        is not None
    )
Beispiel #18
0
async def test_tartiflette_engine_initialization_with_sdl_folder(
    path, clean_registry
):
    engine = Engine(path)

    assert clean_registry.find_schema().find_type("Author") is not None
    assert clean_registry.find_schema().find_type("Blog") is not None
    assert clean_registry.find_schema().find_type("Post") is not None
    assert (
        clean_registry.find_schema().find_type("Query").find_field("blogs")
        is not None
    )
Beispiel #19
0
async def test_tartiflette_execute_object_type_unknown_field(clean_registry):
    schema_sdl = """
    type Post {
        content: Content
        meta_creator: String
    }

    type Content {
        title: String
    }

    type Query {
        posts: [Post!]
    }
    """

    mock_call = Mock()

    @Resolver("Content.title")
    async def func_field_resolver(*args, **kwargs):
        mock_call()
        return "Test"

    @Resolver("Post.content")
    async def func_field_resolver(*args, **kwargs):
        return {"title": "Stuff"}

    Post = namedtuple("Post", ["content", "meta_creator"])
    Content = namedtuple("Content", ["title"])

    @Resolver("Query.posts")
    async def func_field_resolver(*args, **kwargs):
        return [
            Post(content=Content(title="Test"), meta_creator="Dailymotion")
        ]

    ttftt = Engine(schema_sdl)

    result = await ttftt.execute(
        """
    query Test{
        posts {
            content {
                title
            }
        }
    }
    """,
        operation_name="Test",
    )

    assert result == {"data": {"posts": [{"content": {"title": "Test"}}]}}
    assert mock_call.called is True
Beispiel #20
0
async def test_arguments_in_sdl(sdl, query, expected, varis, clean_registry):
    @Resolver("Query.bob")
    async def func_bob_resolver(_pr, arguments, _ctx, _info):
        return arguments["id"] + 2

    ttftt = Engine(sdl)

    result = await ttftt.execute(
        query, variables=varis, operation_name="aQuery"
    )

    assert expected == result
Beispiel #21
0
async def test_tartiflette_nested_resolvers(clean_registry):
    schema_sdl = """
    type Query {
        rootField: RootType
    }

    type RootType {
        nestedField: NestedType
    }

    type NestedType {
        endField: String
    }
    """

    @Resolver("Query.rootField")
    async def func_resolver(parent, arguments, request_ctx, info):
        return {"nestedField": "Nested ?"}

    @Resolver("RootType.nestedField")
    async def func_resolver(parent, arguments, request_ctx, info):
        return {"endField": "Another"}

    @Resolver("NestedType.endField")
    async def func_resolver(parent, arguments, request_ctx, info):
        return "Test"

    ttftt = Engine(schema_sdl)

    result = await ttftt.execute(
        """
    query Test{
        rootField {
            nestedField {
                endField
            }
        }
    }
    """,
        operation_name="Test",
    )

    assert result == {
        "data": {
            "rootField": {
                "nestedField": {
                    "endField": "Test"
                }
            }
        }
    }
Beispiel #22
0
async def test_engine_execute_syntax_error(clean_registry):
    from tartiflette.engine import Engine

    e = Engine("type Query { a: String }")

    assert await e.execute("query { a { }") == {
        "data":
        None,
        "errors": [{
            "message": "1.12: unrecognized character \\xc2",
            "path": None,
            "locations": [],
        }],
    }
Beispiel #23
0
async def test_engine_execute_empty_req_except(clean_registry):
    from tartiflette.engine import Engine

    e = Engine("type Query { a: String }")

    assert await e.execute("") == {
        "data":
        None,
        "errors": [{
            "message": "1.1: syntax error, unexpected EOF",
            "path": None,
            "locations": [],
        }],
    }
Beispiel #24
0
async def test_tartiflette_non_introspectable_execution_directive(
        clean_registry):
    schema = """
    type Query {
        fieldNormal: Int
        fieldHiddendToIntrospactable: Int @non_introspectable
    }
    """

    @Resolver("Query.fieldNormal")
    async def func_field_resolver4(parent, arguments, request_ctx, info):
        return 42

    @Resolver("Query.fieldHiddendToIntrospactable")
    async def func_field_resolver5(parent, arguments, request_ctx, info):
        return 42

    ttftt = Engine(schema)

    assert (clean_registry.find_schema().find_directive("non_introspectable")
            is not None)
    assert (clean_registry.find_schema().find_directive(
        "non_introspectable").implementation is not None)

    result = await ttftt.execute(
        """
    query Test{
        __type(name: "Query") {
            fields {
                name
                isDeprecated
                deprecationReason
            }
        }
    }
    """,
        operation_name="Test",
    )

    assert {
        "data": {
            "__type": {
                "fields": [{
                    "name": "fieldNormal",
                    "isDeprecated": False,
                    "deprecationReason": None,
                }]
            }
        }
    } == result
Beispiel #25
0
async def test_tartiflette_execute_basic(clean_registry):
    schema_sdl = """
    schema {
        query: RootQuery
    }

    type RootQuery {
        defaultField: Int
        testField: Test
    }

    type Test {
        field: String
    }
    """

    mock_one = Mock()
    mock_two = Mock()

    @Resolver("Test.field")
    async def func_field_resolver(*_args, **_kwargs):
        mock_one()
        return None

    @Resolver("RootQuery.testField")
    async def func_testfield_resolver(*_args, **_kwargs):
        return {}

    @Resolver("RootQuery.defaultField")
    async def func_default_query_resolver(*_args, **_kwargs):
        mock_two()
        return 1

    ttftt = Engine(schema_sdl)

    result = await ttftt.execute(
        """
    query Test{
        testField {
            field
        }
    }
    """,
        operation_name="Test",
    )

    assert result == {"data": {"testField": {"field": None}}}
    assert mock_one.called is True
    assert mock_two.called is False
Beispiel #26
0
async def test_tartiflette_execute_nested_coercion(clean_registry):
    schema_sdl = """
    type Book {
        title: String!
        authors: [Author]
    }

    type Author {
        name: String!
    }

    type Query {
        library: [Book!]
    }
    """

    Book = namedtuple("Book", "title,authors")
    Author = namedtuple("Author", "name")

    @Resolver("Query.library")
    async def func_field_library_resolver(*args, **kwargs):
        return [Book("A new beginning", [Author("Lemony Snicket")])]

    ttftt = Engine(sdl=schema_sdl)

    result = await ttftt.execute(
        """
    query TestExecutionCoercion{
        library {
            title
            authors {
                name
            }
        }
    }
    """,
        operation_name="TestExecutionCoercion",
    )

    assert {
        "data": {
            "library": [
                {
                    "title": "A new beginning",
                    "authors": [{"name": "Lemony Snicket"}],
                }
            ]
        }
    } == result
Beispiel #27
0
async def test_tartiflette_deprecated_execution_directive(clean_registry):
    schema = """
    type Query {
        fieldNormal: Int
        fieldDeprecatedDefault: Int @deprecated
        fieldDeprecatedCustom: Int @deprecated(reason: "Unused anymore")
    }
    """

    @Resolver("Query.fieldNormal")
    async def func_field_resolver4(parent, arguments, request_ctx, info):
        return 42

    @Resolver("Query.fieldDeprecatedDefault")
    async def func_field_resolver5(parent, arguments, request_ctx, info):
        return 42

    @Resolver("Query.fieldDeprecatedCustom")
    async def func_field_resolver6(parent, arguments, request_ctx, info):
        return 42

    ttftt = Engine(schema)

    assert (clean_registry.find_schema().find_directive("deprecated")
            is not None)
    assert (clean_registry.find_schema().find_directive(
        "deprecated").implementation is not None)

    result = await ttftt.execute(
        """
    query Test{
        fieldNormal
        fieldDeprecatedDefault
        fieldDeprecatedCustom
    }
    """,
        operation_name="Test",
    )

    assert {
        "data": {
            "fieldNormal": 42,
            "fieldDeprecatedDefault": 42,
            "fieldDeprecatedCustom": 42,
        }
    } == result
Beispiel #28
0
async def test_tartiflette_declare_custom_scalar(clean_registry):
    from tartiflette import Scalar

    sdl = """
        scalar Ntm

        type Lol {
            joey: Ntm
        }

        type Query {
            alol: Lol
        }
    """

    @Resolver("Query.alol")
    async def alol_resolver(*_, **__):
        class customobject:
            def __init__(self, p1):
                self.p1 = p1

        return {"joey": customobject("OL")}

    @Scalar(name="Ntm")
    class Ntm:
        @staticmethod
        def coerce_output(val):
            return "I'am a val %s " % val.p1

        @staticmethod
        def coerce_input(val):
            return val

    ttftt = Engine(sdl)

    result = await ttftt.execute(
        query="""
        query {
            alol {
                joey
            }
        }
        """
    )

    assert {"data": {"alol": {"joey": "I'am a val OL "}}} == result
Beispiel #29
0
async def test_engine_execute_unhandled_exception(clean_registry):
    from tartiflette.engine import Engine

    e = Engine("type Query { a: Ninja } type Ninja { a: String }")

    assert (await e.execute("""
        fragment AFragment on Ninja { a }
        fragment AFragment on Ninja { a }
        query { a { } }
    """) == {
        "data":
        None,
        "errors": [{
            "message": "4.20: unrecognized character \\xc2",
            "path": None,
            "locations": [],
        }],
    })
Beispiel #30
0
async def test_tartiflette_engine_initialization_with_sdl_file_list(
    clean_registry
):
    engine = Engine(
        [
            _curr_path + "/data/splitted_sdl/author.sdl",
            _curr_path + "/data/splitted_sdl/blog.sdl",
            _curr_path + "/data/splitted_sdl/post.sdl",
            _curr_path + "/data/splitted_sdl/query.sdl",
        ]
    )

    assert clean_registry.find_schema().find_type("Author") is not None
    assert clean_registry.find_schema().find_type("Blog") is not None
    assert clean_registry.find_schema().find_type("Post") is not None
    assert (
        clean_registry.find_schema().find_type("Query").find_field("blogs")
        is not None
    )