@SuppressWarnings("ThrowableResultOfMethodCallIgnored") @Override public Task<TResult> then(Task<TResult> task) { if (task.getError() instanceof ParseException) { return c.runOnNetworkAsync(); } return task; } });
@SuppressWarnings("ThrowableResultOfMethodCallIgnored") @Override public Task<TResult> then(Task<TResult> task) { Exception error = task.getError(); if (error instanceof ParseException && ((ParseException) error).getCode() == ParseException.CONNECTION_FAILED) { return c.runFromCacheAsync(); } // Either the query succeeded, or there was an an error with the query, not the // network return task; } });
@Override public T then(Task<List<T>> task) throws Exception { if (task.isFaulted()) { throw task.getError(); } if (task.getResult() != null && task.getResult().size() > 0) { return task.getResult().get(0); } throw new ParseException(ParseException.OBJECT_NOT_FOUND, "no results found for query"); } });
@Override public Void then(Task<Void> task) { exceptionCapture.set(task.getError()); saveCountDown1.countDown(); return null; } });
@Override public Void then(Task<Void> task) { exceptionCapture.set(task.getError()); saveEventuallyCountDown.countDown(); return null; } });
@Override public Void then(Task<Void> task) { exceptionCapture.set(task.getError()); saveCountDown2.countDown(); return null; } });
@Override public Task<Void> then(Task<Void> task) { // Retry the fetch as a save operation because this Installation was deleted on the server. if (task.getError() != null && task.getError() instanceof ParseException) { int errCode = ((ParseException) task.getError()).getCode(); if (errCode == ParseException.OBJECT_NOT_FOUND || (errCode == ParseException.MISSING_REQUIRED_FIELD_ERROR && getObjectId() == null)) { synchronized (mutex) { setState(new State.Builder(getState()).objectId(null).build()); markAllFieldsDirty(); return ParseInstallation.super.saveAsync(sessionToken, toAwait); } } } return task; } });
@Override public Task<JSONObject> then(Task<JSONObject> task) { synchronized (taskQueueSyncLock) { pendingEventuallyTasks.remove(uuid); uuidToOperationSet.remove(uuid); uuidToEventuallyPin.remove(uuid); } Exception error = task.getError(); if (error != null) { tcs.trySetError(error); } else if (task.isCancelled()) { tcs.trySetCancelled(); } else { tcs.trySetResult(task.getResult()); } return tcs.getTask(); } });
@SuppressWarnings("ThrowableResultOfMethodCallIgnored") @Test public void testGetInBackgroundFail() throws Exception { ParseException exception = new ParseException(ParseException.CONNECTION_FAILED, "error"); ParseConfigController controller = mockParseConfigControllerWithException(exception); ParseCorePlugins.getInstance().registerConfigController(controller); Task<ParseConfig> configTask = ParseConfig.getInBackground(); configTask.waitForCompletion(); verify(controller, times(1)).getAsync(anyString()); assertThat(configTask.getError(), instanceOf(ParseException.class)); assertEquals(ParseException.CONNECTION_FAILED, ((ParseException) configTask.getError()).getCode()); assertEquals("error", configTask.getError().getMessage()); }
@Test public void testSubscribeInBackgroundFail() throws Exception { ParsePushChannelsController controller = mock(ParsePushChannelsController.class); ParseException exception = new ParseException(ParseException.OTHER_CAUSE, "error"); when(controller.subscribeInBackground(anyString())).thenReturn(Task.<Void>forError(exception)); ParseCorePlugins.getInstance().registerPushChannelsController(controller); Task<Void> pushTask = ParsePush.subscribeInBackground("test"); pushTask.waitForCompletion(); verify(controller, times(1)).subscribeInBackground("test"); assertTrue(pushTask.isFaulted()); assertSame(exception, pushTask.getError()); }
@Test public void testPermanentFailures() throws Exception { JSONObject json = new JSONObject(); json.put("code", 1337); json.put("error", "mock error"); ParseHttpResponse response = newMockParseHttpResponse(400, json); ParseHttpClient client = mock(ParseHttpClient.class); when(client.execute(any(ParseHttpRequest.class))).thenReturn(response); ParseRESTCommand command = new ParseRESTCommand.Builder() .method(ParseHttpRequest.Method.GET) .installationId("fake_installation_id") .build(); Task<JSONObject> task = command.executeAsync(client); task.waitForCompletion(); verify(client, times(1)).execute(any(ParseHttpRequest.class)); assertTrue(task.isFaulted()); assertEquals(1337, ((ParseException) task.getError()).getCode()); assertEquals("mock error", task.getError().getMessage()); }
@Test public void testCallFunctionInBackgroundFailure() throws Exception { // TODO(mengyan): Remove once we no longer rely on retry logic. ParseRequest.setDefaultInitialRetryDelay(1L); ParseHttpClient restClient = mock(ParseHttpClient.class); when(restClient.execute(any(ParseHttpRequest.class))).thenThrow(new IOException()); ParseCloudCodeController controller = new ParseCloudCodeController(restClient); Task<String> cloudCodeTask = controller.callFunctionInBackground("test", new HashMap<String, Object>(), "sessionToken"); // Do not use ParseTaskUtils.wait() since we do not want to throw the exception cloudCodeTask.waitForCompletion(); // TODO(mengyan): Abstract out command runner so we don't have to account for retries. verify(restClient, times(5)).execute(any(ParseHttpRequest.class)); assertTrue(cloudCodeTask.isFaulted()); Exception error = cloudCodeTask.getError(); assertThat(error, instanceOf(ParseException.class)); assertEquals(ParseException.CONNECTION_FAILED, ((ParseException) error).getCode()); }
/** * Test to verify that handle 401 unauthorized */ @Test public void test401Unauthorized() throws Exception { JSONObject json = new JSONObject(); json.put("error", "unauthorized"); ParseHttpResponse response = newMockParseHttpResponse(401, json); ParseHttpClient client = mock(ParseHttpClient.class); when(client.execute(any(ParseHttpRequest.class))).thenReturn(response); ParseRESTCommand command = new ParseRESTCommand.Builder() .method(ParseHttpRequest.Method.GET) .installationId("fake_installation_id") .build(); Task<JSONObject> task = command.executeAsync(client); task.waitForCompletion(); verify(client, times(1)).execute(any(ParseHttpRequest.class)); assertTrue(task.isFaulted()); assertEquals(0, ((ParseException) task.getError()).getCode()); assertEquals("unauthorized", task.getError().getMessage()); }
@Test public void testUnsubscribeInBackgroundFail() throws Exception { ParsePushChannelsController controller = mock(ParsePushChannelsController.class); ParseException exception = new ParseException(ParseException.OTHER_CAUSE, "error"); when(controller.unsubscribeInBackground(anyString())) .thenReturn(Task.<Void>forError(exception)); ParseCorePlugins.getInstance().registerPushChannelsController(controller); Task<Void> pushTask = ParsePush.unsubscribeInBackground("test"); pushTask.waitForCompletion(); verify(controller, times(1)).unsubscribeInBackground("test"); assertTrue(pushTask.isFaulted()); assertSame(exception, pushTask.getError()); }
@Test public void testSendInBackgroundFailWithIOException() throws Exception { // TODO(mengyan): Remove once we no longer rely on retry logic. ParseRequest.setDefaultInitialRetryDelay(1L); ParseHttpClient restClient = mock(ParseHttpClient.class); when(restClient.execute(any(ParseHttpRequest.class))).thenThrow(new IOException()); ParsePushController controller = new ParsePushController(restClient); JSONObject data = new JSONObject(); data.put(ParsePush.KEY_DATA_MESSAGE, "hello world"); ParsePush.State state = new ParsePush.State.Builder() .data(data) .build(); Task<Void> pushTask = controller.sendInBackground(state, "sessionToken"); // Do not use ParseTaskUtils.wait() since we do not want to throw the exception pushTask.waitForCompletion(); // Verify httpClient is tried enough times // TODO(mengyan): Abstract out command runner so we don't have to account for retries. verify(restClient, times(5)).execute(any(ParseHttpRequest.class)); assertTrue(pushTask.isFaulted()); Exception error = pushTask.getError(); assertThat(error, instanceOf(ParseException.class)); assertEquals(ParseException.CONNECTION_FAILED, ((ParseException) error).getCode()); }
@Test public void testSaveAsyncFailureWithByteArray() throws Exception { // TODO(grantland): Remove once we no longer rely on retry logic. ParseRequest.setDefaultInitialRetryDelay(1L); ParseHttpClient restClient = mock(ParseHttpClient.class); when(restClient.execute(any(ParseHttpRequest.class))).thenThrow(new IOException()); File root = temporaryFolder.getRoot(); ParseFileController controller = new ParseFileController(restClient, root); byte[] data = "hello".getBytes(); ParseFile.State state = new ParseFile.State.Builder() .build(); Task<ParseFile.State> task = controller.saveAsync(state, data, null, null, null); task.waitForCompletion(); // TODO(grantland): Abstract out command runner so we don't have to account for retries. verify(restClient, times(5)).execute(any(ParseHttpRequest.class)); assertTrue(task.isFaulted()); Exception error = task.getError(); assertThat(error, instanceOf(ParseException.class)); assertEquals(ParseException.CONNECTION_FAILED, ((ParseException) error).getCode()); assertEquals(0, root.listFiles().length); }
@Test public void testCallFunctionAsync() throws Exception { ParseCloudCodeController controller = mockParseCloudCodeControllerWithResponse("result"); ParseCorePlugins.getInstance().registerCloudCodeController(controller); Map<String, Object> parameters = new HashMap<>(); parameters.put("key1", Arrays.asList(1, 2, 3)); parameters.put("key2", "value1"); Task cloudCodeTask = ParseCloud.callFunctionInBackground("name", parameters); ParseTaskUtils.wait(cloudCodeTask); verify(controller, times(1)).callFunctionInBackground(eq("name"), eq(parameters), isNull(String.class)); assertTrue(cloudCodeTask.isCompleted()); assertNull(cloudCodeTask.getError()); assertThat(cloudCodeTask.getResult(), instanceOf(String.class)); assertEquals("result", cloudCodeTask.getResult()); }
@Test public void testSaveAsyncFailureWithFile() throws Exception { // TODO(grantland): Remove once we no longer rely on retry logic. ParseRequest.setDefaultInitialRetryDelay(1L); ParseHttpClient restClient = mock(ParseHttpClient.class); when(restClient.execute(any(ParseHttpRequest.class))).thenThrow(new IOException()); File root = temporaryFolder.getRoot(); ParseFileController controller = new ParseFileController(restClient, root); File file = temporaryFolder.newFile("test"); ParseFile.State state = new ParseFile.State.Builder() .build(); Task<ParseFile.State> task = controller.saveAsync(state, file, null, null, null); task.waitForCompletion(); // TODO(grantland): Abstract out command runner so we don't have to account for retries. verify(restClient, times(5)).execute(any(ParseHttpRequest.class)); assertTrue(task.isFaulted()); Exception error = task.getError(); assertThat(error, instanceOf(ParseException.class)); assertEquals(ParseException.CONNECTION_FAILED, ((ParseException) error).getCode()); // Make sure the original file is not deleted and there is no cache file in the folder assertEquals(1, root.listFiles().length); assertTrue(file.exists()); }
@Test public void testFetchAsyncFailure() throws Exception { // TODO(grantland): Remove once we no longer rely on retry logic. ParseRequest.setDefaultInitialRetryDelay(1L); ParseHttpClient fileClient = mock(ParseHttpClient.class); when(fileClient.execute(any(ParseHttpRequest.class))).thenThrow(new IOException()); File root = temporaryFolder.getRoot(); ParseFileController controller = new ParseFileController(null, root).fileClient(fileClient); // We need to set url to make getTempFile() work and check it ParseFile.State state = new ParseFile.State.Builder() .url("test") .build(); Task<File> task = controller.fetchAsync(state, null, null, null); task.waitForCompletion(); // TODO(grantland): Abstract out command runner so we don't have to account for retries. verify(fileClient, times(5)).execute(any(ParseHttpRequest.class)); assertTrue(task.isFaulted()); Exception error = task.getError(); assertThat(error, instanceOf(ParseException.class)); assertEquals(ParseException.CONNECTION_FAILED, ((ParseException) error).getCode()); assertEquals(0, root.listFiles().length); assertFalse(controller.getTempFile(state).exists()); }
@Test public void testDownloadProgress() throws Exception { ParseHttpResponse mockResponse = new ParseHttpResponse.Builder() .setStatusCode(200) .setTotalSize((long) data.length) .setContent(new ByteArrayInputStream(data)) .build(); ParseHttpClient mockHttpClient = mock(ParseHttpClient.class); when(mockHttpClient.execute(any(ParseHttpRequest.class))).thenReturn(mockResponse); File tempFile = temporaryFolder.newFile("test"); ParseFileRequest request = new ParseFileRequest(ParseHttpRequest.Method.GET, "localhost", tempFile); TestProgressCallback downloadProgressCallback = new TestProgressCallback(); Task<Void> task = request.executeAsync(mockHttpClient, null, downloadProgressCallback); task.waitForCompletion(); assertFalse("Download failed: " + task.getError(), task.isFaulted()); assertEquals(data.length, ParseFileUtils.readFileToByteArray(tempFile).length); assertProgressCompletedSuccessfully(downloadProgressCallback); }