JsonOkHttpRequest implements Request<D> { @NonNull @Override @WorkerThread public Result<D> execute(@NonNull Bundle args) { JsonAdapter<D> adapter = getAdapter(); try { return executeRequest(adapter, args); } catch (IOException e) { if (e instanceof UnknownServiceException) { Log.e(TAG, "Unexpected error during network request.", e); tracker.logError(e); } Result<D> result = Result.Builder.fromException(new IOFailureException(e)); if (constructCacheControl(args) == CacheControl.FORCE_NETWORK) { Log.d(TAG, "Cache is disabled, do not attempt getting stale data."); return result; } Log.d(TAG, "Error while getting data, try to get stale data.", e); args = new Bundle(args); args.putBoolean(ALLOW_STALENESS, true); try { Result<D> staleResult = executeRequest(adapter, args); Log.d(TAG, "Stale data was found and used."); return result.updateWith(staleResult); } catch (IOException e2) { Log.d(TAG, "Stale data was not found.", e2); return result; } } } JsonOkHttpRequest(@NonNull Context context, @NonNull Type token);  JsonOkHttpRequest(@NonNull Context context, @NonNull Class<D> token); @NonNull @Override @WorkerThread Result<D> execute(@NonNull Bundle args);  }
@Test public void shouldUseNetwork_WhenOnlineAndNoCacheAvailable() throws IOException { server.enqueue(integerJsonResponse()); server.start(); HttpUrl url = server.url("/fine.json"); Request<Integer> request = new TestRequest(url); Result<Integer> result = request.execute(); assertTrue(result.hasData()); assertEquals(1, (int) result.getData()); }
@Test public void shouldUseCache_WhenOnlineAndCacheAvailable() throws IOException { server.enqueue(integerJsonResponse()); server.enqueue(integerJsonResponse()); server.start(); HttpUrl url = server.url("/fine.json"); Request<Integer> request = new TestRequest(url); Result<Integer> result = request.execute(); assertTrue(result.hasData()); assertEquals(1, (int) result.getData()); Result<Integer> result2 = request.execute(); assertTrue(result2.hasData()); assertEquals(1, (int) result2.getData()); Cache cache = InstanceProvider.getClient(context).cache(); assertNotNull(cache); assertEquals(1, cache.networkCount()); assertEquals(1, cache.hitCount()); assertEquals(2, cache.requestCount()); }
@Test public void shouldUseNetwork_WhenOnlineAndCacheAvailableButRequestingFreshData() throws IOException { server.enqueue(integerJsonResponse(1)); server.enqueue(integerJsonResponse(2)); server.start(); HttpUrl url = server.url("/fine.json"); Request<Integer> request = new TestRequest(url); Result<Integer> result = request.execute(); assertTrue(result.hasData()); assertEquals(1, (int) result.getData()); Bundle args = new Bundle(); args.putBoolean(BaseLiveData.REFRESH_COLD, true); Result<Integer> result2 = request.execute(args); assertTrue(result2.hasData()); assertEquals(2, (int) result2.getData()); Cache cache = InstanceProvider.getClient(context).cache(); assertNotNull(cache); assertEquals(2, cache.networkCount()); assertEquals(0, cache.hitCount()); assertEquals(2, cache.requestCount()); }
@Test public void shouldUseNetwork_WhenRequestIndicatedCacheDurationExpires() throws IOException { server.enqueue(integerJsonResponse(1)); server.enqueue(integerJsonResponse(2)); server.start(); HttpUrl url = server.url("/fine.json"); Request<Integer> request = new TestRequest(url, Duration.ZERO); Result<Integer> result = request.execute(); assertTrue(result.hasData()); assertEquals(1, (int) result.getData()); Result<Integer> result2 = request.execute(); assertTrue(result2.hasData()); assertEquals(2, (int) result2.getData()); Cache cache = InstanceProvider.getClient(context).cache(); assertNotNull(cache); assertEquals(2, cache.networkCount()); assertEquals(0, cache.hitCount()); assertEquals(2, cache.requestCount()); }
@Test(expected = RequestException.class) public void shouldThrow_WhenResponseIsEmpty() throws IOException, RequestException { server.enqueue(new MockResponse()); server.start(); HttpUrl url = server.url("/fine.json"); Request<Integer> request = new TestRequest(url); Result<Integer> result = request.execute(); assertTrue(result.hasException()); assertFalse(result.hasData()); result.getOrThrow(); }
@Test(expected = RequestException.class) public void shouldThrow_WhenResponseIsStringYetInvalidJson() throws IOException, RequestException { server.enqueue(new MockResponse().setBody("\"TEST\"")); server.start(); HttpUrl url = server.url("/fine.json"); Request<Integer> request = new TestRequest(url); Result<Integer> result = request.execute(); assertTrue(result.hasException()); assertFalse(result.hasData()); result.getOrThrow(); }
@Test(expected = RequestException.class) public void shouldTrow_WhenResponseIsNotEmptyYetWrongFormat() throws IOException, RequestException { server.enqueue(new MockResponse().setBody("TEST")); server.start(); HttpUrl url = server.url("/fine.json"); Request<Integer> request = new TestRequest(url); Result<Integer> result = request.execute(); assertTrue(result.hasException()); assertFalse(result.hasData()); result.getOrThrow(); }
@Test(expected = RequestException.class) public void shouldThrow_WhenResponseIsJsonYetExpectedOtherJson() throws IOException, RequestException { server.enqueue(new MockResponse().setBody("{\n" + "\t \"rank\": \"4\",\n" + "\t \"suit\": \"CLUBS\"\n" + "\t }")); server.start(); HttpUrl url = server.url("/fine.json"); Request<Integer> request = new TestRequest(url); Result<Integer> result = request.execute(); assertTrue(result.hasException()); assertFalse(result.hasData()); result.getOrThrow(); }
@Test(expected = RequestException.class) public void shouldThrow_whenOfflineAndNoCacheAvailable() throws RequestException { Request<Integer> request = new TestRequest(HttpUrl.get("http: Result<Integer> result = request.execute(); assertTrue(result.hasException()); assertFalse(result.hasData()); result.getOrThrow(); }
@Test public void shouldUseCache_WhenOfflineAndValidCacheAvailable() throws IOException { server.enqueue(integerJsonResponse()); server.start(); HttpUrl url = server.url("/fine.json"); Request<Integer> request = new TestRequest(url); Result<Integer> result = request.execute(); assertTrue(result.hasData()); assertEquals(1, (int) result.getData()); server.shutdown(); Result<Integer> result2 = request.execute(); assertTrue(result2.hasData()); assertEquals(1, (int) result2.getData()); Cache cache = InstanceProvider.getClient(context).cache(); assertNotNull(cache); assertEquals(1, cache.networkCount()); assertEquals(1, cache.hitCount()); assertEquals(2, cache.requestCount()); }
@Test public void shouldUseCache_WhenOfflineAndCacheAvailableButRequestingFreshData() throws IOException { server.enqueue(integerJsonResponse()); server.start(); HttpUrl url = server.url("/fine.json"); Request<Integer> request = new TestRequest(url); Result<Integer> result = request.execute(); assertTrue(result.hasData()); assertEquals(1, (int) result.getData()); Cache cache = InstanceProvider.getClient(context).cache(); assertNotNull(cache); assertEquals(1, cache.networkCount()); assertEquals(0, cache.hitCount()); assertEquals(1, cache.requestCount()); server.shutdown(); Bundle args = new Bundle(); args.putBoolean(BaseLiveData.REFRESH_COLD, true); Result<Integer> result2 = request.execute(args); assertTrue(result2.hasData()); assertEquals(1, (int) result2.getData()); assertEquals(2, cache.networkCount()); assertEquals(1, cache.hitCount()); assertEquals(3, cache.requestCount()); }
@Test(expected = IOFailureException.class) public void shouldThrow_WhenOfflineAndCacheAvailableButForbiddenToUseCache() throws IOException, RequestException { server.enqueue(integerJsonResponse()); server.start(); HttpUrl url = server.url("/fine.json"); Request<Integer> request = new NoCacheRequest(url); Result<Integer> result = request.execute(); assertTrue(result.hasData()); assertEquals(1, (int) result.getData()); Cache cache = InstanceProvider.getClient(context).cache(); assertNotNull(cache); assertEquals(1, cache.networkCount()); assertEquals(0, cache.hitCount()); assertEquals(1, cache.requestCount()); server.shutdown(); Result<Integer> result2 = request.execute(); assertFalse(result2.hasData()); assertTrue(result2.hasException()); assertEquals(0, cache.hitCount()); result2.getOrThrow(); }
@Test public void shouldUseCache_WhenOfflineAndStaleCacheAvailable() throws IOException { server.enqueue(integerJsonResponse()); server.start(); HttpUrl url = server.url("/fine.json"); Request<Integer> request = new TestRequest(url, Duration.ZERO); Result<Integer> result = request.execute(); assertTrue(result.hasData()); assertEquals(1, (int) result.getData()); Cache cache = InstanceProvider.getClient(context).cache(); assertNotNull(cache); assertEquals(1, cache.networkCount()); assertEquals(0, cache.hitCount()); assertEquals(1, cache.requestCount()); server.shutdown(); Result<Integer> result2 = request.execute(); assertTrue(result2.hasData()); assertEquals(1, (int) result2.getData()); assertEquals(2, cache.networkCount()); assertEquals(1, cache.hitCount()); assertEquals(3, cache.requestCount()); }
@Test(expected = RequestException.class) public void shouldThrow_WhenHttpErrorOccurs() throws IOException, RequestException { server.enqueue(new MockResponse().setResponseCode(500)); server.start(); HttpUrl url = server.url("/fine.json"); Request<Integer> request = new TestRequest(url); Result<Integer> result = request.execute(); assertTrue(result.hasException()); assertFalse(result.hasData()); result.getOrThrow(); }