1 package de.juplo.facebook.errors;
4 import de.juplo.facebook.errors.GraphApiException.Type;
8 import javax.annotation.Resource;
9 import static org.junit.Assert.assertEquals;
10 import static org.junit.Assert.assertNull;
11 import static org.junit.Assert.fail;
12 import org.junit.Before;
13 import org.junit.Test;
14 import org.junit.runner.RunWith;
15 import org.slf4j.Logger;
16 import org.slf4j.LoggerFactory;
17 import org.springframework.http.HttpStatus;
18 import org.springframework.security.access.AccessDeniedException;
19 import org.springframework.security.oauth2.client.OAuth2RestTemplate;
20 import org.springframework.security.oauth2.client.http.OAuth2ErrorHandler;
21 import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
22 import org.springframework.security.oauth2.client.resource.UserApprovalRequiredException;
23 import org.springframework.security.oauth2.client.resource.UserRedirectRequiredException;
24 import org.springframework.security.oauth2.client.token.AccessTokenProvider;
25 import org.springframework.security.oauth2.client.token.AccessTokenRequest;
26 import org.springframework.security.oauth2.common.OAuth2AccessToken;
27 import static org.springframework.security.oauth2.common.OAuth2AccessToken.OAUTH2_TYPE;
28 import org.springframework.security.oauth2.common.OAuth2RefreshToken;
29 import org.springframework.test.context.ContextConfiguration;
30 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
31 import org.springframework.web.client.HttpClientErrorException;
39 @RunWith(SpringJUnit4ClassRunner.class)
40 @ContextConfiguration(
42 "classpath:/spring/test-facebook-error-handler.xml"
44 public class GraphApiErrorHandlerTest
46 private static final Logger log =
47 LoggerFactory.getLogger(GraphApiErrorHandlerTest.class);
50 private OAuth2RestTemplate clientTemplate;
52 private MockClientHttpRequestFactory requestFactory;
56 public void testError1()
58 log.info("testError1");
61 requestFactory.setBody(
65 " \"message\": \"An unknown error has occurred.\",\n" +
66 " \"type\": \"OAuthException\",\n" +
73 clientTemplate.getForObject("ANY", SOME.class);
74 fail("The expected exception was not thrown");
76 catch(UnknownErrorException e)
78 log.debug("{}", e.toString());
79 assertEquals("invalid_request", e.getOAuth2ErrorCode());
80 assertEquals(new Integer(1), e.getCode());
81 assertEquals("An unknown error has occurred.", e.getMessage());
82 assertEquals(Type.OAuthException, e.getType());
87 public void testError2()
89 log.info("testError2");
92 requestFactory.setBody(
96 " \"message\": \"An unexpected error has occurred. Please retry your request later.\",\n" +
97 " \"type\": \"OAuthException\",\n" +
104 clientTemplate.getForObject("ANY", SOME.class);
105 fail("The expected exception was not thrown");
107 catch(UnexpectedErrorException e)
109 log.debug("{}", e.toString());
110 assertEquals("invalid_request", e.getOAuth2ErrorCode());
111 assertEquals(new Integer(2), e.getCode());
112 assertEquals("An unexpected error has occurred. Please retry your request later.", e.getMessage());
113 assertEquals(Type.OAuthException, e.getType());
118 public void testError21()
120 log.info("testError21");
123 requestFactory.setBody(
127 " \"message\": \"(#21) Page ID 590408587650316 was migrated to page ID 1421620791415603. Please update your API calls to the new ID\",\n" +
128 " \"type\": \"OAuthException\",\n" +
135 clientTemplate.getForObject("ANY", SOME.class);
136 fail("The expected exception was not thrown");
138 catch(PageMigratedException e)
140 log.debug("{}", e.toString());
141 assertEquals("invalid_request", e.getOAuth2ErrorCode());
142 assertEquals(new Integer(21), e.getCode());
143 assertEquals("(#21) Page ID 590408587650316 was migrated to page ID 1421620791415603. Please update your API calls to the new ID", e.getMessage());
144 assertEquals(Type.OAuthException, e.getType());
149 public void testError100()
151 log.info("testError100");
154 requestFactory.setBody(
158 " \"message\": \"Unsupported get request.\",\n" +
159 " \"type\": \"GraphMethodException\",\n" +
166 clientTemplate.getForObject("ANY", SOME.class);
167 fail("The expected exception was not thrown");
169 catch(UnsupportedGetRequestException e)
171 log.debug("{}", e.toString());
172 assertEquals("invalid_request", e.getOAuth2ErrorCode());
173 assertEquals(new Integer(100), e.getCode());
174 assertEquals("Unsupported get request.", e.getMessage());
175 assertEquals(Type.GraphMethodException, e.getType());
180 public void testError102()
182 log.info("testError102");
184 requestFactory.setBody("{\"error\":{\"message\":\"A user access token is required to request this resource.\",\"type\":\"OAuthException\",\"code\":102,\"fbtrace_id\":\"DhdMyf23Ki7\"}}");
188 clientTemplate.getForObject("ANY", SOME.class);
189 fail("The expected exception was not thrown");
191 catch(UserAccessTokenRequiredException e)
193 log.debug("{}", e.toString());
194 assertEquals("invalid_request", e.getOAuth2ErrorCode());
195 assertEquals(new Integer(102), e.getCode());
196 assertEquals("A user access token is required to request this resource.", e.getMessage());
197 assertEquals(Type.OAuthException, e.getType());
198 assertEquals("DhdMyf23Ki7", e.getTraceId());
203 public void testError104()
205 log.info("testError104");
207 requestFactory.setBody("{\"error\":{\"message\":\"An access token is required to request this resource.\",\"type\":\"OAuthException\",\"code\":104,\"fbtrace_id\":\"E2Jjkj5++LL\"}}");
211 clientTemplate.getForObject("ANY", SOME.class);
212 fail("The expected exception was not thrown");
214 catch(AccessTokenRequiredException e)
216 log.debug("{}", e.toString());
217 assertEquals("invalid_request", e.getOAuth2ErrorCode());
218 assertEquals(new Integer(104), e.getCode());
219 assertEquals("An access token is required to request this resource.", e.getMessage());
220 assertEquals(Type.OAuthException, e.getType());
221 assertEquals("E2Jjkj5++LL", e.getTraceId());
226 public void testError613()
228 log.info("testError613");
231 requestFactory.setBody(
235 " \"message\": \"(#613) Calls to stream have exceeded the rate of 600 calls per 600 seconds.\",\n" +
236 " \"type\": \"OAuthException\",\n" +
243 clientTemplate.getForObject("ANY", SOME.class);
244 fail("The expected exception was not thrown");
246 catch(RateExceededException e)
248 log.debug("{}", e.toString());
249 assertEquals("invalid_request", e.getOAuth2ErrorCode());
250 assertEquals(new Integer(613), e.getCode());
251 assertEquals("(#613) Calls to stream have exceeded the rate of 600 calls per 600 seconds.", e.getMessage());
252 assertEquals(Type.OAuthException, e.getType());
257 public void testError2200()
259 requestFactory.setBody("{\"error\":{\"message\":\"(#2200) callback verification failed: \",\"type\":\"OAuthException\",\"code\":2200,\"fbtrace_id\":\"ESLjoZKvPXg\"}}");
263 clientTemplate.getForObject("ANY", SOME.class);
264 fail("The expected exception was not thrown");
266 catch(CallbackVerificationFailedException e)
268 log.debug("{}", e.toString());
269 assertEquals("invalid_request", e.getOAuth2ErrorCode());
270 assertEquals(new Integer(2200), e.getCode());
271 assertEquals("(#2200) callback verification failed: ", e.getMessage());
272 assertEquals(Type.OAuthException, e.getType());
273 assertEquals("ESLjoZKvPXg", e.getTraceId());
278 public void testUnmappedError()
280 log.info("testUnmappedError");
283 requestFactory.setBody(
287 " \"message\": \"This error does not exist.\",\n" +
288 " \"type\": \"NonexistentTypeException\",\n" +
289 " \"code\": 999999999\n" +
295 clientTemplate.getForObject("ANY", SOME.class);
296 fail("The expected exception was not thrown");
298 catch(GraphApiException e)
300 log.debug("{}", e.toString());
301 assertEquals("invalid_request", e.getOAuth2ErrorCode());
302 assertEquals(new Integer(999999999), e.getCode());
303 assertEquals("This error does not exist.", e.getMessage());
306 Type type = e.getType();
307 log.error("unknown type: {}", type);
308 fail("unmapped type was resolved by enum: " + type);
310 catch (IllegalArgumentException ee) {}
315 public void testUnmappedErrors()
317 log.info("testUnmappedErrors");
320 requestFactory.setBody(
324 " \"message\": null,\n" +
325 " \"type\": \"WhateverTypeException\",\n" +
326 " \"code\": 999999999\n" +
332 clientTemplate.getForObject("ANY", SOME.class);
333 fail("The expected exception was not thrown");
335 catch(UnmappedErrorException e)
337 log.debug("{}", e.toString());
338 assertNull(e.getMessage());
341 Type type = e.getType();
342 log.error("unknown type: {}", type);
343 fail("unmapped type was resolved by enum: " + type);
345 catch (IllegalArgumentException ee) {}
346 assertEquals(new Integer(999999999), e.getCode());
347 assertNull(e.getSubCode());
348 assertNull(e.getUserTitle());
349 assertNull(e.getUserMessage());
350 assertNull(e.getTraceId());
354 fail("A wrong exception was thrown: " + e.toString());
358 requestFactory.setBody(
362 " \"type\": \"WhateverTypeException\",\n" +
363 " \"code\": 999999999\n" +
369 clientTemplate.getForObject("ANY", SOME.class);
370 fail("The expected exception was not thrown");
372 catch(UnmappedErrorException e)
374 log.debug("{}", e.toString());
375 assertNull(e.getMessage());
378 Type type = e.getType();
379 log.error("unknown type: {}", type);
380 fail("unmapped type was resolved by enum: " + type);
382 catch (IllegalArgumentException ee) {}
383 assertEquals(new Integer(999999999), e.getCode());
384 assertNull(e.getSubCode());
385 assertNull(e.getUserTitle());
386 assertNull(e.getUserMessage());
387 assertNull(e.getTraceId());
391 fail("A wrong exception was thrown: " + e.toString());
395 requestFactory.setBody(
399 " \"message\": \"An unmapped Graph-API-Exception.\",\n" +
400 " \"type\": null,\n" +
401 " \"code\": 999999999\n" +
407 clientTemplate.getForObject("ANY", SOME.class);
408 fail("The expected exception was not thrown");
410 catch(UnmappedErrorException e)
412 log.debug("{}", e.toString());
413 assertEquals("An unmapped Graph-API-Exception.", e.getMessage());
414 assertNull(e.getType());
415 assertEquals(new Integer(999999999), e.getCode());
416 assertNull(e.getSubCode());
417 assertNull(e.getUserTitle());
418 assertNull(e.getUserMessage());
419 assertNull(e.getTraceId());
423 fail("A wrong exception was thrown: " + e.toString());
427 requestFactory.setBody(
431 " \"message\": \"An unmapped Graph-API-Exception.\",\n" +
432 " \"code\": 999999999\n" +
438 clientTemplate.getForObject("ANY", SOME.class);
439 fail("The expected exception was not thrown");
441 catch(UnmappedErrorException e)
443 log.debug("{}", e.toString());
444 assertEquals("An unmapped Graph-API-Exception.", e.getMessage());
445 assertNull(e.getType());
446 assertEquals(new Integer(999999999), e.getCode());
447 assertNull(e.getSubCode());
448 assertNull(e.getUserTitle());
449 assertNull(e.getUserMessage());
450 assertNull(e.getTraceId());
454 fail("A wrong exception was thrown: " + e.toString());
459 public void testInvlalidErrors()
461 log.info("testInvalidErrors");
464 requestFactory.setBody(
468 " \"message\": \"Not a Graph-Api-Exception.\",\n" +
469 " \"type\": \"Whatever\",\n" +
470 " \"code\": \"some string\"\n" +
476 clientTemplate.getForObject("ANY", SOME.class);
477 fail("The expected exception was not thrown");
479 catch(HttpClientErrorException e)
481 log.debug("{}", e.toString());
485 fail("A wrong exception was thrown: " + e.toString());
489 requestFactory.setBody(
493 " \"message\": \"Not a Graph-Api-Exception.\",\n" +
494 " \"type\": \"Whatever\",\n" +
501 clientTemplate.getForObject("ANY", SOME.class);
502 fail("The expected exception was not thrown");
504 catch(HttpClientErrorException e)
506 log.debug("{}", e.toString());
510 fail("A wrong exception was thrown: " + e.toString());
514 requestFactory.setBody(
518 " \"message\": \"Not a Graph-Api-Exception.\",\n" +
519 " \"type\": \"Whatever\",\n" +
520 " \"code\": null\n" +
526 clientTemplate.getForObject("ANY", SOME.class);
527 fail("The expected exception was not thrown");
529 catch(HttpClientErrorException e)
531 log.debug("{}", e.toString());
535 fail("A wrong exception was thrown: " + e.toString());
539 requestFactory.setBody(
543 " \"message\": \"Not a Graph-Api-Exception.\",\n" +
544 " \"type\": \"Whatever\"\n" +
550 clientTemplate.getForObject("ANY", SOME.class);
551 fail("The expected exception was not thrown");
553 catch(HttpClientErrorException e)
555 log.debug("{}", e.toString());
559 fail("A wrong exception was thrown: " + e.toString());
563 requestFactory.setBody("{\"error\":{\"message\":null}}");
567 clientTemplate.getForObject("ANY", SOME.class);
568 fail("The expected exception was not thrown");
570 catch(HttpClientErrorException e)
572 log.debug("{}", e.toString());
576 fail("A wrong exception was thrown: " + e.toString());
580 requestFactory.setBody("{\"error\":{\"type\":null}}");
584 clientTemplate.getForObject("ANY", SOME.class);
585 fail("The expected exception was not thrown");
587 catch(HttpClientErrorException e)
589 log.debug("{}", e.toString());
593 fail("A wrong exception was thrown: " + e.toString());
597 requestFactory.setBody("{\"error\":{\"code\":null}}");
601 clientTemplate.getForObject("ANY", SOME.class);
602 fail("The expected exception was not thrown");
604 catch(HttpClientErrorException e)
606 log.debug("{}", e.toString());
610 fail("A wrong exception was thrown: " + e.toString());
614 requestFactory.setBody("{\"error\":{}}");
618 clientTemplate.getForObject("ANY", SOME.class);
619 fail("The expected exception was not thrown");
621 catch(HttpClientErrorException e)
623 log.debug("{}", e.toString());
627 fail("A wrong exception was thrown: " + e.toString());
631 requestFactory.setBody("{\"error\":\"some message\"}");
635 clientTemplate.getForObject("ANY", SOME.class);
636 fail("The expected exception was not thrown");
638 catch(HttpClientErrorException e)
640 log.debug("{}", e.toString());
644 fail("A wrong exception was thrown: " + e.toString());
648 requestFactory.setBody("{\"error\":null}");
652 clientTemplate.getForObject("ANY", SOME.class);
653 fail("The expected exception was not thrown");
655 catch(HttpClientErrorException e)
657 log.debug("{}", e.toString());
661 fail("A wrong exception was thrown: " + e.toString());
665 requestFactory.setBody("{\"some filed\":\"some message\"}");
669 clientTemplate.getForObject("ANY", SOME.class);
670 fail("The expected exception was not thrown");
672 catch(HttpClientErrorException e)
674 log.debug("{}", e.toString());
678 fail("A wrong exception was thrown: " + e.toString());
682 requestFactory.setBody("{}");
686 clientTemplate.getForObject("ANY", SOME.class);
687 fail("The expected exception was not thrown");
689 catch(HttpClientErrorException e)
691 log.debug("{}", e.toString());
695 fail("A wrong exception was thrown: " + e.toString());
699 requestFactory.setBody("");
703 clientTemplate.getForObject("ANY", SOME.class);
704 fail("The expected exception was not thrown");
706 catch(HttpClientErrorException e)
708 log.debug("{}", e.toString());
712 fail("A wrong exception was thrown: " + e.toString());
720 requestFactory = new MockClientHttpRequestFactory();
721 requestFactory.setStatus(HttpStatus.BAD_REQUEST);
722 requestFactory.addHeader("Content-Type", "application/json");
723 clientTemplate.setRequestFactory(requestFactory);
725 clientTemplate.setErrorHandler(
726 new GraphApiErrorHandler(
727 (OAuth2ErrorHandler)clientTemplate.getErrorHandler()
731 clientTemplate.setAccessTokenProvider(new AccessTokenProvider()
734 public OAuth2AccessToken obtainAccessToken(
735 OAuth2ProtectedResourceDetails details,
736 AccessTokenRequest parameters
739 UserRedirectRequiredException,
740 UserApprovalRequiredException,
741 AccessDeniedException
743 return new OAuth2AccessToken() {
746 public Map<String, Object> getAdditionalInformation()
748 throw new UnsupportedOperationException("Not supported yet.");
752 public Set<String> getScope()
754 throw new UnsupportedOperationException("Not supported yet.");
758 public OAuth2RefreshToken getRefreshToken()
760 throw new UnsupportedOperationException("Not supported yet.");
764 public String getTokenType()
770 public boolean isExpired()
776 public Date getExpiration()
778 throw new UnsupportedOperationException("Not supported yet.");
782 public int getExpiresIn()
784 throw new UnsupportedOperationException("Not supported yet.");
788 public String getValue()
796 public boolean supportsResource(OAuth2ProtectedResourceDetails resource)
802 public OAuth2AccessToken refreshAccessToken(
803 OAuth2ProtectedResourceDetails resource,
804 OAuth2RefreshToken refreshToken,
805 AccessTokenRequest request
808 UserRedirectRequiredException
810 throw new UnsupportedOperationException("Not supported yet.");
814 public boolean supportsRefresh(OAuth2ProtectedResourceDetails resource)