Skip to content

Commit afbcd52

Browse files
committed
#4182 - code built schemas should perform deprecated non null field validations as well as SDL built ones
1 parent 021fe1b commit afbcd52

2 files changed

Lines changed: 45 additions & 4 deletions

File tree

src/main/java/graphql/schema/validation/DeprecatedInputObjectAndArgumentsAreValid.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,8 @@ public TraversalControl visitGraphQLInputObjectField(GraphQLInputObjectField inp
4242
// An applied directive's argument cannot be deprecated.
4343
@Override
4444
public TraversalControl visitGraphQLArgument(GraphQLArgument argument, TraverserContext<GraphQLSchemaElement> context) {
45-
// There can only be at most one @deprecated, because it is not a repeatable directive
46-
GraphQLAppliedDirective deprecatedDirective = argument.getAppliedDirective(Directives.DEPRECATED_DIRECTIVE_DEFINITION.getName());
47-
48-
if (deprecatedDirective != null && GraphQLTypeUtil.isNonNull(argument.getType()) && !argument.hasSetDefaultValue()) {
45+
boolean isDeprecated = isDeprecated(argument);
46+
if (isDeprecated && GraphQLTypeUtil.isNonNull(argument.getType()) && !argument.hasSetDefaultValue()) {
4947
if (context.getParentNode() instanceof GraphQLFieldDefinition) {
5048
GraphQLFieldDefinition fieldDefinition = (GraphQLFieldDefinition) context.getParentNode();
5149
SchemaValidationErrorCollector errorCollector = context.getVarFromParents(SchemaValidationErrorCollector.class);
@@ -61,4 +59,14 @@ public TraversalControl visitGraphQLArgument(GraphQLArgument argument, Traverser
6159
return TraversalControl.CONTINUE;
6260
}
6361

62+
private boolean isDeprecated(GraphQLArgument argument) {
63+
// There can only be at most one @deprecated, because it is not a repeatable directive
64+
GraphQLAppliedDirective deprecatedDirective = argument.getAppliedDirective(Directives.DEPRECATED_DIRECTIVE_DEFINITION.getName());
65+
if (deprecatedDirective != null) {
66+
return true;
67+
}
68+
// handle code built schemas, where they have no directive but `graphql.schema.GraphQLArgument.Builder#deprecate` has been called directly
69+
return argument.isDeprecated();
70+
}
71+
6472
}

src/test/groovy/graphql/schema/validation/DeprecatedInputObjectAndArgumentsAreValidTest.groovy

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
package graphql.schema.validation
22

3+
import graphql.Scalars
34
import graphql.TestUtil
5+
import graphql.schema.GraphQLArgument
6+
import graphql.schema.GraphQLFieldDefinition
7+
import graphql.schema.GraphQLNonNull
8+
import graphql.schema.GraphQLObjectType
9+
import graphql.schema.GraphQLSchema
410
import spock.lang.Specification
511

612
class DeprecatedInputObjectAndArgumentsAreValidTest extends Specification {
@@ -293,4 +299,31 @@ class DeprecatedInputObjectAndArgumentsAreValidTest extends Specification {
293299
noExceptionThrown()
294300
}
295301

302+
def "schema build via code has the same validation rule"() {
303+
when:
304+
GraphQLArgument deprecatedArg = GraphQLArgument.newArgument()
305+
.name("input")
306+
.type(GraphQLNonNull.nonNull(Scalars.GraphQLString))
307+
.deprecate("Some very good reason")
308+
.build()
309+
310+
GraphQLFieldDefinition field = GraphQLFieldDefinition.newFieldDefinition()
311+
.name("field")
312+
.type(Scalars.GraphQLString)
313+
.argument(deprecatedArg)
314+
.build()
315+
316+
GraphQLObjectType queryType = GraphQLObjectType.newObject()
317+
.name("Query")
318+
.field(field)
319+
.build()
320+
321+
GraphQLSchema.newSchema()
322+
.query(queryType)
323+
.build()
324+
325+
then:
326+
def invalidSchemaException = thrown(InvalidSchemaException)
327+
invalidSchemaException.message.contains("Required argument 'input' on field 'field' cannot be deprecated")
328+
}
296329
}

0 commit comments

Comments
 (0)