Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import graphql.nadel.engine.transform.query.NFUtil
import graphql.nadel.engine.transform.query.NadelQueryPath
import graphql.nadel.engine.util.getFieldContainerFor
import graphql.nadel.engine.util.isNonNull
import graphql.nadel.engine.util.toBuilder
import graphql.nadel.engine.util.unwrapAll
import graphql.nadel.validation.NadelValidationContext
import graphql.nadel.validation.NadelValidationInterimResult
Expand Down Expand Up @@ -171,7 +172,12 @@ private fun List<ExecutableNormalizedField>.dedupSourceFields(): List<Executable
listOf(it.objectTypeNames, it.resultKey, it.name, it.normalizedArguments.size)
}.flatMap { (_, fields) ->
if (fields.all { it.normalizedArguments.isEmpty() }) {
listOf(fields.first())
listOf(
fields.first()
.toBuilder()
.children(fields.flatMap { it.children }.dedupSourceFields())
.build()
)
} else {
fields
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package graphql.nadel.tests.next.fixtures.hydration

import graphql.nadel.tests.next.NadelIntegrationTest

/**
* Tests that we can query source fields like
*
* `$source.assigneeCriteria.siteId`
* `$source.id`
* `$source.assigneeCriteria.assigneeId`
*
* There was a bug in the past where only one field under `assigneeCriteria` was queried instead of two.
*/
class HydrationMultipleNestedSourceArgumentsTest : NadelIntegrationTest(
query = """
query {
issueById(id: "ari:cloud:jira:19b8272f-8d25-4706-adce-8db72305e615:issue/1") {
id
key
assignee {
id
name
}
}
}
""".trimIndent(),
variables = mapOf(),
services = listOf(
Service(
name = "issues",
overallSchema = """
type Query {
issueById(id: ID!): Issue
}
type Issue {
id: ID!
key: String
assigneeCriteria: IssueUserCriteria @hidden
assignee: User
@hydrated(
service: "identity"
field: "issueUser"
arguments: [
{name: "siteId", value: "$source.assigneeCriteria.siteId"}
{name: "issueId", value: "$source.id"}
{name: "userId", value: "$source.assigneeCriteria.assigneeId"}
]
)
}
type IssueUserCriteria {
siteId: ID!
assigneeId: ID!
}
""".trimIndent(),
runtimeWiring = { wiring ->
data class IssueUserCriteria(
val siteId: String,
val assigneeId: String,
)

data class Issue(
val id: String,
val key: String,
val assigneeCriteria: IssueUserCriteria? = null,
)

val issuesById = listOf(
Issue(
id = "ari:cloud:jira:19b8272f-8d25-4706-adce-8db72305e615:issue/1",
key = "GQLGW-1",
assigneeCriteria = IssueUserCriteria(
"ari:cloud:platform::site/123",
"ari:cloud:identity::user/1",
),
)
).associateBy { it.id }

wiring
.type("Query") { type ->
type.dataFetcher("issueById") {
issuesById[it.getArgument("id")]
}
}
},
),
Service(
name = "identity",
overallSchema = """
type Query {
issueUser(
siteId: ID!
issueId: ID!
userId: ID!
): User
}
type User {
id: ID!
name: String
}
""".trimIndent(),
runtimeWiring = { wiring ->
data class User(
val id: String,
val name: String,
)

wiring
.type("Query") { type ->
type.dataFetcher("issueUser") {
User(
id = "ari:cloud:identity::user/1",
name = "Franklin Wang",
)
}
}
},
),
),
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// @formatter:off
package graphql.nadel.tests.next.fixtures.hydration

import graphql.nadel.tests.next.ExpectedNadelResult
import graphql.nadel.tests.next.ExpectedServiceCall
import graphql.nadel.tests.next.TestSnapshot
import graphql.nadel.tests.next.listOfJsonStrings
import kotlin.Suppress
import kotlin.collections.List
import kotlin.collections.listOf

private suspend fun main() {
graphql.nadel.tests.next.update<HydrationMultipleNestedSourceArgumentsTest>()
}

/**
* This class is generated. Do NOT modify.
*
* Refer to [graphql.nadel.tests.next.UpdateTestSnapshots]
*/
@Suppress("unused")
public class HydrationMultipleNestedSourceArgumentsTestSnapshot : TestSnapshot() {
override val calls: List<ExpectedServiceCall> = listOf(
ExpectedServiceCall(
service = "identity",
query = """
| {
| issueUser(issueId: "ari:cloud:jira:19b8272f-8d25-4706-adce-8db72305e615:issue/1", siteId: "ari:cloud:platform::site/123", userId: "ari:cloud:identity::user/1") {
| id
| name
| }
| }
""".trimMargin(),
variables = "{}",
result = """
| {
| "data": {
| "issueUser": {
| "id": "ari:cloud:identity::user/1",
| "name": "Franklin Wang"
| }
| }
| }
""".trimMargin(),
delayedResults = listOfJsonStrings(
),
),
ExpectedServiceCall(
service = "issues",
query = """
| {
| issueById(id: "ari:cloud:jira:19b8272f-8d25-4706-adce-8db72305e615:issue/1") {
| __typename__hydration__assignee: __typename
| hydration__assignee__assigneeCriteria: assigneeCriteria {
| assigneeId
| siteId
| }
| id
| hydration__assignee__id: id
| key
| }
| }
""".trimMargin(),
variables = "{}",
result = """
| {
| "data": {
| "issueById": {
| "id": "ari:cloud:jira:19b8272f-8d25-4706-adce-8db72305e615:issue/1",
| "key": "GQLGW-1",
| "hydration__assignee__assigneeCriteria": {
| "siteId": "ari:cloud:platform::site/123",
| "assigneeId": "ari:cloud:identity::user/1"
| },
| "hydration__assignee__id": "ari:cloud:jira:19b8272f-8d25-4706-adce-8db72305e615:issue/1",
| "__typename__hydration__assignee": "Issue"
| }
| }
| }
""".trimMargin(),
delayedResults = listOfJsonStrings(
),
),
)

/**
* ```json
* {
* "data": {
* "issueById": {
* "id": "ari:cloud:jira:19b8272f-8d25-4706-adce-8db72305e615:issue/1",
* "key": "GQLGW-1",
* "assignee": {
* "id": "ari:cloud:identity::user/1",
* "name": "Franklin Wang"
* }
* }
* }
* }
* ```
*/
override val result: ExpectedNadelResult = ExpectedNadelResult(
result = """
| {
| "data": {
| "issueById": {
| "id": "ari:cloud:jira:19b8272f-8d25-4706-adce-8db72305e615:issue/1",
| "key": "GQLGW-1",
| "assignee": {
| "id": "ari:cloud:identity::user/1",
| "name": "Franklin Wang"
| }
| }
| }
| }
""".trimMargin(),
delayedResults = listOfJsonStrings(
),
)
}