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 java.util.Date;
16 import javax.annotation.Resource;
17 import static org.junit.Assert.*;
18 import org.junit.Before;
19 import org.junit.Test;
20 import org.junit.runner.RunWith;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
23 import org.springframework.http.HttpStatus;
24 import org.springframework.security.access.AccessDeniedException;
25 import org.springframework.security.oauth2.client.OAuth2RestTemplate;
26 import org.springframework.security.oauth2.client.http.OAuth2ErrorHandler;
27 import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
28 import org.springframework.security.oauth2.client.resource.UserApprovalRequiredException;
29 import org.springframework.security.oauth2.client.resource.UserRedirectRequiredException;
30 import org.springframework.security.oauth2.client.token.AccessTokenProvider;
31 import org.springframework.security.oauth2.client.token.AccessTokenRequest;
32 import org.springframework.security.oauth2.common.OAuth2AccessToken;
33 import static org.springframework.security.oauth2.common.OAuth2AccessToken.OAUTH2_TYPE;
34 import org.springframework.security.oauth2.common.OAuth2RefreshToken;
35 import org.springframework.test.context.ContextConfiguration;
36 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
37 import org.springframework.web.client.HttpClientErrorException;
45 @RunWith(SpringJUnit4ClassRunner.class)
46 @ContextConfiguration(
48 "classpath:/spring/test-facebook-error-handler.xml"
50 public class GraphApiErrorHandlerTest
52 private static final Logger log =
53 LoggerFactory.getLogger(GraphApiErrorHandlerTest.class);
56 private OAuth2RestTemplate clientTemplate;
58 private MockClientHttpRequestFactory requestFactory;
62 public void testError1()
64 log.info("testError1");
67 requestFactory.setBody(
71 " \"message\": \"An unknown error has occurred.\",\n" +
72 " \"type\": \"OAuthException\",\n" +
79 clientTemplate.getForObject("ANY", SOME.class);
80 fail("The expected exception was not thrown");
82 catch(UnknownErrorException e)
84 log.debug("{}", e.toString());
85 assertEquals("invalid_request", e.getOAuth2ErrorCode());
86 assertEquals(new Integer(1), e.getCode());
87 assertEquals("An unknown error has occurred.", e.getMessage());
88 assertEquals(Type.OAuthException, e.getType());
93 public void testError2()
95 log.info("testError2");
98 requestFactory.setBody(
102 " \"message\": \"An unexpected error has occurred. Please retry your request later.\",\n" +
103 " \"type\": \"OAuthException\",\n" +
110 clientTemplate.getForObject("ANY", SOME.class);
111 fail("The expected exception was not thrown");
113 catch(UnexpectedErrorException e)
115 log.debug("{}", e.toString());
116 assertEquals("invalid_request", e.getOAuth2ErrorCode());
117 assertEquals(new Integer(2), e.getCode());
118 assertEquals("An unexpected error has occurred. Please retry your request later.", e.getMessage());
119 assertEquals(Type.OAuthException, e.getType());
124 public void testError21()
126 log.info("testError21");
129 requestFactory.setBody(
133 " \"message\": \"(#21) Page ID 590408587650316 was migrated to page ID 1421620791415603. Please update your API calls to the new ID\",\n" +
134 " \"type\": \"OAuthException\",\n" +
141 clientTemplate.getForObject("ANY", SOME.class);
142 fail("The expected exception was not thrown");
144 catch(PageMigratedException e)
146 log.debug("{}", e.toString());
147 assertEquals("invalid_request", e.getOAuth2ErrorCode());
148 assertEquals(new Integer(21), e.getCode());
149 assertEquals("(#21) Page ID 590408587650316 was migrated to page ID 1421620791415603. Please update your API calls to the new ID", e.getMessage());
150 assertEquals(Type.OAuthException, e.getType());
155 public void testError100()
157 log.info("testError100");
160 requestFactory.setBody(
164 " \"message\": \"Unsupported get request.\",\n" +
165 " \"type\": \"GraphMethodException\",\n" +
172 clientTemplate.getForObject("ANY", SOME.class);
173 fail("The expected exception was not thrown");
175 catch(UnsupportedGetRequestException e)
177 log.debug("{}", e.toString());
178 assertEquals("invalid_request", e.getOAuth2ErrorCode());
179 assertEquals(new Integer(100), e.getCode());
180 assertEquals("Unsupported get request.", e.getMessage());
181 assertEquals(Type.GraphMethodException, e.getType());
186 public void testError104()
188 log.info("testError104");
190 requestFactory.setBody("{\"error\":{\"message\":\"An access token is required to request this resource.\",\"type\":\"OAuthException\",\"code\":104,\"fbtrace_id\":\"E2Jjkj5++LL\"}}");
194 clientTemplate.getForObject("ANY", SOME.class);
195 fail("The expected exception was not thrown");
197 catch(AccessTokenRequiredException e)
199 log.debug("{}", e.toString());
200 assertEquals("invalid_request", e.getOAuth2ErrorCode());
201 assertEquals(new Integer(104), e.getCode());
202 assertEquals("An access token is required to request this resource.", e.getMessage());
203 assertEquals(Type.OAuthException, e.getType());
204 assertEquals("E2Jjkj5++LL", e.getTraceId());
209 public void testError613()
211 log.info("testError613");
214 requestFactory.setBody(
218 " \"message\": \"(#613) Calls to stream have exceeded the rate of 600 calls per 600 seconds.\",\n" +
219 " \"type\": \"OAuthException\",\n" +
226 clientTemplate.getForObject("ANY", SOME.class);
227 fail("The expected exception was not thrown");
229 catch(RateExceededException e)
231 log.debug("{}", e.toString());
232 assertEquals("invalid_request", e.getOAuth2ErrorCode());
233 assertEquals(new Integer(613), e.getCode());
234 assertEquals("(#613) Calls to stream have exceeded the rate of 600 calls per 600 seconds.", e.getMessage());
235 assertEquals(Type.OAuthException, e.getType());
240 public void testError2200()
242 requestFactory.setBody("{\"error\":{\"message\":\"(#2200) callback verification failed: \",\"type\":\"OAuthException\",\"code\":2200,\"fbtrace_id\":\"ESLjoZKvPXg\"}}");
246 clientTemplate.getForObject("ANY", SOME.class);
247 fail("The expected exception was not thrown");
249 catch(CallbackVerificationFailedException e)
251 log.debug("{}", e.toString());
252 assertEquals("invalid_request", e.getOAuth2ErrorCode());
253 assertEquals(new Integer(2200), e.getCode());
254 assertEquals("(#2200) callback verification failed: ", e.getMessage());
255 assertEquals(Type.OAuthException, e.getType());
256 assertEquals("ESLjoZKvPXg", e.getTraceId());
261 public void testUnmappedError()
263 log.info("testUnmappedError");
266 requestFactory.setBody(
270 " \"message\": \"This error does not exist.\",\n" +
271 " \"type\": \"NonexistentTypeException\",\n" +
272 " \"code\": 999999999\n" +
278 clientTemplate.getForObject("ANY", SOME.class);
279 fail("The expected exception was not thrown");
281 catch(GraphApiException e)
283 log.debug("{}", e.toString());
284 assertEquals("invalid_request", e.getOAuth2ErrorCode());
285 assertEquals(new Integer(999999999), e.getCode());
286 assertEquals("This error does not exist.", e.getMessage());
289 Type type = e.getType();
290 log.error("unknown type: {}", type);
291 fail("unmapped type was resolved by enum: " + type);
293 catch (IllegalArgumentException ee) {}
298 public void testUnmappedErrors()
300 log.info("testUnmappedErrors");
303 requestFactory.setBody(
307 " \"message\": null,\n" +
308 " \"type\": \"WhateverTypeException\",\n" +
309 " \"code\": 999999999\n" +
315 clientTemplate.getForObject("ANY", SOME.class);
316 fail("The expected exception was not thrown");
318 catch(UnmappedErrorException e)
320 log.debug("{}", e.toString());
321 assertNull(e.getMessage());
324 Type type = e.getType();
325 log.error("unknown type: {}", type);
326 fail("unmapped type was resolved by enum: " + type);
328 catch (IllegalArgumentException ee) {}
329 assertEquals(new Integer(999999999), e.getCode());
330 assertNull(e.getSubCode());
331 assertNull(e.getUserTitle());
332 assertNull(e.getUserMessage());
333 assertNull(e.getTraceId());
337 fail("A wrong exception was thrown: " + e.toString());
341 requestFactory.setBody(
345 " \"type\": \"WhateverTypeException\",\n" +
346 " \"code\": 999999999\n" +
352 clientTemplate.getForObject("ANY", SOME.class);
353 fail("The expected exception was not thrown");
355 catch(UnmappedErrorException e)
357 log.debug("{}", e.toString());
358 assertNull(e.getMessage());
361 Type type = e.getType();
362 log.error("unknown type: {}", type);
363 fail("unmapped type was resolved by enum: " + type);
365 catch (IllegalArgumentException ee) {}
366 assertEquals(new Integer(999999999), e.getCode());
367 assertNull(e.getSubCode());
368 assertNull(e.getUserTitle());
369 assertNull(e.getUserMessage());
370 assertNull(e.getTraceId());
374 fail("A wrong exception was thrown: " + e.toString());
378 requestFactory.setBody(
382 " \"message\": \"An unmapped Graph-API-Exception.\",\n" +
383 " \"type\": null,\n" +
384 " \"code\": 999999999\n" +
390 clientTemplate.getForObject("ANY", SOME.class);
391 fail("The expected exception was not thrown");
393 catch(UnmappedErrorException e)
395 log.debug("{}", e.toString());
396 assertEquals("An unmapped Graph-API-Exception.", e.getMessage());
397 assertNull(e.getType());
398 assertEquals(new Integer(999999999), e.getCode());
399 assertNull(e.getSubCode());
400 assertNull(e.getUserTitle());
401 assertNull(e.getUserMessage());
402 assertNull(e.getTraceId());
406 fail("A wrong exception was thrown: " + e.toString());
410 requestFactory.setBody(
414 " \"message\": \"An unmapped Graph-API-Exception.\",\n" +
415 " \"code\": 999999999\n" +
421 clientTemplate.getForObject("ANY", SOME.class);
422 fail("The expected exception was not thrown");
424 catch(UnmappedErrorException e)
426 log.debug("{}", e.toString());
427 assertEquals("An unmapped Graph-API-Exception.", e.getMessage());
428 assertNull(e.getType());
429 assertEquals(new Integer(999999999), e.getCode());
430 assertNull(e.getSubCode());
431 assertNull(e.getUserTitle());
432 assertNull(e.getUserMessage());
433 assertNull(e.getTraceId());
437 fail("A wrong exception was thrown: " + e.toString());
442 public void testInvlalidErrors()
444 log.info("testInvalidErrors");
447 requestFactory.setBody(
451 " \"message\": \"Not a Graph-Api-Exception.\",\n" +
452 " \"type\": \"Whatever\",\n" +
453 " \"code\": \"some string\"\n" +
459 clientTemplate.getForObject("ANY", SOME.class);
460 fail("The expected exception was not thrown");
462 catch(HttpClientErrorException e)
464 log.debug("{}", e.toString());
468 fail("A wrong exception was thrown: " + e.toString());
472 requestFactory.setBody(
476 " \"message\": \"Not a Graph-Api-Exception.\",\n" +
477 " \"type\": \"Whatever\",\n" +
484 clientTemplate.getForObject("ANY", SOME.class);
485 fail("The expected exception was not thrown");
487 catch(HttpClientErrorException e)
489 log.debug("{}", e.toString());
493 fail("A wrong exception was thrown: " + e.toString());
497 requestFactory.setBody(
501 " \"message\": \"Not a Graph-Api-Exception.\",\n" +
502 " \"type\": \"Whatever\",\n" +
503 " \"code\": null\n" +
509 clientTemplate.getForObject("ANY", SOME.class);
510 fail("The expected exception was not thrown");
512 catch(HttpClientErrorException e)
514 log.debug("{}", e.toString());
518 fail("A wrong exception was thrown: " + e.toString());
522 requestFactory.setBody(
526 " \"message\": \"Not a Graph-Api-Exception.\",\n" +
527 " \"type\": \"Whatever\"\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("{\"error\":{\"message\":null}}");
550 clientTemplate.getForObject("ANY", SOME.class);
551 fail("The expected exception was not thrown");
553 catch(HttpClientErrorException e)
555 log.debug("{}", e.toString());
559 fail("A wrong exception was thrown: " + e.toString());
563 requestFactory.setBody("{\"error\":{\"type\":null}}");
567 clientTemplate.getForObject("ANY", SOME.class);
568 fail("The expected exception was not thrown");
570 catch(HttpClientErrorException e)
572 log.debug("{}", e.toString());
576 fail("A wrong exception was thrown: " + e.toString());
580 requestFactory.setBody("{\"error\":{\"code\":null}}");
584 clientTemplate.getForObject("ANY", SOME.class);
585 fail("The expected exception was not thrown");
587 catch(HttpClientErrorException e)
589 log.debug("{}", e.toString());
593 fail("A wrong exception was thrown: " + e.toString());
597 requestFactory.setBody("{\"error\":{}}");
601 clientTemplate.getForObject("ANY", SOME.class);
602 fail("The expected exception was not thrown");
604 catch(HttpClientErrorException e)
606 log.debug("{}", e.toString());
610 fail("A wrong exception was thrown: " + e.toString());
614 requestFactory.setBody("{\"error\":\"some message\"}");
618 clientTemplate.getForObject("ANY", SOME.class);
619 fail("The expected exception was not thrown");
621 catch(HttpClientErrorException e)
623 log.debug("{}", e.toString());
627 fail("A wrong exception was thrown: " + e.toString());
631 requestFactory.setBody("{\"error\":null}");
635 clientTemplate.getForObject("ANY", SOME.class);
636 fail("The expected exception was not thrown");
638 catch(HttpClientErrorException e)
640 log.debug("{}", e.toString());
644 fail("A wrong exception was thrown: " + e.toString());
648 requestFactory.setBody("{\"some filed\":\"some message\"}");
652 clientTemplate.getForObject("ANY", SOME.class);
653 fail("The expected exception was not thrown");
655 catch(HttpClientErrorException e)
657 log.debug("{}", e.toString());
661 fail("A wrong exception was thrown: " + e.toString());
665 requestFactory.setBody("{}");
669 clientTemplate.getForObject("ANY", SOME.class);
670 fail("The expected exception was not thrown");
672 catch(HttpClientErrorException e)
674 log.debug("{}", e.toString());
678 fail("A wrong exception was thrown: " + e.toString());
682 requestFactory.setBody("");
686 clientTemplate.getForObject("ANY", SOME.class);
687 fail("The expected exception was not thrown");
689 catch(HttpClientErrorException e)
691 log.debug("{}", e.toString());
695 fail("A wrong exception was thrown: " + e.toString());
703 requestFactory = new MockClientHttpRequestFactory();
704 requestFactory.setStatus(HttpStatus.BAD_REQUEST);
705 requestFactory.addHeader("Content-Type", "application/json");
706 clientTemplate.setRequestFactory(requestFactory);
708 clientTemplate.setErrorHandler(
709 new GraphApiErrorHandler(
710 (OAuth2ErrorHandler)clientTemplate.getErrorHandler()
714 clientTemplate.setAccessTokenProvider(new AccessTokenProvider()
717 public OAuth2AccessToken obtainAccessToken(
718 OAuth2ProtectedResourceDetails details,
719 AccessTokenRequest parameters
722 UserRedirectRequiredException,
723 UserApprovalRequiredException,
724 AccessDeniedException
726 return new OAuth2AccessToken() {
729 public Map<String, Object> getAdditionalInformation()
731 throw new UnsupportedOperationException("Not supported yet.");
735 public Set<String> getScope()
737 throw new UnsupportedOperationException("Not supported yet.");
741 public OAuth2RefreshToken getRefreshToken()
743 throw new UnsupportedOperationException("Not supported yet.");
747 public String getTokenType()
753 public boolean isExpired()
759 public Date getExpiration()
761 throw new UnsupportedOperationException("Not supported yet.");
765 public int getExpiresIn()
767 throw new UnsupportedOperationException("Not supported yet.");
771 public String getValue()
779 public boolean supportsResource(OAuth2ProtectedResourceDetails resource)
785 public OAuth2AccessToken refreshAccessToken(
786 OAuth2ProtectedResourceDetails resource,
787 OAuth2RefreshToken refreshToken,
788 AccessTokenRequest request
791 UserRedirectRequiredException
793 throw new UnsupportedOperationException("Not supported yet.");
797 public boolean supportsRefresh(OAuth2ProtectedResourceDetails resource)