Skip to content

Commit cfd4de2

Browse files
authored
Merge pull request #480 from thomasw21/nested_inputs_in_extensions_do_not_work
Allowing nested inputs defined in extensions to be parsed as well
2 parents 0b2a3a5 + 2ded2f1 commit cfd4de2

File tree

2 files changed

+69
-17
lines changed

2 files changed

+69
-17
lines changed

src/main/kotlin/graphql/kickstart/tools/SchemaClassScanner.kt

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -333,26 +333,29 @@ internal class SchemaClassScanner(
333333
}
334334

335335
is InputObjectTypeDefinition -> {
336-
graphQLType.inputValueDefinitions.forEach { inputValueDefinition ->
337-
val inputGraphQLType = inputValueDefinition.type.unwrap()
338-
if (inputGraphQLType is TypeName && !ScalarInfo.GRAPHQL_SPECIFICATION_SCALARS_DEFINITIONS.containsKey(inputGraphQLType.name)) {
339-
val inputValueJavaType = findInputValueType(inputValueDefinition.name, inputGraphQLType, javaType.unwrap())
340-
if (inputValueJavaType != null) {
341-
handleFoundType(typeClassMatcher.match(TypeClassMatcher.PotentialMatch.parameterType(
342-
inputValueDefinition.type,
343-
inputValueJavaType,
344-
GenericType(javaType, options).relativeToType(inputValueJavaType),
345-
InputObjectReference(inputValueDefinition)
346-
)))
347-
} else {
348-
var mappingAdvice = "Try adding it manually to the dictionary"
349-
if (javaType.unwrap().name.contains("Map")) {
350-
mappingAdvice = " or add a class to represent your input type instead of a Map."
336+
val inputObjectTypes = listOf(graphQLType) + inputExtensionDefinitions.filter { it.name == graphQLType.name }
337+
inputObjectTypes
338+
.flatMap { it.inputValueDefinitions }
339+
.forEach { inputValueDefinition ->
340+
val inputGraphQLType = inputValueDefinition.type.unwrap()
341+
if (inputGraphQLType is TypeName && !ScalarInfo.GRAPHQL_SPECIFICATION_SCALARS_DEFINITIONS.containsKey(inputGraphQLType.name)) {
342+
val inputValueJavaType = findInputValueType(inputValueDefinition.name, inputGraphQLType, javaType.unwrap())
343+
if (inputValueJavaType != null) {
344+
handleFoundType(typeClassMatcher.match(TypeClassMatcher.PotentialMatch.parameterType(
345+
inputValueDefinition.type,
346+
inputValueJavaType,
347+
GenericType(javaType, options).relativeToType(inputValueJavaType),
348+
InputObjectReference(inputValueDefinition)
349+
)))
350+
} else {
351+
var mappingAdvice = "Try adding it manually to the dictionary"
352+
if (javaType.unwrap().name.contains("Map")) {
353+
mappingAdvice = " or add a class to represent your input type instead of a Map."
354+
}
355+
log.warn("Cannot find definition for field '${inputValueDefinition.name}: ${inputGraphQLType.name}' on input type '${graphQLType.name}' -> ${javaType.unwrap().name}. $mappingAdvice")
351356
}
352-
log.warn("Cannot find definition for field '${inputValueDefinition.name}: ${inputGraphQLType.name}' on input type '${graphQLType.name}' -> ${javaType.unwrap().name}. $mappingAdvice")
353357
}
354358
}
355-
}
356359
}
357360
}
358361
}

src/test/groovy/graphql/kickstart/tools/NestedInputTypesSpec.groovy

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,55 @@ class NestedInputTypesSpec extends Specification {
5353
data.materials == []
5454
}
5555

56+
def "nested input in extensions are parsed"() {
57+
when:
58+
GraphQLSchema schema = SchemaParser.newParser().schemaString('''\
59+
type Query {
60+
materials(filter: MaterialFilter): [Material!]!
61+
}
62+
63+
input MaterialFilter {
64+
title: String
65+
}
66+
67+
extend input MaterialFilter {
68+
requestFilter: RequestFilter
69+
}
70+
71+
input RequestFilter {
72+
and: [RequestFilter!]
73+
or: [RequestFilter!]
74+
discountTypeFilter: DiscountTypeFilter
75+
}
76+
77+
input DiscountTypeFilter {
78+
name: String
79+
}
80+
81+
type Material {
82+
id: ID!
83+
}
84+
''').resolvers(new QueryResolver())
85+
.build()
86+
.makeExecutableSchema()
87+
GraphQL gql = GraphQL.newGraphQL(schema)
88+
.queryExecutionStrategy(new AsyncExecutionStrategy())
89+
.build()
90+
def data = Utils.assertNoGraphQlErrors(gql, [filter: [title: "title", requestFilter: [discountTypeFilter: [name: "discount"]]]]) {
91+
'''
92+
query materials($filter: MaterialFilter!) {
93+
materials(filter: $filter) {
94+
id
95+
}
96+
}
97+
'''
98+
}
99+
100+
then:
101+
noExceptionThrown()
102+
data.materials == []
103+
}
104+
56105
class QueryResolver implements GraphQLQueryResolver {
57106
List<Material> materials(MaterialFilter filter) { Collections.emptyList() }
58107
}

0 commit comments

Comments
 (0)