From 7e2a671ca52fb22c5d86d5d2f5ffe7fbafaceb96 Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Mon, 18 Mar 2024 16:32:07 +0000 Subject: [PATCH] ClassNameTypeResolver resolves to concrete types only See gh-924 --- .../execution/ClassNameTypeResolver.java | 8 ++++--- .../execution/ClassNameTypeResolverTests.java | 23 +++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/ClassNameTypeResolver.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/ClassNameTypeResolver.java index c6881521..2427cf8a 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/execution/ClassNameTypeResolver.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/ClassNameTypeResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import java.util.function.Function; import graphql.TypeResolutionEnvironment; import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLSchema; +import graphql.schema.GraphQLType; import graphql.schema.TypeResolver; import org.springframework.lang.Nullable; @@ -97,8 +98,9 @@ public class ClassNameTypeResolver implements TypeResolver { } name = this.classNameExtractor.apply(clazz); - if (schema.containsType(name)) { - return schema.getObjectType(name); + GraphQLType type = schema.getType(name); + if (type instanceof GraphQLObjectType objectType) { + return objectType; } for (Class interfaceType : clazz.getInterfaces()) { diff --git a/spring-graphql/src/test/java/org/springframework/graphql/execution/ClassNameTypeResolverTests.java b/spring-graphql/src/test/java/org/springframework/graphql/execution/ClassNameTypeResolverTests.java index 93ec4e59..a92a7c40 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/execution/ClassNameTypeResolverTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/execution/ClassNameTypeResolverTests.java @@ -97,6 +97,7 @@ public class ClassNameTypeResolverTests { graphQlSetup.queryFetcher("animals", env -> animalList).toGraphQlService(); ResponseHelper response = ResponseHelper.forResponse(service.execute(document)); + assertThat(response.errorCount()).isEqualTo(0); Mammal mammal = response.toEntity("animals[0]", Dog.class); assertThat(mammal.isHerbivore()).isEqualTo(false); @@ -134,6 +135,7 @@ public class ClassNameTypeResolverTests { .toGraphQlService(); ResponseHelper response = ResponseHelper.forResponse(service.execute(document)); + assertThat(response.errorCount()).isEqualTo(0); Animal animal = response.toEntity("sightings[0]", GrayWolf.class); assertThat(animal.getName()).isEqualTo("Gray Wolf"); @@ -142,6 +144,27 @@ public class ClassNameTypeResolverTests { assertThat(tree.getFamily()).isEqualTo("Redwood"); } + @Test + void javaTypeResolvesToSchemaInterfaceOnly() { + + String document = """ + query Animals { + animals { + __typename + name + } + } + """; + + TestExecutionGraphQlService service = + graphQlSetup.queryFetcher("animals", env -> List.of(new BaseAnimal("Fox"))).toGraphQlService(); + + ResponseHelper response = ResponseHelper.forResponse(service.execute(document)); + assertThat(response.errorCount()).isEqualTo(1); + assertThat(response.error(0).message()).contains("Could not determine the exact type of 'Animal'"); + } + + interface Animal {