|
7 | 7 | from django.utils.importlib import import_module |
8 | 8 | from django.db import models |
9 | 9 |
|
| 10 | +from tastypie.exceptions import BadRequest |
10 | 11 | from tastypie.test import ResourceTestCase |
11 | 12 |
|
12 | 13 | import debug # pyflakes:ignore |
@@ -43,20 +44,53 @@ def test_api_top_level(self): |
43 | 44 | self.assertIn(name, resource_list, |
44 | 45 | "Expected a REST API resource for %s, but didn't find one" % name) |
45 | 46 |
|
| 47 | + def _assertCallbackReturnsSameJSON(self, api_url, json_dict): |
| 48 | + cbclient = Client(Accept='text/javascript') |
| 49 | + identity = lambda x: x # pyflakes:ignore |
| 50 | + |
| 51 | + # To be able to eval JSON, we need to have three more symbols |
| 52 | + # They are used indirectly |
| 53 | + true = True # pyflakes:ignore |
| 54 | + false = False # pyflakes:ignore |
| 55 | + null = None # pyflakes:ignore |
| 56 | + r = cbclient.get(api_url + '?callback=identity') |
| 57 | + code = compile(r.content, '<string>', 'eval') |
| 58 | + # Make sure it is just a call with the identity function |
| 59 | + self.assertTrue(len(code.co_names) == 1, "The callback API returned " |
| 60 | + "code which uses more symbols than just the given \'identity\' " |
| 61 | + "callback function: %s" % ', '.join(code.co_names)) |
| 62 | + self.assertTrue(code.co_names[0] == 'identity', "The callback API " |
| 63 | + "returned code with a different symbol than the given " |
| 64 | + "\'identity\' callback function: %s" % code.co_names[0]) |
| 65 | + # After all these checks, I think calling eval is "safe" |
| 66 | + # Fingers crossed! |
| 67 | + callback_dict = eval(code) |
| 68 | + self.assertEqual(callback_dict, json_dict, "The callback API returned " |
| 69 | + "a different dictionary than the json API") |
| 70 | + |
46 | 71 | def test_all_model_resources_exist(self): |
47 | 72 | client = Client(Accept='application/json') |
48 | 73 | r = client.get("/api/v1") |
49 | 74 | top = json.loads(r.content) |
| 75 | + self._assertCallbackReturnsSameJSON("/api/v1", top) |
50 | 76 | for name in self.apps: |
51 | 77 | app = self.apps[name] |
52 | 78 | self.assertEqual("/api/v1/%s/"%name, top[name]["list_endpoint"]) |
53 | 79 | r = client.get(top[name]["list_endpoint"]) |
54 | 80 | self.assertValidJSONResponse(r) |
55 | 81 | app_resources = json.loads(r.content) |
| 82 | + self._assertCallbackReturnsSameJSON("/api/v1/%s/"%name, app_resources) |
56 | 83 | model_list = models.get_models(app.models) |
57 | 84 | for model in model_list: |
58 | 85 | if not model._meta.model_name in app_resources.keys(): |
59 | 86 | #print("There doesn't seem to be any resource for model %s.models.%s"%(app.__name__,model.__name__,)) |
60 | 87 | self.assertIn(model._meta.model_name, app_resources.keys(), |
61 | 88 | "There doesn't seem to be any API resource for model %s.models.%s"%(app.__name__,model.__name__,)) |
62 | 89 |
|
| 90 | + def test_invalid_jsonp_callback_value(self): |
| 91 | + try: |
| 92 | + Client(Accept='text/javascript').get("/api/v1?callback=$.23") |
| 93 | + except BadRequest: |
| 94 | + return |
| 95 | + self.assertTrue(False, |
| 96 | + "The callback API accepted an invalid JSONP callback name") |
0 commit comments