Refactor tests for cms contentstore.
This commit is contained in:
@@ -1,27 +1,46 @@
|
||||
import json
|
||||
import shutil
|
||||
from django.test import TestCase
|
||||
from django.test.client import Client
|
||||
from override_settings import override_settings
|
||||
from django.conf import settings
|
||||
from django.core.urlresolvers import reverse
|
||||
from path import path
|
||||
from tempfile import mkdtemp
|
||||
import json
|
||||
from fs.osfs import OSFS
|
||||
import copy
|
||||
from mock import Mock
|
||||
|
||||
import xmodule.modulestore.django
|
||||
from factories import *
|
||||
from utils import CmsTestCase
|
||||
from student.models import Registration
|
||||
from django.contrib.auth.models import User
|
||||
from cms.djangoapps.contentstore.utils import get_modulestore
|
||||
|
||||
from utils import ModuleStoreTestCase, parse_json
|
||||
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
|
||||
|
||||
from xmodule.modulestore import Location
|
||||
from xmodule.modulestore.store_utilities import clone_course
|
||||
from xmodule.modulestore.store_utilities import delete_course
|
||||
from xmodule.modulestore.django import modulestore, _MODULESTORES
|
||||
from xmodule.contentstore.django import contentstore
|
||||
from xmodule.templates import update_templates
|
||||
from xmodule.modulestore.xml_exporter import export_to_xml
|
||||
from xmodule.modulestore.xml_importer import import_from_xml
|
||||
|
||||
from xmodule.capa_module import CapaDescriptor
|
||||
from xmodule.course_module import CourseDescriptor
|
||||
from xmodule.seq_module import SequenceDescriptor
|
||||
|
||||
TEST_DATA_MODULESTORE = copy.deepcopy(settings.MODULESTORE)
|
||||
TEST_DATA_MODULESTORE['default']['OPTIONS']['fs_root'] = path('common/test/data')
|
||||
TEST_DATA_MODULESTORE['direct']['OPTIONS']['fs_root'] = path('common/test/data')
|
||||
|
||||
@override_settings(MODULESTORE=TEST_DATA_MODULESTORE)
|
||||
class ContentStoreTest(CmsTestCase):
|
||||
|
||||
class ContentStoreToyCourseTest(ModuleStoreTestCase):
|
||||
"""
|
||||
Tests that rely on the toy courses.
|
||||
TODO: refactor using CourseFactory so they do not.
|
||||
"""
|
||||
def setUp(self):
|
||||
uname = 'testuser'
|
||||
email = 'test+courses@edx.org'
|
||||
@@ -40,109 +59,6 @@ class ContentStoreTest(CmsTestCase):
|
||||
self.client = Client()
|
||||
self.client.login(username=uname, password=password)
|
||||
|
||||
self.course_data = {
|
||||
'template': 'i4x://edx/templates/course/Empty',
|
||||
'org': 'MITx',
|
||||
'number': '999',
|
||||
'display_name': 'Robot Super Course',
|
||||
}
|
||||
|
||||
def test_create_course(self):
|
||||
"""Test new course creation - happy path"""
|
||||
resp = self.client.post(reverse('create_new_course'), self.course_data)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
data = parse_json(resp)
|
||||
self.assertEqual(data['id'], 'i4x://MITx/999/course/Robot_Super_Course')
|
||||
|
||||
def test_create_course_duplicate_course(self):
|
||||
"""Test new course creation - error path"""
|
||||
resp = self.client.post(reverse('create_new_course'), self.course_data)
|
||||
resp = self.client.post(reverse('create_new_course'), self.course_data)
|
||||
data = parse_json(resp)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.assertEqual(data['ErrMsg'], 'There is already a course defined with this name.')
|
||||
|
||||
def test_create_course_duplicate_number(self):
|
||||
"""Test new course creation - error path"""
|
||||
resp = self.client.post(reverse('create_new_course'), self.course_data)
|
||||
self.course_data['display_name'] = 'Robot Super Course Two'
|
||||
|
||||
resp = self.client.post(reverse('create_new_course'), self.course_data)
|
||||
data = parse_json(resp)
|
||||
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.assertEqual(data['ErrMsg'],
|
||||
'There is already a course defined with the same organization and course number.')
|
||||
|
||||
def test_create_course_with_bad_organization(self):
|
||||
"""Test new course creation - error path for bad organization name"""
|
||||
self.course_data['org'] = 'University of California, Berkeley'
|
||||
resp = self.client.post(reverse('create_new_course'), self.course_data)
|
||||
data = parse_json(resp)
|
||||
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.assertEqual(data['ErrMsg'],
|
||||
"Unable to create course 'Robot Super Course'.\n\nInvalid characters in 'University of California, Berkeley'.")
|
||||
|
||||
def test_course_index_view_with_no_courses(self):
|
||||
"""Test viewing the index page with no courses"""
|
||||
# Create a course so there is something to view
|
||||
resp = self.client.get(reverse('index'))
|
||||
self.assertContains(resp,
|
||||
'<h1>My Courses</h1>',
|
||||
status_code=200,
|
||||
html=True)
|
||||
|
||||
def test_course_factory(self):
|
||||
course = CourseFactory.create()
|
||||
self.assertIsInstance(course, CourseDescriptor)
|
||||
|
||||
def test_item_factory(self):
|
||||
course = CourseFactory.create()
|
||||
item = ItemFactory.create(parent_location=course.location)
|
||||
self.assertIsInstance(item, SequenceDescriptor)
|
||||
|
||||
def test_course_index_view_with_course(self):
|
||||
"""Test viewing the index page with an existing course"""
|
||||
CourseFactory.create(display_name='Robot Super Educational Course')
|
||||
resp = self.client.get(reverse('index'))
|
||||
self.assertContains(resp,
|
||||
'<span class="class-name">Robot Super Educational Course</span>',
|
||||
status_code=200,
|
||||
html=True)
|
||||
|
||||
def test_course_overview_view_with_course(self):
|
||||
"""Test viewing the course overview page with an existing course"""
|
||||
CourseFactory.create(org='MITx', course='999', display_name='Robot Super Course')
|
||||
|
||||
data = {
|
||||
'org': 'MITx',
|
||||
'course': '999',
|
||||
'name': Location.clean('Robot Super Course'),
|
||||
}
|
||||
|
||||
resp = self.client.get(reverse('course_index', kwargs=data))
|
||||
self.assertContains(resp,
|
||||
'<a href="/MITx/999/course/Robot_Super_Course" class="class-name">Robot Super Course</a>',
|
||||
status_code=200,
|
||||
html=True)
|
||||
|
||||
def test_clone_item(self):
|
||||
"""Test cloning an item. E.g. creating a new section"""
|
||||
CourseFactory.create(org='MITx', course='999', display_name='Robot Super Course')
|
||||
|
||||
section_data = {
|
||||
'parent_location' : 'i4x://MITx/999/course/Robot_Super_Course',
|
||||
'template' : 'i4x://edx/templates/chapter/Empty',
|
||||
'display_name': 'Section One',
|
||||
}
|
||||
|
||||
resp = self.client.post(reverse('clone_item'), section_data)
|
||||
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
data = parse_json(resp)
|
||||
self.assertRegexpMatches(data['id'],
|
||||
'^i4x:\/\/MITx\/999\/chapter\/([0-9]|[a-f]){32}$')
|
||||
|
||||
def check_edit_unit(self, test_course_name):
|
||||
import_from_xml(modulestore(), 'common/test/data/', [test_course_name])
|
||||
@@ -183,9 +99,6 @@ class ContentStoreTest(CmsTestCase):
|
||||
|
||||
self.assertEqual(reverse_tabs, course_tabs)
|
||||
|
||||
|
||||
|
||||
|
||||
def test_about_overrides(self):
|
||||
'''
|
||||
This test case verifies that a course can use specialized override for about data, e.g. /about/Fall_2012/effort.html
|
||||
@@ -210,11 +123,18 @@ class ContentStoreTest(CmsTestCase):
|
||||
course = ms.get_item(source_location)
|
||||
self.assertNotIn('hide_progress_tab', course.metadata)
|
||||
|
||||
|
||||
def test_clone_course(self):
|
||||
|
||||
course_data = {
|
||||
'template': 'i4x://edx/templates/course/Empty',
|
||||
'org': 'MITx',
|
||||
'number': '999',
|
||||
'display_name': 'Robot Super Course',
|
||||
}
|
||||
|
||||
import_from_xml(modulestore(), 'common/test/data/', ['full'])
|
||||
|
||||
resp = self.client.post(reverse('create_new_course'), self.course_data)
|
||||
resp = self.client.post(reverse('create_new_course'), course_data)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
data = parse_json(resp)
|
||||
self.assertEqual(data['id'], 'i4x://MITx/999/course/Robot_Super_Course')
|
||||
@@ -302,7 +222,6 @@ class ContentStoreTest(CmsTestCase):
|
||||
|
||||
shutil.rmtree(root_dir)
|
||||
|
||||
|
||||
def test_course_handouts_rewrites(self):
|
||||
ms = modulestore('direct')
|
||||
cs = contentstore()
|
||||
@@ -323,6 +242,141 @@ class ContentStoreTest(CmsTestCase):
|
||||
self.assertContains(resp, '/c4x/edX/full/asset/handouts_schematic_tutorial.pdf')
|
||||
|
||||
|
||||
class ContentStoreTest(ModuleStoreTestCase):
|
||||
"""
|
||||
Tests for the CMS ContentStore application.
|
||||
"""
|
||||
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_data = {
|
||||
'template': 'i4x://edx/templates/course/Empty',
|
||||
'org': 'MITx',
|
||||
'number': '999',
|
||||
'display_name': 'Robot Super Course',
|
||||
}
|
||||
|
||||
def test_create_course(self):
|
||||
"""Test new course creation - happy path"""
|
||||
resp = self.client.post(reverse('create_new_course'), self.course_data)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
data = parse_json(resp)
|
||||
self.assertEqual(data['id'], 'i4x://MITx/999/course/Robot_Super_Course')
|
||||
|
||||
def test_create_course_duplicate_course(self):
|
||||
"""Test new course creation - error path"""
|
||||
resp = self.client.post(reverse('create_new_course'), self.course_data)
|
||||
resp = self.client.post(reverse('create_new_course'), self.course_data)
|
||||
data = parse_json(resp)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.assertEqual(data['ErrMsg'], 'There is already a course defined with this name.')
|
||||
|
||||
def test_create_course_duplicate_number(self):
|
||||
"""Test new course creation - error path"""
|
||||
resp = self.client.post(reverse('create_new_course'), self.course_data)
|
||||
self.course_data['display_name'] = 'Robot Super Course Two'
|
||||
|
||||
resp = self.client.post(reverse('create_new_course'), self.course_data)
|
||||
data = parse_json(resp)
|
||||
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.assertEqual(data['ErrMsg'],
|
||||
'There is already a course defined with the same organization and course number.')
|
||||
|
||||
def test_create_course_with_bad_organization(self):
|
||||
"""Test new course creation - error path for bad organization name"""
|
||||
self.course_data['org'] = 'University of California, Berkeley'
|
||||
resp = self.client.post(reverse('create_new_course'), self.course_data)
|
||||
data = parse_json(resp)
|
||||
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.assertEqual(data['ErrMsg'],
|
||||
"Unable to create course 'Robot Super Course'.\n\nInvalid characters in 'University of California, Berkeley'.")
|
||||
|
||||
def test_course_index_view_with_no_courses(self):
|
||||
"""Test viewing the index page with no courses"""
|
||||
# Create a course so there is something to view
|
||||
resp = self.client.get(reverse('index'))
|
||||
self.assertContains(resp,
|
||||
'<h1>My Courses</h1>',
|
||||
status_code=200,
|
||||
html=True)
|
||||
|
||||
def test_course_factory(self):
|
||||
"""Test that the course factory works correctly."""
|
||||
course = CourseFactory.create()
|
||||
self.assertIsInstance(course, CourseDescriptor)
|
||||
|
||||
def test_item_factory(self):
|
||||
"""Test that the item factory works correctly."""
|
||||
course = CourseFactory.create()
|
||||
item = ItemFactory.create(parent_location=course.location)
|
||||
self.assertIsInstance(item, SequenceDescriptor)
|
||||
|
||||
def test_course_index_view_with_course(self):
|
||||
"""Test viewing the index page with an existing course"""
|
||||
CourseFactory.create(display_name='Robot Super Educational Course')
|
||||
resp = self.client.get(reverse('index'))
|
||||
self.assertContains(resp,
|
||||
'<span class="class-name">Robot Super Educational Course</span>',
|
||||
status_code=200,
|
||||
html=True)
|
||||
|
||||
def test_course_overview_view_with_course(self):
|
||||
"""Test viewing the course overview page with an existing course"""
|
||||
CourseFactory.create(org='MITx', course='999', display_name='Robot Super Course')
|
||||
|
||||
data = {
|
||||
'org': 'MITx',
|
||||
'course': '999',
|
||||
'name': Location.clean('Robot Super Course'),
|
||||
}
|
||||
|
||||
resp = self.client.get(reverse('course_index', kwargs=data))
|
||||
self.assertContains(resp,
|
||||
'<a href="/MITx/999/course/Robot_Super_Course" class="class-name">Robot Super Course</a>',
|
||||
status_code=200,
|
||||
html=True)
|
||||
|
||||
def test_clone_item(self):
|
||||
"""Test cloning an item. E.g. creating a new section"""
|
||||
CourseFactory.create(org='MITx', course='999', display_name='Robot Super Course')
|
||||
|
||||
section_data = {
|
||||
'parent_location' : 'i4x://MITx/999/course/Robot_Super_Course',
|
||||
'template' : 'i4x://edx/templates/chapter/Empty',
|
||||
'display_name': 'Section One',
|
||||
}
|
||||
|
||||
resp = self.client.post(reverse('clone_item'), section_data)
|
||||
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
data = parse_json(resp)
|
||||
self.assertRegexpMatches(data['id'],
|
||||
'^i4x:\/\/MITx\/999\/chapter\/([0-9]|[a-f]){32}$')
|
||||
|
||||
def test_capa_module(self):
|
||||
"""Test that a problem treats markdown specially."""
|
||||
CourseFactory.create(org='MITx', course='999', display_name='Robot Super Course')
|
||||
|
||||
@@ -1,21 +1,27 @@
|
||||
from django.test.testcases import TestCase
|
||||
import datetime
|
||||
import time
|
||||
import json
|
||||
import calendar
|
||||
import copy
|
||||
from util import converters
|
||||
from util.converters import jsdate_to_time
|
||||
|
||||
from django.test.testcases import TestCase
|
||||
from django.contrib.auth.models import User
|
||||
import xmodule
|
||||
from django.test.client import Client
|
||||
from django.core.urlresolvers import reverse
|
||||
from xmodule.modulestore import Location
|
||||
from cms.djangoapps.models.settings.course_details import CourseDetails,\
|
||||
CourseSettingsEncoder
|
||||
import json
|
||||
from util import converters
|
||||
import calendar
|
||||
from util.converters import jsdate_to_time
|
||||
from django.utils.timezone import UTC
|
||||
|
||||
import xmodule
|
||||
from xmodule.modulestore import Location
|
||||
from cms.djangoapps.models.settings.course_details import (CourseDetails,
|
||||
CourseSettingsEncoder)
|
||||
from cms.djangoapps.models.settings.course_grading import CourseGradingModel
|
||||
from cms.djangoapps.contentstore.utils import get_modulestore
|
||||
import copy
|
||||
|
||||
from utils import ModuleStoreTestCase
|
||||
from xmodule.modulestore.tests.factories import CourseFactory
|
||||
|
||||
|
||||
# YYYY-MM-DDThh:mm:ss.s+/-HH:MM
|
||||
class ConvertersTestCase(TestCase):
|
||||
@@ -36,8 +42,15 @@ class ConvertersTestCase(TestCase):
|
||||
self.compare_dates(converters.jsdate_to_time("2013-01-01T00:00:00"), converters.jsdate_to_time("2012-12-31T23:59:59"), datetime.timedelta(seconds=1))
|
||||
|
||||
|
||||
class CourseTestCase(TestCase):
|
||||
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'
|
||||
@@ -52,36 +65,15 @@ class CourseTestCase(TestCase):
|
||||
self.user.is_staff = True
|
||||
self.user.save()
|
||||
|
||||
# Flush and initialize the module store
|
||||
# It needs the templates because it creates new records
|
||||
# by cloning from the template.
|
||||
# Note that if your test module gets in some weird state
|
||||
# (though it shouldn't), do this manually
|
||||
# from the bash shell to drop it:
|
||||
# $ mongo test_xmodule --eval "db.dropDatabase()"
|
||||
xmodule.modulestore.django._MODULESTORES = {}
|
||||
xmodule.modulestore.django.modulestore().collection.drop()
|
||||
xmodule.templates.update_templates()
|
||||
|
||||
self.client = Client()
|
||||
self.client.login(username=uname, password=password)
|
||||
|
||||
self.course_data = {
|
||||
'template': 'i4x://edx/templates/course/Empty',
|
||||
'org': 'MITx',
|
||||
'number': '999',
|
||||
'display_name': 'Robot Super Course',
|
||||
}
|
||||
self.course_location = Location('i4x', 'MITx', '999', 'course', 'Robot_Super_Course')
|
||||
self.create_course()
|
||||
|
||||
def tearDown(self):
|
||||
xmodule.modulestore.django._MODULESTORES = {}
|
||||
xmodule.modulestore.django.modulestore().collection.drop()
|
||||
|
||||
def create_course(self):
|
||||
"""Create new course"""
|
||||
self.client.post(reverse('create_new_course'), self.course_data)
|
||||
t='i4x://edx/templates/course/Empty'
|
||||
o='MITx'
|
||||
n='999'
|
||||
dn='Robot Super Course'
|
||||
self.course_location = Location('i4x', o, n, 'course', 'Robot_Super_Course')
|
||||
CourseFactory.create(template=t, org=o, number=n, display_name=dn)
|
||||
|
||||
class CourseDetailsTestCase(CourseTestCase):
|
||||
def test_virgin_fetch(self):
|
||||
@@ -145,7 +137,6 @@ class CourseDetailsViewTest(CourseTestCase):
|
||||
return datetime.isoformat("T")
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def test_update_and_fetch(self):
|
||||
details = CourseDetails.fetch(self.course_location)
|
||||
@@ -271,5 +262,3 @@ class CourseGradingTest(CourseTestCase):
|
||||
test_grader.graders[1]['drop_count'] = test_grader.graders[1].get('drop_count') + 1
|
||||
altered_grader = CourseGradingModel.update_grader_from_json(test_grader.course_location, test_grader.graders[1])
|
||||
self.assertDictEqual(test_grader.graders[1], altered_grader, "drop_count[1] + 2")
|
||||
|
||||
|
||||
|
||||
@@ -11,8 +11,6 @@ import json
|
||||
from fs.osfs import OSFS
|
||||
import copy
|
||||
|
||||
from student.models import Registration
|
||||
from django.contrib.auth.models import User
|
||||
from cms.djangoapps.contentstore.utils import get_modulestore
|
||||
|
||||
from xmodule.modulestore import Location
|
||||
@@ -29,22 +27,7 @@ from xmodule.course_module import CourseDescriptor
|
||||
from xmodule.seq_module import SequenceDescriptor
|
||||
|
||||
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
|
||||
from .utils import CmsTestCase
|
||||
|
||||
def parse_json(response):
|
||||
"""Parse response, which is assumed to be json"""
|
||||
return json.loads(response.content)
|
||||
|
||||
|
||||
def user(email):
|
||||
"""look up a user by email"""
|
||||
return User.objects.get(email=email)
|
||||
|
||||
|
||||
def registration(email):
|
||||
"""look up registration object by email"""
|
||||
return Registration.objects.get(user__email=email)
|
||||
|
||||
from utils import ModuleStoreTestCase, parse_json, user, registration
|
||||
|
||||
class ContentStoreTestCase(TestCase):
|
||||
def _login(self, email, pw):
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
from django.test import TestCase
|
||||
from xmodule.modulestore.django import modulestore, _MODULESTORES
|
||||
import json
|
||||
|
||||
from student.models import Registration
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
import xmodule.modulestore.django
|
||||
from xmodule.templates import update_templates
|
||||
|
||||
# Subclass TestCase and use to initialize the contentstore
|
||||
class CmsTestCase(TestCase):
|
||||
class ModuleStoreTestCase(TestCase):
|
||||
""" Subclass for any test case that uses the mongodb
|
||||
module store. This clears it out before running the TestCase
|
||||
and reinitilizes it with the templates afterwards. """
|
||||
|
||||
def _pre_setup(self):
|
||||
super(CmsTestCase, self)._pre_setup()
|
||||
super(ModuleStoreTestCase, self)._pre_setup()
|
||||
# Flush and initialize the module store
|
||||
# It needs the templates because it creates new records
|
||||
# by cloning from the template.
|
||||
@@ -17,16 +22,27 @@ class CmsTestCase(TestCase):
|
||||
# (though it shouldn't), do this manually
|
||||
# from the bash shell to drop it:
|
||||
# $ mongo test_xmodule --eval "db.dropDatabase()"
|
||||
_MODULESTORES = {}
|
||||
modulestore().collection.drop()
|
||||
xmodule.modulestore.django._MODULESTORES = {}
|
||||
xmodule.modulestore.django.modulestore().collection.drop()
|
||||
update_templates()
|
||||
|
||||
def _post_teardown(self):
|
||||
# Make sure you flush out the test modulestore after the end
|
||||
# of the last test because otherwise on the next run
|
||||
# cms/djangoapps/contentstore/__init__.py
|
||||
# update_templates() will try to update the templates
|
||||
# via upsert and it sometimes seems to be messing things up.
|
||||
_MODULESTORES = {}
|
||||
modulestore().collection.drop()
|
||||
super(CmsTestCase, self)._post_teardown()
|
||||
# of the last test so the collection will be deleted.
|
||||
# Otherwise there will be lingering collections leftover
|
||||
# from executing the tests.
|
||||
xmodule.modulestore.django._MODULESTORES = {}
|
||||
xmodule.modulestore.django.modulestore().collection.drop()
|
||||
super(ModuleStoreTestCase, self)._post_teardown()
|
||||
|
||||
def parse_json(response):
|
||||
"""Parse response, which is assumed to be json"""
|
||||
return json.loads(response.content)
|
||||
|
||||
def user(email):
|
||||
"""look up a user by email"""
|
||||
return User.objects.get(email=email)
|
||||
|
||||
def registration(email):
|
||||
"""look up registration object by email"""
|
||||
return Registration.objects.get(user__email=email)
|
||||
|
||||
@@ -1240,6 +1240,11 @@ def edge(request):
|
||||
@login_required
|
||||
@expect_json
|
||||
def create_new_course(request):
|
||||
# This logic is repeated in xmodule/modulestore/tests/factories.py
|
||||
# so if you change anything here, you need to also change it there.
|
||||
# TODO: write a test that creates two courses, one with the factory and
|
||||
# the other with this method, then compare them to make sure they are
|
||||
# equivalent.
|
||||
template = Location(request.POST['template'])
|
||||
org = request.POST.get('org')
|
||||
number = request.POST.get('number')
|
||||
@@ -1289,8 +1294,11 @@ def initialize_course_tabs(course):
|
||||
# at least a list populated with the minimal times
|
||||
# @TODO: I don't like the fact that the presentation tier is away of these data related constraints, let's find a better
|
||||
# place for this. Also rather than using a simple list of dictionaries a nice class model would be helpful here
|
||||
course.tabs = [{"type": "courseware"},
|
||||
{"type": "course_info", "name": "Course Info"},
|
||||
|
||||
# This logic is repeated in xmodule/modulestore/tests/factories.py
|
||||
# so if you change anything here, you need to also change it there.
|
||||
course.tabs = [{"type": "courseware"},
|
||||
{"type": "course_info", "name": "Course Info"},
|
||||
{"type": "discussion", "name": "Discussion"},
|
||||
{"type": "wiki", "name": "Wiki"},
|
||||
{"type": "progress", "name": "Progress"}]
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
from factory import Factory
|
||||
# from datetime import datetime
|
||||
from time import gmtime
|
||||
from uuid import uuid4
|
||||
from xmodule.modulestore import Location
|
||||
@@ -22,7 +21,8 @@ class XModuleCourseFactory(Factory):
|
||||
|
||||
@classmethod
|
||||
def _create(cls, target_class, *args, **kwargs):
|
||||
|
||||
# This logic was taken from the create_new_course method in
|
||||
# cms/djangoapps/contentstore/views.py
|
||||
template = Location('i4x', 'edx', 'templates', 'course', 'Empty')
|
||||
org = kwargs.get('org')
|
||||
number = kwargs.get('number')
|
||||
@@ -41,6 +41,7 @@ class XModuleCourseFactory(Factory):
|
||||
|
||||
new_course.metadata['data_dir'] = uuid4().hex
|
||||
new_course.metadata['start'] = stringify_time(gmtime())
|
||||
|
||||
new_course.tabs = [{"type": "courseware"},
|
||||
{"type": "course_info", "name": "Course Info"},
|
||||
{"type": "discussion", "name": "Discussion"},
|
||||
@@ -114,4 +115,4 @@ class ItemFactory(XModuleItemFactory):
|
||||
|
||||
parent_location = 'i4x://MITx/999/course/Robot_Super_Course'
|
||||
template = 'i4x://edx/templates/chapter/Empty'
|
||||
display_name = 'Section One'
|
||||
display_name = 'Section One'
|
||||
|
||||
Reference in New Issue
Block a user