diff --git a/src/Core/Types.Selection.Abstractions.Tests/SelectionTestsBase.cs b/src/Core/Types.Selection.Abstractions.Tests/SelectionTestsBase.cs index 6b387941014..4b0dddc1dd5 100644 --- a/src/Core/Types.Selection.Abstractions.Tests/SelectionTestsBase.cs +++ b/src/Core/Types.Selection.Abstractions.Tests/SelectionTestsBase.cs @@ -116,6 +116,52 @@ public virtual void Execute_Selection_Scalar() }); } + [Fact] + public virtual void Execute_Selection_SingleScalarAndTypeName() + { + // arrange + IServiceCollection services; + Func> resolver; + (services, resolver) = _provider.CreateResolver(SAMPLE); + + IQueryable resultCtx = null; + ISchema schema = SchemaBuilder.New() + .AddServices(services.BuildServiceProvider()) + .AddQueryType( + d => d.Field(t => t.Foos) + .Resolver(resolver) + .Use(next => async ctx => + { + await next(ctx).ConfigureAwait(false); + resultCtx = ctx.Result as IQueryable; + }) + .UseSelection()) + .Create(); + IQueryExecutor executor = schema.MakeExecutable(); + + // act + executor.Execute( + "{ foos { bar __typename } }"); + + // assert + Assert.NotNull(resultCtx); + Assert.Collection(resultCtx.ToArray(), + x => + { + Assert.Equal("aa", x.Bar); + Assert.Equal(0, x.Baz); + Assert.Null(x.Nested); + Assert.Null(x.ObjectArray); + }, + x => + { + Assert.Equal("bb", x.Bar); + Assert.Equal(0, x.Baz); + Assert.Null(x.Nested); + Assert.Null(x.ObjectArray); + }); + } + [Fact] public virtual void Execute_Selection_MultipleScalar() { @@ -1522,7 +1568,7 @@ public class Foo public string GetComputedField() => Bar + Baz; - public string GetComputedFieldParent([Parent]Foo foo) => foo.Bar + foo.Baz; + public string GetComputedFieldParent([Parent] Foo foo) => foo.Bar + foo.Baz; public static Foo Create(string bar, int baz) { diff --git a/src/Core/Types.Selection/SelectionVisitor.cs b/src/Core/Types.Selection/SelectionVisitor.cs index f2c822a4da3..bcb87a89ae0 100644 --- a/src/Core/Types.Selection/SelectionVisitor.cs +++ b/src/Core/Types.Selection/SelectionVisitor.cs @@ -5,6 +5,7 @@ using HotChocolate.Execution; using HotChocolate.Language; using HotChocolate.Resolvers; +using HotChocolate.Types.Introspection; using HotChocolate.Types.Selections.Handlers; using HotChocolate.Utilities; @@ -40,6 +41,15 @@ public Expression> Project() return (Expression>)Closures.Peek().CreateMemberInitLambda(); } + protected override bool EnterLeaf(IFieldSelection selection) + { + if (IntrospectionFields.TypeName.Equals(selection.Field.Name)) + { + return false; + } + return base.EnterLeaf(selection); + } + protected override void LeaveLeaf(IFieldSelection selection) { if (selection.Field.Member is PropertyInfo member) diff --git a/src/Core/Types.Selection/SelectionVisitorBase.cs b/src/Core/Types.Selection/SelectionVisitorBase.cs index e1abb6391e8..2dd010bdc4b 100644 --- a/src/Core/Types.Selection/SelectionVisitorBase.cs +++ b/src/Core/Types.Selection/SelectionVisitorBase.cs @@ -5,6 +5,7 @@ using HotChocolate.Execution; using HotChocolate.Language; using HotChocolate.Resolvers; +using HotChocolate.Types.Introspection; using HotChocolate.Types.Relay; using static HotChocolate.Utilities.DotNetTypeInfoFactory; @@ -236,7 +237,8 @@ private static bool HasNonProjectableField(IReadOnlyList select { for (int i = 0; i < selections.Count; i++) { - if (!(selections[i].Field.Member is PropertyInfo)) + if (!(selections[i].Field.Member is PropertyInfo) && + !IntrospectionFields.TypeName.Equals(selections[i].Field.Name)) { return true; }