@@ -11,6 +11,7 @@ import com.apollographql.apollo.cache.http.httpFetchPolicy
1111import com.apollographql.apollo.cache.http.isFromHttpCache
1212import com.apollographql.apollo.exception.ApolloNetworkException
1313import com.apollographql.apollo.exception.HttpCacheMissException
14+ import com.apollographql.apollo.exception.JsonEncodingException
1415import com.apollographql.mockserver.MockServer
1516import com.apollographql.mockserver.awaitRequest
1617import com.apollographql.mockserver.enqueueError
@@ -21,6 +22,7 @@ import httpcache.GetRandom2Query
2122import httpcache.GetRandomQuery
2223import httpcache.RandomSubscription
2324import httpcache.SetRandomMutation
25+ import junit.framework.TestCase.assertFalse
2426import kotlinx.coroutines.delay
2527import kotlinx.coroutines.runBlocking
2628import okhttp3.Interceptor
@@ -31,6 +33,7 @@ import kotlin.test.Test
3133import kotlin.test.assertEquals
3234import kotlin.test.assertIs
3335import kotlin.test.assertNotNull
36+ import kotlin.test.assertTrue
3437
3538class HttpCacheTest {
3639 lateinit var mockServer: MockServer
@@ -215,18 +218,71 @@ class HttpCacheTest {
215218 }
216219 }
217220
221+ /* *
222+ * Whether an incomplete Json is an IO error is still an open question:
223+ * - [ResponseParser] considers yes (and throws an ApolloNetworkException)
224+ * - [ProxySource] considers no (and doesn't abort)
225+ *
226+ * This isn't great and will need to be revisited if that ever becomes a bigger problem
227+ */
218228 @Test
219- fun incompleteJsonIsNotCached () = runTest(before = { before() }, after = { tearDown() }) {
229+ fun incompleteJsonTriggersNetworkException () = runTest(before = { before() }, after = { tearDown() }) {
220230 mockServer.enqueueString(""" {"data":""" )
231+ apolloClient.query(GetRandomQuery ()).execute().apply {
232+ assertIs<ApolloNetworkException >(exception)
233+ }
234+
235+ apolloClient.query(GetRandomQuery ()).httpFetchPolicy(HttpFetchPolicy .CacheOnly ).execute().apply {
236+ /* *
237+ * Because there's a disagreement between ProxySource and HttpCacheApolloInterceptor, the value is stored in the
238+ * HTTP cache and is replayed here
239+ */
240+ assertIs<ApolloNetworkException >(exception)
241+ }
242+ }
243+
244+ @Test
245+ fun malformedJsonIsNotCached () = runTest(before = { before() }, after = { tearDown() }) {
246+ mockServer.enqueueString(""" {"data":}""" )
221247 apolloClient.query(GetRandomQuery ()).execute().exception.apply {
222- assertIs<ApolloNetworkException >(this )
248+ assertIs<JsonEncodingException >(this )
223249 }
224250 // Should not have been cached
225- assertIs<HttpCacheMissException >(
226- apolloClient.query(GetRandomQuery ()).httpFetchPolicy(HttpFetchPolicy .CacheOnly ).execute().exception
227- )
251+ apolloClient.query(GetRandomQuery ()).httpFetchPolicy(HttpFetchPolicy .CacheOnly ).execute().apply {
252+ assertIs<HttpCacheMissException >(exception)
253+ }
254+ }
255+
256+ @Test
257+ fun ioErrorDoesNotRemoveData () = runTest(before = { before() }, after = { tearDown() }) {
258+ mockServer.enqueueString("""
259+ {
260+ "data": {
261+ "random": "42"
262+ }
263+ }
264+ """ .trimIndent())
265+
266+ // Warm the cache
267+ apolloClient.query(GetRandomQuery ()).execute().apply {
268+ assertEquals(42 , data?.random)
269+ assertFalse(isFromHttpCache)
270+ }
271+
272+ // Go offline
273+ mockServer.close()
274+ apolloClient.query(GetRandomQuery ()).httpFetchPolicy(HttpFetchPolicy .NetworkOnly ).execute().apply {
275+ assertIs<ApolloNetworkException >(exception)
276+ }
277+
278+ // The data is still there
279+ apolloClient.query(GetRandomQuery ()).execute().apply {
280+ assertEquals(42 , data?.random)
281+ assertTrue(isFromHttpCache)
282+ }
228283 }
229284
285+
230286 @Test
231287 fun responseWithGraphQLErrorIsNotCached () = runTest(before = { before() }, after = { tearDown() }) {
232288 mockServer.enqueueString("""
0 commit comments