Commit 05cb13b1 by David Baumgold

Adding and fixing tests

parent 77db1f8a
""" Unit tests for checklist methods in views.py. """
from contentstore.utils import get_modulestore, get_url_reverse
from contentstore.tests.test_course_settings import CourseTestCase
from xmodule.modulestore.inheritance import own_metadata
from xmodule.modulestore.tests.factories import CourseFactory
from django.core.urlresolvers import reverse
import json
from .utils import CourseTestCase
class ChecklistTestCase(CourseTestCase):
......
......@@ -10,9 +10,9 @@ class CourseUpdateTest(CourseTestCase):
'''Go through each interface and ensure it works.'''
# first get the update to force the creation
url = reverse('course_info',
kwargs={'org': self.course_location.org,
'course': self.course_location.course,
'name': self.course_location.name})
kwargs={'org': self.course.location.org,
'course': self.course.location.course,
'name': self.course.location.name})
self.client.get(url)
init_content = '<iframe width="560" height="315" src="http://www.youtube.com/embed/RocY-Jd93XU" frameborder="0">'
......@@ -20,8 +20,8 @@ class CourseUpdateTest(CourseTestCase):
payload = {'content': content,
'date': 'January 8, 2013'}
url = reverse('course_info_json',
kwargs={'org': self.course_location.org,
'course': self.course_location.course,
kwargs={'org': self.course.location.org,
'course': self.course.location.course,
'provided_id': ''})
resp = self.client.post(url, json.dumps(payload), "application/json")
......@@ -31,8 +31,8 @@ class CourseUpdateTest(CourseTestCase):
self.assertHTMLEqual(payload['content'], content)
first_update_url = reverse('course_info_json',
kwargs={'org': self.course_location.org,
'course': self.course_location.course,
kwargs={'org': self.course.location.org,
'course': self.course.location.course,
'provided_id': payload['id']})
content += '<div>div <p>p<br/></p></div>'
payload['content'] = content
......@@ -47,8 +47,8 @@ class CourseUpdateTest(CourseTestCase):
payload = {'content': content,
'date': 'January 11, 2013'}
url = reverse('course_info_json',
kwargs={'org': self.course_location.org,
'course': self.course_location.course,
kwargs={'org': self.course.location.org,
'course': self.course.location.course,
'provided_id': ''})
resp = self.client.post(url, json.dumps(payload), "application/json")
......@@ -58,8 +58,8 @@ class CourseUpdateTest(CourseTestCase):
self.assertHTMLEqual(content, payload['content'], "self closing ol")
url = reverse('course_info_json',
kwargs={'org': self.course_location.org,
'course': self.course_location.course,
kwargs={'org': self.course.location.org,
'course': self.course.location.course,
'provided_id': ''})
resp = self.client.get(url)
payload = json.loads(resp.content)
......@@ -73,8 +73,8 @@ class CourseUpdateTest(CourseTestCase):
# now try to update a non-existent update
url = reverse('course_info_json',
kwargs={'org': self.course_location.org,
'course': self.course_location.course,
kwargs={'org': self.course.location.org,
'course': self.course.location.course,
'provided_id': '9'})
content = 'blah blah'
payload = {'content': content,
......@@ -87,8 +87,8 @@ class CourseUpdateTest(CourseTestCase):
content = '<garbage tag No closing brace to force <span>error</span>'
payload = {'content': content,
'date': 'January 11, 2013'}
url = reverse('course_info_json', kwargs={'org': self.course_location.org,
'course': self.course_location.course,
url = reverse('course_info_json', kwargs={'org': self.course.location.org,
'course': self.course.location.course,
'provided_id': ''})
self.assertContains(
......@@ -99,8 +99,8 @@ class CourseUpdateTest(CourseTestCase):
content = "<p><br><br></p>"
payload = {'content': content,
'date': 'January 11, 2013'}
url = reverse('course_info_json', kwargs={'org': self.course_location.org,
'course': self.course_location.course,
url = reverse('course_info_json', kwargs={'org': self.course.location.org,
'course': self.course.location.course,
'provided_id': ''})
resp = self.client.post(url, json.dumps(payload), "application/json")
......@@ -108,8 +108,8 @@ class CourseUpdateTest(CourseTestCase):
self.assertHTMLEqual(content, json.loads(resp.content)['content'])
# now try to delete a non-existent update
url = reverse('course_info_json', kwargs={'org': self.course_location.org,
'course': self.course_location.course,
url = reverse('course_info_json', kwargs={'org': self.course.location.org,
'course': self.course.location.course,
'provided_id': '19'})
payload = {'content': content,
'date': 'January 21, 2013'}
......@@ -119,8 +119,8 @@ class CourseUpdateTest(CourseTestCase):
content = 'blah blah'
payload = {'content': content,
'date': 'January 28, 2013'}
url = reverse('course_info_json', kwargs={'org': self.course_location.org,
'course': self.course_location.course,
url = reverse('course_info_json', kwargs={'org': self.course.location.org,
'course': self.course.location.course,
'provided_id': ''})
resp = self.client.post(url, json.dumps(payload), "application/json")
payload = json.loads(resp.content)
......@@ -128,16 +128,16 @@ class CourseUpdateTest(CourseTestCase):
self.assertHTMLEqual(content, payload['content'], "single iframe")
# first count the entries
url = reverse('course_info_json',
kwargs={'org': self.course_location.org,
'course': self.course_location.course,
kwargs={'org': self.course.location.org,
'course': self.course.location.course,
'provided_id': ''})
resp = self.client.get(url)
payload = json.loads(resp.content)
before_delete = len(payload)
url = reverse('course_info_json',
kwargs={'org': self.course_location.org,
'course': self.course_location.course,
kwargs={'org': self.course.location.org,
'course': self.course.location.course,
'provided_id': this_id})
resp = self.client.delete(url)
payload = json.loads(resp.content)
......
......@@ -22,7 +22,3 @@ class DeleteItem(CourseTestCase):
# Now delete it. There was a bug that the delete was failing (static tabs do not exist in draft modulestore).
resp = self.client.post(reverse('delete_item'), resp.content, "application/json")
self.assertEqual(resp.status_code, 200)
import json
import mock
from unittest import TestCase
from .utils import CourseTestCase
from django.core.urlresolvers import reverse
from contentstore.utils import get_modulestore
from contentstore.views.course import (
validate_textbook_json, TextbookValidationError)
class TextbookTestCase(CourseTestCase):
def setUp(self):
super(TextbookTestCase, self).setUp()
self.url = reverse('textbook_index', kwargs={
'org': self.course.location.org,
'course': self.course.location.course,
'name': self.course.location.name,
})
def test_view_index(self):
resp = self.client.get(self.url)
self.assertEqual(resp.status_code, 200)
# we don't have resp.context right now,
# due to bugs in our testing harness :(
if resp.context:
self.assertEqual(resp.context['course'], self.course)
def test_view_index_xhr(self):
resp = self.client.get(
self.url,
HTTP_ACCEPT="application/json",
HTTP_X_REQUESTED_WITH='XMLHttpRequest'
)
self.assertEqual(resp.status_code, 200)
obj = json.loads(resp.content)
self.assertEqual(self.course.pdf_textbooks, obj)
def test_view_index_xhr_post(self):
textbooks = [
{"tab_title": "Hi, mom!"},
{"tab_title": "Textbook 2"},
]
# import nose; nose.tools.set_trace()
resp = self.client.post(
self.url,
data=json.dumps(textbooks),
content_type="application/json",
HTTP_ACCEPT="application/json",
HTTP_X_REQUESTED_WITH='XMLHttpRequest'
)
self.assertEqual(resp.status_code, 204)
self.assertEqual(resp.content, "")
# reload course
store = get_modulestore(self.course.location)
course = store.get_item(self.course.location)
self.assertEqual(course.pdf_textbooks, textbooks)
class TextbookValidationTestCase(TestCase):
def test_happy_path(self):
textbooks = [
{
"tab_title": "Hi, mom!",
"url": "/mom.pdf"
},
{
"tab_title": "Textbook 2",
"chapters": [
{
"title": "Chapter 1",
"url": "/ch1.pdf"
}, {
"title": "Chapter 2",
"url": "/ch2.pdf"
}
]
}
]
result = validate_textbook_json(json.dumps(textbooks))
self.assertEqual(textbooks, result)
def test_invalid_json(self):
with self.assertRaises(TextbookValidationError):
validate_textbook_json("[{'abc'}]")
def test_wrong_json(self):
with self.assertRaises(TextbookValidationError):
validate_textbook_json('{"tab_title": "Hi, mom!"}')
def test_no_tab_title(self):
with self.assertRaises(TextbookValidationError):
validate_textbook_json('[{"url": "/textbook.pdf"}')
......@@ -6,6 +6,10 @@ import json
from student.models import Registration
from django.contrib.auth.models import User
from django.test.client import Client
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
def parse_json(response):
......@@ -21,3 +25,37 @@ def user(email):
def registration(email):
"""look up registration object by email"""
return Registration.objects.get(user__email=email)
class CourseTestCase(ModuleStoreTestCase):
def setUp(self):
"""
These tests need a user in the DB so that the django Test Client
can log them in.
They inherit from the ModuleStoreTestCase class so that the mongodb collection
will be cleared out before each test case execution and deleted
afterwards.
"""
uname = 'testuser'
email = 'test+courses@edx.org'
password = 'foo'
# Create the use so we can log them in.
self.user = User.objects.create_user(uname, email, password)
# Note that we do not actually need to do anything
# for registration if we directly mark them active.
self.user.is_active = True
# Staff has access to view all courses
self.user.is_staff = True
self.user.save()
self.client = Client()
self.client.login(username=uname, password=password)
self.course = CourseFactory.create(
template='i4x://edx/templates/course/Empty',
org='MITx',
number='999',
display_name='Robot Super Course',
)
......@@ -416,6 +416,23 @@ def course_advanced_updates(request, org, course, name):
return HttpResponse(response_json, mimetype="application/json")
class TextbookValidationError(Exception):
pass
def validate_textbook_json(text):
try:
obj = json.loads(text)
except ValueError:
raise TextbookValidationError("invalid JSON")
if not isinstance(obj, (list, tuple)):
raise TextbookValidationError("must be JSON list")
for textbook in obj:
if not textbook.get("tab_title"):
raise TextbookValidationError("every textbook must have a tab_title")
return obj
@login_required
@ensure_csrf_cookie
def textbook_index(request, org, course, name):
......@@ -433,18 +450,10 @@ def textbook_index(request, org, course, name):
return HttpResponse(json.dumps(course_module.pdf_textbooks), content_type="application/json")
elif request.method == 'POST':
try:
obj = json.loads(request.raw_post_data)
except ValueError:
msg = {"error": "invalid JSON"}
return HttpResponseBadRequest(json.dumps(msg), content_type="application/json")
if not isinstance(obj, (list, tuple)):
msg = {"error": "must be JSON list"}
course_module.pdf_textbooks = validate_textbook_json(request.body)
except TextbookValidationError as e:
msg = {"error": e.message}
return HttpResponseBadRequest(json.dumps(msg), content_type="application/json")
for textbook in obj:
if not textbook.get("tab_title"):
msg = {"error": "every textbook must have a tab_title"}
return HttpResponseBadRequest(json.dumps(msg), content_type="application/json")
course_module.pdf_textbooks = obj
if not any(tab['type'] == 'pdf_textbooks' for tab in course_module.tabs):
course_module.tabs.append({"type": "pdf_textbooks"})
store.update_metadata(course_module.location, own_metadata(course_module))
......
File mode changed from 100644 to 100755
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment