Skip to content

Commit

Permalink
Support @deprecated on arguments and input fields
Browse files Browse the repository at this point in the history
  • Loading branch information
ajkerr committed Sep 13, 2022
1 parent 6a2a523 commit 58c6224
Show file tree
Hide file tree
Showing 3 changed files with 319 additions and 5 deletions.
2 changes: 2 additions & 0 deletions src/main/kotlin/graphql/kickstart/tools/SchemaParser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ class SchemaParser internal constructor(
.definition(inputDefinition)
.description(getDocumentation(inputDefinition, options))
.apply { inputDefinition.defaultValue?.let { v -> defaultValueLiteral(v) } }
.apply { getDeprecated(inputDefinition.directives)?.let { deprecate(it) } }
.type(determineInputType(inputDefinition.type, inputObjects, referencingInputObjects))
.withAppliedDirectives(*buildAppliedDirectives(inputDefinition.directives))
builder.field(fieldBuilder.build())
Expand Down Expand Up @@ -279,6 +280,7 @@ class SchemaParser internal constructor(
.definition(argumentDefinition)
.description(getDocumentation(argumentDefinition, options))
.type(determineInputType(argumentDefinition.type, inputObjects, setOf()))
.apply { getDeprecated(argumentDefinition.directives)?.let { deprecate(it) } }
.apply { argumentDefinition.defaultValue?.let { defaultValueLiteral(it) } }
.withAppliedDirectives(*buildAppliedDirectives(argumentDefinition.directives))

Expand Down
317 changes: 317 additions & 0 deletions src/test/kotlin/graphql/kickstart/tools/DeprecatedDirectiveTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,317 @@
package graphql.kickstart.tools

import graphql.relay.Connection
import graphql.relay.SimpleListConnection
import graphql.schema.DataFetchingEnvironment
import graphql.schema.GraphQLEnumType
import graphql.schema.GraphQLInputObjectType
import graphql.schema.GraphQLObjectType
import org.junit.Test

class DeprecatedDirectiveTest {
@Test
fun `should apply @deprecated directive on output field with default reason`() {
val schema = SchemaParser.newParser()
.schemaString(
"""
type Query {
users: UserConnection
}
type UserConnection {
edges: [UserEdge!]!
}
type UserEdge {
node: User!
}
type User {
id: ID!
name: String @deprecated
}
""")
.resolvers(UsersQueryResolver())
.build()
.makeExecutableSchema()

val userType = schema.getType("User") as GraphQLObjectType
val nameDefinition = userType.getField("name")

assert(nameDefinition.isDeprecated)
assertEquals(nameDefinition.deprecationReason, "No longer supported")
}

@Test
fun `should apply @deprecated directive on output field with custom reason`() {
val schema = SchemaParser.newParser()
.schemaString(
"""
type Query {
users: UserConnection
}
type UserConnection {
edges: [UserEdge!]!
}
type UserEdge {
node: User!
}
type User {
id: ID!
name: String @deprecated(reason: "Use firstName and lastName instead")
}
""")
.resolvers(UsersQueryResolver())
.build()
.makeExecutableSchema()

val userType = schema.getType("User") as GraphQLObjectType
val nameDefinition = userType.getField("name")

assert(nameDefinition.isDeprecated)
assertEquals(nameDefinition.deprecationReason, "Use firstName and lastName instead")
}

@Test
fun `should apply @deprecated directive on enum value with default reason`() {
val schema = SchemaParser.newParser()
.schemaString(
"""
type Query {
users: UserConnection
}
type UserConnection {
edges: [UserEdge!]!
}
type UserEdge {
node: User!
}
enum UserType {
JEDI
BASIC
DROID @deprecated
}
type User {
id: ID!
name: String
type: UserType
}
""")
.resolvers(UsersQueryResolver())
.build()
.makeExecutableSchema()

val userTypeEnum = schema.getType("UserType") as GraphQLEnumType
val droidValue = userTypeEnum.getValue("DROID")

assert(droidValue.isDeprecated)
assertEquals(droidValue.deprecationReason, "No longer supported")
}

@Test
fun `should apply @deprecated directive on enum value with custom reason`() {
val schema = SchemaParser.newParser()
.schemaString(
"""
type Query {
users: UserConnection
}
type UserConnection {
edges: [UserEdge!]!
}
type UserEdge {
node: User!
}
enum UserType {
JEDI
BASIC
DROID @deprecated(reason: "This value is no longer used")
}
type User {
id: ID!
name: String
type: UserType
}
""")
.resolvers(UsersQueryResolver())
.build()
.makeExecutableSchema()

val userTypeEnum = schema.getType("UserType") as GraphQLEnumType
val droidValue = userTypeEnum.getValue("DROID")

assert(droidValue.isDeprecated)
assertEquals(droidValue.deprecationReason, "This value is no longer used")
}

@Test
fun `should apply @deprecated directive on argument with default reason`() {
val schema = SchemaParser.newParser()
.schemaString(
"""
type Query {
users(first: Int @deprecated): UserConnection
}
type UserConnection {
edges: [UserEdge!]!
}
type UserEdge {
node: User!
}
type User {
id: ID!
name: String @deprecated
}
""")
.resolvers(UsersQueryResolver())
.build()
.makeExecutableSchema()

val usersQuery = schema.queryType.getField("users")
val firstArgument = usersQuery.getArgument("first")

assert(firstArgument.isDeprecated)
assertEquals(firstArgument.deprecationReason, "No longer supported")
}

@Test
fun `should apply @deprecated directive on argument with custom reason`() {
val schema = SchemaParser.newParser()
.schemaString(
"""
type Query {
users(first: Int @deprecated(reason: "Please do not use this argument")): UserConnection
}
type UserConnection {
edges: [UserEdge!]!
}
type UserEdge {
node: User!
}
type User {
id: ID!
name: String @deprecated
}
""")
.resolvers(UsersQueryResolver())
.build()
.makeExecutableSchema()

val usersQuery = schema.queryType.getField("users")
val firstArgument = usersQuery.getArgument("first")

assert(firstArgument.isDeprecated)
assertEquals(firstArgument.deprecationReason, "Please do not use this argument")
}

@Test
fun `should apply @deprecated directive on input field with default reason`() {
val schema = SchemaParser.newParser()
.schemaString(
"""
type Query {
users(connectionInput: ConnectionInput): UserConnection
}
input ConnectionInput {
first: Int @deprecated
}
type UserConnection {
edges: [UserEdge!]!
}
type UserEdge {
node: User!
}
type User {
id: ID!
name: String @deprecated
}
""")
.resolvers(UsersQueryResolver())
.build()
.makeExecutableSchema()

val connectionInputType = schema.getType("ConnectionInput") as GraphQLInputObjectType
val firstField = connectionInputType.getField("first")

assert(firstField.isDeprecated)
assertEquals(firstField.deprecationReason, "No longer supported")
}

@Test
fun `should apply @deprecated directive on input field with custom reason`() {
val schema = SchemaParser.newParser()
.schemaString(
"""
type Query {
users(connectionInput: ConnectionInput): UserConnection
}
input ConnectionInput {
first: Int @deprecated(reason: "Please do not use this field")
}
type UserConnection {
edges: [UserEdge!]!
}
type UserEdge {
node: User!
}
type User {
id: ID!
name: String @deprecated
}
""")
.resolvers(UsersQueryResolver())
.build()
.makeExecutableSchema()

val connectionInputType = schema.getType("ConnectionInput") as GraphQLInputObjectType
val firstField = connectionInputType.getField("first")

assert(firstField.isDeprecated)
assertEquals(firstField.deprecationReason, "Please do not use this field")
}

private enum class UserType {
JEDI,
BASIC,
DROID
}

private class UsersQueryResolver : GraphQLQueryResolver {
fun users(env: DataFetchingEnvironment): Connection<User> {
return SimpleListConnection(listOf(User(1L, "Luke Skywalker", "Luke", "Skywalker", UserType.JEDI))).get(env)
}

private data class User(
val id: Long,
val name: String,
val firstName: String,
val lastName: String,
val type: UserType
)
}
}
5 changes: 0 additions & 5 deletions src/test/kotlin/graphql/kickstart/tools/DirectiveTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -244,11 +244,6 @@ class DirectiveTest {
val name: String
)

private enum class AllowedState {
ALLOWED,
DISALLOWED
}

private class AllowedDirective : SchemaDirectiveWiring {
override fun onField(environment: SchemaDirectiveWiringEnvironment<GraphQLFieldDefinition>): GraphQLFieldDefinition {
val field = environment.element
Expand Down

0 comments on commit 58c6224

Please sign in to comment.