From 3daa11168d4a5d2bf5363b5b298a67d7e2617fff Mon Sep 17 00:00:00 2001 From: Tommy Lillehagen Date: Mon, 3 Jun 2024 21:52:32 +0100 Subject: [PATCH] chore: consistently resolve ignore flags in derived types --- .../Types/Resolution/ObjectReflector.cs | 16 +++- .../MetaData/IgnoreAttributeTests.cs | 76 +++++++++++++++++++ 2 files changed, 89 insertions(+), 3 deletions(-) diff --git a/src/GraphQL.Conventions/Types/Resolution/ObjectReflector.cs b/src/GraphQL.Conventions/Types/Resolution/ObjectReflector.cs index c252662..a01256b 100644 --- a/src/GraphQL.Conventions/Types/Resolution/ObjectReflector.cs +++ b/src/GraphQL.Conventions/Types/Resolution/ObjectReflector.cs @@ -250,17 +250,27 @@ private IEnumerable GetFields(TypeInfo typeInfo) .ImplementedInterfaces .SelectMany(iface => iface.GetMethods(DefaultBindingFlags)); - return typeInfo + var fields = typeInfo .GetMethods(DefaultBindingFlags) .Union(implementedMethods) .Union(GetExtensionMethods(typeInfo)) .Where(IsValidMember) .Where(methodInfo => !methodInfo.IsSpecialName) .Cast() - .Union(properties) - .Select(DeriveField) + .Union(properties); + + var deduped = fields + .GroupBy(prop => prop.Name) + .Select(g => g.First()); + + var derivedFields = deduped + .Select(DeriveField); + + var filteredFields = derivedFields .Where(field => !field.IsIgnored) .OrderBy(field => field.Name); + + return filteredFields; } private IEnumerable GetArguments(MethodInfo methodInfo) diff --git a/test/GraphQL.Conventions.Tests/Attributes/MetaData/IgnoreAttributeTests.cs b/test/GraphQL.Conventions.Tests/Attributes/MetaData/IgnoreAttributeTests.cs index 955427e..5ad8641 100644 --- a/test/GraphQL.Conventions.Tests/Attributes/MetaData/IgnoreAttributeTests.cs +++ b/test/GraphQL.Conventions.Tests/Attributes/MetaData/IgnoreAttributeTests.cs @@ -1,4 +1,8 @@ +using System.Linq; using GraphQL.Conventions; +using GraphQL.Conventions.Adapters; +using GraphQL.Conventions.Builders; +using GraphQL.Types; using Tests.Templates; using Tests.Templates.Extensions; // ReSharper disable UnusedMember.Local @@ -24,6 +28,44 @@ public void Enum_Members_Can_Be_Ignored() type.ShouldHaveFieldWithName("DEPRECATED_MEMBER").AndWithDeprecationReason("Some enum member reason"); } + [Test] + public void Derived_Fields_Can_Be_Ignored() + { + var type = TypeInfo(); + type.Fields.Count.ShouldEqual(2); + type.ShouldHaveFieldWithName("firstProperty"); + type.ShouldHaveFieldWithName("someOtherProperty"); + type.ShouldNotHaveFieldWithName("someProperty"); + + var iface = TypeInfo(); + iface.Fields.Count.ShouldEqual(1); + iface.ShouldHaveFieldWithName("firstProperty"); + iface.ShouldNotHaveFieldWithName("someProperty"); + } + + [Test] + public void Can_Ignore_Unwanted_Fields_On_Derived_Types() + { + var schema = new SchemaConstructor(new GraphTypeAdapter()) + .IgnoreTypes((t, m) => m?.Name == nameof(ISomeInterfaceExternal.SomeProperty)) + .Build(typeof(SchemaType)); + + schema.Initialize(); + var type = schema.AllTypes[nameof(ImplementationExternal)] as ObjectGraphType; + Assert.AreEqual(1, type.Fields.Count(f => f.Name == "someOtherProperty")); + Assert.AreEqual(0, type.Fields.Count(f => f.Name == "someProperty")); + } + + private class SchemaType + { + public QueryType Query { get; } + } + + private class QueryType + { + public ImplementationExternal Foo => new(); + } + private class FieldData { public int NormalField { get; set; } @@ -42,5 +84,39 @@ public enum Enum DeprecatedMember, } } + + private class Implementation : ISomeInterface + { + public string FirstProperty { get; set; } + + [Ignore] + public string SomeProperty { get; set; } + + public string SomeOtherProperty { get; set; } + } + + private interface ISomeInterface + { + public string FirstProperty { get; set; } + + [Ignore] + public string SomeProperty { get; set; } + } + + private class ImplementationExternal : ISomeInterfaceExternal + { + public string FirstProperty { get; set; } + + public string SomeProperty { get; set; } + + public string SomeOtherProperty { get; set; } + } + + private interface ISomeInterfaceExternal + { + public string FirstProperty { get; set; } + + public string SomeProperty { get; set; } + } } }