@@ -11,8 +11,12 @@ import graphql.language.Value
1111import graphql.schema.Coercing
1212import graphql.schema.CoercingParseLiteralException
1313import graphql.schema.CoercingSerializeException
14+ import graphql.kickstart.tools.resolver.FieldResolverError
15+ import graphql.kickstart.tools.resolver.MissingResolverDataFetcherProvider
16+ import graphql.schema.DataFetcher
1417import graphql.schema.DataFetchingEnvironment
1518import graphql.schema.GraphQLScalarType
19+ import org.junit.Assert.assertThrows
1620import org.junit.Test
1721import java.lang.reflect.InvocationHandler
1822import java.lang.reflect.Method
@@ -311,45 +315,77 @@ class MethodFieldResolverTest {
311315 }
312316
313317 @Test
314- fun `should warn when a resolver method is missing a parameter for an argument` () {
315- val (_, warnings) = withWarnings {
316- SchemaParser .newParser()
317- .schemaString(
318- """
319- type Query {
320- user(id: ID!, active: Boolean!): String
321- users(active: Boolean, first: Int): String
322- image: Image
323- search(filter: Filter): String
324- count(active: Boolean): String
325- }
326-
327- type Image {
328- thumbnail(size: Int): String
329- }
330-
331- input Filter {
332- name: String
333- }
334- """ )
335- .resolvers(MissingParameterQuery (), ImageResolver ())
336- .options(SchemaParserOptions .newOptions().contextClass(Map ::class ).build())
337- .build()
338- .makeExecutableSchema()
339- }
340-
318+ fun `should fail the build when a resolver method is missing a parameter for an argument` () {
341319 val query = MissingParameterQuery ::class .java.name
342- assertEquals(warnings, listOf (
343- " Field 'Query.user' has no parameter for its argument 'active: Boolean!' in $query .user, so the Map parameter gets the " +
320+ val messagesByQueryField = mapOf (
321+ " user(id: ID!, active: Boolean!): String" to
322+ " Field 'Query.user' has no parameter for its argument 'active: Boolean!' in $query .user, so the Map parameter gets the " +
344323 " argument instead. Add a parameter for each argument, in order, before the Map parameter." ,
345- " Field 'Query.users' has no parameter for its argument 'active: Boolean' in $query .users, so the GraphQLContext parameter " +
324+ " users(active: Boolean, first: Int): String" to
325+ " Field 'Query.users' has no parameter for its argument 'active: Boolean' in $query .users, so the GraphQLContext parameter " +
346326 " gets the argument instead. Add a parameter for each argument, in order, before the GraphQLContext parameter." ,
347- " Field 'Image.thumbnail' has no parameter for its argument 'size: Int' in ${ImageResolver ::class .java.name} .thumbnail, so the " +
348- " DataFetchingEnvironment parameter gets the argument instead. Add a parameter for each argument, in order, before the " +
327+ " image: Image" to
328+ " Field 'Image.thumbnail' has no parameter for its argument 'size: Int' in ${ImageResolver ::class .java.name} .thumbnail, so " +
329+ " the DataFetchingEnvironment parameter gets the argument instead. Add a parameter for each argument, in order, before the " +
349330 " DataFetchingEnvironment parameter."
350- ))
331+ )
332+
333+ messagesByQueryField.forEach { (queryField, message) ->
334+ val error = assertThrows(FieldResolverError ::class .java) {
335+ buildMissingParameterSchema(queryField, SchemaParserOptions .newOptions())
336+ }
337+
338+ assertEquals(error.message, message)
339+ }
340+ }
341+
342+ @Test
343+ fun `should fail the build for a missing parameter when unimplemented resolvers are allowed` () {
344+ val options = listOf (
345+ SchemaParserOptions .newOptions().allowUnimplementedResolvers(true ),
346+ SchemaParserOptions .newOptions().missingResolverDataFetcherProvider(MissingResolverDataFetcherProvider { _, _ -> DataFetcher { " provided" } })
347+ )
348+
349+ options.forEach {
350+ val error = assertThrows(FieldResolverError ::class .java) {
351+ buildMissingParameterSchema(" users(active: Boolean, first: Int): String" , it)
352+ }
353+
354+ assert (" Field 'Query.users' has no parameter for its argument 'active: Boolean'" in error.message!! ) { error.message!! }
355+ }
356+ }
357+
358+ @Test
359+ fun `should build when the context class is an argument type` () {
360+ val schema = buildMissingParameterSchema(
361+ " search(filter: Filter): String\n count(active: Boolean): String" ,
362+ SchemaParserOptions .newOptions()
363+ )
364+
365+ assertEquals(schema.queryType.fieldDefinitions.map { it.name }, listOf (" search" , " count" ))
351366 }
352367
368+ private fun buildMissingParameterSchema (queryField : String , options : SchemaParserOptions .Builder ) =
369+ SchemaParser .newParser()
370+ .schemaString(
371+ """
372+ type Query {
373+ $queryField
374+ }
375+
376+ type Image {
377+ thumbnail(size: Int): String
378+ }
379+
380+ input Filter {
381+ name: String
382+ }
383+ """ )
384+ .resolvers(MissingParameterQuery (), ImageResolver ())
385+ .options(options.contextClass(Map ::class ).build())
386+ .build()
387+ .makeExecutableSchema()
388+
353389 class MissingParameterQuery : GraphQLQueryResolver {
354390 fun user (id : String , context : Map <String , Any >) = " $id $context "
355391 fun users (context : GraphQLContext ? , first : Int? ) = " $context $first "
0 commit comments