Skip to content

Commit 8da7aed

Browse files
authored
fix: willAddGraphQLTypeToSchema needs annotations from field (#1437)
1 parent 0cca1e4 commit 8da7aed

File tree

4 files changed

+51
-8
lines changed

4 files changed

+51
-8
lines changed

generator/graphql-kotlin-schema-generator/src/main/kotlin/com/expediagroup/graphql/generator/internal/extensions/annotationExtensions.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ internal fun List<Annotation>.getUnionAnnotation(): GraphQLUnion? = this.filterI
3737

3838
internal fun List<Annotation>.getCustomUnionClassWithMetaUnionAnnotation(): KClass<*>? = this.firstOrNull { it.getMetaUnionAnnotation() != null }?.annotationClass
3939

40-
private fun Annotation.getMetaUnionAnnotation(): GraphQLUnion? = this.annotationClass.annotations.filterIsInstance(GraphQLUnion::class.java).firstOrNull()
40+
internal fun Annotation.getMetaUnionAnnotation(): GraphQLUnion? = this.annotationClass.annotations.filterIsInstance(GraphQLUnion::class.java).firstOrNull()
4141

4242
internal fun List<Annotation>.getCustomTypeAnnotation(): GraphQLType? = this.filterIsInstance(GraphQLType::class.java).firstOrNull()
4343

generator/graphql-kotlin-schema-generator/src/main/kotlin/com/expediagroup/graphql/generator/internal/types/generateGraphQLType.kt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import com.expediagroup.graphql.generator.extensions.unwrapType
2121
import com.expediagroup.graphql.generator.internal.extensions.getCustomTypeAnnotation
2222
import com.expediagroup.graphql.generator.internal.extensions.getCustomUnionClassWithMetaUnionAnnotation
2323
import com.expediagroup.graphql.generator.internal.extensions.getKClass
24+
import com.expediagroup.graphql.generator.internal.extensions.getMetaUnionAnnotation
2425
import com.expediagroup.graphql.generator.internal.extensions.getUnionAnnotation
2526
import com.expediagroup.graphql.generator.internal.extensions.isAnnotation
2627
import com.expediagroup.graphql.generator.internal.extensions.isEnum
@@ -32,6 +33,7 @@ import graphql.schema.GraphQLType
3233
import graphql.schema.GraphQLTypeReference
3334
import kotlin.reflect.KClass
3435
import kotlin.reflect.KType
36+
import kotlin.reflect.full.createType
3537

3638
/**
3739
* Return a basic GraphQL type given all the information about the kotlin type.
@@ -63,7 +65,19 @@ private fun objectFromReflection(generator: SchemaGenerator, type: KType, typeIn
6365

6466
return generator.cache.buildIfNotUnderConstruction(kClass, typeInfo) {
6567
val graphQLType = getGraphQLType(generator, kClass, type, typeInfo)
66-
generator.config.hooks.willAddGraphQLTypeToSchema(type, graphQLType)
68+
69+
/*
70+
* For a field using the meta union annotation, the `type` is `Any`, but we need to pass the annotation with the meta union annotation as the type
71+
* since that is really the type generated from reflection and has any potential directives on it needed by the hook
72+
*/
73+
val metaUnion = typeInfo.fieldAnnotations.firstOrNull { it.getMetaUnionAnnotation() != null }
74+
val resolvedType = if (kClass.isInstance(Any::class) && metaUnion != null) {
75+
metaUnion.annotationClass.createType()
76+
} else {
77+
type
78+
}
79+
80+
generator.config.hooks.willAddGraphQLTypeToSchema(resolvedType, graphQLType)
6781
}
6882
}
6983

generator/graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/generator/hooks/SchemaGeneratorHooksTest.kt

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@ import com.expediagroup.graphql.generator.SchemaGenerator
2020
import com.expediagroup.graphql.generator.SchemaGeneratorConfig
2121
import com.expediagroup.graphql.generator.TopLevelObject
2222
import com.expediagroup.graphql.generator.annotations.GraphQLIgnore
23+
import com.expediagroup.graphql.generator.annotations.GraphQLUnion
2324
import com.expediagroup.graphql.generator.exceptions.EmptyInputObjectTypeException
2425
import com.expediagroup.graphql.generator.exceptions.EmptyInterfaceTypeException
2526
import com.expediagroup.graphql.generator.exceptions.EmptyObjectTypeException
2627
import com.expediagroup.graphql.generator.extensions.deepName
2728
import com.expediagroup.graphql.generator.getTestSchemaConfigWithHooks
29+
import com.expediagroup.graphql.generator.internal.extensions.getKClass
2830
import com.expediagroup.graphql.generator.internal.extensions.getSimpleName
2931
import com.expediagroup.graphql.generator.test.utils.graphqlUUIDType
3032
import com.expediagroup.graphql.generator.testSchemaConfig
@@ -36,6 +38,7 @@ import graphql.schema.GraphQLObjectType
3638
import graphql.schema.GraphQLScalarType
3739
import graphql.schema.GraphQLSchema
3840
import graphql.schema.GraphQLType
41+
import graphql.schema.GraphQLUnionType
3942
import graphql.schema.validation.InvalidSchemaException
4043
import kotlinx.coroutines.flow.flowOf
4144
import kotlinx.coroutines.reactive.asPublisher
@@ -221,19 +224,25 @@ class SchemaGeneratorHooksTest {
221224
override fun willAddGraphQLTypeToSchema(type: KType, generatedType: GraphQLType): GraphQLType {
222225
hookCalled = true
223226
return when {
224-
generatedType is GraphQLObjectType && generatedType.name == "SomeData" -> GraphQLObjectType.newObject(generatedType).description("My custom description").build()
225-
generatedType is GraphQLInterfaceType && generatedType.name == "RandomData" ->
227+
generatedType is GraphQLObjectType && generatedType.name == "SomeData" && type.getKClass() == SomeData::class ->
228+
GraphQLObjectType.newObject(generatedType).description("My custom description").build()
229+
generatedType is GraphQLInterfaceType && generatedType.name == "RandomData" && type.getKClass() == RandomData::class ->
226230
GraphQLInterfaceType.newInterface(generatedType).description("My custom interface description").build()
231+
generatedType is GraphQLUnionType && generatedType.name == "MyMetaUnion" && type.getKClass() == MyMetaUnion::class ->
232+
GraphQLUnionType.newUnionType(generatedType).description("My meta union description").build()
233+
generatedType is GraphQLUnionType && generatedType.name == "MyAdditionalMetaUnion" && type.getKClass() == MyAdditionalMetaUnion::class ->
234+
GraphQLUnionType.newUnionType(generatedType).description("My additional meta union description").build()
227235
else -> generatedType
228236
}
229237
}
230238
}
231239

232240
val hooks = MockSchemaGeneratorHooks()
233-
val schema = toSchema(
234-
queries = listOf(TopLevelObject(TestQuery())),
235-
config = getTestSchemaConfigWithHooks(hooks)
236-
)
241+
val generator = SchemaGenerator(getTestSchemaConfigWithHooks(hooks))
242+
val schema = generator.use {
243+
it.generateSchema(queries = listOf(TopLevelObject(TestQuery())), additionalTypes = setOf(MyAdditionalMetaUnion::class.createType()))
244+
}
245+
237246
assertTrue(hooks.hookCalled)
238247

239248
val type = schema.getObjectType("SomeData")
@@ -243,6 +252,14 @@ class SchemaGeneratorHooksTest {
243252
val interfaceType = schema.getType("RandomData") as? GraphQLInterfaceType
244253
assertNotNull(interfaceType)
245254
assertEquals(expected = "My custom interface description", actual = interfaceType.description)
255+
256+
val metaUnionType = schema.getType("MyMetaUnion") as? GraphQLUnionType
257+
assertNotNull(metaUnionType)
258+
assertEquals(expected = "My meta union description", actual = metaUnionType.description)
259+
260+
val additionalMetaUnionType = schema.getType("MyAdditionalMetaUnion") as? GraphQLUnionType
261+
assertNotNull(additionalMetaUnionType)
262+
assertEquals(expected = "My additional meta union description", actual = additionalMetaUnionType.description)
246263
}
247264

248265
@Test
@@ -346,8 +363,16 @@ class SchemaGeneratorHooksTest {
346363

347364
class TestQuery {
348365
fun query(): SomeData = SomeData("someData", 0)
366+
@MyMetaUnion
367+
fun unionQuery(): Any = SomeData("someData", 0)
349368
}
350369

370+
@GraphQLUnion(name = "MyMetaUnion", possibleTypes = [SomeData::class])
371+
annotation class MyMetaUnion
372+
373+
@GraphQLUnion(name = "MyAdditionalMetaUnion", possibleTypes = [SomeData::class])
374+
annotation class MyAdditionalMetaUnion
375+
351376
class TestSubscription {
352377
fun subscription(): Publisher<SomeData> = flowOf(SomeData("someData", 0)).asPublisher()
353378
}

generator/graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/generator/internal/extensions/AnnotationExtensionsTest.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ class AnnotationExtensionsTest {
110110
assertNull(WithAnnotations::class.findMemberProperty("id")?.annotations?.getUnionAnnotation())
111111
@Suppress("DEPRECATION")
112112
assertNull(WithAnnotations::class.findMemberProperty("id")?.annotations?.getCustomUnionClassWithMetaUnionAnnotation())
113+
@Suppress("DEPRECATION")
114+
assertNotNull(WithAnnotations::class.findMemberProperty("metaUnion")?.annotations?.firstOrNull { it is MetaUnion }?.getMetaUnionAnnotation())
115+
@Suppress("DEPRECATION")
116+
assertNull(WithAnnotations::class.findMemberProperty("union")?.annotations?.firstOrNull { it is GraphQLUnion }?.getMetaUnionAnnotation())
113117
}
114118

115119
private fun KClass<*>.findMemberProperty(name: String) = this.declaredMemberProperties.find { it.name == name }

0 commit comments

Comments
 (0)