From 43f4a4cefb9d1b7d4837d2a718f424cd0e3af95d Mon Sep 17 00:00:00 2001 From: Kai Moritz Date: Thu, 21 Nov 2019 00:47:13 +0100 Subject: [PATCH] Refined the test-cases and fixed a bug in GraphApiErrorResponseErrorHandler * Fixed naming of test-case for the GraphApiErrorResponseErrorHandler * Moved cases, that test GraphApiException into a separate class * Do not test cases, that are coverd in unit-tests in integration-tests * Instead, do test cases, that can only happen in the integrated environment * GraphApiErrorResponseErrorHandler must only handle 4xx-responses --- .../GraphApiErrorResponseErrorHandler.java | 4 +- .../errors/GraphApiErrorHandlerTest.java | 814 ------------------ ...orResponseErrorHandlerIntegrationTest.java | 205 +++++ .../errors/GraphApiExceptionTest.java | 550 ++++++++++++ 4 files changed, 756 insertions(+), 817 deletions(-) delete mode 100644 src/test/java/de/juplo/facebook/errors/GraphApiErrorHandlerTest.java create mode 100644 src/test/java/de/juplo/facebook/errors/GraphApiErrorResponseErrorHandlerIntegrationTest.java create mode 100644 src/test/java/de/juplo/facebook/errors/GraphApiExceptionTest.java diff --git a/src/main/java/de/juplo/facebook/errors/GraphApiErrorResponseErrorHandler.java b/src/main/java/de/juplo/facebook/errors/GraphApiErrorResponseErrorHandler.java index 41f00fe..e2f52ff 100644 --- a/src/main/java/de/juplo/facebook/errors/GraphApiErrorResponseErrorHandler.java +++ b/src/main/java/de/juplo/facebook/errors/GraphApiErrorResponseErrorHandler.java @@ -58,9 +58,7 @@ public class GraphApiErrorResponseErrorHandler implements ResponseErrorHandler @Override public boolean hasError(ClientHttpResponse response) throws IOException { - return - HttpStatus.Series.CLIENT_ERROR.equals(response.getStatusCode().series()) - || this.parent.hasError(response); + return HttpStatus.Series.CLIENT_ERROR.equals(response.getStatusCode().series()); } @Override diff --git a/src/test/java/de/juplo/facebook/errors/GraphApiErrorHandlerTest.java b/src/test/java/de/juplo/facebook/errors/GraphApiErrorHandlerTest.java deleted file mode 100644 index c171956..0000000 --- a/src/test/java/de/juplo/facebook/errors/GraphApiErrorHandlerTest.java +++ /dev/null @@ -1,814 +0,0 @@ -package de.juplo.facebook.errors; - - -import de.juplo.facebook.errors.GraphApiException.Type; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.fail; -import org.junit.Before; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.HttpStatus; -import org.springframework.web.client.HttpClientErrorException; -import org.springframework.web.client.RestTemplate; - - - -/** - * - * @author Kai Moritz - */ -public class GraphApiErrorHandlerTest -{ - private static final Logger log = - LoggerFactory.getLogger(GraphApiErrorHandlerTest.class); - - private RestTemplate clientTemplate; - private MockClientHttpRequestFactory requestFactory; - - - @Test - public void testError1() - { - log.info("testError1"); - - - requestFactory.setBody( - "{\n" + - " \"error\":\n" + - " {\n" + - " \"message\": \"An unknown error has occurred.\",\n" + - " \"type\": \"OAuthException\",\n" + - " \"code\": 1\n" + - " }\n" + - "}"); - - try - { - clientTemplate.getForObject("ANY", SOME.class); - fail("The expected exception was not thrown"); - } - catch(UnknownErrorException e) - { - log.debug("{}", e.toString()); - assertEquals(new Integer(1), e.getCode()); - assertEquals("An unknown error has occurred.", e.getMessage()); - assertEquals(Type.OAuthException, e.getType()); - } - } - - @Test - public void testError2() - { - log.info("testError2"); - - - requestFactory.setBody( - "{\n" + - " \"error\":\n" + - " {\n" + - " \"message\": \"An unexpected error has occurred. Please retry your request later.\",\n" + - " \"type\": \"OAuthException\",\n" + - " \"code\": 2\n" + - " }\n" + - "}"); - - try - { - clientTemplate.getForObject("ANY", SOME.class); - fail("The expected exception was not thrown"); - } - catch(UnexpectedErrorException e) - { - log.debug("{}", e.toString()); - assertEquals(new Integer(2), e.getCode()); - assertEquals("An unexpected error has occurred. Please retry your request later.", e.getMessage()); - assertEquals(Type.OAuthException, e.getType()); - } - } - - @Test - public void testError4() - { - log.info("testError4"); - - - requestFactory.setBody( - "{\n" + - " \"error\": {\n" + - " \"code\": 4, \n" + - " \"fbtrace_id\": \"HZRM6BTMu+D\", \n" + - " \"is_transient\": true, \n" + - " \"message\": \"(#4) Application request limit reached\", \n" + - " \"type\": \"OAuthException\"\n" + - " }\n" + - "}\n"); - - try - { - clientTemplate.getForObject("ANY", SOME.class); - fail("The expected exception was not thrown"); - } - catch(ApplicationRequestLimitReachedException e) - { - log.debug("{}", e.toString()); - assertEquals(new Integer(4), e.getCode()); - assertEquals("(#4) Application request limit reached", e.getMessage()); - assertEquals(Type.OAuthException, e.getType()); - } - } - - @Test - public void testError12() - { - log.info("testError12"); - - - requestFactory.setBody( - "{\n" + - " \"error\":\n" + - " {\n" + - " \"message\": \"(#12) location field is deprecated for versions v2.5 and higher\",\n" + - " \"type\": \"OAuthException\",\n" + - " \"code\": 12\n," + - " \"fbtrace_id\":\"BoxCYne7GrL\"\n" + - " }\n" + - "}"); - - try - { - clientTemplate.getForObject("ANY", SOME.class); - fail("The expected exception was not thrown"); - } - catch(DeprecatedException e) - { - log.debug("{}", e.toString()); - assertEquals(new Integer(12), e.getCode()); - assertEquals("(#12) location field is deprecated for versions v2.5 and higher", e.getMessage()); - assertEquals(Type.OAuthException, e.getType()); - } - } - - @Test - public void testError21() - { - log.info("testError21"); - - - requestFactory.setBody( - "{\n" + - " \"error\":\n" + - " {\n" + - " \"message\": \"(#21) Page ID 590408587650316 was migrated to page ID 1421620791415603. Please update your API calls to the new ID\",\n" + - " \"type\": \"OAuthException\",\n" + - " \"code\": 21\n" + - " }\n" + - "}"); - - try - { - clientTemplate.getForObject("ANY", SOME.class); - fail("The expected exception was not thrown"); - } - catch(PageMigratedException e) - { - log.debug("{}", e.toString()); - assertEquals(new Integer(21), e.getCode()); - assertEquals("(#21) Page ID 590408587650316 was migrated to page ID 1421620791415603. Please update your API calls to the new ID", e.getMessage()); - assertEquals(Type.OAuthException, e.getType()); - } - } - - @Test - public void testError100() - { - log.info("testError100"); - - - requestFactory.setBody( - "{\n" + - " \"error\":\n" + - " {\n" + - " \"message\": \"Unsupported get request.\",\n" + - " \"type\": \"GraphMethodException\",\n" + - " \"code\": 100\n" + - " }\n" + - "}"); - - try - { - clientTemplate.getForObject("ANY", SOME.class); - fail("The expected exception was not thrown"); - } - catch(UnsupportedGetRequestException e) - { - log.debug("{}", e.toString()); - assertEquals(new Integer(100), e.getCode()); - assertEquals("Unsupported get request.", e.getMessage()); - assertEquals(Type.GraphMethodException, e.getType()); - } - } - - @Test - public void testError102() - { - log.info("testError102"); - - requestFactory.setBody("{\"error\":{\"message\":\"A user access token is required to request this resource.\",\"type\":\"OAuthException\",\"code\":102,\"fbtrace_id\":\"DhdMyf23Ki7\"}}"); - - try - { - clientTemplate.getForObject("ANY", SOME.class); - fail("The expected exception was not thrown"); - } - catch(UserAccessTokenRequiredException e) - { - log.debug("{}", e.toString()); - assertEquals(new Integer(102), e.getCode()); - assertEquals("A user access token is required to request this resource.", e.getMessage()); - assertEquals(Type.OAuthException, e.getType()); - assertEquals("DhdMyf23Ki7", e.getTraceId()); - } - } - - @Test - public void testError104() - { - log.info("testError104"); - - requestFactory.setBody("{\"error\":{\"message\":\"An access token is required to request this resource.\",\"type\":\"OAuthException\",\"code\":104,\"fbtrace_id\":\"E2Jjkj5++LL\"}}"); - - try - { - clientTemplate.getForObject("ANY", SOME.class); - fail("The expected exception was not thrown"); - } - catch(AccessTokenRequiredException e) - { - log.debug("{}", e.toString()); - assertEquals(new Integer(104), e.getCode()); - assertEquals("An access token is required to request this resource.", e.getMessage()); - assertEquals(Type.OAuthException, e.getType()); - assertEquals("E2Jjkj5++LL", e.getTraceId()); - } - } - - @Test - public void testError190() - { - log.info("testError190"); - - requestFactory.setBody("{\"error\":{\"message\":\"Bad signature\",\"type\":\"OAuthException\",\"code\":190,\"fbtrace_id\":\"Ay2OYQrINbXOCfQpBvoxDIw\"}}"); - - try - { - clientTemplate.getForObject("ANY", SOME.class); - fail("The expected exception was not thrown"); - } - catch(AccessTokenExpiredException e) - { - log.debug("{}", e.toString()); - assertEquals(new Integer(190), e.getCode()); - assertEquals("Bad signature", e.getMessage()); - assertEquals(Type.OAuthException, e.getType()); - assertEquals("Ay2OYQrINbXOCfQpBvoxDIw", e.getTraceId()); - } - } - - @Test - public void testError200() - { - log.info("testError200"); - - requestFactory.setBody("{\n" + - " \"error\": {\n" + - " \"message\": \"(#200) The user hasn't authorized the application to perform this action\",\n" + - " \"type\": \"OAuthException\",\n" + - " \"code\": 200\n" + - " }\n" + - "}"); - - try - { - clientTemplate.getForObject("ANY", SOME.class); - fail("The expected exception was not thrown"); - } - catch(ApplicationNotAuthorizedByUserException e) - { - log.debug("{}", e.toString()); - assertEquals(new Integer(200), e.getCode()); - assertEquals("(#200) The user hasn't authorized the application to perform this action", e.getMessage()); - assertEquals(Type.OAuthException, e.getType()); - assertNull(e.getTraceId()); - } - } - - @Test - public void testError613() - { - log.info("testError613"); - - - requestFactory.setBody( - "{\n" + - " \"error\":\n" + - " {\n" + - " \"message\": \"(#613) Calls to stream have exceeded the rate of 600 calls per 600 seconds.\",\n" + - " \"type\": \"OAuthException\",\n" + - " \"code\": 613\n" + - " }\n" + - "}"); - - try - { - clientTemplate.getForObject("ANY", SOME.class); - fail("The expected exception was not thrown"); - } - catch(RateLimitExceededException e) - { - log.debug("{}", e.toString()); - assertEquals(new Integer(613), e.getCode()); - assertEquals("(#613) Calls to stream have exceeded the rate of 600 calls per 600 seconds.", e.getMessage()); - assertEquals(Type.OAuthException, e.getType()); - } - } - - @Test - public void testError2200() - { - requestFactory.setBody("{\"error\":{\"message\":\"(#2200) callback verification failed: \",\"type\":\"OAuthException\",\"code\":2200,\"fbtrace_id\":\"ESLjoZKvPXg\"}}"); - - try - { - clientTemplate.getForObject("ANY", SOME.class); - fail("The expected exception was not thrown"); - } - catch(CallbackVerificationFailedException e) - { - log.debug("{}", e.toString()); - assertEquals(new Integer(2200), e.getCode()); - assertEquals("(#2200) callback verification failed: ", e.getMessage()); - assertEquals(Type.OAuthException, e.getType()); - assertEquals("ESLjoZKvPXg", e.getTraceId()); - } - } - - @Test - public void testUnmappedError() - { - log.info("testUnmappedError"); - - - requestFactory.setBody( - "{\n" + - " \"error\":\n" + - " {\n" + - " \"message\": \"This error does not exist.\",\n" + - " \"type\": \"NonexistentTypeException\",\n" + - " \"code\": 999999999\n" + - " }\n" + - "}"); - - try - { - clientTemplate.getForObject("ANY", SOME.class); - fail("The expected exception was not thrown"); - } - catch(GraphApiException e) - { - log.debug("{}", e.toString()); - assertEquals(new Integer(999999999), e.getCode()); - assertEquals("This error does not exist.", e.getMessage()); - try - { - Type type = e.getType(); - log.error("unknown type: {}", type); - fail("unmapped type was resolved by enum: " + type); - } - catch (IllegalArgumentException ee) {} - } - } - - @Test - public void testUnmappedErrors() - { - log.info("testUnmappedErrors"); - - - requestFactory.setBody( - "{\n" + - " \"error\":\n" + - " {\n" + - " \"message\": null,\n" + - " \"type\": \"WhateverTypeException\",\n" + - " \"code\": 999999999\n" + - " }\n" + - "}"); - - try - { - clientTemplate.getForObject("ANY", SOME.class); - fail("The expected exception was not thrown"); - } - catch(UnmappedErrorException e) - { - log.debug("{}", e.toString()); - assertNull(e.getMessage()); - try - { - Type type = e.getType(); - log.error("unknown type: {}", type); - fail("unmapped type was resolved by enum: " + type); - } - catch (IllegalArgumentException ee) {} - assertEquals(new Integer(999999999), e.getCode()); - assertNull(e.getSubCode()); - assertNull(e.getUserTitle()); - assertNull(e.getUserMessage()); - assertNull(e.getTraceId()); - } - catch(Exception e) - { - fail("A wrong exception was thrown: " + e.toString()); - } - - - requestFactory.setBody( - "{\n" + - " \"error\":\n" + - " {\n" + - " \"type\": \"WhateverTypeException\",\n" + - " \"code\": 999999999\n" + - " }\n" + - "}"); - - try - { - clientTemplate.getForObject("ANY", SOME.class); - fail("The expected exception was not thrown"); - } - catch(UnmappedErrorException e) - { - log.debug("{}", e.toString()); - assertNull(e.getMessage()); - try - { - Type type = e.getType(); - log.error("unknown type: {}", type); - fail("unmapped type was resolved by enum: " + type); - } - catch (IllegalArgumentException ee) {} - assertEquals(new Integer(999999999), e.getCode()); - assertNull(e.getSubCode()); - assertNull(e.getUserTitle()); - assertNull(e.getUserMessage()); - assertNull(e.getTraceId()); - } - catch(Exception e) - { - fail("A wrong exception was thrown: " + e.toString()); - } - - - requestFactory.setBody( - "{\n" + - " \"error\":\n" + - " {\n" + - " \"message\": \"An unmapped Graph-API-Exception.\",\n" + - " \"type\": null,\n" + - " \"code\": 999999999\n" + - " }\n" + - "}"); - - try - { - clientTemplate.getForObject("ANY", SOME.class); - fail("The expected exception was not thrown"); - } - catch(UnmappedErrorException e) - { - log.debug("{}", e.toString()); - assertEquals("An unmapped Graph-API-Exception.", e.getMessage()); - assertNull(e.getType()); - assertEquals(new Integer(999999999), e.getCode()); - assertNull(e.getSubCode()); - assertNull(e.getUserTitle()); - assertNull(e.getUserMessage()); - assertNull(e.getTraceId()); - } - catch(Exception e) - { - fail("A wrong exception was thrown: " + e.toString()); - } - - - requestFactory.setBody( - "{\n" + - " \"error\":\n" + - " {\n" + - " \"message\": \"An unmapped Graph-API-Exception.\",\n" + - " \"code\": 999999999\n" + - " }\n" + - "}"); - - try - { - clientTemplate.getForObject("ANY", SOME.class); - fail("The expected exception was not thrown"); - } - catch(UnmappedErrorException e) - { - log.debug("{}", e.toString()); - assertEquals("An unmapped Graph-API-Exception.", e.getMessage()); - assertNull(e.getType()); - assertEquals(new Integer(999999999), e.getCode()); - assertNull(e.getSubCode()); - assertNull(e.getUserTitle()); - assertNull(e.getUserMessage()); - assertNull(e.getTraceId()); - } - catch(Exception e) - { - fail("A wrong exception was thrown: " + e.toString()); - } - } - - @Test - public void testInvlalidErrors() - { - log.info("testInvalidErrors"); - - - requestFactory.setBody( - "{\n" + - " \"error\":\n" + - " {\n" + - " \"message\": \"Not a Graph-Api-Exception.\",\n" + - " \"type\": \"Whatever\",\n" + - " \"code\": \"some string\"\n" + - " }\n" + - "}"); - - try - { - clientTemplate.getForObject("ANY", SOME.class); - fail("The expected exception was not thrown"); - } - catch(HttpClientErrorException e) - { - log.debug("{}", e.toString()); - } - catch(Exception e) - { - fail("A wrong exception was thrown: " + e.toString()); - } - - - requestFactory.setBody( - "{\n" + - " \"error\":\n" + - " {\n" + - " \"message\": \"Not a Graph-Api-Exception.\",\n" + - " \"type\": \"Whatever\",\n" + - " \"code\": 9.9\n" + - " }\n" + - "}"); - - try - { - clientTemplate.getForObject("ANY", SOME.class); - fail("The expected exception was not thrown"); - } - catch(HttpClientErrorException e) - { - log.debug("{}", e.toString()); - } - catch(Exception e) - { - fail("A wrong exception was thrown: " + e.toString()); - } - - - requestFactory.setBody( - "{\n" + - " \"error\":\n" + - " {\n" + - " \"message\": \"Not a Graph-Api-Exception.\",\n" + - " \"type\": \"Whatever\",\n" + - " \"code\": null\n" + - " }\n" + - "}"); - - try - { - clientTemplate.getForObject("ANY", SOME.class); - fail("The expected exception was not thrown"); - } - catch(HttpClientErrorException e) - { - log.debug("{}", e.toString()); - } - catch(Exception e) - { - fail("A wrong exception was thrown: " + e.toString()); - } - - - requestFactory.setBody( - "{\n" + - " \"error\":\n" + - " {\n" + - " \"message\": \"Not a Graph-Api-Exception.\",\n" + - " \"type\": \"Whatever\"\n" + - " }\n" + - "}"); - - try - { - clientTemplate.getForObject("ANY", SOME.class); - fail("The expected exception was not thrown"); - } - catch(HttpClientErrorException e) - { - log.debug("{}", e.toString()); - } - catch(Exception e) - { - fail("A wrong exception was thrown: " + e.toString()); - } - - - requestFactory.setBody("{\"error\":{\"message\":null}}"); - - try - { - clientTemplate.getForObject("ANY", SOME.class); - fail("The expected exception was not thrown"); - } - catch(HttpClientErrorException e) - { - log.debug("{}", e.toString()); - } - catch(Exception e) - { - fail("A wrong exception was thrown: " + e.toString()); - } - - - requestFactory.setBody("{\"error\":{\"type\":null}}"); - - try - { - clientTemplate.getForObject("ANY", SOME.class); - fail("The expected exception was not thrown"); - } - catch(HttpClientErrorException e) - { - log.debug("{}", e.toString()); - } - catch(Exception e) - { - fail("A wrong exception was thrown: " + e.toString()); - } - - - requestFactory.setBody("{\"error\":{\"code\":null}}"); - - try - { - clientTemplate.getForObject("ANY", SOME.class); - fail("The expected exception was not thrown"); - } - catch(HttpClientErrorException e) - { - log.debug("{}", e.toString()); - } - catch(Exception e) - { - fail("A wrong exception was thrown: " + e.toString()); - } - - - requestFactory.setBody("{\"error\":{}}"); - - try - { - clientTemplate.getForObject("ANY", SOME.class); - fail("The expected exception was not thrown"); - } - catch(HttpClientErrorException e) - { - log.debug("{}", e.toString()); - } - catch(Exception e) - { - fail("A wrong exception was thrown: " + e.toString()); - } - - - requestFactory.setBody("{\"error\":\"some message\"}"); - - try - { - clientTemplate.getForObject("ANY", SOME.class); - fail("The expected exception was not thrown"); - } - catch(HttpClientErrorException e) - { - log.debug("{}", e.toString()); - } - catch(Exception e) - { - fail("A wrong exception was thrown: " + e.toString()); - } - - - requestFactory.setBody("{\"error\":null}"); - - try - { - clientTemplate.getForObject("ANY", SOME.class); - fail("The expected exception was not thrown"); - } - catch(HttpClientErrorException e) - { - log.debug("{}", e.toString()); - } - catch(Exception e) - { - fail("A wrong exception was thrown: " + e.toString()); - } - - - requestFactory.setBody("{\"some filed\":\"some message\"}"); - - try - { - clientTemplate.getForObject("ANY", SOME.class); - fail("The expected exception was not thrown"); - } - catch(HttpClientErrorException e) - { - log.debug("{}", e.toString()); - } - catch(Exception e) - { - fail("A wrong exception was thrown: " + e.toString()); - } - - - requestFactory.setBody("{}"); - - try - { - clientTemplate.getForObject("ANY", SOME.class); - fail("The expected exception was not thrown"); - } - catch(HttpClientErrorException e) - { - log.debug("{}", e.toString()); - } - catch(Exception e) - { - fail("A wrong exception was thrown: " + e.toString()); - } - - - requestFactory.setBody(""); - - try - { - clientTemplate.getForObject("ANY", SOME.class); - fail("The expected exception was not thrown"); - } - catch(HttpClientErrorException e) - { - log.debug("{}", e.toString()); - } - catch(Exception e) - { - fail("A wrong exception was thrown: " + e.toString()); - } - } - - - @Before - public void setUp() - { - requestFactory = new MockClientHttpRequestFactory(); - requestFactory.setStatus(HttpStatus.BAD_REQUEST); - requestFactory.addHeader("Content-Type", "application/json"); - - clientTemplate = new RestTemplate(); - clientTemplate.setRequestFactory(requestFactory); - clientTemplate.setErrorHandler( - new GraphApiErrorResponseErrorHandler(clientTemplate.getErrorHandler()) - ); - } - - - static class SOME - { - } -} diff --git a/src/test/java/de/juplo/facebook/errors/GraphApiErrorResponseErrorHandlerIntegrationTest.java b/src/test/java/de/juplo/facebook/errors/GraphApiErrorResponseErrorHandlerIntegrationTest.java new file mode 100644 index 0000000..6593375 --- /dev/null +++ b/src/test/java/de/juplo/facebook/errors/GraphApiErrorResponseErrorHandlerIntegrationTest.java @@ -0,0 +1,205 @@ +package de.juplo.facebook.errors; + + +import de.juplo.facebook.errors.GraphApiException.Type; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.RestTemplate; + + + +/** + * + * @author Kai Moritz + */ +public class GraphApiErrorResponseErrorHandlerIntegrationTest +{ + private static final Logger LOG = + LoggerFactory.getLogger(GraphApiErrorResponseErrorHandlerIntegrationTest.class); + + private RestTemplate clientTemplate; + private MockClientHttpRequestFactory requestFactory; + + + @Test + public void testNoError() + { + LOG.info("testNoError"); + + requestFactory.setBody("{\n" + + " \"error\": {\n" + + " \"message\": \"(#200) The user hasn't authorized the application to perform this action\",\n" + + " \"type\": \"OAuthException\",\n" + + " \"code\": 200\n" + + " }\n" + + "}"); + + + requestFactory.setStatus(HttpStatus.CONTINUE); + try + { + clientTemplate.getForObject("ANY", SOME.class); + } + catch(Exception e) + { + LOG.debug("{}", e.toString()); + fail("Unexpected error: " + e); + } + + requestFactory.setStatus(HttpStatus.OK); + try + { + clientTemplate.getForObject("ANY", SOME.class); + } + catch(Exception e) + { + LOG.debug("{}", e.toString()); + fail("Unexpected error: " + e); + } + + requestFactory.setStatus(HttpStatus.TEMPORARY_REDIRECT); + try + { + clientTemplate.getForObject("ANY", SOME.class); + } + catch(Exception e) + { + LOG.debug("{}", e.toString()); + fail("Unexpected error: " + e); + } + + requestFactory.setStatus(HttpStatus.INTERNAL_SERVER_ERROR); + try + { + clientTemplate.getForObject("ANY", SOME.class); + } + catch(Exception e) + { + LOG.debug("{}", e.toString()); + fail("Unexpected error: " + e); + } + } + + @Test + public void testValidError() + { + LOG.info("testValidError"); + + + requestFactory.setBody( + "{\n" + + " \"error\":\n" + + " {\n" + + " \"message\": \"(#613) Calls to stream have exceeded the rate of 600 calls per 600 seconds.\",\n" + + " \"type\": \"OAuthException\",\n" + + " \"code\": 613\n" + + " }\n" + + "}"); + + try + { + clientTemplate.getForObject("ANY", SOME.class); + fail("The expected exception was not thrown"); + } + catch(RateLimitExceededException e) + { + LOG.debug("{}", e.toString()); + assertEquals(new Integer(613), e.getCode()); + assertEquals("(#613) Calls to stream have exceeded the rate of 600 calls per 600 seconds.", e.getMessage()); + assertEquals(Type.OAuthException, e.getType()); + } + } + + @Test + public void testUnmappedError() + { + LOG.info("testUnmappedError"); + + + requestFactory.setBody( + "{\n" + + " \"error\":\n" + + " {\n" + + " \"message\": \"This error does not exist.\",\n" + + " \"type\": \"NonexistentTypeException\",\n" + + " \"code\": 999999999\n" + + " }\n" + + "}"); + + try + { + clientTemplate.getForObject("ANY", SOME.class); + fail("The expected exception was not thrown"); + } + catch(GraphApiException e) + { + LOG.debug("{}", e.toString()); + assertEquals(new Integer(999999999), e.getCode()); + assertEquals("This error does not exist.", e.getMessage()); + try + { + Type type = e.getType(); + LOG.error("unknown type: {}", type); + fail("unmapped type was resolved by enum: " + type); + } + catch (IllegalArgumentException ee) {} + } + } + + @Test + public void testInvlalidError() + { + LOG.info("testInvalidError"); + + + requestFactory.setBody( + "{\n" + + " \"error\":\n" + + " {\n" + + " \"message\": \"Not a Graph-Api-Exception.\",\n" + + " \"type\": \"Whatever\",\n" + + " \"code\": \"some string\"\n" + + " }\n" + + "}"); + + try + { + clientTemplate.getForObject("ANY", SOME.class); + fail("The expected exception was not thrown"); + } + catch(HttpClientErrorException e) + { + LOG.debug("{}", e.toString()); + } + catch(Exception e) + { + fail("A wrong exception was thrown: " + e.toString()); + } + } + + + @Before + public void setUp() + { + requestFactory = new MockClientHttpRequestFactory(); + requestFactory.setStatus(HttpStatus.BAD_REQUEST); + requestFactory.addHeader("Content-Type", "application/json"); + + clientTemplate = new RestTemplate(); + clientTemplate.setRequestFactory(requestFactory); + clientTemplate.setErrorHandler( + new GraphApiErrorResponseErrorHandler(clientTemplate.getErrorHandler()) + ); + } + + + static class SOME + { + } +} diff --git a/src/test/java/de/juplo/facebook/errors/GraphApiExceptionTest.java b/src/test/java/de/juplo/facebook/errors/GraphApiExceptionTest.java new file mode 100644 index 0000000..f2591d1 --- /dev/null +++ b/src/test/java/de/juplo/facebook/errors/GraphApiExceptionTest.java @@ -0,0 +1,550 @@ +package de.juplo.facebook.errors; + + +import de.juplo.facebook.errors.GraphApiException.Type; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; + + + +/** + * + * @author Kai Moritz + */ +public class GraphApiExceptionTest +{ + private static final Logger LOG = + LoggerFactory.getLogger(GraphApiExceptionTest.class); + + private HttpStatus status = HttpStatus.I_AM_A_TEAPOT; + private HttpHeaders headers = HttpHeaders.EMPTY; + + + @Test + public void testError1() + { + LOG.info("testError1"); + + String str = + "{\n" + + " \"error\":\n" + + " {\n" + + " \"message\": \"An unknown error has occurred.\",\n" + + " \"type\": \"OAuthException\",\n" + + " \"code\": 1\n" + + " }\n" + + "}"; + byte[] message = str.getBytes(); + GraphApiException e = GraphApiException.create (status, headers, message); + + assertTrue(e.getClass().equals(UnknownErrorException.class)); + LOG.debug("{}", e.toString()); + } + + @Test + public void testError2() + { + LOG.info("testError2"); + + + String str = + "{\n" + + " \"error\":\n" + + " {\n" + + " \"message\": \"An unexpected error has occurred. Please retry your request later.\",\n" + + " \"type\": \"OAuthException\",\n" + + " \"code\": 2\n" + + " }\n" + + "}"; + byte[] message = str.getBytes(); + GraphApiException e = GraphApiException.create (status, headers, message); + + assertTrue(e.getClass().equals(UnexpectedErrorException.class)); + LOG.debug("{}", e.toString()); + assertEquals(new Integer(2), e.getCode()); + assertEquals("An unexpected error has occurred. Please retry your request later.", e.getMessage()); + assertEquals(Type.OAuthException, e.getType()); + } + + @Test + public void testError4() + { + LOG.info("testError4"); + + + String str = + "{\n" + + " \"error\": {\n" + + " \"code\": 4, \n" + + " \"fbtrace_id\": \"HZRM6BTMu+D\", \n" + + " \"is_transient\": true, \n" + + " \"message\": \"(#4) Application request limit reached\", \n" + + " \"type\": \"OAuthException\"\n" + + " }\n" + + "}\n"; + byte[] message = str.getBytes(); + GraphApiException e = GraphApiException.create (status, headers, message); + + assertTrue(e.getClass().equals(ApplicationRequestLimitReachedException.class)); + LOG.debug("{}", e.toString()); + assertEquals(new Integer(4), e.getCode()); + assertEquals("(#4) Application request limit reached", e.getMessage()); + assertEquals(Type.OAuthException, e.getType()); + } + + @Test + public void testError12() + { + LOG.info("testError12"); + + + String str = + "{\n" + + " \"error\":\n" + + " {\n" + + " \"message\": \"(#12) location field is deprecated for versions v2.5 and higher\",\n" + + " \"type\": \"OAuthException\",\n" + + " \"code\": 12\n," + + " \"fbtrace_id\":\"BoxCYne7GrL\"\n" + + " }\n" + + "}"; + byte[] message = str.getBytes(); + GraphApiException e = GraphApiException.create (status, headers, message); + + assertTrue(e.getClass().equals(DeprecatedException.class)); + LOG.debug("{}", e.toString()); + assertEquals(new Integer(12), e.getCode()); + assertEquals("(#12) location field is deprecated for versions v2.5 and higher", e.getMessage()); + assertEquals(Type.OAuthException, e.getType()); + } + + @Test + public void testError21() + { + LOG.info("testError21"); + + + String str = + "{\n" + + " \"error\":\n" + + " {\n" + + " \"message\": \"(#21) Page ID 590408587650316 was migrated to page ID 1421620791415603. Please update your API calls to the new ID\",\n" + + " \"type\": \"OAuthException\",\n" + + " \"code\": 21\n" + + " }\n" + + "}"; + byte[] message = str.getBytes(); + GraphApiException e = GraphApiException.create (status, headers, message); + + assertTrue(e.getClass().equals(PageMigratedException.class)); + LOG.debug("{}", e.toString()); + assertEquals(new Integer(21), e.getCode()); + assertEquals("(#21) Page ID 590408587650316 was migrated to page ID 1421620791415603. Please update your API calls to the new ID", e.getMessage()); + assertEquals(Type.OAuthException, e.getType()); + } + + @Test + public void testError100() + { + LOG.info("testError100"); + + + String str = + "{\n" + + " \"error\":\n" + + " {\n" + + " \"message\": \"Unsupported get request.\",\n" + + " \"type\": \"GraphMethodException\",\n" + + " \"code\": 100\n" + + " }\n" + + "}"; + byte[] message = str.getBytes(); + GraphApiException e = GraphApiException.create (status, headers, message); + + + assertTrue(e.getClass().equals(UnsupportedGetRequestException.class)); + LOG.debug("{}", e.toString()); + assertEquals(new Integer(100), e.getCode()); + assertEquals("Unsupported get request.", e.getMessage()); + assertEquals(Type.GraphMethodException, e.getType()); + } + + @Test + public void testError102() + { + LOG.info("testError102"); + + String str ="{\"error\":{\"message\":\"A user access token is required to request this resource.\",\"type\":\"OAuthException\",\"code\":102,\"fbtrace_id\":\"DhdMyf23Ki7\"}}"; + byte[] message = str.getBytes(); + GraphApiException e = GraphApiException.create (status, headers, message); + + + assertTrue(e.getClass().equals(UserAccessTokenRequiredException.class)); + LOG.debug("{}", e.toString()); + } + + @Test + public void testError104() + { + LOG.info("testError104"); + + String str ="{\"error\":{\"message\":\"An access token is required to request this resource.\",\"type\":\"OAuthException\",\"code\":104,\"fbtrace_id\":\"E2Jjkj5++LL\"}}"; + byte[] message = str.getBytes(); + GraphApiException e = GraphApiException.create (status, headers, message); + + assertTrue(e.getClass().equals(AccessTokenRequiredException.class)); + LOG.debug("{}", e.toString()); + } + + @Test + public void testError190() + { + LOG.info("testError190"); + + String str ="{\"error\":{\"message\":\"Bad signature\",\"type\":\"OAuthException\",\"code\":190,\"fbtrace_id\":\"Ay2OYQrINbXOCfQpBvoxDIw\"}}"; + byte[] message = str.getBytes(); + GraphApiException e = GraphApiException.create (status, headers, message); + + assertTrue(e.getClass().equals(AccessTokenExpiredException.class)); + LOG.debug("{}", e.toString()); + } + + @Test + public void testError200() + { + LOG.info("testError200"); + + String str ="{\n" + + " \"error\": {\n" + + " \"message\": \"(#200) The user hasn't authorized the application to perform this action\",\n" + + " \"type\": \"OAuthException\",\n" + + " \"code\": 200\n" + + " }\n" + + "}"; + byte[] message = str.getBytes(); + GraphApiException e = GraphApiException.create (status, headers, message); + + assertTrue(e.getClass().equals(ApplicationNotAuthorizedByUserException.class)); + LOG.debug("{}", e.toString()); + } + + @Test + public void testError613() + { + LOG.info("testError613"); + + + String str = + "{\n" + + " \"error\":\n" + + " {\n" + + " \"message\": \"(#613) Calls to stream have exceeded the rate of 600 calls per 600 seconds.\",\n" + + " \"type\": \"OAuthException\",\n" + + " \"code\": 613\n" + + " }\n" + + "}"; + byte[] message = str.getBytes(); + GraphApiException e = GraphApiException.create (status, headers, message); + + assertTrue(e.getClass().equals(RateLimitExceededException.class)); + LOG.debug("{}", e.toString()); + assertEquals(new Integer(613), e.getCode()); + assertEquals("(#613) Calls to stream have exceeded the rate of 600 calls per 600 seconds.", e.getMessage()); + assertEquals(Type.OAuthException, e.getType()); + } + + @Test + public void testError2200() + { + LOG.info("testError2200"); + + String str ="{\"error\":{\"message\":\"(#2200) callback verification failed: \",\"type\":\"OAuthException\",\"code\":2200,\"fbtrace_id\":\"ESLjoZKvPXg\"}}"; + byte[] message = str.getBytes(); + GraphApiException e = GraphApiException.create (status, headers, message); + + assertTrue(e.getClass().equals(CallbackVerificationFailedException.class)); + LOG.debug("{}", e.toString()); + } + + @Test + public void testUnmappedError() + { + LOG.info("testUnmappedError"); + + + String str = + "{\n" + + " \"error\":\n" + + " {\n" + + " \"message\": \"This error does not exist.\",\n" + + " \"type\": \"NonexistentTypeException\",\n" + + " \"code\": 999999999\n" + + " }\n" + + "}"; + byte[] message = str.getBytes(); + GraphApiException e = GraphApiException.create (status, headers, message); + + assertTrue(e.getClass().equals(UnmappedErrorException.class)); + LOG.debug("{}", e.toString()); + assertEquals(new Integer(999999999), e.getCode()); + assertEquals("This error does not exist.", e.getMessage()); + try + { + Type type = e.getType(); + LOG.error("unknown type: {}", type); + fail("unmapped type was resolved by enum: " + type); + } + catch (IllegalArgumentException ee) {} + } + + @Test + public void testUnmappedErrors() + { + LOG.info("testUnmappedErrors"); + + String str; + byte[] message; + GraphApiException e; + + + str = + "{\n" + + " \"error\":\n" + + " {\n" + + " \"message\": null,\n" + + " \"type\": \"WhateverTypeException\",\n" + + " \"code\": 999999999\n" + + " }\n" + + "}"; + message = str.getBytes(); + e = GraphApiException.create (status, headers, message); + + assertTrue(e.getClass().equals(UnmappedErrorException.class)); + LOG.debug("{}", e.toString()); + assertNull(e.getMessage()); + try + { + Type type = e.getType(); + LOG.error("unknown type: {}", type); + fail("unmapped type was resolved by enum: " + type); + } + catch (IllegalArgumentException ee) {} + assertEquals(new Integer(999999999), e.getCode()); + assertNull(e.getSubCode()); + assertNull(e.getUserTitle()); + assertNull(e.getUserMessage()); + assertNull(e.getTraceId()); + + + str = + "{\n" + + " \"error\":\n" + + " {\n" + + " \"type\": \"WhateverTypeException\",\n" + + " \"code\": 999999999\n" + + " }\n" + + "}"; + message = str.getBytes(); + e = GraphApiException.create (status, headers, message); + + assertTrue(e.getClass().equals(UnmappedErrorException.class)); + LOG.debug("{}", e.toString()); + assertNull(e.getMessage()); + try + { + Type type = e.getType(); + LOG.error("unknown type: {}", type); + fail("unmapped type was resolved by enum: " + type); + } + catch (IllegalArgumentException ee) {} + assertEquals(new Integer(999999999), e.getCode()); + assertNull(e.getSubCode()); + assertNull(e.getUserTitle()); + assertNull(e.getUserMessage()); + assertNull(e.getTraceId()); + + + str = + "{\n" + + " \"error\":\n" + + " {\n" + + " \"message\": \"An unmapped Graph-API-Exception.\",\n" + + " \"type\": null,\n" + + " \"code\": 999999999\n" + + " }\n" + + "}"; + message = str.getBytes(); + e = GraphApiException.create (status, headers, message); + + assertTrue(e.getClass().equals(UnmappedErrorException.class)); + LOG.debug("{}", e.toString()); + assertEquals("An unmapped Graph-API-Exception.", e.getMessage()); + assertNull(e.getType()); + assertEquals(new Integer(999999999), e.getCode()); + assertNull(e.getSubCode()); + assertNull(e.getUserTitle()); + assertNull(e.getUserMessage()); + assertNull(e.getTraceId()); + + + str = + "{\n" + + " \"error\":\n" + + " {\n" + + " \"message\": \"An unmapped Graph-API-Exception.\",\n" + + " \"code\": 999999999\n" + + " }\n" + + "}"; + message = str.getBytes(); + e = GraphApiException.create (status, headers, message); + + assertTrue(e.getClass().equals(UnmappedErrorException.class)); + LOG.debug("{}", e.toString()); + assertEquals("An unmapped Graph-API-Exception.", e.getMessage()); + assertNull(e.getType()); + assertEquals(new Integer(999999999), e.getCode()); + assertNull(e.getSubCode()); + assertNull(e.getUserTitle()); + assertNull(e.getUserMessage()); + assertNull(e.getTraceId()); + } + + @Test + public void testInvlalidErrors() + { + LOG.info("testInvalidErrors"); + + String str; + byte[] message; + GraphApiException e; + + + str = + "{\n" + + " \"error\":\n" + + " {\n" + + " \"message\": \"Not a Graph-Api-Exception.\",\n" + + " \"type\": \"Whatever\",\n" + + " \"code\": \"some string\"\n" + + " }\n" + + "}"; + message = str.getBytes(); + e = GraphApiException.create (status, headers, message); + assertTrue(e.getClass().equals(ErrorResponseParsingErrorException.class)); + LOG.debug("{}", e.toString()); + + + str = + "{\n" + + " \"error\":\n" + + " {\n" + + " \"message\": \"Not a Graph-Api-Exception.\",\n" + + " \"type\": \"Whatever\",\n" + + " \"code\": 9.9\n" + + " }\n" + + "}"; + message = str.getBytes(); + e = GraphApiException.create (status, headers, message); + assertTrue(e.getClass().equals(ErrorResponseParsingErrorException.class)); + LOG.debug("{}", e.toString()); + + + str = + "{\n" + + " \"error\":\n" + + " {\n" + + " \"message\": \"Not a Graph-Api-Exception.\",\n" + + " \"type\": \"Whatever\",\n" + + " \"code\": null\n" + + " }\n" + + "}"; + message = str.getBytes(); + e = GraphApiException.create (status, headers, message); + assertTrue(e.getClass().equals(ErrorResponseParsingErrorException.class)); + LOG.debug("{}", e.toString()); + + + str = + "{\n" + + " \"error\":\n" + + " {\n" + + " \"message\": \"Not a Graph-Api-Exception.\",\n" + + " \"type\": \"Whatever\"\n" + + " }\n" + + "}"; + message = str.getBytes(); + e = GraphApiException.create (status, headers, message); + assertTrue(e.getClass().equals(ErrorResponseParsingErrorException.class)); + LOG.debug("{}", e.toString()); + + + str ="{\"error\":{\"message\":null}}"; + message = str.getBytes(); + e = GraphApiException.create (status, headers, message); + assertTrue(e.getClass().equals(ErrorResponseParsingErrorException.class)); + LOG.debug("{}", e.toString()); + + + str ="{\"error\":{\"type\":null}}"; + message = str.getBytes(); + e = GraphApiException.create (status, headers, message); + assertTrue(e.getClass().equals(ErrorResponseParsingErrorException.class)); + LOG.debug("{}", e.toString()); + + + str ="{\"error\":{\"code\":null}}"; + message = str.getBytes(); + e = GraphApiException.create (status, headers, message); + assertTrue(e.getClass().equals(ErrorResponseParsingErrorException.class)); + LOG.debug("{}", e.toString()); + + + str ="{\"error\":{}}"; + message = str.getBytes(); + e = GraphApiException.create (status, headers, message); + assertTrue(e.getClass().equals(ErrorResponseParsingErrorException.class)); + LOG.debug("{}", e.toString()); + + + str ="{\"error\":\"some message\"}"; + message = str.getBytes(); + e = GraphApiException.create (status, headers, message); + assertTrue(e.getClass().equals(ErrorResponseParsingErrorException.class)); + LOG.debug("{}", e.toString()); + + + str ="{\"error\":null}"; + message = str.getBytes(); + e = GraphApiException.create (status, headers, message); + assertTrue(e.getClass().equals(ErrorResponseParsingErrorException.class)); + LOG.debug("{}", e.toString()); + + + str ="{\"some filed\":\"some message\"}"; + message = str.getBytes(); + e = GraphApiException.create (status, headers, message); + assertTrue(e.getClass().equals(ErrorResponseParsingErrorException.class)); + LOG.debug("{}", e.toString()); + + + str ="{}"; + message = str.getBytes(); + e = GraphApiException.create (status, headers, message); + assertTrue(e.getClass().equals(ErrorResponseParsingErrorException.class)); + LOG.debug("{}", e.toString()); + + + str =""; + message = str.getBytes(); + e = GraphApiException.create (status, headers, message); + assertTrue(e.getClass().equals(ErrorResponseParsingErrorException.class)); + LOG.debug("{}", e.toString()); + } +} -- 2.20.1