Merge remote-tracking branch 'origin/release' into dj18-release-merge
Conflicts: common/djangoapps/util/testing.py lms/djangoapps/instructor/views/api.py lms/djangoapps/teams/tests/test_views.py openedx/core/djangoapps/programs/models.py openedx/core/djangoapps/user_api/accounts/tests/test_views.py requirements/edx/github.txt
This commit is contained in:
@@ -1,2 +0,0 @@
|
||||
""" module init will register signal handlers """
|
||||
import contentstore.signals
|
||||
|
||||
@@ -15,7 +15,7 @@ config.readfp(config_file)
|
||||
|
||||
def doc_url(request=None): # pylint: disable=unused-argument
|
||||
"""
|
||||
This function is added in the list of TEMPLATE_CONTEXT_PROCESSORS, which is a django setting for
|
||||
This function is added in the list of TEMPLATES 'context_processors' OPTION, which is a django setting for
|
||||
a tuple of callables that take a request object as their argument and return a dictionary of items
|
||||
to be merged into the RequestContext.
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import re
|
||||
from six import add_metaclass
|
||||
|
||||
from django.conf import settings
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.utils.translation import ugettext_lazy, ugettext as _
|
||||
from django.core.urlresolvers import resolve
|
||||
|
||||
from contentstore.utils import course_image_url
|
||||
@@ -350,7 +350,7 @@ class CoursewareSearchIndexer(SearchIndexerBase):
|
||||
'category': 'courseware_index'
|
||||
}
|
||||
|
||||
UNNAMED_MODULE_NAME = _("(Unnamed)")
|
||||
UNNAMED_MODULE_NAME = ugettext_lazy("(Unnamed)")
|
||||
|
||||
@classmethod
|
||||
def normalize_structure_key(cls, structure_key):
|
||||
@@ -417,7 +417,7 @@ class CoursewareSearchIndexer(SearchIndexerBase):
|
||||
while parent is not None:
|
||||
path_component_name = parent.display_name
|
||||
if not path_component_name:
|
||||
path_component_name = cls.UNNAMED_MODULE_NAME
|
||||
path_component_name = unicode(cls.UNNAMED_MODULE_NAME)
|
||||
location_path.append(path_component_name)
|
||||
parent = parent.get_parent()
|
||||
location_path.reverse()
|
||||
|
||||
@@ -14,18 +14,19 @@ class Command(BaseCommand):
|
||||
|commit|: optional argument. If not provided, will not run task.
|
||||
'''
|
||||
|
||||
def handle(self, *args, **options):
|
||||
if len(args) not in {1, 2}:
|
||||
raise CommandError("delete_orphans requires one or more arguments: <course_id> |commit|")
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('course_id')
|
||||
parser.add_argument('--commit', action='store')
|
||||
|
||||
def handle(self, *args, **options):
|
||||
try:
|
||||
course_key = CourseKey.from_string(args[0])
|
||||
course_key = CourseKey.from_string(options['course_id'])
|
||||
except InvalidKeyError:
|
||||
raise CommandError("Invalid course key.")
|
||||
|
||||
commit = False
|
||||
if len(args) == 2:
|
||||
commit = args[1] == 'commit'
|
||||
if options['commit']:
|
||||
commit = options['commit'] == 'commit'
|
||||
|
||||
if commit:
|
||||
print 'Deleting orphans from the course:'
|
||||
|
||||
@@ -18,23 +18,24 @@ class Command(BaseCommand):
|
||||
"""
|
||||
help = 'Export the specified data directory into the default ModuleStore'
|
||||
|
||||
def handle(self, *args, **options):
|
||||
"Execute the command"
|
||||
if len(args) != 2:
|
||||
raise CommandError("export requires two arguments: <course id> <output path>")
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('course_id')
|
||||
parser.add_argument('output_path')
|
||||
|
||||
def handle(self, *args, **options):
|
||||
"""Execute the command"""
|
||||
try:
|
||||
course_key = CourseKey.from_string(args[0])
|
||||
course_key = CourseKey.from_string(options['course_id'])
|
||||
except InvalidKeyError:
|
||||
try:
|
||||
course_key = SlashSeparatedCourseKey.from_deprecated_string(args[0])
|
||||
course_key = SlashSeparatedCourseKey.from_deprecated_string(options['course_id'])
|
||||
except InvalidKeyError:
|
||||
raise CommandError("Invalid course_key: '%s'. " % args[0])
|
||||
raise CommandError("Invalid course_key: '%s'." % options['course_id'])
|
||||
|
||||
if not modulestore().get_course(course_key):
|
||||
raise CommandError("Course with %s key not found." % args[0])
|
||||
raise CommandError("Course with %s key not found." % options['course_id'])
|
||||
|
||||
output_path = args[1]
|
||||
output_path = options['output_path']
|
||||
|
||||
print "Exporting course id = {0} to {1}".format(course_key, output_path)
|
||||
|
||||
|
||||
@@ -13,12 +13,14 @@ class Command(BaseCommand):
|
||||
"""Fix a course's item not found errors"""
|
||||
help = "Fix a course's ItemNotFound errors"
|
||||
|
||||
def handle(self, *args, **options):
|
||||
"Execute the command"
|
||||
if len(args) != 1:
|
||||
raise CommandError("requires 1 argument: <course_id>")
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('course_id')
|
||||
|
||||
course_key = CourseKey.from_string(args[0])
|
||||
def handle(self, *args, **options):
|
||||
"""Execute the command"""
|
||||
course_id = options.get('course_id', None)
|
||||
|
||||
course_key = CourseKey.from_string(course_id)
|
||||
# for now only support on split mongo
|
||||
# pylint: disable=protected-access
|
||||
owning_store = modulestore()._get_modulestore_for_courselike(course_key)
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
"""
|
||||
Script for importing courseware from XML format
|
||||
"""
|
||||
from optparse import make_option
|
||||
|
||||
from django.core.management.base import BaseCommand, CommandError, make_option
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
from django_comment_common.utils import (seed_permissions_roles,
|
||||
are_permissions_roles_seeded)
|
||||
from xmodule.modulestore.xml_importer import import_course_from_xml
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Tests running the delete_orphan command"""
|
||||
|
||||
import ddt
|
||||
from django.core.management import call_command
|
||||
from django.core.management import call_command, CommandError
|
||||
from contentstore.tests.test_orphan import TestOrphanBase
|
||||
|
||||
from xmodule.modulestore.tests.factories import CourseFactory
|
||||
@@ -14,6 +14,13 @@ class TestDeleteOrphan(TestOrphanBase):
|
||||
Tests for running the delete_orphan management command.
|
||||
Inherits from TestOrphan in order to use its setUp method.
|
||||
"""
|
||||
def test_no_args(self):
|
||||
"""
|
||||
Test delete_orphans command with no arguments
|
||||
"""
|
||||
with self.assertRaisesRegexp(CommandError, 'Error: too few arguments'):
|
||||
call_command('delete_orphans')
|
||||
|
||||
@ddt.data(ModuleStoreEnum.Type.split, ModuleStoreEnum.Type.mongo)
|
||||
def test_delete_orphans_no_commit(self, default_store):
|
||||
"""
|
||||
@@ -35,7 +42,7 @@ class TestDeleteOrphan(TestOrphanBase):
|
||||
"""
|
||||
course = self.create_course_with_orphans(default_store)
|
||||
|
||||
call_command('delete_orphans', unicode(course.id), 'commit')
|
||||
call_command('delete_orphans', unicode(course.id), commit='commit')
|
||||
|
||||
# make sure this module wasn't deleted
|
||||
self.assertTrue(self.store.has_item(course.id.make_usage_key('html', 'multi_parent_html')))
|
||||
@@ -59,7 +66,7 @@ class TestDeleteOrphan(TestOrphanBase):
|
||||
|
||||
# call delete orphans, specifying the published branch
|
||||
# of the course
|
||||
call_command('delete_orphans', unicode(published_branch), 'commit')
|
||||
call_command('delete_orphans', unicode(published_branch), commit='commit')
|
||||
|
||||
# now all orphans should be deleted
|
||||
self.assertOrphanCount(course.id, 0)
|
||||
|
||||
@@ -24,11 +24,9 @@ class TestArgParsingCourseExport(unittest.TestCase):
|
||||
"""
|
||||
Test export command with no arguments
|
||||
"""
|
||||
errstring = "export requires two arguments: <course id> <output path>"
|
||||
with self.assertRaises(SystemExit) as ex:
|
||||
with self.assertRaisesRegexp(CommandError, errstring):
|
||||
call_command('export')
|
||||
self.assertEqual(ex.exception.code, 1)
|
||||
errstring = "Error: too few arguments"
|
||||
with self.assertRaisesRegexp(CommandError, errstring):
|
||||
call_command('export')
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -59,11 +57,9 @@ class TestCourseExport(ModuleStoreTestCase):
|
||||
"Could not find course in {}".format(store)
|
||||
)
|
||||
# Test `export` management command with invalid course_id
|
||||
errstring = "Invalid course_key 'InvalidCourseID'."
|
||||
with self.assertRaises(SystemExit) as ex:
|
||||
with self.assertRaisesRegexp(CommandError, errstring):
|
||||
call_command('export', "InvalidCourseID", self.temp_dir_1)
|
||||
self.assertEqual(ex.exception.code, 1)
|
||||
errstring = "Invalid course_key: 'InvalidCourseID'."
|
||||
with self.assertRaisesRegexp(CommandError, errstring):
|
||||
call_command('export', "InvalidCourseID", self.temp_dir_1)
|
||||
|
||||
# Test `export` management command with correct course_id
|
||||
for output_dir in [self.temp_dir_1, self.temp_dir_2]:
|
||||
@@ -74,7 +70,5 @@ class TestCourseExport(ModuleStoreTestCase):
|
||||
Test export command with a valid course key that doesn't exist
|
||||
"""
|
||||
errstring = "Course with x/y/z key not found."
|
||||
with self.assertRaises(SystemExit) as ex:
|
||||
with self.assertRaisesRegexp(CommandError, errstring):
|
||||
call_command('export', "x/y/z", self.temp_dir_1)
|
||||
self.assertEqual(ex.exception.code, 1)
|
||||
with self.assertRaisesRegexp(CommandError, errstring):
|
||||
call_command('export', "x/y/z", self.temp_dir_1)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
Tests for the fix_not_found management command
|
||||
"""
|
||||
|
||||
from django.core.management import call_command
|
||||
from django.core.management import CommandError, call_command
|
||||
from xmodule.modulestore import ModuleStoreEnum
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
|
||||
@@ -12,12 +12,19 @@ class TestFixNotFound(ModuleStoreTestCase):
|
||||
"""
|
||||
Tests for the fix_not_found management command
|
||||
"""
|
||||
def test_no_args(self):
|
||||
"""
|
||||
Test fix_not_found command with no arguments
|
||||
"""
|
||||
with self.assertRaisesRegexp(CommandError, "Error: too few arguments"):
|
||||
call_command('fix_not_found')
|
||||
|
||||
def test_fix_not_found_non_split(self):
|
||||
"""
|
||||
The management command doesn't work on non split courses
|
||||
"""
|
||||
course = CourseFactory.create(default_store=ModuleStoreEnum.Type.mongo)
|
||||
with self.assertRaises(SystemExit):
|
||||
with self.assertRaisesRegexp(CommandError, "The owning modulestore does not support this command."):
|
||||
call_command("fix_not_found", unicode(course.id))
|
||||
|
||||
def test_fix_not_found(self):
|
||||
|
||||
@@ -56,57 +56,33 @@ class TestGitExport(CourseTestCase):
|
||||
Test that the command interface works. Ignore stderr for clean
|
||||
test output.
|
||||
"""
|
||||
with self.assertRaises(SystemExit) as ex:
|
||||
with self.assertRaisesRegexp(CommandError, 'This script requires.*'):
|
||||
call_command('git_export', 'blah', 'blah', 'blah',
|
||||
stderr=StringIO.StringIO())
|
||||
self.assertEqual(ex.exception.code, 1)
|
||||
with self.assertRaisesRegexp(CommandError, 'This script requires.*'):
|
||||
call_command('git_export', 'blah', 'blah', 'blah', stderr=StringIO.StringIO())
|
||||
|
||||
with self.assertRaises(SystemExit) as ex:
|
||||
with self.assertRaisesRegexp(CommandError, 'This script requires.*'):
|
||||
call_command('git_export', stderr=StringIO.StringIO())
|
||||
self.assertEqual(ex.exception.code, 1)
|
||||
with self.assertRaisesRegexp(CommandError, 'This script requires.*'):
|
||||
call_command('git_export', stderr=StringIO.StringIO())
|
||||
|
||||
# Send bad url to get course not exported
|
||||
with self.assertRaises(SystemExit) as ex:
|
||||
with self.assertRaisesRegexp(CommandError, unicode(GitExportError.URL_BAD)):
|
||||
call_command('git_export', 'foo/bar/baz', 'silly',
|
||||
stderr=StringIO.StringIO())
|
||||
self.assertEqual(ex.exception.code, 1)
|
||||
with self.assertRaisesRegexp(CommandError, unicode(GitExportError.URL_BAD)):
|
||||
call_command('git_export', 'foo/bar/baz', 'silly', stderr=StringIO.StringIO())
|
||||
|
||||
# Send bad course_id to get course not exported
|
||||
with self.assertRaises(SystemExit) as ex:
|
||||
with self.assertRaisesRegexp(CommandError, unicode(GitExportError.BAD_COURSE)):
|
||||
call_command('git_export', 'foo/bar:baz', 'silly',
|
||||
stderr=StringIO.StringIO())
|
||||
self.assertEqual(ex.exception.code, 1)
|
||||
with self.assertRaisesRegexp(CommandError, unicode(GitExportError.BAD_COURSE)):
|
||||
call_command('git_export', 'foo/bar:baz', 'silly', stderr=StringIO.StringIO())
|
||||
|
||||
def test_error_output(self):
|
||||
"""
|
||||
Verify that error output is actually resolved as the correct string
|
||||
"""
|
||||
output = StringIO.StringIO()
|
||||
with self.assertRaises(SystemExit):
|
||||
with self.assertRaisesRegexp(CommandError, unicode(GitExportError.BAD_COURSE)):
|
||||
call_command(
|
||||
'git_export', 'foo/bar:baz', 'silly',
|
||||
stdout=output, stderr=output
|
||||
)
|
||||
self.assertIn('Bad course location provided', output.getvalue())
|
||||
output.close()
|
||||
with self.assertRaisesRegexp(CommandError, unicode(GitExportError.BAD_COURSE)):
|
||||
call_command(
|
||||
'git_export', 'foo/bar:baz', 'silly'
|
||||
)
|
||||
|
||||
output = StringIO.StringIO()
|
||||
with self.assertRaises(SystemExit):
|
||||
with self.assertRaisesRegexp(CommandError, unicode(GitExportError.URL_BAD)):
|
||||
call_command(
|
||||
'git_export', 'foo/bar/baz', 'silly',
|
||||
stdout=output, stderr=output
|
||||
)
|
||||
self.assertIn(
|
||||
'Non writable git url provided. Expecting something like:'
|
||||
' git@github.com:mitocw/edx4edx_lite.git',
|
||||
output.getvalue()
|
||||
)
|
||||
output.close()
|
||||
with self.assertRaisesRegexp(CommandError, unicode(GitExportError.URL_BAD)):
|
||||
call_command(
|
||||
'git_export', 'foo/bar/baz', 'silly'
|
||||
)
|
||||
|
||||
def test_bad_git_url(self):
|
||||
"""
|
||||
|
||||
@@ -6,7 +6,6 @@ import mock
|
||||
from xmodule.modulestore import ModuleStoreEnum
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
from common.test.utils import nostderr
|
||||
from xmodule.modulestore.tests.factories import CourseFactory, LibraryFactory
|
||||
|
||||
from contentstore.management.commands.reindex_course import Command as ReindexCommand
|
||||
@@ -48,36 +47,30 @@ class TestReindexCourse(ModuleStoreTestCase):
|
||||
|
||||
def test_given_no_arguments_raises_command_error(self):
|
||||
""" Test that raises CommandError for incorrect arguments """
|
||||
with self.assertRaises(SystemExit), nostderr():
|
||||
with self.assertRaisesRegexp(CommandError, ".* requires one or more arguments .*"):
|
||||
call_command('reindex_course')
|
||||
with self.assertRaisesRegexp(CommandError, ".* requires one or more arguments.*"):
|
||||
call_command('reindex_course')
|
||||
|
||||
@ddt.data('qwerty', 'invalid_key', 'xblock-v1:qwe+rty')
|
||||
@ddt.data('qwerty', 'invalid_key', 'xblockv1:qwerty')
|
||||
def test_given_invalid_course_key_raises_not_found(self, invalid_key):
|
||||
""" Test that raises InvalidKeyError for invalid keys """
|
||||
errstring = "Invalid course_key: '%s'." % invalid_key
|
||||
with self.assertRaises(SystemExit) as ex:
|
||||
with self.assertRaisesRegexp(CommandError, errstring):
|
||||
call_command('reindex_course', invalid_key)
|
||||
self.assertEqual(ex.exception.code, 1)
|
||||
err_string = "Invalid course_key: '{0}'".format(invalid_key)
|
||||
with self.assertRaisesRegexp(CommandError, err_string):
|
||||
call_command('reindex_course', invalid_key)
|
||||
|
||||
def test_given_library_key_raises_command_error(self):
|
||||
""" Test that raises CommandError if library key is passed """
|
||||
with self.assertRaises(SystemExit), nostderr():
|
||||
with self.assertRaisesRegexp(SearchIndexingError, ".* is not a course key"):
|
||||
call_command('reindex_course', unicode(self._get_lib_key(self.first_lib)))
|
||||
with self.assertRaisesRegexp(CommandError, ".* is not a course key"):
|
||||
call_command('reindex_course', unicode(self._get_lib_key(self.first_lib)))
|
||||
|
||||
with self.assertRaises(SystemExit), nostderr():
|
||||
with self.assertRaisesRegexp(SearchIndexingError, ".* is not a course key"):
|
||||
call_command('reindex_course', unicode(self._get_lib_key(self.second_lib)))
|
||||
with self.assertRaisesRegexp(CommandError, ".* is not a course key"):
|
||||
call_command('reindex_course', unicode(self._get_lib_key(self.second_lib)))
|
||||
|
||||
with self.assertRaises(SystemExit), nostderr():
|
||||
with self.assertRaisesRegexp(SearchIndexingError, ".* is not a course key"):
|
||||
call_command(
|
||||
'reindex_course',
|
||||
unicode(self.second_course.id),
|
||||
unicode(self._get_lib_key(self.first_lib))
|
||||
)
|
||||
with self.assertRaisesRegexp(CommandError, ".* is not a course key"):
|
||||
call_command(
|
||||
'reindex_course',
|
||||
unicode(self.second_course.id),
|
||||
unicode(self._get_lib_key(self.first_lib))
|
||||
)
|
||||
|
||||
def test_given_id_list_indexes_courses(self):
|
||||
""" Test that reindexes courses when given single course key or a list of course keys """
|
||||
|
||||
@@ -6,7 +6,6 @@ import mock
|
||||
from xmodule.modulestore import ModuleStoreEnum
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
from common.test.utils import nostderr
|
||||
from xmodule.modulestore.tests.factories import CourseFactory, LibraryFactory
|
||||
|
||||
from opaque_keys import InvalidKeyError
|
||||
@@ -50,9 +49,8 @@ class TestReindexLibrary(ModuleStoreTestCase):
|
||||
|
||||
def test_given_no_arguments_raises_command_error(self):
|
||||
""" Test that raises CommandError for incorrect arguments """
|
||||
with self.assertRaises(SystemExit), nostderr():
|
||||
with self.assertRaisesRegexp(CommandError, ".* requires one or more arguments .*"):
|
||||
call_command('reindex_library')
|
||||
with self.assertRaisesRegexp(CommandError, ".* requires one or more arguments.*"):
|
||||
call_command('reindex_library')
|
||||
|
||||
@ddt.data('qwerty', 'invalid_key', 'xblock-v1:qwe+rty')
|
||||
def test_given_invalid_lib_key_raises_not_found(self, invalid_key):
|
||||
@@ -62,21 +60,18 @@ class TestReindexLibrary(ModuleStoreTestCase):
|
||||
|
||||
def test_given_course_key_raises_command_error(self):
|
||||
""" Test that raises CommandError if course key is passed """
|
||||
with self.assertRaises(SystemExit), nostderr():
|
||||
with self.assertRaisesRegexp(CommandError, ".* is not a library key"):
|
||||
call_command('reindex_library', unicode(self.first_course.id))
|
||||
with self.assertRaisesRegexp(CommandError, ".* is not a library key"):
|
||||
call_command('reindex_library', unicode(self.first_course.id))
|
||||
|
||||
with self.assertRaises(SystemExit), nostderr():
|
||||
with self.assertRaisesRegexp(CommandError, ".* is not a library key"):
|
||||
call_command('reindex_library', unicode(self.second_course.id))
|
||||
with self.assertRaisesRegexp(CommandError, ".* is not a library key"):
|
||||
call_command('reindex_library', unicode(self.second_course.id))
|
||||
|
||||
with self.assertRaises(SystemExit), nostderr():
|
||||
with self.assertRaisesRegexp(CommandError, ".* is not a library key"):
|
||||
call_command(
|
||||
'reindex_library',
|
||||
unicode(self.second_course.id),
|
||||
unicode(self._get_lib_key(self.first_lib))
|
||||
)
|
||||
with self.assertRaisesRegexp(CommandError, ".* is not a library key"):
|
||||
call_command(
|
||||
'reindex_library',
|
||||
unicode(self.second_course.id),
|
||||
unicode(self._get_lib_key(self.first_lib))
|
||||
)
|
||||
|
||||
def test_given_id_list_indexes_libraries(self):
|
||||
""" Test that reindexes libraries when given single library key or a list of library keys """
|
||||
|
||||
@@ -1,80 +1,43 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
def forwards(self, orm):
|
||||
# Adding model 'VideoUploadConfig'
|
||||
db.create_table('contentstore_videouploadconfig', (
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('change_date', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
|
||||
('changed_by', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True, on_delete=models.PROTECT)),
|
||||
('enabled', self.gf('django.db.models.fields.BooleanField')(default=False)),
|
||||
('profile_whitelist', self.gf('django.db.models.fields.TextField')(blank=True)),
|
||||
('status_whitelist', self.gf('django.db.models.fields.TextField')(blank=True)),
|
||||
))
|
||||
db.send_create_signal('contentstore', ['VideoUploadConfig'])
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
if not db.dry_run:
|
||||
orm.VideoUploadConfig.objects.create(
|
||||
profile_whitelist="desktop_mp4,desktop_webm,mobile_low,youtube",
|
||||
status_whitelist="Uploading,In Progress,Complete,Failed,Invalid Token,Unknown"
|
||||
)
|
||||
|
||||
def backwards(self, orm):
|
||||
# Deleting model 'VideoUploadConfig'
|
||||
db.delete_table('contentstore_videouploadconfig')
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||
},
|
||||
'auth.permission': {
|
||||
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
|
||||
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
'auth.user': {
|
||||
'Meta': {'object_name': 'User'},
|
||||
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||
},
|
||||
'contentstore.videouploadconfig': {
|
||||
'Meta': {'object_name': 'VideoUploadConfig'},
|
||||
'change_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'changed_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'on_delete': 'models.PROTECT'}),
|
||||
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'profile_whitelist': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'status_whitelist': ('django.db.models.fields.TextField', [], {'blank': 'True'})
|
||||
},
|
||||
'contenttypes.contenttype': {
|
||||
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['contentstore']
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='PushNotificationConfig',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('change_date', models.DateTimeField(auto_now_add=True, verbose_name='Change date')),
|
||||
('enabled', models.BooleanField(default=False, verbose_name='Enabled')),
|
||||
('changed_by', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, editable=False, to=settings.AUTH_USER_MODEL, null=True, verbose_name='Changed by')),
|
||||
],
|
||||
options={
|
||||
'ordering': ('-change_date',),
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='VideoUploadConfig',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('change_date', models.DateTimeField(auto_now_add=True, verbose_name='Change date')),
|
||||
('enabled', models.BooleanField(default=False, verbose_name='Enabled')),
|
||||
('profile_whitelist', models.TextField(help_text=b'A comma-separated list of names of profiles to include in video encoding downloads.', blank=True)),
|
||||
('changed_by', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, editable=False, to=settings.AUTH_USER_MODEL, null=True, verbose_name='Changed by')),
|
||||
],
|
||||
options={
|
||||
'ordering': ('-change_date',),
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
]
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
# Deleting field 'VideoUploadConfig.status_whitelist'
|
||||
db.delete_column('contentstore_videouploadconfig', 'status_whitelist')
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Adding field 'VideoUploadConfig.status_whitelist'
|
||||
db.add_column('contentstore_videouploadconfig', 'status_whitelist',
|
||||
self.gf('django.db.models.fields.TextField')(default='', blank=True),
|
||||
keep_default=False)
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||
},
|
||||
'auth.permission': {
|
||||
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
|
||||
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
'auth.user': {
|
||||
'Meta': {'object_name': 'User'},
|
||||
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||
},
|
||||
'contentstore.videouploadconfig': {
|
||||
'Meta': {'object_name': 'VideoUploadConfig'},
|
||||
'change_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'changed_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'on_delete': 'models.PROTECT'}),
|
||||
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'profile_whitelist': ('django.db.models.fields.TextField', [], {'blank': 'True'})
|
||||
},
|
||||
'contenttypes.contenttype': {
|
||||
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['contentstore']
|
||||
@@ -1,80 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from south.utils import datetime_utils as datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
# Adding model 'PushNotificationConfig'
|
||||
db.create_table('contentstore_pushnotificationconfig', (
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('change_date', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
|
||||
('changed_by', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True, on_delete=models.PROTECT)),
|
||||
('enabled', self.gf('django.db.models.fields.BooleanField')(default=False)),
|
||||
))
|
||||
db.send_create_signal('contentstore', ['PushNotificationConfig'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Deleting model 'PushNotificationConfig'
|
||||
db.delete_table('contentstore_pushnotificationconfig')
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||
},
|
||||
'auth.permission': {
|
||||
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
|
||||
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
'auth.user': {
|
||||
'Meta': {'object_name': 'User'},
|
||||
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||
},
|
||||
'contentstore.pushnotificationconfig': {
|
||||
'Meta': {'object_name': 'PushNotificationConfig'},
|
||||
'change_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'changed_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'on_delete': 'models.PROTECT'}),
|
||||
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||
},
|
||||
'contentstore.videouploadconfig': {
|
||||
'Meta': {'object_name': 'VideoUploadConfig'},
|
||||
'change_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'changed_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'on_delete': 'models.PROTECT'}),
|
||||
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'profile_whitelist': ('django.db.models.fields.TextField', [], {'blank': 'True'})
|
||||
},
|
||||
'contenttypes.contenttype': {
|
||||
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['contentstore']
|
||||
2
cms/djangoapps/contentstore/startup.py
Normal file
2
cms/djangoapps/contentstore/startup.py
Normal file
@@ -0,0 +1,2 @@
|
||||
""" will register signal handlers, moved out of __init__.py to ensure correct loading order post Django 1.7 """
|
||||
from . import signals # pylint: disable=unused-import
|
||||
@@ -187,7 +187,7 @@ def _get_entrance_exam(request, course_key): # pylint: disable=W0613
|
||||
exam_descriptor = modulestore().get_item(exam_key)
|
||||
return HttpResponse(
|
||||
escape_json_dumps({'locator': unicode(exam_descriptor.location)}),
|
||||
status=200, mimetype='application/json')
|
||||
status=200, content_type='application/json')
|
||||
except ItemNotFoundError:
|
||||
return HttpResponse(status=404)
|
||||
|
||||
|
||||
@@ -301,7 +301,7 @@ def xblock_view_handler(request, usage_key_string, view_name):
|
||||
|
||||
hashed_resources = OrderedDict()
|
||||
for resource in fragment.resources:
|
||||
hashed_resources[hash_resource(resource)] = resource
|
||||
hashed_resources[hash_resource(resource)] = resource._asdict()
|
||||
|
||||
return JsonResponse({
|
||||
'html': fragment.content,
|
||||
|
||||
@@ -38,7 +38,7 @@ from .session_kv_store import SessionKeyValueStore
|
||||
from .helpers import render_from_lms
|
||||
|
||||
from contentstore.views.access import get_user_role
|
||||
from cms.djangoapps.xblock_config.models import StudioConfig
|
||||
from xblock_config.models import StudioConfig
|
||||
|
||||
__all__ = ['preview_handler']
|
||||
|
||||
|
||||
@@ -610,12 +610,12 @@ class TestCourseReIndex(CourseTestCase):
|
||||
response = non_staff_client.get(index_url, {}, HTTP_ACCEPT='application/json')
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
def test_content_type_none(self):
|
||||
def test_empty_content_type(self):
|
||||
"""
|
||||
Test json content type is set if none is selected
|
||||
Test json content type is set if '' is selected
|
||||
"""
|
||||
index_url = reverse_course_url('course_search_index_handler', self.course.id)
|
||||
response = self.client.get(index_url, {}, CONTENT_TYPE=None)
|
||||
response = self.client.get(index_url, {}, CONTENT_TYPE='')
|
||||
|
||||
# A course with the default release date should display as "Unscheduled"
|
||||
self.assertIn(self.SUCCESSFUL_RESPONSE, response.content)
|
||||
|
||||
@@ -17,7 +17,7 @@ from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
from contentstore.views.preview import get_preview_fragment, _preview_module_system
|
||||
from xmodule.modulestore import ModuleStoreEnum
|
||||
from xmodule.modulestore.tests.test_asides import AsideTestType
|
||||
from cms.djangoapps.xblock_config.models import StudioConfig
|
||||
from xblock_config.models import StudioConfig
|
||||
from xmodule.modulestore.django import modulestore
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user