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.GraphApiException.Type;
10 import de.juplo.facebook.exceptions.UnknownErrorException;
11 import de.juplo.facebook.exceptions.PageMigratedException;
12 import de.juplo.facebook.exceptions.UnmappedErrorException;
13 import de.juplo.facebook.exceptions.UserAccessTokenRequiredException;
14 import java.util.Date;
17 import javax.annotation.Resource;
18 import static org.junit.Assert.*;
19 import org.junit.Before;
20 import org.junit.Test;
21 import org.junit.runner.RunWith;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24 import org.springframework.http.HttpStatus;
25 import org.springframework.security.access.AccessDeniedException;
26 import org.springframework.security.oauth2.client.OAuth2RestTemplate;
27 import org.springframework.security.oauth2.client.http.OAuth2ErrorHandler;
28 import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
29 import org.springframework.security.oauth2.client.resource.UserApprovalRequiredException;
30 import org.springframework.security.oauth2.client.resource.UserRedirectRequiredException;
31 import org.springframework.security.oauth2.client.token.AccessTokenProvider;
32 import org.springframework.security.oauth2.client.token.AccessTokenRequest;
33 import org.springframework.security.oauth2.common.OAuth2AccessToken;
34 import static org.springframework.security.oauth2.common.OAuth2AccessToken.OAUTH2_TYPE;
35 import org.springframework.security.oauth2.common.OAuth2RefreshToken;
36 import org.springframework.test.context.ContextConfiguration;
37 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
38 import org.springframework.web.client.HttpClientErrorException;
46 @RunWith(SpringJUnit4ClassRunner.class)
47 @ContextConfiguration(
49 "classpath:/spring/test-facebook-error-handler.xml"
51 public class GraphApiErrorHandlerTest
53 private static final Logger log =
54 LoggerFactory.getLogger(GraphApiErrorHandlerTest.class);
57 private OAuth2RestTemplate clientTemplate;
59 private MockClientHttpRequestFactory requestFactory;
63 public void testError1()
65 log.info("testError1");
68 requestFactory.setBody(
72 " \"message\": \"An unknown error has occurred.\",\n" +
73 " \"type\": \"OAuthException\",\n" +
80 clientTemplate.getForObject("ANY", SOME.class);
81 fail("The expected exception was not thrown");
83 catch(UnknownErrorException e)
85 log.debug("{}", e.toString());
86 assertEquals("invalid_request", e.getOAuth2ErrorCode());
87 assertEquals(new Integer(1), e.getCode());
88 assertEquals("An unknown error has occurred.", e.getMessage());
89 assertEquals(Type.OAuthException, e.getType());
94 public void testError2()
96 log.info("testError2");
99 requestFactory.setBody(
103 " \"message\": \"An unexpected error has occurred. Please retry your request later.\",\n" +
104 " \"type\": \"OAuthException\",\n" +
111 clientTemplate.getForObject("ANY", SOME.class);
112 fail("The expected exception was not thrown");
114 catch(UnexpectedErrorException e)
116 log.debug("{}", e.toString());
117 assertEquals("invalid_request", e.getOAuth2ErrorCode());
118 assertEquals(new Integer(2), e.getCode());
119 assertEquals("An unexpected error has occurred. Please retry your request later.", e.getMessage());
120 assertEquals(Type.OAuthException, e.getType());
125 public void testError21()
127 log.info("testError21");
130 requestFactory.setBody(
134 " \"message\": \"(#21) Page ID 590408587650316 was migrated to page ID 1421620791415603. Please update your API calls to the new ID\",\n" +
135 " \"type\": \"OAuthException\",\n" +
142 clientTemplate.getForObject("ANY", SOME.class);
143 fail("The expected exception was not thrown");
145 catch(PageMigratedException e)
147 log.debug("{}", e.toString());
148 assertEquals("invalid_request", e.getOAuth2ErrorCode());
149 assertEquals(new Integer(21), e.getCode());
150 assertEquals("(#21) Page ID 590408587650316 was migrated to page ID 1421620791415603. Please update your API calls to the new ID", e.getMessage());
151 assertEquals(Type.OAuthException, e.getType());
156 public void testError100()
158 log.info("testError100");
161 requestFactory.setBody(
165 " \"message\": \"Unsupported get request.\",\n" +
166 " \"type\": \"GraphMethodException\",\n" +
173 clientTemplate.getForObject("ANY", SOME.class);
174 fail("The expected exception was not thrown");
176 catch(UnsupportedGetRequestException e)
178 log.debug("{}", e.toString());
179 assertEquals("invalid_request", e.getOAuth2ErrorCode());
180 assertEquals(new Integer(100), e.getCode());
181 assertEquals("Unsupported get request.", e.getMessage());
182 assertEquals(Type.GraphMethodException, e.getType());
187 public void testError102()
189 log.info("testError102");
191 requestFactory.setBody("{\"error\":{\"message\":\"A user access token is required to request this resource.\",\"type\":\"OAuthException\",\"code\":102,\"fbtrace_id\":\"DhdMyf23Ki7\"}}");
195 clientTemplate.getForObject("ANY", SOME.class);
196 fail("The expected exception was not thrown");
198 catch(UserAccessTokenRequiredException e)
200 log.debug("{}", e.toString());
201 assertEquals("invalid_request", e.getOAuth2ErrorCode());
202 assertEquals(new Integer(102), e.getCode());
203 assertEquals("A user access token is required to request this resource.", e.getMessage());
204 assertEquals(Type.OAuthException, e.getType());
205 assertEquals("DhdMyf23Ki7", e.getTraceId());
210 public void testError104()
212 log.info("testError104");
214 requestFactory.setBody("{\"error\":{\"message\":\"An access token is required to request this resource.\",\"type\":\"OAuthException\",\"code\":104,\"fbtrace_id\":\"E2Jjkj5++LL\"}}");
218 clientTemplate.getForObject("ANY", SOME.class);
219 fail("The expected exception was not thrown");
221 catch(AccessTokenRequiredException e)
223 log.debug("{}", e.toString());
224 assertEquals("invalid_request", e.getOAuth2ErrorCode());
225 assertEquals(new Integer(104), e.getCode());
226 assertEquals("An access token is required to request this resource.", e.getMessage());
227 assertEquals(Type.OAuthException, e.getType());
228 assertEquals("E2Jjkj5++LL", e.getTraceId());
233 public void testError613()
235 log.info("testError613");
238 requestFactory.setBody(
242 " \"message\": \"(#613) Calls to stream have exceeded the rate of 600 calls per 600 seconds.\",\n" +
243 " \"type\": \"OAuthException\",\n" +
250 clientTemplate.getForObject("ANY", SOME.class);
251 fail("The expected exception was not thrown");
253 catch(RateExceededException e)
255 log.debug("{}", e.toString());
256 assertEquals("invalid_request", e.getOAuth2ErrorCode());
257 assertEquals(new Integer(613), e.getCode());
258 assertEquals("(#613) Calls to stream have exceeded the rate of 600 calls per 600 seconds.", e.getMessage());
259 assertEquals(Type.OAuthException, e.getType());
264 public void testError2200()
266 requestFactory.setBody("{\"error\":{\"message\":\"(#2200) callback verification failed: \",\"type\":\"OAuthException\",\"code\":2200,\"fbtrace_id\":\"ESLjoZKvPXg\"}}");
270 clientTemplate.getForObject("ANY", SOME.class);
271 fail("The expected exception was not thrown");
273 catch(CallbackVerificationFailedException e)
275 log.debug("{}", e.toString());
276 assertEquals("invalid_request", e.getOAuth2ErrorCode());
277 assertEquals(new Integer(2200), e.getCode());
278 assertEquals("(#2200) callback verification failed: ", e.getMessage());
279 assertEquals(Type.OAuthException, e.getType());
280 assertEquals("ESLjoZKvPXg", e.getTraceId());
285 public void testUnmappedError()
287 log.info("testUnmappedError");
290 requestFactory.setBody(
294 " \"message\": \"This error does not exist.\",\n" +
295 " \"type\": \"NonexistentTypeException\",\n" +
296 " \"code\": 999999999\n" +
302 clientTemplate.getForObject("ANY", SOME.class);
303 fail("The expected exception was not thrown");
305 catch(GraphApiException e)
307 log.debug("{}", e.toString());
308 assertEquals("invalid_request", e.getOAuth2ErrorCode());
309 assertEquals(new Integer(999999999), e.getCode());
310 assertEquals("This error does not exist.", e.getMessage());
313 Type type = e.getType();
314 log.error("unknown type: {}", type);
315 fail("unmapped type was resolved by enum: " + type);
317 catch (IllegalArgumentException ee) {}
322 public void testUnmappedErrors()
324 log.info("testUnmappedErrors");
327 requestFactory.setBody(
331 " \"message\": null,\n" +
332 " \"type\": \"WhateverTypeException\",\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());
348 Type type = e.getType();
349 log.error("unknown type: {}", type);
350 fail("unmapped type was resolved by enum: " + type);
352 catch (IllegalArgumentException ee) {}
353 assertEquals(new Integer(999999999), e.getCode());
354 assertNull(e.getSubCode());
355 assertNull(e.getUserTitle());
356 assertNull(e.getUserMessage());
357 assertNull(e.getTraceId());
361 fail("A wrong exception was thrown: " + e.toString());
365 requestFactory.setBody(
369 " \"type\": \"WhateverTypeException\",\n" +
370 " \"code\": 999999999\n" +
376 clientTemplate.getForObject("ANY", SOME.class);
377 fail("The expected exception was not thrown");
379 catch(UnmappedErrorException e)
381 log.debug("{}", e.toString());
382 assertNull(e.getMessage());
385 Type type = e.getType();
386 log.error("unknown type: {}", type);
387 fail("unmapped type was resolved by enum: " + type);
389 catch (IllegalArgumentException ee) {}
390 assertEquals(new Integer(999999999), e.getCode());
391 assertNull(e.getSubCode());
392 assertNull(e.getUserTitle());
393 assertNull(e.getUserMessage());
394 assertNull(e.getTraceId());
398 fail("A wrong exception was thrown: " + e.toString());
402 requestFactory.setBody(
406 " \"message\": \"An unmapped Graph-API-Exception.\",\n" +
407 " \"type\": null,\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());
434 requestFactory.setBody(
438 " \"message\": \"An unmapped Graph-API-Exception.\",\n" +
439 " \"code\": 999999999\n" +
445 clientTemplate.getForObject("ANY", SOME.class);
446 fail("The expected exception was not thrown");
448 catch(UnmappedErrorException e)
450 log.debug("{}", e.toString());
451 assertEquals("An unmapped Graph-API-Exception.", e.getMessage());
452 assertNull(e.getType());
453 assertEquals(new Integer(999999999), e.getCode());
454 assertNull(e.getSubCode());
455 assertNull(e.getUserTitle());
456 assertNull(e.getUserMessage());
457 assertNull(e.getTraceId());
461 fail("A wrong exception was thrown: " + e.toString());
466 public void testInvlalidErrors()
468 log.info("testInvalidErrors");
471 requestFactory.setBody(
475 " \"message\": \"Not a Graph-Api-Exception.\",\n" +
476 " \"type\": \"Whatever\",\n" +
477 " \"code\": \"some string\"\n" +
483 clientTemplate.getForObject("ANY", SOME.class);
484 fail("The expected exception was not thrown");
486 catch(HttpClientErrorException e)
488 log.debug("{}", e.toString());
492 fail("A wrong exception was thrown: " + e.toString());
496 requestFactory.setBody(
500 " \"message\": \"Not a Graph-Api-Exception.\",\n" +
501 " \"type\": \"Whatever\",\n" +
508 clientTemplate.getForObject("ANY", SOME.class);
509 fail("The expected exception was not thrown");
511 catch(HttpClientErrorException e)
513 log.debug("{}", e.toString());
517 fail("A wrong exception was thrown: " + e.toString());
521 requestFactory.setBody(
525 " \"message\": \"Not a Graph-Api-Exception.\",\n" +
526 " \"type\": \"Whatever\",\n" +
527 " \"code\": null\n" +
533 clientTemplate.getForObject("ANY", SOME.class);
534 fail("The expected exception was not thrown");
536 catch(HttpClientErrorException e)
538 log.debug("{}", e.toString());
542 fail("A wrong exception was thrown: " + e.toString());
546 requestFactory.setBody(
550 " \"message\": \"Not a Graph-Api-Exception.\",\n" +
551 " \"type\": \"Whatever\"\n" +
557 clientTemplate.getForObject("ANY", SOME.class);
558 fail("The expected exception was not thrown");
560 catch(HttpClientErrorException e)
562 log.debug("{}", e.toString());
566 fail("A wrong exception was thrown: " + e.toString());
570 requestFactory.setBody("{\"error\":{\"message\":null}}");
574 clientTemplate.getForObject("ANY", SOME.class);
575 fail("The expected exception was not thrown");
577 catch(HttpClientErrorException e)
579 log.debug("{}", e.toString());
583 fail("A wrong exception was thrown: " + e.toString());
587 requestFactory.setBody("{\"error\":{\"type\":null}}");
591 clientTemplate.getForObject("ANY", SOME.class);
592 fail("The expected exception was not thrown");
594 catch(HttpClientErrorException e)
596 log.debug("{}", e.toString());
600 fail("A wrong exception was thrown: " + e.toString());
604 requestFactory.setBody("{\"error\":{\"code\":null}}");
608 clientTemplate.getForObject("ANY", SOME.class);
609 fail("The expected exception was not thrown");
611 catch(HttpClientErrorException e)
613 log.debug("{}", e.toString());
617 fail("A wrong exception was thrown: " + e.toString());
621 requestFactory.setBody("{\"error\":{}}");
625 clientTemplate.getForObject("ANY", SOME.class);
626 fail("The expected exception was not thrown");
628 catch(HttpClientErrorException e)
630 log.debug("{}", e.toString());
634 fail("A wrong exception was thrown: " + e.toString());
638 requestFactory.setBody("{\"error\":\"some message\"}");
642 clientTemplate.getForObject("ANY", SOME.class);
643 fail("The expected exception was not thrown");
645 catch(HttpClientErrorException e)
647 log.debug("{}", e.toString());
651 fail("A wrong exception was thrown: " + e.toString());
655 requestFactory.setBody("{\"error\":null}");
659 clientTemplate.getForObject("ANY", SOME.class);
660 fail("The expected exception was not thrown");
662 catch(HttpClientErrorException e)
664 log.debug("{}", e.toString());
668 fail("A wrong exception was thrown: " + e.toString());
672 requestFactory.setBody("{\"some filed\":\"some message\"}");
676 clientTemplate.getForObject("ANY", SOME.class);
677 fail("The expected exception was not thrown");
679 catch(HttpClientErrorException e)
681 log.debug("{}", e.toString());
685 fail("A wrong exception was thrown: " + e.toString());
689 requestFactory.setBody("{}");
693 clientTemplate.getForObject("ANY", SOME.class);
694 fail("The expected exception was not thrown");
696 catch(HttpClientErrorException e)
698 log.debug("{}", e.toString());
702 fail("A wrong exception was thrown: " + e.toString());
706 requestFactory.setBody("");
710 clientTemplate.getForObject("ANY", SOME.class);
711 fail("The expected exception was not thrown");
713 catch(HttpClientErrorException e)
715 log.debug("{}", e.toString());
719 fail("A wrong exception was thrown: " + e.toString());
727 requestFactory = new MockClientHttpRequestFactory();
728 requestFactory.setStatus(HttpStatus.BAD_REQUEST);
729 requestFactory.addHeader("Content-Type", "application/json");
730 clientTemplate.setRequestFactory(requestFactory);
732 clientTemplate.setErrorHandler(
733 new GraphApiErrorHandler(
734 (OAuth2ErrorHandler)clientTemplate.getErrorHandler()
738 clientTemplate.setAccessTokenProvider(new AccessTokenProvider()
741 public OAuth2AccessToken obtainAccessToken(
742 OAuth2ProtectedResourceDetails details,
743 AccessTokenRequest parameters
746 UserRedirectRequiredException,
747 UserApprovalRequiredException,
748 AccessDeniedException
750 return new OAuth2AccessToken() {
753 public Map<String, Object> getAdditionalInformation()
755 throw new UnsupportedOperationException("Not supported yet.");
759 public Set<String> getScope()
761 throw new UnsupportedOperationException("Not supported yet.");
765 public OAuth2RefreshToken getRefreshToken()
767 throw new UnsupportedOperationException("Not supported yet.");
771 public String getTokenType()
777 public boolean isExpired()
783 public Date getExpiration()
785 throw new UnsupportedOperationException("Not supported yet.");
789 public int getExpiresIn()
791 throw new UnsupportedOperationException("Not supported yet.");
795 public String getValue()
803 public boolean supportsResource(OAuth2ProtectedResourceDetails resource)
809 public OAuth2AccessToken refreshAccessToken(
810 OAuth2ProtectedResourceDetails resource,
811 OAuth2RefreshToken refreshToken,
812 AccessTokenRequest request
815 UserRedirectRequiredException
817 throw new UnsupportedOperationException("Not supported yet.");
821 public boolean supportsRefresh(OAuth2ProtectedResourceDetails resource)