diff --git a/test/src/test/kotlin/graphql/nadel/tests/next/fixtures/defer/transforms/DeferWithTransformThrowsErrorTest.kt b/test/src/test/kotlin/graphql/nadel/tests/next/fixtures/defer/transforms/DeferWithTransformThrowsErrorTest.kt new file mode 100644 index 000000000..1d1818430 --- /dev/null +++ b/test/src/test/kotlin/graphql/nadel/tests/next/fixtures/defer/transforms/DeferWithTransformThrowsErrorTest.kt @@ -0,0 +1,62 @@ +package graphql.nadel.tests.next.fixtures.defer.transforms + +import graphql.nadel.NadelExecutionHints +import graphql.nadel.tests.next.NadelIntegrationTest + +open class DeferWithTransformThrowsErrorTest : NadelIntegrationTest( + query = """ + query { + defer { + hello + ... @defer(label: "slow-defer") { + slow + } + } + } + """.trimIndent(), + services = listOf( + Service( + name = "defer", + overallSchema = """ + directive @defer(if: Boolean, label: String) on FRAGMENT_SPREAD | INLINE_FRAGMENT + + type Query { + defer: DeferApi + } + type DeferApi { + hello: String + slow: String @renamed(from: "underlyingSlow") + } + + """.trimIndent(), + runtimeWiring = { wiring -> + data class DeferApi( + val hello: String, + val slow: String, + ) + + wiring + .type("Query") { type -> + type + .dataFetcher("defer") { env -> + Any() + } + } + .type("DeferApi") { type -> + type + .dataFetcher("hello") { env -> + "helloString" + } + .dataFetcher("underlyingSlow") { env -> + throw RuntimeException("An error occurred while fetching 'slow'") + } + } + }, + ), + ), +) { + override fun makeExecutionHints(): NadelExecutionHints.Builder { + return super.makeExecutionHints() + .deferSupport { true } + } +} diff --git a/test/src/test/kotlin/graphql/nadel/tests/next/fixtures/defer/transforms/DeferWithTransformThrowsErrorTestSnapshot.kt b/test/src/test/kotlin/graphql/nadel/tests/next/fixtures/defer/transforms/DeferWithTransformThrowsErrorTestSnapshot.kt new file mode 100644 index 000000000..0c6396301 --- /dev/null +++ b/test/src/test/kotlin/graphql/nadel/tests/next/fixtures/defer/transforms/DeferWithTransformThrowsErrorTestSnapshot.kt @@ -0,0 +1,167 @@ +// @formatter:off +package graphql.nadel.tests.next.fixtures.defer.transforms + +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() +} + +/** + * This class is generated. Do NOT modify. + * + * Refer to [graphql.nadel.tests.next.UpdateTestSnapshots + */ +@Suppress("unused") +public class DeferWithTransformThrowsErrorTestSnapshot : TestSnapshot() { + override val calls: List = listOf( + ExpectedServiceCall( + service = "defer", + query = """ + | { + | defer { + | hello + | ... @defer(label: "slow-defer") { + | rename__slow__underlyingSlow: underlyingSlow + | __typename__rename__slow: __typename + | } + | } + | } + """.trimMargin(), + variables = " {}", + result = """ + | { + | "data": { + | "defer": { + | "hello": "helloString" + | } + | }, + | "hasNext": true + | } + """.trimMargin(), + delayedResults = listOfJsonStrings( + """ + | { + | "hasNext": false, + | "incremental": [ + | { + | "path": [ + | "defer" + | ], + | "label": "slow-defer", + | "errors": [ + | { + | "message": "Exception while fetching data (/defer/rename__slow__underlyingSlow) : An error occurred while fetching 'slow'", + | "locations": [ + | { + | "line": 5, + | "column": 7 + | } + | ], + | "path": [ + | "defer", + | "rename__slow__underlyingSlow" + | ], + | "extensions": { + | "classification": "DataFetchingException" + | } + | } + | ], + | "data": { + | "rename__slow__underlyingSlow": null, + | "__typename__rename__slow": "DeferApi" + | } + | } + | ] + | } + """.trimMargin(), + ), + ), + ) + + /** + * ```json + * { + * "data": { + * "defer": { + * "hello": "helloString", + * "slow": null + * } + * }, + * "errors": [ + * { + * "message": "Exception while fetching data (/defer/rename__slow__underlyingSlow) : An + * error occurred while fetching 'slow'", + * "locations": [ + * { + * "line": 5, + * "column": 7 + * } + * ], + * "path": [ + * "defer", + * "rename__slow__underlyingSlow" + * ], + * "extensions": { + * "classification": "DataFetchingException" + * } + * } + * ] + * } + * ``` + */ + override val result: ExpectedNadelResult = ExpectedNadelResult( + result = """ + | { + | "data": { + | "defer": { + | "hello": "helloString" + | } + | }, + | "hasNext": true + | } + """.trimMargin(), + delayedResults = listOfJsonStrings( + """ + | { + | "hasNext": false, + | "incremental": [ + | { + | "path": [ + | "defer" + | ], + | "label": "slow-defer", + | "errors": [ + | { + | "message": "Exception while fetching data (/defer/rename__slow__underlyingSlow) : An error occurred while fetching 'slow'", + | "locations": [ + | { + | "line": 5, + | "column": 7 + | } + | ], + | "path": [ + | "defer", + | "rename__slow__underlyingSlow" + | ], + | "extensions": { + | "classification": "DataFetchingException" + | } + | } + | ], + | "data": { + | "slow": null + | } + | } + | ] + | } + """.trimMargin(), + ), + ) +} diff --git a/test/src/test/kotlin/graphql/nadel/tests/next/fixtures/defer/transforms/DeferredRenamedInputTypeTest.kt b/test/src/test/kotlin/graphql/nadel/tests/next/fixtures/defer/transforms/DeferredRenamedInputTypeTest.kt new file mode 100644 index 000000000..c7093f80d --- /dev/null +++ b/test/src/test/kotlin/graphql/nadel/tests/next/fixtures/defer/transforms/DeferredRenamedInputTypeTest.kt @@ -0,0 +1,87 @@ +package graphql.nadel.tests.next.fixtures.defer.transforms + +import graphql.nadel.NadelExecutionHints +import graphql.nadel.tests.next.NadelIntegrationTest + +/** + * The `ConfluenceLegacyPathType` input type was renamed. + * + * In the test snapshot we ensure the variable is defined as `PathType`. + * + * This tests the NadelRenameArgumentInputTypesTransform with defer + */ +class DeferredRenamedInputTypeTest : NadelIntegrationTest( + query = """ + query { + me { + profilePicture { + ...@defer { + path(type: ABSOLUTE) + } + } + } + } + """.trimIndent(), + services = listOf( + Service( + name = "confluence_legacy", + overallSchema = """ + type Query { + me: ConfluenceLegacyUser + } + type ConfluenceLegacyUser @renamed(from: "User") { + profilePicture: ConfluenceLegacyProfilePicture + } + type ConfluenceLegacyProfilePicture @renamed(from: "ProfilePicture") { + path(type: ConfluenceLegacyPathType!): String + } + enum ConfluenceLegacyPathType @renamed(from: "PathType") { + ABSOLUTE + RELATIVE + } + """.trimIndent(), + runtimeWiring = { wiring -> + data class ProfilePicture( + val absolutePath: String, + val relativePath: String, + ) + + data class User( + val profilePicture: ProfilePicture, + ) + + wiring + .type("Query") { type -> + type + .dataFetcher("me") { env -> + User( + profilePicture = ProfilePicture( + relativePath = "/wiki/aa-avatar/5ee0a4ef55749e0ab6e0fb70", + absolutePath = "https://atlassian.net/wiki/aa-avatar/5ee0a4ef55749e0ab6e0fb70", + ), + ) + } + } + .type("ProfilePicture") { type -> + type + .dataFetcher("path") { env -> + val pfp = env.getSource()!! + when (val urlType = env.getArgument("type")) { + "ABSOLUTE" -> pfp.absolutePath + "RELATIVE" -> pfp.relativePath + else -> throw IllegalArgumentException(urlType) + } + } + } + }, + ), + ), +) { + override fun makeExecutionHints(): NadelExecutionHints.Builder { + return super.makeExecutionHints() + // todo: this should be on by default + .allDocumentVariablesHint { + true + } + } +} diff --git a/test/src/test/kotlin/graphql/nadel/tests/next/fixtures/defer/transforms/DeferredRenamedInputTypeTestSnapshot.kt b/test/src/test/kotlin/graphql/nadel/tests/next/fixtures/defer/transforms/DeferredRenamedInputTypeTestSnapshot.kt new file mode 100644 index 000000000..ab3e38552 --- /dev/null +++ b/test/src/test/kotlin/graphql/nadel/tests/next/fixtures/defer/transforms/DeferredRenamedInputTypeTestSnapshot.kt @@ -0,0 +1,84 @@ +// @formatter:off +package graphql.nadel.tests.next.fixtures.defer.transforms + +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() +} + +/** + * This class is generated. Do NOT modify. + * + * Refer to [graphql.nadel.tests.next.UpdateTestSnapshots + */ +@Suppress("unused") +public class DeferredRenamedInputTypeTestSnapshot : TestSnapshot() { + override val calls: List = listOf( + ExpectedServiceCall( + service = "confluence_legacy", + query = """ + | query (${'$'}v0: PathType!) { + | me { + | profilePicture { + | path(type: ${'$'}v0) + | } + | } + | } + """.trimMargin(), + variables = """ + | { + | "v0": "ABSOLUTE" + | } + """.trimMargin(), + result = """ + | { + | "data": { + | "me": { + | "profilePicture": { + | "path": "https://atlassian.net/wiki/aa-avatar/5ee0a4ef55749e0ab6e0fb70" + | } + | } + | } + | } + """.trimMargin(), + delayedResults = listOfJsonStrings( + ), + ), + ) + + /** + * ```json + * { + * "data": { + * "me": { + * "profilePicture": { + * "path": "https://atlassian.net/wiki/aa-avatar/5ee0a4ef55749e0ab6e0fb70" + * } + * } + * } + * } + * ``` + */ + override val result: ExpectedNadelResult = ExpectedNadelResult( + result = """ + | { + | "data": { + | "me": { + | "profilePicture": { + | "path": "https://atlassian.net/wiki/aa-avatar/5ee0a4ef55749e0ab6e0fb70" + | } + | } + | } + | } + """.trimMargin(), + delayedResults = listOfJsonStrings( + ), + ) +} diff --git a/test/src/test/kotlin/graphql/nadel/tests/next/fixtures/defer/transforms/DeferredServiceTypeFilterTest.kt b/test/src/test/kotlin/graphql/nadel/tests/next/fixtures/defer/transforms/DeferredServiceTypeFilterTest.kt new file mode 100644 index 000000000..112f4e9bf --- /dev/null +++ b/test/src/test/kotlin/graphql/nadel/tests/next/fixtures/defer/transforms/DeferredServiceTypeFilterTest.kt @@ -0,0 +1,100 @@ +package graphql.nadel.tests.next.fixtures.defer.transforms + +import graphql.nadel.NadelExecutionHints +import graphql.nadel.tests.next.NadelIntegrationTest + +/** + * This tests the NadelServiceTypeFilterTransform with defer + */ +open class DeferredServiceTypeFilterTest : NadelIntegrationTest( + query = """ + query { + aErrors { + ...@defer { + ...on AError { + id + } + ...on BError { + id + } + } + } + } + """.trimIndent(), + services = listOf( + Service( + name = "A", + overallSchema = """ + type Query { + aErrors: Error + } + type AError implements Error { id: ID } + interface Error { id: ID } + """.trimIndent(), + underlyingSchema = """ + type Query { + aErrors: Error + } + type AError implements Error { id: ID } + interface Error { id: ID } + """.trimIndent(), + runtimeWiring = { wiring -> + wiring + .type("Query") { type -> + type + .dataFetcher("aErrors") { env -> + Any() + } + } + .type("AError") { type -> + type + .dataFetcher("id") { env -> + "A-ERROR-1" + } + } + .type("Error") { type -> + type + .typeResolver { env -> + env.schema.getObjectType("AError") + } + } + }, + ), + Service( + name = "B", + overallSchema = """ + type Query { + echo: String + } + type BError implements Error { + id: ID + b: String + } + """.trimIndent(), + underlyingSchema = """ + type Query { + echo: String + } + type BError implements Error { + id: ID + b: String + } + interface Error { id: ID } + """.trimIndent(), + runtimeWiring = { wiring -> + wiring + .type("Error") { type -> + type + .typeResolver { env -> + env.schema.getObjectType("BError") + } + } + }, + ), + ), +) { + override fun makeExecutionHints(): NadelExecutionHints.Builder { + return super.makeExecutionHints() + .deferSupport { true } + } +} diff --git a/test/src/test/kotlin/graphql/nadel/tests/next/fixtures/defer/transforms/DeferredServiceTypeFilterTestSnapshot.kt b/test/src/test/kotlin/graphql/nadel/tests/next/fixtures/defer/transforms/DeferredServiceTypeFilterTestSnapshot.kt new file mode 100644 index 000000000..f11f2c83e --- /dev/null +++ b/test/src/test/kotlin/graphql/nadel/tests/next/fixtures/defer/transforms/DeferredServiceTypeFilterTestSnapshot.kt @@ -0,0 +1,72 @@ +// @formatter:off +package graphql.nadel.tests.next.fixtures.defer.transforms + +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() +} + +/** + * This class is generated. Do NOT modify. + * + * Refer to [graphql.nadel.tests.next.UpdateTestSnapshots + */ +@Suppress("unused") +public class DeferredServiceTypeFilterTestSnapshot : TestSnapshot() { + override val calls: List = listOf( + ExpectedServiceCall( + service = "A", + query = """ + | { + | aErrors { + | id + | } + | } + """.trimMargin(), + variables = " {}", + result = """ + | { + | "data": { + | "aErrors": { + | "id": "A-ERROR-1" + | } + | } + | } + """.trimMargin(), + delayedResults = listOfJsonStrings( + ), + ), + ) + + /** + * ```json + * { + * "data": { + * "aErrors": { + * "id": "A-ERROR-1" + * } + * } + * } + * ``` + */ + override val result: ExpectedNadelResult = ExpectedNadelResult( + result = """ + | { + | "data": { + | "aErrors": { + | "id": "A-ERROR-1" + | } + | } + | } + """.trimMargin(), + delayedResults = listOfJsonStrings( + ), + ) +}