Skip to content

Commit e288467

Browse files
committed
Fix @Source resolution for interface types and add test coverage
- Updated `SourceArgumentResolver` to support assigning interface types by using `isAssignableFrom`. - Added test cases for handling `@Source` with interface types. - Extended GraphQL schema and test data to include `Movie` and `Entertainment` examples.
1 parent a07759a commit e288467

File tree

3 files changed

+71
-3
lines changed

3 files changed

+71
-3
lines changed

graphql-dgs/src/main/kotlin/com/netflix/graphql/dgs/internal/method/SourceArgumentResolver.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class SourceArgumentResolver : ArgumentResolver {
3232
throw IllegalArgumentException("Source is null. Are you trying to use @Source on a root field (e.g. @DgsQuery)?")
3333
}
3434

35-
if (parameter.parameterType == source.javaClass) {
35+
if (parameter.parameterType.isAssignableFrom(source.javaClass)) {
3636
return source
3737
} else {
3838
throw IllegalArgumentException(

graphql-dgs/src/test/kotlin/com/netflix/graphql/dgs/internal/SourceArgumentTest.kt

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,17 @@ internal class SourceArgumentTest {
5252
),
5353
)
5454

55+
interface Entertainment {
56+
val title: String
57+
}
58+
5559
data class Show(
56-
val title: String,
57-
)
60+
override val title: String,
61+
) : Entertainment
62+
63+
data class Movie(
64+
override val title: String,
65+
) : Entertainment
5866

5967
@Test
6068
fun `@Source argument`() {
@@ -96,6 +104,60 @@ internal class SourceArgumentTest {
96104
}
97105
}
98106

107+
@Test
108+
fun `@Source argument with interface type`() {
109+
@DgsComponent
110+
class Fetcher {
111+
@DgsQuery
112+
fun shows(): List<Show> = listOf(Show("Stranger Things"))
113+
114+
@DgsQuery
115+
fun movies(): List<Movie> = listOf(Movie("Batman"))
116+
117+
@DgsData(parentType = "Show")
118+
@DgsData(parentType = "Movie")
119+
fun description(
120+
@Source entertainment: Entertainment,
121+
): String = "Description of ${entertainment.title}"
122+
}
123+
124+
contextRunner.withBean(Fetcher::class.java).run { context ->
125+
val provider = schemaProvider(context)
126+
val schema = provider.schema().graphQLSchema
127+
128+
val build = GraphQL.newGraphQL(schema).build()
129+
val executionResult =
130+
build.execute(
131+
"""{
132+
| shows {
133+
| title
134+
| description
135+
| }
136+
|
137+
| movies {
138+
| title
139+
| description
140+
| }
141+
|}
142+
""".trimMargin(),
143+
)
144+
145+
assertThat(executionResult.errors).isEmpty()
146+
assertThat(executionResult.isDataPresent).isTrue
147+
val data = executionResult.getData<Map<String, *>>()
148+
149+
@Suppress("UNCHECKED_CAST")
150+
val showData = (data["shows"] as List<Map<*, *>>)[0]
151+
assertThat(showData["title"]).isEqualTo("Stranger Things")
152+
assertThat(showData["description"]).isEqualTo("Description of Stranger Things")
153+
154+
@Suppress("UNCHECKED_CAST")
155+
val movieData = (data["movies"] as List<Map<*, *>>)[0]
156+
assertThat(movieData["title"]).isEqualTo("Batman")
157+
assertThat(movieData["description"]).isEqualTo("Description of Batman")
158+
}
159+
}
160+
99161
@Test
100162
fun `Incorrect @Source argument type`() {
101163
@DgsComponent
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
type Query {
22
shows: [Show]
3+
movies: [Movie]
34
}
45

56
type Show {
67
title: String
78
description: String
9+
}
10+
11+
type Movie {
12+
title: String
13+
description: String
814
}

0 commit comments

Comments
 (0)