datatracker/ietf/api/tests.py
Henrik Levkowetz 69c9d25022 Merged in [13125] from rcross@amsl.com:
Add REST API endpoint to notify Datatracker that new recording files are available.
 - Legacy-Id: 13158
Note: SVN reference [13125] has been migrated to Git commit a50b09b152
2017-03-27 21:51:55 +00:00

115 lines
4.8 KiB
Python

import os
import sys
import json
from importlib import import_module
from django.apps import apps
from django.test import Client
from django.conf import settings
from django.urls import reverse as urlreverse
from tastypie.exceptions import BadRequest
from tastypie.test import ResourceTestCaseMixin
import debug # pyflakes:ignore
from ietf.utils.test_utils import TestCase
from ietf.meeting.test_data import make_meeting_test_data
OMITTED_APPS = (
'ietf.secr.meetings',
'ietf.secr.proceedings',
'ietf.ipr',
)
class CustomApiTestCase(TestCase):
def test_notify_meeting_import_audio_files(self):
meeting = make_meeting_test_data()
client = Client(Accept='application/json')
# try invalid method GET
url = urlreverse('ietf.meeting.views.api_import_recordings', kwargs={'number':meeting.number})
r = client.get(url)
self.assertEqual(r.status_code, 405)
# try valid method POST
r = client.post(url)
self.assertEqual(r.status_code, 201)
class TastypieApiTestCase(ResourceTestCaseMixin, TestCase):
def __init__(self, *args, **kwargs):
self.apps = {}
for app_name in settings.INSTALLED_APPS:
if app_name.startswith('ietf') and not app_name in OMITTED_APPS:
app = import_module(app_name)
name = app_name.split('.',1)[-1]
models_path = os.path.join(os.path.dirname(app.__file__), "models.py")
if os.path.exists(models_path):
self.apps[name] = app_name
super(TastypieApiTestCase, self).__init__(*args, **kwargs)
def test_api_top_level(self):
client = Client(Accept='application/json')
r = client.get("/api/v1/")
self.assertValidJSONResponse(r)
resource_list = json.loads(r.content)
for name in self.apps:
if not name in self.apps:
sys.stderr.write("Expected a REST API resource for %s, but didn't find one\n" % name)
for name in self.apps:
self.assertIn(name, resource_list,
"Expected a REST API resource for %s, but didn't find one" % name)
def _assertCallbackReturnsSameJSON(self, api_url, json_dict):
cbclient = Client(Accept='text/javascript')
identity = lambda x: x # pyflakes:ignore
# To be able to eval JSON, we need to have three more symbols
# They are used indirectly
true = True # pyflakes:ignore
false = False # pyflakes:ignore
null = None # pyflakes:ignore
r = cbclient.get(api_url + '?callback=identity')
code = compile(r.content, '<string>', 'eval')
# Make sure it is just a call with the identity function
self.assertTrue(len(code.co_names) == 1, "The callback API returned "
"code which uses more symbols than just the given \'identity\' "
"callback function: %s" % ', '.join(code.co_names))
self.assertTrue(code.co_names[0] == 'identity', "The callback API "
"returned code with a different symbol than the given "
"\'identity\' callback function: %s" % code.co_names[0])
# After all these checks, I think calling eval is "safe"
# Fingers crossed!
callback_dict = eval(code)
self.assertEqual(callback_dict, json_dict, "The callback API returned "
"a different dictionary than the json API")
def test_all_model_resources_exist(self):
client = Client(Accept='application/json')
r = client.get("/api/v1")
top = json.loads(r.content)
self._assertCallbackReturnsSameJSON("/api/v1", top)
for name in self.apps:
app_name = self.apps[name]
app = import_module(app_name)
self.assertEqual("/api/v1/%s/"%name, top[name]["list_endpoint"])
r = client.get(top[name]["list_endpoint"])
self.assertValidJSONResponse(r)
app_resources = json.loads(r.content)
self._assertCallbackReturnsSameJSON("/api/v1/%s/"%name, app_resources)
#
model_list = apps.get_app_config(name).get_models()
for model in model_list:
if not model._meta.model_name in app_resources.keys():
#print("There doesn't seem to be any resource for model %s.models.%s"%(app.__name__,model.__name__,))
self.assertIn(model._meta.model_name, app_resources.keys(),
"There doesn't seem to be any API resource for model %s.models.%s"%(app.__name__,model.__name__,))
def test_invalid_jsonp_callback_value(self):
try:
Client(Accept='text/javascript').get("/api/v1?callback=$.23")
except BadRequest:
return
self.assertTrue(False,
"The callback API accepted an invalid JSONP callback name")