Improve paginated type check in schema inspection

Closes gh-1053
This commit is contained in:
rstoyanchev
2024-09-04 17:08:14 +01:00
parent 1979e435c3
commit 579bb649bd
2 changed files with 53 additions and 15 deletions

View File

@@ -684,8 +684,9 @@ public final class SchemaMappingInspector {
// Remove GraphQL type wrappers, and nest within Java generic types
GraphQLType outputType = unwrapIfNonNull(field.getType());
if (isPaginatedType(outputType)) {
outputType = getPaginatedType((GraphQLObjectType) outputType, schema);
GraphQLType paginatedType = getPaginatedType(outputType);
if (paginatedType != null) {
outputType = paginatedType;
resolvableType = nestForConnection(resolvableType);
}
else if (outputType instanceof GraphQLList listType) {
@@ -702,17 +703,26 @@ public final class SchemaMappingInspector {
return (type instanceof GraphQLNonNull graphQLNonNull) ? graphQLNonNull.getWrappedType() : type;
}
private static boolean isPaginatedType(GraphQLType type) {
return (type instanceof GraphQLObjectType objectType &&
objectType.getName().endsWith("Connection") &&
objectType.getField("edges") != null && objectType.getField("pageInfo") != null);
}
private static GraphQLType getPaginatedType(GraphQLObjectType type, GraphQLSchema schema) {
String name = type.getName().substring(0, type.getName().length() - 10);
GraphQLType nodeType = schema.getType(name);
Assert.state(nodeType != null, "No node type for '" + type.getName() + "'");
return nodeType;
@Nullable
private static GraphQLType getPaginatedType(GraphQLType type) {
if (!(type instanceof GraphQLObjectType cot && cot.getName().endsWith("Connection"))) {
return null;
}
GraphQLFieldDefinition edges = cot.getField("edges");
if (edges == null) {
return null;
}
if (!(unwrapIfNonNull(edges.getType()) instanceof GraphQLList lt)) {
return null;
}
if (!(lt.getWrappedType() instanceof GraphQLObjectType eot)) {
return null;
}
GraphQLFieldDefinition node = eot.getField("node");
if (node == null) {
return null;
}
return unwrapIfNonNull(node.getType());
}
private static ResolvableType nestForConnection(ResolvableType type) {

View File

@@ -113,7 +113,7 @@ class SchemaMappingInspectorTests extends SchemaMappingInspectorTestSupport {
}
@Test
void reportWorksForQueryWithConnection() {
void reportWorksForConnectionType() {
String schema = """
type Query {
paginatedBooks: BookConnection
@@ -124,7 +124,7 @@ class SchemaMappingInspectorTests extends SchemaMappingInspectorTestSupport {
}
type BookEdge {
cursor: String!
# ...
node: Book!
}
type PageInfo {
startCursor: String
@@ -140,6 +140,34 @@ class SchemaMappingInspectorTests extends SchemaMappingInspectorTestSupport {
assertThatReport(report).hasUnmappedFieldCount(1).containsUnmappedFields("Book", "missing");
}
@Test // gh-1053
void reportWorksForConnectionWithCustomNodeTypeName() {
String schema = """
type Query {
paginatedBooks: BookConnection
}
type BookConnection {
edges: [BookEdge]!
pageInfo: PageInfo!
}
type BookEdge {
cursor: String!
node: MyBook!
}
type PageInfo {
startCursor: String
# ...
}
type MyBook {
id: ID
name: String
missing: Boolean
}
""";
SchemaReport report = inspectSchema(schema, BookController.class);
assertThatReport(report).hasUnmappedFieldCount(1).containsUnmappedFields("MyBook", "missing");
}
@Test
void reportWorksForQueryWithExtensionType() {
String schema = """