-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Earlier validation that document operations exist in the schema #3361
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
8f8c6d1
28af525
f8673e6
9a69970
d6be93a
36e56e0
896440c
c467a02
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| package graphql.validation.rules; | ||
|
|
||
| import graphql.Internal; | ||
| import graphql.language.OperationDefinition; | ||
| import graphql.schema.GraphQLSchema; | ||
| import graphql.util.StringKit; | ||
| import graphql.validation.AbstractRule; | ||
| import graphql.validation.ValidationContext; | ||
| import graphql.validation.ValidationErrorCollector; | ||
|
|
||
| import static graphql.validation.ValidationErrorType.UnknownOperation; | ||
|
|
||
| /** | ||
| * Unique variable names | ||
| * <p> | ||
| * A GraphQL operation is only valid if all its variables are uniquely named. | ||
| */ | ||
| @Internal | ||
| public class KnownOperationTypes extends AbstractRule { | ||
|
|
||
| public KnownOperationTypes(ValidationContext validationContext, ValidationErrorCollector validationErrorCollector) { | ||
| super(validationContext, validationErrorCollector); | ||
| } | ||
|
|
||
| @Override | ||
| public void checkOperationDefinition(OperationDefinition operationDefinition) { | ||
| OperationDefinition.Operation documentOperation = operationDefinition.getOperation(); | ||
| GraphQLSchema graphQLSchema = getValidationContext().getSchema(); | ||
| if (documentOperation == OperationDefinition.Operation.MUTATION | ||
| && graphQLSchema.getMutationType() == null) { | ||
| String message = i18n(UnknownOperation, "KnownOperationTypes.noOperation", formatOperation(documentOperation)); | ||
| addError(UnknownOperation, operationDefinition.getSourceLocation(), message); | ||
| } else if (documentOperation == OperationDefinition.Operation.SUBSCRIPTION | ||
| && graphQLSchema.getSubscriptionType() == null) { | ||
| String message = i18n(UnknownOperation, "KnownOperationTypes.noOperation", formatOperation(documentOperation)); | ||
| addError(UnknownOperation, operationDefinition.getSourceLocation(), message); | ||
| } else if (documentOperation == OperationDefinition.Operation.QUERY | ||
| && graphQLSchema.getQueryType() == null) { | ||
| // This is unlikely to happen, as a validated GraphQLSchema must have a Query type by definition | ||
| String message = i18n(UnknownOperation, "KnownOperationTypes.noOperation", formatOperation(documentOperation)); | ||
| addError(UnknownOperation, operationDefinition.getSourceLocation(), message); | ||
| } | ||
| } | ||
|
|
||
| private String formatOperation(OperationDefinition.Operation operation) { | ||
| return StringKit.capitalize(operation.name().toLowerCase()); | ||
| } | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Our Operation enums are ALL CAPS and I thought that was too shouty |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -350,7 +350,7 @@ class GraphQLTest extends Specification { | |
| thrown(GraphQLException) | ||
| } | ||
|
|
||
| def "null mutation type does not throw an npe re: #345 but returns and error"() { | ||
| def "null mutation type does not throw an npe but returns and error"() { | ||
| given: | ||
|
|
||
| GraphQLSchema schema = newSchema().query( | ||
|
|
@@ -370,7 +370,7 @@ class GraphQLTest extends Specification { | |
|
|
||
| then: | ||
| result.errors.size() == 1 | ||
| result.errors[0].class == MissingRootTypeException | ||
| ((ValidationError) result.errors[0]).validationErrorType == ValidationErrorType.UnknownOperation | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd like to discuss this Previously, the same sort of problem would be caught at execution time, throwing a
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Discussed offline - will keep in the old error in case, to be conservative |
||
| } | ||
|
|
||
| def "#875 a subscription query against a schema that doesn't support subscriptions should result in a GraphQL error"() { | ||
|
|
@@ -393,7 +393,7 @@ class GraphQLTest extends Specification { | |
|
|
||
| then: | ||
| result.errors.size() == 1 | ||
| result.errors[0].class == MissingRootTypeException | ||
| ((ValidationError) result.errors[0]).validationErrorType == ValidationErrorType.UnknownOperation | ||
| } | ||
|
|
||
| def "query with int literal too large"() { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -246,6 +246,10 @@ class KnownDirectivesTest extends Specification { | |
| field: String | ||
| } | ||
|
|
||
| type Subscription { | ||
| field: String | ||
| } | ||
|
|
||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test needed an adjustment to be valid |
||
| ''' | ||
|
|
||
| def schema = TestUtil.schema(sdl) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A valid GraphQLSchema should have already been checked for a query type, I am being defensive here