1 package de.juplo.facebook.client;
3 import de.juplo.facebook.exceptions.AccessTokenRequiredException;
4 import de.juplo.facebook.exceptions.CallbackVerificationFailedException;
5 import de.juplo.facebook.exceptions.UnsupportedGetRequestException;
6 import de.juplo.facebook.exceptions.UnexpectedErrorException;
7 import de.juplo.facebook.exceptions.RateExceededException;
8 import de.juplo.facebook.exceptions.GraphApiException;
9 import de.juplo.facebook.exceptions.UnknownErrorException;
10 import de.juplo.facebook.exceptions.PageMigratedException;
11 import de.juplo.facebook.exceptions.UnmappedErrorException;
12 import java.util.Date;
15 import javax.annotation.Resource;
16 import static org.junit.Assert.*;
17 import org.junit.Before;
18 import org.junit.Test;
19 import org.junit.runner.RunWith;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
22 import org.springframework.http.HttpStatus;
23 import org.springframework.security.access.AccessDeniedException;
24 import org.springframework.security.oauth2.client.OAuth2RestTemplate;
25 import org.springframework.security.oauth2.client.http.OAuth2ErrorHandler;
26 import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
27 import org.springframework.security.oauth2.client.resource.UserApprovalRequiredException;
28 import org.springframework.security.oauth2.client.resource.UserRedirectRequiredException;
29 import org.springframework.security.oauth2.client.token.AccessTokenProvider;
30 import org.springframework.security.oauth2.client.token.AccessTokenRequest;
31 import org.springframework.security.oauth2.common.OAuth2AccessToken;
32 import static org.springframework.security.oauth2.common.OAuth2AccessToken.OAUTH2_TYPE;
33 import org.springframework.security.oauth2.common.OAuth2RefreshToken;
34 import org.springframework.test.context.ContextConfiguration;
35 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
36 import org.springframework.web.client.HttpClientErrorException;
44 @RunWith(SpringJUnit4ClassRunner.class)
45 @ContextConfiguration(
47 "classpath:/spring/test-facebook-error-handler.xml"
49 public class GraphApiErrorHandlerTest
51 private static final Logger log =
52 LoggerFactory.getLogger(GraphApiErrorHandlerTest.class);
55 private OAuth2RestTemplate clientTemplate;
57 private MockClientHttpRequestFactory requestFactory;
61 public void testError1()
63 log.info("testError1");
66 requestFactory.setBody(
70 " \"message\": \"An unknown error has occurred.\",\n" +
71 " \"type\": \"OAuthException\",\n" +
78 clientTemplate.getForObject("ANY", SOME.class);
79 fail("The expected exception was not thrown");
81 catch(UnknownErrorException e)
83 log.debug("{}", e.toString());
84 assertEquals("invalid_request", e.getOAuth2ErrorCode());
85 assertEquals(new Integer(1), e.getCode());
86 assertEquals("An unknown error has occurred.", e.getMessage());
87 assertEquals("OAuthException", e.getType());
92 public void testError2()
94 log.info("testError2");
97 requestFactory.setBody(
101 " \"message\": \"An unexpected error has occurred. Please retry your request later.\",\n" +
102 " \"type\": \"OAuthException\",\n" +
109 clientTemplate.getForObject("ANY", SOME.class);
110 fail("The expected exception was not thrown");
112 catch(UnexpectedErrorException e)
114 log.debug("{}", e.toString());
115 assertEquals("invalid_request", e.getOAuth2ErrorCode());
116 assertEquals(new Integer(2), e.getCode());
117 assertEquals("An unexpected error has occurred. Please retry your request later.", e.getMessage());
118 assertEquals("OAuthException", e.getType());
123 public void testError21()
125 log.info("testError21");
128 requestFactory.setBody(
132 " \"message\": \"(#21) Page ID 590408587650316 was migrated to page ID 1421620791415603. Please update your API calls to the new ID\",\n" +
133 " \"type\": \"OAuthException\",\n" +
140 clientTemplate.getForObject("ANY", SOME.class);
141 fail("The expected exception was not thrown");
143 catch(PageMigratedException e)
145 log.debug("{}", e.toString());
146 assertEquals("invalid_request", e.getOAuth2ErrorCode());
147 assertEquals(new Integer(21), e.getCode());
148 assertEquals("(#21) Page ID 590408587650316 was migrated to page ID 1421620791415603. Please update your API calls to the new ID", e.getMessage());
149 assertEquals("OAuthException", e.getType());
154 public void testError100()
156 log.info("testError100");
159 requestFactory.setBody(
163 " \"message\": \"Unsupported get request.\",\n" +
164 " \"type\": \"GraphMethodException\",\n" +
171 clientTemplate.getForObject("ANY", SOME.class);
172 fail("The expected exception was not thrown");
174 catch(UnsupportedGetRequestException e)
176 log.debug("{}", e.toString());
177 assertEquals("invalid_request", e.getOAuth2ErrorCode());
178 assertEquals(new Integer(100), e.getCode());
179 assertEquals("Unsupported get request.", e.getMessage());
180 assertEquals("GraphMethodException", e.getType());
185 public void testError104()
187 log.info("testError104");
189 requestFactory.setBody("{\"error\":{\"message\":\"An access token is required to request this resource.\",\"type\":\"OAuthException\",\"code\":104,\"fbtrace_id\":\"E2Jjkj5++LL\"}}");
193 clientTemplate.getForObject("ANY", SOME.class);
194 fail("The expected exception was not thrown");
196 catch(AccessTokenRequiredException e)
198 log.debug("{}", e.toString());
199 assertEquals("invalid_request", e.getOAuth2ErrorCode());
200 assertEquals(new Integer(104), e.getCode());
201 assertEquals("An access token is required to request this resource.", e.getMessage());
202 assertEquals("OAuthException", e.getType());
203 assertEquals("E2Jjkj5++LL", e.getTraceId());
208 public void testError613()
210 log.info("testError613");
213 requestFactory.setBody(
217 " \"message\": \"(#613) Calls to stream have exceeded the rate of 600 calls per 600 seconds.\",\n" +
218 " \"type\": \"OAuthException\",\n" +
225 clientTemplate.getForObject("ANY", SOME.class);
226 fail("The expected exception was not thrown");
228 catch(RateExceededException e)
230 log.debug("{}", e.toString());
231 assertEquals("invalid_request", e.getOAuth2ErrorCode());
232 assertEquals(new Integer(613), e.getCode());
233 assertEquals("(#613) Calls to stream have exceeded the rate of 600 calls per 600 seconds.", e.getMessage());
234 assertEquals("OAuthException", e.getType());
239 public void testError2200()
241 requestFactory.setBody("{\"error\":{\"message\":\"(#2200) callback verification failed: \",\"type\":\"OAuthException\",\"code\":2200,\"fbtrace_id\":\"ESLjoZKvPXg\"}}");
245 clientTemplate.getForObject("ANY", SOME.class);
246 fail("The expected exception was not thrown");
248 catch(CallbackVerificationFailedException e)
250 log.debug("{}", e.toString());
251 assertEquals("invalid_request", e.getOAuth2ErrorCode());
252 assertEquals(new Integer(2200), e.getCode());
253 assertEquals("(#2200) callback verification failed: ", e.getMessage());
254 assertEquals(Type.OAuthException, e.getType());
255 assertEquals("ESLjoZKvPXg", e.getTraceId());
260 public void testUnmappedError()
262 log.info("testUnmappedError");
265 requestFactory.setBody(
269 " \"message\": \"This error does not exist.\",\n" +
270 " \"type\": \"NonexistentException\",\n" +
271 " \"code\": 999999999\n" +
277 clientTemplate.getForObject("ANY", SOME.class);
278 fail("The expected exception was not thrown");
280 catch(GraphApiException e)
282 log.debug("{}", e.toString());
283 assertEquals("invalid_request", e.getOAuth2ErrorCode());
284 assertEquals(new Integer(999999999), e.getCode());
285 assertEquals("This error does not exist.", e.getMessage());
286 assertEquals("NonexistentException", e.getType());
291 public void testUnmappedErrors()
293 log.info("testUnmappedErrors");
296 requestFactory.setBody(
300 " \"message\": null,\n" +
301 " \"type\": \"Whatever\",\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());
315 assertEquals("Whatever", e.getType());
316 assertEquals(new Integer(999999999), e.getCode());
317 assertNull(e.getSubCode());
318 assertNull(e.getUserTitle());
319 assertNull(e.getUserMessage());
320 assertNull(e.getTraceId());
324 fail("A wrong exception was thrown: " + e.toString());
328 requestFactory.setBody(
332 " \"type\": \"Whatever\",\n" +
333 " \"code\": 999999999\n" +
339 clientTemplate.getForObject("ANY", SOME.class);
340 fail("The expected exception was not thrown");
342 catch(UnmappedErrorException e)
344 log.debug("{}", e.toString());
345 assertNull(e.getMessage());
346 assertEquals("Whatever", e.getType());
347 assertEquals(new Integer(999999999), e.getCode());
348 assertNull(e.getSubCode());
349 assertNull(e.getUserTitle());
350 assertNull(e.getUserMessage());
351 assertNull(e.getTraceId());
355 fail("A wrong exception was thrown: " + e.toString());
359 requestFactory.setBody(
363 " \"message\": \"An unmapped Graph-API-Exception.\",\n" +
364 " \"type\": null,\n" +
365 " \"code\": 999999999\n" +
371 clientTemplate.getForObject("ANY", SOME.class);
372 fail("The expected exception was not thrown");
374 catch(UnmappedErrorException e)
376 log.debug("{}", e.toString());
377 assertEquals("An unmapped Graph-API-Exception.", e.getMessage());
378 assertNull(e.getType());
379 assertEquals(new Integer(999999999), e.getCode());
380 assertNull(e.getSubCode());
381 assertNull(e.getUserTitle());
382 assertNull(e.getUserMessage());
383 assertNull(e.getTraceId());
387 fail("A wrong exception was thrown: " + e.toString());
391 requestFactory.setBody(
395 " \"message\": \"An unmapped Graph-API-Exception.\",\n" +
396 " \"code\": 999999999\n" +
402 clientTemplate.getForObject("ANY", SOME.class);
403 fail("The expected exception was not thrown");
405 catch(UnmappedErrorException e)
407 log.debug("{}", e.toString());
408 assertEquals("An unmapped Graph-API-Exception.", e.getMessage());
409 assertNull(e.getType());
410 assertEquals(new Integer(999999999), e.getCode());
411 assertNull(e.getSubCode());
412 assertNull(e.getUserTitle());
413 assertNull(e.getUserMessage());
414 assertNull(e.getTraceId());
418 fail("A wrong exception was thrown: " + e.toString());
423 public void testInvlalidErrors()
425 log.info("testInvalidErrors");
428 requestFactory.setBody(
432 " \"message\": \"Not a Graph-Api-Exception.\",\n" +
433 " \"type\": \"Whatever\",\n" +
434 " \"code\": \"some string\"\n" +
440 clientTemplate.getForObject("ANY", SOME.class);
441 fail("The expected exception was not thrown");
443 catch(HttpClientErrorException e)
445 log.debug("{}", e.toString());
449 fail("A wrong exception was thrown: " + e.toString());
453 requestFactory.setBody(
457 " \"message\": \"Not a Graph-Api-Exception.\",\n" +
458 " \"type\": \"Whatever\",\n" +
465 clientTemplate.getForObject("ANY", SOME.class);
466 fail("The expected exception was not thrown");
468 catch(HttpClientErrorException e)
470 log.debug("{}", e.toString());
474 fail("A wrong exception was thrown: " + e.toString());
478 requestFactory.setBody(
482 " \"message\": \"Not a Graph-Api-Exception.\",\n" +
483 " \"type\": \"Whatever\",\n" +
484 " \"code\": null\n" +
490 clientTemplate.getForObject("ANY", SOME.class);
491 fail("The expected exception was not thrown");
493 catch(HttpClientErrorException e)
495 log.debug("{}", e.toString());
499 fail("A wrong exception was thrown: " + e.toString());
503 requestFactory.setBody(
507 " \"message\": \"Not a Graph-Api-Exception.\",\n" +
508 " \"type\": \"Whatever\"\n" +
514 clientTemplate.getForObject("ANY", SOME.class);
515 fail("The expected exception was not thrown");
517 catch(HttpClientErrorException e)
519 log.debug("{}", e.toString());
523 fail("A wrong exception was thrown: " + e.toString());
527 requestFactory.setBody("{\"error\":{\"message\":null}}");
531 clientTemplate.getForObject("ANY", SOME.class);
532 fail("The expected exception was not thrown");
534 catch(HttpClientErrorException e)
536 log.debug("{}", e.toString());
540 fail("A wrong exception was thrown: " + e.toString());
544 requestFactory.setBody("{\"error\":{\"type\":null}}");
548 clientTemplate.getForObject("ANY", SOME.class);
549 fail("The expected exception was not thrown");
551 catch(HttpClientErrorException e)
553 log.debug("{}", e.toString());
557 fail("A wrong exception was thrown: " + e.toString());
561 requestFactory.setBody("{\"error\":{\"code\":null}}");
565 clientTemplate.getForObject("ANY", SOME.class);
566 fail("The expected exception was not thrown");
568 catch(HttpClientErrorException e)
570 log.debug("{}", e.toString());
574 fail("A wrong exception was thrown: " + e.toString());
578 requestFactory.setBody("{\"error\":{}}");
582 clientTemplate.getForObject("ANY", SOME.class);
583 fail("The expected exception was not thrown");
585 catch(HttpClientErrorException e)
587 log.debug("{}", e.toString());
591 fail("A wrong exception was thrown: " + e.toString());
595 requestFactory.setBody("{\"error\":\"some message\"}");
599 clientTemplate.getForObject("ANY", SOME.class);
600 fail("The expected exception was not thrown");
602 catch(HttpClientErrorException e)
604 log.debug("{}", e.toString());
608 fail("A wrong exception was thrown: " + e.toString());
612 requestFactory.setBody("{\"error\":null}");
616 clientTemplate.getForObject("ANY", SOME.class);
617 fail("The expected exception was not thrown");
619 catch(HttpClientErrorException e)
621 log.debug("{}", e.toString());
625 fail("A wrong exception was thrown: " + e.toString());
629 requestFactory.setBody("{\"some filed\":\"some message\"}");
633 clientTemplate.getForObject("ANY", SOME.class);
634 fail("The expected exception was not thrown");
636 catch(HttpClientErrorException e)
638 log.debug("{}", e.toString());
642 fail("A wrong exception was thrown: " + e.toString());
646 requestFactory.setBody("{}");
650 clientTemplate.getForObject("ANY", SOME.class);
651 fail("The expected exception was not thrown");
653 catch(HttpClientErrorException e)
655 log.debug("{}", e.toString());
659 fail("A wrong exception was thrown: " + e.toString());
663 requestFactory.setBody("");
667 clientTemplate.getForObject("ANY", SOME.class);
668 fail("The expected exception was not thrown");
670 catch(HttpClientErrorException e)
672 log.debug("{}", e.toString());
676 fail("A wrong exception was thrown: " + e.toString());
684 requestFactory = new MockClientHttpRequestFactory();
685 requestFactory.setStatus(HttpStatus.BAD_REQUEST);
686 requestFactory.addHeader("Content-Type", "application/json");
687 clientTemplate.setRequestFactory(requestFactory);
689 clientTemplate.setErrorHandler(
690 new GraphApiErrorHandler(
691 (OAuth2ErrorHandler)clientTemplate.getErrorHandler()
695 clientTemplate.setAccessTokenProvider(new AccessTokenProvider()
698 public OAuth2AccessToken obtainAccessToken(
699 OAuth2ProtectedResourceDetails details,
700 AccessTokenRequest parameters
703 UserRedirectRequiredException,
704 UserApprovalRequiredException,
705 AccessDeniedException
707 return new OAuth2AccessToken() {
710 public Map<String, Object> getAdditionalInformation()
712 throw new UnsupportedOperationException("Not supported yet.");
716 public Set<String> getScope()
718 throw new UnsupportedOperationException("Not supported yet.");
722 public OAuth2RefreshToken getRefreshToken()
724 throw new UnsupportedOperationException("Not supported yet.");
728 public String getTokenType()
734 public boolean isExpired()
740 public Date getExpiration()
742 throw new UnsupportedOperationException("Not supported yet.");
746 public int getExpiresIn()
748 throw new UnsupportedOperationException("Not supported yet.");
752 public String getValue()
760 public boolean supportsResource(OAuth2ProtectedResourceDetails resource)
766 public OAuth2AccessToken refreshAccessToken(
767 OAuth2ProtectedResourceDetails resource,
768 OAuth2RefreshToken refreshToken,
769 AccessTokenRequest request
772 UserRedirectRequiredException
774 throw new UnsupportedOperationException("Not supported yet.");
778 public boolean supportsRefresh(OAuth2ProtectedResourceDetails resource)