diff --git a/cms/djangoapps/contentstore/tests/test_course_settings.py b/cms/djangoapps/contentstore/tests/test_course_settings.py index 40ec2ed3c734..8e764d5a17cd 100644 --- a/cms/djangoapps/contentstore/tests/test_course_settings.py +++ b/cms/djangoapps/contentstore/tests/test_course_settings.py @@ -54,8 +54,8 @@ def setUp(self): self.client = Client() self.client.login(username=uname, password=password) - course = CourseFactory.create(template='i4x://edx/templates/course/Empty', org='MITx', number='999', display_name='Robot Super Course') - self.course_location = course.location + self.course = CourseFactory.create(template='i4x://edx/templates/course/Empty', org='MITx', number='999', display_name='Robot Super Course') + self.course_location = self.course.location class CourseDetailsTestCase(CourseTestCase): diff --git a/cms/djangoapps/contentstore/tests/test_item.py b/cms/djangoapps/contentstore/tests/test_item.py index 1831a5769a61..6693c8c4fbb3 100644 --- a/cms/djangoapps/contentstore/tests/test_item.py +++ b/cms/djangoapps/contentstore/tests/test_item.py @@ -1,15 +1,30 @@ +"""Tests for items views.""" +import os +import json +import tempfile +from uuid import uuid4 + +from lxml import etree +from django.core.urlresolvers import reverse +from django.template.defaultfilters import slugify + from contentstore.tests.test_course_settings import CourseTestCase +from cache_toolbox.core import del_cached_content from xmodule.modulestore.tests.factories import CourseFactory -from django.core.urlresolvers import reverse +from xmodule.modulestore.django import modulestore +from xmodule.contentstore.django import contentstore +from xmodule.contentstore.content import StaticContent +from xmodule.exceptions import NotFoundError class DeleteItem(CourseTestCase): + """Tests for '/delete_item' url.""" def setUp(self): """ Creates the test course with a static page in it. """ super(DeleteItem, self).setUp() self.course = CourseFactory.create(org='mitX', number='333', display_name='Dummy Course') - def testDeleteStaticPage(self): + def test_delete_static_page(self): # Add static tab data = { 'parent_location': 'i4x://mitX/333/course/Dummy_Course', @@ -24,5 +39,629 @@ def testDeleteStaticPage(self): self.assertEqual(resp.status_code, 200) +class BaseSubtitles(CourseTestCase): + """Base test class for subtitles tests.""" + + org = 'MITx' + number = '999' + + def clear_subs_content(self): + """Remove, if subtitles content exists.""" + for youtube_id in self.get_youtube_ids().values(): + filename = 'subs_{0}.srt.sjson'.format(youtube_id) + content_location = StaticContent.compute_location( + self.org, self.number, filename) + try: + content = contentstore().find(content_location) + contentstore().delete(content.get_id()) + except NotFoundError: + pass + + def setUp(self): + """Create initial data.""" + super(BaseSubtitles, self).setUp() + + # Add videoalpha module + data = { + 'parent_location': str(self.course_location), + 'template': 'i4x://edx/templates/videoalpha/Video_Alpha' + } + resp = self.client.post(reverse('clone_item'), data) + self.item_location = json.loads(resp.content).get('id') + self.assertEqual(resp.status_code, 200) + + # hI10vDNYz4M - valid Youtube ID with subtitles. + # JMD_ifUUfsU, AKqURZnYqpk, DYpADpL7jAY - valid Youtube IDs + # without subtitles. + data = '' + modulestore().update_item(self.item_location, data) + + self.item = modulestore().get_item(self.item_location) + + # Remove all subtitles for current module. + self.clear_subs_content() + + def get_youtube_ids(self): + """Return youtube speeds and ids.""" + xmltree = etree.fromstring(self.item.data) + youtube = xmltree.get('youtube') + return dict([ + (float(i.split(':')[0]), i.split(':')[1]) + for i in youtube.split(',') + ]) + + +class ImportSubtitles(BaseSubtitles): + """Tests for '/import_subtitles' url.""" + + def test_success_videoalpha_module_subs_importing(self): + # Import subtitles. + resp = self.client.post( + reverse('import_subtitles'), {'id': self.item_location}) + + self.assertEqual(resp.status_code, 200) + self.assertTrue(json.loads(resp.content).get('success')) + + # Check assets status after importing subtitles. + for youtube_id in self.get_youtube_ids().values(): + filename = 'subs_{0}.srt.sjson'.format(youtube_id) + content_location = StaticContent.compute_location( + self.org, self.number, filename) + self.assertTrue(contentstore().find(content_location)) + + def test_fail_data_without_id(self): + resp = self.client.post( + reverse('import_subtitles'), {}) + + self.assertEqual(resp.status_code, 200) + self.assertFalse(json.loads(resp.content).get('success')) + + def test_fail_data_with_bad_location(self): + # Test for raising `InvalidLocationError` exception. + resp = self.client.post( + reverse('import_subtitles'), {'id': 'BAD_LOCATION'}) + + self.assertEqual(resp.status_code, 200) + self.assertFalse(json.loads(resp.content).get('success')) + + # Test for raising `ItemNotFoundError` exception. + resp = self.client.post( + reverse('import_subtitles'), + {'id': '{0}_{1}'.format(self.item_location, 'BAD_LOCATION')} + ) + + self.assertEqual(resp.status_code, 200) + self.assertFalse(json.loads(resp.content).get('success')) + + def test_fail_for_non_videoalpha_module(self): + # Video module: setup + data = { + 'parent_location': str(self.course_location), + 'template': 'i4x://edx/templates/video/default' + } + resp = self.client.post(reverse('clone_item'), data) + item_location = json.loads(resp.content).get('id') + data = '