Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 06075c6

Browse filesBrowse files
BUG: TypeExpression type names on TypeExtensions (#139)
* Fixed a bug with type expression naming on extension fields
1 parent 027adde commit 06075c6
Copy full SHA for 06075c6

14 files changed

+527
-23
lines changed

‎src/graphql-aspnet/Schemas/GraphTypeExpression_Statics.cs

Copy file name to clipboardExpand all lines: src/graphql-aspnet/Schemas/GraphTypeExpression_Statics.cs
+30-16Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -156,19 +156,39 @@ public static GraphTypeExpression FromDeclaration(ReadOnlySpan<char> typeExpress
156156
/// <param name="typeWrappers">An optional set of wrappers to use as a set of overrides on the type provided.</param>
157157
/// <returns>GraphFieldOptions.</returns>
158158
public static GraphTypeExpression FromType(Type typeToCheck, MetaGraphTypes[] typeWrappers = null)
159+
{
160+
return FromType(typeToCheck, TypeKind.OBJECT, typeWrappers);
161+
}
162+
163+
/// <summary>
164+
/// Inspects the provided type and generates a type expression to represent it in the object grpah.
165+
/// </summary>
166+
/// <param name="typeToCheck">The complete type specification to check.</param>
167+
/// <param name="typeKind">An explicit typekind to use when determining the name of the <paramref name="typeToCheck"/>
168+
/// that will be included in the expression.</param>
169+
/// <param name="typeWrappers">An optional set of wrappers to use as a set of overrides on the type provided.</param>
170+
/// <returns>GraphFieldOptions.</returns>
171+
public static GraphTypeExpression FromType(Type typeToCheck, TypeKind typeKind, MetaGraphTypes[] typeWrappers = null)
172+
{
173+
var name = GraphTypeNames.ParseName(typeToCheck, typeKind);
174+
return FromType(typeToCheck, name, typeWrappers);
175+
}
176+
177+
/// <summary>
178+
/// Inspects the provided type and generates a type expression to represent it in the object grpah.
179+
/// </summary>
180+
/// <param name="typeToCheck">The complete type specification to check.</param>
181+
/// <param name="typeName">An explicit typename to use in the type expression. This value
182+
/// will override any name gleaned from <paramref name="typeToCheck"/>. </param>
183+
/// <param name="typeWrappers">An optional set of wrappers to use as a set of overrides on the type provided.</param>
184+
/// <returns>GraphFieldOptions.</returns>
185+
public static GraphTypeExpression FromType(Type typeToCheck, string typeName, MetaGraphTypes[] typeWrappers = null)
159186
{
160187
Validation.ThrowIfNull(typeToCheck, nameof(typeToCheck));
188+
typeName = Validation.ThrowIfNullWhiteSpaceOrReturn(typeName, nameof(typeName));
161189

162190
if (typeWrappers != null)
163-
{
164-
typeToCheck = GraphValidation.EliminateWrappersFromCoreType(
165-
typeToCheck,
166-
eliminateEnumerables: true,
167-
eliminateTask: true,
168-
eliminateNullableT: true);
169-
170-
return new GraphTypeExpression(typeToCheck.FriendlyGraphTypeName(), typeWrappers);
171-
}
191+
return new GraphTypeExpression(typeName, typeWrappers);
172192

173193
// strip out Task{T} before doin any type inspections
174194
typeToCheck = GraphValidation.EliminateWrappersFromCoreType(
@@ -207,13 +227,7 @@ public static GraphTypeExpression FromType(Type typeToCheck, MetaGraphTypes[] ty
207227
wrappers.Add(MetaGraphTypes.IsNotNull);
208228
}
209229

210-
typeToCheck = GraphValidation.EliminateWrappersFromCoreType(
211-
typeToCheck,
212-
eliminateEnumerables: false,
213-
eliminateTask: false,
214-
eliminateNullableT: true);
215-
216-
return new GraphTypeExpression(typeToCheck.FriendlyGraphTypeName(), wrappers);
230+
return new GraphTypeExpression(typeName, wrappers);
217231
}
218232

219233
/// <summary>

‎src/unit-tests/graphql-aspnet-tests/Execution/IntrospectionTests.cs

Copy file name to clipboardExpand all lines: src/unit-tests/graphql-aspnet-tests/Execution/IntrospectionTests.cs
+186Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2013,5 +2013,191 @@ public async Task Descriptions_OnInheritedInterfaces_AreRetrievedViaIntrospectio
20132013

20142014
CommonAssertions.AreEqualJsonStrings(expectedResponse, response);
20152015
}
2016+
2017+
[Test]
2018+
public async Task TypeExtension_ReturnsChildObject_WithCustomName_RendersWithCorrectCustomName()
2019+
{
2020+
var server = new TestServerBuilder()
2021+
.AddController<TypeWithNoCustomNameTypeExtensionController>()
2022+
.Build();
2023+
2024+
var context = server.CreateQueryContextBuilder()
2025+
.AddQueryText(@"
2026+
{
2027+
__type(name: ""TypeWithNoCustomName"")
2028+
{
2029+
kind
2030+
name
2031+
fields(includeDeprecated: true) {
2032+
name
2033+
}
2034+
}
2035+
}");
2036+
2037+
var response = await server.RenderResult(context);
2038+
2039+
var expectedResult = @"
2040+
{
2041+
""data"": {
2042+
""__type"": {
2043+
""kind"": ""OBJECT"",
2044+
""name"": ""TypeWithNoCustomName"",
2045+
""fields"": [
2046+
{
2047+
""name"": ""field1""
2048+
},
2049+
{
2050+
""name"": ""fieldTwo""
2051+
}
2052+
]
2053+
}
2054+
}
2055+
}";
2056+
2057+
CommonAssertions.AreEqualJsonStrings(expectedResult, response);
2058+
2059+
Assert.IsNotNull(server.Schema.KnownTypes.FindGraphType("TypeWithNoCustomName"));
2060+
Assert.IsNotNull(server.Schema.KnownTypes.FindGraphType("Type_With_Custom_Name"));
2061+
}
2062+
2063+
[Test]
2064+
public async Task BatchTypeExntesion_ReturnsChildObject_WithCustomName_RendersWithCorrectCustomName()
2065+
{
2066+
var server = new TestServerBuilder()
2067+
.AddController<TypeWithNoCustomNameBatchExtensionController>()
2068+
.Build();
2069+
2070+
var context = server.CreateQueryContextBuilder()
2071+
.AddQueryText(@"
2072+
{
2073+
__type(name: ""TypeWithNoCustomName"")
2074+
{
2075+
kind
2076+
name
2077+
fields(includeDeprecated: true) {
2078+
name
2079+
}
2080+
}
2081+
}");
2082+
2083+
var response = await server.RenderResult(context);
2084+
2085+
var expectedResult = @"
2086+
{
2087+
""data"": {
2088+
""__type"": {
2089+
""kind"": ""OBJECT"",
2090+
""name"": ""TypeWithNoCustomName"",
2091+
""fields"": [
2092+
{
2093+
""name"": ""field1""
2094+
},
2095+
{
2096+
""name"": ""fieldTwo""
2097+
}
2098+
]
2099+
}
2100+
}
2101+
}";
2102+
2103+
CommonAssertions.AreEqualJsonStrings(expectedResult, response);
2104+
2105+
Assert.IsNotNull(server.Schema.KnownTypes.FindGraphType("TypeWithNoCustomName"));
2106+
Assert.IsNotNull(server.Schema.KnownTypes.FindGraphType("Type_With_Custom_Name"));
2107+
}
2108+
2109+
[Test]
2110+
public async Task TypeExtension_Type_ThatHasCustomName_AndChildOfSameType_RendersProperly()
2111+
{
2112+
var server = new TestServerBuilder()
2113+
.AddController<TypeWithCustomNameTypeExtensionController>()
2114+
.Build();
2115+
2116+
var context = server.CreateQueryContextBuilder()
2117+
.AddQueryText(@"
2118+
{
2119+
#custom named
2120+
__type(name: ""Type_With_Custom_Name"")
2121+
{
2122+
kind
2123+
name
2124+
fields(includeDeprecated: true) {
2125+
name
2126+
}
2127+
}
2128+
}");
2129+
2130+
var response = await server.RenderResult(context);
2131+
2132+
var expectedResult = @"
2133+
{
2134+
""data"": {
2135+
""__type"": {
2136+
""kind"": ""OBJECT"",
2137+
""name"": ""Type_With_Custom_Name"",
2138+
""fields"": [
2139+
{
2140+
""name"": ""field1""
2141+
},
2142+
{
2143+
""name"": ""fieldTwo""
2144+
},
2145+
{
2146+
""name"": ""fieldThree""
2147+
}
2148+
]
2149+
}
2150+
}
2151+
}";
2152+
2153+
CommonAssertions.AreEqualJsonStrings(expectedResult, response);
2154+
}
2155+
2156+
[Test]
2157+
public async Task BatchTypeExtension_Type_ThatHasCustomName_AndChildrenOfSameType_RendersProperly()
2158+
{
2159+
var server = new TestServerBuilder()
2160+
.AddController<TypeWithCustomNameBatchExtensionController>()
2161+
.Build();
2162+
2163+
var context = server.CreateQueryContextBuilder()
2164+
.AddQueryText(@"
2165+
{
2166+
#custom named
2167+
__type(name: ""Type_With_Custom_Name"")
2168+
{
2169+
kind
2170+
name
2171+
fields(includeDeprecated: true) {
2172+
name
2173+
}
2174+
}
2175+
}");
2176+
2177+
var response = await server.RenderResult(context);
2178+
2179+
var expectedResult = @"
2180+
{
2181+
""data"": {
2182+
""__type"": {
2183+
""kind"": ""OBJECT"",
2184+
""name"": ""Type_With_Custom_Name"",
2185+
""fields"": [
2186+
{
2187+
""name"": ""field1""
2188+
},
2189+
{
2190+
""name"": ""fieldTwo""
2191+
},
2192+
{
2193+
""name"": ""fieldThree""
2194+
}
2195+
]
2196+
}
2197+
}
2198+
}";
2199+
2200+
CommonAssertions.AreEqualJsonStrings(expectedResult, response);
2201+
}
20162202
}
20172203
}
+22Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// *************************************************************
2+
// project: graphql-aspnet
3+
// --
4+
// repo: https://github.com/graphql-aspnet
5+
// docs: https://graphql-aspnet.github.io
6+
// --
7+
// License: MIT
8+
// *************************************************************
9+
10+
namespace GraphQL.AspNet.Tests.Execution.TestData.IntrospectionTestData
11+
{
12+
using GraphQL.AspNet.Attributes;
13+
14+
[GraphType("Type_With_Custom_Name")]
15+
public class TypeWithCustomName
16+
{
17+
public int Field1 { get; set; }
18+
19+
[GraphField("FieldTwo")]
20+
public string Field2 { get; set; }
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// *************************************************************
2+
// project: graphql-aspnet
3+
// --
4+
// repo: https://github.com/graphql-aspnet
5+
// docs: https://graphql-aspnet.github.io
6+
// --
7+
// License: MIT
8+
// *************************************************************
9+
10+
namespace GraphQL.AspNet.Tests.Execution.TestData.IntrospectionTestData
11+
{
12+
using System.Collections;
13+
using System.Collections.Generic;
14+
using GraphQL.AspNet.Attributes;
15+
using GraphQL.AspNet.Controllers;
16+
17+
public class TypeWithCustomNameBatchExtensionController : GraphController
18+
{
19+
[BatchTypeExtension(typeof(TypeWithCustomName), "fieldThree")]
20+
public IDictionary<TypeWithCustomName, IEnumerable<TypeWithCustomName>> TypeWithCustomNameField3(
21+
IEnumerable<TypeWithCustomName> parents)
22+
{
23+
var dic = new Dictionary<TypeWithCustomName, IEnumerable<TypeWithCustomName>>();
24+
var i = 0;
25+
foreach (var item in parents)
26+
{
27+
dic.Add(item, new List<TypeWithCustomName>()
28+
{
29+
new TypeWithCustomName()
30+
{
31+
Field1 = i++,
32+
Field2 = $"Child_Of_{item.Field2}",
33+
},
34+
new TypeWithCustomName()
35+
{
36+
Field1 = i++,
37+
Field2 = $"Child_Of_{item.Field2}",
38+
},
39+
});
40+
}
41+
42+
return dic;
43+
}
44+
}
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// *************************************************************
2+
// project: graphql-aspnet
3+
// --
4+
// repo: https://github.com/graphql-aspnet
5+
// docs: https://graphql-aspnet.github.io
6+
// --
7+
// License: MIT
8+
// *************************************************************
9+
10+
namespace GraphQL.AspNet.Tests.Execution.TestData.IntrospectionTestData
11+
{
12+
using GraphQL.AspNet.Attributes;
13+
using GraphQL.AspNet.Controllers;
14+
15+
public class TypeWithCustomNameTypeExtensionController : GraphController
16+
{
17+
[TypeExtension(typeof(TypeWithCustomName), "fieldThree")]
18+
public TypeWithCustomName TypeWithCustomNameField3(
19+
TypeWithCustomName parent)
20+
{
21+
return new TypeWithCustomName()
22+
{
23+
Field1 = 0,
24+
Field2 = $"Child_Of_{parent.Field2}",
25+
};
26+
}
27+
}
28+
}
+16Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// *************************************************************
2+
// project: graphql-aspnet
3+
// --
4+
// repo: https://github.com/graphql-aspnet
5+
// docs: https://graphql-aspnet.github.io
6+
// --
7+
// License: MIT
8+
// *************************************************************
9+
10+
namespace GraphQL.AspNet.Tests.Execution.TestData.IntrospectionTestData
11+
{
12+
public class TypeWithNoCustomName
13+
{
14+
public string Field1 { get; set; }
15+
}
16+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.