From 45945b11bf056ba7b9a5c1c75a4c78381d4ef85d Mon Sep 17 00:00:00 2001 From: BoD Date: Mon, 7 Apr 2025 19:25:07 +0200 Subject: [PATCH] Add a test of using partial results with @catch(to: RESULT) --- .../src/commonMain/graphql/extra.graphqls | 2 + .../src/commonMain/graphql/operation.graphql | 11 +++++ .../src/commonMain/graphql/schema.graphqls | 6 +++ .../kotlin/test/CachePartialResultTest.kt | 42 +++++++++++++++++++ 4 files changed, 61 insertions(+) diff --git a/tests/partial-results/src/commonMain/graphql/extra.graphqls b/tests/partial-results/src/commonMain/graphql/extra.graphqls index 60f9d95e..68976056 100644 --- a/tests/partial-results/src/commonMain/graphql/extra.graphqls +++ b/tests/partial-results/src/commonMain/graphql/extra.graphqls @@ -26,3 +26,5 @@ extend type EmployeeInfo @semanticNonNullField(name: "salary") @semanticNonNullField(name: "department") extend type EmployeeInfo @cacheControlField(name: "salary", maxAge: 0) + +extend type DepartmentInfo @cacheControlField(name: "name", maxAge: 0) diff --git a/tests/partial-results/src/commonMain/graphql/operation.graphql b/tests/partial-results/src/commonMain/graphql/operation.graphql index 41a7ea29..daf35fe6 100644 --- a/tests/partial-results/src/commonMain/graphql/operation.graphql +++ b/tests/partial-results/src/commonMain/graphql/operation.graphql @@ -129,3 +129,14 @@ query MeWithEmployeeInfoQuery { } } } + +query MeWithDepartmentInfoQuery { + me { + firstName + lastName + departmentInfo { + id + name @catch(to: RESULT) + } + } +} diff --git a/tests/partial-results/src/commonMain/graphql/schema.graphqls b/tests/partial-results/src/commonMain/graphql/schema.graphqls index 8a7375d9..a63f307d 100644 --- a/tests/partial-results/src/commonMain/graphql/schema.graphqls +++ b/tests/partial-results/src/commonMain/graphql/schema.graphqls @@ -19,6 +19,7 @@ type User { category: Category! moreInfo: Json! employeeInfo: EmployeeInfo + departmentInfo: DepartmentInfo! } type Project { @@ -35,5 +36,10 @@ type EmployeeInfo { department: String } +type DepartmentInfo { + id: ID! + name: String +} + scalar Category scalar Json diff --git a/tests/partial-results/src/commonTest/kotlin/test/CachePartialResultTest.kt b/tests/partial-results/src/commonTest/kotlin/test/CachePartialResultTest.kt index faf87012..110bd37d 100644 --- a/tests/partial-results/src/commonTest/kotlin/test/CachePartialResultTest.kt +++ b/tests/partial-results/src/commonTest/kotlin/test/CachePartialResultTest.kt @@ -5,6 +5,7 @@ import com.apollographql.apollo.api.ApolloRequest import com.apollographql.apollo.api.ApolloResponse import com.apollographql.apollo.api.Error import com.apollographql.apollo.api.Operation +import com.apollographql.apollo.api.graphQLErrorOrNull import com.apollographql.apollo.interceptor.ApolloInterceptor import com.apollographql.apollo.interceptor.ApolloInterceptorChain import com.apollographql.apollo.testing.internal.runTest @@ -824,6 +825,47 @@ class CachePartialResultTest { ) } } + + @Test + fun cacheControlWithCatchToResult() = runTest(before = { setUp() }, after = { tearDown() }) { + mockServer.enqueueString( + // language=JSON + """ + { + "data": { + "me": { + "__typename": "User", + "id": "1", + "firstName": "John", + "lastName": "Smith", + "departmentInfo": { + "id": "1", + "name": "Engineering" + } + } + } + } + """ + ) + ApolloClient.Builder() + .serverUrl(mockServer.url()) + .normalizedCache(MemoryCacheFactory(), cacheResolver = CacheControlCacheResolver(SchemaCoordinatesMaxAgeProvider(Cache.maxAges, Duration.INFINITE))) + .storeReceivedDate(true) + .build() + .use { apolloClient -> + apolloClient.query(MeWithDepartmentInfoQuery()) + .fetchPolicy(FetchPolicy.NetworkOnly) + .execute() + val cacheMissResult = apolloClient.query(MeWithDepartmentInfoQuery()) + .fetchPolicyInterceptor(PartialCacheOnlyInterceptor) + .execute() + assertErrorsEquals( + Error.Builder("Field 'name' on object '${CacheKey("User:1").append("departmentInfo").keyToString()}' is stale in the cache") + .path(listOf("me", "departmentInfo", "name")).build(), + cacheMissResult.data?.me?.departmentInfo?.name?.graphQLErrorOrNull() + ) + } + } } val PartialCacheOnlyInterceptor = object : ApolloInterceptor {