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"}
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", ]
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 } """)
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]
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 } """))
def test_mutation_operation_without_name(): assert print_ast(parse("mutation { id, name }")) == dedent(""" mutation { id name } """)
def test_query_operation_without_name(): assert print_ast(parse("query { id, name }")) == dedent(""" { id name } """)
async def test_raises_on_unsupported_operations(starwars_schema): with pytest.raises(RuntimeError): subscribe( starwars_schema, parse("query { counter(delay: 0.001) }"), runtime=AsyncIORuntime(), )
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" }, }, )
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" }, ], } }, )
def test_block_string_single_line_with_leading_space(): assert (print_ast( parse(''' { field(arg: """ space-led value""") } ''')) == dedent(''' { field(arg: """ space-led value""") } '''))
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 } ''')
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 } """))
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]]
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", ]
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"}
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" """) } ''')
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 } """)
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" }}, )
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", ]
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", ]
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" }}, )
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}, )
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
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(), )
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 )
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" }}, )
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"]
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", )], )
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")