1 package de.juplo.facebook.exceptions;
3 import de.juplo.facebook.exceptions.GraphApiException.Type;
7 import javax.annotation.Resource;
8 import static org.junit.Assert.assertEquals;
9 import static org.junit.Assert.assertNull;
10 import static org.junit.Assert.fail;
11 import org.junit.Before;
12 import org.junit.Test;
13 import org.junit.runner.RunWith;
14 import org.slf4j.Logger;
15 import org.slf4j.LoggerFactory;
16 import org.springframework.http.HttpStatus;
17 import org.springframework.security.access.AccessDeniedException;
18 import org.springframework.security.oauth2.client.OAuth2RestTemplate;
19 import org.springframework.security.oauth2.client.http.OAuth2ErrorHandler;
20 import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
21 import org.springframework.security.oauth2.client.resource.UserApprovalRequiredException;
22 import org.springframework.security.oauth2.client.resource.UserRedirectRequiredException;
23 import org.springframework.security.oauth2.client.token.AccessTokenProvider;
24 import org.springframework.security.oauth2.client.token.AccessTokenRequest;
25 import org.springframework.security.oauth2.common.OAuth2AccessToken;
26 import static org.springframework.security.oauth2.common.OAuth2AccessToken.OAUTH2_TYPE;
27 import org.springframework.security.oauth2.common.OAuth2RefreshToken;
28 import org.springframework.test.context.ContextConfiguration;
29 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
30 import org.springframework.web.client.HttpClientErrorException;
38 @RunWith(SpringJUnit4ClassRunner.class)
39 @ContextConfiguration(
41 "classpath:/spring/test-facebook-error-handler.xml"
43 public class GraphApiErrorHandlerTest
45 private static final Logger log =
46 LoggerFactory.getLogger(GraphApiErrorHandlerTest.class);
49 private OAuth2RestTemplate clientTemplate;
51 private MockClientHttpRequestFactory requestFactory;
55 public void testError1()
57 log.info("testError1");
60 requestFactory.setBody(
64 " \"message\": \"An unknown error has occurred.\",\n" +
65 " \"type\": \"OAuthException\",\n" +
72 clientTemplate.getForObject("ANY", SOME.class);
73 fail("The expected exception was not thrown");
75 catch(UnknownErrorException e)
77 log.debug("{}", e.toString());
78 assertEquals("invalid_request", e.getOAuth2ErrorCode());
79 assertEquals(new Integer(1), e.getCode());
80 assertEquals("An unknown error has occurred.", e.getMessage());
81 assertEquals(Type.OAuthException, e.getType());
86 public void testError2()
88 log.info("testError2");
91 requestFactory.setBody(
95 " \"message\": \"An unexpected error has occurred. Please retry your request later.\",\n" +
96 " \"type\": \"OAuthException\",\n" +
103 clientTemplate.getForObject("ANY", SOME.class);
104 fail("The expected exception was not thrown");
106 catch(UnexpectedErrorException e)
108 log.debug("{}", e.toString());
109 assertEquals("invalid_request", e.getOAuth2ErrorCode());
110 assertEquals(new Integer(2), e.getCode());
111 assertEquals("An unexpected error has occurred. Please retry your request later.", e.getMessage());
112 assertEquals(Type.OAuthException, e.getType());
117 public void testError21()
119 log.info("testError21");
122 requestFactory.setBody(
126 " \"message\": \"(#21) Page ID 590408587650316 was migrated to page ID 1421620791415603. Please update your API calls to the new ID\",\n" +
127 " \"type\": \"OAuthException\",\n" +
134 clientTemplate.getForObject("ANY", SOME.class);
135 fail("The expected exception was not thrown");
137 catch(PageMigratedException e)
139 log.debug("{}", e.toString());
140 assertEquals("invalid_request", e.getOAuth2ErrorCode());
141 assertEquals(new Integer(21), e.getCode());
142 assertEquals("(#21) Page ID 590408587650316 was migrated to page ID 1421620791415603. Please update your API calls to the new ID", e.getMessage());
143 assertEquals(Type.OAuthException, e.getType());
148 public void testError100()
150 log.info("testError100");
153 requestFactory.setBody(
157 " \"message\": \"Unsupported get request.\",\n" +
158 " \"type\": \"GraphMethodException\",\n" +
165 clientTemplate.getForObject("ANY", SOME.class);
166 fail("The expected exception was not thrown");
168 catch(UnsupportedGetRequestException e)
170 log.debug("{}", e.toString());
171 assertEquals("invalid_request", e.getOAuth2ErrorCode());
172 assertEquals(new Integer(100), e.getCode());
173 assertEquals("Unsupported get request.", e.getMessage());
174 assertEquals(Type.GraphMethodException, e.getType());
179 public void testError104()
181 log.info("testError104");
183 requestFactory.setBody("{\"error\":{\"message\":\"An access token is required to request this resource.\",\"type\":\"OAuthException\",\"code\":104,\"fbtrace_id\":\"E2Jjkj5++LL\"}}");
187 clientTemplate.getForObject("ANY", SOME.class);
188 fail("The expected exception was not thrown");
190 catch(AccessTokenRequiredException e)
192 log.debug("{}", e.toString());
193 assertEquals("invalid_request", e.getOAuth2ErrorCode());
194 assertEquals(new Integer(104), e.getCode());
195 assertEquals("An access token is required to request this resource.", e.getMessage());
196 assertEquals(Type.OAuthException, e.getType());
197 assertEquals("E2Jjkj5++LL", e.getTraceId());
202 public void testError613()
204 log.info("testError613");
207 requestFactory.setBody(
211 " \"message\": \"(#613) Calls to stream have exceeded the rate of 600 calls per 600 seconds.\",\n" +
212 " \"type\": \"OAuthException\",\n" +
219 clientTemplate.getForObject("ANY", SOME.class);
220 fail("The expected exception was not thrown");
222 catch(RateExceededException e)
224 log.debug("{}", e.toString());
225 assertEquals("invalid_request", e.getOAuth2ErrorCode());
226 assertEquals(new Integer(613), e.getCode());
227 assertEquals("(#613) Calls to stream have exceeded the rate of 600 calls per 600 seconds.", e.getMessage());
228 assertEquals(Type.OAuthException, e.getType());
233 public void testError2200()
235 requestFactory.setBody("{\"error\":{\"message\":\"(#2200) callback verification failed: \",\"type\":\"OAuthException\",\"code\":2200,\"fbtrace_id\":\"ESLjoZKvPXg\"}}");
239 clientTemplate.getForObject("ANY", SOME.class);
240 fail("The expected exception was not thrown");
242 catch(CallbackVerificationFailedException e)
244 log.debug("{}", e.toString());
245 assertEquals("invalid_request", e.getOAuth2ErrorCode());
246 assertEquals(new Integer(2200), e.getCode());
247 assertEquals("(#2200) callback verification failed: ", e.getMessage());
248 assertEquals(Type.OAuthException, e.getType());
249 assertEquals("ESLjoZKvPXg", e.getTraceId());
254 public void testUnmappedError()
256 log.info("testUnmappedError");
259 requestFactory.setBody(
263 " \"message\": \"This error does not exist.\",\n" +
264 " \"type\": \"NonexistentTypeException\",\n" +
265 " \"code\": 999999999\n" +
271 clientTemplate.getForObject("ANY", SOME.class);
272 fail("The expected exception was not thrown");
274 catch(GraphApiException e)
276 log.debug("{}", e.toString());
277 assertEquals("invalid_request", e.getOAuth2ErrorCode());
278 assertEquals(new Integer(999999999), e.getCode());
279 assertEquals("This error does not exist.", e.getMessage());
282 Type type = e.getType();
283 log.error("unknown type: {}", type);
284 fail("unmapped type was resolved by enum: " + type);
286 catch (IllegalArgumentException ee) {}
291 public void testUnmappedErrors()
293 log.info("testUnmappedErrors");
296 requestFactory.setBody(
300 " \"message\": null,\n" +
301 " \"type\": \"WhateverTypeException\",\n" +
302 " \"code\": 999999999\n" +
308 clientTemplate.getForObject("ANY", SOME.class);
309 fail("The expected exception was not thrown");
311 catch(UnmappedErrorException e)
313 log.debug("{}", e.toString());
314 assertNull(e.getMessage());
317 Type type = e.getType();
318 log.error("unknown type: {}", type);
319 fail("unmapped type was resolved by enum: " + type);
321 catch (IllegalArgumentException ee) {}
322 assertEquals(new Integer(999999999), e.getCode());
323 assertNull(e.getSubCode());
324 assertNull(e.getUserTitle());
325 assertNull(e.getUserMessage());
326 assertNull(e.getTraceId());
330 fail("A wrong exception was thrown: " + e.toString());
334 requestFactory.setBody(
338 " \"type\": \"WhateverTypeException\",\n" +
339 " \"code\": 999999999\n" +
345 clientTemplate.getForObject("ANY", SOME.class);
346 fail("The expected exception was not thrown");
348 catch(UnmappedErrorException e)
350 log.debug("{}", e.toString());
351 assertNull(e.getMessage());
354 Type type = e.getType();
355 log.error("unknown type: {}", type);
356 fail("unmapped type was resolved by enum: " + type);
358 catch (IllegalArgumentException ee) {}
359 assertEquals(new Integer(999999999), e.getCode());
360 assertNull(e.getSubCode());
361 assertNull(e.getUserTitle());
362 assertNull(e.getUserMessage());
363 assertNull(e.getTraceId());
367 fail("A wrong exception was thrown: " + e.toString());
371 requestFactory.setBody(
375 " \"message\": \"An unmapped Graph-API-Exception.\",\n" +
376 " \"type\": null,\n" +
377 " \"code\": 999999999\n" +
383 clientTemplate.getForObject("ANY", SOME.class);
384 fail("The expected exception was not thrown");
386 catch(UnmappedErrorException e)
388 log.debug("{}", e.toString());
389 assertEquals("An unmapped Graph-API-Exception.", e.getMessage());
390 assertNull(e.getType());
391 assertEquals(new Integer(999999999), e.getCode());
392 assertNull(e.getSubCode());
393 assertNull(e.getUserTitle());
394 assertNull(e.getUserMessage());
395 assertNull(e.getTraceId());
399 fail("A wrong exception was thrown: " + e.toString());
403 requestFactory.setBody(
407 " \"message\": \"An unmapped Graph-API-Exception.\",\n" +
408 " \"code\": 999999999\n" +
414 clientTemplate.getForObject("ANY", SOME.class);
415 fail("The expected exception was not thrown");
417 catch(UnmappedErrorException e)
419 log.debug("{}", e.toString());
420 assertEquals("An unmapped Graph-API-Exception.", e.getMessage());
421 assertNull(e.getType());
422 assertEquals(new Integer(999999999), e.getCode());
423 assertNull(e.getSubCode());
424 assertNull(e.getUserTitle());
425 assertNull(e.getUserMessage());
426 assertNull(e.getTraceId());
430 fail("A wrong exception was thrown: " + e.toString());
435 public void testInvlalidErrors()
437 log.info("testInvalidErrors");
440 requestFactory.setBody(
444 " \"message\": \"Not a Graph-Api-Exception.\",\n" +
445 " \"type\": \"Whatever\",\n" +
446 " \"code\": \"some string\"\n" +
452 clientTemplate.getForObject("ANY", SOME.class);
453 fail("The expected exception was not thrown");
455 catch(HttpClientErrorException e)
457 log.debug("{}", e.toString());
461 fail("A wrong exception was thrown: " + e.toString());
465 requestFactory.setBody(
469 " \"message\": \"Not a Graph-Api-Exception.\",\n" +
470 " \"type\": \"Whatever\",\n" +
477 clientTemplate.getForObject("ANY", SOME.class);
478 fail("The expected exception was not thrown");
480 catch(HttpClientErrorException e)
482 log.debug("{}", e.toString());
486 fail("A wrong exception was thrown: " + e.toString());
490 requestFactory.setBody(
494 " \"message\": \"Not a Graph-Api-Exception.\",\n" +
495 " \"type\": \"Whatever\",\n" +
496 " \"code\": null\n" +
502 clientTemplate.getForObject("ANY", SOME.class);
503 fail("The expected exception was not thrown");
505 catch(HttpClientErrorException e)
507 log.debug("{}", e.toString());
511 fail("A wrong exception was thrown: " + e.toString());
515 requestFactory.setBody(
519 " \"message\": \"Not a Graph-Api-Exception.\",\n" +
520 " \"type\": \"Whatever\"\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("{\"error\":{\"message\":null}}");
543 clientTemplate.getForObject("ANY", SOME.class);
544 fail("The expected exception was not thrown");
546 catch(HttpClientErrorException e)
548 log.debug("{}", e.toString());
552 fail("A wrong exception was thrown: " + e.toString());
556 requestFactory.setBody("{\"error\":{\"type\":null}}");
560 clientTemplate.getForObject("ANY", SOME.class);
561 fail("The expected exception was not thrown");
563 catch(HttpClientErrorException e)
565 log.debug("{}", e.toString());
569 fail("A wrong exception was thrown: " + e.toString());
573 requestFactory.setBody("{\"error\":{\"code\":null}}");
577 clientTemplate.getForObject("ANY", SOME.class);
578 fail("The expected exception was not thrown");
580 catch(HttpClientErrorException e)
582 log.debug("{}", e.toString());
586 fail("A wrong exception was thrown: " + e.toString());
590 requestFactory.setBody("{\"error\":{}}");
594 clientTemplate.getForObject("ANY", SOME.class);
595 fail("The expected exception was not thrown");
597 catch(HttpClientErrorException e)
599 log.debug("{}", e.toString());
603 fail("A wrong exception was thrown: " + e.toString());
607 requestFactory.setBody("{\"error\":\"some message\"}");
611 clientTemplate.getForObject("ANY", SOME.class);
612 fail("The expected exception was not thrown");
614 catch(HttpClientErrorException e)
616 log.debug("{}", e.toString());
620 fail("A wrong exception was thrown: " + e.toString());
624 requestFactory.setBody("{\"error\":null}");
628 clientTemplate.getForObject("ANY", SOME.class);
629 fail("The expected exception was not thrown");
631 catch(HttpClientErrorException e)
633 log.debug("{}", e.toString());
637 fail("A wrong exception was thrown: " + e.toString());
641 requestFactory.setBody("{\"some filed\":\"some message\"}");
645 clientTemplate.getForObject("ANY", SOME.class);
646 fail("The expected exception was not thrown");
648 catch(HttpClientErrorException e)
650 log.debug("{}", e.toString());
654 fail("A wrong exception was thrown: " + e.toString());
658 requestFactory.setBody("{}");
662 clientTemplate.getForObject("ANY", SOME.class);
663 fail("The expected exception was not thrown");
665 catch(HttpClientErrorException e)
667 log.debug("{}", e.toString());
671 fail("A wrong exception was thrown: " + e.toString());
675 requestFactory.setBody("");
679 clientTemplate.getForObject("ANY", SOME.class);
680 fail("The expected exception was not thrown");
682 catch(HttpClientErrorException e)
684 log.debug("{}", e.toString());
688 fail("A wrong exception was thrown: " + e.toString());
696 requestFactory = new MockClientHttpRequestFactory();
697 requestFactory.setStatus(HttpStatus.BAD_REQUEST);
698 requestFactory.addHeader("Content-Type", "application/json");
699 clientTemplate.setRequestFactory(requestFactory);
701 clientTemplate.setErrorHandler(
702 new GraphApiErrorHandler(
703 (OAuth2ErrorHandler)clientTemplate.getErrorHandler()
707 clientTemplate.setAccessTokenProvider(new AccessTokenProvider()
710 public OAuth2AccessToken obtainAccessToken(
711 OAuth2ProtectedResourceDetails details,
712 AccessTokenRequest parameters
715 UserRedirectRequiredException,
716 UserApprovalRequiredException,
717 AccessDeniedException
719 return new OAuth2AccessToken() {
722 public Map<String, Object> getAdditionalInformation()
724 throw new UnsupportedOperationException("Not supported yet.");
728 public Set<String> getScope()
730 throw new UnsupportedOperationException("Not supported yet.");
734 public OAuth2RefreshToken getRefreshToken()
736 throw new UnsupportedOperationException("Not supported yet.");
740 public String getTokenType()
746 public boolean isExpired()
752 public Date getExpiration()
754 throw new UnsupportedOperationException("Not supported yet.");
758 public int getExpiresIn()
760 throw new UnsupportedOperationException("Not supported yet.");
764 public String getValue()
772 public boolean supportsResource(OAuth2ProtectedResourceDetails resource)
778 public OAuth2AccessToken refreshAccessToken(
779 OAuth2ProtectedResourceDetails resource,
780 OAuth2RefreshToken refreshToken,
781 AccessTokenRequest request
784 UserRedirectRequiredException
786 throw new UnsupportedOperationException("Not supported yet.");
790 public boolean supportsRefresh(OAuth2ProtectedResourceDetails resource)