예제 #1
0
async def test_forwarded_resolver_arguments(mocker, assert_execution):

    resolver = mocker.Mock(return_value="foo")
    context = mocker.Mock()
    root = mocker.Mock()

    field = Field("test", String, [Argument("arg", String)], resolver=resolver)
    query_type = ObjectType("Test", [field])
    doc = parse("query ($var: String) { result: test(arg: $var) }")
    schema = Schema(query_type)

    result = assert_execution(
        schema,
        doc,
        context_value=context,
        initial_value=root,
        variables={"var": 123},
    )

    if isawaitable(result):
        await result

    (parent_value, ctx, info), args = resolver.call_args

    assert info.field_definition is field
    assert info.parent_type is query_type
    assert info.path == ["result"]
    assert info.variables == {"var": "123"}
    assert info.schema is schema

    assert ctx is context
    assert parent_value is root

    assert args == {"arg": "123"}
예제 #2
0
def test_skip_and_include_directives_on_fields():
    document = parse(
        """
        query {
            foo {
                default {
                    nested
                }
                skipped @skip(if: true) {
                    nested
                }
                not_included @include(if: false) {
                    nested
                }
            }
        }
    """
    )
    field = _first_field(document)
    fieldnames = selected_fields(
        field, fragments=document.fragments, variables={}, maxdepth=3
    )
    assert fieldnames == [
        "default",
        "default/nested",
    ]
예제 #3
0
def test_SnakeCaseToCamelCaseVisitor():
    query = parse("""
        {
            foo_bar {
                bar_foo
                ... on Object {
                    baz_foo
                }
            }
        }

        fragment A on Object {
            foo_baz
        }
        """)

    visited_query = ast_transforms.SnakeCaseToCamelCaseVisitor().visit(
        query.deepcopy())

    assert visited_query

    assert print_ast(visited_query, indent=4) == dedent("""
        {
            fooBar {
                barFoo
                ... on Object {
                    bazFoo
                }
            }
        }

        fragment A on Object {
            fooBaz
        }
        """)
예제 #4
0
def assert_validation_result(schema,
                             source,
                             expected_msgs=None,
                             expected_locs=None,
                             checkers=None):
    # Prints are here so we can more easily debug when running pytest with -v
    expected_msgs = expected_msgs or []
    expected_locs = expected_locs or []
    print(source)
    result = validate_ast(
        schema,
        parse(dedent(source), allow_type_system=True),
        validators=[
            lambda s, d, v: default_validator(
                s, d, v, validators=(checkers or SPECIFIED_RULES))
        ],
    )
    errors = result.errors

    msgs = [str(err) for err in errors]
    locs = [[node.loc for node in err.nodes] for err in errors]

    print(" [msgs] ", msgs)
    print(" [locs] ", locs)

    assert msgs == expected_msgs
    if expected_locs:
        assert locs == [_ensure_list(l) for l in expected_locs]
예제 #5
0
def test_custom_indentation_object():
    assert (ASTPrinter(indent=4)(parse("""
            {
                bar {
                    one
                        two
                    ... on Object {
                        three
                    }
                    ...A
                }
            }

            fragment A on Object {
                four
            five
            }
            """)) == dedent("""
            {
                bar {
                    one
                    two
                    ... on Object {
                        three
                    }
                    ...A
                }
            }

            fragment A on Object {
                four
                five
            }
            """))
예제 #6
0
def test_mutation_operation_without_name():
    assert print_ast(parse("mutation { id, name }")) == dedent("""
    mutation {
      id
      name
    }
    """)
예제 #7
0
def test_query_operation_without_name():
    assert print_ast(parse("query { id, name }")) == dedent("""
    {
      id
      name
    }
    """)
예제 #8
0
async def test_raises_on_unsupported_operations(starwars_schema):
    with pytest.raises(RuntimeError):
        subscribe(
            starwars_schema,
            parse("query { counter(delay: 0.001) }"),
            runtime=AsyncIORuntime(),
        )
예제 #9
0
async def test_same_root_field_multiple_aliases(starwars_schema,
                                                assert_execution):
    await assert_execution(
        starwars_schema,
        parse("""
            query FetchLukeAndLeiaAliased {
                luke: human(id: "1000") {
                    name
                    homePlanet
                }
                leia: human(id: "1003") {
                    name
                    homePlanet
                }
            }
            """),
        expected_data={
            "luke": {
                "name": "Luke Skywalker",
                "homePlanet": "Tatooine"
            },
            "leia": {
                "name": "Leia Organa",
                "homePlanet": "Alderaan"
            },
        },
    )
예제 #10
0
async def test_id_and_friends_of_r2_d2(starwars_schema, assert_execution):
    await assert_execution(
        starwars_schema,
        parse("""
            query HeroNameAndFriendsQuery {
                hero {
                    id
                    name
                    friends {
                        name
                    }
                }
            }
            """),
        expected_data={
            "hero": {
                "id":
                "2001",
                "name":
                "R2-D2",
                "friends": [
                    {
                        "name": "Luke Skywalker"
                    },
                    {
                        "name": "Han Solo"
                    },
                    {
                        "name": "Leia Organa"
                    },
                ],
            }
        },
    )
예제 #11
0
def test_block_string_single_line_with_leading_space():
    assert (print_ast(
        parse('''
        { field(arg: """    space-led value""") }
    ''')) == dedent('''
    {
      field(arg: """    space-led value""")
    }
    '''))
예제 #12
0
def test_kitchen_sink(fixture_file):
    ks = fixture_file("kitchen-sink.graphql")
    assert print_ast(parse(ks)) == dedent('''
query queryName($foo: ComplexType, $site: Site = MOBILE) {
  whoever123is: node(id: [123, 456]) {
    id
    ... on User @defer {
      field2 {
        id
        alias: field1(first: 10, after: $foo) @include(if: $foo) {
          id
          ...frag
        }
      }
    }
    ... @skip(unless: $foo) {
      id
    }
    ... {
      id
    }
  }
}

mutation likeStory {
  like(story: 123) @defer {
    story {
      id
    }
  }
}

subscription StoryLikeSubscription($input: StoryLikeSubscribeInput) {
  storyLikeSubscribe(input: $input) {
    story {
      likers {
        count
      }
      likeSentence {
        text
      }
    }
  }
}

fragment frag on Friend {
  foo(size: $size, bar: $b, obj: {key: "value", block: """
    block string uses \\"""
  """})
}

{
  unnamed(truthy: true, falsey: false, nullish: null)
  query
}
''')
예제 #13
0
def test_mutation_operation_without_name_and_artifacts():
    assert (print_ast(
        parse("""
        mutation ($foo: TestType) @testDirective { id, name }
    """)) == dedent("""
    mutation ($foo: TestType) @testDirective {
      id
      name
    }
    """))
예제 #14
0
def test_errors_point_to_the_correct_operation_node(starwars_schema):
    rule = MaxDepthValidationRule(5)
    doc = parse(MULTIPLE_OPERATIONS)
    errors = rule(starwars_schema, doc)

    ops = [
        o for o in doc.definitions if isinstance(o, ast.OperationDefinition)
    ]

    assert errors[0].nodes == [ops[1]]
    assert errors[1].nodes == [ops[3]]
예제 #15
0
def test_default_case():
    document = parse(DOCUMENT)
    field = _first_field(document)
    fieldnames = selected_fields(
        field, fragments=document.fragments, variables={}
    )
    assert fieldnames == [
        "field",
        "other_field",
        "bar",
        "baz",
    ]
예제 #16
0
def test_built_schema_is_executable():
    schema = build_schema(
        parse(
            """
            type Query {
                str: String
            }
            """,
            allow_type_system=True,
        )
    )
    data, _ = graphql_blocking(schema, "{ str }", root={"str": 123})
    assert data == {"str": "123"}
예제 #17
0
def test_block_string_single_line_with_leading_space_and_quotation():
    ast = parse('''
    {
      field(arg: """    space-led value "quoted string"
      """)
    }
    ''')
    assert print_ast(ast) == dedent('''
    {
      field(arg: """    space-led value "quoted string"
      """)
    }
    ''')
예제 #18
0
def test_fragment_defined_variables():
    ast = parse(
        """
    fragment Foo($a: ComplexType, $b: Boolean = false) on TestType {
        id
    }
    """,
        experimental_fragment_variables=True,
    )
    assert print_ast(ast) == dedent("""
    fragment Foo($a: ComplexType, $b: Boolean = false) on TestType {
      id
    }
    """)
예제 #19
0
async def test_luke_skywalker_using_id(starwars_schema, assert_execution):
    await assert_execution(
        starwars_schema,
        parse("""
            query FetchLukeQuery {
                human(id: "1000") {
                name
                }
            }
            """),
        expected_data={"human": {
            "name": "Luke Skywalker"
        }},
    )
예제 #20
0
def test_nesting():
    document = parse(DOCUMENT)
    field = _first_field(document)
    fieldnames = selected_fields(
        field, fragments=document.fragments, variables={}, maxdepth=2
    )
    assert fieldnames == [
        "field",
        "other_field",
        "other_field/nested_field",
        "bar",
        "baz",
        "baz/nested_baz_field",
    ]
예제 #21
0
def test_filtering():
    document = parse(DOCUMENT)
    field = _first_field(document)
    fieldnames = selected_fields(
        field,
        fragments=document.fragments,
        variables={},
        maxdepth=3,
        pattern="other_field/*",
    )
    assert fieldnames == [
        "other_field/nested_field",
        "other_field/nested_field/deeper_nested_field",
    ]
예제 #22
0
async def test_changing_key_with_alias(starwars_schema, assert_execution):
    await assert_execution(
        starwars_schema,
        parse("""
            query FetchLukeAliased {
                luke: human(id: "1000") {
                name
                }
            }
            """),
        expected_data={"luke": {
            "name": "Luke Skywalker"
        }},
    )
예제 #23
0
async def test_generic_query_using_id_and_variable(starwars_schema,
                                                   assert_execution, id_,
                                                   expected):
    await assert_execution(
        starwars_schema,
        parse("""
            query FetchSomeIDQuery($someId: String!) {
                human(id: $someId) {
                name
                }
            }
            """),
        variables={"someId": id_},
        expected_data={"human": expected},
    )
예제 #24
0
async def test_get_directive_arguments_missing(mocker):
    CustomDirective = Directive(
        "custom", ["FIELD"],
        [Argument("a", String), Argument("b", Int)])

    resolver = mocker.Mock(return_value=42)

    execute(
        Schema(test_type, directives=[CustomDirective]),
        parse("{ a }"),
        initial_value=_obj(a=resolver),
    )

    (_, info), _ = resolver.call_args

    assert info.get_directive_arguments("custom") is None
예제 #25
0
async def test_raises_on_missing_subscription_resolver(starwars_schema):
    schema = subscription_schema(
        Field(
            "counter",
            NonNullType(Int),
            args=[Argument("delay", NonNullType(Float))],
            resolver=lambda event, *_, **__: event,
        )
    )

    with pytest.raises(RuntimeError):
        subscribe(
            schema,
            parse("subscription { counter(delay: 0.001) }"),
            runtime=AsyncIORuntime(),
        )
예제 #26
0
async def test_raises_on_unsupported_runtime():
    schema = subscription_schema(
        Field(
            "counter",
            NonNullType(Int),
            args=[Argument("delay", NonNullType(Float))],
            subscription_resolver=lambda *_, delay: AsyncCounter(delay, 10),
            resolver=lambda event, *_, **__: event,
        )
    )

    with pytest.raises(RuntimeError):
        subscribe(
            schema,
            parse("subscription { counter(delay: 0.001) }"),
            runtime=BlockingRuntime(),  # type: ignore
        )
예제 #27
0
async def test_it_correctly_identifies_r2_d2_as_the_hero_of_the_star_wars_saga(
        starwars_schema, assert_execution):
    await assert_execution(
        starwars_schema,
        parse("""
            query HeroNameQuery {
                hero {
                    name
                    id
                }
            }
            """),
        expected_data={"hero": {
            "name": "R2-D2",
            "id": "2001"
        }},
    )
예제 #28
0
def test_example_case():
    document = parse(
        """
        query {
            field {
                foo {
                    bar {
                        baz
                    }
                }
            }
        }
        """
    )
    field = _first_field(document)
    fieldnames = selected_fields(field, fragments={}, variables={}, maxdepth=0)
    assert fieldnames == ["foo", "foo/bar", "foo/bar/baz"]
예제 #29
0
async def test_error_on_missing_argument(starwars_schema, assert_execution):
    await assert_execution(
        starwars_schema,
        parse("""
            {
                luke: human {
                    name
                }
            }
            """),
        expected_data={"luke": None},
        expected_errors=[(
            'Argument "id" of required type "String!" was not provided',
            (31, 87),
            "luke",
        )],
    )
예제 #30
0
async def test_get_directive_arguments_unknown(mocker):
    CustomDirective = Directive(
        "custom", ["FIELD"],
        [Argument("a", String), Argument("b", Int)])

    resolver = mocker.Mock(return_value=42)

    execute(
        Schema(test_type, directives=[CustomDirective]),
        parse('{ a @custom(a: "foo", b: 42) }'),
        initial_value=_obj(a=resolver),
    )

    (_, info), _ = resolver.call_args

    with pytest.raises(KeyError):
        info.get_directive_arguments("foo")