Skip to content

Commit 2c85ef0

Browse files
author
Cole Turner
authored
fix(InputerValueSerializer): allow scalars to be assignable from class (#555)
* fix(InputerValueSerializer): allow scalars to be assignable from class resolves #1522 * lint
1 parent c153b6f commit 2c85ef0

File tree

3 files changed

+111
-6
lines changed

3 files changed

+111
-6
lines changed

graphql-dgs-codegen-shared-core/src/main/kotlin/com/netflix/graphql/dgs/client/codegen/InputValueSerializer.kt

+4-2
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,10 @@ class InputValueSerializer(private val scalars: Map<Class<*>, Coercing<*, *>> =
8181
return input
8282
}
8383

84-
if (input::class.java in scalars) {
85-
return scalars.getValue(input::class.java).valueToLiteral(input)
84+
for (scalar in scalars.keys) {
85+
if (input::class.java == scalar || scalar.isAssignableFrom(input::class.java)) {
86+
return scalars[scalar]!!.valueToLiteral(input)
87+
}
8688
}
8789

8890
if (input::class in toStringClasses) {

graphql-dgs-codegen-shared-core/src/test/kotlin/com/netflix/graphql/dgs/client/codegen/GraphQLQueryRequestTest.kt

+5-4
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ import graphql.schema.Coercing
2828
import org.assertj.core.api.Assertions.assertThat
2929
import org.junit.jupiter.api.Test
3030
import java.time.LocalDate
31-
import java.util.Optional
32-
import java.util.UUID
31+
import java.time.ZoneId
32+
import java.util.*
3333

3434
class GraphQLQueryRequestTest {
3535
@Test
@@ -160,15 +160,16 @@ class GraphQLQueryRequestTest {
160160
val query = TestNamedGraphQLQuery().apply {
161161
input["movie"] = Movie(123, "greatMovie")
162162
input["dateRange"] = DateRange(LocalDate.of(2020, 1, 1), LocalDate.of(2021, 5, 11))
163+
input["zoneId"] = ZoneId.of("Europe/Berlin")
163164
}
164165
val request =
165-
GraphQLQueryRequest(query, MovieProjection(), mapOf(DateRange::class.java to DateRangeScalar()))
166+
GraphQLQueryRequest(query, MovieProjection(), mapOf(DateRange::class.java to DateRangeScalar(), ZoneId::class.java to ZoneIdScalar()))
166167

167168
val result = request.serialize()
168169
assertValidQuery(result)
169170
assertThat(result).isEqualTo(
170171
"""query TestNamedQuery {
171-
| test(movie: {movieId : 123, name : "greatMovie"}, dateRange: "01/01/2020-05/11/2021")
172+
| test(movie: {movieId : 123, name : "greatMovie"}, dateRange: "01/01/2020-05/11/2021", zoneId: "Europe/Berlin")
172173
|}
173174
""".trimMargin()
174175
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
*
3+
* Copyright 2020 Netflix, Inc.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
package com.netflix.graphql.dgs.client.codegen
20+
21+
import com.netflix.graphql.dgs.DgsScalar
22+
import graphql.language.StringValue
23+
import graphql.language.Value
24+
import graphql.schema.Coercing
25+
import graphql.schema.CoercingParseLiteralException
26+
import graphql.schema.CoercingParseValueException
27+
import graphql.schema.CoercingSerializeException
28+
import java.time.ZoneId
29+
import java.time.format.DateTimeParseException
30+
import java.time.zone.ZoneRulesException
31+
32+
@DgsScalar(name = "ZoneId")
33+
class ZoneIdScalar : Coercing<ZoneId, String> {
34+
@Throws(CoercingSerializeException::class)
35+
override fun serialize(dataFetcherResult: Any): String {
36+
return dataFetcherResult as? String
37+
?: if (dataFetcherResult is ZoneId) {
38+
dataFetcherResult.id
39+
} else {
40+
throw CoercingSerializeException("Expected type 'ZoneId', but was " + dataFetcherResult.javaClass.name)
41+
}
42+
}
43+
44+
@Throws(CoercingParseValueException::class)
45+
override fun parseValue(input: Any): ZoneId {
46+
return try {
47+
if (input is String) {
48+
ZoneId.of(input)
49+
} else {
50+
throw CoercingParseValueException("Expected a String")
51+
}
52+
} catch (e: DateTimeParseException) {
53+
throw CoercingParseValueException(
54+
String.format(
55+
"A valid ZoneId must be provided. I.e. 'Europe/Berlin' or 'UTC'. Was: '%s'.",
56+
input
57+
),
58+
e
59+
)
60+
} catch (e: ZoneRulesException) {
61+
throw CoercingParseValueException(
62+
String.format(
63+
"A valid ZoneId must be provided. I.e. 'Europe/Berlin' or 'UTC'. Was: '%s'.",
64+
input
65+
),
66+
e
67+
)
68+
}
69+
}
70+
71+
@Throws(CoercingParseLiteralException::class)
72+
override fun parseLiteral(input: Any): ZoneId {
73+
return if (input is StringValue) {
74+
try {
75+
ZoneId.of(input.getValue())
76+
} catch (e: DateTimeParseException) {
77+
throw CoercingParseValueException(
78+
String.format(
79+
"A valid ZoneId must be provided. I.e. 'Europe/Berlin' or 'UTC'. Was: '%s'.",
80+
input
81+
),
82+
e
83+
)
84+
} catch (e: ZoneRulesException) {
85+
throw CoercingParseValueException(
86+
String.format(
87+
"A valid ZoneId must be provided. I.e. 'Europe/Berlin' or 'UTC'. Was: '%s'.",
88+
input
89+
),
90+
e
91+
)
92+
}
93+
} else {
94+
throw CoercingParseLiteralException("Expected a StringValue.")
95+
}
96+
}
97+
98+
@Throws(CoercingParseLiteralException::class)
99+
override fun valueToLiteral(input: Any): Value<out Value<*>> {
100+
return StringValue.of(input.toString())
101+
}
102+
}

0 commit comments

Comments
 (0)