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 testError104()
182 log.info("testError104");
184 requestFactory.setBody("{\"error\":{\"message\":\"An access token is required to request this resource.\",\"type\":\"OAuthException\",\"code\":104,\"fbtrace_id\":\"E2Jjkj5++LL\"}}");
188 clientTemplate.getForObject("ANY", SOME.class);
189 fail("The expected exception was not thrown");
191 catch(AccessTokenRequiredException e)
193 log.debug("{}", e.toString());
194 assertEquals("invalid_request", e.getOAuth2ErrorCode());
195 assertEquals(new Integer(104), e.getCode());
196 assertEquals("An access token is required to request this resource.", e.getMessage());
197 assertEquals(Type.OAuthException, e.getType());
198 assertEquals("E2Jjkj5++LL", e.getTraceId());
203 public void testError613()
205 log.info("testError613");
208 requestFactory.setBody(
212 " \"message\": \"(#613) Calls to stream have exceeded the rate of 600 calls per 600 seconds.\",\n" +
213 " \"type\": \"OAuthException\",\n" +
220 clientTemplate.getForObject("ANY", SOME.class);
221 fail("The expected exception was not thrown");
223 catch(RateExceededException e)
225 log.debug("{}", e.toString());
226 assertEquals("invalid_request", e.getOAuth2ErrorCode());
227 assertEquals(new Integer(613), e.getCode());
228 assertEquals("(#613) Calls to stream have exceeded the rate of 600 calls per 600 seconds.", e.getMessage());
229 assertEquals(Type.OAuthException, e.getType());
234 public void testError2200()
236 requestFactory.setBody("{\"error\":{\"message\":\"(#2200) callback verification failed: \",\"type\":\"OAuthException\",\"code\":2200,\"fbtrace_id\":\"ESLjoZKvPXg\"}}");
240 clientTemplate.getForObject("ANY", SOME.class);
241 fail("The expected exception was not thrown");
243 catch(CallbackVerificationFailedException e)
245 log.debug("{}", e.toString());
246 assertEquals("invalid_request", e.getOAuth2ErrorCode());
247 assertEquals(new Integer(2200), e.getCode());
248 assertEquals("(#2200) callback verification failed: ", e.getMessage());
249 assertEquals(Type.OAuthException, e.getType());
250 assertEquals("ESLjoZKvPXg", e.getTraceId());
255 public void testUnmappedError()
257 log.info("testUnmappedError");
260 requestFactory.setBody(
264 " \"message\": \"This error does not exist.\",\n" +
265 " \"type\": \"NonexistentTypeException\",\n" +
266 " \"code\": 999999999\n" +
272 clientTemplate.getForObject("ANY", SOME.class);
273 fail("The expected exception was not thrown");
275 catch(GraphApiException e)
277 log.debug("{}", e.toString());
278 assertEquals("invalid_request", e.getOAuth2ErrorCode());
279 assertEquals(new Integer(999999999), e.getCode());
280 assertEquals("This error does not exist.", e.getMessage());
283 Type type = e.getType();
284 log.error("unknown type: {}", type);
285 fail("unmapped type was resolved by enum: " + type);
287 catch (IllegalArgumentException ee) {}
292 public void testUnmappedErrors()
294 log.info("testUnmappedErrors");
297 requestFactory.setBody(
301 " \"message\": null,\n" +
302 " \"type\": \"WhateverTypeException\",\n" +
303 " \"code\": 999999999\n" +
309 clientTemplate.getForObject("ANY", SOME.class);
310 fail("The expected exception was not thrown");
312 catch(UnmappedErrorException e)
314 log.debug("{}", e.toString());
315 assertNull(e.getMessage());
318 Type type = e.getType();
319 log.error("unknown type: {}", type);
320 fail("unmapped type was resolved by enum: " + type);
322 catch (IllegalArgumentException ee) {}
323 assertEquals(new Integer(999999999), e.getCode());
324 assertNull(e.getSubCode());
325 assertNull(e.getUserTitle());
326 assertNull(e.getUserMessage());
327 assertNull(e.getTraceId());
331 fail("A wrong exception was thrown: " + e.toString());
335 requestFactory.setBody(
339 " \"type\": \"WhateverTypeException\",\n" +
340 " \"code\": 999999999\n" +
346 clientTemplate.getForObject("ANY", SOME.class);
347 fail("The expected exception was not thrown");
349 catch(UnmappedErrorException e)
351 log.debug("{}", e.toString());
352 assertNull(e.getMessage());
355 Type type = e.getType();
356 log.error("unknown type: {}", type);
357 fail("unmapped type was resolved by enum: " + type);
359 catch (IllegalArgumentException ee) {}
360 assertEquals(new Integer(999999999), e.getCode());
361 assertNull(e.getSubCode());
362 assertNull(e.getUserTitle());
363 assertNull(e.getUserMessage());
364 assertNull(e.getTraceId());
368 fail("A wrong exception was thrown: " + e.toString());
372 requestFactory.setBody(
376 " \"message\": \"An unmapped Graph-API-Exception.\",\n" +
377 " \"type\": null,\n" +
378 " \"code\": 999999999\n" +
384 clientTemplate.getForObject("ANY", SOME.class);
385 fail("The expected exception was not thrown");
387 catch(UnmappedErrorException e)
389 log.debug("{}", e.toString());
390 assertEquals("An unmapped Graph-API-Exception.", e.getMessage());
391 assertNull(e.getType());
392 assertEquals(new Integer(999999999), e.getCode());
393 assertNull(e.getSubCode());
394 assertNull(e.getUserTitle());
395 assertNull(e.getUserMessage());
396 assertNull(e.getTraceId());
400 fail("A wrong exception was thrown: " + e.toString());
404 requestFactory.setBody(
408 " \"message\": \"An unmapped Graph-API-Exception.\",\n" +
409 " \"code\": 999999999\n" +
415 clientTemplate.getForObject("ANY", SOME.class);
416 fail("The expected exception was not thrown");
418 catch(UnmappedErrorException e)
420 log.debug("{}", e.toString());
421 assertEquals("An unmapped Graph-API-Exception.", e.getMessage());
422 assertNull(e.getType());
423 assertEquals(new Integer(999999999), e.getCode());
424 assertNull(e.getSubCode());
425 assertNull(e.getUserTitle());
426 assertNull(e.getUserMessage());
427 assertNull(e.getTraceId());
431 fail("A wrong exception was thrown: " + e.toString());
436 public void testInvlalidErrors()
438 log.info("testInvalidErrors");
441 requestFactory.setBody(
445 " \"message\": \"Not a Graph-Api-Exception.\",\n" +
446 " \"type\": \"Whatever\",\n" +
447 " \"code\": \"some string\"\n" +
453 clientTemplate.getForObject("ANY", SOME.class);
454 fail("The expected exception was not thrown");
456 catch(HttpClientErrorException e)
458 log.debug("{}", e.toString());
462 fail("A wrong exception was thrown: " + e.toString());
466 requestFactory.setBody(
470 " \"message\": \"Not a Graph-Api-Exception.\",\n" +
471 " \"type\": \"Whatever\",\n" +
478 clientTemplate.getForObject("ANY", SOME.class);
479 fail("The expected exception was not thrown");
481 catch(HttpClientErrorException e)
483 log.debug("{}", e.toString());
487 fail("A wrong exception was thrown: " + e.toString());
491 requestFactory.setBody(
495 " \"message\": \"Not a Graph-Api-Exception.\",\n" +
496 " \"type\": \"Whatever\",\n" +
497 " \"code\": null\n" +
503 clientTemplate.getForObject("ANY", SOME.class);
504 fail("The expected exception was not thrown");
506 catch(HttpClientErrorException e)
508 log.debug("{}", e.toString());
512 fail("A wrong exception was thrown: " + e.toString());
516 requestFactory.setBody(
520 " \"message\": \"Not a Graph-Api-Exception.\",\n" +
521 " \"type\": \"Whatever\"\n" +
527 clientTemplate.getForObject("ANY", SOME.class);
528 fail("The expected exception was not thrown");
530 catch(HttpClientErrorException e)
532 log.debug("{}", e.toString());
536 fail("A wrong exception was thrown: " + e.toString());
540 requestFactory.setBody("{\"error\":{\"message\":null}}");
544 clientTemplate.getForObject("ANY", SOME.class);
545 fail("The expected exception was not thrown");
547 catch(HttpClientErrorException e)
549 log.debug("{}", e.toString());
553 fail("A wrong exception was thrown: " + e.toString());
557 requestFactory.setBody("{\"error\":{\"type\":null}}");
561 clientTemplate.getForObject("ANY", SOME.class);
562 fail("The expected exception was not thrown");
564 catch(HttpClientErrorException e)
566 log.debug("{}", e.toString());
570 fail("A wrong exception was thrown: " + e.toString());
574 requestFactory.setBody("{\"error\":{\"code\":null}}");
578 clientTemplate.getForObject("ANY", SOME.class);
579 fail("The expected exception was not thrown");
581 catch(HttpClientErrorException e)
583 log.debug("{}", e.toString());
587 fail("A wrong exception was thrown: " + e.toString());
591 requestFactory.setBody("{\"error\":{}}");
595 clientTemplate.getForObject("ANY", SOME.class);
596 fail("The expected exception was not thrown");
598 catch(HttpClientErrorException e)
600 log.debug("{}", e.toString());
604 fail("A wrong exception was thrown: " + e.toString());
608 requestFactory.setBody("{\"error\":\"some message\"}");
612 clientTemplate.getForObject("ANY", SOME.class);
613 fail("The expected exception was not thrown");
615 catch(HttpClientErrorException e)
617 log.debug("{}", e.toString());
621 fail("A wrong exception was thrown: " + e.toString());
625 requestFactory.setBody("{\"error\":null}");
629 clientTemplate.getForObject("ANY", SOME.class);
630 fail("The expected exception was not thrown");
632 catch(HttpClientErrorException e)
634 log.debug("{}", e.toString());
638 fail("A wrong exception was thrown: " + e.toString());
642 requestFactory.setBody("{\"some filed\":\"some message\"}");
646 clientTemplate.getForObject("ANY", SOME.class);
647 fail("The expected exception was not thrown");
649 catch(HttpClientErrorException e)
651 log.debug("{}", e.toString());
655 fail("A wrong exception was thrown: " + e.toString());
659 requestFactory.setBody("{}");
663 clientTemplate.getForObject("ANY", SOME.class);
664 fail("The expected exception was not thrown");
666 catch(HttpClientErrorException e)
668 log.debug("{}", e.toString());
672 fail("A wrong exception was thrown: " + e.toString());
676 requestFactory.setBody("");
680 clientTemplate.getForObject("ANY", SOME.class);
681 fail("The expected exception was not thrown");
683 catch(HttpClientErrorException e)
685 log.debug("{}", e.toString());
689 fail("A wrong exception was thrown: " + e.toString());
697 requestFactory = new MockClientHttpRequestFactory();
698 requestFactory.setStatus(HttpStatus.BAD_REQUEST);
699 requestFactory.addHeader("Content-Type", "application/json");
700 clientTemplate.setRequestFactory(requestFactory);
702 clientTemplate.setErrorHandler(
703 new GraphApiErrorHandler(
704 (OAuth2ErrorHandler)clientTemplate.getErrorHandler()
708 clientTemplate.setAccessTokenProvider(new AccessTokenProvider()
711 public OAuth2AccessToken obtainAccessToken(
712 OAuth2ProtectedResourceDetails details,
713 AccessTokenRequest parameters
716 UserRedirectRequiredException,
717 UserApprovalRequiredException,
718 AccessDeniedException
720 return new OAuth2AccessToken() {
723 public Map<String, Object> getAdditionalInformation()
725 throw new UnsupportedOperationException("Not supported yet.");
729 public Set<String> getScope()
731 throw new UnsupportedOperationException("Not supported yet.");
735 public OAuth2RefreshToken getRefreshToken()
737 throw new UnsupportedOperationException("Not supported yet.");
741 public String getTokenType()
747 public boolean isExpired()
753 public Date getExpiration()
755 throw new UnsupportedOperationException("Not supported yet.");
759 public int getExpiresIn()
761 throw new UnsupportedOperationException("Not supported yet.");
765 public String getValue()
773 public boolean supportsResource(OAuth2ProtectedResourceDetails resource)
779 public OAuth2AccessToken refreshAccessToken(
780 OAuth2ProtectedResourceDetails resource,
781 OAuth2RefreshToken refreshToken,
782 AccessTokenRequest request
785 UserRedirectRequiredException
787 throw new UnsupportedOperationException("Not supported yet.");
791 public boolean supportsRefresh(OAuth2ProtectedResourceDetails resource)