Skip to content

Commit cc01a65

Browse files
committed
Support @deprecated on arguments and input fields
1 parent 6a2a523 commit cc01a65

File tree

3 files changed

+319
-5
lines changed

3 files changed

+319
-5
lines changed

src/main/kotlin/graphql/kickstart/tools/SchemaParser.kt

+2
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ class SchemaParser internal constructor(
168168
.definition(inputDefinition)
169169
.description(getDocumentation(inputDefinition, options))
170170
.apply { inputDefinition.defaultValue?.let { v -> defaultValueLiteral(v) } }
171+
.apply { getDeprecated(inputDefinition.directives)?.let { deprecate(it) } }
171172
.type(determineInputType(inputDefinition.type, inputObjects, referencingInputObjects))
172173
.withAppliedDirectives(*buildAppliedDirectives(inputDefinition.directives))
173174
builder.field(fieldBuilder.build())
@@ -279,6 +280,7 @@ class SchemaParser internal constructor(
279280
.definition(argumentDefinition)
280281
.description(getDocumentation(argumentDefinition, options))
281282
.type(determineInputType(argumentDefinition.type, inputObjects, setOf()))
283+
.apply { getDeprecated(argumentDefinition.directives)?.let { deprecate(it) } }
282284
.apply { argumentDefinition.defaultValue?.let { defaultValueLiteral(it) } }
283285
.withAppliedDirectives(*buildAppliedDirectives(argumentDefinition.directives))
284286

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,317 @@
1+
package graphql.kickstart.tools
2+
3+
import graphql.relay.Connection
4+
import graphql.relay.SimpleListConnection
5+
import graphql.schema.DataFetchingEnvironment
6+
import graphql.schema.GraphQLEnumType
7+
import graphql.schema.GraphQLInputObjectType
8+
import graphql.schema.GraphQLObjectType
9+
import org.junit.Test
10+
11+
class DeprecatedDirectiveTest {
12+
@Test
13+
fun `should apply @deprecated directive on output field with default reason`() {
14+
val schema = SchemaParser.newParser()
15+
.schemaString(
16+
"""
17+
type Query {
18+
users: UserConnection
19+
}
20+
21+
type UserConnection {
22+
edges: [UserEdge!]!
23+
}
24+
25+
type UserEdge {
26+
node: User!
27+
}
28+
29+
type User {
30+
id: ID!
31+
name: String @deprecated
32+
}
33+
""")
34+
.resolvers(UsersQueryResolver())
35+
.build()
36+
.makeExecutableSchema()
37+
38+
val userType = schema.getType("User") as GraphQLObjectType
39+
val nameDefinition = userType.getField("name")
40+
41+
assert(nameDefinition.isDeprecated)
42+
assertEquals(nameDefinition.deprecationReason, "No longer supported")
43+
}
44+
45+
@Test
46+
fun `should apply @deprecated directive on output field with custom reason`() {
47+
val schema = SchemaParser.newParser()
48+
.schemaString(
49+
"""
50+
type Query {
51+
users: UserConnection
52+
}
53+
54+
type UserConnection {
55+
edges: [UserEdge!]!
56+
}
57+
58+
type UserEdge {
59+
node: User!
60+
}
61+
62+
type User {
63+
id: ID!
64+
name: String @deprecated(reason: "Use firstName and lastName instead")
65+
}
66+
""")
67+
.resolvers(UsersQueryResolver())
68+
.build()
69+
.makeExecutableSchema()
70+
71+
val userType = schema.getType("User") as GraphQLObjectType
72+
val nameDefinition = userType.getField("name")
73+
74+
assert(nameDefinition.isDeprecated)
75+
assertEquals(nameDefinition.deprecationReason, "Use firstName and lastName instead")
76+
}
77+
78+
@Test
79+
fun `should apply @deprecated directive on enum value with default reason`() {
80+
val schema = SchemaParser.newParser()
81+
.schemaString(
82+
"""
83+
type Query {
84+
users: UserConnection
85+
}
86+
87+
type UserConnection {
88+
edges: [UserEdge!]!
89+
}
90+
91+
type UserEdge {
92+
node: User!
93+
}
94+
95+
enum UserType {
96+
JEDI
97+
BASIC
98+
DROID @deprecated
99+
}
100+
101+
type User {
102+
id: ID!
103+
name: String
104+
type: UserType
105+
}
106+
""")
107+
.resolvers(UsersQueryResolver())
108+
.build()
109+
.makeExecutableSchema()
110+
111+
val userTypeEnum = schema.getType("UserType") as GraphQLEnumType
112+
val droidValue = userTypeEnum.getValue("DROID")
113+
114+
assert(droidValue.isDeprecated)
115+
assertEquals(droidValue.deprecationReason, "No longer supported")
116+
}
117+
118+
@Test
119+
fun `should apply @deprecated directive on enum value with custom reason`() {
120+
val schema = SchemaParser.newParser()
121+
.schemaString(
122+
"""
123+
type Query {
124+
users: UserConnection
125+
}
126+
127+
type UserConnection {
128+
edges: [UserEdge!]!
129+
}
130+
131+
type UserEdge {
132+
node: User!
133+
}
134+
135+
enum UserType {
136+
JEDI
137+
BASIC
138+
DROID @deprecated(reason: "This type is no longer used")
139+
}
140+
141+
type User {
142+
id: ID!
143+
name: String
144+
type: UserType
145+
}
146+
""")
147+
.resolvers(UsersQueryResolver())
148+
.build()
149+
.makeExecutableSchema()
150+
151+
val userTypeEnum = schema.getType("UserType") as GraphQLEnumType
152+
val droidValue = userTypeEnum.getValue("DROID")
153+
154+
assert(droidValue.isDeprecated)
155+
assertEquals(droidValue.deprecationReason, "This type is no longer used")
156+
}
157+
158+
@Test
159+
fun `should apply @deprecated directive on argument with default reason`() {
160+
val schema = SchemaParser.newParser()
161+
.schemaString(
162+
"""
163+
type Query {
164+
users(first: Int @deprecated): UserConnection
165+
}
166+
167+
type UserConnection {
168+
edges: [UserEdge!]!
169+
}
170+
171+
type UserEdge {
172+
node: User!
173+
}
174+
175+
type User {
176+
id: ID!
177+
name: String @deprecated
178+
}
179+
""")
180+
.resolvers(UsersQueryResolver())
181+
.build()
182+
.makeExecutableSchema()
183+
184+
val usersQuery = schema.queryType.getField("users")
185+
val firstArgument = usersQuery.getArgument("first")
186+
187+
assert(firstArgument.isDeprecated)
188+
assertEquals(firstArgument.deprecationReason, "No longer supported")
189+
}
190+
191+
@Test
192+
fun `should apply @deprecated directive on argument with custom reason`() {
193+
val schema = SchemaParser.newParser()
194+
.schemaString(
195+
"""
196+
type Query {
197+
users(first: Int @deprecated(reason: "Please do not use this argument")): UserConnection
198+
}
199+
200+
type UserConnection {
201+
edges: [UserEdge!]!
202+
}
203+
204+
type UserEdge {
205+
node: User!
206+
}
207+
208+
type User {
209+
id: ID!
210+
name: String @deprecated
211+
}
212+
""")
213+
.resolvers(UsersQueryResolver())
214+
.build()
215+
.makeExecutableSchema()
216+
217+
val usersQuery = schema.queryType.getField("users")
218+
val firstArgument = usersQuery.getArgument("first")
219+
220+
assert(firstArgument.isDeprecated)
221+
assertEquals(firstArgument.deprecationReason, "Please do not use this argument")
222+
}
223+
224+
@Test
225+
fun `should apply @deprecated directive on input field with default reason`() {
226+
val schema = SchemaParser.newParser()
227+
.schemaString(
228+
"""
229+
type Query {
230+
users(connectionInput: ConnectionInput): UserConnection
231+
}
232+
233+
input ConnectionInput {
234+
first: Int @deprecated
235+
}
236+
237+
type UserConnection {
238+
edges: [UserEdge!]!
239+
}
240+
241+
type UserEdge {
242+
node: User!
243+
}
244+
245+
type User {
246+
id: ID!
247+
name: String @deprecated
248+
}
249+
""")
250+
.resolvers(UsersQueryResolver())
251+
.build()
252+
.makeExecutableSchema()
253+
254+
val connectionInputType = schema.getType("ConnectionInput") as GraphQLInputObjectType
255+
val firstField = connectionInputType.getField("first")
256+
257+
assert(firstField.isDeprecated)
258+
assertEquals(firstField.deprecationReason, "No longer supported")
259+
}
260+
261+
@Test
262+
fun `should apply @deprecated directive on input field with custom reason`() {
263+
val schema = SchemaParser.newParser()
264+
.schemaString(
265+
"""
266+
type Query {
267+
users(connectionInput: ConnectionInput): UserConnection
268+
}
269+
270+
input ConnectionInput {
271+
first: Int @deprecated(reason: "Please do not use this field")
272+
}
273+
274+
type UserConnection {
275+
edges: [UserEdge!]!
276+
}
277+
278+
type UserEdge {
279+
node: User!
280+
}
281+
282+
type User {
283+
id: ID!
284+
name: String @deprecated
285+
}
286+
""")
287+
.resolvers(UsersQueryResolver())
288+
.build()
289+
.makeExecutableSchema()
290+
291+
val connectionInputType = schema.getType("ConnectionInput") as GraphQLInputObjectType
292+
val firstField = connectionInputType.getField("first")
293+
294+
assert(firstField.isDeprecated)
295+
assertEquals(firstField.deprecationReason, "Please do not use this field")
296+
}
297+
298+
private enum class UserType {
299+
JEDI,
300+
BASIC,
301+
DROID
302+
}
303+
304+
private class UsersQueryResolver : GraphQLQueryResolver {
305+
fun users(env: DataFetchingEnvironment): Connection<User> {
306+
return SimpleListConnection(listOf(User(1L, "Luke Skywalker", "Luke", "Skywalker", UserType.JEDI))).get(env)
307+
}
308+
309+
private data class User(
310+
val id: Long,
311+
val name: String,
312+
val firstName: String,
313+
val lastName: String,
314+
val type: UserType
315+
)
316+
}
317+
}

src/test/kotlin/graphql/kickstart/tools/DirectiveTest.kt

-5
Original file line numberDiff line numberDiff line change
@@ -244,11 +244,6 @@ class DirectiveTest {
244244
val name: String
245245
)
246246

247-
private enum class AllowedState {
248-
ALLOWED,
249-
DISALLOWED
250-
}
251-
252247
private class AllowedDirective : SchemaDirectiveWiring {
253248
override fun onField(environment: SchemaDirectiveWiringEnvironment<GraphQLFieldDefinition>): GraphQLFieldDefinition {
254249
val field = environment.element

0 commit comments

Comments
 (0)