1 package de.juplo.facebook;
6 import javax.annotation.Resource;
7 import static org.junit.Assert.*;
8 import org.junit.Before;
10 import org.junit.runner.RunWith;
11 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory;
13 import org.springframework.http.HttpStatus;
14 import org.springframework.http.converter.HttpMessageNotReadableException;
15 import org.springframework.security.access.AccessDeniedException;
16 import org.springframework.security.oauth2.client.OAuth2RestTemplate;
17 import org.springframework.security.oauth2.client.http.OAuth2ErrorHandler;
18 import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
19 import org.springframework.security.oauth2.client.resource.UserApprovalRequiredException;
20 import org.springframework.security.oauth2.client.resource.UserRedirectRequiredException;
21 import org.springframework.security.oauth2.client.token.AccessTokenProvider;
22 import org.springframework.security.oauth2.client.token.AccessTokenRequest;
23 import org.springframework.security.oauth2.common.OAuth2AccessToken;
24 import static org.springframework.security.oauth2.common.OAuth2AccessToken.OAUTH2_TYPE;
25 import org.springframework.security.oauth2.common.OAuth2RefreshToken;
26 import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
27 import org.springframework.test.context.ContextConfiguration;
28 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
36 @RunWith(SpringJUnit4ClassRunner.class)
37 @ContextConfiguration(
39 "classpath:/spring/test-facebook-error-handler.xml"
41 public class GraphApiErrorHandlerTest
43 private static final Logger log =
44 LoggerFactory.getLogger(GraphApiErrorHandlerTest.class);
47 private OAuth2RestTemplate clientTemplate;
49 private MockClientHttpRequestFactory requestFactory;
53 public void testError1()
55 log.info("testError1");
58 requestFactory.setBody(
62 " \"message\": \"An unknown error has occurred.\",\n" +
63 " \"type\": \"OAuthException\",\n" +
70 clientTemplate.getForObject("ANY", SOME.class);
71 fail("The expected exception was not thrown");
73 catch(UnknownErrorException e)
75 log.debug("{}", e.toString());
76 assertEquals("invalid_request", e.getOAuth2ErrorCode());
77 assertEquals(1, e.getCode());
78 assertEquals("An unknown error has occurred.", e.getMessage());
79 assertEquals("OAuthException", e.getType());
84 public void testError2()
86 log.info("testError2");
89 requestFactory.setBody(
93 " \"message\": \"An unexpected error has occurred. Please retry your request later.\",\n" +
94 " \"type\": \"OAuthException\",\n" +
101 clientTemplate.getForObject("ANY", SOME.class);
102 fail("The expected exception was not thrown");
104 catch(UnexpectedErrorException e)
106 log.debug("{}", e.toString());
107 assertEquals("invalid_request", e.getOAuth2ErrorCode());
108 assertEquals(2, e.getCode());
109 assertEquals("An unexpected error has occurred. Please retry your request later.", e.getMessage());
110 assertEquals("OAuthException", e.getType());
115 public void testError21()
117 log.info("testError21");
120 requestFactory.setBody(
124 " \"message\": \"(#21) Page ID 590408587650316 was migrated to page ID 1421620791415603. Please update your API calls to the new ID\",\n" +
125 " \"type\": \"OAuthException\",\n" +
132 clientTemplate.getForObject("ANY", SOME.class);
133 fail("The expected exception was not thrown");
135 catch(PageMigratedException e)
137 log.debug("{}", e.toString());
138 assertEquals("invalid_request", e.getOAuth2ErrorCode());
139 assertEquals(21, e.getCode());
140 assertEquals("(#21) Page ID 590408587650316 was migrated to page ID 1421620791415603. Please update your API calls to the new ID", e.getMessage());
141 assertEquals("OAuthException", e.getType());
146 public void testError100()
148 log.info("testError100");
151 requestFactory.setBody(
155 " \"message\": \"Unsupported get request.\",\n" +
156 " \"type\": \"GraphMethodException\",\n" +
163 clientTemplate.getForObject("ANY", SOME.class);
164 fail("The expected exception was not thrown");
166 catch(UnsupportedGetRequestException e)
168 log.debug("{}", e.toString());
169 assertEquals("invalid_request", e.getOAuth2ErrorCode());
170 assertEquals(100, e.getCode());
171 assertEquals("Unsupported get request.", e.getMessage());
172 assertEquals("GraphMethodException", e.getType());
177 public void testError613()
179 log.info("testError613");
182 requestFactory.setBody(
186 " \"message\": \"(#613) Calls to stream have exceeded the rate of 600 calls per 600 seconds.\",\n" +
187 " \"type\": \"OAuthException\",\n" +
194 clientTemplate.getForObject("ANY", SOME.class);
195 fail("The expected exception was not thrown");
197 catch(RateExceededException e)
199 log.debug("{}", e.toString());
200 assertEquals("invalid_request", e.getOAuth2ErrorCode());
201 assertEquals(613, e.getCode());
202 assertEquals("(#613) Calls to stream have exceeded the rate of 600 calls per 600 seconds.", e.getMessage());
203 assertEquals("OAuthException", e.getType());
208 public void testUnmappedError()
210 log.info("testUnmappedError");
213 requestFactory.setBody(
217 " \"message\": \"This error does not exist.\",\n" +
218 " \"type\": \"NonexistentException\",\n" +
219 " \"code\": 999999999\n" +
225 clientTemplate.getForObject("ANY", SOME.class);
226 fail("The expected exception was not thrown");
228 catch(GraphApiException e)
230 log.debug("{}", e.toString());
231 assertEquals("invalid_request", e.getOAuth2ErrorCode());
232 assertEquals(999999999, e.getCode());
233 assertEquals("This error does not exist.", e.getMessage());
234 assertEquals("NonexistentException", e.getType());
239 public void testInvlalidErrors()
241 log.info("testInvalidErrors");
244 requestFactory.setBody(
248 " \"message\": null,\n" +
249 " \"type\": \"Whatever\",\n" +
250 " \"code\": 999999999\n" +
256 clientTemplate.getForObject("ANY", SOME.class);
257 fail("The expected exception was not thrown");
259 catch(OAuth2Exception e)
261 log.debug("{}", e.toString());
262 assertEquals("invalid_request", e.getOAuth2ErrorCode());
263 assertFalse(e instanceof GraphApiException);
267 requestFactory.setBody(
271 " \"type\": \"Whatever\",\n" +
272 " \"code\": 999999999\n" +
278 clientTemplate.getForObject("ANY", SOME.class);
279 fail("The expected exception was not thrown");
281 catch(OAuth2Exception e)
283 log.debug("{}", e.toString());
284 assertEquals("invalid_request", e.getOAuth2ErrorCode());
285 assertFalse(e instanceof GraphApiException);
289 requestFactory.setBody(
293 " \"message\": \"Not a Graph-Api-Exception.\",\n" +
294 " \"type\": null,\n" +
295 " \"code\": 999999999\n" +
301 clientTemplate.getForObject("ANY", SOME.class);
302 fail("The expected exception was not thrown");
304 catch(OAuth2Exception e)
306 log.debug("{}", e.toString());
307 assertEquals("invalid_request", e.getOAuth2ErrorCode());
308 assertFalse(e instanceof GraphApiException);
312 requestFactory.setBody(
316 " \"message\": \"Not a Graph-Api-Exception.\",\n" +
317 " \"code\": 999999999\n" +
323 clientTemplate.getForObject("ANY", SOME.class);
324 fail("The expected exception was not thrown");
326 catch(OAuth2Exception e)
328 log.debug("{}", e.toString());
329 assertEquals("invalid_request", e.getOAuth2ErrorCode());
330 assertFalse(e instanceof GraphApiException);
334 requestFactory.setBody(
338 " \"message\": \"Not a Graph-Api-Exception.\",\n" +
339 " \"type\": \"Whatever\",\n" +
340 " \"code\": \"some string\"\n" +
346 clientTemplate.getForObject("ANY", SOME.class);
347 fail("The expected exception was not thrown");
349 catch(OAuth2Exception e)
351 log.debug("{}", e.toString());
352 assertEquals("invalid_request", e.getOAuth2ErrorCode());
353 assertFalse(e instanceof GraphApiException);
357 requestFactory.setBody(
361 " \"message\": \"Not a Graph-Api-Exception.\",\n" +
362 " \"type\": \"Whatever\",\n" +
369 clientTemplate.getForObject("ANY", SOME.class);
370 fail("The expected exception was not thrown");
372 catch(OAuth2Exception e)
374 log.debug("{}", e.toString());
375 assertEquals("invalid_request", e.getOAuth2ErrorCode());
376 assertFalse(e instanceof GraphApiException);
380 requestFactory.setBody(
384 " \"message\": \"Not a Graph-Api-Exception.\",\n" +
385 " \"type\": \"Whatever\",\n" +
386 " \"code\": null\n" +
392 clientTemplate.getForObject("ANY", SOME.class);
393 fail("The expected exception was not thrown");
395 catch(OAuth2Exception e)
397 log.debug("{}", e.toString());
398 assertEquals("invalid_request", e.getOAuth2ErrorCode());
399 assertFalse(e instanceof GraphApiException);
403 requestFactory.setBody(
407 " \"message\": \"Not a Graph-Api-Exception.\",\n" +
408 " \"type\": \"Whatever\"\n" +
414 clientTemplate.getForObject("ANY", SOME.class);
415 fail("The expected exception was not thrown");
417 catch(OAuth2Exception e)
419 log.debug("{}", e.toString());
420 assertEquals("invalid_request", e.getOAuth2ErrorCode());
421 assertFalse(e instanceof GraphApiException);
425 requestFactory.setBody("{\"error\":{\"message\":null}}");
429 clientTemplate.getForObject("ANY", SOME.class);
430 fail("The expected exception was not thrown");
432 catch(OAuth2Exception e)
434 log.debug("{}", e.toString());
435 assertEquals("invalid_request", e.getOAuth2ErrorCode());
436 assertFalse(e instanceof GraphApiException);
440 requestFactory.setBody("{\"error\":{\"type\":null}}");
444 clientTemplate.getForObject("ANY", SOME.class);
445 fail("The expected exception was not thrown");
447 catch(OAuth2Exception e)
449 log.debug("{}", e.toString());
450 assertEquals("invalid_request", e.getOAuth2ErrorCode());
451 assertFalse(e instanceof GraphApiException);
455 requestFactory.setBody("{\"error\":{\"code\":null}}");
459 clientTemplate.getForObject("ANY", SOME.class);
460 fail("The expected exception was not thrown");
462 catch(OAuth2Exception e)
464 log.debug("{}", e.toString());
465 assertEquals("invalid_request", e.getOAuth2ErrorCode());
466 assertFalse(e instanceof GraphApiException);
470 requestFactory.setBody("{\"error\":{}}");
474 clientTemplate.getForObject("ANY", SOME.class);
475 fail("The expected exception was not thrown");
477 catch(OAuth2Exception e)
479 log.debug("{}", e.toString());
480 assertEquals("invalid_request", e.getOAuth2ErrorCode());
481 assertFalse(e instanceof GraphApiException);
485 requestFactory.setBody("{\"error\":\"some message\"}");
489 clientTemplate.getForObject("ANY", SOME.class);
490 fail("The expected exception was not thrown");
492 catch(OAuth2Exception e)
494 log.debug("{}", e.toString());
495 assertEquals("invalid_request", e.getOAuth2ErrorCode());
496 assertFalse(e instanceof GraphApiException);
500 requestFactory.setBody("{\"error\":null}");
504 clientTemplate.getForObject("ANY", SOME.class);
505 fail("The expected exception was not thrown");
507 catch(OAuth2Exception e)
509 log.debug("{}", e.toString());
510 assertEquals("invalid_request", e.getOAuth2ErrorCode());
511 assertFalse(e instanceof GraphApiException);
515 requestFactory.setBody("{\"some filed\":\"some message\"}");
519 clientTemplate.getForObject("ANY", SOME.class);
520 fail("The expected exception was not thrown");
522 catch(OAuth2Exception e)
524 log.debug("{}", e.toString());
525 assertEquals("invalid_request", e.getOAuth2ErrorCode());
526 assertFalse(e instanceof GraphApiException);
530 requestFactory.setBody("{}");
534 clientTemplate.getForObject("ANY", SOME.class);
535 fail("The expected exception was not thrown");
537 catch(OAuth2Exception e)
539 log.debug("{}", e.toString());
540 assertEquals("invalid_request", e.getOAuth2ErrorCode());
541 assertFalse(e instanceof GraphApiException);
545 requestFactory.setBody("");
549 clientTemplate.getForObject("ANY", SOME.class);
550 fail("The expected exception was not thrown");
552 catch(HttpMessageNotReadableException e)
554 // TODO: OAuth2ErrorHandler fails, if body contains no valid JSON!
555 log.debug("{}", e.toString());
563 requestFactory = new MockClientHttpRequestFactory();
564 requestFactory.setStatus(HttpStatus.BAD_REQUEST);
565 requestFactory.addHeader("Content-Type", "application/json");
566 clientTemplate.setRequestFactory(requestFactory);
568 clientTemplate.setErrorHandler(
569 new GraphApiErrorHandler(
570 (OAuth2ErrorHandler)clientTemplate.getErrorHandler()
574 clientTemplate.setAccessTokenProvider(new AccessTokenProvider()
577 public OAuth2AccessToken obtainAccessToken(
578 OAuth2ProtectedResourceDetails details,
579 AccessTokenRequest parameters
582 UserRedirectRequiredException,
583 UserApprovalRequiredException,
584 AccessDeniedException
586 return new OAuth2AccessToken() {
589 public Map<String, Object> getAdditionalInformation()
591 throw new UnsupportedOperationException("Not supported yet.");
595 public Set<String> getScope()
597 throw new UnsupportedOperationException("Not supported yet.");
601 public OAuth2RefreshToken getRefreshToken()
603 throw new UnsupportedOperationException("Not supported yet.");
607 public String getTokenType()
613 public boolean isExpired()
619 public Date getExpiration()
621 throw new UnsupportedOperationException("Not supported yet.");
625 public int getExpiresIn()
627 throw new UnsupportedOperationException("Not supported yet.");
631 public String getValue()
639 public boolean supportsResource(OAuth2ProtectedResourceDetails resource)
645 public OAuth2AccessToken refreshAccessToken(
646 OAuth2ProtectedResourceDetails resource,
647 OAuth2RefreshToken refreshToken,
648 AccessTokenRequest request
651 UserRedirectRequiredException
653 throw new UnsupportedOperationException("Not supported yet.");
657 public boolean supportsRefresh(OAuth2ProtectedResourceDetails resource)