d93121bfa0041390551e59e2feb86144ed6172c0
[facebook-utils] / src / test / java / de / juplo / facebook / GraphApiErrorHandlerTest.java
1 package de.juplo.facebook;
2
3 import java.util.Date;
4 import java.util.Map;
5 import java.util.Set;
6 import javax.annotation.Resource;
7 import static org.junit.Assert.*;
8 import org.junit.Before;
9 import org.junit.Test;
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;
29
30
31
32 /**
33  *
34  * @author kai
35  */
36 @RunWith(SpringJUnit4ClassRunner.class)
37 @ContextConfiguration(
38   locations = {
39     "classpath:/spring/test-facebook-error-handler.xml"
40     })
41 public class GraphApiErrorHandlerTest
42 {
43   private static final Logger log =
44       LoggerFactory.getLogger(GraphApiErrorHandlerTest.class);
45
46   @Resource
47   private OAuth2RestTemplate clientTemplate;
48
49   private MockClientHttpRequestFactory requestFactory;
50
51
52   @Test
53   public void testError1()
54   {
55     log.info("testError1");
56
57
58     requestFactory.setBody(
59         "{\n" +
60         "  \"error\":\n" +
61         "  {\n" +
62         "    \"message\": \"An unknown error has occurred.\",\n" +
63         "    \"type\": \"OAuthException\",\n" +
64         "    \"code\": 1\n" +
65         "  }\n" +
66         "}");
67
68     try
69     {
70       clientTemplate.getForObject("ANY", SOME.class);
71       fail("The expected exception was not thrown");
72     }
73     catch(UnknownErrorException e)
74     {
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());
80     }
81   }
82
83   @Test
84   public void testError2()
85   {
86     log.info("testError2");
87
88
89     requestFactory.setBody(
90         "{\n" +
91         "  \"error\":\n" +
92         "  {\n" +
93         "    \"message\": \"An unexpected error has occurred. Please retry your request later.\",\n" +
94         "    \"type\": \"OAuthException\",\n" +
95         "    \"code\": 2\n" +
96         "  }\n" +
97         "}");
98
99     try
100     {
101       clientTemplate.getForObject("ANY", SOME.class);
102       fail("The expected exception was not thrown");
103     }
104     catch(UnexpectedErrorException e)
105     {
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());
111     }
112   }
113
114   @Test
115   public void testError21()
116   {
117     log.info("testError21");
118
119
120     requestFactory.setBody(
121         "{\n" +
122         "  \"error\":\n" +
123         "  {\n" +
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" +
126         "    \"code\": 21\n" +
127         "  }\n" +
128         "}");
129
130     try
131     {
132       clientTemplate.getForObject("ANY", SOME.class);
133       fail("The expected exception was not thrown");
134     }
135     catch(PageMigratedException e)
136     {
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());
142     }
143   }
144
145   @Test
146   public void testError100()
147   {
148     log.info("testError100");
149
150
151     requestFactory.setBody(
152         "{\n" +
153         "  \"error\":\n" +
154         "  {\n" +
155         "    \"message\": \"Unsupported get request.\",\n" +
156         "    \"type\": \"GraphMethodException\",\n" +
157         "    \"code\": 100\n" +
158         "  }\n" +
159         "}");
160
161     try
162     {
163       clientTemplate.getForObject("ANY", SOME.class);
164       fail("The expected exception was not thrown");
165     }
166     catch(UnsupportedGetRequestException e)
167     {
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());
173     }
174   }
175
176   @Test
177   public void testError613()
178   {
179     log.info("testError613");
180
181
182     requestFactory.setBody(
183         "{\n" +
184         "  \"error\":\n" +
185         "  {\n" +
186         "    \"message\": \"(#613) Calls to stream have exceeded the rate of 600 calls per 600 seconds.\",\n" +
187         "    \"type\": \"OAuthException\",\n" +
188         "    \"code\": 613\n" +
189         "  }\n" +
190         "}");
191
192     try
193     {
194       clientTemplate.getForObject("ANY", SOME.class);
195       fail("The expected exception was not thrown");
196     }
197     catch(RateExceededException e)
198     {
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());
204     }
205   }
206
207   @Test
208   public void testUnmappedError()
209   {
210     log.info("testUnmappedError");
211
212
213     requestFactory.setBody(
214         "{\n" +
215         "  \"error\":\n" +
216         "  {\n" +
217         "    \"message\": \"This error does not exist.\",\n" +
218         "    \"type\": \"NonexistentException\",\n" +
219         "    \"code\": 999999999\n" +
220         "  }\n" +
221         "}");
222
223     try
224     {
225       clientTemplate.getForObject("ANY", SOME.class);
226       fail("The expected exception was not thrown");
227     }
228     catch(GraphApiException e)
229     {
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());
235     }
236   }
237
238   @Test
239   public void testInvlalidErrors()
240   {
241     log.info("testInvalidErrors");
242
243
244     requestFactory.setBody(
245         "{\n" +
246         "  \"error\":\n" +
247         "  {\n" +
248         "    \"message\": null,\n" +
249         "    \"type\": \"Whatever\",\n" +
250         "    \"code\": 999999999\n" +
251         "  }\n" +
252         "}");
253
254     try
255     {
256       clientTemplate.getForObject("ANY", SOME.class);
257       fail("The expected exception was not thrown");
258     }
259     catch(OAuth2Exception e)
260     {
261       log.debug("{}", e.toString());
262       assertEquals("invalid_request", e.getOAuth2ErrorCode());
263       assertFalse(e instanceof GraphApiException);
264     }
265
266
267     requestFactory.setBody(
268         "{\n" +
269         "  \"error\":\n" +
270         "  {\n" +
271         "    \"type\": \"Whatever\",\n" +
272         "    \"code\": 999999999\n" +
273         "  }\n" +
274         "}");
275
276     try
277     {
278       clientTemplate.getForObject("ANY", SOME.class);
279       fail("The expected exception was not thrown");
280     }
281     catch(OAuth2Exception e)
282     {
283       log.debug("{}", e.toString());
284       assertEquals("invalid_request", e.getOAuth2ErrorCode());
285       assertFalse(e instanceof GraphApiException);
286     }
287
288
289     requestFactory.setBody(
290         "{\n" +
291         "  \"error\":\n" +
292         "  {\n" +
293         "    \"message\": \"Not a Graph-Api-Exception.\",\n" +
294         "    \"type\": null,\n" +
295         "    \"code\": 999999999\n" +
296         "  }\n" +
297         "}");
298
299     try
300     {
301       clientTemplate.getForObject("ANY", SOME.class);
302       fail("The expected exception was not thrown");
303     }
304     catch(OAuth2Exception e)
305     {
306       log.debug("{}", e.toString());
307       assertEquals("invalid_request", e.getOAuth2ErrorCode());
308       assertFalse(e instanceof GraphApiException);
309     }
310
311
312     requestFactory.setBody(
313         "{\n" +
314         "  \"error\":\n" +
315         "  {\n" +
316         "    \"message\": \"Not a Graph-Api-Exception.\",\n" +
317         "    \"code\": 999999999\n" +
318         "  }\n" +
319         "}");
320
321     try
322     {
323       clientTemplate.getForObject("ANY", SOME.class);
324       fail("The expected exception was not thrown");
325     }
326     catch(OAuth2Exception e)
327     {
328       log.debug("{}", e.toString());
329       assertEquals("invalid_request", e.getOAuth2ErrorCode());
330       assertFalse(e instanceof GraphApiException);
331     }
332
333
334     requestFactory.setBody(
335         "{\n" +
336         "  \"error\":\n" +
337         "  {\n" +
338         "    \"message\": \"Not a Graph-Api-Exception.\",\n" +
339         "    \"type\": \"Whatever\",\n" +
340         "    \"code\": \"some string\"\n" +
341         "  }\n" +
342         "}");
343
344     try
345     {
346       clientTemplate.getForObject("ANY", SOME.class);
347       fail("The expected exception was not thrown");
348     }
349     catch(OAuth2Exception e)
350     {
351       log.debug("{}", e.toString());
352       assertEquals("invalid_request", e.getOAuth2ErrorCode());
353       assertFalse(e instanceof GraphApiException);
354     }
355
356
357     requestFactory.setBody(
358         "{\n" +
359         "  \"error\":\n" +
360         "  {\n" +
361         "    \"message\": \"Not a Graph-Api-Exception.\",\n" +
362         "    \"type\": \"Whatever\",\n" +
363         "    \"code\": 9.9\n" +
364         "  }\n" +
365         "}");
366
367     try
368     {
369       clientTemplate.getForObject("ANY", SOME.class);
370       fail("The expected exception was not thrown");
371     }
372     catch(OAuth2Exception e)
373     {
374       log.debug("{}", e.toString());
375       assertEquals("invalid_request", e.getOAuth2ErrorCode());
376       assertFalse(e instanceof GraphApiException);
377     }
378
379
380     requestFactory.setBody(
381         "{\n" +
382         "  \"error\":\n" +
383         "  {\n" +
384         "    \"message\": \"Not a Graph-Api-Exception.\",\n" +
385         "    \"type\": \"Whatever\",\n" +
386         "    \"code\": null\n" +
387         "  }\n" +
388         "}");
389
390     try
391     {
392       clientTemplate.getForObject("ANY", SOME.class);
393       fail("The expected exception was not thrown");
394     }
395     catch(OAuth2Exception e)
396     {
397       log.debug("{}", e.toString());
398       assertEquals("invalid_request", e.getOAuth2ErrorCode());
399       assertFalse(e instanceof GraphApiException);
400     }
401
402
403     requestFactory.setBody(
404         "{\n" +
405         "  \"error\":\n" +
406         "  {\n" +
407         "    \"message\": \"Not a Graph-Api-Exception.\",\n" +
408         "    \"type\": \"Whatever\"\n" +
409         "  }\n" +
410         "}");
411
412     try
413     {
414       clientTemplate.getForObject("ANY", SOME.class);
415       fail("The expected exception was not thrown");
416     }
417     catch(OAuth2Exception e)
418     {
419       log.debug("{}", e.toString());
420       assertEquals("invalid_request", e.getOAuth2ErrorCode());
421       assertFalse(e instanceof GraphApiException);
422     }
423
424
425     requestFactory.setBody("{\"error\":{\"message\":null}}");
426
427     try
428     {
429       clientTemplate.getForObject("ANY", SOME.class);
430       fail("The expected exception was not thrown");
431     }
432     catch(OAuth2Exception e)
433     {
434       log.debug("{}", e.toString());
435       assertEquals("invalid_request", e.getOAuth2ErrorCode());
436       assertFalse(e instanceof GraphApiException);
437     }
438
439
440     requestFactory.setBody("{\"error\":{\"type\":null}}");
441
442     try
443     {
444       clientTemplate.getForObject("ANY", SOME.class);
445       fail("The expected exception was not thrown");
446     }
447     catch(OAuth2Exception e)
448     {
449       log.debug("{}", e.toString());
450       assertEquals("invalid_request", e.getOAuth2ErrorCode());
451       assertFalse(e instanceof GraphApiException);
452     }
453
454
455     requestFactory.setBody("{\"error\":{\"code\":null}}");
456
457     try
458     {
459       clientTemplate.getForObject("ANY", SOME.class);
460       fail("The expected exception was not thrown");
461     }
462     catch(OAuth2Exception e)
463     {
464       log.debug("{}", e.toString());
465       assertEquals("invalid_request", e.getOAuth2ErrorCode());
466       assertFalse(e instanceof GraphApiException);
467     }
468
469
470     requestFactory.setBody("{\"error\":{}}");
471
472     try
473     {
474       clientTemplate.getForObject("ANY", SOME.class);
475       fail("The expected exception was not thrown");
476     }
477     catch(OAuth2Exception e)
478     {
479       log.debug("{}", e.toString());
480       assertEquals("invalid_request", e.getOAuth2ErrorCode());
481       assertFalse(e instanceof GraphApiException);
482     }
483
484
485     requestFactory.setBody("{\"error\":\"some message\"}");
486
487     try
488     {
489       clientTemplate.getForObject("ANY", SOME.class);
490       fail("The expected exception was not thrown");
491     }
492     catch(OAuth2Exception e)
493     {
494       log.debug("{}", e.toString());
495       assertEquals("invalid_request", e.getOAuth2ErrorCode());
496       assertFalse(e instanceof GraphApiException);
497     }
498
499
500     requestFactory.setBody("{\"error\":null}");
501
502     try
503     {
504       clientTemplate.getForObject("ANY", SOME.class);
505       fail("The expected exception was not thrown");
506     }
507     catch(OAuth2Exception e)
508     {
509       log.debug("{}", e.toString());
510       assertEquals("invalid_request", e.getOAuth2ErrorCode());
511       assertFalse(e instanceof GraphApiException);
512     }
513
514
515     requestFactory.setBody("{\"some filed\":\"some message\"}");
516
517     try
518     {
519       clientTemplate.getForObject("ANY", SOME.class);
520       fail("The expected exception was not thrown");
521     }
522     catch(OAuth2Exception e)
523     {
524       log.debug("{}", e.toString());
525       assertEquals("invalid_request", e.getOAuth2ErrorCode());
526       assertFalse(e instanceof GraphApiException);
527     }
528
529
530     requestFactory.setBody("{}");
531
532     try
533     {
534       clientTemplate.getForObject("ANY", SOME.class);
535       fail("The expected exception was not thrown");
536     }
537     catch(OAuth2Exception e)
538     {
539       log.debug("{}", e.toString());
540       assertEquals("invalid_request", e.getOAuth2ErrorCode());
541       assertFalse(e instanceof GraphApiException);
542     }
543
544
545     requestFactory.setBody("");
546
547     try
548     {
549       clientTemplate.getForObject("ANY", SOME.class);
550       fail("The expected exception was not thrown");
551     }
552     catch(HttpMessageNotReadableException e)
553     {
554       // TODO: OAuth2ErrorHandler fails, if body contains no valid JSON!
555       log.debug("{}", e.toString());
556     }
557   }
558
559
560   @Before
561   public void setUp()
562   {
563     requestFactory = new MockClientHttpRequestFactory();
564     requestFactory.setStatus(HttpStatus.BAD_REQUEST);
565     requestFactory.addHeader("Content-Type", "application/json");
566     clientTemplate.setRequestFactory(requestFactory);
567
568     clientTemplate.setErrorHandler(
569         new GraphApiErrorHandler(
570             (OAuth2ErrorHandler)clientTemplate.getErrorHandler()
571             )
572         );
573
574     clientTemplate.setAccessTokenProvider(new AccessTokenProvider()
575     {
576       @Override
577       public OAuth2AccessToken obtainAccessToken(
578           OAuth2ProtectedResourceDetails details,
579           AccessTokenRequest parameters
580           )
581           throws
582             UserRedirectRequiredException,
583             UserApprovalRequiredException,
584             AccessDeniedException
585       {
586         return new OAuth2AccessToken() {
587
588           @Override
589           public Map<String, Object> getAdditionalInformation()
590           {
591             throw new UnsupportedOperationException("Not supported yet.");
592           }
593
594           @Override
595           public Set<String> getScope()
596           {
597             throw new UnsupportedOperationException("Not supported yet.");
598           }
599
600           @Override
601           public OAuth2RefreshToken getRefreshToken()
602           {
603             throw new UnsupportedOperationException("Not supported yet.");
604           }
605
606           @Override
607           public String getTokenType()
608           {
609             return OAUTH2_TYPE;
610           }
611
612           @Override
613           public boolean isExpired()
614           {
615             return false;
616           }
617
618           @Override
619           public Date getExpiration()
620           {
621             throw new UnsupportedOperationException("Not supported yet.");
622           }
623
624           @Override
625           public int getExpiresIn()
626           {
627             throw new UnsupportedOperationException("Not supported yet.");
628           }
629
630           @Override
631           public String getValue()
632           {
633             return "ANY";
634           }
635         };
636       }
637
638       @Override
639       public boolean supportsResource(OAuth2ProtectedResourceDetails resource)
640       {
641         return true;
642       }
643
644       @Override
645       public OAuth2AccessToken refreshAccessToken(
646           OAuth2ProtectedResourceDetails resource,
647           OAuth2RefreshToken refreshToken,
648           AccessTokenRequest request
649           )
650           throws
651             UserRedirectRequiredException
652       {
653         throw new UnsupportedOperationException("Not supported yet.");
654       }
655
656       @Override
657       public boolean supportsRefresh(OAuth2ProtectedResourceDetails resource)
658       {
659         return false;
660       }
661     });
662   }
663
664
665   static class SOME
666   {
667   }
668 }