Skip to content

Commit 051736c

Browse files
authored
[generator] fix deserialization of enum values that have custom names (#1516)
Enum value mapping logic was only using Kotlin/Java Enum value name. Updated logic to account for custom `@GraphQLName` values. Resolves: #1496
1 parent 385d00a commit 051736c

File tree

2 files changed

+43
-3
lines changed

2 files changed

+43
-3
lines changed

generator/graphql-kotlin-schema-generator/src/main/kotlin/com/expediagroup/graphql/generator/execution/convertArgumentValue.kt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package com.expediagroup.graphql.generator.execution
1818

1919
import com.expediagroup.graphql.generator.exceptions.PrimaryConstructorNotFound
20+
import com.expediagroup.graphql.generator.internal.extensions.getGraphQLName
2021
import com.expediagroup.graphql.generator.internal.extensions.getKClass
2122
import com.expediagroup.graphql.generator.internal.extensions.getName
2223
import com.expediagroup.graphql.generator.internal.extensions.getTypeOfFirstArgument
@@ -105,8 +106,16 @@ private fun <T : Any> mapToKotlinObject(input: Map<String, *>, targetClass: KCla
105106
return targetConstructor.callBy(constructorArguments)
106107
}
107108

108-
private fun mapToEnumValue(paramType: KType, enumValue: String): Enum<*> =
109-
paramType.getKClass().java.enumConstants.filterIsInstance(Enum::class.java).first { it.name == enumValue }
109+
private fun mapToEnumValue(paramType: KType, enumValue: String): Enum<*> = paramType.getKClass()
110+
.java
111+
.enumConstants
112+
.filterIsInstance(Enum::class.java)
113+
.map { enum ->
114+
val enumValueField = paramType.getKClass().java.getField(enum.name)
115+
enumValueField.getGraphQLName() to enum
116+
}
117+
.first { (name, _) -> name == enumValue }
118+
.second
110119

111120
private fun <T : Any> mapToInlineValueClass(value: Any?, targetClass: KClass<T>): T {
112121
val targetConstructor = targetClass.primaryConstructor ?: throw PrimaryConstructorNotFound(targetClass)

generator/graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/generator/execution/ConvertArgumentValueTest.kt

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package com.expediagroup.graphql.generator.execution
1818

19+
import com.expediagroup.graphql.generator.annotations.GraphQLName
1920
import com.expediagroup.graphql.generator.scalars.ID
2021
import graphql.schema.DataFetchingEnvironment
2122
import io.mockk.every
@@ -53,6 +54,15 @@ class ConvertArgumentValueTest {
5354
assertEquals(Foo.BAR, castResult)
5455
}
5556

57+
@Test
58+
fun `renamed enum object is parsed`() {
59+
val kParam = assertNotNull(TestFunctions::enumInput.findParameterByName("input"))
60+
val inputValue = "baz"
61+
val result = convertArgumentValue("input", kParam, mapOf("input" to inputValue))
62+
val castResult = assertIs<Foo>(result)
63+
assertEquals(Foo.BAZ, castResult)
64+
}
65+
5666
@Test
5767
fun `generic map object is parsed`() {
5868
val kParam = assertNotNull(TestFunctions::inputObject.findParameterByName("input"))
@@ -210,6 +220,23 @@ class ConvertArgumentValueTest {
210220
assertEquals("1234", result.value)
211221
}
212222

223+
@Test
224+
fun `input object with renamed fields is correctly deserialized`() {
225+
val kParam = assertNotNull(TestFunctions::inputObjectRenamed.findParameterByName("input"))
226+
val result = convertArgumentValue(
227+
"input",
228+
kParam,
229+
mapOf(
230+
"input" to mapOf(
231+
"bar" to "renamed"
232+
)
233+
)
234+
)
235+
236+
val castResult = assertIs<TestInputRenamed>(result)
237+
assertEquals("renamed", castResult.foo)
238+
}
239+
213240
class TestFunctions {
214241
fun enumInput(input: Foo): String = TODO()
215242
fun idInput(input: ID): String = TODO()
@@ -222,16 +249,20 @@ class ConvertArgumentValueTest {
222249
fun optionalInputObject(input: OptionalInput<TestInput>): String = TODO()
223250
fun optionalInputListObject(input: OptionalInput<List<TestInput>>): String = TODO()
224251
fun stringInput(input: String): String = TODO()
252+
fun inputObjectRenamed(input: TestInputRenamed): String = TODO()
225253
}
226254

227255
class TestInput(val foo: String, val bar: String? = null, val baz: List<String>? = null, val qux: String? = null)
228256
class TestInputNested(val foo: String? = "foo", val bar: String? = "bar", val nested: TestInputNestedType? = TestInputNestedType())
229257
class TestInputNestedType(val value: String = "nested default value")
230-
class TestInputNullableScalar(val foo: String, val id: ID? = null)
258+
class TestInputNullableScalar(val foo: String? = null, val id: ID? = null)
231259
class TestInputNotNullableScalar(val foo: String, val id: ID = ID("1234"))
232260

261+
class TestInputRenamed(@GraphQLName("bar") val foo: String)
262+
233263
enum class Foo {
234264
BAR,
265+
@GraphQLName("baz")
235266
BAZ
236267
}
237268
}

0 commit comments

Comments
 (0)