Improves generic type support in schema inspection

The fix targets cases when a method's return type has a generic
type, and the generic type is declared inline on the return type.
We need to pass containing class information as a ResolvableType
in order to be able to resolve generic types.

Closes gh-1037
This commit is contained in:
rstoyanchev
2024-09-13 18:58:13 +01:00
parent 579bb649bd
commit 763877bee7
2 changed files with 33 additions and 4 deletions

View File

@@ -93,7 +93,6 @@ public final class SchemaMappingInspector {
(!method.getDeclaringClass().equals(Object.class) && !method.getReturnType().equals(Void.class) &&
method.getParameterCount() == 0 && Modifier.isPublic(method.getModifiers()));
private final GraphQLSchema schema;
private final Map<String, Map<String, DataFetcher>> dataFetchers;
@@ -182,13 +181,15 @@ public final class SchemaMappingInspector {
if (resolvableType != null) {
PropertyDescriptor descriptor = getProperty(resolvableType, fieldName);
if (descriptor != null) {
checkField(fieldContainer, field, ResolvableType.forMethodReturnType(descriptor.getReadMethod()));
MethodParameter returnType = new MethodParameter(descriptor.getReadMethod(), -1);
checkField(fieldContainer, field, ResolvableType.forMethodParameter(returnType, resolvableType));
continue;
}
// Kotlin function?
Method method = getRecordLikeMethod(resolvableType, fieldName);
if (method != null) {
checkField(fieldContainer, field, ResolvableType.forMethodReturnType(method));
MethodParameter returnType = new MethodParameter(method, -1);
checkField(fieldContainer, field, ResolvableType.forMethodParameter(returnType, resolvableType));
continue;
}
}

View File

@@ -310,7 +310,7 @@ class SchemaMappingInspectorTests extends SchemaMappingInspectorTestSupport {
@Nested
class TypesInspectionTests {
class SchemaTypeInspectionTests {
@Test
void reportIsEmptyWhenFieldHasMatchingObjectProperty() {
@@ -434,6 +434,25 @@ class SchemaMappingInspectorTests extends SchemaMappingInspectorTestSupport {
assertThatReport(report).hasUnmappedFieldCount(1).containsUnmappedFields("Author", "missing");
}
@Test // gh-1037
void reportHasUnmappedFieldOnGenericType() {
String schema = """
type Query {
teamContainer: TeamContainer
}
type TeamContainer {
items: [Team]
}
type Team {
name: String
missing: String
}
""";
SchemaReport report = inspectSchema(schema, TeamController.class);
assertThatReport(report).hasUnmappedFieldCount(1).containsUnmappedFields("Team", "missing");
}
@Test
void reportWorksWithCyclicRelations() {
String schema = """
@@ -680,6 +699,10 @@ class SchemaMappingInspectorTests extends SchemaMappingInspectorTestSupport {
return null;
}
@QueryMapping
public ListContainer<Team> teamContainer() {
return new ListContainer<>(Collections.emptyList());
}
}
@@ -692,4 +715,9 @@ class SchemaMappingInspectorTests extends SchemaMappingInspectorTestSupport {
}
record ListContainer<T>(List<T> items) {
}
}