Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add ProhibitDeprecatedFieldsRule and deprecate findDeprecatedUsages
- Loading branch information
1 parent
d10cf6c
commit b6925a0
Showing
14 changed files
with
224 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
135 changes: 135 additions & 0 deletions
135
src/validation/__tests__/ProhibitDeprecatedFieldsRule-test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
// @flow strict | ||
|
||
import { describe, it } from 'mocha'; | ||
|
||
import { buildSchema } from '../../utilities/buildASTSchema'; | ||
|
||
import { ProhibitDeprecatedFieldsRule } from '../rules/optional/ProhibitDeprecatedFieldsRule'; | ||
|
||
import { expectValidationErrorsWithSchema } from './harness'; | ||
|
||
const schema = buildSchema(` | ||
enum EnumType { | ||
NORMAL_VALUE | ||
DEPRECATED_VALUE @deprecated(reason: "Some enum reason.") | ||
DEPRECATED_VALUE_WITH_NO_REASON @deprecated | ||
} | ||
type Query { | ||
normalField(enumArg: [EnumType]): String | ||
deprecatedField: String @deprecated(reason: "Some field reason.") | ||
deprecatedFieldWithNoReason: String @deprecated | ||
} | ||
`); | ||
|
||
function expectErrors(queryStr) { | ||
return expectValidationErrorsWithSchema( | ||
schema, | ||
ProhibitDeprecatedFieldsRule, | ||
queryStr, | ||
); | ||
} | ||
|
||
function expectValid(queryStr) { | ||
expectErrors(queryStr).to.deep.equal([]); | ||
} | ||
|
||
describe('Validate: prohibit deprecated fields', () => { | ||
it('ignores fields and enum values that are not deprecated', () => { | ||
expectValid(` | ||
{ | ||
normalField(enumArg: [NORMAL_VALUE]) | ||
} | ||
`); | ||
}); | ||
|
||
it('ignores unknown fields and enum values', () => { | ||
expectValid(` | ||
fragment UnknownFragment on UnknownType { | ||
unknownField(unknownArg: UNKNOWN_VALUE) | ||
} | ||
`); | ||
}); | ||
|
||
it('reports error when a deprecated field is selected', () => { | ||
expectErrors(` | ||
{ | ||
normalField | ||
deprecatedField | ||
} | ||
`).to.deep.equal([ | ||
{ | ||
message: | ||
'The field Query.deprecatedField is deprecated. Some field reason.', | ||
locations: [{ line: 4, column: 9 }], | ||
}, | ||
]); | ||
}); | ||
|
||
it('reports error when a deprecated field with default reason is selected', () => { | ||
expectErrors(` | ||
{ | ||
normalField | ||
deprecatedFieldWithNoReason | ||
} | ||
`).to.deep.equal([ | ||
{ | ||
message: | ||
'The field Query.deprecatedFieldWithNoReason is deprecated. No longer supported', | ||
locations: [{ line: 4, column: 9 }], | ||
}, | ||
]); | ||
}); | ||
|
||
it('reports error when a deprecated enum value is used', () => { | ||
expectErrors(` | ||
{ | ||
normalField(enumArg: [NORMAL_VALUE, DEPRECATED_VALUE]) | ||
} | ||
`).to.deep.equal([ | ||
{ | ||
message: | ||
'The enum value "EnumType.DEPRECATED_VALUE" is deprecated. Some enum reason.', | ||
locations: [{ line: 3, column: 45 }], | ||
}, | ||
]); | ||
}); | ||
|
||
it('reports error when a deprecated enum value with default reason is used', () => { | ||
expectErrors(` | ||
{ | ||
normalField(enumArg: [DEPRECATED_VALUE_WITH_NO_REASON]) | ||
} | ||
`).to.deep.equal([ | ||
{ | ||
message: | ||
'The enum value "EnumType.DEPRECATED_VALUE_WITH_NO_REASON" is deprecated. No longer supported', | ||
locations: [{ line: 3, column: 31 }], | ||
}, | ||
]); | ||
}); | ||
|
||
it('reports error when a deprecated field is selected or an enum value is used inside a fragment', () => { | ||
expectErrors(` | ||
{ | ||
...QueryFragment | ||
} | ||
fragment QueryFragment on Query { | ||
deprecatedField | ||
normalField(enumArg: [NORMAL_VALUE, DEPRECATED_VALUE]) | ||
} | ||
`).to.deep.equal([ | ||
{ | ||
message: | ||
'The field Query.deprecatedField is deprecated. Some field reason.', | ||
locations: [{ line: 7, column: 9 }], | ||
}, | ||
{ | ||
message: | ||
'The enum value "EnumType.DEPRECATED_VALUE" is deprecated. Some enum reason.', | ||
locations: [{ line: 8, column: 45 }], | ||
}, | ||
]); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
src/validation/rules/optional/ProhibitDeprecatedFieldsRule.d.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { ASTVisitor } from '../../../language/visitor'; | ||
import { ValidationContext } from '../../ValidationContext'; | ||
|
||
/** | ||
* Prohibit deprecated fields | ||
* | ||
* A GraphQL document is only valid if all selected fields and all used enum | ||
* values have not been deprecated. | ||
* | ||
* Note: This rule is optional and is not part of the Validation section of the | ||
* GraphQL Specification. | ||
*/ | ||
export function ProhibitDeprecatedFieldsRule( | ||
context: ValidationContext, | ||
): ASTVisitor; |
52 changes: 52 additions & 0 deletions
52
src/validation/rules/optional/ProhibitDeprecatedFieldsRule.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// @flow strict | ||
|
||
import { GraphQLError } from '../../../error/GraphQLError'; | ||
|
||
import { type EnumValueNode, type FieldNode } from '../../../language/ast'; | ||
import { type ASTVisitor } from '../../../language/visitor'; | ||
|
||
import { getNamedType } from '../../../type/definition'; | ||
|
||
import { type ValidationContext } from '../../ValidationContext'; | ||
|
||
/** | ||
* Prohibit deprecated fields | ||
* | ||
* A GraphQL document is only valid if all selected fields and all used enum | ||
* values have not been deprecated. | ||
* | ||
* Note: This rule is optional and is not part of the Validation section of the | ||
* GraphQL Specification. | ||
*/ | ||
export function ProhibitDeprecatedFieldsRule( | ||
context: ValidationContext, | ||
): ASTVisitor { | ||
return { | ||
Field(node: FieldNode) { | ||
const fieldDef = context.getFieldDef(); | ||
const parentType = context.getParentType(); | ||
if (parentType && fieldDef && fieldDef.deprecationReason != null) { | ||
context.reportError( | ||
new GraphQLError( | ||
`The field ${parentType.name}.${fieldDef.name} is deprecated. ` + | ||
fieldDef.deprecationReason, | ||
[node], | ||
), | ||
); | ||
} | ||
}, | ||
EnumValue(node: EnumValueNode) { | ||
const type = getNamedType(context.getInputType()); | ||
const enumValue = context.getEnumValue(); | ||
if (type && enumValue?.deprecationReason != null) { | ||
context.reportError( | ||
new GraphQLError( | ||
`The enum value "${type.name}.${enumValue.name}" is deprecated. ` + | ||
enumValue.deprecationReason, | ||
node, | ||
), | ||
); | ||
} | ||
}, | ||
}; | ||
} |